diff --git a/.changes/allow-prevent-window-close.md b/.changes/allow-prevent-window-close.md deleted file mode 100644 index 8cfe999e84f1..000000000000 --- a/.changes/allow-prevent-window-close.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Allow preventing window close when the user requests it. diff --git a/.changes/allowlist-clipboard.md b/.changes/allowlist-clipboard.md new file mode 100644 index 000000000000..451fb8dc6241 --- /dev/null +++ b/.changes/allowlist-clipboard.md @@ -0,0 +1,5 @@ +--- +"tauri-utils": patch +--- + +The `allowlist` configuration now includes a `clipboard` object, controlling the exposure of the `writeText` and `readText` APIs. diff --git a/.changes/allowlist-dialog.md b/.changes/allowlist-dialog.md new file mode 100644 index 000000000000..ffbcd6a568cf --- /dev/null +++ b/.changes/allowlist-dialog.md @@ -0,0 +1,6 @@ +--- +"tauri-utils": patch +"tauri": patch +--- + +The dialog allowlist now includes flags for the `message`, `ask` and `confirm` APIs. diff --git a/.changes/allowlist-process.md b/.changes/allowlist-process.md new file mode 100644 index 000000000000..490c3d1fb5ca --- /dev/null +++ b/.changes/allowlist-process.md @@ -0,0 +1,5 @@ +--- +"tauri-utils": patch +--- + +The `allowlist` configuration now includes a `process` object, controlling the exposure of the `relaunch` and `exit` APIs. diff --git a/.changes/allowlist-window.md b/.changes/allowlist-window.md new file mode 100644 index 000000000000..7fe9048de4b4 --- /dev/null +++ b/.changes/allowlist-window.md @@ -0,0 +1,5 @@ +--- +tauri-utils: patch +--- + +The `window` allowlist now includes options to enable all window modification APIs: `center`, `close`, `create`, `hide`, `maximize`, `minimize`, `print`, `requestUserAttention`, `setAlwaysOnTop`, `setDecorations`, `setFocus`, `setFullscreen`, `setIcon`, `setMaxSize`, `setMinSize`, `setPosition`, `setResizable`, `setSize`, `setSkipTaskbar`, `setTitle`, `show`, `startDragging`, `unmaximize` and `unminimize`. diff --git a/.changes/anonymous-lifetimes.md b/.changes/anonymous-lifetimes.md deleted file mode 100644 index cfab536387c4..000000000000 --- a/.changes/anonymous-lifetimes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Remove anonymous lifetimes on examples. \ No newline at end of file diff --git a/.changes/api-WebviewWindow-fileDropEnabled.md b/.changes/api-WebviewWindow-fileDropEnabled.md new file mode 100644 index 000000000000..06835a9298fb --- /dev/null +++ b/.changes/api-WebviewWindow-fileDropEnabled.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Add `fileDropEnabled` property to `WindowOptions` so you can now disable it when creating windows from js. diff --git a/.changes/api-add-log-dir.md b/.changes/api-add-log-dir.md new file mode 100644 index 000000000000..7cd73ba19ef5 --- /dev/null +++ b/.changes/api-add-log-dir.md @@ -0,0 +1,6 @@ +--- +"api": patch +--- + +Add `logDir` function to the `path` module to access the sugested log directory. +Add `BaseDirectory.Log` to the `fs` module. diff --git a/.changes/api-change-events.md b/.changes/api-change-events.md new file mode 100644 index 000000000000..df0b1f5563dd --- /dev/null +++ b/.changes/api-change-events.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +--- + +* **Breaking change**: Renamed `tauri::Event` to `tauri::RunEvent` +* Exported `tauri::Event` and `tauri::EventHandler` so you can define a function and pass it to `Window::listen` diff --git a/.changes/api-cjs-chunks.md b/.changes/api-cjs-chunks.md deleted file mode 100644 index 672e5b816e81..000000000000 --- a/.changes/api-cjs-chunks.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -CommonJS chunks are now properly exported with `.cjs` extension diff --git a/.changes/api-clipboard-export.md b/.changes/api-clipboard-export.md deleted file mode 100644 index ae1696237ec4..000000000000 --- a/.changes/api-clipboard-export.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"api": patch ---- - - -`bundle` now exports `clipboard` module so you can `import { clipboard } from "@tauri-apps/api"`. diff --git a/.changes/api-convert-file-url.md b/.changes/api-convert-file-url.md deleted file mode 100644 index 3904389f0e06..000000000000 --- a/.changes/api-convert-file-url.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `convertFileSrc` helper to the `tauri` module, simplifying the process of using file paths as webview source (`img`, `video`, etc). diff --git a/.changes/api-dialog-ask-message-confirm.md b/.changes/api-dialog-ask-message-confirm.md new file mode 100644 index 000000000000..f698df09a108 --- /dev/null +++ b/.changes/api-dialog-ask-message-confirm.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Expose `ask`, `message` and `confirm` APIs on the dialog module. diff --git a/.changes/api-emit-payload-type.md b/.changes/api-emit-payload-type.md new file mode 100644 index 000000000000..4ed130564181 --- /dev/null +++ b/.changes/api-emit-payload-type.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Event `emit` now automatically serialize non-string types. diff --git a/.changes/api-export-BaseDirectory.md b/.changes/api-export-BaseDirectory.md deleted file mode 100644 index 90fb9bb9318a..000000000000 --- a/.changes/api-export-BaseDirectory.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"api": patch ---- - -Export `BaseDirectory` in `path` module - diff --git a/.changes/api-export-package-json.md b/.changes/api-export-package-json.md deleted file mode 100644 index bc04cc61e6d2..000000000000 --- a/.changes/api-export-package-json.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `package.json` to the `exports` object. diff --git a/.changes/api-export-type-fix.md b/.changes/api-export-type-fix.md deleted file mode 100644 index 8c871e80ce79..000000000000 --- a/.changes/api-export-type-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Export `Response` and `ResponseType` as value instead of type. diff --git a/.changes/api-export-type.md b/.changes/api-export-type.md deleted file mode 100644 index 0acee57af74d..000000000000 --- a/.changes/api-export-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Use `export type` to export TS types, enums and interfaces. diff --git a/.changes/api-feature-flags.md b/.changes/api-feature-flags.md deleted file mode 100644 index 5612620af17e..000000000000 --- a/.changes/api-feature-flags.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Moves `shell`, `dialog::FileDialogBuilder` and `process::Command` APIs behind their allowlist feature flags. diff --git a/.changes/api-features.md b/.changes/api-features.md new file mode 100644 index 000000000000..51c5d93ece9b --- /dev/null +++ b/.changes/api-features.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The `tauri::api` modules `http`, `notification`, `dialog`, and `process::Command` APIs are now hidden behind a feature flag, `http-api`, `notification`, `dialog` and `command`, respectively. diff --git a/.changes/api-fetch-empty-reponse.md b/.changes/api-fetch-empty-reponse.md new file mode 100644 index 000000000000..d0b81376f7ac --- /dev/null +++ b/.changes/api-fetch-empty-reponse.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Fix `http.fetch` throwing error if the response is successful but the body is empty. diff --git a/.changes/api-file-dialog-title.md b/.changes/api-file-dialog-title.md new file mode 100644 index 000000000000..2613a41604e0 --- /dev/null +++ b/.changes/api-file-dialog-title.md @@ -0,0 +1,6 @@ +--- +"api": patch +"tauri": patch +--- + +Add `title` option to file open/save dialogs. diff --git a/.changes/api-fix-double-window.md b/.changes/api-fix-double-window.md deleted file mode 100644 index 5fe3032e7e73..000000000000 --- a/.changes/api-fix-double-window.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Fix double window creation diff --git a/.changes/api-fix-os-platform-return.md b/.changes/api-fix-os-platform-return.md new file mode 100644 index 000000000000..fdf7d03b079b --- /dev/null +++ b/.changes/api-fix-os-platform-return.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Fix `os.platform` returning `macos` and `windows` instead of `darwin` and `win32`. diff --git a/.changes/api-focus.md b/.changes/api-focus.md deleted file mode 100644 index 5278795b3bce..000000000000 --- a/.changes/api-focus.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `focus?: boolean` to the WindowOptions interface. diff --git a/.changes/api-format-callback.md b/.changes/api-format-callback.md new file mode 100644 index 000000000000..a517cff7c268 --- /dev/null +++ b/.changes/api-format-callback.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +The `formatCallback` helper function now returns a number instead of a string. diff --git a/.changes/api-is-decorated.md b/.changes/api-is-decorated.md deleted file mode 100644 index 0806cdf89822..000000000000 --- a/.changes/api-is-decorated.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `isDecorated` getter on the window API. diff --git a/.changes/api-is-resizable.md b/.changes/api-is-resizable.md deleted file mode 100644 index c81d120a90e6..000000000000 --- a/.changes/api-is-resizable.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `isResizable` getter on the window API. diff --git a/.changes/api-is-visible.md b/.changes/api-is-visible.md deleted file mode 100644 index e3cfd2250f18..000000000000 --- a/.changes/api-is-visible.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `isVisible` getter on the window API. diff --git a/.changes/api-os-module.md b/.changes/api-os-module.md deleted file mode 100644 index 7935a98beec0..000000000000 --- a/.changes/api-os-module.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -"api": patch ---- -Add `os` module which exports `EOL`, `platform()`, `version()`, `type()`, `arch()`, `tempdir()` diff --git a/.changes/api-path-module.md b/.changes/api-path-module.md deleted file mode 100644 index 0a967305019a..000000000000 --- a/.changes/api-path-module.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"api": patch ---- - -- Add new nodejs-inspired functions which are `join`, `resolve`, `normalize`, `dirname`, `basename` and `extname`. -- Add `sep` and `delimiter` constants. -- Removed `resolvePath` API, use `resolve` instead. diff --git a/.changes/api-raw-headers.md b/.changes/api-raw-headers.md new file mode 100644 index 000000000000..2d384f6b38ba --- /dev/null +++ b/.changes/api-raw-headers.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Added `rawHeaders` to `http > Response`. diff --git a/.changes/api-remove-current-dir.md b/.changes/api-remove-current-dir.md new file mode 100644 index 000000000000..375fa7f78110 --- /dev/null +++ b/.changes/api-remove-current-dir.md @@ -0,0 +1,5 @@ +--- +"api": "patch" +--- + +Removed the `currentDir` API from the `path` module. diff --git a/.changes/api-remove-ts-files.md b/.changes/api-remove-ts-files.md new file mode 100644 index 000000000000..8497514e9a03 --- /dev/null +++ b/.changes/api-remove-ts-files.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Remove `.ts` files on the published package. diff --git a/.changes/api-request-user-attention.md b/.changes/api-request-user-attention.md deleted file mode 100644 index 1454f9afb93d..000000000000 --- a/.changes/api-request-user-attention.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `requestUserAttention` API to the `window` module. diff --git a/.changes/api-set-focus.md b/.changes/api-set-focus.md deleted file mode 100644 index 1e214ce8e091..000000000000 --- a/.changes/api-set-focus.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `setFocus` to the window API. diff --git a/.changes/api-set-skip-taskbar.md b/.changes/api-set-skip-taskbar.md deleted file mode 100644 index 3546889a497e..000000000000 --- a/.changes/api-set-skip-taskbar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `setSkipTaskbar` to the window API. diff --git a/.changes/api-skip-taskbar.md b/.changes/api-skip-taskbar.md deleted file mode 100644 index a37747212b3a..000000000000 --- a/.changes/api-skip-taskbar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `skipTaskbar?: boolean` to the WindowOptions interface. diff --git a/.changes/api-target-es2021.md b/.changes/api-target-es2021.md deleted file mode 100644 index ca3743586043..000000000000 --- a/.changes/api-target-es2021.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Change target to ES2021. diff --git a/.changes/api-toggle-maximize.md b/.changes/api-toggle-maximize.md deleted file mode 100644 index 485d09031521..000000000000 --- a/.changes/api-toggle-maximize.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Add `toggleMaximize()` function to the `WebviewWindow` class. diff --git a/.changes/api-transparent-window.md b/.changes/api-transparent-window.md deleted file mode 100644 index 496af1ca0c5d..000000000000 --- a/.changes/api-transparent-window.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `transparent?: boolean` to the `WindowOptions` interface. diff --git a/.changes/api-ts-expect-error.md b/.changes/api-ts-expect-error.md deleted file mode 100644 index 91038679ca93..000000000000 --- a/.changes/api-ts-expect-error.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -"api": patch ---- -Fix `@ts-expect` error usage diff --git a/.changes/api-use-uint8array.md b/.changes/api-use-uint8array.md new file mode 100644 index 000000000000..a23c35bbf564 --- /dev/null +++ b/.changes/api-use-uint8array.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +**Breaking change:** Replaces all usages of `number[]` with `Uint8Array` to be closer aligned with the wider JS ecosystem. diff --git a/.changes/api-window-center.md b/.changes/api-window-center.md deleted file mode 100644 index 30eb31437c73..000000000000 --- a/.changes/api-window-center.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `center?: boolean` to `WindowOptions` and `center()` API to the `appWindow`. diff --git a/.changes/api-window-type-for-size-and-position.md b/.changes/api-window-type-for-size-and-position.md new file mode 100644 index 000000000000..0b7818c1f575 --- /dev/null +++ b/.changes/api-window-type-for-size-and-position.md @@ -0,0 +1,6 @@ +--- +"api": patch +--- + +`WindowManager` methods `innerPosition` `outerPosition` now correctly return instance of `PhysicalPosition`. +`WindowManager` methods `innerSize` `outerSize` now correctly return instance of `PhysicalSize`. diff --git a/.changes/app-any-thread.md b/.changes/app-any-thread.md new file mode 100644 index 000000000000..a413e36af267 --- /dev/null +++ b/.changes/app-any-thread.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Added `any_thread()` to the `tauri::Builder` to run applications on any thread (only exposed on Linux and Windows). diff --git a/.changes/app-callback.md b/.changes/app-callback.md deleted file mode 100644 index 0f9ebff43643..000000000000 --- a/.changes/app-callback.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Add `App#run` method with callback argument (event loop event handler). diff --git a/.changes/app-dir-refactor.md b/.changes/app-dir-refactor.md deleted file mode 100644 index 023b2071a4e9..000000000000 --- a/.changes/app-dir-refactor.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch ---- - -**Breaking:** `api::path::resolve_path()` and `api::path::app_dir()` now takes the config as first argument and the `PackageInfo` as second argument. -**Breaking:** `api::path::app_dir()` now resolves to `${configDir}/${config.tauri.bundle.identifier}`. diff --git a/.changes/app-folder-structure.md b/.changes/app-folder-structure.md new file mode 100644 index 000000000000..c4396de4ddf6 --- /dev/null +++ b/.changes/app-folder-structure.md @@ -0,0 +1,6 @@ +--- +"cli.js": patch +"cli.rs": patch +--- + +Do not force Tauri application code on `src-tauri` folder and use a glob pattern to look for a subfolder with a `tauri.conf.json` file. diff --git a/.changes/app-handle-create-window.md b/.changes/app-handle-create-window.md deleted file mode 100644 index 52cb110536f7..000000000000 --- a/.changes/app-handle-create-window.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `create_window` API to the `AppHandle` struct. diff --git a/.changes/app-handle-exit-cleanup.md b/.changes/app-handle-exit-cleanup.md deleted file mode 100644 index bdec484413a1..000000000000 --- a/.changes/app-handle-exit-cleanup.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Cleanup application on `AppHandle#exit`. diff --git a/.changes/app-handle.md b/.changes/app-handle.md deleted file mode 100644 index bcff2bdee0e7..000000000000 --- a/.changes/app-handle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds a `handle` function to the `App` struct, which returns a `Send` handle to the app instance. diff --git a/.changes/app-set-activation-policy.md b/.changes/app-set-activation-policy.md deleted file mode 100644 index 1bf47c37211c..000000000000 --- a/.changes/app-set-activation-policy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `set_activation_policy` API to the `tauri::App` struct (macOS only). diff --git a/.changes/app-state.md b/.changes/app-state.md deleted file mode 100644 index cee7282c15d0..000000000000 --- a/.changes/app-state.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `manage` API to the `Builder` struct, which manages app state. diff --git a/.changes/appwindow-events.md b/.changes/appwindow-events.md deleted file mode 100644 index c0eb42ae066c..000000000000 --- a/.changes/appwindow-events.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -You can now use `emit`, `listen` and `once` using the `appWindow` exported by the window module. diff --git a/.changes/asset-allowlist.md b/.changes/asset-allowlist.md new file mode 100644 index 000000000000..ca00d66be72b --- /dev/null +++ b/.changes/asset-allowlist.md @@ -0,0 +1,5 @@ +--- +"tauri-utils": patch +--- + +Added `asset` allowlist configuration, which enables the `asset` protocol and defines it access scope. diff --git a/.changes/asset-cors.md b/.changes/asset-cors.md new file mode 100644 index 000000000000..4444dc4ffdc6 --- /dev/null +++ b/.changes/asset-cors.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Enable CORS on the `asset` protocol. diff --git a/.changes/asset-path.md b/.changes/asset-path.md deleted file mode 100644 index ed31e639b662..000000000000 --- a/.changes/asset-path.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"api": patch -"tauri": patch ---- - -Fix missing asset protocol path.Now the protocol is `https://asset.localhost/path/to/file` on Windows. Lunix and macOS -is still `asset://path/to/file`. diff --git a/.changes/asset-protocol-feature-flag.md b/.changes/asset-protocol-feature-flag.md new file mode 100644 index 000000000000..f3cc874bf255 --- /dev/null +++ b/.changes/asset-protocol-feature-flag.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The `asset://` custom protocol is only defined when either the `api-all`, `protocol-all` or `protocol-asset` feature flags are enabled. These feature flags are accessible with the `tauri.conf.json` allowlist. diff --git a/.changes/asset-protocol.md b/.changes/asset-protocol.md deleted file mode 100644 index 64d40a8753b5..000000000000 --- a/.changes/asset-protocol.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Add asset custom protocol to access local file system. diff --git a/.changes/asset-resolver.md b/.changes/asset-resolver.md new file mode 100644 index 000000000000..cadbb49e790a --- /dev/null +++ b/.changes/asset-resolver.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Expose the `asset_resolver` API on the `App` and `AppHandle` structs. diff --git a/.changes/assets-refactor.md b/.changes/assets-refactor.md deleted file mode 100644 index 9fd475e1b498..000000000000 --- a/.changes/assets-refactor.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri-codegen": patch -"tauri-utils": patch -"tauri": patch ---- - -**Breaking:** The `assets` field on the `tauri::Context` struct is now a `Arc`. diff --git a/.changes/async-commands.md b/.changes/async-commands.md deleted file mode 100644 index 49e7831cf424..000000000000 --- a/.changes/async-commands.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-macros": patch ---- - -Only commands with a `async fn` are executed on a separate task. `#[command] fn command_name` runs on the main thread. diff --git a/.changes/async-runtime-handle-api.md b/.changes/async-runtime-handle-api.md deleted file mode 100644 index 58ab8fb18589..000000000000 --- a/.changes/async-runtime-handle-api.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Add `handle` API to `tauri::async_runtime`. diff --git a/.changes/async-runtime-refactor.md b/.changes/async-runtime-refactor.md new file mode 100644 index 000000000000..4367fe552fa3 --- /dev/null +++ b/.changes/async-runtime-refactor.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +**Breaking change:** Refactored the types returned from the `async_runtime` module. diff --git a/.changes/async-runtime-set.md b/.changes/async-runtime-set.md new file mode 100644 index 000000000000..7b00e0127e89 --- /dev/null +++ b/.changes/async-runtime-set.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Added `tauri::async_runtime::set` method, allowing to share your tokio runtime with Tauri. diff --git a/.changes/async-runtime-spawn-blocking.md b/.changes/async-runtime-spawn-blocking.md new file mode 100644 index 000000000000..b39939c1e7ae --- /dev/null +++ b/.changes/async-runtime-spawn-blocking.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Added `tauri::async_runtime::spawn_blocking` API. diff --git a/.changes/async-runtime-spawn-returns-join-handle.md b/.changes/async-runtime-spawn-returns-join-handle.md deleted file mode 100644 index 34d76a76b319..000000000000 --- a/.changes/async-runtime-spawn-returns-join-handle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -**Breaking change:** The `tauri::async_runtime::spawn` function now returns `tauri::async_runtime::JoinHandle`. diff --git a/.changes/attohttpc-default-client.md b/.changes/attohttpc-default-client.md deleted file mode 100644 index 6a6204d99351..000000000000 --- a/.changes/attohttpc-default-client.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Use `attohttpc` on the HTTP API by default for bundle size optimization. `reqwest` is implemented behind the `reqwest-client` feature flag. diff --git a/.changes/before-script-envs.md b/.changes/before-script-envs.md new file mode 100644 index 000000000000..d1a28bfa0f85 --- /dev/null +++ b/.changes/before-script-envs.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Define `TAURI_PLATFORM`, `TAURI_ARCH`, `TAURI_FAMILY`, `TAURI_PLATFORM_TYPE`, `TAURI_PLATFORM_VERSION` and `TAURI_DEBUG` environment variables for the `beforeDevCommand` and `beforeBuildCommand` scripts. diff --git a/.changes/beta.md b/.changes/beta.md deleted file mode 100644 index b959151dbee0..000000000000 --- a/.changes/beta.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"api": major -"tauri-bundler": major -"cli.rs": major -"cli.js": major -"tauri-utils": major -"tauri-codegen": major -"tauri-macros": major -"tauri-build": major -"tauri-runtime": minor -"tauri-runtime-wry": minor -"tauri": major -"create-tauri-app": major ---- - -Upgrade to beta! diff --git a/.changes/build-on-m1.md b/.changes/build-on-m1.md deleted file mode 100644 index cdb3fd7ddf8f..000000000000 --- a/.changes/build-on-m1.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Support `cargo tauri build` on Apple M1 chip. diff --git a/.changes/build-specify-win-sdk.md b/.changes/build-specify-win-sdk.md new file mode 100644 index 000000000000..1eab9d981be7 --- /dev/null +++ b/.changes/build-specify-win-sdk.md @@ -0,0 +1,5 @@ +--- +"tauri-build": patch +--- + +Allow user to specify windows sdk path in build.rs. \ No newline at end of file diff --git a/.changes/bundle-deb-installed-size.md b/.changes/bundle-deb-installed-size.md deleted file mode 100644 index 932472af2b60..000000000000 --- a/.changes/bundle-deb-installed-size.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Fixes the `Installed-Size` value on the debian package. diff --git a/.changes/bundler-add-provider-short-name.md b/.changes/bundler-add-provider-short-name.md new file mode 100644 index 000000000000..65eaae6be092 --- /dev/null +++ b/.changes/bundler-add-provider-short-name.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": patch +--- + +Provide a provider short name for macOS app notarization if your Apple developer account is connected to more than one team. diff --git a/.changes/bundler-appimage-fuse.md b/.changes/bundler-appimage-fuse.md new file mode 100644 index 000000000000..ec7a25876ef4 --- /dev/null +++ b/.changes/bundler-appimage-fuse.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": patch +--- + +Allow building AppImages on systems without FUSE setup. diff --git a/.changes/bundler-arm.md b/.changes/bundler-arm.md deleted file mode 100644 index a6b99d1cd268..000000000000 --- a/.changes/bundler-arm.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Use `armhf` as Debian package architecture on `arm` CPUs. diff --git a/.changes/bundler-docs.md b/.changes/bundler-docs.md deleted file mode 100644 index 2efc8e1504b2..000000000000 --- a/.changes/bundler-docs.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Adds basic library documentation. diff --git a/.changes/bundler-fix-appimage.md b/.changes/bundler-fix-appimage.md new file mode 100644 index 000000000000..fcaf8b4dbaca --- /dev/null +++ b/.changes/bundler-fix-appimage.md @@ -0,0 +1,5 @@ +--- +'tauri-bundler': patch +--- + +Fixes AppImage crashes caused by missing WebKit runtime files. diff --git a/.changes/bundler-merge-info-plist.md b/.changes/bundler-merge-info-plist.md deleted file mode 100644 index 545b18e71cb9..000000000000 --- a/.changes/bundler-merge-info-plist.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Merge Tauri-generated Info.plist with the contents of `src-tauri/Info.plist` if it exists. diff --git a/.changes/bundler-msi-init-installdir.md b/.changes/bundler-msi-init-installdir.md new file mode 100644 index 000000000000..430f2ba1c2f7 --- /dev/null +++ b/.changes/bundler-msi-init-installdir.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": patch +--- + +Initialize the preselected installation path with the location of the previous installation. \ No newline at end of file diff --git a/.changes/bundler-msi-upgrade-same-version.md b/.changes/bundler-msi-upgrade-same-version.md deleted file mode 100644 index 5778a0df80c1..000000000000 --- a/.changes/bundler-msi-upgrade-same-version.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Change the WiX config to allow upgrading installation with same version instead of duplicating the application. diff --git a/.changes/bundler-not-copy-resources-outdir.md b/.changes/bundler-not-copy-resources-outdir.md deleted file mode 100644 index 81f615d3cb3e..000000000000 --- a/.changes/bundler-not-copy-resources-outdir.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -The process of copying binaries and resources to `project_out_directory` was moved to the Tauri CLI. diff --git a/.changes/bundler-package-types.md b/.changes/bundler-package-types.md deleted file mode 100644 index e48c03154f0a..000000000000 --- a/.changes/bundler-package-types.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -The `PackageTypes` enum now includes all options, including Windows packages. diff --git a/.changes/bundler-print-cfg.md b/.changes/bundler-print-cfg.md new file mode 100644 index 000000000000..d382978884e9 --- /dev/null +++ b/.changes/bundler-print-cfg.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": patch +--- + +Replaces usage of the nightly command `RUSTC_BOOTSTRAP=1 rustc -Z unstable-options --print target-spec-json` with the stable command `rustc --print cfg`, improving target triple detection. diff --git a/.changes/bundler-runtime-target-arch.md b/.changes/bundler-runtime-target-arch.md deleted file mode 100644 index 2cedf258f8e4..000000000000 --- a/.changes/bundler-runtime-target-arch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Check target architecture at runtime running `$ RUSTC_BOOTSTRAP=1 rustc -Z unstable-options --print target-spec-json` and parsing the `llvm-target` field, fixing macOS M1 sidecar check until we can compile the CLI with M1 target on GitHub Actions. diff --git a/.changes/bundler-windows-icon-path.md b/.changes/bundler-windows-icon-path.md deleted file mode 100644 index 25063f829154..000000000000 --- a/.changes/bundler-windows-icon-path.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Adds `icon_path` field to the `WindowsSettings` struct (defaults to `icons/icon.ico`). diff --git a/.changes/bundler-windows-uninstaller.md b/.changes/bundler-windows-uninstaller.md deleted file mode 100644 index 306fdd0fc4ac..000000000000 --- a/.changes/bundler-windows-uninstaller.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Fix WIX uninstaller by using unique `GUID` shortcut. diff --git a/.changes/bundler-wix-banner-icon.md b/.changes/bundler-wix-banner-icon.md deleted file mode 100644 index fbe360201afd..000000000000 --- a/.changes/bundler-wix-banner-icon.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Added `banner_path` field to the `WixSettings` struct. - diff --git a/.changes/bundler-wix-dialog-image.md b/.changes/bundler-wix-dialog-image.md deleted file mode 100644 index 3f29587c35aa..000000000000 --- a/.changes/bundler-wix-dialog-image.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Added `dialog_image_path` field to the `WixSettings` struct. diff --git a/.changes/callback-validation.md b/.changes/callback-validation.md new file mode 100644 index 000000000000..4aa93397bf85 --- /dev/null +++ b/.changes/callback-validation.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The `callback` and `error` invoke fields, along with other `transformCallback` usages, are now validated to be numeric. diff --git a/.changes/cargo-cache.md b/.changes/cargo-cache.md deleted file mode 100644 index 07e9eabea311..000000000000 --- a/.changes/cargo-cache.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Fixes a cargo `target/` cache issue. diff --git a/.changes/child-process-cleanup.md b/.changes/child-process-cleanup.md deleted file mode 100644 index c38d83da74f2..000000000000 --- a/.changes/child-process-cleanup.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Kill child processes spawned with `tauri::api::process::Command` on `tauri::App` drop. Can be skipped with `tauri::Builder#skip_cleanup_on_drop`. diff --git a/.changes/clap-beta.4-core.md b/.changes/clap-beta.4-core.md new file mode 100644 index 000000000000..bc371dabe284 --- /dev/null +++ b/.changes/clap-beta.4-core.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Change `Error::ParseCliArguments(clap::Error)` to `Error::ParseCliArguments(String)` because `clap::Error` is not `Send`. diff --git a/.changes/clap-beta.4.md b/.changes/clap-beta.4.md new file mode 100644 index 000000000000..d29f9f87f9de --- /dev/null +++ b/.changes/clap-beta.4.md @@ -0,0 +1,5 @@ +--- +"tauri-utils": patch +--- + +Change `CliArg` numeric types from `u64` to `usize`. diff --git a/.changes/cli-config-path.md b/.changes/cli-config-path.md new file mode 100644 index 000000000000..8354c6e53a9c --- /dev/null +++ b/.changes/cli-config-path.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Allow `config` arg to be a path to a JSON file on the `dev` and `build` commands. diff --git a/.changes/cli-error-logging.md b/.changes/cli-error-logging.md deleted file mode 100644 index a4d885a7edfa..000000000000 --- a/.changes/cli-error-logging.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Improve error logging. diff --git a/.changes/cli-error-message.md b/.changes/cli-error-message.md deleted file mode 100644 index 8e041a5102b8..000000000000 --- a/.changes/cli-error-message.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Improve error message when the product name is invalid. diff --git a/.changes/cli-init-infer-prompts.md b/.changes/cli-init-infer-prompts.md deleted file mode 100644 index 1c54c5a133c2..000000000000 --- a/.changes/cli-init-infer-prompts.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"cli.rs": patch ---- - -Infer `app name` and `window title` from `package.json > productName` or `package.json > name`. -Infer `distDir` and `devPath` by reading the package.json and trying to determine the UI framework (Vue.js, Angular, React, Svelte and some UI frameworks). diff --git a/.changes/cli-rs-info-webview2.md b/.changes/cli-rs-info-webview2.md deleted file mode 100644 index 302bda7e1ce7..000000000000 --- a/.changes/cli-rs-info-webview2.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Adds Webview2 version on `info` command. diff --git a/.changes/cli-rs-macos-signing-id-env.md b/.changes/cli-rs-macos-signing-id-env.md deleted file mode 100644 index 228ebed5dffc..000000000000 --- a/.changes/cli-rs-macos-signing-id-env.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Added `APPLE_SIGNING_IDENTITY` as supported environment variable for the bundler. diff --git a/.changes/cli-rs-powerhsell-no-profile.md b/.changes/cli-rs-powerhsell-no-profile.md deleted file mode 100644 index 3ea422d8a5af..000000000000 --- a/.changes/cli-rs-powerhsell-no-profile.md +++ /dev/null @@ -1,7 +0,0 @@ - ---- - "cli.rs": patch - "cli.js": patch - "tauri-bundler": patch ---- -Run powershell commands with `-NoProfile` flag diff --git a/.changes/cli-runner-arg.md b/.changes/cli-runner-arg.md deleted file mode 100644 index f3ee8baaf75d..000000000000 --- a/.changes/cli-runner-arg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Adds `--runner [PROGRAM]` argument on the `dev` and `build` command, allowing using the specified program to run and build the application (example program: `cross`). diff --git a/.changes/cli-target-triple.md b/.changes/cli-target-triple.md deleted file mode 100644 index 4ba3cea99ad3..000000000000 --- a/.changes/cli-target-triple.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Adds `--target [TARGET_TRIPLE]` option to the `build` command (example: `--target arm-unknown-linux-gnueabihf`). diff --git a/.changes/cli-targets-refactor.md b/.changes/cli-targets-refactor.md deleted file mode 100644 index 0b6deb8fee99..000000000000 --- a/.changes/cli-targets-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Rename `--target` option on the `build` command to `--bundle`. diff --git a/.changes/cli.js-cjs-output.md b/.changes/cli.js-cjs-output.md new file mode 100644 index 000000000000..53bf7d818539 --- /dev/null +++ b/.changes/cli.js-cjs-output.md @@ -0,0 +1,5 @@ +--- +"cli.js": patch +--- + +Added CommonJS output to the `dist` folder. diff --git a/.changes/cli.js-deps-update-manifest.md b/.changes/cli.js-deps-update-manifest.md deleted file mode 100644 index ec8694ae25be..000000000000 --- a/.changes/cli.js-deps-update-manifest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Force Cargo manifest update when running the `deps update` command and fix the version that is written to the file. diff --git a/.changes/cli.js-empty-args.md b/.changes/cli.js-empty-args.md deleted file mode 100644 index 1750745bcabb..000000000000 --- a/.changes/cli.js-empty-args.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Allow empty argument when running `cli.rs`. diff --git a/.changes/cli.js-error-propagation.md b/.changes/cli.js-error-propagation.md deleted file mode 100644 index 4fa07c3b51fb..000000000000 --- a/.changes/cli.js-error-propagation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Fixes `UnhandledPromiseRejectionWarning` when the Rust CLI call fails. diff --git a/.changes/cli.js-es-module.md b/.changes/cli.js-es-module.md deleted file mode 100644 index 3e0a0cdf906b..000000000000 --- a/.changes/cli.js-es-module.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -The CLI is now a ES module and requires at least Node.js v12.20. diff --git a/.changes/cli.js-fix-ico.md b/.changes/cli.js-fix-ico.md new file mode 100644 index 000000000000..05b5bab9eb48 --- /dev/null +++ b/.changes/cli.js-fix-ico.md @@ -0,0 +1,5 @@ +--- +"cli.js": patch +--- + +Fixes `.ico` icon generation. diff --git a/.changes/cli.js-package-check.md b/.changes/cli.js-package-check.md deleted file mode 100644 index 4f4d496590a6..000000000000 --- a/.changes/cli.js-package-check.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Packages are checked with `!=` instead of `semver` for beta releases. diff --git a/.changes/cli.js-proxy.md b/.changes/cli.js-proxy.md deleted file mode 100644 index c2e4d13b2d80..000000000000 --- a/.changes/cli.js-proxy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Adds support to HTTPS proxy set with the `HTTPS_PROXY` environment variable. diff --git a/.changes/cli.js-rustup.md b/.changes/cli.js-rustup.md deleted file mode 100644 index a943c5134502..000000000000 --- a/.changes/cli.js-rustup.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Download `rustup` script on runtime instead of shipping it. diff --git a/.changes/cli.rs-active-toolchain.md b/.changes/cli.rs-active-toolchain.md new file mode 100644 index 000000000000..b39202bcdca3 --- /dev/null +++ b/.changes/cli.rs-active-toolchain.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Add `rustup` version and active rust toolchain to the `info` command output. diff --git a/.changes/cli.rs-build-tools-info.md b/.changes/cli.rs-build-tools-info.md new file mode 100644 index 000000000000..6165773ca2fd --- /dev/null +++ b/.changes/cli.rs-build-tools-info.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Add `Visual Studio Build Tools` installed versions to the `info` command output. diff --git a/.changes/cli.rs-default-svelte-port.md b/.changes/cli.rs-default-svelte-port.md new file mode 100644 index 000000000000..97ba9adb88f6 --- /dev/null +++ b/.changes/cli.rs-default-svelte-port.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +The inferred development server port for Svelte is now `8080` (assumes latest Svelte with `sirv-cli >= 2.0.0`). diff --git a/.changes/cli.rs-detect-git.md b/.changes/cli.rs-detect-git.md new file mode 100644 index 000000000000..d6cde127f145 --- /dev/null +++ b/.changes/cli.rs-detect-git.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Detect if tauri is used from git in the `info` command. diff --git a/.changes/cli.rs-dev-workspaces.md b/.changes/cli.rs-dev-workspaces.md deleted file mode 100644 index 0e84c549df3a..000000000000 --- a/.changes/cli.rs-dev-workspaces.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Watch workspace crates on `dev` command. diff --git a/.changes/cli.rs-dialoguer.md b/.changes/cli.rs-dialoguer.md new file mode 100644 index 000000000000..073e45e828ab --- /dev/null +++ b/.changes/cli.rs-dialoguer.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Drop the `dialoguer` soft fork and use the published version instead. diff --git a/.changes/cli.rs-features-arg.md b/.changes/cli.rs-features-arg.md deleted file mode 100644 index d078b6ba6ae7..000000000000 --- a/.changes/cli.rs-features-arg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Adds `features` argument to the `dev` and `build` commands. diff --git a/.changes/cli.rs-fix-cli.yml-assertion.md b/.changes/cli.rs-fix-cli.yml-assertion.md deleted file mode 100644 index e218de586bb1..000000000000 --- a/.changes/cli.rs-fix-cli.yml-assertion.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Update cli.yml to pass clap ArgSettings::MultipleValues assertion. diff --git a/.changes/cli.rs-fix-windows-x86.md b/.changes/cli.rs-fix-windows-x86.md new file mode 100644 index 000000000000..e4c4833aa1bd --- /dev/null +++ b/.changes/cli.rs-fix-windows-x86.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Fix `build` command when executed on a 32-bit Windows machine when pulling from the `binary-releases` repo. diff --git a/.changes/cli.rs-libwebkit2gtk-4.0-37.md b/.changes/cli.rs-libwebkit2gtk-4.0-37.md deleted file mode 100644 index 6892b1f7b1b9..000000000000 --- a/.changes/cli.rs-libwebkit2gtk-4.0-37.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Fixes the libwebkit2gtk package name. diff --git a/.changes/cli.rs-refactor-signer.md b/.changes/cli.rs-refactor-signer.md new file mode 100644 index 000000000000..fbafd3be5b1b --- /dev/null +++ b/.changes/cli.rs-refactor-signer.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +The `generate` and `sign` commands are now available under a `signer` subcommand. diff --git a/.changes/cli.rs-release-arg.md b/.changes/cli.rs-release-arg.md deleted file mode 100644 index 9fa0060c3967..000000000000 --- a/.changes/cli.rs-release-arg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Adds `release` argument to the `dev` command. Allowing to run the backend in release mode during development. diff --git a/.changes/cli.rs-use-tauri-utils.md b/.changes/cli.rs-use-tauri-utils.md new file mode 100644 index 000000000000..d83665e22d8a --- /dev/null +++ b/.changes/cli.rs-use-tauri-utils.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Use `tauri-utils` to get the `Config` types. diff --git a/.changes/cli.rs-validate-dist-dir.md b/.changes/cli.rs-validate-dist-dir.md new file mode 100644 index 000000000000..cd00837b7834 --- /dev/null +++ b/.changes/cli.rs-validate-dist-dir.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Print warning and exit if `distDir` contains `node_modules`, `src-tauri` or `target` folders. diff --git a/.changes/cli.rs-wix-banner-icon.md b/.changes/cli.rs-wix-banner-icon.md deleted file mode 100644 index 71bafa4d764b..000000000000 --- a/.changes/cli.rs-wix-banner-icon.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Added configuration for the WiX banner icon under `tauri.conf.json > tauri > bundle > windows > wix > bannerPath`. diff --git a/.changes/cli.rs-wix-dialog-image.md b/.changes/cli.rs-wix-dialog-image.md deleted file mode 100644 index b2622d924c54..000000000000 --- a/.changes/cli.rs-wix-dialog-image.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Added configuration for the WiX dialog background bitmap under `tauri.conf.json > tauri > bundle > windows > wix > dialogImagePath`. diff --git a/.changes/cli.rs-wix-license.md b/.changes/cli.rs-wix-license.md new file mode 100644 index 000000000000..25b10f15f9c3 --- /dev/null +++ b/.changes/cli.rs-wix-license.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Fix `tauri build` failing on Windows if `tauri.conf.json > tauri > bundle > Windows > wix > license` is used. diff --git a/.changes/clipboard-api.md b/.changes/clipboard-api.md deleted file mode 100644 index 681ddf14fe36..000000000000 --- a/.changes/clipboard-api.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"api": patch -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `clipboard` APIs (write and read text). diff --git a/.changes/cmd-invoke-binding.md b/.changes/cmd-invoke-binding.md deleted file mode 100644 index 216b66138915..000000000000 --- a/.changes/cmd-invoke-binding.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-macros": patch ---- - -Fixes a name collision when the command function is named `invoke`. diff --git a/.changes/cmd-touch-bindings.md b/.changes/cmd-touch-bindings.md deleted file mode 100644 index 4872790badb5..000000000000 --- a/.changes/cmd-touch-bindings.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-macros": patch ---- - -Fixes a name collision when the command function is named `message` or `resolver`. diff --git a/.changes/command-api-module.md b/.changes/command-api-module.md deleted file mode 100644 index dbb27d1091a3..000000000000 --- a/.changes/command-api-module.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Renamed the `command` API module to `process`. diff --git a/.changes/command-app-handle.md b/.changes/command-app-handle.md deleted file mode 100644 index c6ec27bedb11..000000000000 --- a/.changes/command-app-handle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Allow accessing an `AppHandle` instance on a command through dependency injection. diff --git a/.changes/command-feature-flag.md b/.changes/command-feature-flag.md new file mode 100644 index 000000000000..7868da9f2051 --- /dev/null +++ b/.changes/command-feature-flag.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The `api::process::Command` APIs are now hidden behind the `command` feature flag. \ No newline at end of file diff --git a/.changes/command-generics.md b/.changes/command-generics.md deleted file mode 100644 index 0eeba6879725..000000000000 --- a/.changes/command-generics.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-macros": patch ---- - -`#[command]` now generates a macro instead of a function to allow passing through `Params` and other generics. -`generate_handler!` has been changed to consume the generated `#[command]` macro diff --git a/.changes/command-macros-binding-refactor.md b/.changes/command-macros-binding-refactor.md deleted file mode 100644 index 1d48c96b8288..000000000000 --- a/.changes/command-macros-binding-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-macros": patch ---- - -internal: Refactor all macro code that expects specific bindings to be passed Idents diff --git a/.changes/command-message-blocking.md b/.changes/command-message-blocking.md deleted file mode 100644 index 720060d53aef..000000000000 --- a/.changes/command-message-blocking.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes child processes messages not arriving until the subprocess is terminated. diff --git a/.changes/command-options.md b/.changes/command-options.md deleted file mode 100644 index 1405460d977b..000000000000 --- a/.changes/command-options.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"api": patch -"tauri": patch ---- - -Adds `options` argument to the shell command API (`env` and `cwd` configuration). diff --git a/.changes/command-return.md b/.changes/command-return.md deleted file mode 100644 index 21b918d7451f..000000000000 --- a/.changes/command-return.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-macros": patch ---- - -Improves support for commands returning `Result`. diff --git a/.changes/command-state.md b/.changes/command-state.md deleted file mode 100644 index 9ed0ae453c8c..000000000000 --- a/.changes/command-state.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-macros": patch ---- - -Adds support to command state, triggered when a command argument is `arg: State<'_, StateType>`. diff --git a/.changes/command-status-and-output.md b/.changes/command-status-and-output.md deleted file mode 100644 index 004de55596b2..000000000000 --- a/.changes/command-status-and-output.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `status` and `output` APIs to the `tauri::api::process::Command` struct. diff --git a/.changes/config-mut-getter.md b/.changes/config-mut-getter.md deleted file mode 100644 index 93a24dd5a69c..000000000000 --- a/.changes/config-mut-getter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds a mutable `config` getter on the `Context` struct. diff --git a/.changes/config-package-info-getters.md b/.changes/config-package-info-getters.md deleted file mode 100644 index 26c1dc48e44f..000000000000 --- a/.changes/config-package-info-getters.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `config` and `package_info` getters to the `App` and `AppHandle` structs. diff --git a/.changes/config.json b/.changes/config.json index df24db02df71..b041d2c995bf 100644 --- a/.changes/config.json +++ b/.changes/config.json @@ -3,7 +3,7 @@ "timeout": 3600000, "pkgManagers": { "rust": { - "errorOnVersionRange": "1.0.0-beta.100 - 99.x || ^1.1.0-0 || ^2.0.0-0", + "errorOnVersionRange": "1.0.0-rc.100 - 99.x || ^1.1.0-0 || ^2.0.0-0", "version": true, "getPublishedVersion": "cargo search ${ pkgFile.pkg.package.name } --limit 1 | sed -nE \"s/^[^\\\"]*\\\"//; s/\\\".*//1p\"", "prepublish": [ @@ -78,7 +78,7 @@ ] }, "javascript": { - "errorOnVersionRange": "1.0.0-beta-rc.100 - 99.x || ^1.1.0-0 || ^2.0.0-0", + "errorOnVersionRange": "1.0.0-rc.100 - 99.x || ^1.1.0-0 || ^2.0.0-0", "version": true, "getPublishedVersion": "npm view ${ pkgFile.pkg.name } version", "prepublish": [ @@ -208,7 +208,10 @@ }, "tauri-bundler": { "path": "./tooling/bundler", - "manager": "rust" + "manager": "rust", + "dependencies": [ + "tauri-utils" + ] }, "tauri-utils": { "path": "./core/tauri-utils", @@ -217,30 +220,43 @@ "tauri-runtime": { "path": "./core/tauri-runtime", "manager": "rust", - "dependencies": ["tauri-utils"], - "postversion": "node ../../.scripts/sync-prerelease.js ${ pkg.pkg } ${ release.type }" + "dependencies": [ + "tauri-utils" + ], + "postversion": "node ../../.scripts/covector/sync-prerelease.js ${ pkg.pkg } ${ release.type }" }, "tauri-runtime-wry": { "path": "./core/tauri-runtime-wry", "manager": "rust", - "dependencies": ["tauri-utils", "tauri-runtime"], - "postversion": "node ../../.scripts/sync-prerelease.js ${ pkg.pkg } ${ release.type }" + "dependencies": [ + "tauri-utils", + "tauri-runtime" + ], + "postversion": "node ../../.scripts/covector/sync-prerelease.js ${ pkg.pkg } ${ release.type }" }, "tauri-codegen": { "path": "./core/tauri-codegen", "manager": "rust", - "dependencies": ["tauri-utils"] + "dependencies": [ + "tauri-utils" + ] }, "tauri-macros": { "path": "./core/tauri-macros", "manager": "rust", - "dependencies": ["tauri-codegen"] + "dependencies": [ + "tauri-codegen", + "tauri-utils" + ] }, "tauri-build": { "path": "./core/tauri-build", "manager": "rust", - "dependencies": ["tauri-codegen", "tauri-utils"], - "postversion": "node ../../.scripts/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }" + "dependencies": [ + "tauri-codegen", + "tauri-utils" + ], + "postversion": "node ../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }" }, "tauri": { "path": "./core/tauri", @@ -251,24 +267,26 @@ "tauri-runtime", "tauri-runtime-wry" ], - "postversion": "node ../../.scripts/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }" + "postversion": "node ../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }" }, "cli.js": { - "path": "./tooling/cli.js", + "path": "./tooling/cli/node", "manager": "javascript", - "dependencies": ["cli.rs"], - "postversion": "node ../../.scripts/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }", - "assets": [ - { - "path": "./tooling/cli.js/tauri-apps-cli-${ pkgFile.version }.tgz", - "name": "cli.js-${ pkgFile.version }.tgz" - } - ] + "dependencies": [ + "cli.rs" + ], + "postversion": "node ../../.scripts/covector/sync-cli-metadata.js ${ pkg.pkg } ${ release.type }", + "prepublish": [], + "publish": [], + "postpublish": [] }, "cli.rs": { - "path": "./tooling/cli.rs", + "path": "./tooling/cli", "manager": "rust", - "dependencies": ["tauri-bundler"], + "dependencies": [ + "tauri-bundler", + "tauri-utils" + ], "postversion": "cargo check" }, "create-tauri-app": { @@ -278,7 +296,7 @@ "tauri-driver": { "path": "./tooling/webdriver", "manager": "rust", - "postversion": "node ../../.scripts/sync-prerelease.js ${ pkg.pkg } ${ release.type }" + "postversion": "node ../../.scripts/covector/sync-prerelease.js ${ pkg.pkg } ${ release.type }" } } -} +} \ No newline at end of file diff --git a/.changes/consistent-event-name-usage.md b/.changes/consistent-event-name-usage.md new file mode 100644 index 000000000000..907fd3bdfad4 --- /dev/null +++ b/.changes/consistent-event-name-usage.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Change the `event` field of the `Event` interface to type `EventName` instead of `string`. \ No newline at end of file diff --git a/.changes/context-mutable-methods.md b/.changes/context-mutable-methods.md deleted file mode 100644 index 53a0d21328ed..000000000000 --- a/.changes/context-mutable-methods.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"tauri": patch ---- - -Expose mutable getters for the rest of the public `Context` getters. -* `pub fn assets_mut(&mut self) -> &mut Arc` -* `pub fn default_window_icon_mut(&mut self) -> &mut Option>` -* `pub fn system_tray_icon_mut(&mut self) -> &mut Option` -* `pub fn package_info_mut(&mut self) -> &mut tauri::api::PackageInfo` diff --git a/.changes/core-add-log-dir.md b/.changes/core-add-log-dir.md new file mode 100644 index 000000000000..c694620382bd --- /dev/null +++ b/.changes/core-add-log-dir.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Add `tauri::api::path::log_dir` function to access the sugested log directory path. diff --git a/.changes/core-asset-fallback.md b/.changes/core-asset-fallback.md deleted file mode 100644 index 2a3da7765f53..000000000000 --- a/.changes/core-asset-fallback.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Assets will now fallback to `/index.html` before `/index.html`, allowing anchor links to work as expected. diff --git a/.changes/core-center-window.md b/.changes/core-center-window.md new file mode 100644 index 000000000000..4b9653be87fe --- /dev/null +++ b/.changes/core-center-window.md @@ -0,0 +1,5 @@ +--- +"tauri-runtime-wry": patch +--- + +Fix `window.center` panic when window size is bigger than screen size. diff --git a/.changes/core-drag-region-resizable.md b/.changes/core-drag-region-resizable.md deleted file mode 100644 index 423b9a6896b9..000000000000 --- a/.changes/core-drag-region-resizable.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fix `data-tauri-drag-region` double-click, will now respect `resizable: false` and won't maximize. diff --git a/.changes/core-env.md b/.changes/core-env.md new file mode 100644 index 000000000000..328d91833c75 --- /dev/null +++ b/.changes/core-env.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The `process`, `path` and `updater` APIs now takes a `tauri::Env` argument, used to force environment variables load on startup to prevent env var update attacks. diff --git a/.changes/core-features.md b/.changes/core-features.md deleted file mode 100644 index 7ce2353e4195..000000000000 --- a/.changes/core-features.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Properly keep all `tauri` features that are not managed by the CLI. diff --git a/.changes/core-notification-typo.md b/.changes/core-notification-typo.md deleted file mode 100644 index 45a49dd81a1f..000000000000 --- a/.changes/core-notification-typo.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fix `Notification.requestPermission()` throwing `Unhandled Promise Rejection: TypeError: undefined is not a function (near '...window.__TAURI__.invoke...')` diff --git a/.changes/core-path-endpoint-path-doesnt-exist-error.md b/.changes/core-path-endpoint-path-doesnt-exist-error.md new file mode 100644 index 000000000000..2a2d24bd0cc0 --- /dev/null +++ b/.changes/core-path-endpoint-path-doesnt-exist-error.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"api": patch +--- + +Now `resolve()`, `join()` and `normalize()` from the `path` module, won't throw errors if the path doesn't exist, which matches NodeJS behavior. diff --git a/.changes/core-request-user-attention.md b/.changes/core-request-user-attention.md deleted file mode 100644 index 5fdc2a64b7ba..000000000000 --- a/.changes/core-request-user-attention.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `request_user_attention` API to the `Window` struct. diff --git a/.changes/core-show-hide-menu.md b/.changes/core-show-hide-menu.md deleted file mode 100644 index bd3c98775546..000000000000 --- a/.changes/core-show-hide-menu.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `show`, `hide`, `is_visible` and `toggle` APIs to the `MenuHandle`. diff --git a/.changes/core-webview-events.md b/.changes/core-webview-events.md deleted file mode 100644 index fd3e26a92ffc..000000000000 --- a/.changes/core-webview-events.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Fix blur/focus events being incorrect on Windows. diff --git a/.changes/create-window-refactor.md b/.changes/create-window-refactor.md deleted file mode 100644 index 28102ada34f2..000000000000 --- a/.changes/create-window-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -The `create_window` API callback now takes two arguments: the `WindowBuilder` and the `WebviewAttributes` and must return a tuple containing both values. diff --git a/.changes/create-window-return-window.md b/.changes/create-window-return-window.md new file mode 100644 index 000000000000..73e224c633b1 --- /dev/null +++ b/.changes/create-window-return-window.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +**Breaking change:** Return `Window` on `App` and `AppHandle`'s `create_window` function. diff --git a/.changes/csp-nonces.md b/.changes/csp-nonces.md new file mode 100644 index 000000000000..4762aeeea201 --- /dev/null +++ b/.changes/csp-nonces.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +"tauri-codegen": patch +"tauri-utils": patch +--- + +Apply `nonce` to `script` and `style` tags and set them on the `CSP` (`script-src` and `style-src` fetch directives). diff --git a/.changes/csp-self.md b/.changes/csp-self.md deleted file mode 100644 index cba1c072a034..000000000000 --- a/.changes/csp-self.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Add `'self'` to default CSP because otherwise no joy on macOS. diff --git a/.changes/csp.md b/.changes/csp.md deleted file mode 100644 index ec79a527dd74..000000000000 --- a/.changes/csp.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri-codegen": patch -"tauri-utils": patch -"tauri": patch ---- - -Reintroduce `csp` injection, configured on `tauri.conf.json > tauri > security > csp`. diff --git a/.changes/cta-add-empty-description-for-rust-dominator.md b/.changes/cta-add-empty-description-for-rust-dominator.md new file mode 100644 index 000000000000..8de51d27359e --- /dev/null +++ b/.changes/cta-add-empty-description-for-rust-dominator.md @@ -0,0 +1,5 @@ +--- +"create-tauri-app": patch +--- + +Add empty description to Cargo.toml in dominator recipe. \ No newline at end of file diff --git a/.changes/cta-added-angular-cli.md b/.changes/cta-added-angular-cli.md deleted file mode 100644 index e4787aa4341a..000000000000 --- a/.changes/cta-added-angular-cli.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Added Angular CLI recipe. \ No newline at end of file diff --git a/.changes/cta-ci-compatible.md b/.changes/cta-ci-compatible.md new file mode 100644 index 000000000000..71c4e8dcb85f --- /dev/null +++ b/.changes/cta-ci-compatible.md @@ -0,0 +1,5 @@ +--- +"create-tauri-app": patch +--- + +`create-tauri-app` should now be fully compatiable with CI environments. diff --git a/.changes/cta-explicitly-install-vite.md b/.changes/cta-explicitly-install-vite.md deleted file mode 100644 index 722f6951fb01..000000000000 --- a/.changes/cta-explicitly-install-vite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Explicitly install deps after a vite recipe. diff --git a/.changes/cta-pnpm-support.md b/.changes/cta-pnpm-support.md deleted file mode 100644 index 287192e868a4..000000000000 --- a/.changes/cta-pnpm-support.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -[`pnpm`](https://pnpm.io) package manager is now officially supported, either run `pnpx create-tauri-app` or explicitly specifiy it `npx create-tauri-app --manager pnpm`. diff --git a/.changes/cta-prompt-api.md b/.changes/cta-prompt-api.md deleted file mode 100644 index 9d1d44bb72fc..000000000000 --- a/.changes/cta-prompt-api.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -`create-tauri-app` will prompt users to install `@tauri-apps/api` npm package. diff --git a/.changes/cta-react-disable-open-browser.md b/.changes/cta-react-disable-open-browser.md new file mode 100644 index 000000000000..9103cf6fa25a --- /dev/null +++ b/.changes/cta-react-disable-open-browser.md @@ -0,0 +1,5 @@ +--- +"create-tauri-app": patch +--- + +Stop react recipe from opening in browser by default. diff --git a/.changes/cta-shift-and-type.md b/.changes/cta-shift-and-type.md deleted file mode 100644 index c9ca82e8d458..000000000000 --- a/.changes/cta-shift-and-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Shift everything out of the `bin` and into `.ts` so we can apply Typescript types. diff --git a/.changes/cta-solid-recipe.md b/.changes/cta-solid-recipe.md new file mode 100644 index 000000000000..6dccde7d79c9 --- /dev/null +++ b/.changes/cta-solid-recipe.md @@ -0,0 +1,5 @@ +--- +'create-tauri-app': patch +--- + +Add SolidJS recipe using the official template. diff --git a/.changes/cta-svelte-recipe.md b/.changes/cta-svelte-recipe.md deleted file mode 100644 index f0fd464c92cb..000000000000 --- a/.changes/cta-svelte-recipe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Add Svelte recipe using the official template. \ No newline at end of file diff --git a/.changes/cta-test-script.md b/.changes/cta-test-script.md deleted file mode 100644 index 6d952cc5f024..000000000000 --- a/.changes/cta-test-script.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"create-tauri-app": patch -"cli.js": patch ---- - -Adjust check for `dev` mode and switch CTA test to a script runner. The script gives us more control and better output into any failures. diff --git a/.changes/cta-testing-suite.md b/.changes/cta-testing-suite.md deleted file mode 100644 index 7f77533b3a05..000000000000 --- a/.changes/cta-testing-suite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -We setup an e2e type test suite for CTA. It is mostly an internal change, but should help with stability moving forward. diff --git a/.changes/cta-update-vite-package.md b/.changes/cta-update-vite-package.md deleted file mode 100644 index 05597ba317e8..000000000000 --- a/.changes/cta-update-vite-package.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Update vite recipe to use the new vite npm [package](https://github.com/vitejs/vite/tree/main/packages/create-vite). diff --git a/.changes/cta-vite-before-dev.md b/.changes/cta-vite-before-dev.md deleted file mode 100644 index cf3d317daabd..000000000000 --- a/.changes/cta-vite-before-dev.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Fixes the `beforeDevCommand` on vite recipe. diff --git a/.changes/cta-vite-esbuild-install-direct.md b/.changes/cta-vite-esbuild-install-direct.md deleted file mode 100644 index 01c9dd5923ab..000000000000 --- a/.changes/cta-vite-esbuild-install-direct.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Work around bugs between esbuild and npm by installing directly at the end of the sequence. Also default to using the latest on all of the installs instead of npx's cache. diff --git a/.changes/cta-vite-templates.md b/.changes/cta-vite-templates.md deleted file mode 100644 index 955a162a1902..000000000000 --- a/.changes/cta-vite-templates.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Add support for all vite templates diff --git a/.changes/cta-welcome-prompt-and-links.md b/.changes/cta-welcome-prompt-and-links.md deleted file mode 100644 index 4b36854b8eef..000000000000 --- a/.changes/cta-welcome-prompt-and-links.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"create-tauri-app": patch ---- - -Add a welcome prompt to let the user know about the process and links to more info including prerequisite setup steps. Also add links to each of the templates to give the user more context what they are getting into. diff --git a/.changes/current-binary-caching.md b/.changes/current-binary-caching.md new file mode 100644 index 000000000000..c404d6ac9fc5 --- /dev/null +++ b/.changes/current-binary-caching.md @@ -0,0 +1,6 @@ +--- +tauri: patch +tauri-utils: patch +--- + +The path returned from `tauri::api::process::current_binary` is now cached when loading the binary. diff --git a/.changes/custom-invoke-system.md b/.changes/custom-invoke-system.md new file mode 100644 index 000000000000..66396453907d --- /dev/null +++ b/.changes/custom-invoke-system.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Added an API to use a custom invoke system to receive and respond to commands (`Builder#invoke_system`). diff --git a/.changes/data-url-csp.md b/.changes/data-url-csp.md new file mode 100644 index 000000000000..461446cd39e3 --- /dev/null +++ b/.changes/data-url-csp.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Inject configured `CSP` on `data:` URLs. diff --git a/.changes/dblclick-tauri-drag-maximize.md b/.changes/dblclick-tauri-drag-maximize.md deleted file mode 100644 index 785f18d426d1..000000000000 --- a/.changes/dblclick-tauri-drag-maximize.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -"tauri": patch ---- -Double clicking a `data-tauri-drag-region` element will toggle the window maximized state. diff --git a/.changes/debian-depends.md b/.changes/debian-depends.md deleted file mode 100644 index 342b81e5f836..000000000000 --- a/.changes/debian-depends.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Automatically add Tauri dependencies to the debian package `Depends` section. diff --git a/.changes/default-params-type.md b/.changes/default-params-type.md deleted file mode 100644 index e574da383296..000000000000 --- a/.changes/default-params-type.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch ---- - -Adds the default types used with `Builder::default()` to items that expose `Params` in their type. This allows you to -skip specifying a generic parameter to types like `Window

` if you use the default type. diff --git a/.changes/dev-copy-resources.md b/.changes/dev-copy-resources.md deleted file mode 100644 index 461c095c7a98..000000000000 --- a/.changes/dev-copy-resources.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Copy resources and binaries to `OUT_DIR` on `tauri dev` command. diff --git a/.changes/dev-csp.md b/.changes/dev-csp.md new file mode 100644 index 000000000000..ce9f40968998 --- /dev/null +++ b/.changes/dev-csp.md @@ -0,0 +1,6 @@ +--- +"tauri-utils": patch +"cli.rs": patch +--- + +Added `dev_csp` to the `security` configuration object. diff --git a/.changes/dev-path-dist-dir-array.md b/.changes/dev-path-dist-dir-array.md deleted file mode 100644 index 1ad11730a008..000000000000 --- a/.changes/dev-path-dist-dir-array.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-codegen": patch -"tauri-utils": patch ---- - -Allow `dev_path` and `dist_dir` to be an array of root files and directories to embed. diff --git a/.changes/dev-path-dist-dir-validation.md b/.changes/dev-path-dist-dir-validation.md deleted file mode 100644 index 648ec4b65021..000000000000 --- a/.changes/dev-path-dist-dir-validation.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-utils": patch -"tauri-codegen": patch ---- - -Validate `tauri.conf.json > build > devPath` and `tauri.conf.json > build > distDir` values. diff --git a/.changes/dev-server-exit.md b/.changes/dev-server-exit.md new file mode 100644 index 000000000000..6e92eaea9263 --- /dev/null +++ b/.changes/dev-server-exit.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Kill process if `beforeDevCommand` exits with a non-zero status code. diff --git a/.changes/dialog-ask-message-parent.md b/.changes/dialog-ask-message-parent.md deleted file mode 100644 index 2e02eb4f1571..000000000000 --- a/.changes/dialog-ask-message-parent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -**Breaking change:** Added `window_parent: Option<&Window>` as first argument to the `ask` and `message` APIs on the `tauri::api::dialog` module. diff --git a/.changes/dialog-parent.md b/.changes/dialog-parent.md deleted file mode 100644 index 78117dc24db6..000000000000 --- a/.changes/dialog-parent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Set the Tauri window as parent for dialogs. diff --git a/.changes/dialog-thread-handling.md b/.changes/dialog-thread-handling.md deleted file mode 100644 index f3727360b888..000000000000 --- a/.changes/dialog-thread-handling.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch ---- - -Allow the `tauri::api::dialog` APIs to be executed on any secondary thread. -**Breaking change:** All dialog APIs now takes a closure instead of returning the response on the function call. diff --git a/.changes/dmg-bundle-fixes.md b/.changes/dmg-bundle-fixes.md deleted file mode 100644 index 43b908237b58..000000000000 --- a/.changes/dmg-bundle-fixes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Pull latest changes from `create-dmg`, fixing unmount issue. diff --git a/.changes/doc-tauri-utils.md b/.changes/doc-tauri-utils.md deleted file mode 100644 index 73d4c438c114..000000000000 --- a/.changes/doc-tauri-utils.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": minor ---- - -Move items which `tauri::api` re-exports from `tauri-utils` to individual module `utils`. Because these items has their -own Error/Result types which are not related to api module at all. - diff --git a/.changes/drag-and-drop-config.md b/.changes/drag-and-drop-config.md deleted file mode 100644 index 572893fef739..000000000000 --- a/.changes/drag-and-drop-config.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-utils": patch ---- - -Adds `file_drop_enabled` flag on `WindowConfig`. diff --git a/.changes/drag-region-refactor.md b/.changes/drag-region-refactor.md deleted file mode 100644 index a8a1027f88df..000000000000 --- a/.changes/drag-region-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Change draggable region element detection from `drag-region` class to `data-tauri-drag-region` attribute. diff --git a/.changes/drag-window-api.md b/.changes/drag-window-api.md deleted file mode 100644 index 1e0d5ad39c81..000000000000 --- a/.changes/drag-window-api.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Adds `startDragging` API on the window module. diff --git a/.changes/dynamic-plugin.md b/.changes/dynamic-plugin.md deleted file mode 100644 index f93c708633fe..000000000000 --- a/.changes/dynamic-plugin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Allow registering a plugin through an `AppHandle` instance using the `plugin` method. diff --git a/.changes/embed-plist.md b/.changes/embed-plist.md deleted file mode 100644 index 4939235333b6..000000000000 --- a/.changes/embed-plist.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-codegen": patch -"tauri": patch ---- - -Embed Info.plist file contents on binary on dev. diff --git a/.changes/emit-and-trigger-tauri-events.md b/.changes/emit-and-trigger-tauri-events.md new file mode 100644 index 000000000000..1e925fe0311a --- /dev/null +++ b/.changes/emit-and-trigger-tauri-events.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Emit `tauri://*` events to Rust listeners. diff --git a/.changes/emit-window-created-backend.md b/.changes/emit-window-created-backend.md new file mode 100644 index 000000000000..f03e855d8bd7 --- /dev/null +++ b/.changes/emit-window-created-backend.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Emit `tauri://window-created` event for windows created on the backend. diff --git a/.changes/emit-window-events.md b/.changes/emit-window-events.md deleted file mode 100644 index 948c4b81e10d..000000000000 --- a/.changes/emit-window-events.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Emit `tauri://resize`, `tauri://move`, `tauri://close-requested`, `tauri://destroyed`, `tauri://focus`, `tauri://blur` and `tauri://scale-change` events to the window. diff --git a/.changes/enable-linux-cookie-persistence.md b/.changes/enable-linux-cookie-persistence.md new file mode 100644 index 000000000000..0a51cdc1108c --- /dev/null +++ b/.changes/enable-linux-cookie-persistence.md @@ -0,0 +1,6 @@ +--- +"tauri": "patch" +"tauri-runtime-wry": patch +--- + +Enable non-session cookie persistence on Linux. diff --git a/.changes/event-refactor.md b/.changes/event-refactor.md deleted file mode 100644 index c950f5114e6d..000000000000 --- a/.changes/event-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -The event `emit` function payload type is now `impl Serialize` instead of `Option`. diff --git a/.changes/exit-requested-event.md b/.changes/exit-requested-event.md deleted file mode 100644 index c8cea2d5e82e..000000000000 --- a/.changes/exit-requested-event.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Add `ExitRequested` event that allows preventing the app from exiting when all windows are closed, and an `AppHandle.exit()` function to exit the app manually. diff --git a/.changes/expose-escape-json-string.md b/.changes/expose-escape-json-string.md new file mode 100644 index 000000000000..792d69a8ff45 --- /dev/null +++ b/.changes/expose-escape-json-string.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Expose `tauri::api::ipc::{serialize_js_with, serialize_js}` functions. diff --git a/.changes/features-support.md b/.changes/features-support.md deleted file mode 100644 index c891bb3d05ea..000000000000 --- a/.changes/features-support.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Read cargo features from `tauri.conf.json > build > features` and propagate them on `dev` and `build`. diff --git a/.changes/fix-asset-loading-vue-router.md b/.changes/fix-asset-loading-vue-router.md deleted file mode 100644 index c59c745d2457..000000000000 --- a/.changes/fix-asset-loading-vue-router.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fallback to `index.html` on asset loading so router with history mode works. diff --git a/.changes/fix-asset-loading.md b/.changes/fix-asset-loading.md deleted file mode 100644 index ff5a486aca9d..000000000000 --- a/.changes/fix-asset-loading.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes custom protocol asset loader not decoding the percent-encoded path. diff --git a/.changes/fix-asset-protocol-panicking.md b/.changes/fix-asset-protocol-panicking.md new file mode 100644 index 000000000000..332a9861ed5e --- /dev/null +++ b/.changes/fix-asset-protocol-panicking.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Resolve `asset` protocol HTTP request instead of panicking if the file does not exist or cannot be read. diff --git a/.changes/fix-attribute-drag-region.md b/.changes/fix-attribute-drag-region.md deleted file mode 100644 index 50f840b8a43c..000000000000 --- a/.changes/fix-attribute-drag-region.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -As some frameworks automatically add "true" as the value of the attribute, we need to check if it exists instead. diff --git a/.changes/fix-before-dev-command-kill.md b/.changes/fix-before-dev-command-kill.md deleted file mode 100644 index bd1b8ce4f4ff..000000000000 --- a/.changes/fix-before-dev-command-kill.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Properly kill `beforeDevCommand` process. diff --git a/.changes/fix-block-on-runtime.md b/.changes/fix-block-on-runtime.md new file mode 100644 index 000000000000..44ef3ba2d7a3 --- /dev/null +++ b/.changes/fix-block-on-runtime.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Avoid `async_runtime::block_on` panics when used along another tokio runtime. diff --git a/.changes/fix-bundle-targets-config.md b/.changes/fix-bundle-targets-config.md deleted file mode 100644 index 1db217ff5907..000000000000 --- a/.changes/fix-bundle-targets-config.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Fixes `tauri.conf.json > tauri > bundle > targets` not applying to the bundler. diff --git a/.changes/fix-bundler-platform-detection.md b/.changes/fix-bundler-platform-detection.md deleted file mode 100644 index 3bd6dc577bad..000000000000 --- a/.changes/fix-bundler-platform-detection.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"cli.rs": patch -"tauri-bundler": patch ---- - -Properly detect target platform's architecture. diff --git a/.changes/fix-cli-target-set.md b/.changes/fix-cli-target-set.md deleted file mode 100644 index 21d9de851d38..000000000000 --- a/.changes/fix-cli-target-set.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Fixes `build` command when the `target` arg is set. diff --git a/.changes/fix-cli.rs-bundle-arg.md b/.changes/fix-cli.rs-bundle-arg.md deleted file mode 100644 index b61cc1c12caf..000000000000 --- a/.changes/fix-cli.rs-bundle-arg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": minor ---- - -Fix a typo that would result in bundle arg being ignored. diff --git a/.changes/fix-close-requested-js-event.md b/.changes/fix-close-requested-js-event.md new file mode 100644 index 000000000000..cfc1519a9a51 --- /dev/null +++ b/.changes/fix-close-requested-js-event.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Prevent window closing if `tauri://close-requested` is listened on the JS layer. Users must call `appWindow.close()` manually when listening to that event. diff --git a/.changes/fix-command-event-channel.md b/.changes/fix-command-event-channel.md deleted file mode 100644 index 54710cd568a3..000000000000 --- a/.changes/fix-command-event-channel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes `api::process::Command` events not firing consistently. diff --git a/.changes/fix-command-named-cmd.md b/.changes/fix-command-named-cmd.md deleted file mode 100644 index 59e50df90113..000000000000 --- a/.changes/fix-command-named-cmd.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-macros": patch ---- - -Fixes a name collision when the command function is named `cmd`. diff --git a/.changes/fix-create-window-str.md b/.changes/fix-create-window-str.md deleted file mode 100644 index f5dbf5946c3d..000000000000 --- a/.changes/fix-create-window-str.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Change `App.create_window()` and `AppHandle.create_window()` to accept an `Into` type instead of `String`. diff --git a/.changes/fix-custom-protocol.md b/.changes/fix-custom-protocol.md deleted file mode 100644 index 2d31f7f2503c..000000000000 --- a/.changes/fix-custom-protocol.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes `asset` protocol crashing application. diff --git a/.changes/fix-data-tauri-drag-region.md b/.changes/fix-data-tauri-drag-region.md deleted file mode 100644 index 944bd5561277..000000000000 --- a/.changes/fix-data-tauri-drag-region.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes `data-tauri-drag-region` not firing its events. diff --git a/.changes/fix-deadlock-create-window-from-menu.md b/.changes/fix-deadlock-create-window-from-menu.md new file mode 100644 index 000000000000..6ac2fb83515b --- /dev/null +++ b/.changes/fix-deadlock-create-window-from-menu.md @@ -0,0 +1,7 @@ +--- +"tauri-runtime-wry": patch +"tauri": patch +--- + +Fixes a deadlock when creating a window from a menu event handler. + \ No newline at end of file diff --git a/.changes/fix-deadlock-path-iter.md b/.changes/fix-deadlock-path-iter.md new file mode 100644 index 000000000000..3aa9c8a92fa1 --- /dev/null +++ b/.changes/fix-deadlock-path-iter.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": patch +--- + +Fixes a deadlock on the `ResourcePaths` iterator. diff --git a/.changes/fix-dialog-allowlist..md b/.changes/fix-dialog-allowlist..md deleted file mode 100644 index 46cd20bf3514..000000000000 --- a/.changes/fix-dialog-allowlist..md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes build without the dialog Cargo features. diff --git a/.changes/fix-dialog-default-path.md b/.changes/fix-dialog-default-path.md new file mode 100644 index 000000000000..1aefe3f2c320 --- /dev/null +++ b/.changes/fix-dialog-default-path.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"api": patch +--- + +Fixes the dialog `defaultPath` usage on Linux. diff --git a/.changes/fix-dialog-save-default-path-linux.md b/.changes/fix-dialog-save-default-path-linux.md deleted file mode 100644 index 376aae0971cd..000000000000 --- a/.changes/fix-dialog-save-default-path-linux.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes `defaultPath` option on dialog API not setting the file name if it doesn't exist on Linux. diff --git a/.changes/fix-dmg-volume-icon.md b/.changes/fix-dmg-volume-icon.md deleted file mode 100644 index aae9bb286ef1..000000000000 --- a/.changes/fix-dmg-volume-icon.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Fixes DMG volume icon. diff --git a/.changes/fix-drag-and-drop.md b/.changes/fix-drag-and-drop.md deleted file mode 100644 index 6468b1918a01..000000000000 --- a/.changes/fix-drag-and-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Allow disabling the webview file drop handler (required to use drag and drop on the frontend on Windows) using the `tauri.conf.json > tauri > windows > fileDropEnabled` flag or the `WebviewAttributes#disable_file_drop_handler` method. diff --git a/.changes/fix-esm-detection.md b/.changes/fix-esm-detection.md deleted file mode 100644 index 9bd6c327f3a4..000000000000 --- a/.changes/fix-esm-detection.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-codegen": patch ---- - -Fix ES Module detection for default imports with relative paths or scoped packages and exporting of async functions. diff --git a/.changes/fix-event-queue.md b/.changes/fix-event-queue.md deleted file mode 100644 index 9ac753a29c5c..000000000000 --- a/.changes/fix-event-queue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fix `listen` calls receiving past events. diff --git a/.changes/fix-file-drop-events.md b/.changes/fix-file-drop-events.md deleted file mode 100644 index 0ece0fa1e422..000000000000 --- a/.changes/fix-file-drop-events.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"api": patch ---- - -Fixes file drop events being swapped (`file-drop-hover` on drop and `file-drop` on hover). \ No newline at end of file diff --git a/.changes/fix-focus-blur-events-wry.md b/.changes/fix-focus-blur-events-wry.md new file mode 100644 index 000000000000..a853b593cef4 --- /dev/null +++ b/.changes/fix-focus-blur-events-wry.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime-wry": patch +"tauri": patch +--- + +Fixes `WindowEvent::Focus` and `WindowEvent::Blur` events not firing. diff --git a/.changes/fix-focus-blur-events.md b/.changes/fix-focus-blur-events.md new file mode 100644 index 000000000000..1d14f5c961d4 --- /dev/null +++ b/.changes/fix-focus-blur-events.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Fixes `tauri://focus` and `tauri://blur` events not firing. diff --git a/.changes/fix-global-tauri.md b/.changes/fix-global-tauri.md deleted file mode 100644 index a48b59744eaa..000000000000 --- a/.changes/fix-global-tauri.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Fixes the global bundle UMD code. diff --git a/.changes/fix-http-binary-response.md b/.changes/fix-http-binary-response.md deleted file mode 100644 index 8339bc1f20e4..000000000000 --- a/.changes/fix-http-binary-response.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes the HTTP API binary response serialization. diff --git a/.changes/fix-http-resolve-error.md b/.changes/fix-http-resolve-error.md deleted file mode 100644 index 964a33723035..000000000000 --- a/.changes/fix-http-resolve-error.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"api": patch ---- - -The `http` APIs now resolve the returned promise when the API call finishes with an error status code. diff --git a/.changes/fix-inner-size.md b/.changes/fix-inner-size.md new file mode 100644 index 000000000000..989445b6c8ed --- /dev/null +++ b/.changes/fix-inner-size.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-runtime-wry": patch +--- + +Use webview's inner_size instead of window's value to get the correct size on macOS. diff --git a/.changes/fix-javascript-iife-esm-rewrite.md b/.changes/fix-javascript-iife-esm-rewrite.md deleted file mode 100644 index cfa0450ffef1..000000000000 --- a/.changes/fix-javascript-iife-esm-rewrite.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-codegen": patch ---- - -Detect ESM scripts and inject the invoke key directly instead of using an IIFE. diff --git a/.changes/fix-linux-resource-path.md b/.changes/fix-linux-resource-path.md new file mode 100644 index 000000000000..7b684afd5c08 --- /dev/null +++ b/.changes/fix-linux-resource-path.md @@ -0,0 +1,6 @@ +--- +"tauri-utils": patch +"tauri": patch +--- + +Fixes resource directory resolution on Linux. diff --git a/.changes/fix-listen_global-not-getting-events.md b/.changes/fix-listen_global-not-getting-events.md deleted file mode 100644 index d1d67117444e..000000000000 --- a/.changes/fix-listen_global-not-getting-events.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes `app.listen_global` not receiving events emitted in javascript. \ No newline at end of file diff --git a/.changes/fix-macos-updater.md b/.changes/fix-macos-updater.md deleted file mode 100644 index 50fa6397c8e6..000000000000 --- a/.changes/fix-macos-updater.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fix macOS `EXC_BAD_ACCESS` panic when app is code-signed. diff --git a/.changes/fix-menu-ids.md b/.changes/fix-menu-ids.md new file mode 100644 index 000000000000..6b87270a0bd3 --- /dev/null +++ b/.changes/fix-menu-ids.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Fixes the menu id mapping not reflecting the current window. diff --git a/.changes/fix-min-height-typo.md b/.changes/fix-min-height-typo.md deleted file mode 100644 index 00343c9fce52..000000000000 --- a/.changes/fix-min-height-typo.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri-utils": patch -"tauri-runtime": patch -"tauri": patch ---- - -Fixes minimum window height being used as maximum height. diff --git a/.changes/fix-monitor-api.md b/.changes/fix-monitor-api.md deleted file mode 100644 index 978757558502..000000000000 --- a/.changes/fix-monitor-api.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"api": patch ---- - -- Fixes monitor api not working. -- Fixes window.print() not working on macOS. diff --git a/.changes/fix-notifications-on-windows.md b/.changes/fix-notifications-on-windows.md deleted file mode 100644 index 3d875648dd52..000000000000 --- a/.changes/fix-notifications-on-windows.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Run the `notification.show()` method on a dedicated async task to prevent a panic on Windows. diff --git a/.changes/fix-once-fnonce.md b/.changes/fix-once-fnonce.md new file mode 100644 index 000000000000..fd167c1d4f75 --- /dev/null +++ b/.changes/fix-once-fnonce.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +`Manager::once_global` and `Window::once` allow `FnOnce` callbacks. diff --git a/.changes/fix-out-dir-detection.md b/.changes/fix-out-dir-detection.md new file mode 100644 index 000000000000..4d58c009ae21 --- /dev/null +++ b/.changes/fix-out-dir-detection.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Fixes output directory detection when using Cargo workspaces. diff --git a/.changes/fix-ready-check.md b/.changes/fix-ready-check.md new file mode 100644 index 000000000000..02ddcf78d151 --- /dev/null +++ b/.changes/fix-ready-check.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Properly check if document is loaded before invoking commands. diff --git a/.changes/fix-reqwest-headers.md b/.changes/fix-reqwest-headers.md deleted file mode 100644 index 8bbe3bb762b3..000000000000 --- a/.changes/fix-reqwest-headers.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes HTTP API headers being overwritten when using the `reqwest` client. diff --git a/.changes/fix-svg-mime-type.md b/.changes/fix-svg-mime-type.md deleted file mode 100644 index 4f29c44e08f9..000000000000 --- a/.changes/fix-svg-mime-type.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime-wry": patch -"tauri": patch ---- - -Fixes SVG loading on custom protocol. diff --git a/.changes/fix-tray-command.md b/.changes/fix-tray-command.md new file mode 100644 index 000000000000..6de01cedc5b2 --- /dev/null +++ b/.changes/fix-tray-command.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Initialize system tray before windows so `tray_handle` can be accessed on command handlers. diff --git a/.changes/fix-tray-remove-windows.md b/.changes/fix-tray-remove-windows.md new file mode 100644 index 000000000000..ab347c29c5df --- /dev/null +++ b/.changes/fix-tray-remove-windows.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-runtime-wry": patch +--- + +Reimplement `remove_system_tray` on Windows to drop the `SystemTray` to run its cleanup code. diff --git a/.changes/fix-unlisten-js.md b/.changes/fix-unlisten-js.md deleted file mode 100644 index 29e261512680..000000000000 --- a/.changes/fix-unlisten-js.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes `unlisten` calls from JavaScript removing every registered event listener. \ No newline at end of file diff --git a/.changes/fix-url-concatenation.md b/.changes/fix-url-concatenation.md deleted file mode 100644 index 34661324d335..000000000000 --- a/.changes/fix-url-concatenation.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch ---- - -Use [`Url.join()`](https://docs.rs/url/2.2.2/url/struct.Url.html#method.join) when building webview URLs in -`WindowManager`, to handle edge cases and leading/trailing slashes in paths and urls. diff --git a/.changes/fix-window-config-center-focus.md b/.changes/fix-window-config-center-focus.md deleted file mode 100644 index 33c43c96c02f..000000000000 --- a/.changes/fix-window-config-center-focus.md +++ /dev/null @@ -1,7 +0,0 @@ - ---- - "cli.rs": patch - "tauri-runtime-wry": patch ---- - -Fixes `center` and `focus` not being allowed in `tauri.conf.json > tauri > windows` and ignored in `WindowBuilderWrapper`. \ No newline at end of file diff --git a/.changes/fix-window-created-listen.md b/.changes/fix-window-created-listen.md new file mode 100644 index 000000000000..6713df383243 --- /dev/null +++ b/.changes/fix-window-created-listen.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Immediately listen to `tauri://window-created` event to catch it before the application triggers it. diff --git a/.changes/fix-window-events.md b/.changes/fix-window-events.md deleted file mode 100644 index f09eef5c8754..000000000000 --- a/.changes/fix-window-events.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-runtime-wry": patch ---- - -Fixes window event being emitted to all windows listeners. diff --git a/.changes/fix-window-get-all.md b/.changes/fix-window-get-all.md deleted file mode 100644 index 3328955d3355..000000000000 --- a/.changes/fix-window-get-all.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Remove closed window from the `window.__TAURI__.__windows` array, used by the `window.getAll` API from `@tauri-apps/api`. diff --git a/.changes/fix-window-getter-deadlock.md b/.changes/fix-window-getter-deadlock.md deleted file mode 100644 index bf4c137a5ba5..000000000000 --- a/.changes/fix-window-getter-deadlock.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime-wry": patch -"tauri": patch ---- - -Panic on window getters usage on the main thread when the event loop is not running and document it. diff --git a/.changes/fix-window-label-api.md b/.changes/fix-window-label-api.md new file mode 100644 index 000000000000..e2c3ac45937b --- /dev/null +++ b/.changes/fix-window-label-api.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Fixes `window.label` property returning null instead of the actual label. diff --git a/.changes/fix-window-specific-event-system.md b/.changes/fix-window-specific-event-system.md new file mode 100644 index 000000000000..2682c8745756 --- /dev/null +++ b/.changes/fix-window-specific-event-system.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +--- + +The `tauri::Window#emit` functiow now correctly sends the event to all windows that has a registered listener. +**Breaking change:** `Window#emit_and_trigger` and `Window#emit` now requires the payload to be cloneable. diff --git a/.changes/fix-windows-info-cmd.md b/.changes/fix-windows-info-cmd.md deleted file mode 100644 index d01b3293120b..000000000000 --- a/.changes/fix-windows-info-cmd.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Fixes `info` command not striping `\r` from child process version output. diff --git a/.changes/fix-wix-resources.md b/.changes/fix-wix-resources.md deleted file mode 100644 index 5239c020d0cf..000000000000 --- a/.changes/fix-wix-resources.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Properly bundle resources with nested folder structure. diff --git a/.changes/fix-yarn-pnp.md b/.changes/fix-yarn-pnp.md new file mode 100644 index 000000000000..d56e9f3296ba --- /dev/null +++ b/.changes/fix-yarn-pnp.md @@ -0,0 +1,5 @@ +--- +"cli.js": patch +--- + +Automatically unplug `@tauri-apps/cli` in yarn 2+ installations to fix the download of the rust-cli. diff --git a/.changes/fixed-webview2-runtime.md b/.changes/fixed-webview2-runtime.md new file mode 100644 index 000000000000..8cc45d8dc943 --- /dev/null +++ b/.changes/fixed-webview2-runtime.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +"tauri-utils": patch +"cli.rs": patch +--- + +Allow using a fixed version for the Webview2 runtime via the `tauri > bundle > windows > webviewFixedRuntimePath` config option. diff --git a/.changes/focus.md b/.changes/focus.md deleted file mode 100644 index 25359b18a320..000000000000 --- a/.changes/focus.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `focus` API to the WindowBuilder. diff --git a/.changes/force-updater-public-key.md b/.changes/force-updater-public-key.md new file mode 100644 index 000000000000..24e25f514a2c --- /dev/null +++ b/.changes/force-updater-public-key.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-utils": patch +--- + +The updater `pubkey` is now a required field for security reasons. Sign your updates with the `tauri signer` command. diff --git a/.changes/fs-all-feature-base64-crate.md b/.changes/fs-all-feature-base64-crate.md deleted file mode 100644 index 7e5f89b992a6..000000000000 --- a/.changes/fs-all-feature-base64-crate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes `fs-all` feature not requiring the `base64` crate. diff --git a/.changes/get-menu.md b/.changes/get-menu.md new file mode 100644 index 000000000000..db34c3bf1600 --- /dev/null +++ b/.changes/get-menu.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime": minor +"tauri-runtime-wry": minor +--- + +Replace `WindowBuilder`'s `has_menu` with `get_menu`. diff --git a/.changes/global-shortcut-refactor.md b/.changes/global-shortcut-refactor.md deleted file mode 100644 index 71f253e96bc6..000000000000 --- a/.changes/global-shortcut-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -**Breaking change**: The global shortcut API is now managed by `tao` so it cannot be accessed globally, the manager is now exposed on the `App` and `AppHandle` structs. diff --git a/.changes/going-rc.md b/.changes/going-rc.md new file mode 100644 index 000000000000..81aef49dd673 --- /dev/null +++ b/.changes/going-rc.md @@ -0,0 +1,15 @@ +--- +'api': major +'cli.js': major +'cli.rs': major +'tauri': major +'tauri-bundler': major +'tauri-utils': major +'tauri-codegen': major +'tauri-macros': major +'tauri-build': major +'create-tauri-app': major +'tauri-driver': patch +--- + +Upgrade to `rc`! diff --git a/.changes/gtk-window.md b/.changes/gtk-window.md deleted file mode 100644 index f0611a9504dc..000000000000 --- a/.changes/gtk-window.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Expose `gtk_window` getter. diff --git a/.changes/gtk14.md b/.changes/gtk14.md deleted file mode 100644 index 8c93f2940421..000000000000 --- a/.changes/gtk14.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -tauri: patch -tauri-runtime: patch -tauri-runtime-wry: patch ---- - -Update gtk and its related libraries to v0.14. This also remove requirements of `clang` as build dependency. - diff --git a/.changes/header-value-bytes.md b/.changes/header-value-bytes.md deleted file mode 100644 index a80e96f82946..000000000000 --- a/.changes/header-value-bytes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Use `HeaderValue::from_bytes` instead of `HeaderValue::from_str` and `HeaderValue#to_bytes` instead of `HeaderValue#to_str` to improve compatibility. diff --git a/.changes/hide-phf.md b/.changes/hide-phf.md deleted file mode 100644 index 2dd2240de3ae..000000000000 --- a/.changes/hide-phf.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-utils": patch -"tauri": patch ---- - -Hide `phf` crate export (not public API). diff --git a/.changes/hotkey-0.1.2.md b/.changes/hotkey-0.1.2.md deleted file mode 100644 index d24e62f967e1..000000000000 --- a/.changes/hotkey-0.1.2.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Update `tauri-hotkey` to v0.1.2, fixing a compilation issue on 32-bit platforms. diff --git a/.changes/http-refactor.md b/.changes/http-refactor.md new file mode 100644 index 000000000000..75e53e9e789b --- /dev/null +++ b/.changes/http-refactor.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +`tauri::api::HttpRequestBuilder::new` now returns a `Result` to validate the url. diff --git a/.changes/icon-png-support.md b/.changes/icon-png-support.md deleted file mode 100644 index 4e740dabac11..000000000000 --- a/.changes/icon-png-support.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-runtime-wry": patch ---- - -Adds support to PNG icons. diff --git a/.changes/implement-debug.md b/.changes/implement-debug.md deleted file mode 100644 index 34032a0b28e1..000000000000 --- a/.changes/implement-debug.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"tauri": patch -"tauri-build": patch -"tauri-utils": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Implement `Debug` on public API structs and enums. diff --git a/.changes/improve-api-types.md b/.changes/improve-api-types.md deleted file mode 100644 index f9a4d1d56e58..000000000000 --- a/.changes/improve-api-types.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Improve `EventName` type using `type-fest`'s `LiteralUnion`. diff --git a/.changes/improve-esm-detection.md b/.changes/improve-esm-detection.md deleted file mode 100644 index e1c4b8185f51..000000000000 --- a/.changes/improve-esm-detection.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-codegen": patch ---- - -Improve ESM detection with regexes. diff --git a/.changes/inject-invoke-key-module-script.md b/.changes/inject-invoke-key-module-script.md deleted file mode 100644 index b0bc07ce0389..000000000000 --- a/.changes/inject-invoke-key-module-script.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-codegen": patch -"tauri-utils": patch ---- - -Inject invoke key on `script` tags with `type="module"`. diff --git a/.changes/internal-default-args.md b/.changes/internal-default-args.md deleted file mode 100644 index 843ec299bdbd..000000000000 --- a/.changes/internal-default-args.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch ---- - -(internal): allow `wry` dependency to be optional again while keeping default args. -code that wishes to expose a struct with a default arg should use the `crate::manager::default_args!` macro to declare -the struct, so that it can automatically feature-gate `DefaultArgs` behind using `wry`. diff --git a/.changes/invoke-key-performance.md b/.changes/invoke-key-performance.md deleted file mode 100644 index 6296fa58272d..000000000000 --- a/.changes/invoke-key-performance.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-codegen": patch ---- - -Improve invoke key code injection performance time rewriting code at compile time. diff --git a/.changes/is-decorated.md b/.changes/is-decorated.md deleted file mode 100644 index 7e4b2e406c7c..000000000000 --- a/.changes/is-decorated.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `is_decorated` getter on Window. diff --git a/.changes/is-resizable.md b/.changes/is-resizable.md deleted file mode 100644 index e4b096eef75a..000000000000 --- a/.changes/is-resizable.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `is_resizable` getter on Window. diff --git a/.changes/is-visible.md b/.changes/is-visible.md deleted file mode 100644 index a3931eca32e7..000000000000 --- a/.changes/is-visible.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `is_visible` getter on Window. diff --git a/.changes/isolation-pattern.md b/.changes/isolation-pattern.md new file mode 100644 index 000000000000..12b4942ad892 --- /dev/null +++ b/.changes/isolation-pattern.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +"tauri-utils": patch +"tauri-codegen": patch +--- + +Added the `isolation` pattern. diff --git a/.changes/join-handle-abort.md b/.changes/join-handle-abort.md new file mode 100644 index 000000000000..3e4d7622947b --- /dev/null +++ b/.changes/join-handle-abort.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Added `abort` method to `tauri::async_runtime::JoinHandle`. diff --git a/.changes/json5.md b/.changes/json5.md new file mode 100644 index 000000000000..00a934e8818d --- /dev/null +++ b/.changes/json5.md @@ -0,0 +1,21 @@ +--- +"tauri": patch +"tauri-build": patch +"tauri-codegen": patch +"tauri-macros": patch +"tauri-utils": patch +"cli.rs": patch +--- + +Adds support for using JSON5 format for the `tauri.conf.json` file, along with also supporting the `.json5` extension. + +Here is the logic flow that determines if JSON or JSON5 will be used to parse the config: + +1. Check if `tauri.conf.json` exists + a. Parse it with `serde_json` + b. Parse it with `json5` if `serde_json` fails + c. Return original `serde_json` error if all above steps failed +2. Check if `tauri.conf.json5` exists + a. Parse it with `json5` + b. Return error if all above steps failed +3. Return error if all above steps failed diff --git a/.changes/link-stop-propagation.md b/.changes/link-stop-propagation.md new file mode 100644 index 000000000000..5f7c8a5feb6c --- /dev/null +++ b/.changes/link-stop-propagation.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Allow preventing opening the default browser on a click on an `` element via `stopImmediatePropagation()`. diff --git a/.changes/linux-app-name.md b/.changes/linux-app-name.md deleted file mode 100644 index b0218c5bd330..000000000000 --- a/.changes/linux-app-name.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"cli.rs": patch -"tauri-bundler": patch ---- - -Only convert package name and binary name to kebab-case, keeping the `.desktop` `Name` field with the original configured value. diff --git a/.changes/linux-cors.md b/.changes/linux-cors.md new file mode 100644 index 000000000000..4dc7ecd290f2 --- /dev/null +++ b/.changes/linux-cors.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime-wry": patch +--- + +Fix empty header from CORS on Linux. + diff --git a/.changes/linux-run-return.md b/.changes/linux-run-return.md new file mode 100644 index 000000000000..f59b6cbe1f1e --- /dev/null +++ b/.changes/linux-run-return.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +"tauri-runtime": patch +"tauri-runtime-wry": patch +--- + +The `run_return` API is now available on Linux. diff --git a/.changes/linux-window-icon.md b/.changes/linux-window-icon.md deleted file mode 100644 index 16215cf8e9e0..000000000000 --- a/.changes/linux-window-icon.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-codegen": patch -"tauri": patch ---- - -Read `tauri.conf.json > tauri > bundle > icons` and use the first `.png` icon as window icon on Linux. Defaults to `icon/icon.png` if a PNG icon is not configured. diff --git a/.changes/linuxdeploy.md b/.changes/linuxdeploy.md deleted file mode 100644 index ec29b0a6f093..000000000000 --- a/.changes/linuxdeploy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Use `linuxdeploy` instead of `appimagetool` for `AppImage` bundling. diff --git a/.changes/locks.md b/.changes/locks.md deleted file mode 100644 index e4164234910e..000000000000 --- a/.changes/locks.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-runtime-wry": patch ---- - -Remove a few locks requirement in tauri-runtime-wry \ No newline at end of file diff --git a/.changes/mac-cpu.md b/.changes/mac-cpu.md deleted file mode 100644 index bf1935d75a2a..000000000000 --- a/.changes/mac-cpu.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime-wry": patch -"tauri": patch ---- - - Fix macOS high CPU usage. diff --git a/.changes/main-events-cleared-and-resumed.md b/.changes/main-events-cleared-and-resumed.md deleted file mode 100644 index 8d4e65d4891e..000000000000 --- a/.changes/main-events-cleared-and-resumed.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `Resumed` and `MainEventsCleared` variants to the `Event` enum. diff --git a/.changes/main-thread-api-calls.md b/.changes/main-thread-api-calls.md new file mode 100644 index 000000000000..a9bddb9feb21 --- /dev/null +++ b/.changes/main-thread-api-calls.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-runtime-wry": patch +--- + +Allow window, global shortcut and clipboard APIs to be called on the main thread. diff --git a/.changes/menu-export.md b/.changes/menu-export.md deleted file mode 100644 index 0b7b1dc07ca1..000000000000 --- a/.changes/menu-export.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Export `MenuHandle` and `MenuEvent` types on `tauri::window`. diff --git a/.changes/menu-item-accelerator.md b/.changes/menu-item-accelerator.md deleted file mode 100644 index 0799864b9b3f..000000000000 --- a/.changes/menu-item-accelerator.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch ---- - -Adds `accelerator` method to the `CustomMenuItem` struct to define a keyboard shortcut for the menu item. diff --git a/.changes/menu-refactor.md b/.changes/menu-refactor.md deleted file mode 100644 index 45910136e77a..000000000000 --- a/.changes/menu-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -**Breaking change**: The `menu` API was not designed to have all the new features: submenus, item updates, disabled state... so we broke it before going to stable. diff --git a/.changes/menu-with-items-constructor.md b/.changes/menu-with-items-constructor.md new file mode 100644 index 000000000000..1c5a43f0f20e --- /dev/null +++ b/.changes/menu-with-items-constructor.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime": patch +"tauri": patch +--- + +Add `Menu::with_items` constructor, taking an iterator of `MenuEntry`. diff --git a/.changes/menu.md b/.changes/menu.md deleted file mode 100644 index e9f51810d3ba..000000000000 --- a/.changes/menu.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Implemented window menus APIs. diff --git a/.changes/menuhash-fix.md b/.changes/menuhash-fix.md deleted file mode 100644 index a9fea561ab83..000000000000 --- a/.changes/menuhash-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-runtime-wry": patch ---- - -Fix the error "cannot find type MenuHash in this scope" diff --git a/.changes/misign-update.md b/.changes/misign-update.md new file mode 100644 index 000000000000..e1a0281d82a3 --- /dev/null +++ b/.changes/misign-update.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The updater now expects signatures created with the latest CLI release. diff --git a/.changes/msi-license.md b/.changes/msi-license.md deleted file mode 100644 index 953e3662949f..000000000000 --- a/.changes/msi-license.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"cli.rs": patch -"tauri-bundler": patch ---- - -Allow setting a path to a license file for the Windows Installer (`tauri.conf.json > bundle > windows > wix > license`). diff --git a/.changes/mutable-callbacks.md b/.changes/mutable-callbacks.md new file mode 100644 index 000000000000..979bd92c5930 --- /dev/null +++ b/.changes/mutable-callbacks.md @@ -0,0 +1,7 @@ +--- +"tauri-runtime-wry": minor +"tauri-runtime": minor +"tauri": minor +--- + +Change event loop callbacks definition to allow callers to move in mutable values. \ No newline at end of file diff --git a/.changes/non-exhaustive.md b/.changes/non-exhaustive.md deleted file mode 100644 index 2d6a6df8735e..000000000000 --- a/.changes/non-exhaustive.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"tauri": patch -"tauri-bundler": patch -"tauri-codegen": patch -"tauri-utils": patch ---- - -Added the `#[non_exhaustive] attribute where appropriate. diff --git a/.changes/notification-permission.md b/.changes/notification-permission.md deleted file mode 100644 index 6eae571a46c4..000000000000 --- a/.changes/notification-permission.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch ---- - -`Notification.requestPermission()` now returns `"denied"` when not allowlisted. -`IsNotificationPermissionGranted` returns `false` when not allowlisted. diff --git a/.changes/open-devtools.md b/.changes/open-devtools.md new file mode 100644 index 000000000000..416969967ce5 --- /dev/null +++ b/.changes/open-devtools.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Added `Window#open_devtools` API. diff --git a/.changes/package-json-configure-app-path.md b/.changes/package-json-configure-app-path.md new file mode 100644 index 000000000000..39ba4210136d --- /dev/null +++ b/.changes/package-json-configure-app-path.md @@ -0,0 +1,5 @@ +--- +"cli.js": patch +--- + +Read `package.json` and check for a `tauri` object containing the `appPath` string, which points to the tauri crate path. diff --git a/.changes/panic-dispatcher-getter-main-thread.md b/.changes/panic-dispatcher-getter-main-thread.md deleted file mode 100644 index 157e6ee5d087..000000000000 --- a/.changes/panic-dispatcher-getter-main-thread.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Panic when a dispatcher getter method (`Window`, `GlobalShortcutHandle`, `ClipboardManager` and `MenuHandle` APIs) is called on the main thread. diff --git a/.changes/path-resolver.md b/.changes/path-resolver.md deleted file mode 100644 index 2fc012fb1a84..000000000000 --- a/.changes/path-resolver.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds a `PathResolver` struct to simplify the usage of the `tauri::api::path::{app_dir, resource_dir}` APIs, accessible through the `App` and `AppHandle` `path_resolver` methods. diff --git a/.changes/percent-decode-asset-protocol.md b/.changes/percent-decode-asset-protocol.md deleted file mode 100644 index 771bd470ec9a..000000000000 --- a/.changes/percent-decode-asset-protocol.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Use `percent_encoding::percent_decode` on the `asset` custom protocol URL before reading the file. diff --git a/.changes/platform-specific-config.md b/.changes/platform-specific-config.md deleted file mode 100644 index ddb617fccbbb..000000000000 --- a/.changes/platform-specific-config.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Merge platform-specific `tauri.linux.conf.json`, `tauri.windows.conf.json` and `tauri.macos.conf.json` into the config JSON from `tauri.conf.json`. diff --git a/.changes/plugin-builder.md b/.changes/plugin-builder.md new file mode 100644 index 000000000000..970467870628 --- /dev/null +++ b/.changes/plugin-builder.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Add a `plugin::Builder` struct to make plugin creation more convenient. diff --git a/.changes/plugin-command.md b/.changes/plugin-command.md new file mode 100644 index 000000000000..865b5af03e0f --- /dev/null +++ b/.changes/plugin-command.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Added `$ tauri plugin init` command, which initializes a Tauri plugin. diff --git a/.changes/plugin-initialize-app-handle.md b/.changes/plugin-initialize-app-handle.md deleted file mode 100644 index fcff2fabed5d..000000000000 --- a/.changes/plugin-initialize-app-handle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -**Breaking change**: The `Plugin` trait `initialize` method now takes an `AppHandle` reference instead of `App`. diff --git a/.changes/plugin-on_event.md b/.changes/plugin-on_event.md new file mode 100644 index 000000000000..d844fd78d857 --- /dev/null +++ b/.changes/plugin-on_event.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Added `on_event` on the `Plugin` trait, which allows a plugin to react to the event loop. diff --git a/.changes/plugin-refactor.md b/.changes/plugin-refactor.md deleted file mode 100644 index fa9cc5c26f36..000000000000 --- a/.changes/plugin-refactor.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch ---- - -Refactored the `Plugin` trait `initialize` and `extend_api` signatures. -`initialize` now takes the `App` as first argument, and `extend_api` takes an `Invoke` instead of `InvokeMessage`. -This adds support to managed state on plugins. diff --git a/.changes/pnpm-support.md b/.changes/pnpm-support.md deleted file mode 100644 index 70e9ed886c17..000000000000 --- a/.changes/pnpm-support.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Adds `pnpm` support. diff --git a/.changes/pre.json b/.changes/pre.json index 9eaf60d72b18..25aecd0a67cb 100644 --- a/.changes/pre.json +++ b/.changes/pre.json @@ -1,306 +1,6 @@ { - "tag": "beta", + "tag": "rc", "changes": [ - ".changes/allow-prevent-window-close.md", - ".changes/anonymous-lifetimes.md", - ".changes/api-cjs-chunks.md", - ".changes/api-clipboard-export.md", - ".changes/api-convert-file-url.md", - ".changes/api-export-BaseDirectory.md", - ".changes/api-export-package-json.md", - ".changes/api-export-type-fix.md", - ".changes/api-export-type.md", - ".changes/api-feature-flags.md", - ".changes/api-fix-double-window.md", - ".changes/api-focus.md", - ".changes/api-is-decorated.md", - ".changes/api-is-resizable.md", - ".changes/api-is-visible.md", - ".changes/api-os-module.md", - ".changes/api-path-module.md", - ".changes/api-request-user-attention.md", - ".changes/api-set-focus.md", - ".changes/api-set-skip-taskbar.md", - ".changes/api-skip-taskbar.md", - ".changes/api-target-es2021.md", - ".changes/api-toggle-maximize.md", - ".changes/api-transparent-window.md", - ".changes/api-ts-expect-error.md", - ".changes/api-window-center.md", - ".changes/app-callback.md", - ".changes/app-dir-refactor.md", - ".changes/app-handle-create-window.md", - ".changes/app-handle-exit-cleanup.md", - ".changes/app-handle.md", - ".changes/app-set-activation-policy.md", - ".changes/app-state.md", - ".changes/appwindow-events.md", - ".changes/asset-path.md", - ".changes/asset-protocol.md", - ".changes/assets-refactor.md", - ".changes/async-commands.md", - ".changes/async-runtime-handle-api.md", - ".changes/async-runtime-spawn-returns-join-handle.md", - ".changes/attohttpc-default-client.md", - ".changes/beta.md", - ".changes/build-on-m1.md", - ".changes/bundle-deb-installed-size.md", - ".changes/bundler-arm.md", - ".changes/bundler-docs.md", - ".changes/bundler-merge-info-plist.md", - ".changes/bundler-msi-upgrade-same-version.md", - ".changes/bundler-not-copy-resources-outdir.md", - ".changes/bundler-package-types.md", - ".changes/bundler-runtime-target-arch.md", - ".changes/bundler-windows-icon-path.md", - ".changes/bundler-windows-uninstaller.md", - ".changes/bundler-wix-banner-icon.md", - ".changes/bundler-wix-dialog-image.md", - ".changes/cargo-cache.md", - ".changes/child-process-cleanup.md", - ".changes/cli-error-logging.md", - ".changes/cli-error-message.md", - ".changes/cli-init-infer-prompts.md", - ".changes/cli-rs-info-webview2.md", - ".changes/cli-rs-macos-signing-id-env.md", - ".changes/cli-rs-powerhsell-no-profile.md", - ".changes/cli-runner-arg.md", - ".changes/cli-target-triple.md", - ".changes/cli-targets-refactor.md", - ".changes/cli.js-deps-update-manifest.md", - ".changes/cli.js-empty-args.md", - ".changes/cli.js-error-propagation.md", - ".changes/cli.js-es-module.md", - ".changes/cli.js-package-check.md", - ".changes/cli.js-proxy.md", - ".changes/cli.js-rustup.md", - ".changes/cli.rs-dev-workspaces.md", - ".changes/cli.rs-features-arg.md", - ".changes/cli.rs-fix-cli.yml-assertion.md", - ".changes/cli.rs-libwebkit2gtk-4.0-37.md", - ".changes/cli.rs-release-arg.md", - ".changes/cli.rs-wix-banner-icon.md", - ".changes/cli.rs-wix-dialog-image.md", - ".changes/clipboard-api.md", - ".changes/cmd-invoke-binding.md", - ".changes/cmd-touch-bindings.md", - ".changes/command-api-module.md", - ".changes/command-app-handle.md", - ".changes/command-generics.md", - ".changes/command-macros-binding-refactor.md", - ".changes/command-message-blocking.md", - ".changes/command-options.md", - ".changes/command-return.md", - ".changes/command-state.md", - ".changes/command-status-and-output.md", - ".changes/config-mut-getter.md", - ".changes/config-package-info-getters.md", - ".changes/context-mutable-methods.md", - ".changes/core-asset-fallback.md", - ".changes/core-drag-region-resizable.md", - ".changes/core-features.md", - ".changes/core-notification-typo.md", - ".changes/core-request-user-attention.md", - ".changes/core-show-hide-menu.md", - ".changes/core-webview-events.md", - ".changes/create-window-refactor.md", - ".changes/csp-self.md", - ".changes/csp.md", - ".changes/cta-added-angular-cli.md", - ".changes/cta-explicitly-install-vite.md", - ".changes/cta-pnpm-support.md", - ".changes/cta-prompt-api.md", - ".changes/cta-shift-and-type.md", - ".changes/cta-svelte-recipe.md", - ".changes/cta-test-script.md", - ".changes/cta-testing-suite.md", - ".changes/cta-update-vite-package.md", - ".changes/cta-vite-before-dev.md", - ".changes/cta-vite-esbuild-install-direct.md", - ".changes/cta-vite-templates.md", - ".changes/cta-welcome-prompt-and-links.md", - ".changes/dblclick-tauri-drag-maximize.md", - ".changes/debian-depends.md", - ".changes/default-params-type.md", - ".changes/dev-copy-resources.md", - ".changes/dev-path-dist-dir-array.md", - ".changes/dev-path-dist-dir-validation.md", - ".changes/dialog-ask-message-parent.md", - ".changes/dialog-parent.md", - ".changes/dialog-thread-handling.md", - ".changes/dmg-bundle-fixes.md", - ".changes/doc-tauri-utils.md", - ".changes/drag-and-drop-config.md", - ".changes/drag-region-refactor.md", - ".changes/drag-window-api.md", - ".changes/dynamic-plugin.md", - ".changes/embed-plist.md", - ".changes/emit-window-events.md", - ".changes/event-refactor.md", - ".changes/exit-requested-event.md", - ".changes/features-support.md", - ".changes/fix-asset-loading-vue-router.md", - ".changes/fix-asset-loading.md", - ".changes/fix-attribute-drag-region.md", - ".changes/fix-before-dev-command-kill.md", - ".changes/fix-bundle-targets-config.md", - ".changes/fix-bundler-platform-detection.md", - ".changes/fix-cli-target-set.md", - ".changes/fix-cli.rs-bundle-arg.md", - ".changes/fix-command-event-channel.md", - ".changes/fix-command-named-cmd.md", - ".changes/fix-create-window-str.md", - ".changes/fix-custom-protocol.md", - ".changes/fix-data-tauri-drag-region.md", - ".changes/fix-dialog-allowlist..md", - ".changes/fix-dialog-save-default-path-linux.md", - ".changes/fix-dmg-volume-icon.md", - ".changes/fix-drag-and-drop.md", - ".changes/fix-esm-detection.md", - ".changes/fix-event-queue.md", - ".changes/fix-file-drop-events.md", - ".changes/fix-global-tauri.md", - ".changes/fix-http-binary-response.md", - ".changes/fix-http-resolve-error.md", - ".changes/fix-javascript-iife-esm-rewrite.md", - ".changes/fix-listen_global-not-getting-events.md", - ".changes/fix-macos-updater.md", - ".changes/fix-min-height-typo.md", - ".changes/fix-monitor-api.md", - ".changes/fix-notifications-on-windows.md", - ".changes/fix-reqwest-headers.md", - ".changes/fix-svg-mime-type.md", - ".changes/fix-unlisten-js.md", - ".changes/fix-url-concatenation.md", - ".changes/fix-window-config-center-focus.md", - ".changes/fix-window-events.md", - ".changes/fix-window-get-all.md", - ".changes/fix-window-getter-deadlock.md", - ".changes/fix-windows-info-cmd.md", - ".changes/fix-wix-resources.md", - ".changes/focus.md", - ".changes/fs-all-feature-base64-crate.md", - ".changes/global-shortcut-refactor.md", - ".changes/gtk-window.md", - ".changes/gtk14.md", - ".changes/header-value-bytes.md", - ".changes/hide-phf.md", - ".changes/hotkey-0.1.2.md", - ".changes/icon-png-support.md", - ".changes/implement-debug.md", - ".changes/improve-api-types.md", - ".changes/improve-esm-detection.md", - ".changes/inject-invoke-key-module-script.md", - ".changes/internal-default-args.md", - ".changes/invoke-key-performance.md", - ".changes/is-decorated.md", - ".changes/is-resizable.md", - ".changes/is-visible.md", - ".changes/linux-app-name.md", - ".changes/linux-window-icon.md", - ".changes/linuxdeploy.md", - ".changes/locks.md", - ".changes/mac-cpu.md", - ".changes/main-events-cleared-and-resumed.md", - ".changes/menu-export.md", - ".changes/menu-item-accelerator.md", - ".changes/menu-refactor.md", - ".changes/menu.md", - ".changes/menuhash-fix.md", - ".changes/msi-license.md", - ".changes/non-exhaustive.md", - ".changes/notification-permission.md", - ".changes/panic-dispatcher-getter-main-thread.md", - ".changes/path-resolver.md", - ".changes/percent-decode-asset-protocol.md", - ".changes/platform-specific-config.md", - ".changes/plugin-initialize-app-handle.md", - ".changes/plugin-refactor.md", - ".changes/pnpm-support.md", - ".changes/print.md", - ".changes/private-context.md", - ".changes/process-api.md", - ".changes/product-name-original.md", - ".changes/raw-window-handle-dependency.md", - ".changes/readd-esm-cli.js.md", - ".changes/refactor-register-uri-scheme-protocol.md", - ".changes/refactor-settings.md", - ".changes/refactor-window-management.md", - ".changes/regular-script-invoke-key-injection.md", - ".changes/remove-api-modules.md", - ".changes/remove-image-crate.md", - ".changes/remove-menu-flag.md", - ".changes/remove-salt.md", - ".changes/remove-window-on-exit.md", - ".changes/remove-with-window.md", - ".changes/resources-dir-refactor.md", - ".changes/restart-application.md", - ".changes/revert-cli.js-es-module.md", - ".changes/revert-es2021.md", - ".changes/rpc-security.md", - ".changes/run-iteration.md", - ".changes/run-on-main-thread-refactor.md", - ".changes/runtime-crate.md", - ".changes/runtime-global-shortcut.md", - ".changes/runtime-main-events-cleared-and-resumed.md", - ".changes/runtime-request-user-attention.md", - ".changes/runtime-run-iteration.md", - ".changes/runtime-set-activation-policy.md", - ".changes/runtime-show-hide-menu.md", - ".changes/rust-1.54.md", - ".changes/set-focus.md", - ".changes/set-skip-taskbar.md", - ".changes/setup-error-send.md", - ".changes/setup-fix.md", - ".changes/shell-command-output-order.md", - ".changes/simplify-handle-event-loop.md", - ".changes/simplify-tag-label-usage.md", - ".changes/skip-taskbar.md", - ".changes/support-dep-formats.md", - ".changes/system-tray-refactor.md", - ".changes/system-tray-usage-fix.md", - ".changes/tauri-build-icon-path.md", - ".changes/tauri-data-directory.md", - ".changes/tauri-driver.md", - ".changes/tauri-empty-window.md", - ".changes/tauri-expose-shortcut-clipboard.md", - ".changes/tauri-icon-fix.md", - ".changes/tauri-info-framework-bundler.md", - ".changes/tauri-macos-tray-icon-template.md", - ".changes/tauri-protocol.md", - ".changes/tauri-ready-event.md", - ".changes/tauri-updater-linux.md", - ".changes/tauri-updater-windows.md", - ".changes/tauri-wry-migrate.md", - ".changes/tauri-wry.md", - ".changes/template-csp-change.md", - ".changes/throw-error-on-cli-download-failure.md", - ".changes/transparency-fix.md", - ".changes/tray.md", - ".changes/try-state.md", - ".changes/uri-parse.md", - ".changes/weak-typing.md", - ".changes/webdriver.md", - ".changes/webview-window-constructor-pub.md", - ".changes/webview-window-extends-window-manager.md", - ".changes/window-api-validations.md", - ".changes/window-attributes-rename.md", - ".changes/window-center.md", - ".changes/window-create-refactor.md", - ".changes/window-events.md", - ".changes/window-getters.md", - ".changes/window-label-unique.md", - ".changes/window-parent-and-owner.md", - ".changes/window-parent.md", - ".changes/window-send-sync.md", - ".changes/windows-protocol-path.md", - ".changes/windows-resources-set-values.md", - ".changes/windows-shortcut.md", - ".changes/wix-bundle-language.md", - ".changes/wix-config-language.md", - ".changes/wix-resource-bundling-fix.md", - ".changes/wix-uninstall-skip-uac-task.md", - ".changes/wix-update-on-windows-without-uac.md", - ".changes/wry-update.md" + ".changes/going-rc.md" ] } diff --git a/.changes/prevent-path-traversal.md b/.changes/prevent-path-traversal.md new file mode 100644 index 000000000000..f7e83be938f9 --- /dev/null +++ b/.changes/prevent-path-traversal.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Prevent path traversal on the file system APIs. diff --git a/.changes/print.md b/.changes/print.md deleted file mode 100644 index 62db4e424169..000000000000 --- a/.changes/print.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -`window.print()` now works on all platforms. diff --git a/.changes/private-api.md b/.changes/private-api.md new file mode 100644 index 000000000000..1db7aabeb898 --- /dev/null +++ b/.changes/private-api.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +"tauri-runtime-wry": patch +"cli.rs": patch +--- + +Add `macos-private-api` feature flag, enabled via `tauri.conf.json > tauri > macOSPrivateApi`. diff --git a/.changes/private-context.md b/.changes/private-context.md deleted file mode 100644 index 315cd2916224..000000000000 --- a/.changes/private-context.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -**Breaking:** `Context` fields are now private, and is expected to be created through `Context::new(...)`. -All fields previously available through `Context` are now public methods. diff --git a/.changes/process-api.md b/.changes/process-api.md deleted file mode 100644 index 4a29c35efdbb..000000000000 --- a/.changes/process-api.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Move `exit` and `relaunch` APIs from `app` to `process` module. diff --git a/.changes/product-name-original.md b/.changes/product-name-original.md deleted file mode 100644 index 6a7f48a93cac..000000000000 --- a/.changes/product-name-original.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-utils": patch ---- - -Keep original value on `config > package > productName` on Linux (previously converted to kebab-case). diff --git a/.changes/raw-headers.md b/.changes/raw-headers.md new file mode 100644 index 000000000000..87ea3e7d4137 --- /dev/null +++ b/.changes/raw-headers.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Add `raw_headers` to `tauri::api::http::ResponseData`. diff --git a/.changes/raw-window-handle-dependency.md b/.changes/raw-window-handle-dependency.md deleted file mode 100644 index f8d4ef3b0887..000000000000 --- a/.changes/raw-window-handle-dependency.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fix `raw-window-handle` dependency declaration. diff --git a/.changes/raw-window-handle.md b/.changes/raw-window-handle.md new file mode 100644 index 000000000000..ffa0856fdd74 --- /dev/null +++ b/.changes/raw-window-handle.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Implement `raw_window_handle::RawWindowHandle` for `tauri::Window` on `Windows` and `macOS`. The `tauri::api::dialog::window_parent` function was removed since now you can use the window directly. diff --git a/.changes/readd-esm-cli.js.md b/.changes/readd-esm-cli.js.md deleted file mode 100644 index 6f7e16ba91c0..000000000000 --- a/.changes/readd-esm-cli.js.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -The CLI is now an ES module and requires at least Node.js v12.20. Fixed previous releases by using Rollup instead of Webpack. diff --git a/.changes/refactor-create-tao-window.md b/.changes/refactor-create-tao-window.md new file mode 100644 index 000000000000..8bad9c78b84c --- /dev/null +++ b/.changes/refactor-create-tao-window.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime-wry": patch +"tauri": patch +--- + +Refactor `create_tao_window` API to return `Weak` instead of `Arc`. diff --git a/.changes/refactor-dialog-apis.md b/.changes/refactor-dialog-apis.md new file mode 100644 index 000000000000..d78dbeda50d4 --- /dev/null +++ b/.changes/refactor-dialog-apis.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Added the `tauri::api::dialog::blocking` module. diff --git a/.changes/refactor-notification-permission-check.md b/.changes/refactor-notification-permission-check.md new file mode 100644 index 000000000000..3c16e2f2b5b3 --- /dev/null +++ b/.changes/refactor-notification-permission-check.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The notification endpoint now checks for the permission flag and requests if the value is not set. diff --git a/.changes/refactor-register-uri-scheme-protocol.md b/.changes/refactor-register-uri-scheme-protocol.md deleted file mode 100644 index f04210b75ae6..000000000000 --- a/.changes/refactor-register-uri-scheme-protocol.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch ---- - -**Breaking change:** Removed `register_uri_scheme_protocol` from the `WebviewAttibutes` struct and renamed `register_global_uri_scheme_protocol` to `register_uri_scheme_protocol` on the `Builder` struct, which now takes a `Fn(&AppHandle, &http::Request) -> http::Response` closure. diff --git a/.changes/refactor-resources-sidecar-copying.md b/.changes/refactor-resources-sidecar-copying.md new file mode 100644 index 000000000000..b20407f19acd --- /dev/null +++ b/.changes/refactor-resources-sidecar-copying.md @@ -0,0 +1,8 @@ +--- +"cli.rs": patch +"tauri-bundler": patch +"tauri-utils": patch +"tauri-build": patch +--- + +Move the copying of resources and sidecars from `cli.rs` to `tauri-build` so using the Cargo CLI directly processes the files for the application execution in development. diff --git a/.changes/refactor-settings.md b/.changes/refactor-settings.md deleted file mode 100644 index 58a4776ee59d..000000000000 --- a/.changes/refactor-settings.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -`Settings` is now serialized using `bincode`. diff --git a/.changes/refactor-window-event-close-requested.md b/.changes/refactor-window-event-close-requested.md new file mode 100644 index 000000000000..1c5219b14ed4 --- /dev/null +++ b/.changes/refactor-window-event-close-requested.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +**Breaking change:** The `WindowEvent::CloseRequested` variant now includes `label` and `signal_tx` fields to allow preventing closing the window. diff --git a/.changes/refactor-window-management.md b/.changes/refactor-window-management.md deleted file mode 100644 index d75d406eb9d3..000000000000 --- a/.changes/refactor-window-management.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"api": patch -"tauri": patch ---- - -The window management API was refactored: removed `setX`, `setY`, `setWidth`, `setHeight` APIs, renamed `resize` to `setSize` and the size and position APIs now allow defining both logical and physical values. diff --git a/.changes/refactor-window-metadata.md b/.changes/refactor-window-metadata.md new file mode 100644 index 000000000000..ba23c2abce9e --- /dev/null +++ b/.changes/refactor-window-metadata.md @@ -0,0 +1,5 @@ +--- +"tauri": "patch" +--- + +**Breaking change:** Move `__currentWindow` and `__windows` values from `window.__TAURI__` to `window.__TAURI_METADATA__`. diff --git a/.changes/regular-script-invoke-key-injection.md b/.changes/regular-script-invoke-key-injection.md deleted file mode 100644 index 25bb64b18781..000000000000 --- a/.changes/regular-script-invoke-key-injection.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-utils": patch -"tauri": patch ---- - -Inject the invoke key on regular `` tags. diff --git a/.changes/remove-api-modules.md b/.changes/remove-api-modules.md deleted file mode 100644 index da25d60e7136..000000000000 --- a/.changes/remove-api-modules.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Removed the `tcp` module from `tauri::api`. diff --git a/.changes/remove-current-base-directory.md b/.changes/remove-current-base-directory.md new file mode 100644 index 000000000000..8413cce8927d --- /dev/null +++ b/.changes/remove-current-base-directory.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"api": patch +--- + +Remove the `BaseDirectory::Current` enum variant for security reasons. diff --git a/.changes/remove-image-crate.md b/.changes/remove-image-crate.md deleted file mode 100644 index 91b5bdfc6be6..000000000000 --- a/.changes/remove-image-crate.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-runtime-wry": patch ---- - -Removes `image` dependency. For now only `.ico` icons on Windows are supported, and we'll implement other types on demand to optimize bundle size. diff --git a/.changes/remove-menu-flag.md b/.changes/remove-menu-flag.md deleted file mode 100644 index 42563fd7c255..000000000000 --- a/.changes/remove-menu-flag.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": minor -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Remove menu feature flag since there's no package dependency need to be installed on any platform anymore. diff --git a/.changes/remove-salt.md b/.changes/remove-salt.md deleted file mode 100644 index 31729dd0f1b2..000000000000 --- a/.changes/remove-salt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Remove salt-related APIs (no longer needed after the `__TAURI_INVOKE_KEY__` implementation). diff --git a/.changes/remove-tauricon.md b/.changes/remove-tauricon.md new file mode 100644 index 000000000000..658eb068ae5e --- /dev/null +++ b/.changes/remove-tauricon.md @@ -0,0 +1,5 @@ +--- +"cli.js": patch +--- + +Removed the `icon` command, now exposed as a separate package, see https://github.com/tauri-apps/tauricon. diff --git a/.changes/remove-window-default.md b/.changes/remove-window-default.md new file mode 100644 index 000000000000..617d2fb4a04d --- /dev/null +++ b/.changes/remove-window-default.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-utils": patch +--- + +**Breaking change*** Remove default webview window when `tauri.conf.json > tauri > windows` is not set. diff --git a/.changes/remove-window-on-exit.md b/.changes/remove-window-on-exit.md deleted file mode 100644 index 13b70977cbb0..000000000000 --- a/.changes/remove-window-on-exit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Remove window object from the `Manager` internal `HashMap` on close. This fixes the behavior of using `[App|AppHandle|Window]#get_window` after the window is closed (now correctly returns `None`). diff --git a/.changes/remove-with-window.md b/.changes/remove-with-window.md deleted file mode 100644 index 36cabc9ca931..000000000000 --- a/.changes/remove-with-window.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Removes the `with_window` attribute on the `command` macro. Tauri now infers it using the `CommandArg` trait. diff --git a/.changes/resources-dir-refactor.md b/.changes/resources-dir-refactor.md deleted file mode 100644 index 347c0a4086da..000000000000 --- a/.changes/resources-dir-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-utils": patch ---- - -The `platform::resource_dir` API now takes the `PackageInfo`. diff --git a/.changes/restart-application.md b/.changes/restart-application.md deleted file mode 100644 index a9e3aa3b5678..000000000000 --- a/.changes/restart-application.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Move `restart_application` API from `app` module to `process` module. diff --git a/.changes/revert-cli.js-es-module.md b/.changes/revert-cli.js-es-module.md deleted file mode 100644 index c99ddb127c2b..000000000000 --- a/.changes/revert-cli.js-es-module.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Reverts ESM distribution. diff --git a/.changes/revert-es2021.md b/.changes/revert-es2021.md deleted file mode 100644 index 094a24b825e4..000000000000 --- a/.changes/revert-es2021.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Revert target back to ES5. diff --git a/.changes/rpc-mod-refactor.md b/.changes/rpc-mod-refactor.md new file mode 100644 index 000000000000..6f54a83845a8 --- /dev/null +++ b/.changes/rpc-mod-refactor.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +**Breaking change:** Renamed the `rpc` module to `ipc`. diff --git a/.changes/rpc-security.md b/.changes/rpc-security.md deleted file mode 100644 index f584b4162c46..000000000000 --- a/.changes/rpc-security.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"api": patch -"tauri": patch ---- - -Improve RPC security by requiring a numeric code to invoke commands. The codes are generated by the Rust side and injected into the app's code using a closure, so external scripts can't access the backend. This change doesn't protect `withGlobalTauri` (`window.__TAURI__`) usage. diff --git a/.changes/run-iteration.md b/.changes/run-iteration.md deleted file mode 100644 index ecf43ea6d9a6..000000000000 --- a/.changes/run-iteration.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `run_iteration` API to the `App` and return the app instance on the `build` method of the `Builder`. The `run_iteration` method runs the window event loop step by step, allowing Tauri to be run along other applications. diff --git a/.changes/run-on-main-thread-refactor.md b/.changes/run-on-main-thread-refactor.md deleted file mode 100644 index 541cd5f51930..000000000000 --- a/.changes/run-on-main-thread-refactor.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime-wry": patch -"tauri": patch ---- - -The `run_on_main_thread` API now uses WRY's UserEvent, so it wakes the event loop. diff --git a/.changes/run-on-main-thread.md b/.changes/run-on-main-thread.md new file mode 100644 index 000000000000..5af644d68554 --- /dev/null +++ b/.changes/run-on-main-thread.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Expose `run_on_main_thread` APIs on `Window` and `AppHandle`. diff --git a/.changes/runtime-any-thread.md b/.changes/runtime-any-thread.md new file mode 100644 index 000000000000..f0b20ccec620 --- /dev/null +++ b/.changes/runtime-any-thread.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime": patch +"tauri-runtime-wry": patch +--- + +Added `any_thread` constructor on the `Runtime` trait (only possible on Linux and Windows). diff --git a/.changes/runtime-crate.md b/.changes/runtime-crate.md deleted file mode 100644 index 4df240148d53..000000000000 --- a/.changes/runtime-crate.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": minor -"tauri": patch ---- - -`tauri-runtime` crate initial release. diff --git a/.changes/runtime-global-shortcut.md b/.changes/runtime-global-shortcut.md deleted file mode 100644 index c6e29b688d55..000000000000 --- a/.changes/runtime-global-shortcut.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds global shortcut interfaces. diff --git a/.changes/runtime-handle-run-on-main-thread.md b/.changes/runtime-handle-run-on-main-thread.md new file mode 100644 index 000000000000..06854acdc229 --- /dev/null +++ b/.changes/runtime-handle-run-on-main-thread.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime": "patch" +"tauri-runtime-wry": patch +--- + +Added `run_on_main_thread` API on `RuntimeHandle`. diff --git a/.changes/runtime-ipc.md b/.changes/runtime-ipc.md new file mode 100644 index 000000000000..d7c7d63ccaf0 --- /dev/null +++ b/.changes/runtime-ipc.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime": minor +"tauri-runtime-wry": minor +--- + +**Breaking change:** Renamed the `RPC` interface to `IPC`. diff --git a/.changes/runtime-main-events-cleared-and-resumed.md b/.changes/runtime-main-events-cleared-and-resumed.md deleted file mode 100644 index b163fe01ab2e..000000000000 --- a/.changes/runtime-main-events-cleared-and-resumed.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `Resumed` and `MainEventsCleared` variants to the `RunEvent` enum. diff --git a/.changes/runtime-open-devtools.md b/.changes/runtime-open-devtools.md new file mode 100644 index 000000000000..72d31a52d2d1 --- /dev/null +++ b/.changes/runtime-open-devtools.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime": patch +"tauri-runtime-wry": patch +--- + +Added `open_devtools` to the `Dispatcher` trait. diff --git a/.changes/runtime-request-user-attention.md b/.changes/runtime-request-user-attention.md deleted file mode 100644 index 9476e6d3c693..000000000000 --- a/.changes/runtime-request-user-attention.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `request_user_attention` API to the `Dispatcher` trait. diff --git a/.changes/runtime-run-iteration.md b/.changes/runtime-run-iteration.md deleted file mode 100644 index 38ba2a19b766..000000000000 --- a/.changes/runtime-run-iteration.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Adds `fn run_iteration` (macOS and Windows only) to the Runtime trait. diff --git a/.changes/runtime-set-activation-policy.md b/.changes/runtime-set-activation-policy.md deleted file mode 100644 index b409873c3d3d..000000000000 --- a/.changes/runtime-set-activation-policy.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Adds `set_activation_policy` API to the `Runtime` trait (macOS only). diff --git a/.changes/runtime-show-hide-menu.md b/.changes/runtime-show-hide-menu.md deleted file mode 100644 index b9835f01d23c..000000000000 --- a/.changes/runtime-show-hide-menu.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `show_menu`, `hide_menu` and `is_menu_visible` APIs to the `Dispatcher` trait. diff --git a/.changes/rust-1.54.md b/.changes/rust-1.54.md deleted file mode 100644 index e05c6a6c00e6..000000000000 --- a/.changes/rust-1.54.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"cli.rs": patch -"tauri": patch ---- - -Update minimum Rust version to 1.54.0. diff --git a/.changes/rust-1.56.0.md b/.changes/rust-1.56.0.md new file mode 100644 index 000000000000..c41f453a69e0 --- /dev/null +++ b/.changes/rust-1.56.0.md @@ -0,0 +1,14 @@ +--- +"tauri": patch +"cli.rs": patch +"tauri-bundler": patch +"tauri-utils": patch +"tauri-macros": patch +"tauri-codegen": patch +"tauri-runtime": patch +"tauri-runtime-wry": patch +"tauri-driver": patch +"tauri-build": patch +--- + +The minimum Rust version is now `1.56`. diff --git a/.changes/rust-1.57.md b/.changes/rust-1.57.md new file mode 100644 index 000000000000..24cb734f547b --- /dev/null +++ b/.changes/rust-1.57.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The minimum Rust version is now 1.57. diff --git a/.changes/scope-config.md b/.changes/scope-config.md new file mode 100644 index 000000000000..b364a27be192 --- /dev/null +++ b/.changes/scope-config.md @@ -0,0 +1,7 @@ +--- +"tauri-utils": patch +--- + +Adds `scope` glob array config under `tauri > allowlist > fs`. +Adds `assetScope` glob array config under `tauri > allowlist > protocol`. +Adds `scope` URL array config under `tauri > allowlist > http`. diff --git a/.changes/scopes.md b/.changes/scopes.md new file mode 100644 index 000000000000..096838e7b4f5 --- /dev/null +++ b/.changes/scopes.md @@ -0,0 +1,8 @@ +--- +"tauri": patch +--- + +Scopes the `filesystem` APIs from the webview access using `tauri.conf.json > tauri > allowlist > fs > scope`. +Scopes the `asset` protocol access using `tauri.conf.json > tauri > allowlist > protocol > assetScope`. +Scopes the `http` APIs from the webview access using `tauri.conf.json > tauri > allowlist > http > scope`. +Scopes the `shell` execute API from the webview access using `tauri.conf.json > tauri > allowlist > shell > scope`. Additionally, check the `tauri.conf.json > tauri > bundle > externalBin` to prevent access to unknown sidecars. diff --git a/.changes/set-focus.md b/.changes/set-focus.md deleted file mode 100644 index 322690c1dfff..000000000000 --- a/.changes/set-focus.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `set_focus` API on Window. diff --git a/.changes/set-skip-taskbar.md b/.changes/set-skip-taskbar.md deleted file mode 100644 index 9cd73be1a483..000000000000 --- a/.changes/set-skip-taskbar.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `set_skip_taskbar` API on Window. diff --git a/.changes/setup-error-send.md b/.changes/setup-error-send.md deleted file mode 100644 index ea45aa89dc6d..000000000000 --- a/.changes/setup-error-send.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -The `setup` Error type must be `Send`. diff --git a/.changes/setup-fix.md b/.changes/setup-fix.md deleted file mode 100644 index c9ebba535510..000000000000 --- a/.changes/setup-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Run the setup callback after preparing the system tray. diff --git a/.changes/setup-fn-once.md b/.changes/setup-fn-once.md new file mode 100644 index 000000000000..7f06a05ed92a --- /dev/null +++ b/.changes/setup-fn-once.md @@ -0,0 +1,5 @@ +--- +"tauri": "patch" +--- + +`Builder#setup` closure type changed from `Fn` to `FnOnce`. diff --git a/.changes/shell-command-output-order.md b/.changes/shell-command-output-order.md deleted file mode 100644 index b06ad0d0fe13..000000000000 --- a/.changes/shell-command-output-order.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fixes a consistency issue on the order of `tauri::process::Command` emitted events. diff --git a/.changes/shell-open-with-refactor.md b/.changes/shell-open-with-refactor.md new file mode 100644 index 000000000000..d2124c7b43f6 --- /dev/null +++ b/.changes/shell-open-with-refactor.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +The `tauri::api::shell::open`'s `with` argument is now an enum value instead of any string. diff --git a/.changes/sidecar-allowlist.md b/.changes/sidecar-allowlist.md new file mode 100644 index 000000000000..f85d37c34368 --- /dev/null +++ b/.changes/sidecar-allowlist.md @@ -0,0 +1,6 @@ +--- +"tauri-utils": patch +"tauri": patch +--- + +The `shell` allowlist now includes a `sidecar` flag, which enables the use of the `shell` API to execute sidecars. diff --git a/.changes/sidecar-runtime-rename.md b/.changes/sidecar-runtime-rename.md new file mode 100644 index 000000000000..97828c5bd674 --- /dev/null +++ b/.changes/sidecar-runtime-rename.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-bundler": patch +--- + +**Breaking change**: The sidecar's target triple suffix is now removed at build time. diff --git a/.changes/simplify-handle-event-loop.md b/.changes/simplify-handle-event-loop.md deleted file mode 100644 index 114789dc19b2..000000000000 --- a/.changes/simplify-handle-event-loop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-runtime-wry": minor ---- - -Update `wry` to v0.10.0 and replace the removed `dispatch_script` and `evaluate_script` methods with the new `evaluate_script` method in `handle_event_loop`. diff --git a/.changes/simplify-tag-label-usage.md b/.changes/simplify-tag-label-usage.md deleted file mode 100644 index 38ca6a143424..000000000000 --- a/.changes/simplify-tag-label-usage.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"tauri": patch ---- - -Simplify usage of app event and window label types. The following functions now -accept references the `Tag` can be borrowed as. This means an `&str` can now be -accepted for functions like `Window::emit`. This is a breaking change for the -following items, which now need to take a reference. Additionally, type inference -for `&"event".into()` will no longer work, but `&"event".to_string()` will. The -solution for this is to now just pass `"event"` because `Borrow` is implemented -for the default event type `String`. - -* **Breaking:** `Window::emit` now accepts `Borrow` for the event. -* **Breaking:** `Window::emit_others` now accepts `Borrow` for the event -* **Breaking:** `Window::trigger` now accepts `Borrow` for the event. -* **Breaking:** `Manager::emit_all` now accepts `Borrow` for the event. -* **Breaking:** `Manager::emit_to` now accepts `Borrow` for both the event and window label. -* **Breaking:** `Manager::trigger_global` now accepts `Borrow` for the event. -* **Breaking:** `Manager::get_window` now accepts `Borrow` for the window label. -* _(internal):_ `trait tauri::runtime::tag::TagRef` helper for accepting tag references. - Any time you want to accept a tag reference, that trait will handle requiring the reference - to have all the necessary bounds, and generate errors when the exposed function doesn't - set a bound like `P::Event: Borrow`. diff --git a/.changes/simplify-window-label-types.md b/.changes/simplify-window-label-types.md new file mode 100644 index 000000000000..5aab845e1d81 --- /dev/null +++ b/.changes/simplify-window-label-types.md @@ -0,0 +1,5 @@ +--- +"api": patch +--- + +Change `WindowLabel` type to `string`. diff --git a/.changes/skip-taskbar.md b/.changes/skip-taskbar.md deleted file mode 100644 index b5cc84e6b9dd..000000000000 --- a/.changes/skip-taskbar.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Adds `skip_taskbar` API to the WindowBuilder. diff --git a/.changes/streaming-small-file-fix.md b/.changes/streaming-small-file-fix.md new file mode 100644 index 000000000000..e4b316e40800 --- /dev/null +++ b/.changes/streaming-small-file-fix.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Fix streaming of small files using the `asset` protocol. diff --git a/.changes/strip.md b/.changes/strip.md new file mode 100644 index 000000000000..f49c954b149e --- /dev/null +++ b/.changes/strip.md @@ -0,0 +1,5 @@ +--- +"cli.rs": "patch" +--- + +Automatically `strip` the built binary on Linux and macOS if `--debug` is not specified. diff --git a/.changes/support-dep-formats.md b/.changes/support-dep-formats.md deleted file mode 100644 index 0b40adea43b6..000000000000 --- a/.changes/support-dep-formats.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Adds support to `tauri` dependency as string and table on `Cargo.toml`. diff --git a/.changes/system-tray-refactor.md b/.changes/system-tray-refactor.md deleted file mode 100644 index cd109fdf2774..000000000000 --- a/.changes/system-tray-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -**Breaking change**: The `system_tray` and `on_system_tray_event` APIs were not designed to have all the new features: submenus, item updates, click events, positioning... so we broke it before going to stable. diff --git a/.changes/system-tray-usage-fix.md b/.changes/system-tray-usage-fix.md deleted file mode 100644 index d6a9a44e90f1..000000000000 --- a/.changes/system-tray-usage-fix.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Fixes `system-tray` feature usage. diff --git a/.changes/tauri-build-icon-path.md b/.changes/tauri-build-icon-path.md deleted file mode 100644 index 8f46aa002790..000000000000 --- a/.changes/tauri-build-icon-path.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-build": patch ---- - -The `try_build` method now has a `Attributes` argument to allow specifying the window icon path used on Windows. diff --git a/.changes/tauri-data-directory.md b/.changes/tauri-data-directory.md deleted file mode 100644 index 99af363f1304..000000000000 --- a/.changes/tauri-data-directory.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Force data directory even on non-local window. diff --git a/.changes/tauri-driver.md b/.changes/tauri-driver.md deleted file mode 100644 index 70d3b46238d0..000000000000 --- a/.changes/tauri-driver.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-driver": minor ---- - -Initial release including Linux and Windows support. diff --git a/.changes/tauri-empty-window.md b/.changes/tauri-empty-window.md deleted file mode 100644 index 4e6b6e9d3686..000000000000 --- a/.changes/tauri-empty-window.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Allow creation of empty Window with `create_tao_window()` and management with `send_tao_window_event()` on the AppHandler. diff --git a/.changes/tauri-expose-shortcut-clipboard.md b/.changes/tauri-expose-shortcut-clipboard.md deleted file mode 100644 index ca33ca8f3db7..000000000000 --- a/.changes/tauri-expose-shortcut-clipboard.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch ---- - -Make `ClipboardManager` and `GlobalShortcutManager` public as they are exposed in the `AppHandle`. - diff --git a/.changes/tauri-icon-fix.md b/.changes/tauri-icon-fix.md deleted file mode 100644 index 799322e249fd..000000000000 --- a/.changes/tauri-icon-fix.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"cli.js": patch ---- - -Updates to `tauri icon` -- detect if icon is NOT transparent via metadata -- detect again on pixel level -- remove pngquant as a waste of space -- make optipng default -- relax optipng settings diff --git a/.changes/tauri-info-framework-bundler.md b/.changes/tauri-info-framework-bundler.md deleted file mode 100644 index f0e191f41f97..000000000000 --- a/.changes/tauri-info-framework-bundler.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Show `framework` and `bundler` on the `info` command by reading the `package.json` file and matching known dependencies. diff --git a/.changes/tauri-macos-tray-icon-template.md b/.changes/tauri-macos-tray-icon-template.md deleted file mode 100644 index 97f2ba2fd7ac..000000000000 --- a/.changes/tauri-macos-tray-icon-template.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -- Support [macOS tray icon template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) to adjust automatically based on taskbar color. - -- Images you mark as template images should consist of only black and clear colors. You can use the alpha channel in the image to adjust the opacity of black content, however. diff --git a/.changes/tauri-protocol.md b/.changes/tauri-protocol.md deleted file mode 100644 index a7f84e45fafc..000000000000 --- a/.changes/tauri-protocol.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": minor -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Migrate to latest custom protocol allowing `Partial content` streaming and Header parsing. diff --git a/.changes/tauri-ready-event.md b/.changes/tauri-ready-event.md deleted file mode 100644 index 1e6b781012c7..000000000000 --- a/.changes/tauri-ready-event.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": minor -"tauri-runtime": minor -"tauri-runtime-wry": minor ---- - -Add `Event::Ready` on the `run()` callback. Triggered once when the event loop is ready. diff --git a/.changes/tauri-updater-linux.md b/.changes/tauri-updater-linux.md deleted file mode 100644 index 2414249e2ba9..000000000000 --- a/.changes/tauri-updater-linux.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Use glib context for linux updater to prevent GTK panic. diff --git a/.changes/tauri-updater-windows.md b/.changes/tauri-updater-windows.md deleted file mode 100644 index b27aa62021aa..000000000000 --- a/.changes/tauri-updater-windows.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch ---- - -- Do not run the updater with UAC task if server don't tell us. (Allow toggling server-side) -- The updater expect a field named `with_elevated_task` with a `boolean` and will not run if the task is not installed first. (windows only) diff --git a/.changes/tauri-wry-migrate.md b/.changes/tauri-wry-migrate.md deleted file mode 100644 index 2425560baf3b..000000000000 --- a/.changes/tauri-wry-migrate.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-runtime-wry": patch ---- - -Bump `wry` 0.11 and fix focus integration to make it compatible with tao 0.4. diff --git a/.changes/tauri-wry.md b/.changes/tauri-wry.md deleted file mode 100644 index 85090d8728da..000000000000 --- a/.changes/tauri-wry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri": patch -"tauri-runtime-wry": minor ---- - -`tauri-runtime-wry` initial release. diff --git a/.changes/template-csp-change.md b/.changes/template-csp-change.md deleted file mode 100644 index be04ca81ba62..000000000000 --- a/.changes/template-csp-change.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Change the `csp` value on the template to include `wss:` and `tauri:` to the `default-src` attribute. diff --git a/.changes/throw-error-on-cli-download-failure.md b/.changes/throw-error-on-cli-download-failure.md deleted file mode 100644 index 2258e72bd2e4..000000000000 --- a/.changes/throw-error-on-cli-download-failure.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.js": patch ---- - -Throw error on `cli.rs` download failure instead of silent exit. diff --git a/.changes/tooling-fix-pnpm-info-error.md b/.changes/tooling-fix-pnpm-info-error.md new file mode 100644 index 000000000000..f5494b3412ab --- /dev/null +++ b/.changes/tooling-fix-pnpm-info-error.md @@ -0,0 +1,5 @@ +--- +'cli.rs': patch +--- + +Fixes pnpm error when running `pnpm tauri info`. diff --git a/.changes/transparency-fix.md b/.changes/transparency-fix.md deleted file mode 100644 index 3287454c82d1..000000000000 --- a/.changes/transparency-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-runtime-wry": patch ---- - -Fixes webview transparency. diff --git a/.changes/tray-set-menu.md b/.changes/tray-set-menu.md new file mode 100644 index 000000000000..d0b2dc500fb7 --- /dev/null +++ b/.changes/tray-set-menu.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Add `set_menu` API on `tauri::SystemTrayHandle`. diff --git a/.changes/tray.md b/.changes/tray.md deleted file mode 100644 index c89950c19a52..000000000000 --- a/.changes/tray.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds system tray support. diff --git a/.changes/try-state.md b/.changes/try-state.md deleted file mode 100644 index d59192098fa1..000000000000 --- a/.changes/try-state.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Add `try_state` API to the `Manager` trait. diff --git a/.changes/universal-apple-target-sidecar.md b/.changes/universal-apple-target-sidecar.md new file mode 100644 index 000000000000..13eb66b43453 --- /dev/null +++ b/.changes/universal-apple-target-sidecar.md @@ -0,0 +1,9 @@ +--- +"tauri-bundler": patch +"api": patch +--- + +When building Universal macOS Binaries through the virtual target `universal-apple-darwin`: + +- Expect a universal binary to be created by the user +- Ensure that binary is bundled and accessed correctly at runtime diff --git a/.changes/universal-apple-target.md b/.changes/universal-apple-target.md new file mode 100644 index 000000000000..fcd7eead2a18 --- /dev/null +++ b/.changes/universal-apple-target.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Add support to building Universal macOS Binaries through the virtual target `universal-apple-darwin` (run `tauri build --target universal-apple-darwin`). diff --git a/.changes/unlisten.md b/.changes/unlisten.md new file mode 100644 index 000000000000..d60cce4adc40 --- /dev/null +++ b/.changes/unlisten.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Adds `unlisten` function to the `Window` struct. diff --git a/.changes/updater-endpoint-url-https.md b/.changes/updater-endpoint-url-https.md new file mode 100644 index 000000000000..cd998f3bd6b0 --- /dev/null +++ b/.changes/updater-endpoint-url-https.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-utils": patch +--- + +Force updater endpoint URL to use `https` on release builds. diff --git a/.changes/uri-parse.md b/.changes/uri-parse.md deleted file mode 100644 index 2b12788d9b69..000000000000 --- a/.changes/uri-parse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Fix loading url containing URI fragment diff --git a/.changes/validate-allowlist.md b/.changes/validate-allowlist.md new file mode 100644 index 000000000000..a8ead7e2e92d --- /dev/null +++ b/.changes/validate-allowlist.md @@ -0,0 +1,5 @@ +--- +"tauri-build": patch +--- + +Validate `tauri` dependency `features` under `Cargo.toml` matching `tauri.conf.json`'s `allowlist`. diff --git a/.changes/validate-appimage.md b/.changes/validate-appimage.md new file mode 100644 index 000000000000..ef18a4764083 --- /dev/null +++ b/.changes/validate-appimage.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Validate the `std::env::current_exe` return value if `APPDIR` or `APPIMAGE` environment variables are set. diff --git a/.changes/validate-event-name.md b/.changes/validate-event-name.md new file mode 100644 index 000000000000..43badb3fa53f --- /dev/null +++ b/.changes/validate-event-name.md @@ -0,0 +1,6 @@ +--- +"tauri": "patch" +--- + +The event name is now validated. On a IPC message, it returns an error if it fails validation; on the Rust side, it panics. +It must include only alphanumeric characters, `-`, `/`, `:` and `_`. diff --git a/.changes/validate-window-label.md b/.changes/validate-window-label.md new file mode 100644 index 000000000000..9f4b71deaaa0 --- /dev/null +++ b/.changes/validate-window-label.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-runtime": patch +--- + +The window label is now validated and must be alphanumeric, resulting in a panic if it isn't. diff --git a/.changes/version-package-json.md b/.changes/version-package-json.md new file mode 100644 index 000000000000..f22887f99121 --- /dev/null +++ b/.changes/version-package-json.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Allow `tauri.conf.json > package > version` to specify a path to a `package.json` file and pull the version from it. diff --git a/.changes/wait-dev-server-url.md b/.changes/wait-dev-server-url.md new file mode 100644 index 000000000000..612b53e55e96 --- /dev/null +++ b/.changes/wait-dev-server-url.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Wait for `devPath` URL to be reachable before starting the application. Skipped if the `TAURI_SKIP_DEVSERVER_CHECK` environment variable is set to `true`. diff --git a/.changes/weak-typing.md b/.changes/weak-typing.md deleted file mode 100644 index 69f721613dd4..000000000000 --- a/.changes/weak-typing.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch -"tauri-macros": patch -"tauri-utils": patch ---- - -`Params` has been removed, along with all the associated types on it. Functions that previously accepted those -associated types now accept strings instead. Type that used a generic parameter `Params` now use `Runtime` instead. If -you use the `wry` feature, then types with a `Runtime` generic parameter should default to `Wry`, letting you omit the -explicit type and let the compiler infer it instead. - -`tauri`: - -* See `Params` note -* If you were using `Params` inside a function parameter or definition, all references to it have been replaced with a - simple runtime that defaults to `Wry`. If you are not using a custom runtime, just remove `Params` from the definition - of functions/items that previously took it. If you are using a custom runtime, you _may_ need to pass the runtime type - to these functions. -* If you were using custom types for `Params` (uncommon and if you don't understand you probably were not using it), all - methods that were previously taking the custom type now takes an `Into` or a `&str`. The types were already - required to be string-able, so just make sure to convert it into a string before passing it in if this breaking change - affects you. - -`tauri-macros`: - -* (internal) Added private `default_runtime` proc macro to allow us to give item definitions a custom runtime only when - the specified feature is enabled. - -`tauri-runtime`: - -* See `Params` note -* Removed `Params`, `MenuId`, `Tag`, `TagRef`. -* Added `menu::{MenuHash, MenuId, MenuIdRef}` as type aliases for the internal type that menu types now use. - * All previous menu items that had a `MenuId` generic now use the underlying `MenuId` type without a generic. -* `Runtime`, `RuntimeHandle`, and `Dispatch` have no more generic parameter on `create_window(...)` and instead use the - `Runtime` type directly -* `Runtime::system_tray` has no more `MenuId` generic and uses the string based `SystemTray` type directly. -* (internal) `CustomMenuItem::id_value()` is now hashed on creation and exposed as the `id` field with type `MenuHash`. - -`tauri-runtime-wry`: - -* See `Params` note -* update menu and runtime related types to the ones changed in `tauri-runtime`. - -`tauri-utils`: - -* `Assets::get` signature has changed to take a `&AssetKey` instead of `impl Into` to become trait object - safe. diff --git a/.changes/webdriver-args.md b/.changes/webdriver-args.md new file mode 100644 index 000000000000..7296a4bbee50 --- /dev/null +++ b/.changes/webdriver-args.md @@ -0,0 +1,5 @@ +--- +"tauri-driver": patch +--- + +Add `args` field (array of application CLI arguments) to the `tauri:options` capabilities. diff --git a/.changes/webdriver.md b/.changes/webdriver.md deleted file mode 100644 index 426b54e3cef7..000000000000 --- a/.changes/webdriver.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-runtime-wry": patch ---- - -Add webdriver support to Tauri. diff --git a/.changes/webview-attributes-clipboard.md b/.changes/webview-attributes-clipboard.md new file mode 100644 index 000000000000..7f34d4c05f92 --- /dev/null +++ b/.changes/webview-attributes-clipboard.md @@ -0,0 +1,6 @@ +--- +"tauri": patch +"tauri-runtime": patch +--- + +Added `clipboard` field on the `WebviewAttributes` struct, which must be set to `true` to enable clipboard access on the webview. diff --git a/.changes/webview-window-constructor-pub.md b/.changes/webview-window-constructor-pub.md deleted file mode 100644 index 6a3306d02686..000000000000 --- a/.changes/webview-window-constructor-pub.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Mark the `WebviewWindow` constructor as public. diff --git a/.changes/webview-window-extends-window-manager.md b/.changes/webview-window-extends-window-manager.md deleted file mode 100644 index ff78a2ec80b2..000000000000 --- a/.changes/webview-window-extends-window-manager.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Allow manipulating a spawned window directly using `WebviewWindow`, which now extends `WindowManager`. diff --git a/.changes/webview2-com.md b/.changes/webview2-com.md new file mode 100644 index 000000000000..bddac4929581 --- /dev/null +++ b/.changes/webview2-com.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +"tauri-runtime": patch +"tauri-runtime-wry": patch +--- + +Replace all of the `winapi` crate references with the `windows` crate, and replace `webview2` and `webview2-sys` with `webview2-com` and `webview2-com-sys` built with the `windows` crate. This goes along with updates to the TAO and WRY `next` branches. \ No newline at end of file diff --git a/.changes/window-api-validations.md b/.changes/window-api-validations.md deleted file mode 100644 index 6e39784185c2..000000000000 --- a/.changes/window-api-validations.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Validate arguments on the window `setLocation`, `setSize`, `setMinSize` and `setMaxSize` API. diff --git a/.changes/window-attributes-rename.md b/.changes/window-attributes-rename.md deleted file mode 100644 index 28d298d47415..000000000000 --- a/.changes/window-attributes-rename.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Rename `Attributes` to `WindowBuilder`. diff --git a/.changes/window-center.md b/.changes/window-center.md deleted file mode 100644 index 48b38a83abb7..000000000000 --- a/.changes/window-center.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri-runtime": patch -"tauri-runtime-wry": patch -"tauri": patch ---- - -Adds `Window#center` and `WindowBuilder#center` APIs. diff --git a/.changes/window-confirm.md b/.changes/window-confirm.md new file mode 100644 index 000000000000..e6ddc59adf25 --- /dev/null +++ b/.changes/window-confirm.md @@ -0,0 +1,5 @@ +--- +"tauri": patch +--- + +Show `Ok/Cancel` buttons instead of `Yes/No` when executing `window.confirm`. diff --git a/.changes/window-create-refactor.md b/.changes/window-create-refactor.md deleted file mode 100644 index cb31e8f40c03..000000000000 --- a/.changes/window-create-refactor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -The `Window#create_window` API now has the same signature as `App#create_window`. diff --git a/.changes/window-events.md b/.changes/window-events.md deleted file mode 100644 index 1d8e9d5cf20d..000000000000 --- a/.changes/window-events.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Adds `on_window_event` API to the `Window` struct. diff --git a/.changes/window-getters.md b/.changes/window-getters.md deleted file mode 100644 index 51c1c94b1480..000000000000 --- a/.changes/window-getters.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"api": patch -"tauri": patch ---- - -Adds window getters. diff --git a/.changes/window-label-unique.md b/.changes/window-label-unique.md deleted file mode 100644 index 27aa3f6caea0..000000000000 --- a/.changes/window-label-unique.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Enfore uniqueness of window label. diff --git a/.changes/window-parent-and-owner.md b/.changes/window-parent-and-owner.md deleted file mode 100644 index 3fbfc0c1d3e8..000000000000 --- a/.changes/window-parent-and-owner.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Adds `parent_window` and `owner_window` setters to the `WindowBuilder` (Windows only). diff --git a/.changes/window-parent.md b/.changes/window-parent.md deleted file mode 100644 index 69bc531d11ae..000000000000 --- a/.changes/window-parent.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime": patch -"tauri-runtime-wry": patch ---- - -Adds window native handle getter (HWND on Windows). diff --git a/.changes/window-send-sync.md b/.changes/window-send-sync.md deleted file mode 100644 index bc547f2df0fd..000000000000 --- a/.changes/window-send-sync.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"tauri": patch -"tauri-runtime-wry": patch -"tauri-runtime": patch ---- - -`Window` is now `Send + Sync` on Windows. diff --git a/.changes/windows-0.25.0.md b/.changes/windows-0.25.0.md new file mode 100644 index 000000000000..60365d3157d5 --- /dev/null +++ b/.changes/windows-0.25.0.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +"tauri-runtime": patch +"tauri-runtime-wry": patch +--- + +Update the `windows` crate to 0.25.0, which comes with pre-built libraries. WRY and Tao can both reference the same types directly from the `windows` crate instead of sharing bindings in `webview2-com-sys`. \ No newline at end of file diff --git a/.changes/windows-modify-cmd-string-behaviour.md b/.changes/windows-modify-cmd-string-behaviour.md new file mode 100644 index 000000000000..9be3b3c64c06 --- /dev/null +++ b/.changes/windows-modify-cmd-string-behaviour.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +On Windows, Fix `beforeDevCommand` and `beforeBuildCommand` not executing the expected command if it contains quotes. This is done by executing them with `CMD /S /C {command}` instead of `CMD /C {command}` on Windows. \ No newline at end of file diff --git a/.changes/windows-null.md b/.changes/windows-null.md new file mode 100644 index 000000000000..532322bb0a3f --- /dev/null +++ b/.changes/windows-null.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime-wry": patch +--- + +This is a temporary fix of null pointer crash on `get_content` of web resource request. +We will switch it back once upstream is updated. diff --git a/.changes/windows-protocol-path.md b/.changes/windows-protocol-path.md deleted file mode 100644 index b98d9c15754e..000000000000 --- a/.changes/windows-protocol-path.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"api": patch ---- - -Update protocol url path with wry 0.12.1 on Windows. diff --git a/.changes/windows-resources-set-values.md b/.changes/windows-resources-set-values.md deleted file mode 100644 index c212e100e2e6..000000000000 --- a/.changes/windows-resources-set-values.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-build": patch ---- - -Pull Windows resource information (`FileVersion`, `ProductVersion`, `ProductName` and `FileDescription`) from `tauri.conf.json > package` configuration. diff --git a/.changes/windows-shortcut.md b/.changes/windows-shortcut.md deleted file mode 100644 index afb7d42e8c48..000000000000 --- a/.changes/windows-shortcut.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Configure app shortcut on the Windows Installer. diff --git a/.changes/wix-bundle-language.md b/.changes/wix-bundle-language.md deleted file mode 100644 index 62792b914c85..000000000000 --- a/.changes/wix-bundle-language.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Allow setting the Windows installer language and using project names that contains non-Unicode characters. diff --git a/.changes/wix-config-language.md b/.changes/wix-config-language.md deleted file mode 100644 index 287de9228b2d..000000000000 --- a/.changes/wix-config-language.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"cli.rs": patch ---- - -Adds `tauri > bundle > windows > wix > language` config option. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables. diff --git a/.changes/wix-localization.md b/.changes/wix-localization.md new file mode 100644 index 000000000000..4187442a40e2 --- /dev/null +++ b/.changes/wix-localization.md @@ -0,0 +1,6 @@ +--- +"cli.rs": patch +"tauri-bundler": patch +--- + +Allow setting the localization file for WiX. diff --git a/.changes/wix-registry-keys.md b/.changes/wix-registry-keys.md new file mode 100644 index 000000000000..f9930f3d4c27 --- /dev/null +++ b/.changes/wix-registry-keys.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": patch +--- + +Fix registry keys on the WiX template. diff --git a/.changes/wix-resource-bundling-fix.md b/.changes/wix-resource-bundling-fix.md deleted file mode 100644 index c691900d8422..000000000000 --- a/.changes/wix-resource-bundling-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri-bundler": patch ---- - -Fixes resource bundling on Windows when there is nested resource folders. diff --git a/.changes/wix-run-app.md b/.changes/wix-run-app.md new file mode 100644 index 000000000000..30db1d3ff296 --- /dev/null +++ b/.changes/wix-run-app.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": patch +--- + +Configure WiX to add an option to launch the application after finishing setup. diff --git a/.changes/wix-signing.md b/.changes/wix-signing.md new file mode 100644 index 000000000000..af26aca9189f --- /dev/null +++ b/.changes/wix-signing.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": patch +--- + +Sign WiX installer in addition to the executable file. diff --git a/.changes/wix-uninstall-skip-uac-task.md b/.changes/wix-uninstall-skip-uac-task.md deleted file mode 100644 index 1ca0836a6a8e..000000000000 --- a/.changes/wix-uninstall-skip-uac-task.md +++ /dev/null @@ -1,5 +0,0 @@ --- -"tauri-bundler": patch --- - -Added script to uninstall the Skip-UAC Windows Task during application uninstall. diff --git a/.changes/wix-update-on-windows-without-uac.md b/.changes/wix-update-on-windows-without-uac.md deleted file mode 100644 index 0bd2a21f5643..000000000000 --- a/.changes/wix-update-on-windows-without-uac.md +++ /dev/null @@ -1,5 +0,0 @@ --- -"tauri-bundler": patch --- - -Added option to update a Tauri application without Windows UAC Prompt. \ No newline at end of file diff --git a/.changes/wry-13.md b/.changes/wry-13.md new file mode 100644 index 000000000000..b6248fcc68e8 --- /dev/null +++ b/.changes/wry-13.md @@ -0,0 +1,6 @@ +--- +"tauri-runtime-wry": patch +--- + +Update wry to 0.13. + diff --git a/.changes/wry-update.md b/.changes/wry-update.md deleted file mode 100644 index 26f588031276..000000000000 --- a/.changes/wry-update.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"tauri": patch ---- - -Update `wry` to v0.9. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b141445ba422..dfe16ecf0f15 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -17,8 +17,8 @@ /tooling/bundler/ @tauri-apps/bundler -/tooling/cli.rs/ @tauri-apps/core +/tooling/cli/ @tauri-apps/core -/tooling/cli.js/ @tauri-apps/js-cli +/tooling/cli/node/ @tauri-apps/js-cli /core/** @tauri-apps/core diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 6af3729a295e..4f3fc1189de2 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -28,6 +28,9 @@ Hi! We, the maintainers, are really excited that you are interested in contribut ## Pull Request Guidelines +- We only accept *signed commits*, so sign your commits! [Here is a great guide](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) that walks you through all the required steps. + > Note: Despite what the guide claims, GitHub Desktop honors the repo/system wide git config, so after running `git config --global commit.gpgsign true` GitHub Desktop will sign commits as well. + - It's OK to have multiple small commits as you work on the PR - we will let GitHub automatically squash it before merging. - If adding new feature: @@ -46,35 +49,26 @@ Hi! We, the maintainers, are really excited that you are interested in contribut First, [join our Discord server](https://discord.gg/SpmNs4S) and let us know that you want to contribute. This way we can point you in the right direction and help ensure your contribution will be as helpful as possible. -To set up your machine for development, follow the [Tauri setup guide](https://tauri.studio/en/docs/getting-started/intro#setting-up-your-environment) to get all the tools you need to develop Tauri apps. The only additional tool you may need is [Yarn](https://yarnpkg.com/), it is only required if you are developing the Node CLI/API (`tooling/cli.js` and `api`). Next, fork and clone this repo. It is structured as a monorepo, which means that all the various Tauri packages are under the same repository. The development process varies depending on what part of Tauri you are contributing to, see the guides below for per-package instructions. +To set up your machine for development, follow the [Tauri setup guide](https://tauri.studio/en/docs/get-started/intro#setting-up-your-environment) to get all the tools you need to develop Tauri apps. The only additional tool you may need is [Yarn](https://yarnpkg.com/), it is only required if you are developing the Node CLI or API packages (`tooling/cli/node` and `tooling/api`). Next, fork and clone this repo. It is structured as a monorepo, which means that all the various Tauri packages are under the same repository. The development process varies depending on what part of Tauri you are contributing to, see the guides below for per-package instructions. -Some Tauri packages will be automatically built when running one of the examples. Others, however, will need to be built beforehand. To build these automatically, run the `.scripts/setup.sh` (Linux and macOS) or `.scripts/setup.ps1` (Windows) script. This will install the Rust and Node.js CLI and build the JS API. After that, you should be able to run all the examples. +Some Tauri packages will be automatically built when running one of the examples. Others, however, will need to be built beforehand. To build these automatically, run the `.scripts/setup.sh` (Linux and macOS) or `.scripts/setup.ps1` (Windows) script. This will install the Rust and Node.js CLI and build the JS API. After that, you should be able to run all the examples. Note that the setup script should be executed from the root folder of the respository in order to run correctly. ### Packages Overview - The JS API (`/tooling/api`) contains JS bindings to the builtin Rust functions in the Rust API. -- The Rust CLI (`/tooling/cli.rs`) is the primary CLI for creating and developing Tauri apps. -- cli.js (`/tooling/cli.js`) is a Node.js CLI wrapper for `cli.rs`. +- cli.rs (`/tooling/cli`) is the primary CLI for creating and developing Tauri apps. +- cli.js (`/tooling/cli/node`) is a Node.js CLI wrapper for `cli.rs`. - Tauri Bundler (`/tooling/bundler`) is used by the Rust CLI to package executables into installers. - Tauri Core (`/core/tauri`) is the heart of Tauri. It contains the code that starts the app, configures communication between Rust and the Webview, and ties all the other packages together. - The Macros (`/core/tauri-macros`) are used by Tauri Core for various functions. ### Developing The Node.js CLI (cli.js) -`cli.js` is a CLI tool that houses the `icon`, and `deps` command. The code for cli.js is located in `[Tauri repo root]/tooling/cli.js`. There are a few package scripts you should be aware of: - -- `build` builds the CLI -- `test` runs the unit and e2e test suite -- `lint` runs ESLint to catch linting errors -- `format` formats code with Prettier to match the style guide - -To test your changes, we recommend using the helloworld example app, located in `[Tauri repo root]/examples/helloworld`. Run `yarn tauri [COMMAND]` to run a command using your local cli.js copy. You will need to rebuild cli.js after every change by running `yarn build` in the cli.js directory. - -If you want to use your local copy of cli.js in another app, we recommend using [yarn link](https://classic.yarnpkg.com/en/docs/cli/link/). First, make sure you have don't have cli.js installed globally by running `npm uninstall -g tauri && yarn global remove tauri`. Then, run `yarn link` in the cli.js directory (note that the setup script will do this for you, so you can skip this step if you ran that). Now, you can just run `tauri [COMMAND]` anywhere, and your local copy will be used. +`cli.js` is a wrapper to `cli.rs` so most changes should be written on the Rust CLI. The `[Tauri repo root]/tooling/cli/node` folder contains only packaging scripts to properly publish the Rust CLI binaries to NPM. ### Developing Tauri Bundler and Rust CLI -The code for the bundler is located in `[Tauri repo root]/tooling/bundler`, and the code for the Rust CLI is located in `[Tauri repo root]/tooling/cli.rs`. If you are using your local copy of cli.js (see above), any changes you make to the bundler and CLI will be automatically built and applied when running the build or dev command. Otherwise, running `cargo install --path .` in the Rust CLI directory will allow you to run `cargo tauri build` and `cargo tauri dev` anywhere, using the updated copy of the bundler and cli. You will have to run this command each time you make a change in either package. +The code for the bundler is located in `[Tauri repo root]/tooling/bundler`, and the code for the Rust CLI is located in `[Tauri repo root]/tooling/cli`. If you are using your local copy of cli.js (see above), any changes you make to the bundler and CLI will be automatically built and applied when running the build or dev command. Otherwise, running `cargo install --path .` in the Rust CLI directory will allow you to run `cargo tauri build` and `cargo tauri dev` anywhere, using the updated copy of the bundler and cli. You will have to run this command each time you make a change in either package. ### Developing Tauri Core and Related Components (Rust API, Macros, Codegen, and Utils) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 55e8e4861ec8..000000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve Tauri -title: '' -labels: bug -assignees: '' - ---- - - - - -### **Describe the bug** -A clear and concise description of what the bug is. - -### **To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -### **Expected behavior** -A clear and concise description of what you expected to happen. - -### **Screenshots** -If applicable, add screenshots to help explain your problem. - -### **Platform and Versions (required):** - -``` -Operating System - -Node.js environment -Node.js -@tauri-apps/cli -@tauri-apps/api - -Global packages -npm -yarn - -Rust environment -rustc -cargo - -App directory structure - - -App -tauri.rs -build-type -CSP -``` - -### **Additional context** -Add any other context about the problem here. - -### **Stack Trace** - diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000000..b2a5c15882b9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,60 @@ +name: 🐞 Bug Report +title: '[bug] ' +description: Report a bug +labels: 'type: bug' + +body: + - type: markdown + attributes: + value: | + ## First of all + 1. Please search for [existing issues](https://github.com/tauri-apps/tauri/issues?q=is%3Aissue) about this problem first. + 2. Make sure `rustc` and all relevant Tauri packages are up to date. + 3. Make sure it's an issue with Tauri and not something else you are using. + 4. Remember to follow our community guidelines and be friendly. + + - type: textarea + id: description + attributes: + label: Describe the bug + description: A clear description of what the bug is. Include screenshots if applicable. + placeholder: Bug description + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Reproduction + description: Steps to reproduce the behavior. + placeholder: | + 1. Go to ... + 2. Click on ... + 3. See error + + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: A clear description of what you expected to happen. + + - type: textarea + id: info + attributes: + label: Platform and versions + description: "Output of `npm run tauri info` or `cargo tauri info`" + render: shell + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Stack trace + render: shell + + - type: textarea + id: context + attributes: + label: Additional context + description: Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000000..de285b08c7b5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: + - name: 💬 Discord Chat + url: https://discord.com/invite/tauri + about: Ask questions and talk to other Tauri users and the maintainers diff --git a/.github/ISSUE_TEMPLATE/docs-report.md b/.github/ISSUE_TEMPLATE/docs-report.md deleted file mode 100644 index c0b7ebc75cde..000000000000 --- a/.github/ISSUE_TEMPLATE/docs-report.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Docs report -about: Create a report to help us improve Tauri docs -title: "[docs]" -labels: docs -assignees: '' - ---- - - diff --git a/.github/ISSUE_TEMPLATE/docs_report.md b/.github/ISSUE_TEMPLATE/docs_report.md new file mode 100644 index 000000000000..25350673ca78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/docs_report.md @@ -0,0 +1,8 @@ +--- +name: 📚 Docs Report +about: Create a report to help us improve the docs +title: "[docs] " +labels: 'type: documentation' +assignees: '' + +--- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index d82e0b2b871d..000000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for Tauri -title: '' -labels: feature request -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000000..0b611fafba94 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,35 @@ +name: 💡 Feature Request +title: '[feat] ' +description: Suggest an idea +labels: 'type: feature request' + +body: + - type: textarea + id: problem + attributes: + label: Describe the problem + description: A clear description of the problem this feature would solve + placeholder: "I'm always frustrated when..." + validations: + required: true + + - type: textarea + id: solution + attributes: + label: "Describe the solution you'd like" + description: A clear description of what change you would like + placeholder: "I would like to..." + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: "Any alternative solutions you've considered" + + - type: textarea + id: context + attributes: + label: Additional context + description: Add any other context about the problem here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6301def49841..7cb3c1f282e8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,40 +1,30 @@ - - - +Update "[ ]" to "[x]" to check a box -**What kind of change does this PR introduce?** (check at least one) - +### What kind of change does this PR introduce? + + - [ ] Bugfix - [ ] Feature - [ ] Docs -- [ ] New Binding Issue #___ +- [ ] New Binding issue #___ - [ ] Code style update - [ ] Refactor - [ ] Build-related changes - [ ] Other, please describe: -**Does this PR introduce a breaking change?** (check one) - +### Does this PR introduce a breaking change? + -- [ ] Yes. Issue #___ +- [ ] Yes, and the changes were approved in issue #___ - [ ] No - -**The PR fulfills these requirements:** - -- [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix: #xxx[,#xxx]`, where "xxx" is the issue number) +### Checklist +- [ ] When resolving issues, they are referenced in the PR's title (e.g `fix: remove a typo, closes #___, #___`) - [ ] A change file is added if any packages will require a version bump due to this PR per [the instructions in the readme](https://github.com/tauri-apps/tauri/blob/dev/.changes/readme.md). +- [ ] I have added a convincing reason for adding this feature, if necessary -If adding a **new feature**, the PR's description includes: -- [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it) - -**Other information:** +### Other information diff --git a/docs/splash.png b/.github/splash.png similarity index 100% rename from docs/splash.png rename to .github/splash.png diff --git a/.github/workflows/artifacts-updater.yml b/.github/workflows/artifacts-updater.yml index 8392bfd3455c..2e9c94a5d27c 100644 --- a/.github/workflows/artifacts-updater.yml +++ b/.github/workflows/artifacts-updater.yml @@ -7,11 +7,12 @@ on: push: branches: - dev + - next pull_request: paths: - '.github/workflows/artifacts-updater.yml' - 'core/tauri/**' - - 'tooling/cli.rs/**' + - 'tooling/cli/**' - 'tooling/bundler/**' - 'examples/updater/**' @@ -36,7 +37,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf - + - name: Get current date run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV if: matrix.platform == 'macos-latest' || matrix.platform == 'ubuntu-latest' @@ -77,38 +78,34 @@ jobs: restore-keys: | ${{ matrix.platform }}-stable-cargo-core-${{ hashFiles('core/**/Cargo.toml') }} ${{ matrix.platform }}-stable-cargo-core- - + - name: Cache CLI cargo target uses: actions/cache@v2 with: - path: tooling/cli.rs/target + path: tooling/cli/target # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }}-${{ env.CURRENT_DATE }} + key: ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }}-${{ env.CURRENT_DATE }} # Restore from outdated cache for speed restore-keys: | - ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }} + ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }} ${{ matrix.platform }}-stable-cargo-cli- - - name: install cli deps via yarn - working-directory: ./tooling/cli.js - run: yarn - - name: build cli - working-directory: ./tooling/cli.js - run: yarn build + - name: build and install cli.rs + run: cargo install --path tooling/cli - name: Check whether code signing should be enabled id: enablecodesigning env: - ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }} + ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }} run: | - echo "Enable code signing: ${{ env.ENABLE_CODE_SIGNING != '' }}" - echo "::set-output name=enabled::${{ env.ENABLE_CODE_SIGNING != '' }}" + echo "Enable code signing: ${{ env.ENABLE_CODE_SIGNING != '' }}" + echo "::set-output name=enabled::${{ env.ENABLE_CODE_SIGNING != '' }}" # run only on tauri-apps/tauri repo (require secrets) - name: build sample artifacts + code signing (updater) if: steps.enablecodesigning.outputs.enabled == 'true' working-directory: ./examples/updater run: | yarn install - node ../../tooling/cli.js/bin/tauri build + cargo tauri build env: # Notarization (disabled) # FIXME: enable only on `dev` push maybe? as it take some times... @@ -128,7 +125,7 @@ jobs: working-directory: ./examples/updater run: | yarn install - node ../../tooling/cli.js/bin/tauri build + cargo tauri build env: TAURI_PRIVATE_KEY: dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5YTBGV3JiTy9lRDZVd3NkL0RoQ1htZmExNDd3RmJaNmRMT1ZGVjczWTBKZ0FBQkFBQUFBQUFBQUFBQUlBQUFBQWdMekUzVkE4K0tWQ1hjeGt1Vkx2QnRUR3pzQjVuV0ZpM2czWXNkRm9hVUxrVnB6TUN3K1NheHJMREhQbUVWVFZRK3NIL1VsMDBHNW5ET1EzQno0UStSb21nRW4vZlpTaXIwZFh5ZmRlL1lSN0dKcHdyOUVPclVvdzFhVkxDVnZrbHM2T1o4Tk1NWEU9Cg== # upload assets @@ -136,14 +133,14 @@ jobs: if: matrix.platform == 'ubuntu-latest' with: name: linux-updater-artifacts - path: ./target/release/bundle/appimage/updater-example_*.AppImage.* + path: ./examples/updater/src-tauri/target/release/bundle/appimage/updater-example_*.AppImage.* - uses: actions/upload-artifact@v2 if: matrix.platform == 'windows-latest' with: name: windows-updater-artifacts - path: ./target/release/bundle/msi/* + path: ./examples/updater/src-tauri/target/release/bundle/msi/* - uses: actions/upload-artifact@v2 if: matrix.platform == 'macos-latest' with: name: macos-updater-artifacts - path: ./target/release/bundle/macos/updater-example.app.tar.* + path: ./examples/updater/src-tauri/target/release/bundle/macos/updater-example.app.tar.* diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 37f1a7f160b3..361ab4585269 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -10,10 +10,10 @@ on: - cron: '0 0 * * *' push: paths: - - "**/Cargo.lock" - - "**/Cargo.toml" - - "**/package.json" - - "**/yarn.lock" + - '**/Cargo.lock' + - '**/Cargo.toml' + - '**/package.json' + - '**/yarn.lock' jobs: audit-rust: @@ -30,5 +30,5 @@ jobs: steps: - uses: actions/checkout@v2 - name: yarn audit - working-directory: tooling/cli.js + working-directory: tooling/cli/node run: yarn audit diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 47f9231b709b..878b3745b830 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -4,6 +4,7 @@ on: push: branches: - dev + - next workflow_dispatch: jobs: @@ -83,7 +84,7 @@ jobs: with: path: tooling/bench/tests/target # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-benches-${{ hashFiles('tooling/bench/tests/Cargo.lock') }}-${{ env.CURRENT_DATE }} + key: ${{ matrix.platform }}-nightly-cargo-benches-${{ hashFiles('tooling/bench/tests/Cargo.lock') }}-${{ env.CURRENT_DATE }} # Restore from outdated cache for speed restore-keys: | ${{ matrix.platform }}-nightly-cargo-benches-${{ hashFiles('tooling/bench/tests/Cargo.lock') }} diff --git a/.github/workflows/build-smoke-tests.yml b/.github/workflows/build-smoke-tests.yml index 0a39805ffa16..070b7d9cb75e 100644 --- a/.github/workflows/build-smoke-tests.yml +++ b/.github/workflows/build-smoke-tests.yml @@ -57,10 +57,11 @@ jobs: ref: ${{ github.event.inputs.ref }} path: example - name: setup node - uses: actions/setup-node@v1 + uses: actions/setup-node@v2 with: node-version: 14 - - name: install rust stable + cache: yarn + cache-dependency-path: tooling/*/yarn.lock uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -70,15 +71,8 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf - - name: yarn install for cli - working-directory: tauri/tooling/cli.js - run: yarn - - name: build cli.js - working-directory: tauri/tooling/cli.js - run: | - yarn build-release - yarn global add $PWD - echo "::add-path::$(yarn global bin)" + - name: build and install cli.rs + run: cargo install --path tauri/tooling/cli - name: install and build assets working-directory: "example/${{ github.event.inputs.dir }}" run: ${{ github.event.inputs.buildAssets }} @@ -87,6 +81,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: + tauriScript: cargo tauri includeDebug: true projectPath: "example/${{ github.event.inputs.dir }}" preferGlobal: true diff --git a/.github/workflows/core-lint-fmt.yml b/.github/workflows/core-lint-fmt.yml index a8c0541f4ecb..d15203d220ee 100644 --- a/.github/workflows/core-lint-fmt.yml +++ b/.github/workflows/core-lint-fmt.yml @@ -8,12 +8,13 @@ on: push: branches: - dev + - next pull_request: paths: - '.github/workflows/core-lint-fmt.yml' - 'core/**' - 'examples/**' - - 'tooling/cli.rs/**' + - 'tooling/cli/**' jobs: workspace_clippy_fmt_check: @@ -88,20 +89,20 @@ jobs: - uses: actions-rs/toolchain@v1 with: - profile: minimal - toolchain: nightly - override: true - components: rustfmt, clippy + profile: minimal + toolchain: nightly + override: true + components: rustfmt, clippy - uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - args: --manifest-path ./tooling/cli.rs/Cargo.toml --all-targets --all-features -- -D warnings + args: --manifest-path ./tooling/cli/Cargo.toml --all-targets --all-features -- -D warnings name: cli - name: Get current date run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - + - name: Cache cargo registry uses: actions/cache@v2.1.4 with: @@ -127,18 +128,18 @@ jobs: - name: Cache CLI cargo target uses: actions/cache@v2 with: - path: tooling/cli.rs/target + path: tooling/cli/target # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }}-${{ env.CURRENT_DATE }} + key: ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }}-${{ env.CURRENT_DATE }} # Restore from outdated cache for speed restore-keys: | - ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }} + ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }} ubuntu-latest-nightly-cargo-cli- - uses: actions-rs/cargo@v1 with: command: fmt - args: --manifest-path ./tooling/cli.rs/Cargo.toml --all -- --check + args: --manifest-path ./tooling/cli/Cargo.toml --all -- --check core_clippy_check: runs-on: ubuntu-latest @@ -155,10 +156,10 @@ jobs: - uses: actions-rs/toolchain@v1 with: - profile: minimal - toolchain: nightly - override: true - components: rustfmt, clippy + profile: minimal + toolchain: nightly + override: true + components: rustfmt, clippy - name: Get current date run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV diff --git a/.github/workflows/covector-version-or-publish.yml b/.github/workflows/covector-version-or-publish.yml index 2bdaa13e7479..187985413613 100644 --- a/.github/workflows/covector-version-or-publish.yml +++ b/.github/workflows/covector-version-or-publish.yml @@ -22,10 +22,30 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: node-version: 14 - registry-url: "https://registry.npmjs.org" + registry-url: 'https://registry.npmjs.org' + cache: yarn + cache-dependency-path: tooling/*/yarn.lock + + - name: Cache CLI cargo target + uses: actions/cache@v2 + with: + path: tooling/cli/target + # Add date to the cache to keep it up to date + key: ubuntu-latest-stable-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ubuntu-latest-stable-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }} + ubuntu-latest-stable-cargo-cli- + + - name: build CLI + uses: actions-rs/cargo@v1 + with: + command: build + args: --manifest-path ./tooling/cli/Cargo.toml + - name: cargo login run: cargo login ${{ secrets.crate_token }} - name: git config @@ -40,7 +60,7 @@ jobs: CARGO_AUDIT_OPTIONS: ${{ secrets.CARGO_AUDIT_OPTIONS }} with: token: ${{ secrets.GITHUB_TOKEN }} - command: "version-or-publish" + command: 'version-or-publish' createRelease: true - name: Create Pull Request With Versions Bumped if: steps.covector.outputs.commandRan == 'version' @@ -49,122 +69,24 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} branch: release/version-updates title: Apply Version Updates From Current Changes - commit-message: "apply version updates" - labels: "version updates" + commit-message: 'apply version updates' + labels: 'version updates' body: ${{ steps.covector.outputs.change }} - update-docs: - needs: version-or-publish - if: needs.version-or-publish.outputs.successfulPublish == 'true' - runs-on: ubuntu-latest - steps: - # Setup - - name: checkout tauri - uses: actions/checkout@v2 - with: - path: tauri - - name: checkout tauri-docs - uses: actions/checkout@v2 + - name: Trigger doc update + if: steps.covector.outputs.successfulPublish == 'true' + uses: peter-evans/repository-dispatch@v1 with: + token: ${{ secrets.TAURI_BOT_PAT }} repository: tauri-apps/tauri-docs - path: tauri-docs - - name: checkout tauri-search-bot - uses: actions/checkout@v2 - with: - repository: tauri-apps/tauri-search-bot - path: tauri-search-bot - - name: install webkit2gtk - run: | - sudo apt-get update - sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf - - # Rust - - name: generate rust docs - working-directory: ./tauri/core/tauri - run: cargo doc --no-deps - - name: run rustdocusaurus - uses: tauri-apps/rustdocusaurus/github-action@v1.0.3 - with: - originPath: ./tauri/target/doc/ - targetPath: ./tauri-docs/docs/en/api/rust/ - sidebarPath: ./tauri-docs/sidebars/rustdoc.json - linksRoot: "" - cratesToProcess: "tauri" - - # TypeScript - - name: run typedocusaurus - uses: tauri-apps/typedocusaurus@v1 - with: - originPath: ./tauri/tooling/api/ - sidebarFile: ./tauri-docs/sidebars/typedoc.json - targetPath: ./tauri-docs/en/api/js/ - docusaurusPath: ./tauri-docs/ + event-type: update-docs - # Moving docs for Indexation - - name: copy docs - working-directory: ./tauri - run: mv docs/sidebar.json ../tauri-docs/sidebars/core.json && cp -r docs ../tauri-docs/docs/en - - # Indexing - - name: meilisearch indexation - uses: tauri-apps/docusaurus-meilisearch-indexer@v1 - with: - version: ${{ github.event.release.tag_name }} - docusaurusPath: ./tauri-docs - host: https://search.tauri.studio - apiKey: ${{ secrets.MEILISEARCH_APIKEY }} - docs: "Getting started,Usage,API" - - # Applying Version - - name: set docs' Tauri version - working-directory: ./tauri-docs - run: echo ${{ github.event.release.tag_name }} > version.txt - - name: set bot's Tauri version - working-directory: ./tauri-search-bot - run: echo ${{ github.event.release.tag_name }} > version.txt - - - uses: iamsauravsharma/create-dotenv@v1.1.0 - with: - directory: './tauri-search-bot' - env: - ENV_KEY_DISCORD_BOT_SECRET: ${{ secrets.DISCORD_BOT_SECRET }} - ENV_KEY_PREFIX: \! - ENV_KEY_SITE: tauri.studio - ENV_KEY_ICON: https://i.imgur.com/UzDERvw.png - ENV_KEY_LIMIT: 5 - ENV_KEY_SEARCH_INDEX: ${{ github.event.release.tag_name }} - ENV_KEY_MEILISEARCH_PUBLIC_KEY: ea0105f56bb5a2111ed28c7a0c637fc0bed07273f571dc7cb1f73900e44f8e7f - - # Bot Deployment - - name: scp bot - uses: appleboy/scp-action@master - with: - host: ${{ secrets.DISCORD_BOT_HOST }} - username: ${{ secrets.DISCORD_BOT_SSH_USER }} - key: ${{ secrets.DISCORD_BOT_SSH_KEY }} - source: "./tauri-search-bot" - target: "~/tauri-search-bot" - - name: restart the bot - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.DISCORD_BOT_HOST }} - username: ${{ secrets.DISCORD_BOT_SSH_USER }} - key: ${{ secrets.DISCORD_BOT_SSH_KEY }} - script: cd ~/tauri-search-bot && yarn && forever stopall && forever start ./src/index.js - - # tauri-docs PR - - name: git config - run: | - git config --global user.name "${{ github.event.pusher.name }}" - git config --global user.email "${{ github.event.pusher.email }}" - - name: create pull request for updated docs - uses: tauri-apps/create-pull-request@v3.4.1 + - name: Trigger cli.js publishing workflow + if: | + steps.covector.outputs.successfulPublish == 'true' && + contains(steps.covector.outputs.packagesPublished, 'tauri-cli') + uses: peter-evans/repository-dispatch@v1 with: token: ${{ secrets.TAURI_BOT_PAT }} - commit-message: "chore(docs): Update Rust & TS docs" - branch: docs/release - path: tauri-docs - title: Update Docs - labels: "new release" - body: | - These are the updated docs from the most recent release. + repository: tauri-apps/tauri + event-type: publish-clijs diff --git a/.github/workflows/js-lint.yml b/.github/workflows/js-lint.yml index 5528c41203ba..4da6b3a82c65 100644 --- a/.github/workflows/js-lint.yml +++ b/.github/workflows/js-lint.yml @@ -8,7 +8,7 @@ on: pull_request: paths: - '.github/workflows/js-lint.yml' - - 'tooling/cli.js/**' + - 'tooling/cli/node/**' - 'tooling/api/**' - 'tooling/create-tauri-app/**' @@ -17,17 +17,20 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: node-version: '12' + cache: yarn + cache-dependency-path: tooling/*/yarn.lock - name: install cli.js deps via yarn - working-directory: ./tooling/cli.js/ + working-directory: ./tooling/cli/node/ run: yarn - - name: run cli.js lint - working-directory: ./tooling/cli.js/ - run: yarn lint + # nothing to lint + #- name: run cli.js lint + # working-directory: ./tooling/cli/node/ + # run: yarn lint - name: run cli.js format - working-directory: ./tooling/cli.js/ + working-directory: ./tooling/cli/node/ run: yarn format:check - name: install api deps via yarn diff --git a/.github/workflows/publish-cli.yml b/.github/workflows/publish-cli.yml new file mode 100644 index 000000000000..3a8595cd7eed --- /dev/null +++ b/.github/workflows/publish-cli.yml @@ -0,0 +1,390 @@ +name: publish cli.js +env: + DEBUG: napi:* + APP_NAME: cli + MACOSX_DEPLOYMENT_TARGET: '10.13' +on: + workflow_dispatch: + repository_dispatch: + types: [publish-clijs] + +defaults: + run: + working-directory: tooling/cli/node/ + +jobs: + build: + strategy: + fail-fast: false + matrix: + settings: + - host: macos-latest + target: x86_64-apple-darwin + architecture: x64 + build: | + yarn build + strip -x *.node + - host: windows-latest + build: yarn build + target: x86_64-pc-windows-msvc + architecture: x64 + - host: ubuntu-18.04 + target: x86_64-unknown-linux-gnu + architecture: x64 + docker: | + docker pull $DOCKER_REGISTRY_URL/napi-rs/napi-rs/nodejs-rust:lts-debian + docker tag $DOCKER_REGISTRY_URL/napi-rs/napi-rs/nodejs-rust:lts-debian builder + build: | + docker run --rm -v ~/.cargo/git:/root/.cargo/git -v ~/.cargo/registry:/root/.cargo/registry -v $(pwd)/../../../:/build -w /build builder sh -c "cd tooling/cli/node && yarn build && strip *.node" + - host: ubuntu-18.04 + target: x86_64-unknown-linux-musl + architecture: x64 + docker: | + docker pull $DOCKER_REGISTRY_URL/napi-rs/napi-rs/nodejs-rust:lts-alpine + docker tag $DOCKER_REGISTRY_URL/napi-rs/napi-rs/nodejs-rust:lts-alpine builder + build: docker run --rm -v ~/.cargo/git:/root/.cargo/git -v ~/.cargo/registry:/root/.cargo/registry -v $(pwd)/../../../:/build -w /build builder sh -c "cd tooling/cli/node && yarn build && strip *.node" + - host: macos-latest + target: aarch64-apple-darwin + build: | + yarn build --target=aarch64-apple-darwin + strip -x *.node + - host: ubuntu-18.04 + architecture: x64 + target: aarch64-unknown-linux-gnu + setup: | + sudo apt-get update + sudo apt-get install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu -y + build: | + yarn build --target=aarch64-unknown-linux-gnu + aarch64-linux-gnu-strip *.node + - host: ubuntu-18.04 + architecture: x64 + target: armv7-unknown-linux-gnueabihf + setup: | + sudo apt-get update + sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y + build: | + yarn build --target=armv7-unknown-linux-gnueabihf + arm-linux-gnueabihf-strip *.node + - host: ubuntu-18.04 + architecture: x64 + target: aarch64-unknown-linux-musl + downloadTarget: aarch64-unknown-linux-musl + docker: | + docker pull ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine + docker tag ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine builder + build: | + docker run --rm -v ~/.cargo/git:/root/.cargo/git -v ~/.cargo/registry:/root/.cargo/registry -v $(pwd)/../../../:/build -w /build builder sh -c "cd tooling/cli/node && yarn build --target=aarch64-unknown-linux-musl && /aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip *.node" + #- host: windows-latest + # architecture: x64 + # target: aarch64-pc-windows-msvc + # build: yarn build --target aarch64-pc-windows-msvc + name: stable - ${{ matrix.settings.target }} - node@16 + runs-on: ${{ matrix.settings.host }} + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 16 + check-latest: true + cache: yarn + cache-dependency-path: 'tooling/cli/node/yarn.lock' + architecture: ${{ matrix.settings.architecture }} + - name: Install + uses: actions-rs/toolchain@v1 + with: + profile: minimal + override: true + toolchain: stable + target: ${{ matrix.settings.target }} + # should be committed + #- name: Generate Cargo.lock + # uses: actions-rs/cargo@v1 + # with: + # command: generate-lockfile + - uses: Swatinem/rust-cache@v1 + with: + key: ${{ matrix.settings.target }} + working-directory: 'tooling/cli/' + - name: Pull latest image + run: ${{ matrix.settings.docker }} + env: + DOCKER_REGISTRY_URL: ghcr.io + if: ${{ matrix.settings.docker }} + - name: Setup toolchain + run: ${{ matrix.settings.setup }} + if: ${{ matrix.settings.setup }} + shell: bash + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Build + run: ${{ matrix.settings.build }} + shell: bash + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: bindings-${{ matrix.settings.target }} + path: tooling/cli/node/${{ env.APP_NAME }}.*.node + if-no-files-found: error + # build-freebsd: + # runs-on: macos-10.15 + # name: Build FreeBSD + # steps: + # - uses: actions/checkout@v2 + # - name: Build + # id: build + # uses: vmactions/freebsd-vm@v0.1.5 + # env: + # DEBUG: napi:* + # RUSTUP_HOME: /usr/local/rustup + # CARGO_HOME: /usr/local/cargo + # RUSTUP_IO_THREADS: 1 + # with: + # envs: DEBUG RUSTUP_HOME CARGO_HOME RUSTUP_IO_THREADS + # usesh: true + # mem: 3000 + # prepare: | + # pkg install -y curl node14 python2 + # curl -qL https://www.npmjs.com/install.sh | sh + # npm install -g yarn + # curl https://sh.rustup.rs -sSf --output rustup.sh + # sh rustup.sh -y --profile minimal --default-toolchain stable + # export PATH="/usr/local/cargo/bin:$PATH" + # echo "~~~~ rustc --version ~~~~" + # rustc --version + # echo "~~~~ node -v ~~~~" + # node -v + # echo "~~~~ yarn --version ~~~~" + # yarn --version + # run: | + # export PATH="/usr/local/cargo/bin:$PATH" + # pwd + # ls -lah + # whoami + # env + # freebsd-version + # cd ./tooling/cli/node/ + # yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + # yarn build + # strip -x *.node + # rm -rf node_modules + # rm -rf ../target + # - name: Upload artifact + # uses: actions/upload-artifact@v2 + # with: + # name: bindings-freebsd + # path: tooling/cli/node/${{ env.APP_NAME }}.*.node + # if-no-files-found: error + test-macOS-windows-binding: + name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + settings: + - host: macos-latest + target: 'x86_64-apple-darwin' + - host: windows-latest + target: x86_64-pc-windows-msvc + node: + - '12' + - '14' + - '16' + runs-on: ${{ matrix.settings.host }} + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + check-latest: true + cache: yarn + cache-dependency-path: 'tooling/cli/node/yarn.lock' + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-${{ matrix.settings.target }} + path: 'tooling/cli/node/' + - name: List packages + run: ls -R . + shell: bash + - name: Test bindings + run: yarn test + test-linux-x64-gnu-binding: + name: Test bindings on Linux-x64-gnu - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: + - '12' + - '14' + - '16' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + check-latest: true + cache: yarn + cache-dependency-path: 'tooling/cli/node/yarn.lock' + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-x86_64-unknown-linux-gnu + path: 'tooling/cli/node/' + - name: List packages + run: ls -R . + shell: bash + - name: install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf + - name: Test bindings + run: yarn test + test-linux-x64-musl-binding: + name: Test bindings on x86_64-unknown-linux-musl - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: + - '12' + - '14' + - '16' + runs-on: ubuntu-latest + container: + image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + check-latest: true + cache: yarn + cache-dependency-path: 'tooling/cli/node/yarn.lock' + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-x86_64-unknown-linux-musl + path: 'tooling/cli/node/' + - name: List packages + run: ls -R . + shell: bash + - name: Install system dependencies + run: | + apk add openssl-dev musl-dev glib-dev cairo-dev pkgconfig gdk-pixbuf-dev webkit2gtk-dev curl libappindicator-dev patchelf librsvg-dev gtk+3.0-dev + - name: Setup and run tests + run: | + yarn tauri --help + ls -la + # TODO: fix this test: https://github.com/tauri-apps/tauri/runs/5145729140?check_suite_focus=true#step:9:704 + #- name: Setup and run tests + # run: | + # rustup install stable + # rustup default stable + # yarn test + # ls -la + test-linux-arm-bindings: + name: Test bindings on ${{ matrix.image }} - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: + - '12' + - '14' + - '16' + image: + - ghcr.io/napi-rs/napi-rs/nodejs:aarch64-16 + - ghcr.io/napi-rs/napi-rs/nodejs:armhf-16 + runs-on: ubuntu-latest + steps: + - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + working-directory: ${{ github.workspace }} + - uses: actions/checkout@v2 + - name: List packages + run: ls -R . + shell: bash + - name: Install dependencies + run: yarn install --ignore-scripts --ignore-platform --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download aarch64-gnu artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-aarch64-unknown-linux-gnu + path: 'tooling/cli/node/' + - name: Download armv7-gnueabihf artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-armv7-unknown-linux-gnueabihf + path: 'tooling/cli/node/' + # TODO: actually run test, blocked by https://github.com/rust-lang/cargo/issues/8719 + - uses: addnab/docker-run-action@v3 + with: + image: ${{ matrix.image }} + options: '-v ${{ github.workspace }}:/build -w /build -e RUSTUP_HOME=/usr/local/rustup -e CARGO_HOME=/usr/local/cargo' + shell: bash + run: | + set -e + export PATH=/usr/local/cargo/bin/:/usr/local/fnm:$PATH + apt-get update + DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install --no-install-recommends -y unzip libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf + bash + curl https://sh.rustup.rs -sSf | bash -s -- -y + curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir "/usr/local/fnm" --skip-shell + eval "$(fnm env --use-on-cd)" + fnm install ${{ matrix.node }} + fnm use ${{ matrix.node }} + cd tooling/cli/node + yarn tauri --help + ls -la + publish: + name: Publish + runs-on: ubuntu-latest + needs: + #- build-freebsd + - test-macOS-windows-binding + - test-linux-x64-gnu-binding + - test-linux-x64-musl-binding + #- test-linux-arm-bindings + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 16 + check-latest: true + cache: yarn + cache-dependency-path: 'tooling/cli/node/yarn.lock' + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download all artifacts + uses: actions/download-artifact@v2 + with: + path: tooling/cli/node/artifacts + - name: Move artifacts + run: yarn artifacts + - name: List packages + run: ls -R ./npm + shell: bash + - name: Publish + run: | + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + npm publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/test-bundler.yml b/.github/workflows/test-bundler.yml index 6f88392d8dee..37f0c047643f 100644 --- a/.github/workflows/test-bundler.yml +++ b/.github/workflows/test-bundler.yml @@ -8,6 +8,7 @@ on: push: branches: - dev + - next pull_request: paths: - '.github/workflows/test-bundler.yml' @@ -72,7 +73,7 @@ jobs: with: path: tooling/bundler/target # Add date to the cache to keep it up to date - key: ubuntu-latest-stable-cargo-bundler-${{ hashFiles('tooling/bundler/Cargo.lock') }}-${{ env.CURRENT_DATE }} + key: ${{ matrix.platform }}-stable-cargo-bundler-${{ hashFiles('tooling/bundler/Cargo.lock') }}-${{ env.CURRENT_DATE }} # Restore from outdated cache for speed restore-keys: | ${{ matrix.platform }}-stable-cargo-bundler-${{ hashFiles('tooling/bundler/Cargo.lock') }} diff --git a/.github/workflows/test-core.yml b/.github/workflows/test-core.yml index 6a8967dac56b..0da34e220738 100644 --- a/.github/workflows/test-core.yml +++ b/.github/workflows/test-core.yml @@ -8,6 +8,7 @@ on: push: branches: - dev + - next pull_request: paths: - '.github/workflows/test-core.yml' @@ -19,7 +20,7 @@ env: RUST_BACKTRACE: 1 jobs: - build-tauri-core: + test-tauri-core: runs-on: ${{ matrix.platform }} strategy: @@ -83,6 +84,8 @@ jobs: - name: test run: | cargo test + cargo test --features api-all + cargo test --features compression,wry,isolation,custom-protocol,api-all,cli,updater,system-tray test-tauri-cli: runs-on: ${{ matrix.platform }} @@ -107,7 +110,7 @@ jobs: - name: Get current date if: matrix.platform == 'windows-latest' run: echo "CURRENT_DATE=$(Get-Date -Format "yyyy-MM-dd")" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - + - name: Cache cargo registry uses: actions/cache@v2.1.4 with: @@ -133,19 +136,19 @@ jobs: - name: Cache CLI cargo target uses: actions/cache@v2 with: - path: tooling/cli.rs/target + path: tooling/cli/target # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }}-${{ env.CURRENT_DATE }} + key: ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }}-${{ env.CURRENT_DATE }} # Restore from outdated cache for speed restore-keys: | - ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }} + ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }} ${{ matrix.platform }}-stable-cargo-cli- - name: build CLI uses: actions-rs/cargo@v1 with: command: build - args: --manifest-path ./tooling/cli.rs/Cargo.toml + args: --manifest-path ./tooling/cli/Cargo.toml test-tauri-js-cli: runs-on: ${{ matrix.platform }} @@ -157,6 +160,17 @@ jobs: steps: - uses: actions/checkout@v2 + - name: install Rust stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - name: setup node + uses: actions/setup-node@v2 + with: + node-version: 14 + cache: yarn + cache-dependency-path: tooling/cli/node/yarn.lock - name: install webkit2gtk (ubuntu only) if: matrix.platform == 'ubuntu-latest' run: | @@ -170,7 +184,7 @@ jobs: - name: Get current date if: matrix.platform == 'windows-latest' run: echo "CURRENT_DATE=$(Get-Date -Format "yyyy-MM-dd")" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - + - name: Cache cargo registry uses: actions/cache@v2.1.4 with: @@ -196,21 +210,29 @@ jobs: - name: Cache CLI cargo target uses: actions/cache@v2 with: - path: tooling/cli.rs/target + path: tooling/cli/target # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }}-${{ env.CURRENT_DATE }} + key: ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }}-${{ env.CURRENT_DATE }} # Restore from outdated cache for speed restore-keys: | - ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }} + ${{ matrix.platform }}-stable-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }} ${{ matrix.platform }}-stable-cargo-cli- + - name: Cache template cargo target + uses: actions/cache@v2 + with: + path: tooling/cli/node/test/jest/fixtures/empty/src-tauri/target + # Add date to the cache to keep it up to date + key: ${{ matrix.platform }}-stable-template-${{ hashFiles('tooling/cli/templates/app/**') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ${{ matrix.platform }}-stable-template-${{ hashFiles('tooling/cli/templates/app/**') }} + ${{ matrix.platform }}-stable-template- + - name: test timeout-minutes: 30 run: | - cd ./tooling/cli.js + cd ./tooling/cli/node yarn + yarn build yarn test - - name: run release build - timeout-minutes: 15 - working-directory: tooling/cli.js - run: yarn build-release diff --git a/.github/workflows/test-cta.yml b/.github/workflows/test-cta.yml index 85141d712d73..c8e45a74d1fe 100644 --- a/.github/workflows/test-cta.yml +++ b/.github/workflows/test-cta.yml @@ -5,30 +5,30 @@ name: test create-tauri-app env: RUST_BACKTRACE: 1 - TAURI_RECIPE: 'vanillajs,cra,vite,ngcli' + TAURI_RECIPE: 'vanillajs,cra,vite,ngcli,solid' on: workflow_dispatch: inputs: platform: - default: "ubuntu" + default: 'ubuntu' pull_request: paths: - - "tooling/create-tauri-app/**" + - 'tooling/create-tauri-app/**' jobs: create-recipe-with-npm: - name: "node@${{ matrix.node }} + npm@${{ matrix.manager }}" + name: 'node@${{ matrix.node }} + npm@${{ matrix.manager }}' runs-on: ${{ github.event.inputs.platform || 'ubuntu' }}-latest strategy: fail-fast: false matrix: - node: ["14", "16"] - manager: ["7"] + node: ['14', '16'] + manager: ['7'] exclude: - - node: "16" - manager: "6" + - node: '16' + manager: '6' steps: - uses: actions/checkout@v2 @@ -46,10 +46,10 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf - - run: yarn - working-directory: tooling/cli.js - - run: yarn build - working-directory: tooling/cli.js + #- run: yarn + # working-directory: tooling/cli/node + #- run: yarn build + # working-directory: tooling/cli/node - run: yarn working-directory: tooling/api - run: yarn build @@ -61,7 +61,7 @@ jobs: - run: yarn test working-directory: tooling/create-tauri-app env: - TAURI_RUN_MANAGER: "npm" + TAURI_RUN_MANAGER: 'npm' # create-recipe-with-yarn: # name: "node@${{ matrix.node }} + yarn@1" diff --git a/.github/workflows/udeps.yml b/.github/workflows/udeps.yml index 23f3014ab121..9b2fa8c91ed6 100644 --- a/.github/workflows/udeps.yml +++ b/.github/workflows/udeps.yml @@ -10,99 +10,99 @@ on: - '.github/workflows/udeps.yml' - 'core/**' - 'tooling/bundler/**' - - 'tooling/cli.rs/**' + - 'tooling/cli/**' jobs: udeps: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: nightly - override: true + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true - - name: Get current date - run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV + - name: Get current date + run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - - name: Cache cargo registry - uses: actions/cache@v2.1.4 - with: - path: ~/.cargo/registry - # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-registry-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} - # Restore from outdated cache for speed - restore-keys: | - ubuntu-latest-nightly-cargo-registry-${{ hashFiles('**/Cargo.toml') }} - ubuntu-latest-nightly-cargo-registry- + - name: Cache cargo registry + uses: actions/cache@v2.1.4 + with: + path: ~/.cargo/registry + # Add date to the cache to keep it up to date + key: ubuntu-latest-nightly-cargo-registry-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ubuntu-latest-nightly-cargo-registry-${{ hashFiles('**/Cargo.toml') }} + ubuntu-latest-nightly-cargo-registry- - - name: Cache cargo index - uses: actions/cache@v2.1.4 - with: - path: ~/.cargo/git - # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-index-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} - # Restore from outdated cache for speed - restore-keys: | - ubuntu-latest-nightly-cargo-index-${{ hashFiles('**/Cargo.toml') }} - ubuntu-latest-nightly-cargo-index- + - name: Cache cargo index + uses: actions/cache@v2.1.4 + with: + path: ~/.cargo/git + # Add date to the cache to keep it up to date + key: ubuntu-latest-nightly-cargo-index-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ubuntu-latest-nightly-cargo-index-${{ hashFiles('**/Cargo.toml') }} + ubuntu-latest-nightly-cargo-index- - - name: Cache core cargo target - uses: actions/cache@v2 - with: - path: target - # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-core-${{ hashFiles('core/**/Cargo.toml') }}-${{ env.CURRENT_DATE }} - # Restore from outdated cache for speed - restore-keys: | - ubuntu-latest-nightly-cargo-core-${{ hashFiles('core/**/Cargo.toml') }} - ubuntu-latest-nightly-cargo-core- + - name: Cache core cargo target + uses: actions/cache@v2 + with: + path: target + # Add date to the cache to keep it up to date + key: ubuntu-latest-nightly-cargo-core-${{ hashFiles('core/**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ubuntu-latest-nightly-cargo-core-${{ hashFiles('core/**/Cargo.toml') }} + ubuntu-latest-nightly-cargo-core- - - name: Cache bundler cargo target - uses: actions/cache@v2 - with: - path: tooling/bundler/target - # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-bundler-${{ hashFiles('tooling/bundler/Cargo.lock') }}-${{ env.CURRENT_DATE }} - # Restore from outdated cache for speed - restore-keys: | - ubuntu-latest-nightly-cargo-bundler-${{ hashFiles('tooling/bundler/Cargo.lock') }} - ubuntu-latest-nightly-cargo-bundler- + - name: Cache bundler cargo target + uses: actions/cache@v2 + with: + path: tooling/bundler/target + # Add date to the cache to keep it up to date + key: ubuntu-latest-nightly-cargo-bundler-${{ hashFiles('tooling/bundler/Cargo.lock') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ubuntu-latest-nightly-cargo-bundler-${{ hashFiles('tooling/bundler/Cargo.lock') }} + ubuntu-latest-nightly-cargo-bundler- - - name: Cache CLI cargo target - uses: actions/cache@v2 - with: - path: tooling/cli.rs/target - # Add date to the cache to keep it up to date - key: ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }}-${{ env.CURRENT_DATE }} - # Restore from outdated cache for speed - restore-keys: | - ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli.rs/Cargo.lock') }} - ubuntu-latest-nightly-cargo-cli- + - name: Cache CLI cargo target + uses: actions/cache@v2 + with: + path: tooling/cli/target + # Add date to the cache to keep it up to date + key: ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ubuntu-latest-nightly-cargo-cli-${{ hashFiles('tooling/cli/Cargo.lock') }} + ubuntu-latest-nightly-cargo-cli- - - uses: actions-rs/cargo@v1 - with: - command: install - args: cargo-udeps --locked + - uses: actions-rs/cargo@v1 + with: + command: install + args: cargo-udeps --locked - - name: Install required packages - run: | - sudo apt-get update - sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf + - name: Install required packages + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf - - uses: actions-rs/cargo@v1 - with: - command: udeps - args: --all-targets --all-features + - uses: actions-rs/cargo@v1 + with: + command: udeps + args: --all-targets --all-features - - uses: actions-rs/cargo@v1 - with: - command: udeps - args: --manifest-path ./tooling/bundler/Cargo.toml --all-targets --all-features + - uses: actions-rs/cargo@v1 + with: + command: udeps + args: --manifest-path ./tooling/bundler/Cargo.toml --all-targets --all-features - - uses: actions-rs/cargo@v1 - with: - command: udeps - args: --manifest-path ./tooling/cli.rs/Cargo.toml --all-targets --all-features + - uses: actions-rs/cargo@v1 + with: + command: udeps + args: --manifest-path ./tooling/cli/Cargo.toml --all-targets --all-features diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml deleted file mode 100644 index fa1a1cb1b227..000000000000 --- a/.github/workflows/update-docs.yml +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2019-2021 Tauri Programme within The Commons Conservancy -# SPDX-License-Identifier: Apache-2.0 -# SPDX-License-Identifier: MIT - -name: update-docs - -on: - release: - types: [published] - workflow_dispatch: - inputs: - gitName: - description: "git name for PR" - required: false - default: "tauri-bot" - gitEmail: - description: "git email for PR" - required: false - default: "tauri-bot@tauri.studio" - version: - description: "Tauri version" - required: true - -jobs: - update-docs: - runs-on: ubuntu-latest - steps: - # Setup - - name: checkout tauri - uses: actions/checkout@v2 - with: - path: tauri - - name: checkout tauri-docs - uses: actions/checkout@v2 - with: - repository: tauri-apps/tauri-docs - path: tauri-docs - - name: checkout tauri-search-bot - uses: actions/checkout@v2 - with: - repository: tauri-apps/tauri-search-bot - path: tauri-search-bot - - name: install webkit2gtk - run: | - sudo apt-get update - sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf - - # Rust - - name: generate rust docs - working-directory: ./tauri/core/tauri - run: cargo doc --no-deps - - name: run rustdocusaurus - uses: tauri-apps/rustdocusaurus/github-action@v1 - with: - originPath: ./tauri/target/doc/ - targetPath: ./tauri-docs/docs/en/api/rust/ - sidebarPath: "${{ github.workspace }}/tauri-docs/sidebars/rustdoc.json" - linksRoot: "" - cratesToProcess: "tauri" - - # TypeScript - - name: install API deps - working-directory: ./tauri/tooling/api - run: yarn && yarn add typescript@4.2 - - name: run typedocusaurus - uses: tauri-apps/typedocusaurus@v1 - with: - originPath: ./tauri/tooling/api/ - sidebarFile: "${{ github.workspace }}/tauri-docs/sidebars/typedoc.json" - targetPath: ${{ github.workspace }}/tauri-docs/docs/en/api/js - docusaurusPath: ./tauri-docs/ - - # Moving docs for Indexation - - name: copy docs - working-directory: ./tauri - run: mv docs/sidebar.json ${{ github.workspace }}/tauri-docs/sidebars/core.json && cp -r docs/* ${{ github.workspace }}/tauri-docs/docs/en - - # Indexing - - name: meilisearch indexation - uses: tauri-apps/docusaurus-meilisearch-indexer@v1 - with: - version: ${{ github.event.inputs.version || github.event.release.tag_name }} - docusaurusPath: "${{ github.workspace }}/tauri-docs" - host: https://search.tauri.studio - apiKey: ${{ secrets.MEILISEARCH_APIKEY }} - docs: "Getting started,Usage,API" - - # Applying Version - - name: set docs' Tauri version - working-directory: ./tauri-docs - run: echo ${{ github.event.inputs.version || github.event.release.tag_name }} > version.txt - - name: set bot's Tauri version - working-directory: ./tauri-search-bot - run: echo ${{ github.event.inputs.version || github.event.release.tag_name }} > version.txt - - - uses: iamsauravsharma/create-dotenv@v1.1.0 - with: - directory: './tauri-search-bot' - env: - ENV_KEY_DISCORD_BOT_SECRET: ${{ secrets.DISCORD_BOT_SECRET }} - ENV_KEY_PREFIX: \! - ENV_KEY_SITE: tauri.studio - ENV_KEY_ICON: https://i.imgur.com/UzDERvw.png - ENV_KEY_LIMIT: 5 - ENV_KEY_SEARCH_INDEX: ${{ github.event.release.tag_name }} - ENV_KEY_MEILISEARCH_PUBLIC_KEY: ea0105f56bb5a2111ed28c7a0c637fc0bed07273f571dc7cb1f73900e44f8e7f - - # Bot Deployment - - name: scp bot - uses: appleboy/scp-action@master - with: - host: ${{ secrets.DISCORD_BOT_HOST }} - username: ${{ secrets.DISCORD_BOT_SSH_USER }} - key: ${{ secrets.DISCORD_BOT_SSH_KEY }} - source: "${{ github.workspace }}/tauri-search-bot" - target: "~/tauri-search-bot" - - name: restart the bot - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.DISCORD_BOT_HOST }} - username: ${{ secrets.DISCORD_BOT_SSH_USER }} - key: ${{ secrets.DISCORD_BOT_SSH_KEY }} - script: cd ~/tauri-search-bot/github/workspace/tauri-search-bot/ && yarn && forever stopall && forever start ./src/index.js - - # tauri-docs PR - - name: git config - run: | - git config --global user.name "${{ github.event.inputs.gitName }}" - git config --global user.email "${{ github.event.inputs.gitEmail }}" - - name: create pull request for updated docs - uses: tauri-apps/create-pull-request@v3.4.1 - with: - token: ${{ secrets.TAURI_BOT_PAT }} - commit-message: "chore(docs): Update Rust & TS docs" - branch: docs/release - path: tauri-docs - title: Update Docs - labels: "new release" - body: | - These are the updated docs from the most recent release. diff --git a/.gitignore b/.gitignore index 40f8bc2233dd..cc1a831a3e49 100644 --- a/.gitignore +++ b/.gitignore @@ -69,11 +69,6 @@ package-lock.json proptest-regressions/ TODO.md - -# Tauri output -/bundle.json -/config.json - # rust compiled folders target @@ -82,12 +77,6 @@ target /tooling/bench/tests/Cargo.lock /yarn.lock -/tooling/cli.js/test/jest/tmp - -# doing this because of how our tests currently (naively) drop the tauri.conf.js in that folder -# todo: needs a proper fic -/tooling/cli.js/tauri.conf.js - # ignore frida handlers __handlers__/ diff --git a/.husky/pre-commit b/.husky/pre-commit index 1f5cbfeeeff9..1b7d9d961672 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -15,13 +15,12 @@ else cd ../.. fi -if [ -z "$(git diff --name-only tooling/cli.js)" ]; then +if [ -z "$(git diff --name-only tooling/cli/node)" ]; then echo "skipping cli.js - no changes detected" else - cd tooling/cli.js + cd tooling/cli/node yarn format - yarn lint-fix - cd ../.. + cd ../../.. fi if [ -z "$(git diff --name-only tooling/create-tauri-app)" ]; then diff --git a/.scripts/covector/sync-cli-metadata.js b/.scripts/covector/sync-cli-metadata.js new file mode 100644 index 000000000000..cd1ceaa5388c --- /dev/null +++ b/.scripts/covector/sync-cli-metadata.js @@ -0,0 +1,49 @@ +#!/usr/bin/env node + // Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +/* +This script is solely intended to be run as part of the `covector version` step to +keep the `../tooling/cli/metadata.json` up to date with other version bumps. Long term +we should look to find a more "rusty way" to import / "pin" a version value in our cli.rs +rust binaries. +*/ + +const { + readFileSync, + writeFileSync +} = require('fs') + +const filePath = `../../tooling/cli/metadata.json` +const packageNickname = process.argv[2] +const bump = process.argv[3] +if (bump !== 'prerelease' && bump !== 'prepatch') { + throw new Error( + `We don't handle anything except prerelease right now. Exiting.` + ) +} + +const inc = (version) => { + const v = version.split('.') + const n = v[v.length - 1] + v[v.length - 1] = String(Number(n) + 1) + return v.join('.') +} + +// read file into js object +const metadata = JSON.parse(readFileSync(filePath, 'utf-8')) + +// set field version +let version +if (packageNickname === 'cli.js') { + version = inc(metadata[packageNickname].version) + metadata[packageNickname].version = version +} else { + version = inc(metadata[packageNickname]) + metadata[packageNickname] = version +} + +writeFileSync(filePath, JSON.stringify(metadata, null, 2) + '\n') +console.log(`wrote ${version} for ${packageNickname} into metadata.json`) +console.dir(metadata) diff --git a/.scripts/sync-prerelease.js b/.scripts/covector/sync-prerelease.js similarity index 91% rename from .scripts/sync-prerelease.js rename to .scripts/covector/sync-prerelease.js index 48a9cdd78443..b7a9c3c63d2a 100644 --- a/.scripts/sync-prerelease.js +++ b/.scripts/covector/sync-prerelease.js @@ -1,14 +1,17 @@ #!/usr/bin/env node -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy + // Copyright 2019-2021 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT /* This script is solely intended to be run as part of the `covector version` step to -keep the `tauri-runtime`, `tauri-runtime-wry` and `tauri-driver` crates version without the `beta` or `beta-rc` suffix. +keep the `tauri-runtime`, `tauri-runtime-wry` and `tauri-driver` crates version without the `beta` or `rc` suffix. */ -const { readFileSync, writeFileSync } = require('fs') +const { + readFileSync, + writeFileSync +} = require('fs') const packageNickname = process.argv[2] const bump = process.argv[3] diff --git a/.scripts/setup.ps1 b/.scripts/setup.ps1 index 29b9525da7b5..4d435d46534b 100644 --- a/.scripts/setup.ps1 +++ b/.scripts/setup.ps1 @@ -9,7 +9,7 @@ yarn; yarn build cd ..\.. echo "Installing the Tauri Rust CLI..." -cd tooling\cli.rs +cd tooling\cli cargo install --path . cd ..\.. echo "Tauri Rust CLI installed. Run it with '$ cargo tauri [COMMAND]'." @@ -21,9 +21,9 @@ $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) $result = $host.ui.PromptForChoice("Node.js CLI", "Do you want to install the Node.js CLI?", $options, 1) switch ($result) { 0{ - cd tooling\cli.js + cd tooling\cli\node yarn; yarn build; yarn link cd ..\.. - echo "Tauri Node.js CLI installed. Run it with '$ tauri [COMMAND]'" + echo "Tauri Node.js CLI installed. use `yarn link @tauri-apps/cli` and run it with '$ yarn tauri [COMMAND]'." } } diff --git a/.scripts/setup.sh b/.scripts/setup.sh old mode 100644 new mode 100755 index a0f46cc5583b..0f2410946da8 --- a/.scripts/setup.sh +++ b/.scripts/setup.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash # Copyright 2019-2021 Tauri Programme within The Commons Conservancy # SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: MIT @@ -9,7 +9,7 @@ yarn && yarn build cd ../.. echo "Building the Tauri Rust CLI..." -cd tooling/cli.rs +cd tooling/cli cargo install --path . cd ../.. echo "Tauri Rust CLI installed. Run it with '$ cargo tauri [COMMAND]'." @@ -18,10 +18,10 @@ echo "Do you want to install the Node.js CLI?" select yn in "Yes" "No"; do case $yn in Yes ) - cd tooling/cli.js + cd tooling/cli/node yarn && yarn build && yarn link - cd ../.. - echo "Tauri Node.js CLI installed. Run it with '$ tauri [COMMAND]'." + cd ../../.. + echo "Tauri Node.js CLI installed. use `yarn link @tauri-apps/cli` and run it with '$ yarn tauri [COMMAND]'." break;; No ) break;; esac diff --git a/.scripts/sync-cli-metadata.js b/.scripts/sync-cli-metadata.js deleted file mode 100644 index 0ed5b9f23449..000000000000 --- a/.scripts/sync-cli-metadata.js +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -/* -This script is solely intended to be run as part of the `covector version` step to -keep the `../tooling/cli.rs/metadata.json` up to date with other version bumps. Long term -we should look to find a more "rusty way" to import / "pin" a version value in our cli.rs -rust binaries. -*/ - -const { readFileSync, writeFileSync } = require('fs') - -const filePath = `../../tooling/cli.rs/metadata.json` -const packageNickname = process.argv[2] -const bump = process.argv[3] -if (bump !== 'prerelease') { - throw new Error( - `We don't handle anything except prerelease right now. Exiting.` - ) -} - -const inc = (version) => { - const v = version.split('') - const n = v.pop() - return [...v, String(Number(n) + 1)].join('') -} - -// read file into js object -const metadata = JSON.parse(readFileSync(filePath, 'utf-8')) - -// set field version -let version -if (packageNickname === 'cli.js') { - version = inc(metadata[packageNickname].version) - metadata[packageNickname].version = version -} else { - version = inc(metadata[packageNickname]) - metadata[packageNickname] = version -} - -writeFileSync(filePath, JSON.stringify(metadata, null, 2) + '\n') -console.log(`wrote ${version} for ${packageNickname} into metadata.json`) -console.dir(metadata) diff --git a/.scripts/update-lockfiles.sh b/.scripts/update-lockfiles.sh new file mode 100755 index 000000000000..1a9c84cdecea --- /dev/null +++ b/.scripts/update-lockfiles.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env sh +# Copyright 2019-2021 Tauri Programme within The Commons Conservancy +# SPDX-License-Identifier: Apache-2.0 +# SPDX-License-Identifier: MIT + +declare -a examples=("api" "sidecar" "updater" "resources") +declare -a tooling=("bench" "cli" "webdriver") + +for example in "${examples[@]}" +do + cd examples/$example/src-tauri + cargo update + cargo build + cd ../../.. +done + +for tooling in "${tooling[@]}" +do + cd tooling/$tooling + cargo update + cargo build + cd ../.. +done + +cd tooling/bench/tests +cd cpu_intensive/src-tauri +cargo update +cargo build +cd ../../files_transfer/src-tauri +cargo update +cargo build +cd ../../../../.. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index af52c47fb7c4..8bb874e2cc5b 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -8,7 +8,7 @@ Tauri is a polyglot and generic toolkit that is very composable and allows engin Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the OS's webview. They do not ship a runtime, since the final binary is compiled from Rust. This makes the reversing of Tauri apps not a trivial task. ## What Tauri is NOT -- Tauri is not a lightweight kernel wrapper...instead it directly uses WRY and TAO to do the heavy-lifting in making system calls to the OS. +- Tauri is not a lightweight kernel wrapper...instead it directly uses [WRY](#wry) and [TAO](#tao) to do the heavy-lifting in making system calls to the OS. - Tauri is not a VM or virtualized environment...instead it is an application toolkit that allows making Webview OS applications. ## Major Components @@ -44,10 +44,10 @@ A typescript library that creates `cjs` and `esm` Javascript endpoints for you t #### [bundler](https://github.com/tauri-apps/tauri/tree/dev/tooling/bundler) [RUST / SHELL] The bundler is a library that builds a Tauri App for the platform triple it detects / is told. At the moment it currently supports macOS, Windows and Linux - but in the near future will support mobile platforms as well. May be used outside of Tauri projects. -#### [cli.js](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli.js) [JS] -Written in Typescript and packaged such that it can be used with `npm`, `pnpm`, and `yarn`, this library provides a node.js runner for common tasks when using Tauri, like `yarn tauri dev`. For the most part it is a wrapper around [cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli.rs). +#### [cli.js](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli/node) [JS] +It is a wrapper around [cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli) using [napi-rs](https://github.com/napi-rs/napi-rs) to produce NPM packages for each platform. -#### [cli.rs](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli.rs) [RUST] +#### [cli.rs](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli) [RUST] This rust executable provides the full interface to all of the required activities for which the CLI is required. It will run on macOS, Windows, and Linux. #### [create-tauri-app](https://github.com/tauri-apps/tauri/tree/dev/tooling/create-tauri-app) [JS] @@ -84,7 +84,7 @@ This plugin allows you to very quickly install tauri in a vue-cli project. ## [tauri-vscode](https://github.com/tauri-apps/tauri-vscode) This project enhances the VS Code interface with several nice-to-have features. -# Tauri Plugins [documentation](https://tauri.studio/en/docs/usage/guides/plugin) +# Tauri Plugins [documentation](https://tauri.studio/en/docs/guides/plugin) Generally speaking, plugins are authored by third parties (even though there may be official, supported plugins). A plugin generally does 3 things: 1. It provides rust code to do "something". diff --git a/Cargo.toml b/Cargo.toml index 0d00a02aa9b5..c95d732b27c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,10 @@ members = [ exclude = [ # examples that can be compiled with the tauri CLI "examples/api/src-tauri", - "examples/updater/src-tauri" + "examples/updater/src-tauri", + "examples/resources/src-tauri", + "examples/sidecar/src-tauri", + "examples/isolation/src-tauri" ] # default to small, optimized workspace release binaries diff --git a/README.md b/README.md index 2891c16bbebf..e1f04fe1742c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Tauri +Tauri [![status](https://img.shields.io/badge/Status-Beta-green.svg)](https://github.com/tauri-apps/tauri/tree/dev) [![License](https://img.shields.io/badge/License-MIT%20or%20Apache%202-green.svg)](https://opencollective.com/tauri) @@ -7,7 +7,7 @@ [![Chat Server](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/SpmNs4S) [![devto](https://img.shields.io/badge/blog-dev.to-black.svg)](https://dev.to/tauri) -[![devto](https://img.shields.io/badge/documentation-tauri.studio-purple.svg)](https://tauri.studio/docs/getting-started/intro) +[![devto](https://img.shields.io/badge/documentation-tauri.studio-purple.svg)](https://tauri.studio/docs/get-started/intro) [![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) [![support](https://img.shields.io/badge/sponsor-open%20collective-blue.svg)](https://opencollective.com/tauri) @@ -15,8 +15,8 @@ | Component | Description | Version | Lin | Win | Mac | | --------------------------------------------------------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --- | --- | --- | -| [**cli.rs**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli.rs) | create, develop and build apps | [![](https://img.shields.io/crates/v/tauri-cli.svg)](https://crates.io/crates/tauri-cli) | ✅ | ✅ | ✅ | -| [**cli.js**](https://github.com/tauri-apps/tauri/tree/dev/tooling/cli.js) | 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) | ✅ | ✅ | ✅ | +| [**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) | ✅ | ✅ | ✅ | +| [**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) | ✅ | ✅ | ✅ | | [**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) | ✅ | ✅ | ✅ | | [**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) | ✅ | ✅ | ✅ | | [**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) | ✅ | ✅ | ✅ | @@ -33,14 +33,14 @@ To learn more about the details of how all of these pieces fit together, please ## Get Started If 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: -#### Platforms +### Platforms - [x] Windows 7,8,10 - [x] Linux - [x] macOS - [ ] iOS (in progress) - [ ] android (soon) -#### App Bundles +### App Bundles - [x] App Icons - [x] Build on MacOS (.app, .dmg) - [x] Build on Linux (.deb, AppImage) @@ -77,7 +77,7 @@ If you are interested in making a tauri-app, please visit the [documentation web | -------------------------- | ------ | -------------------- | | Installer Size Linux | 3.1 MB | 52.1 MB | | Memory Consumption Linux | 180 MB | 462 MB | -| Launch Time Linux | 0.39s | 0.80s | +| Launch Time Linux | 0.39s | 0.80s | | Interface Service Provider | WRY | Chromium | | Backend Binding | Rust | Node.js (ECMAScript) | | Underlying Engine | Rust | V8 (C/C++) | @@ -85,8 +85,7 @@ If you are interested in making a tauri-app, please visit the [documentation web | Multithreading | Yes | Yes | | Bytecode Delivery | Yes | No | | Multiple Windows | Yes | Yes | -| Auto Updater | Yes | Yes (1) | -| Cross Platform | Yes | Yes | +| Auto Updater | Yes | Yes1 | | Custom App Icon | Yes | Yes | | Windows Binary | Yes | Yes | | MacOS Binary | Yes | Yes | @@ -104,16 +103,16 @@ If you are interested in making a tauri-app, please visit the [documentation web Tauri is a system composed of a number of moving pieces: ### Infrastructure -- git for code management -- github for project management -- github actions for CI and CD -- discord for discussions -- netlify-hosted documentation website -- digital ocean meilisearch instance +- Git for code management +- GitHub for project management +- GitHub actions for CI and CD +- Discord for discussions +- Netlify-hosted documentation website +- DigitalOcean meilisearch instance ### Major Runtimes -- node.js for running the CLI (deno and pure rust are on the roadmap) -- cargo for testing, running the dev service, building binaries and as the runtime harness for the webview +- Node.js for running the CLI (deno and pure rust are on the roadmap) +- Cargo for testing, running the dev service, building binaries and as the runtime harness for the webview ### Major Languages - Rust for the CLI @@ -124,8 +123,12 @@ Tauri is a system composed of a number of moving pieces: ### Operating systems Tauri 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. -### Contribution Flow -Before you start working on something, it is best to check if there is an existing issue first. Also it is a good idea to stop by the Discord guild and confirm with the team if it makes sense or if someone is already working on it. If you want to read more about this, please see [this page](https://github.com/tauri-apps/tauri/blob/dev/.github/CONTRIBUTING.md). +### Contributing +Before 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. + +Please make sure to read the [Contributing Guide](./.github/CONTRIBUTING.md) before making a pull request. + +Thank you to everyone contributing to Tauri! ### Documentation Documentation 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 @@ -143,12 +146,6 @@ We recommend you read this article to understand better how we run our pipelines ## Organization Tauri 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). -## Contributing -Please make sure to read the [Contributing Guide](./.github/CONTRIBUTING.md) -before making a pull request. - -Thank you to all the people who already contributed to Tauri! - ## Semver **tauri** is following [Semantic Versioning 2.0](https://semver.org/). diff --git a/audits/Radically_Open_Security-v1-report.pdf b/audits/Radically_Open_Security-v1-report.pdf new file mode 100644 index 000000000000..743d8be9bf3e Binary files /dev/null and b/audits/Radically_Open_Security-v1-report.pdf differ diff --git a/core/tauri-build/Cargo.toml b/core/tauri-build/Cargo.toml index d637b206ddb0..dd58d6308b95 100644 --- a/core/tauri-build/Cargo.toml +++ b/core/tauri-build/Cargo.toml @@ -7,7 +7,8 @@ license = "Apache-2.0 OR MIT" homepage = "https://tauri.studio" repository = "https://github.com/tauri-apps/tauri/tree/dev/core/tauri-build" description = "build time code to pair with https://crates.io/crates/tauri" -edition = "2018" +edition = "2021" +rust-version = "1.57" exclude = [ ".license_template", "CHANGELOG.md", "/target" ] readme = "README.md" @@ -17,14 +18,16 @@ rustdoc-args = [ "--cfg", "doc_cfg" ] [dependencies] anyhow = "1" -proc-macro2 = "1" -quote = "1" +quote = { version = "1", optional = true } tauri-codegen = { version = "1.0.0-beta.4", path = "../tauri-codegen", optional = true } +tauri-utils = { version = "1.0.0-beta.0", path = "../tauri-utils", features = [ "build", "resources" ] } +cargo_toml = "0.11" +serde_json = "1" [target."cfg(windows)".dependencies] winres = "0.1" -serde_json = "1.0" -tauri-utils = { version = "1.0.0-beta.0", path = "../tauri-utils", features = [ "build" ] } [features] -codegen = [ "tauri-codegen" ] +codegen = [ "tauri-codegen", "quote" ] +isolation = ["tauri-codegen/isolation", "tauri-utils/isolation"] +config-json5 = [ "tauri-utils/config-json5" ] diff --git a/core/tauri-build/src/codegen/context.rs b/core/tauri-build/src/codegen/context.rs index 54e86f4e6a4d..29356b09885b 100644 --- a/core/tauri-build/src/codegen/context.rs +++ b/core/tauri-build/src/codegen/context.rs @@ -42,6 +42,7 @@ impl CodegenContext { /// This defaults to a file called `tauri.conf.json` inside of the current working directory of /// the package compiling; does not need to be set manually if that config file is in the same /// directory as your `Cargo.toml`. + #[must_use] pub fn config_path(mut self, config_path: impl Into) -> Self { self.config_path = config_path.into(); self @@ -58,6 +59,7 @@ impl CodegenContext { /// Defaults to `tauri-build-context.rs`. /// /// [`tauri::include_codegen_context!`]: https://docs.rs/tauri/0.12/tauri/macro.include_codegen_context.html + #[must_use] pub fn out_file(mut self, filename: PathBuf) -> Self { self.out_file = filename; self @@ -65,6 +67,7 @@ impl CodegenContext { /// Run the codegen in a `dev` context, meaning that Tauri is using a dev server or local file for development purposes, /// usually with the `tauri dev` CLI command. + #[must_use] pub fn dev(mut self) -> Self { self.dev = true; self @@ -117,7 +120,7 @@ impl CodegenContext { ) })?; - writeln!(&mut file, "{}", code).with_context(|| { + writeln!(file, "{}", code).with_context(|| { format!( "Unable to write tokenstream to out file during tauri-build {}", out.display() diff --git a/core/tauri-build/src/lib.rs b/core/tauri-build/src/lib.rs index 4d91e04cc13f..9c4f23d1a365 100644 --- a/core/tauri-build/src/lib.rs +++ b/core/tauri-build/src/lib.rs @@ -5,6 +5,7 @@ #![cfg_attr(doc_cfg, feature(doc_cfg))] pub use anyhow::Result; +use tauri_utils::resources::{external_binaries, resource_relpath, ResourcePaths}; use std::path::{Path, PathBuf}; @@ -15,17 +16,62 @@ mod codegen; #[cfg_attr(doc_cfg, doc(cfg(feature = "codegen")))] pub use codegen::context::CodegenContext; +fn copy_file(from: impl AsRef, to: impl AsRef) -> Result<()> { + let from = from.as_ref(); + let to = to.as_ref(); + if !from.exists() { + return Err(anyhow::anyhow!("{:?} does not exist", from)); + } + if !from.is_file() { + return Err(anyhow::anyhow!("{:?} is not a file", from)); + } + let dest_dir = to.parent().expect("No data in parent"); + std::fs::create_dir_all(dest_dir)?; + std::fs::copy(from, to)?; + Ok(()) +} + +fn copy_binaries<'a>(binaries: ResourcePaths<'a>, target_triple: &str, path: &Path) -> Result<()> { + for src in binaries { + let src = src?; + let dest = path.join( + src + .file_name() + .expect("failed to extract external binary filename") + .to_string_lossy() + .replace(&format!("-{}", target_triple), ""), + ); + copy_file(&src, &dest)?; + } + Ok(()) +} + +/// Copies resources to a path. +fn copy_resources(resources: ResourcePaths<'_>, path: &Path) -> Result<()> { + for src in resources { + let src = src?; + let dest = path.join(resource_relpath(&src)); + copy_file(&src, &dest)?; + } + Ok(()) +} + /// Attributes used on Windows. #[allow(dead_code)] #[derive(Debug)] pub struct WindowsAttributes { window_icon_path: PathBuf, + /// The path to the sdk location. This can be a absolute or relative path. If not supplied + /// this defaults to whatever `winres` crate determines is the best. See the + /// [winres documentation](https://docs.rs/winres/*/winres/struct.WindowsResource.html#method.set_toolkit_path) + sdk_dir: Option, } impl Default for WindowsAttributes { fn default() -> Self { Self { window_icon_path: PathBuf::from("icons/icon.ico"), + sdk_dir: None, } } } @@ -38,10 +84,19 @@ impl WindowsAttributes { /// Sets the icon to use on the window. Currently only used on Windows. /// It must be in `ico` format. Defaults to `icons/icon.ico`. + #[must_use] pub fn window_icon_path>(mut self, window_icon_path: P) -> Self { self.window_icon_path = window_icon_path.as_ref().into(); self } + + /// Sets the sdk dir for windows. Currently only used on Windows. This must be a vaild UTF-8 + /// path. Defaults to whatever the `winres` crate determines is best. + #[must_use] + pub fn sdk_dir>(mut self, sdk_dir: P) -> Self { + self.sdk_dir = Some(sdk_dir.as_ref().into()); + self + } } /// The attributes used on the build. @@ -58,6 +113,7 @@ impl Attributes { } /// Sets the icon to use on the window. Currently only used on Windows. + #[must_use] pub fn windows_attributes(mut self, windows_attributes: WindowsAttributes) -> Self { self.windows_attributes = windows_attributes; self @@ -92,18 +148,102 @@ pub fn build() { /// Non-panicking [`build()`]. #[allow(unused_variables)] pub fn try_build(attributes: Attributes) -> Result<()> { + use anyhow::anyhow; + use cargo_toml::{Dependency, Manifest}; + use tauri_utils::config::{Config, TauriConfig}; + + println!("cargo:rerun-if-changed=src/Cargo.toml"); + println!("cargo:rerun-if-changed=tauri.conf.json"); + #[cfg(feature = "config-json5")] + println!("cargo:rerun-if-changed=tauri.conf.json5"); + + let config: Config = if let Ok(env) = std::env::var("TAURI_CONFIG") { + serde_json::from_str(&env)? + } else { + serde_json::from_value(tauri_utils::config::parse::read_from( + std::env::current_dir().unwrap(), + )?)? + }; + + let mut manifest = Manifest::from_path("Cargo.toml")?; + if let Some(tauri) = manifest.dependencies.remove("tauri") { + let features = match tauri { + Dependency::Simple(_) => Vec::new(), + Dependency::Detailed(dep) => dep.features, + }; + + let all_cli_managed_features = TauriConfig::all_features(); + let diff = features_diff( + &features + .into_iter() + .filter(|f| all_cli_managed_features.contains(&f.as_str())) + .collect::>(), + &config + .tauri + .features() + .into_iter() + .map(|f| f.to_string()) + .collect::>(), + ); + + let mut error_message = String::new(); + if !diff.remove.is_empty() { + error_message.push_str("remove the `"); + error_message.push_str(&diff.remove.join(", ")); + error_message.push_str(if diff.remove.len() == 1 { + "` feature" + } else { + "` features" + }); + if !diff.add.is_empty() { + error_message.push_str(" and "); + } + } + if !diff.add.is_empty() { + error_message.push_str("add the `"); + error_message.push_str(&diff.add.join(", ")); + error_message.push_str(if diff.add.len() == 1 { + "` feature" + } else { + "` features" + }); + } + + if !error_message.is_empty() { + return Err(anyhow!(" + The `tauri` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`. + Please run `tauri dev` or `tauri build` or {}. + ", error_message)); + } + } + + let target_triple = std::env::var("TARGET").unwrap(); + let out_dir = std::env::var("OUT_DIR").unwrap(); + // TODO: far from ideal, but there's no other way to get the target dir, see + let target_dir = Path::new(&out_dir) + .parent() + .unwrap() + .parent() + .unwrap() + .parent() + .unwrap(); + + if let Some(paths) = config.tauri.bundle.external_bin { + copy_binaries( + ResourcePaths::new(external_binaries(&paths, &target_triple).as_slice(), true), + &target_triple, + target_dir, + )?; + } + if let Some(paths) = config.tauri.bundle.resources { + copy_resources(ResourcePaths::new(paths.as_slice(), true), target_dir)?; + } + #[cfg(windows)] { - use anyhow::{anyhow, Context}; - use std::fs::read_to_string; - use tauri_utils::config::Config; + use anyhow::Context; use winres::WindowsResource; - let config: Config = serde_json::from_str( - &read_to_string("tauri.conf.json").expect("failed to read tauri.conf.json"), - ) - .expect("failed to parse tauri.conf.json"); - let icon_path_string = attributes .windows_attributes .window_icon_path @@ -112,6 +252,15 @@ pub fn try_build(attributes: Attributes) -> Result<()> { if attributes.windows_attributes.window_icon_path.exists() { let mut res = WindowsResource::new(); + if let Some(sdk_dir) = &attributes.windows_attributes.sdk_dir { + if let Some(sdk_dir_str) = sdk_dir.to_str() { + res.set_toolkit_path(sdk_dir_str); + } else { + return Err(anyhow!( + "sdk_dir path is not valid; only UTF-8 characters are allowed" + )); + } + } if let Some(version) = &config.package.version { res.set("FileVersion", version); res.set("ProductVersion", version); @@ -137,3 +286,66 @@ pub fn try_build(attributes: Attributes) -> Result<()> { Ok(()) } + +#[derive(Debug, Default, PartialEq, Eq)] +struct Diff { + remove: Vec, + add: Vec, +} + +fn features_diff(current: &[String], expected: &[String]) -> Diff { + let mut remove = Vec::new(); + let mut add = Vec::new(); + for feature in current { + if !expected.contains(feature) { + remove.push(feature.clone()); + } + } + + for feature in expected { + if !current.contains(feature) { + add.push(feature.clone()); + } + } + + Diff { remove, add } +} + +#[cfg(test)] +mod tests { + use super::Diff; + + #[test] + fn array_diff() { + for (current, expected, result) in [ + (vec![], vec![], Default::default()), + ( + vec!["a".into()], + vec![], + Diff { + remove: vec!["a".into()], + add: vec![], + }, + ), + (vec!["a".into()], vec!["a".into()], Default::default()), + ( + vec!["a".into(), "b".into()], + vec!["a".into()], + Diff { + remove: vec!["b".into()], + add: vec![], + }, + ), + ( + vec!["a".into(), "b".into()], + vec!["a".into(), "c".into()], + Diff { + remove: vec!["b".into()], + add: vec!["c".into()], + }, + ), + ] { + assert_eq!(super::features_diff(¤t, &expected), result); + } + } +} diff --git a/core/tauri-codegen/Cargo.toml b/core/tauri-codegen/Cargo.toml index 7d7952b6da2c..11f2fa4ba303 100644 --- a/core/tauri-codegen/Cargo.toml +++ b/core/tauri-codegen/Cargo.toml @@ -7,12 +7,15 @@ license = "Apache-2.0 OR MIT" homepage = "https://tauri.studio" repository = "https://github.com/tauri-apps/tauri/tree/dev/core/tauri-codegen" description = "code generation meant to be consumed inside of `tauri` through `tauri-build` or `tauri-macros`" -edition = "2018" +edition = "2021" +rust-version = "1.57" exclude = [ ".license_template", "CHANGELOG.md", "/target" ] readme = "README.md" [dependencies] -blake3 = { version = "1.0", features = [ "rayon" ] } +sha2 = "0.10" +base64 = "0.13" +blake3 = { version = "1.3", features = [ "rayon" ] } proc-macro2 = "1" quote = "1" serde = { version = "1", features = [ "derive" ] } @@ -20,6 +23,13 @@ serde_json = "1" tauri-utils = { version = "1.0.0-beta.3", path = "../tauri-utils", features = [ "build" ] } thiserror = "1" walkdir = "2" -zstd = "0.9" -kuchiki = "0.8" -regex = "1" +zstd = { version = "0.10", optional = true } +regex = { version = "1", optional = true } +uuid = { version = "0.8", features = [ "v4" ] } + +[features] +default = [ "compression" ] +compression = [ "zstd", "tauri-utils/compression" ] +isolation = ["tauri-utils/isolation"] +shell-scope = ["regex"] +config-json5 = [ "tauri-utils/config-json5" ] diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index bd4307238e01..9e1762e2e283 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -2,11 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::embedded_assets::{AssetOptions, EmbeddedAssets, EmbeddedAssetsError}; +use std::ffi::OsStr; +use std::path::{Path, PathBuf}; + use proc_macro2::TokenStream; use quote::quote; -use std::path::{Path, PathBuf}; -use tauri_utils::config::{AppUrl, Config, WindowUrl}; +use sha2::{Digest, Sha256}; + +use tauri_utils::assets::AssetKey; +use tauri_utils::config::{AppUrl, Config, PatternKind, WindowUrl}; +use tauri_utils::html::{inject_nonce_token, parse as parse_html, NodeRef}; + +#[cfg(feature = "shell-scope")] +use tauri_utils::config::{ShellAllowedArg, ShellAllowedArgs, ShellAllowlistScope}; + +use crate::embedded_assets::{AssetOptions, CspHashes, EmbeddedAssets, EmbeddedAssetsError}; /// Necessary data needed by [`context_codegen`] to generate code for a Tauri application context. pub struct ContextData { @@ -16,6 +26,81 @@ pub struct ContextData { pub root: TokenStream, } +fn load_csp(document: &mut NodeRef, key: &AssetKey, csp_hashes: &mut CspHashes) { + #[cfg(target_os = "linux")] + ::tauri_utils::html::inject_csp_token(document); + inject_nonce_token(document); + if let Ok(inline_script_elements) = document.select("script:not(empty)") { + let mut scripts = Vec::new(); + for inline_script_el in inline_script_elements { + let script = inline_script_el.as_node().text_contents(); + let mut hasher = Sha256::new(); + hasher.update(&script); + let hash = hasher.finalize(); + scripts.push(format!("'sha256-{}'", base64::encode(&hash))); + } + csp_hashes + .inline_scripts + .entry(key.clone().into()) + .or_default() + .append(&mut scripts); + } +} + +fn map_core_assets( + options: &AssetOptions, +) -> impl Fn(&AssetKey, &Path, &mut Vec, &mut CspHashes) -> Result<(), EmbeddedAssetsError> { + #[cfg(feature = "isolation")] + let pattern = tauri_utils::html::PatternObject::from(&options.pattern); + let csp = options.csp; + move |key, path, input, csp_hashes| { + if path.extension() == Some(OsStr::new("html")) { + let mut document = parse_html(String::from_utf8_lossy(input).into_owned()); + + if csp { + load_csp(&mut document, key, csp_hashes); + + #[cfg(feature = "isolation")] + if let tauri_utils::html::PatternObject::Isolation { .. } = &pattern { + // create the csp for the isolation iframe styling now, to make the runtime less complex + let mut hasher = Sha256::new(); + hasher.update(tauri_utils::pattern::isolation::IFRAME_STYLE); + let hash = hasher.finalize(); + csp_hashes + .styles + .push(format!("'sha256-{}'", base64::encode(&hash))); + } + } + + *input = document.to_string().as_bytes().to_vec(); + } + Ok(()) + } +} + +#[cfg(feature = "isolation")] +fn map_isolation( + _options: &AssetOptions, + dir: PathBuf, +) -> impl Fn(&AssetKey, &Path, &mut Vec, &mut CspHashes) -> Result<(), EmbeddedAssetsError> { + move |_key, path, input, _csp_hashes| { + if path.extension() == Some(OsStr::new("html")) { + let mut isolation_html = + tauri_utils::html::parse(String::from_utf8_lossy(input).into_owned()); + + // this is appended, so no need to reverse order it + tauri_utils::html::inject_codegen_isolation_script(&mut isolation_html); + + // temporary workaround for windows not loading assets + tauri_utils::html::inline_isolation(&mut isolation_html, &dir); + + *input = isolation_html.to_string().as_bytes().to_vec() + } + + Ok(()) + } +} + /// Build a `tauri::Context` for including in application code. pub fn context_codegen(data: ContextData) -> Result { let ContextData { @@ -25,9 +110,20 @@ pub fn context_codegen(data: ContextData) -> Result Result unimplemented!(), }, - AppUrl::Files(files) => EmbeddedAssets::load_paths( - files.iter().map(|p| config_parent.join(p)).collect(), - options, + AppUrl::Files(files) => EmbeddedAssets::new( + files + .iter() + .map(|p| config_parent.join(p)) + .collect::>(), + map_core_assets(&options), )?, _ => unimplemented!(), }; @@ -100,6 +199,8 @@ pub fn context_codegen(data: ContextData) -> Result Result Result quote!(#root::Pattern::Brownfield(std::marker::PhantomData)), + #[cfg(feature = "isolation")] + PatternKind::Isolation { dir } => { + let dir = config_parent.join(dir); + if !dir.exists() { + panic!( + "The isolation dir configuration is set to `{:?}` but this path doesn't exist", + dir + ) + } + + let key = uuid::Uuid::new_v4().to_string(); + let assets = EmbeddedAssets::new(dir.clone(), map_isolation(&options, dir))?; + let schema = options.isolation_schema; + + quote!(#root::Pattern::Isolation { + assets: ::std::sync::Arc::new(#assets), + schema: #schema.into(), + key: #key.into(), + crypto_keys: std::boxed::Box::new(::tauri::utils::pattern::isolation::Keys::new().expect("unable to generate cryptographically secure keys for Tauri \"Isolation\" Pattern")), + }) + } + }; + + #[cfg(feature = "shell-scope")] + let shell_scope_config = { + use regex::Regex; + use tauri_utils::config::ShellAllowlistOpen; + + let shell_scopes = get_allowed_clis(&root, &config.tauri.allowlist.shell.scope); + + let shell_scope_open = match &config.tauri.allowlist.shell.open { + ShellAllowlistOpen::Flag(false) => quote!(::std::option::Option::None), + ShellAllowlistOpen::Flag(true) => { + quote!(::std::option::Option::Some(#root::regex::Regex::new("^https?://").unwrap())) + } + ShellAllowlistOpen::Validate(regex) => match Regex::new(regex) { + Ok(_) => quote!(::std::option::Option::Some(#root::regex::Regex::new(#regex).unwrap())), + Err(error) => { + let error = error.to_string(); + quote!({ + compile_error!(#error); + ::std::option::Option::Some(#root::regex::Regex::new(#regex).unwrap()) + }) + } + }, + _ => panic!("unknown shell open format, unable to prepare"), + }; + + quote!(#root::ShellScopeConfig { + open: #shell_scope_open, + scopes: #shell_scopes + }) + }; + + #[cfg(not(feature = "shell-scope"))] + let shell_scope_config = quote!(); + Ok(quote!(#root::Context::new( #config, ::std::sync::Arc::new(#assets), @@ -171,6 +332,8 @@ pub fn context_codegen(data: ContextData) -> Result bool>( .unwrap_or_else(|| default.to_string()); config_parent.join(icon_path).display().to_string() } + +#[cfg(feature = "shell-scope")] +fn get_allowed_clis(root: &TokenStream, scope: &ShellAllowlistScope) -> TokenStream { + let commands = scope + .0 + .iter() + .map(|scope| { + let sidecar = &scope.sidecar; + + let name = &scope.name; + let name = quote!(#name.into()); + + let command = scope.command.to_string_lossy(); + let command = quote!(::std::path::PathBuf::from(#command)); + + let args = match &scope.args { + ShellAllowedArgs::Flag(true) => quote!(::std::option::Option::None), + ShellAllowedArgs::Flag(false) => quote!(::std::option::Option::Some(::std::vec![])), + ShellAllowedArgs::List(list) => { + let list = list.iter().map(|arg| match arg { + ShellAllowedArg::Fixed(fixed) => { + quote!(#root::scope::ShellScopeAllowedArg::Fixed(#fixed.into())) + } + ShellAllowedArg::Var { validator } => { + let validator = match regex::Regex::new(validator) { + Ok(regex) => { + let regex = regex.as_str(); + quote!(#root::regex::Regex::new(#regex).unwrap()) + } + Err(error) => { + let error = error.to_string(); + quote!({ + compile_error!(#error); + #root::regex::Regex::new(#validator).unwrap() + }) + } + }; + + quote!(#root::scope::ShellScopeAllowedArg::Var { validator: #validator }) + } + _ => panic!("unknown shell scope arg, unable to prepare"), + }); + + quote!(::std::option::Option::Some(::std::vec![#(#list),*])) + } + _ => panic!("unknown shell scope command, unable to prepare"), + }; + + ( + quote!(#name), + quote!( + #root::scope::ShellScopeAllowedCommand { + command: #command, + args: #args, + sidecar: #sidecar, + } + ), + ) + }) + .collect::>(); + + if commands.is_empty() { + quote!(::std::collections::HashMap::new()) + } else { + let insertions = commands + .iter() + .map(|(name, value)| quote!(hashmap.insert(#name, #value);)); + + quote!({ + let mut hashmap = ::std::collections::HashMap::new(); + #(#insertions)* + hashmap + }) + } +} diff --git a/core/tauri-codegen/src/embedded_assets.rs b/core/tauri-codegen/src/embedded_assets.rs index 5fdb00f3828e..5f29057b56d1 100644 --- a/core/tauri-codegen/src/embedded_assets.rs +++ b/core/tauri-codegen/src/embedded_assets.rs @@ -2,22 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use kuchiki::traits::*; use proc_macro2::TokenStream; use quote::{quote, ToTokens, TokenStreamExt}; -use regex::RegexSet; +use sha2::{Digest, Sha256}; use std::{ collections::HashMap, - ffi::OsStr, fs::File, path::{Path, PathBuf}, }; -use tauri_utils::{ - assets::AssetKey, - html::{inject_csp, inject_invoke_key_token}, -}; +use tauri_utils::assets::AssetKey; +use tauri_utils::config::PatternKind; use thiserror::Error; -use walkdir::WalkDir; +use walkdir::{DirEntry, WalkDir}; /// The subdirectory inside the target directory we want to place assets. const TARGET_PATH: &str = "tauri-codegen-assets"; @@ -67,95 +63,189 @@ pub enum EmbeddedAssetsError { /// through [`ToTokens`]. The generated code is meant to be injected into an application to include /// the compressed assets in that application's binary. #[derive(Default)] -pub struct EmbeddedAssets(HashMap); +pub struct EmbeddedAssets { + assets: HashMap, + csp_hashes: CspHashes, +} + +pub struct EmbeddedAssetsInput(Vec); + +impl From for EmbeddedAssetsInput { + fn from(path: PathBuf) -> Self { + Self(vec![path]) + } +} + +impl From> for EmbeddedAssetsInput { + fn from(paths: Vec) -> Self { + Self(paths) + } +} + +/// Holds a list of (prefix, entry) +struct RawEmbeddedAssets { + paths: Vec<(PathBuf, DirEntry)>, + csp_hashes: CspHashes, +} + +impl RawEmbeddedAssets { + /// Creates a new list of (prefix, entry) from a collection of inputs. + fn new(input: EmbeddedAssetsInput) -> Result { + let mut csp_hashes = CspHashes::default(); + + input + .0 + .into_iter() + .flat_map(|path| { + let prefix = if path.is_dir() { + path.clone() + } else { + path + .parent() + .expect("embedded file asset has no parent") + .to_path_buf() + }; + + WalkDir::new(&path) + .follow_links(true) + .contents_first(true) + .into_iter() + .map(move |entry| (prefix.clone(), entry)) + }) + .filter_map(|(prefix, entry)| { + match entry { + // we only serve files, not directory listings + Ok(entry) if entry.file_type().is_dir() => None, + + // compress all files encountered + Ok(entry) => { + if let Err(error) = csp_hashes.add_if_applicable(&entry) { + Some(Err(error)) + } else { + Some(Ok((prefix, entry))) + } + } + + // pass down error through filter to fail when encountering any error + Err(error) => Some(Err(EmbeddedAssetsError::Walkdir { + path: prefix, + error, + })), + } + }) + .collect::, _>>() + .map(|paths| Self { paths, csp_hashes }) + } +} + +/// Holds all hashes that we will apply on the CSP tag/header. +#[derive(Debug, Default)] +pub struct CspHashes { + /// Scripts that are part of the asset collection (JS or MJS files). + pub(crate) scripts: Vec, + /// Inline scripts (``). Maps a HTML path to a list of hashes. + pub(crate) inline_scripts: HashMap>, + /// A list of hashes of the contents of all `style` elements. + pub(crate) styles: Vec, +} + +impl CspHashes { + /// Only add a CSP hash to the appropriate category if we think the file matches + /// + /// Note: this only checks the file extension, much like how a browser will assume a .js file is + /// a JavaScript file unless HTTP headers tell it otherwise. + pub fn add_if_applicable(&mut self, entry: &DirEntry) -> Result<(), EmbeddedAssetsError> { + let path = entry.path(); + + // we only hash JavaScript files for now, may expand to other CSP hashable types in the future + if let Some("js") | Some("mjs") = path.extension().and_then(|os| os.to_str()) { + let mut hasher = Sha256::new(); + hasher.update( + &std::fs::read(path).map_err(|error| EmbeddedAssetsError::AssetRead { + path: path.to_path_buf(), + error, + })?, + ); + let hash = hasher.finalize(); + self + .scripts + .push(format!("'sha256-{}'", base64::encode(hash))) + } + + Ok(()) + } +} /// Options used to embed assets. #[derive(Default)] pub struct AssetOptions { - csp: Option, + pub(crate) csp: bool, + pub(crate) pattern: PatternKind, + pub(crate) freeze_prototype: bool, + #[cfg(feature = "isolation")] + pub(crate) isolation_schema: String, } impl AssetOptions { /// Creates the default asset options. - pub fn new() -> Self { - Self::default() + pub fn new(pattern: PatternKind) -> Self { + Self { + csp: false, + pattern, + freeze_prototype: true, + #[cfg(feature = "isolation")] + isolation_schema: format!("isolation-{}", uuid::Uuid::new_v4()), + } } - /// Sets the content security policy to add to HTML files. - pub fn csp(mut self, csp: String) -> Self { - self.csp.replace(csp); + /// Instruct the asset handler to inject the CSP token to HTML files. + #[must_use] + pub fn with_csp(mut self) -> Self { + self.csp = true; + self + } + + /// Instruct the asset handler to include a script to freeze the `Object.prototype` on all HTML files. + #[must_use] + pub fn freeze_prototype(mut self, freeze: bool) -> Self { + self.freeze_prototype = freeze; self } } impl EmbeddedAssets { - /// Compress a directory of assets, ready to be generated into a [`tauri_utils::assets::Assets`]. - pub fn new(path: &Path, options: AssetOptions) -> Result { - WalkDir::new(&path) - .follow_links(true) - .into_iter() - .filter_map(|entry| match entry { - // we only serve files, not directory listings - Ok(entry) if entry.file_type().is_dir() => None, - - // compress all files encountered - Ok(entry) => Some(Self::compress_file(path, entry.path(), &options)), + /// Compress a collection of files and directories, ready to be generated into [`Assets`]. + /// + /// [`Assets`]: tauri_utils::assets::Assets + pub fn new( + input: impl Into, + map: impl Fn(&AssetKey, &Path, &mut Vec, &mut CspHashes) -> Result<(), EmbeddedAssetsError>, + ) -> Result { + // we need to pre-compute all files now, so that we can inject data from all files into a few + let RawEmbeddedAssets { paths, csp_hashes } = RawEmbeddedAssets::new(input.into())?; - // pass down error through filter to fail when encountering any error - Err(error) => Some(Err(EmbeddedAssetsError::Walkdir { - path: path.to_owned(), - error, - })), - }) - .collect::>() - .map(Self) - } + struct CompressState { + csp_hashes: CspHashes, + assets: HashMap, + } - /// Compress a list of files and directories. - pub fn load_paths( - paths: Vec, - options: AssetOptions, - ) -> Result { - Ok(Self( - paths - .iter() - .map(|path| { - let is_file = path.is_file(); - WalkDir::new(&path) - .follow_links(true) - .into_iter() - .filter_map(|entry| { - match entry { - // we only serve files, not directory listings - Ok(entry) if entry.file_type().is_dir() => None, - - // compress all files encountered - Ok(entry) => Some(Self::compress_file( - if is_file { - path.parent().unwrap() - } else { - path - }, - entry.path(), - &options, - )), - - // pass down error through filter to fail when encountering any error - Err(error) => Some(Err(EmbeddedAssetsError::Walkdir { - path: path.to_path_buf(), - error, - })), - } - }) - .collect::, _>>() - }) - .flatten() - .flatten() - .collect::<_>(), - )) + let CompressState { assets, csp_hashes } = paths.into_iter().try_fold( + CompressState { + csp_hashes, + assets: HashMap::new(), + }, + move |mut state, (prefix, entry)| { + let (key, asset) = Self::compress_file(&prefix, entry.path(), &map, &mut state.csp_hashes)?; + state.assets.insert(key, asset); + Ok(state) + }, + )?; + + Ok(Self { assets, csp_hashes }) } /// Use highest compression level for release, the fastest one for everything else + #[cfg(feature = "compression")] fn compression_level() -> i32 { let levels = zstd::compression_level_range(); if cfg!(debug_assertions) { @@ -169,66 +259,25 @@ impl EmbeddedAssets { fn compress_file( prefix: &Path, path: &Path, - options: &AssetOptions, + map: &impl Fn(&AssetKey, &Path, &mut Vec, &mut CspHashes) -> Result<(), EmbeddedAssetsError>, + csp_hashes: &mut CspHashes, ) -> Result { let mut input = std::fs::read(path).map_err(|error| EmbeddedAssetsError::AssetRead { path: path.to_owned(), error, })?; - if path.extension() == Some(OsStr::new("html")) { - let mut document = kuchiki::parse_html().one(String::from_utf8_lossy(&input).into_owned()); - if let Some(csp) = &options.csp { - inject_csp(&mut document, csp); - } - inject_invoke_key_token(&mut document); - input = document.to_string().as_bytes().to_vec(); - } else { - let is_javascript = ["js", "cjs", "mjs"] - .iter() - .any(|e| path.extension() == Some(OsStr::new(e))); - if is_javascript { - let js = String::from_utf8_lossy(&input).into_owned(); - input = if RegexSet::new(&[ - // import keywords - "import\\{", - "import \\{", - "import\\*", - "import \\*", - "import (\"|');?$", - "import\\(", - "import (.|\n)+ from (\"|')([A-Za-z/\\.@-]+)(\"|')", - // export keywords - "export\\{", - "export \\{", - "export\\*", - "export \\*", - "export (default|class|let|const|function|async)", - ]) - .unwrap() - .is_match(&js) - { - format!( - r#" - const __TAURI_INVOKE_KEY__ = __TAURI__INVOKE_KEY_TOKEN__; - {} - "#, - js - ) - .as_bytes() - .to_vec() - } else { - format!( - r#"(function () {{ - const __TAURI_INVOKE_KEY__ = __TAURI__INVOKE_KEY_TOKEN__; - {} - }})()"#, - js - ) - .as_bytes() - .to_vec() - }; - } - } + + // get a key to the asset path without the asset directory prefix + let key = path + .strip_prefix(prefix) + .map(AssetKey::from) // format the path for use in assets + .map_err(|_| EmbeddedAssetsError::PrefixInvalid { + prefix: prefix.to_owned(), + path: path.to_owned(), + })?; + + // perform any caller-requested input manipulation + map(&key, path, &mut input, csp_hashes)?; // we must canonicalize the base of our paths to allow long paths on windows let out_dir = std::env::var("OUT_DIR") @@ -260,11 +309,25 @@ impl EmbeddedAssets { // only compress and write to the file if it doesn't already exist. if !out_path.exists() { - let out_file = File::create(&out_path).map_err(|error| EmbeddedAssetsError::AssetWrite { - path: out_path.clone(), - error, - })?; + #[allow(unused_mut)] + let mut out_file = + File::create(&out_path).map_err(|error| EmbeddedAssetsError::AssetWrite { + path: out_path.clone(), + error, + })?; + + #[cfg(not(feature = "compression"))] + { + use std::io::Write; + out_file + .write_all(&input) + .map_err(|error| EmbeddedAssetsError::AssetWrite { + path: path.to_owned(), + error, + })?; + } + #[cfg(feature = "compression")] // entirely write input to the output file path with compression zstd::stream::copy_encode(&*input, out_file, Self::compression_level()).map_err(|error| { EmbeddedAssetsError::AssetWrite { @@ -274,38 +337,51 @@ impl EmbeddedAssets { })?; } - // get a key to the asset path without the asset directory prefix - let key = path - .strip_prefix(prefix) - .map(AssetKey::from) // format the path for use in assets - .map_err(|_| EmbeddedAssetsError::PrefixInvalid { - prefix: prefix.to_owned(), - path: path.to_owned(), - })?; - Ok((key, (path.into(), out_path))) } } impl ToTokens for EmbeddedAssets { fn to_tokens(&self, tokens: &mut TokenStream) { - let mut map = TokenStream::new(); - for (key, (input, output)) in &self.0 { + let mut assets = TokenStream::new(); + for (key, (input, output)) in &self.assets { let key: &str = key.as_ref(); let input = input.display().to_string(); let output = output.display().to_string(); // add original asset as a compiler dependency, rely on dead code elimination to clean it up - map.append_all(quote!(#key => { + assets.append_all(quote!(#key => { const _: &[u8] = include_bytes!(#input); include_bytes!(#output) },)); } + let mut global_hashes = TokenStream::new(); + for script_hash in &self.csp_hashes.scripts { + let hash = script_hash.as_str(); + global_hashes.append_all(quote!(CspHash::Script(#hash),)); + } + + for style_hash in &self.csp_hashes.styles { + let hash = style_hash.as_str(); + global_hashes.append_all(quote!(CspHash::Style(#hash),)); + } + + let mut html_hashes = TokenStream::new(); + for (path, hashes) in &self.csp_hashes.inline_scripts { + let key = path.as_str(); + let mut value = TokenStream::new(); + for script_hash in hashes { + let hash = script_hash.as_str(); + value.append_all(quote!(CspHash::Script(#hash),)); + } + html_hashes.append_all(quote!(#key => &[#value],)); + } + // we expect phf related items to be in path when generating the path code tokens.append_all(quote! {{ - use ::tauri::utils::assets::{EmbeddedAssets, phf, phf::phf_map}; - EmbeddedAssets::from_zstd(phf_map! { #map }) + use ::tauri::utils::assets::{CspHash, EmbeddedAssets, phf, phf::phf_map}; + EmbeddedAssets::new(phf_map! { #assets }, &[#global_hashes], phf_map! { #html_hashes }) }}); } } diff --git a/core/tauri-codegen/src/lib.rs b/core/tauri-codegen/src/lib.rs index 4a2f08e8ccb4..4eedaa1434ee 100644 --- a/core/tauri-codegen/src/lib.rs +++ b/core/tauri-codegen/src/lib.rs @@ -2,23 +2,20 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -pub use context::{context_codegen, ContextData}; +pub use self::context::{context_codegen, ContextData}; use std::{ borrow::Cow, - fs::File, - io::BufReader, path::{Path, PathBuf}, }; -use tauri_utils::config::Config; -use thiserror::Error; +pub use tauri_utils::config::{parse::ConfigError, Config}; mod context; pub mod embedded_assets; -/// Represents all the errors that can happen while reading the config. -#[derive(Debug, Error)] +/// Represents all the errors that can happen while reading the config during codegen. +#[derive(Debug, thiserror::Error)] #[non_exhaustive] -pub enum ConfigError { +pub enum CodegenConfigError { #[error("unable to access current working directory: {0}")] CurrentDir(std::io::Error), @@ -26,29 +23,20 @@ pub enum ConfigError { #[error("Tauri config file has no parent, this shouldn't be possible. file an issue on https://github.com/tauri-apps/tauri - target {0}")] Parent(PathBuf), - #[error("unable to parse inline TAURI_CONFIG env var: {0}")] + #[error("unable to parse inline JSON TAURI_CONFIG env var: {0}")] FormatInline(serde_json::Error), - #[error("unable to parse Tauri config file at {path} because {error}")] - Format { - path: PathBuf, - error: serde_json::Error, - }, - - #[error("unable to read Tauri config file at {path} because {error}")] - Io { - path: PathBuf, - error: std::io::Error, - }, + #[error("{0}")] + ConfigError(#[from] ConfigError), } /// Get the [`Config`] from the `TAURI_CONFIG` environmental variable, or read from the passed path. /// /// If the passed path is relative, it should be relative to the current working directory of the /// compiling crate. -pub fn get_config(path: &Path) -> Result<(Config, PathBuf), ConfigError> { +pub fn get_config(path: &Path) -> Result<(Config, PathBuf), CodegenConfigError> { let path = if path.is_relative() { - let cwd = std::env::current_dir().map_err(ConfigError::CurrentDir)?; + let cwd = std::env::current_dir().map_err(CodegenConfigError::CurrentDir)?; Cow::Owned(cwd.join(path)) } else { Cow::Borrowed(path) @@ -59,27 +47,16 @@ pub fn get_config(path: &Path) -> Result<(Config, PathBuf), ConfigError> { // already unlikely unless the developer goes out of their way to run the cli on a different // project than the target crate. let config = if let Ok(env) = std::env::var("TAURI_CONFIG") { - serde_json::from_str(&env).map_err(ConfigError::FormatInline)? + serde_json::from_str(&env).map_err(CodegenConfigError::FormatInline)? } else { - File::open(&path) - .map_err(|error| ConfigError::Io { - path: path.clone().into_owned(), - error, - }) - .map(BufReader::new) - .and_then(|file| { - serde_json::from_reader(file).map_err(|error| ConfigError::Format { - path: path.clone().into_owned(), - error, - }) - })? + tauri_utils::config::parse(path.to_path_buf())? }; // this should be impossible because of the use of `current_dir()` above, but handle it anyways let parent = path .parent() .map(ToOwned::to_owned) - .ok_or_else(|| ConfigError::Parent(path.into_owned()))?; + .ok_or_else(|| CodegenConfigError::Parent(path.into_owned()))?; Ok((config, parent)) } diff --git a/core/tauri-macros/Cargo.toml b/core/tauri-macros/Cargo.toml index 362126b8c35a..ed99b79a9be4 100644 --- a/core/tauri-macros/Cargo.toml +++ b/core/tauri-macros/Cargo.toml @@ -7,7 +7,8 @@ license = "Apache-2.0 OR MIT" homepage = "https://tauri.studio" repository = "https://github.com/tauri-apps/tauri" description = "Macros for the tauri crate." -edition = "2018" +edition = "2021" +rust-version = "1.57" exclude = [ ".license_template", "CHANGELOG.md", "/target" ] readme = "README.md" @@ -18,7 +19,13 @@ proc-macro = true proc-macro2 = "1" quote = "1" syn = { version = "1", features = [ "full" ] } -tauri-codegen = { version = "1.0.0-beta.4", path = "../tauri-codegen" } +heck = "0.4" +tauri-codegen = { version = "1.0.0-beta.4", default-features = false, path = "../tauri-codegen" } +tauri-utils = { version = "1.0.0-beta.3", path = "../tauri-utils" } [features] custom-protocol = [ ] +compression = [ "tauri-codegen/compression" ] +isolation = ["tauri-codegen/isolation"] +shell-scope = ["tauri-codegen/shell-scope"] +config-json5 = [ "tauri-codegen/config-json5", "tauri-utils/config-json5" ] diff --git a/core/tauri-macros/src/command/handler.rs b/core/tauri-macros/src/command/handler.rs index 131f6f85b2b4..75e882442527 100644 --- a/core/tauri-macros/src/command/handler.rs +++ b/core/tauri-macros/src/command/handler.rs @@ -16,7 +16,7 @@ pub struct Handler { } impl Parse for Handler { - fn parse(input: &ParseBuffer) -> syn::Result { + fn parse(input: &ParseBuffer<'_>) -> syn::Result { let paths = input.parse_terminated::(Path::parse)?; // parse the command names and wrappers from the passed paths diff --git a/core/tauri-macros/src/command/wrapper.rs b/core/tauri-macros/src/command/wrapper.rs index c4f5820eeba5..9d27962feb45 100644 --- a/core/tauri-macros/src/command/wrapper.rs +++ b/core/tauri-macros/src/command/wrapper.rs @@ -19,7 +19,7 @@ enum ExecutionContext { } impl Parse for ExecutionContext { - fn parse(input: &ParseBuffer) -> syn::Result { + fn parse(input: &ParseBuffer<'_>) -> syn::Result { if input.is_empty() { return Ok(Self::Blocking); } diff --git a/core/tauri-macros/src/command_module.rs b/core/tauri-macros/src/command_module.rs new file mode 100644 index 000000000000..a8301a8a421d --- /dev/null +++ b/core/tauri-macros/src/command_module.rs @@ -0,0 +1,208 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use heck::ToSnakeCase; +use proc_macro::TokenStream; +use proc_macro2::{Span, TokenStream as TokenStream2, TokenTree}; + +use quote::{format_ident, quote, quote_spanned}; +use syn::{ + parse::{Parse, ParseStream}, + spanned::Spanned, + Data, DeriveInput, Error, Fields, FnArg, Ident, ItemFn, LitStr, Pat, Token, +}; + +pub fn generate_run_fn(input: DeriveInput) -> TokenStream { + let name = &input.ident; + let data = &input.data; + + let mut is_async = false; + let attrs = input.attrs; + for attr in attrs { + if attr.path.is_ident("cmd") { + let _ = attr.parse_args_with(|input: ParseStream| { + while let Some(token) = input.parse()? { + if let TokenTree::Ident(ident) = token { + is_async |= ident == "async"; + } + } + Ok(()) + }); + } + } + let maybe_await = if is_async { quote!(.await) } else { quote!() }; + let maybe_async = if is_async { quote!(async) } else { quote!() }; + + let mut matcher; + + match data { + Data::Enum(data_enum) => { + matcher = TokenStream2::new(); + + for variant in &data_enum.variants { + let variant_name = &variant.ident; + + let (fields_in_variant, variables) = match &variant.fields { + Fields::Unit => (quote_spanned! { variant.span() => }, quote!()), + Fields::Unnamed(fields) => { + let mut variables = TokenStream2::new(); + for i in 0..fields.unnamed.len() { + let variable_name = format_ident!("value{}", i); + variables.extend(quote!(#variable_name,)); + } + (quote_spanned! { variant.span() => (#variables) }, variables) + } + Fields::Named(fields) => { + let mut variables = TokenStream2::new(); + for field in &fields.named { + let ident = field.ident.as_ref().unwrap(); + variables.extend(quote!(#ident,)); + } + ( + quote_spanned! { variant.span() => { #variables } }, + variables, + ) + } + }; + + let mut variant_execute_function_name = format_ident!( + "{}", + variant_name.to_string().to_snake_case().to_lowercase() + ); + variant_execute_function_name.set_span(variant_name.span()); + + matcher.extend(quote_spanned! { + variant.span() => #name::#variant_name #fields_in_variant => #name::#variant_execute_function_name(context, #variables)#maybe_await.map(Into::into), + }); + } + } + _ => { + return Error::new( + Span::call_site(), + "CommandModule is only implemented for enums", + ) + .to_compile_error() + .into() + } + }; + + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + + let expanded = quote! { + impl #impl_generics #name #ty_generics #where_clause { + pub #maybe_async fn run(self, context: crate::endpoints::InvokeContext) -> crate::Result { + match self { + #matcher + } + } + } + }; + + TokenStream::from(expanded) +} + +/// Attributes for the module enum variant handler. +pub struct HandlerAttributes { + allowlist: Ident, + error_message: String, +} + +impl Parse for HandlerAttributes { + fn parse(input: ParseStream) -> syn::Result { + let allowlist = input.parse()?; + input.parse::()?; + let raw: LitStr = input.parse()?; + let error_message = raw.value(); + Ok(Self { + allowlist, + error_message, + }) + } +} + +pub struct HandlerTestAttributes { + allowlist: Ident, + error_message: String, + is_async: bool, +} + +impl Parse for HandlerTestAttributes { + fn parse(input: ParseStream) -> syn::Result { + let allowlist = input.parse()?; + input.parse::()?; + let error_message_raw: LitStr = input.parse()?; + let error_message = error_message_raw.value(); + let _ = input.parse::(); + let is_async = input + .parse::() + .map(|i| i == "async") + .unwrap_or_default(); + + Ok(Self { + allowlist, + error_message, + is_async, + }) + } +} + +pub fn command_handler(attributes: HandlerAttributes, function: ItemFn) -> TokenStream2 { + let allowlist = attributes.allowlist; + let error_message = attributes.error_message.as_str(); + let signature = function.sig.clone(); + + quote!( + #[cfg(#allowlist)] + #function + + #[cfg(not(#allowlist))] + #[allow(unused_variables)] + #[allow(unused_mut)] + #signature { + Err(crate::Error::ApiNotAllowlisted( + #error_message.to_string(), + )) + } + ) +} + +pub fn command_test(attributes: HandlerTestAttributes, function: ItemFn) -> TokenStream2 { + let allowlist = attributes.allowlist; + let is_async = attributes.is_async; + let error_message = attributes.error_message.as_str(); + let signature = function.sig.clone(); + let test_name = function.sig.ident.clone(); + let mut args = quote!(); + for arg in &function.sig.inputs { + if let FnArg::Typed(t) = arg { + if let Pat::Ident(i) = &*t.pat { + let ident = &i.ident; + args.extend(quote!(#ident,)) + } + } + } + + let response = if is_async { + quote!(crate::async_runtime::block_on( + super::Cmd::#test_name(crate::test::mock_invoke_context(), #args) + )) + } else { + quote!(super::Cmd::#test_name(crate::test::mock_invoke_context(), #args)) + }; + + quote!( + #[cfg(#allowlist)] + #function + + #[cfg(not(#allowlist))] + #[quickcheck_macros::quickcheck] + #signature { + if let Err(crate::Error::ApiNotAllowlisted(e)) = #response { + assert_eq!(e, #error_message); + } else { + panic!("unexpected response"); + } + } + ) +} diff --git a/core/tauri-macros/src/context.rs b/core/tauri-macros/src/context.rs index ee17c13f9ca3..337fe3a6098e 100644 --- a/core/tauri-macros/src/context.rs +++ b/core/tauri-macros/src/context.rs @@ -11,6 +11,7 @@ use syn::{ LitStr, PathArguments, PathSegment, Token, }; use tauri_codegen::{context_codegen, get_config, ContextData}; +use tauri_utils::config::parse::does_supported_extension_exist; pub(crate) struct ContextItems { config_file: PathBuf, @@ -18,7 +19,7 @@ pub(crate) struct ContextItems { } impl Parse for ContextItems { - fn parse(input: &ParseBuffer) -> syn::parse::Result { + fn parse(input: &ParseBuffer<'_>) -> syn::parse::Result { let config_file = if input.is_empty() { std::env::var("CARGO_MANIFEST_DIR").map(|m| PathBuf::from(m).join("tauri.conf.json")) } else { @@ -35,7 +36,7 @@ impl Parse for ContextItems { VarError::NotUnicode(_) => "CARGO_MANIFEST_DIR env var contained invalid utf8".into(), }) .and_then(|path| { - if path.exists() { + if does_supported_extension_exist(&path) { Ok(path) } else { Err(format!( diff --git a/core/tauri-macros/src/lib.rs b/core/tauri-macros/src/lib.rs index 01ac0a3f966b..b431b39ba31c 100644 --- a/core/tauri-macros/src/lib.rs +++ b/core/tauri-macros/src/lib.rs @@ -2,12 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -extern crate proc_macro; use crate::context::ContextItems; use proc_macro::TokenStream; -use syn::{parse_macro_input, DeriveInput}; +use syn::{parse_macro_input, DeriveInput, ItemFn}; mod command; +mod command_module; mod runtime; #[macro_use] @@ -28,16 +28,17 @@ pub fn command(attributes: TokenStream, item: TokenStream) -> TokenStream { /// /// # Example /// ```rust,ignore -/// use tauri::command; +/// use tauri_macros::{command, generate_handler}; /// #[command] -/// fn command_one() {} +/// fn command_one() { +/// println!("command one called"); +/// } /// #[command] -/// fn command_two() {} +/// fn command_two() { +/// println!("command two called"); +/// } /// fn main() { -/// tauri::Builder::default() -/// .invoke_handler(tauri::generate_handler![command_one, command_two]) -/// .run(tauri::generate_context!()) -/// .expect("error while running tauri application"); +/// let _handler = generate_handler![command_one, command_two]; /// } /// ``` /// # Stability @@ -74,3 +75,32 @@ pub fn default_runtime(attributes: TokenStream, input: TokenStream) -> TokenStre let input = parse_macro_input!(input as DeriveInput); runtime::default_runtime(attributes, input).into() } + +/// Adds a `run` method to an enum (one of the tauri endpoint modules). +/// The `run` method takes a `tauri::endpoints::InvokeContext` +/// and returns a `tauri::Result`. +/// It matches on each enum variant and call a method with name equal to the variant name, lowercased and snake_cased, +/// passing the the context and the variant's fields as arguments. +/// That function must also return the same `Result`. +#[doc(hidden)] +#[proc_macro_derive(CommandModule, attributes(cmd))] +pub fn derive_command_module(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + command_module::generate_run_fn(input) +} + +#[doc(hidden)] +#[proc_macro_attribute] +pub fn module_command_handler(attributes: TokenStream, input: TokenStream) -> TokenStream { + let attributes = parse_macro_input!(attributes as command_module::HandlerAttributes); + let input = parse_macro_input!(input as ItemFn); + command_module::command_handler(attributes, input).into() +} + +#[doc(hidden)] +#[proc_macro_attribute] +pub fn module_command_test(attributes: TokenStream, input: TokenStream) -> TokenStream { + let attributes = parse_macro_input!(attributes as command_module::HandlerTestAttributes); + let input = parse_macro_input!(input as ItemFn); + command_module::command_test(attributes, input).into() +} diff --git a/core/tauri-macros/src/runtime.rs b/core/tauri-macros/src/runtime.rs index 83213d30f941..3fe0f0d2b005 100644 --- a/core/tauri-macros/src/runtime.rs +++ b/core/tauri-macros/src/runtime.rs @@ -14,7 +14,7 @@ pub(crate) struct Attributes { } impl Parse for Attributes { - fn parse(input: ParseStream) -> syn::Result { + fn parse(input: ParseStream<'_>) -> syn::Result { let default_type = input.parse()?; input.parse::()?; Ok(Attributes { diff --git a/core/tauri-runtime-wry/Cargo.toml b/core/tauri-runtime-wry/Cargo.toml index 5cd97298b65d..db22ed8bf01f 100644 --- a/core/tauri-runtime-wry/Cargo.toml +++ b/core/tauri-runtime-wry/Cargo.toml @@ -7,12 +7,13 @@ license = "Apache-2.0 OR MIT" homepage = "https://tauri.studio" repository = "https://github.com/tauri-apps/tauri" description = "Wry bindings to the Tauri runtime" -edition = "2018" +edition = "2021" +rust-version = "1.57" exclude = [ ".license_template", "CHANGELOG.md", "/target" ] readme = "README.md" [dependencies] -wry = { version = "0.12", default-features = false, features = [ "file-drop", "protocol" ] } +wry = { version = "0.13.1", default-features = false, features = [ "file-drop", "protocol" ] } tauri-runtime = { version = "0.2.1", path = "../tauri-runtime" } tauri-utils = { version = "1.0.0-beta.3", path = "../tauri-utils" } uuid = { version = "0.8.2", features = [ "v4" ] } @@ -20,12 +21,20 @@ infer = "0.4" [target."cfg(windows)".dependencies] ico = "0.1" -winapi = "0.3" +webview2-com = "0.11.0" + +[target."cfg(windows)".dependencies.windows] +version = "0.30.0" +features = [ + "Win32_Foundation", +] [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] png = "0.16" -gtk = { version = "0.14", features = [ "v3_20" ] } +gtk = { version = "0.15", features = [ "v3_20" ] } [features] dox = [ "wry/dox" ] +devtools = [ "wry/devtool", "tauri-runtime/devtools" ] system-tray = [ "wry/tray", "tauri-runtime/system-tray" ] +macos-private-api = [ "wry/fullscreen", "wry/transparent", "tauri-runtime/macos-private-api" ] diff --git a/core/tauri-runtime-wry/src/lib.rs b/core/tauri-runtime-wry/src/lib.rs index ebece72cee1a..809b4c4413fc 100644 --- a/core/tauri-runtime-wry/src/lib.rs +++ b/core/tauri-runtime-wry/src/lib.rs @@ -9,14 +9,12 @@ use tauri_runtime::{ Request as HttpRequest, RequestParts as HttpRequestParts, Response as HttpResponse, ResponseParts as HttpResponseParts, }, - menu::{CustomMenuItem, Menu, MenuEntry, MenuHash, MenuItem, MenuUpdate, Submenu}, + menu::{CustomMenuItem, Menu, MenuEntry, MenuHash, MenuId, MenuItem, MenuUpdate}, monitor::Monitor, - webview::{ - FileDropEvent, FileDropHandler, RpcRequest, WebviewRpcHandler, WindowBuilder, WindowBuilderBase, - }, + webview::{FileDropEvent, FileDropHandler, WebviewIpcHandler, WindowBuilder, WindowBuilderBase}, window::{ dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}, - DetachedWindow, PendingWindow, WindowEvent, + DetachedWindow, JsEventListenerKey, PendingWindow, WindowEvent, }, ClipboardManager, Dispatch, Error, ExitRequestedEventAction, GlobalShortcutManager, Icon, Result, RunEvent, RunIteration, Runtime, RuntimeHandle, UserAttentionType, @@ -26,7 +24,9 @@ use tauri_runtime::window::MenuEvent; #[cfg(feature = "system-tray")] use tauri_runtime::{SystemTray, SystemTrayEvent}; #[cfg(windows)] -use winapi::shared::windef::HWND; +use webview2_com::FocusChangedEventHandler; +#[cfg(windows)] +use windows::Win32::{Foundation::HWND, System::WinRT::EventRegistrationToken}; #[cfg(all(feature = "system-tray", target_os = "macos"))] use wry::application::platform::macos::{SystemTrayBuilderExtMacOS, SystemTrayExtMacOS}; #[cfg(target_os = "linux")] @@ -62,10 +62,7 @@ use wry::{ Request as WryHttpRequest, RequestParts as WryRequestParts, Response as WryHttpResponse, ResponseParts as WryResponseParts, }, - webview::{ - FileDropEvent as WryFileDropEvent, RpcRequest as WryRpcRequest, RpcResponse, WebContext, - WebView, WebViewBuilder, - }, + webview::{FileDropEvent as WryFileDropEvent, WebContext, WebView, WebViewBuilder}, }; pub use wry::application::window::{Window, WindowBuilder as WryWindowBuilder, WindowId}; @@ -84,16 +81,15 @@ pub use wry::application::platform::macos::{ use std::{ collections::{ hash_map::Entry::{Occupied, Vacant}, - HashMap, + HashMap, HashSet, }, - convert::TryFrom, fmt, fs::read, + ops::Deref, path::PathBuf, sync::{ - atomic::{AtomicBool, Ordering}, mpsc::{channel, Sender}, - Arc, Mutex, MutexGuard, + Arc, Mutex, MutexGuard, Weak, }, thread::{current as current_thread, ThreadId}, }; @@ -103,7 +99,7 @@ mod system_tray; #[cfg(feature = "system-tray")] use system_tray::*; -type WebContextStore = Mutex, WebContext>>; +type WebContextStore = Arc, WebContext>>>; // window type WindowEventHandler = Box; type WindowEventListenersMap = Arc>>; @@ -115,46 +111,77 @@ pub type MenuEventHandler = Box; pub type MenuEventListeners = Arc>>; pub type WindowMenuEventListeners = Arc>>; -macro_rules! dispatcher_getter { +macro_rules! getter { + ($self: ident, $rx: expr, $message: expr) => {{ + send_user_message(&$self.context, $message)?; + $rx.recv().map_err(|_| Error::FailedToReceiveMessage) + }}; +} + +macro_rules! window_getter { ($self: ident, $message: expr) => {{ - if current_thread().id() == $self.context.main_thread_id { - panic!("This API cannot be called on the main thread. Try using `std::thread::spawn` or `tauri::async_runtime::spawn`."); - } - if !$self.context.is_event_loop_running.load(Ordering::Relaxed) { - panic!("This API cannot be called when the event loop is not running. Try using `std::thread::spawn` or `tauri::async_runtime::spawn`."); - } let (tx, rx) = channel(); - $self - .context - .proxy - .send_event(Message::Window($self.window_id, $message(tx))) - .map_err(|_| Error::FailedToSendMessage)?; - rx.recv().unwrap() + getter!($self, rx, Message::Window($self.window_id, $message(tx))) }}; } -macro_rules! getter { - ($self: ident, $rx: expr, $message: expr) => {{ - if current_thread().id() == $self.context.main_thread_id { - panic!("This API cannot be called on the main thread. Try using `std::thread::spawn` or `tauri::async_runtime::spawn`."); - } - if !$self.context.is_event_loop_running.load(Ordering::Relaxed) { - panic!("This API cannot be called when the event loop is not running. Try using `std::thread::spawn` or `tauri::async_runtime::spawn`."); - } - $self - .context +fn send_user_message(context: &Context, message: Message) -> Result<()> { + if current_thread().id() == context.main_thread_id { + handle_user_message( + &context.main_thread.window_target, + message, + UserMessageContext { + window_event_listeners: &context.window_event_listeners, + global_shortcut_manager: context.main_thread.global_shortcut_manager.clone(), + clipboard_manager: context.main_thread.clipboard_manager.clone(), + menu_event_listeners: &context.menu_event_listeners, + windows: context.main_thread.windows.clone(), + #[cfg(feature = "system-tray")] + tray_context: &context.main_thread.tray_context, + }, + &context.main_thread.web_context, + ); + Ok(()) + } else { + context .proxy - .send_event($message) - .map_err(|_| Error::FailedToSendMessage)?; - $rx.recv().unwrap() - }}; + .send_event(message) + .map_err(|_| Error::FailedToSendMessage) + } } -#[derive(Debug, Clone)] -struct EventLoopContext { +#[derive(Clone)] +struct Context { main_thread_id: ThreadId, - is_event_loop_running: Arc, proxy: EventLoopProxy, + window_event_listeners: WindowEventListeners, + menu_event_listeners: MenuEventListeners, + main_thread: DispatcherMainThreadContext, +} + +#[derive(Debug, Clone)] +struct DispatcherMainThreadContext { + window_target: EventLoopWindowTarget, + web_context: WebContextStore, + global_shortcut_manager: Arc>, + clipboard_manager: Arc>, + windows: Arc>>, + #[cfg(feature = "system-tray")] + tray_context: TrayContext, +} + +// SAFETY: we ensure this type is only used on the main thread. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Send for DispatcherMainThreadContext {} + +impl fmt::Debug for Context { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Context") + .field("main_thread_id", &self.main_thread_id) + .field("proxy", &self.proxy) + .field("main_thread", &self.main_thread) + .finish() + } } struct HttpRequestPartsWrapper(HttpRequestParts); @@ -344,16 +371,22 @@ impl From for NativeImageWrapper { #[derive(Debug, Clone)] pub struct GlobalShortcutWrapper(GlobalShortcut); +// SAFETY: usage outside of main thread is guarded, we use the event loop on such cases. +#[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for GlobalShortcutWrapper {} /// Wrapper around [`WryShortcutManager`]. #[derive(Clone)] pub struct GlobalShortcutManagerHandle { - context: EventLoopContext, + context: Context, shortcuts: Arc>>, listeners: GlobalShortcutListeners, } +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for GlobalShortcutManagerHandle {} + impl fmt::Debug for GlobalShortcutManagerHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("GlobalShortcutManagerHandle") @@ -366,14 +399,14 @@ impl fmt::Debug for GlobalShortcutManagerHandle { impl GlobalShortcutManager for GlobalShortcutManagerHandle { fn is_registered(&self, accelerator: &str) -> Result { let (tx, rx) = channel(); - Ok(getter!( + getter!( self, rx, Message::GlobalShortcut(GlobalShortcutMessage::IsRegistered( accelerator.parse().expect("invalid accelerator"), tx )) - )) + ) } fn register(&mut self, accelerator: &str, handler: F) -> Result<()> { @@ -384,7 +417,7 @@ impl GlobalShortcutManager for GlobalShortcutManagerHandle { self, rx, Message::GlobalShortcut(GlobalShortcutMessage::Register(wry_accelerator, tx)) - )?; + )??; self.listeners.lock().unwrap().insert(id, Box::new(handler)); self @@ -402,7 +435,7 @@ impl GlobalShortcutManager for GlobalShortcutManagerHandle { self, rx, Message::GlobalShortcut(GlobalShortcutMessage::UnregisterAll(tx)) - )?; + )??; self.listeners.lock().unwrap().clear(); self.shortcuts.lock().unwrap().clear(); Ok(()) @@ -415,7 +448,7 @@ impl GlobalShortcutManager for GlobalShortcutManagerHandle { self, rx, Message::GlobalShortcut(GlobalShortcutMessage::Unregister(shortcut, tx)) - )?; + )??; self.listeners.lock().unwrap().remove(&accelerator_id); } Ok(()) @@ -424,17 +457,17 @@ impl GlobalShortcutManager for GlobalShortcutManagerHandle { #[derive(Debug, Clone)] pub struct ClipboardManagerWrapper { - context: EventLoopContext, + context: Context, } +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for ClipboardManagerWrapper {} + impl ClipboardManager for ClipboardManagerWrapper { fn read_text(&self) -> Result> { let (tx, rx) = channel(); - Ok(getter!( - self, - rx, - Message::Clipboard(ClipboardMessage::ReadText(tx)) - )) + getter!(self, rx, Message::Clipboard(ClipboardMessage::ReadText(tx))) } fn write_text>(&mut self, text: T) -> Result<()> { @@ -443,7 +476,7 @@ impl ClipboardManager for ClipboardManagerWrapper { self, rx, Message::Clipboard(ClipboardMessage::WriteText(text.into(), tx)) - ); + )?; Ok(()) } } @@ -500,6 +533,19 @@ impl TryFrom for WryIcon { struct WindowEventWrapper(Option); +impl WindowEventWrapper { + fn parse(webview: &WindowHandle, event: &WryWindowEvent<'_>) -> Self { + match event { + // resized event from tao doesn't include a reliable size on macOS + // because wry replaces the NSView + WryWindowEvent::Resized(_) => Self(Some(WindowEvent::Resized( + PhysicalSizeWrapper(webview.inner_size()).into(), + ))), + e => e.into(), + } + } +} + impl<'a> From<&WryWindowEvent<'a>> for WindowEventWrapper { fn from(event: &WryWindowEvent<'a>) -> Self { let event = match event { @@ -507,7 +553,6 @@ impl<'a> From<&WryWindowEvent<'a>> for WindowEventWrapper { WryWindowEvent::Moved(position) => { WindowEvent::Moved(PhysicalPositionWrapper(*position).into()) } - WryWindowEvent::CloseRequested => WindowEvent::CloseRequested, WryWindowEvent::Destroyed => WindowEvent::Destroyed, WryWindowEvent::ScaleFactorChanged { scale_factor, @@ -516,6 +561,8 @@ impl<'a> From<&WryWindowEvent<'a>> for WindowEventWrapper { scale_factor: *scale_factor, new_inner_size: PhysicalSizeWrapper(**new_inner_size).into(), }, + #[cfg(any(target_os = "linux", target_os = "macos"))] + WryWindowEvent::Focused(focused) => WindowEvent::Focused(*focused), _ => return Self(None), }; Self(Some(event)) @@ -645,10 +692,11 @@ impl From for UserAttentionTypeWrapper { pub struct WindowBuilderWrapper { inner: WryWindowBuilder, center: bool, - menu: Menu, + menu: Option

, } -// safe since `menu_items` are read only here +// SAFETY: this type is `Send` since `menu_items` are read only here +#[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for WindowBuilderWrapper {} impl WindowBuilderBase for WindowBuilderWrapper {} @@ -663,13 +711,17 @@ impl WindowBuilder for WindowBuilderWrapper { .inner_size(config.width, config.height) .visible(config.visible) .resizable(config.resizable) + .fullscreen(config.fullscreen) .decorations(config.decorations) .maximized(config.maximized) - .fullscreen(config.fullscreen) - .transparent(config.transparent) .always_on_top(config.always_on_top) .skip_taskbar(config.skip_taskbar); + #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] + { + window = window.transparent(config.transparent); + } + if let (Some(min_width), Some(min_height)) = (config.min_width, config.min_height) { window = window.min_inner_size(min_width, min_height); } @@ -688,7 +740,7 @@ impl WindowBuilder for WindowBuilderWrapper { } fn menu(mut self, menu: Menu) -> Self { - self.menu = convert_menu_id(Menu::new(), menu); + self.menu.replace(menu); self } @@ -760,6 +812,7 @@ impl WindowBuilder for WindowBuilderWrapper { self } + #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] fn transparent(mut self, transparent: bool) -> Self { self.inner = self.inner.with_transparent(transparent); self @@ -809,19 +862,8 @@ impl WindowBuilder for WindowBuilderWrapper { self.inner.window.window_icon.is_some() } - fn has_menu(&self) -> bool { - self.inner.window.window_menu.is_some() - } -} - -pub struct RpcRequestWrapper(WryRpcRequest); - -impl From for RpcRequest { - fn from(request: RpcRequestWrapper) -> Self { - Self { - command: request.0.method, - params: request.0.params, - } + fn get_menu(&self) -> Option<&Menu> { + self.menu.as_ref() } } @@ -842,11 +884,13 @@ impl From for FileDropEvent { #[cfg(target_os = "macos")] pub struct NSWindow(*mut std::ffi::c_void); #[cfg(target_os = "macos")] +#[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for NSWindow {} #[cfg(windows)] pub struct Hwnd(HWND); #[cfg(windows)] +#[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for Hwnd {} #[cfg(any( @@ -864,10 +908,13 @@ pub struct GtkWindow(gtk::ApplicationWindow); target_os = "netbsd", target_os = "openbsd" ))] +#[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for GtkWindow {} #[derive(Debug, Clone)] pub enum WindowMessage { + #[cfg(any(debug_assertions, feature = "devtools"))] + OpenDevTools, // Getters ScaleFactor(Sender), InnerPosition(Sender>>), @@ -921,6 +968,7 @@ pub enum WindowMessage { SetSkipTaskbar(bool), DragWindow, UpdateMenuItem(u16, MenuUpdate), + RequestRedraw, } #[derive(Debug, Clone)] @@ -941,9 +989,11 @@ pub enum WebviewEvent { #[derive(Debug, Clone)] pub enum TrayMessage { UpdateItem(u16, MenuUpdate), + UpdateMenu(SystemTrayMenu), UpdateIcon(Icon), #[cfg(target_os = "macos")] UpdateIconAsTemplate(bool), + Close, } #[derive(Debug, Clone)] @@ -974,28 +1024,23 @@ pub enum Message { ), CreateWindow( Box (String, WryWindowBuilder) + Send>, - Sender>>, + Sender>>, ), GlobalShortcut(GlobalShortcutMessage), Clipboard(ClipboardMessage), } -#[derive(Clone)] -struct DispatcherContext { - main_thread_id: ThreadId, - is_event_loop_running: Arc, - proxy: EventLoopProxy, - window_event_listeners: WindowEventListeners, - menu_event_listeners: MenuEventListeners, -} - -impl fmt::Debug for DispatcherContext { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("DispatcherContext") - .field("main_thread_id", &self.main_thread_id) - .field("is_event_loop_running", &self.is_event_loop_running) - .field("proxy", &self.proxy) - .finish() +impl Clone for Message { + fn clone(&self) -> Self { + match self { + Self::Window(i, m) => Self::Window(*i, m.clone()), + Self::Webview(i, m) => Self::Webview(*i, m.clone()), + #[cfg(feature = "system-tray")] + Self::Tray(m) => Self::Tray(m.clone()), + Self::GlobalShortcut(m) => Self::GlobalShortcut(m.clone()), + Self::Clipboard(m) => Self::Clipboard(m.clone()), + _ => unimplemented!(), + } } } @@ -1003,19 +1048,19 @@ impl fmt::Debug for DispatcherContext { #[derive(Debug, Clone)] pub struct WryDispatcher { window_id: WindowId, - context: DispatcherContext, + context: Context, } +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for WryDispatcher {} + impl Dispatch for WryDispatcher { type Runtime = Wry; type WindowBuilder = WindowBuilderWrapper; fn run_on_main_thread(&self, f: F) -> Result<()> { - self - .context - .proxy - .send_event(Message::Task(Box::new(f))) - .map_err(|_| Error::FailedToSendMessage) + send_user_message(&self.context, Message::Task(Box::new(f))) } fn on_window_event(&self, f: F) -> Uuid { @@ -1048,71 +1093,73 @@ impl Dispatch for WryDispatcher { id } + #[cfg(any(debug_assertions, feature = "devtools"))] + fn open_devtools(&self) { + let _ = send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::OpenDevTools), + ); + } + // Getters fn scale_factor(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::ScaleFactor)) + window_getter!(self, WindowMessage::ScaleFactor) } fn inner_position(&self) -> Result> { - dispatcher_getter!(self, WindowMessage::InnerPosition) + window_getter!(self, WindowMessage::InnerPosition)? } fn outer_position(&self) -> Result> { - dispatcher_getter!(self, WindowMessage::OuterPosition) + window_getter!(self, WindowMessage::OuterPosition)? } fn inner_size(&self) -> Result> { - Ok(dispatcher_getter!(self, WindowMessage::InnerSize)) + window_getter!(self, WindowMessage::InnerSize) } fn outer_size(&self) -> Result> { - Ok(dispatcher_getter!(self, WindowMessage::OuterSize)) + window_getter!(self, WindowMessage::OuterSize) } fn is_fullscreen(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::IsFullscreen)) + window_getter!(self, WindowMessage::IsFullscreen) } fn is_maximized(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::IsMaximized)) + window_getter!(self, WindowMessage::IsMaximized) } /// Gets the window’s current decoration state. fn is_decorated(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::IsDecorated)) + window_getter!(self, WindowMessage::IsDecorated) } /// Gets the window’s current resizable state. fn is_resizable(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::IsResizable)) + window_getter!(self, WindowMessage::IsResizable) } fn is_visible(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::IsVisible)) + window_getter!(self, WindowMessage::IsVisible) } fn is_menu_visible(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::IsMenuVisible)) + window_getter!(self, WindowMessage::IsMenuVisible) } fn current_monitor(&self) -> Result> { - Ok( - dispatcher_getter!(self, WindowMessage::CurrentMonitor) - .map(|m| MonitorHandleWrapper(m).into()), - ) + Ok(window_getter!(self, WindowMessage::CurrentMonitor)?.map(|m| MonitorHandleWrapper(m).into())) } fn primary_monitor(&self) -> Result> { - Ok( - dispatcher_getter!(self, WindowMessage::PrimaryMonitor) - .map(|m| MonitorHandleWrapper(m).into()), - ) + Ok(window_getter!(self, WindowMessage::PrimaryMonitor)?.map(|m| MonitorHandleWrapper(m).into())) } fn available_monitors(&self) -> Result> { Ok( - dispatcher_getter!(self, WindowMessage::AvailableMonitors) + window_getter!(self, WindowMessage::AvailableMonitors)? .into_iter() .map(|m| MonitorHandleWrapper(m).into()) .collect(), @@ -1121,12 +1168,12 @@ impl Dispatch for WryDispatcher { #[cfg(target_os = "macos")] fn ns_window(&self) -> Result<*mut std::ffi::c_void> { - Ok(dispatcher_getter!(self, WindowMessage::NSWindow).0) + window_getter!(self, WindowMessage::NSWindow).map(|w| w.0) } #[cfg(windows)] fn hwnd(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::Hwnd).0) + window_getter!(self, WindowMessage::Hwnd).map(|w| w.0) } /// Returns the `ApplicatonWindow` from gtk crate that is used by this window. @@ -1138,32 +1185,30 @@ impl Dispatch for WryDispatcher { target_os = "openbsd" ))] fn gtk_window(&self) -> Result { - Ok(dispatcher_getter!(self, WindowMessage::GtkWindow).0) + window_getter!(self, WindowMessage::GtkWindow).map(|w| w.0) } // Setters fn center(&self) -> Result<()> { - dispatcher_getter!(self, WindowMessage::Center) + window_getter!(self, WindowMessage::Center)? } fn print(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Webview(self.window_id, WebviewMessage::Print)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Webview(self.window_id, WebviewMessage::Print), + ) } fn request_user_attention(&self, request_type: Option) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( + send_user_message( + &self.context, + Message::Window( self.window_id, WindowMessage::RequestUserAttention(request_type.map(Into::into)), - )) - .map_err(|_| Error::FailedToSendMessage) + ), + ) } // Creates a window by dispatching a message to the event loop. @@ -1174,114 +1219,105 @@ impl Dispatch for WryDispatcher { ) -> Result> { let (tx, rx) = channel(); let label = pending.label.clone(); + let menu_ids = pending.menu_ids.clone(); + let js_event_listeners = pending.js_event_listeners.clone(); let context = self.context.clone(); - self - .context - .proxy - .send_event(Message::CreateWebview( + send_user_message( + &self.context, + Message::CreateWebview( Box::new(move |event_loop, web_context| { create_webview(event_loop, web_context, context, pending) }), tx, - )) - .map_err(|_| Error::FailedToSendMessage)?; + ), + )?; let window_id = rx.recv().unwrap(); let dispatcher = WryDispatcher { window_id, context: self.context.clone(), }; - Ok(DetachedWindow { label, dispatcher }) + Ok(DetachedWindow { + label, + dispatcher, + menu_ids, + js_event_listeners, + }) } fn set_resizable(&self, resizable: bool) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetResizable(resizable), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetResizable(resizable)), + ) } fn set_title>(&self, title: S) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetTitle(title.into()), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetTitle(title.into())), + ) } fn maximize(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::Maximize)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::Maximize), + ) } fn unmaximize(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::Unmaximize)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::Unmaximize), + ) } fn minimize(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::Minimize)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::Minimize), + ) } fn unminimize(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::Unminimize)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::Unminimize), + ) } fn show_menu(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::ShowMenu)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::ShowMenu), + ) } fn hide_menu(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::HideMenu)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::HideMenu), + ) } fn show(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::Show)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::Show), + ) } fn hide(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::Hide)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::Hide), + ) } fn close(&self) -> Result<()> { + // NOTE: close cannot use the `send_user_message` function because it accesses the event loop callback self .context .proxy @@ -1290,140 +1326,100 @@ impl Dispatch for WryDispatcher { } fn set_decorations(&self, decorations: bool) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetDecorations(decorations), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetDecorations(decorations)), + ) } fn set_always_on_top(&self, always_on_top: bool) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetAlwaysOnTop(always_on_top), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetAlwaysOnTop(always_on_top)), + ) } fn set_size(&self, size: Size) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetSize(size), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetSize(size)), + ) } fn set_min_size(&self, size: Option) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetMinSize(size), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetMinSize(size)), + ) } fn set_max_size(&self, size: Option) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetMaxSize(size), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetMaxSize(size)), + ) } fn set_position(&self, position: Position) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetPosition(position), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetPosition(position)), + ) } fn set_fullscreen(&self, fullscreen: bool) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetFullscreen(fullscreen), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetFullscreen(fullscreen)), + ) } fn set_focus(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::SetFocus)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetFocus), + ) } fn set_icon(&self, icon: Icon) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( + send_user_message( + &self.context, + Message::Window( self.window_id, WindowMessage::SetIcon(WryIcon::try_from(icon)?.0), - )) - .map_err(|_| Error::FailedToSendMessage) + ), + ) } fn set_skip_taskbar(&self, skip: bool) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::SetSkipTaskbar(skip), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetSkipTaskbar(skip)), + ) } fn start_dragging(&self) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window(self.window_id, WindowMessage::DragWindow)) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::DragWindow), + ) } fn eval_script>(&self, script: S) -> Result<()> { - self - .context - .proxy - .send_event(Message::Webview( + send_user_message( + &self.context, + Message::Webview( self.window_id, WebviewMessage::EvaluateScript(script.into()), - )) - .map_err(|_| Error::FailedToSendMessage) - } + ), + ) + } fn update_menu_item(&self, id: u16, update: MenuUpdate) -> Result<()> { - self - .context - .proxy - .send_event(Message::Window( - self.window_id, - WindowMessage::UpdateMenuItem(id, update), - )) - .map_err(|_| Error::FailedToSendMessage) + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::UpdateMenuItem(id, update)), + ) } } @@ -1435,11 +1431,26 @@ struct TrayContext { items: SystemTrayItems, } +#[cfg(feature = "system-tray")] +impl fmt::Debug for TrayContext { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TrayContext") + .field("items", &self.items) + .finish() + } +} + enum WindowHandle { Webview(WebView), Window(Arc), } +impl fmt::Debug for WindowHandle { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + Ok(()) + } +} + impl WindowHandle { fn window(&self) -> &Window { match self { @@ -1447,12 +1458,20 @@ impl WindowHandle { Self::Window(w) => w, } } + + fn inner_size(&self) -> WryPhysicalSize { + match self { + WindowHandle::Window(w) => w.inner_size(), + WindowHandle::Webview(w) => w.inner_size(), + } + } } +#[derive(Debug)] pub struct WindowWrapper { label: String, inner: WindowHandle, - menu_items: HashMap, + menu_items: Option>, } /// A Tauri [`Runtime`] wrapper around wry. @@ -1462,7 +1481,6 @@ pub struct Wry { global_shortcut_manager_handle: GlobalShortcutManagerHandle, clipboard_manager: Arc>, clipboard_manager_handle: ClipboardManagerWrapper, - is_event_loop_running: Arc, event_loop: EventLoop, windows: Arc>>, web_context: WebContextStore, @@ -1475,28 +1493,28 @@ pub struct Wry { /// A handle to the Wry runtime. #[derive(Debug, Clone)] pub struct WryHandle { - dispatcher_context: DispatcherContext, + context: Context, } +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for WryHandle {} + impl WryHandle { /// Creates a new tao window using a callback, and returns its window id. pub fn create_tao_window (String, WryWindowBuilder) + Send + 'static>( &self, f: F, - ) -> Result> { + ) -> Result> { let (tx, rx) = channel(); - self - .dispatcher_context - .proxy - .send_event(Message::CreateWindow(Box::new(f), tx)) - .map_err(|_| Error::FailedToSendMessage)?; + send_user_message(&self.context, Message::CreateWindow(Box::new(f), tx))?; rx.recv().unwrap() } /// Send a message to the event loop. pub fn send_event(&self, message: Message) -> Result<()> { self - .dispatcher_context + .context .proxy .send_event(message) .map_err(|_| Error::FailedToSendMessage)?; @@ -1515,89 +1533,138 @@ impl RuntimeHandle for WryHandle { ) -> Result> { let (tx, rx) = channel(); let label = pending.label.clone(); - let dispatcher_context = self.dispatcher_context.clone(); - self - .dispatcher_context - .proxy - .send_event(Message::CreateWebview( + let menu_ids = pending.menu_ids.clone(); + let js_event_listeners = pending.js_event_listeners.clone(); + let context = self.context.clone(); + send_user_message( + &self.context, + Message::CreateWebview( Box::new(move |event_loop, web_context| { - create_webview(event_loop, web_context, dispatcher_context, pending) + create_webview(event_loop, web_context, context, pending) }), tx, - )) - .map_err(|_| Error::FailedToSendMessage)?; + ), + )?; let window_id = rx.recv().unwrap(); let dispatcher = WryDispatcher { window_id, - context: self.dispatcher_context.clone(), + context: self.context.clone(), }; - Ok(DetachedWindow { label, dispatcher }) + Ok(DetachedWindow { + label, + dispatcher, + menu_ids, + js_event_listeners, + }) + } + + fn run_on_main_thread(&self, f: F) -> Result<()> { + send_user_message(&self.context, Message::Task(Box::new(f))) } #[cfg(all(windows, feature = "system-tray"))] /// Deprecated. (not needed anymore) fn remove_system_tray(&self) -> Result<()> { - Ok(()) + send_user_message(&self.context, Message::Tray(TrayMessage::Close)) } } -impl Runtime for Wry { - type Dispatcher = WryDispatcher; - type Handle = WryHandle; - type GlobalShortcutManager = GlobalShortcutManagerHandle; - type ClipboardManager = ClipboardManagerWrapper; - #[cfg(feature = "system-tray")] - type TrayHandler = SystemTrayHandle; - - fn new() -> Result { - let event_loop = EventLoop::::with_user_event(); +impl Wry { + fn init(event_loop: EventLoop) -> Result { let proxy = event_loop.create_proxy(); let main_thread_id = current_thread().id(); - let is_event_loop_running = Arc::new(AtomicBool::default()); + let web_context = WebContextStore::default(); + let global_shortcut_manager = Arc::new(Mutex::new(WryShortcutManager::new(&event_loop))); + let clipboard_manager = Arc::new(Mutex::new(Clipboard::new())); + let windows = Arc::new(Mutex::new(HashMap::default())); + let window_event_listeners = WindowEventListeners::default(); + let menu_event_listeners = MenuEventListeners::default(); + + #[cfg(feature = "system-tray")] + let tray_context = TrayContext::default(); - let event_loop_context = EventLoopContext { + let event_loop_context = Context { main_thread_id, - is_event_loop_running: is_event_loop_running.clone(), proxy, + window_event_listeners: window_event_listeners.clone(), + menu_event_listeners: menu_event_listeners.clone(), + main_thread: DispatcherMainThreadContext { + window_target: event_loop.deref().clone(), + web_context: web_context.clone(), + global_shortcut_manager: global_shortcut_manager.clone(), + clipboard_manager: clipboard_manager.clone(), + windows: windows.clone(), + #[cfg(feature = "system-tray")] + tray_context: tray_context.clone(), + }, }; - let global_shortcut_manager = WryShortcutManager::new(&event_loop); let global_shortcut_listeners = GlobalShortcutListeners::default(); - let clipboard_manager = Clipboard::new(); let clipboard_manager_handle = ClipboardManagerWrapper { context: event_loop_context.clone(), }; Ok(Self { main_thread_id, - global_shortcut_manager: Arc::new(Mutex::new(global_shortcut_manager)), + global_shortcut_manager, global_shortcut_manager_handle: GlobalShortcutManagerHandle { context: event_loop_context, shortcuts: Default::default(), listeners: global_shortcut_listeners, }, - clipboard_manager: Arc::new(Mutex::new(clipboard_manager)), + clipboard_manager, clipboard_manager_handle, - is_event_loop_running, event_loop, - windows: Default::default(), - web_context: Default::default(), - window_event_listeners: Default::default(), - menu_event_listeners: Default::default(), + windows, + web_context, + window_event_listeners, + menu_event_listeners, #[cfg(feature = "system-tray")] - tray_context: Default::default(), + tray_context, }) } +} + +impl Runtime for Wry { + type Dispatcher = WryDispatcher; + type Handle = WryHandle; + type GlobalShortcutManager = GlobalShortcutManagerHandle; + type ClipboardManager = ClipboardManagerWrapper; + #[cfg(feature = "system-tray")] + type TrayHandler = SystemTrayHandle; + + fn new() -> Result { + let event_loop = EventLoop::::with_user_event(); + Self::init(event_loop) + } + + #[cfg(any(windows, target_os = "linux"))] + fn new_any_thread() -> Result { + #[cfg(target_os = "linux")] + use wry::application::platform::unix::EventLoopExtUnix; + #[cfg(windows)] + use wry::application::platform::windows::EventLoopExtWindows; + let event_loop = EventLoop::::new_any_thread(); + Self::init(event_loop) + } fn handle(&self) -> Self::Handle { WryHandle { - dispatcher_context: DispatcherContext { + context: Context { main_thread_id: self.main_thread_id, - is_event_loop_running: self.is_event_loop_running.clone(), proxy: self.event_loop.create_proxy(), window_event_listeners: self.window_event_listeners.clone(), menu_event_listeners: self.menu_event_listeners.clone(), + main_thread: DispatcherMainThreadContext { + window_target: self.event_loop.deref().clone(), + web_context: self.web_context.clone(), + global_shortcut_manager: self.global_shortcut_manager.clone(), + clipboard_manager: self.clipboard_manager.clone(), + windows: self.windows.clone(), + #[cfg(feature = "system-tray")] + tray_context: self.tray_context.clone(), + }, }, } } @@ -1612,16 +1679,26 @@ impl Runtime for Wry { fn create_window(&self, pending: PendingWindow) -> Result> { let label = pending.label.clone(); + let menu_ids = pending.menu_ids.clone(); + let js_event_listeners = pending.js_event_listeners.clone(); let proxy = self.event_loop.create_proxy(); let webview = create_webview( &self.event_loop, &self.web_context, - DispatcherContext { + Context { main_thread_id: self.main_thread_id, - is_event_loop_running: self.is_event_loop_running.clone(), proxy: proxy.clone(), window_event_listeners: self.window_event_listeners.clone(), menu_event_listeners: self.menu_event_listeners.clone(), + main_thread: DispatcherMainThreadContext { + window_target: self.event_loop.deref().clone(), + web_context: self.web_context.clone(), + global_shortcut_manager: self.global_shortcut_manager.clone(), + clipboard_manager: self.clipboard_manager.clone(), + windows: self.windows.clone(), + #[cfg(feature = "system-tray")] + tray_context: self.tray_context.clone(), + }, }, pending, )?; @@ -1632,37 +1709,54 @@ impl Runtime for Wry { if let WindowHandle::Webview(ref webview) = webview.inner { if let Some(controller) = webview.controller() { let proxy = self.event_loop.create_proxy(); - controller - .add_got_focus(move |_| { - let _ = proxy.send_event(Message::Webview( - id, - WebviewMessage::WebviewEvent(WebviewEvent::Focused(true)), - )); - Ok(()) - }) - .unwrap(); + let mut token = EventRegistrationToken::default(); + unsafe { + controller.GotFocus( + FocusChangedEventHandler::create(Box::new(move |_, _| { + let _ = proxy.send_event(Message::Webview( + id, + WebviewMessage::WebviewEvent(WebviewEvent::Focused(true)), + )); + Ok(()) + })), + &mut token, + ) + } + .unwrap(); let proxy = self.event_loop.create_proxy(); - controller - .add_lost_focus(move |_| { - let _ = proxy.send_event(Message::Webview( - id, - WebviewMessage::WebviewEvent(WebviewEvent::Focused(false)), - )); - Ok(()) - }) - .unwrap(); + unsafe { + controller.LostFocus( + FocusChangedEventHandler::create(Box::new(move |_, _| { + let _ = proxy.send_event(Message::Webview( + id, + WebviewMessage::WebviewEvent(WebviewEvent::Focused(false)), + )); + Ok(()) + })), + &mut token, + ) + } + .unwrap(); } } } let dispatcher = WryDispatcher { window_id: webview.inner.window().id(), - context: DispatcherContext { + context: Context { main_thread_id: self.main_thread_id, - is_event_loop_running: self.is_event_loop_running.clone(), proxy, window_event_listeners: self.window_event_listeners.clone(), menu_event_listeners: self.menu_event_listeners.clone(), + main_thread: DispatcherMainThreadContext { + window_target: self.event_loop.deref().clone(), + web_context: self.web_context.clone(), + global_shortcut_manager: self.global_shortcut_manager.clone(), + clipboard_manager: self.clipboard_manager.clone(), + windows: self.windows.clone(), + #[cfg(feature = "system-tray")] + tray_context: self.tray_context.clone(), + }, }, }; @@ -1672,7 +1766,12 @@ impl Runtime for Wry { .unwrap() .insert(webview.inner.window().id(), webview); - Ok(DetachedWindow { label, dispatcher }) + Ok(DetachedWindow { + label, + dispatcher, + menu_ids, + js_event_listeners, + }) } #[cfg(feature = "system-tray")] @@ -1737,8 +1836,7 @@ impl Runtime for Wry { }); } - #[cfg(any(target_os = "windows", target_os = "macos"))] - fn run_iteration(&mut self, callback: F) -> RunIteration { + fn run_iteration(&mut self, mut callback: F) -> RunIteration { use wry::application::platform::run_return::EventLoopExtRunReturn; let windows = self.windows.clone(); let web_context = &self.web_context; @@ -1749,23 +1847,23 @@ impl Runtime for Wry { let global_shortcut_manager = self.global_shortcut_manager.clone(); let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone(); let clipboard_manager = self.clipboard_manager.clone(); - let mut iteration = RunIteration::default(); - self.is_event_loop_running.store(true, Ordering::Relaxed); self .event_loop .run_return(|event, event_loop, control_flow| { + *control_flow = ControlFlow::Wait; if let Event::MainEventsCleared = &event { *control_flow = ControlFlow::Exit; } + iteration = handle_event_loop( event, event_loop, control_flow, EventLoopIterationContext { - callback: &callback, - windows: windows.lock().expect("poisoned webview collection"), + callback: &mut callback, + windows: windows.clone(), window_event_listeners: &window_event_listeners, global_shortcut_manager: global_shortcut_manager.clone(), global_shortcut_manager_handle: &global_shortcut_manager_handle, @@ -1777,13 +1875,11 @@ impl Runtime for Wry { web_context, ); }); - self.is_event_loop_running.store(false, Ordering::Relaxed); iteration } - fn run(self, callback: F) { - self.is_event_loop_running.store(true, Ordering::Relaxed); + fn run(self, mut callback: F) { let windows = self.windows.clone(); let web_context = self.web_context; let window_event_listeners = self.window_event_listeners.clone(); @@ -1800,8 +1896,8 @@ impl Runtime for Wry { event_loop, control_flow, EventLoopIterationContext { - callback: &callback, - windows: windows.lock().expect("poisoned webview collection"), + callback: &mut callback, + windows: windows.clone(), window_event_listeners: &window_event_listeners, global_shortcut_manager: global_shortcut_manager.clone(), global_shortcut_manager_handle: &global_shortcut_manager_handle, @@ -1816,9 +1912,9 @@ impl Runtime for Wry { } } -struct EventLoopIterationContext<'a> { - callback: &'a (dyn Fn(RunEvent) + 'static), - windows: MutexGuard<'a, HashMap>, +pub struct EventLoopIterationContext<'a> { + callback: &'a mut (dyn FnMut(RunEvent) + 'static), + windows: Arc>>, window_event_listeners: &'a WindowEventListeners, global_shortcut_manager: Arc>, global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle, @@ -1828,8 +1924,351 @@ struct EventLoopIterationContext<'a> { tray_context: &'a TrayContext, } +struct UserMessageContext<'a> { + window_event_listeners: &'a WindowEventListeners, + global_shortcut_manager: Arc>, + clipboard_manager: Arc>, + menu_event_listeners: &'a MenuEventListeners, + windows: Arc>>, + #[cfg(feature = "system-tray")] + tray_context: &'a TrayContext, +} + +fn handle_user_message( + event_loop: &EventLoopWindowTarget, + message: Message, + context: UserMessageContext<'_>, + web_context: &WebContextStore, +) -> RunIteration { + let UserMessageContext { + window_event_listeners, + menu_event_listeners, + global_shortcut_manager, + clipboard_manager, + windows, + #[cfg(feature = "system-tray")] + tray_context, + } = context; + match message { + Message::Task(task) => task(), + Message::Window(id, window_message) => { + if let Some(webview) = windows + .lock() + .expect("poisoned webview collection") + .get_mut(&id) + { + let window = webview.inner.window(); + match window_message { + #[cfg(any(debug_assertions, feature = "devtools"))] + WindowMessage::OpenDevTools => { + if let WindowHandle::Webview(w) = &webview.inner { + w.devtool(); + } + } + // Getters + WindowMessage::ScaleFactor(tx) => tx.send(window.scale_factor()).unwrap(), + WindowMessage::InnerPosition(tx) => tx + .send( + window + .inner_position() + .map(|p| PhysicalPositionWrapper(p).into()) + .map_err(|_| Error::FailedToSendMessage), + ) + .unwrap(), + WindowMessage::OuterPosition(tx) => tx + .send( + window + .outer_position() + .map(|p| PhysicalPositionWrapper(p).into()) + .map_err(|_| Error::FailedToSendMessage), + ) + .unwrap(), + WindowMessage::InnerSize(tx) => tx + .send(PhysicalSizeWrapper(webview.inner.inner_size()).into()) + .unwrap(), + WindowMessage::OuterSize(tx) => tx + .send(PhysicalSizeWrapper(window.outer_size()).into()) + .unwrap(), + WindowMessage::IsFullscreen(tx) => tx.send(window.fullscreen().is_some()).unwrap(), + WindowMessage::IsMaximized(tx) => tx.send(window.is_maximized()).unwrap(), + WindowMessage::IsDecorated(tx) => tx.send(window.is_decorated()).unwrap(), + WindowMessage::IsResizable(tx) => tx.send(window.is_resizable()).unwrap(), + WindowMessage::IsVisible(tx) => tx.send(window.is_visible()).unwrap(), + WindowMessage::IsMenuVisible(tx) => tx.send(window.is_menu_visible()).unwrap(), + WindowMessage::CurrentMonitor(tx) => tx.send(window.current_monitor()).unwrap(), + WindowMessage::PrimaryMonitor(tx) => tx.send(window.primary_monitor()).unwrap(), + WindowMessage::AvailableMonitors(tx) => { + tx.send(window.available_monitors().collect()).unwrap() + } + #[cfg(target_os = "macos")] + WindowMessage::NSWindow(tx) => tx.send(NSWindow(window.ns_window())).unwrap(), + #[cfg(windows)] + WindowMessage::Hwnd(tx) => tx.send(Hwnd(HWND(window.hwnd() as _))).unwrap(), + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + ))] + WindowMessage::GtkWindow(tx) => tx.send(GtkWindow(window.gtk_window().clone())).unwrap(), + // Setters + WindowMessage::Center(tx) => { + tx.send(center_window(window, webview.inner.inner_size())) + .unwrap(); + } + WindowMessage::RequestUserAttention(request_type) => { + window.request_user_attention(request_type.map(|r| r.0)); + } + WindowMessage::SetResizable(resizable) => window.set_resizable(resizable), + WindowMessage::SetTitle(title) => window.set_title(&title), + WindowMessage::Maximize => window.set_maximized(true), + WindowMessage::Unmaximize => window.set_maximized(false), + WindowMessage::Minimize => window.set_minimized(true), + WindowMessage::Unminimize => window.set_minimized(false), + WindowMessage::ShowMenu => window.show_menu(), + WindowMessage::HideMenu => window.hide_menu(), + WindowMessage::Show => window.set_visible(true), + WindowMessage::Hide => window.set_visible(false), + WindowMessage::Close => panic!("cannot handle `WindowMessage::Close` on the main thread"), + WindowMessage::SetDecorations(decorations) => window.set_decorations(decorations), + WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top), + WindowMessage::SetSize(size) => { + window.set_inner_size(SizeWrapper::from(size).0); + } + WindowMessage::SetMinSize(size) => { + window.set_min_inner_size(size.map(|s| SizeWrapper::from(s).0)); + } + WindowMessage::SetMaxSize(size) => { + window.set_max_inner_size(size.map(|s| SizeWrapper::from(s).0)); + } + WindowMessage::SetPosition(position) => { + window.set_outer_position(PositionWrapper::from(position).0) + } + WindowMessage::SetFullscreen(fullscreen) => { + if fullscreen { + window.set_fullscreen(Some(Fullscreen::Borderless(None))) + } else { + window.set_fullscreen(None) + } + } + WindowMessage::SetFocus => { + window.set_focus(); + } + WindowMessage::SetIcon(icon) => { + window.set_window_icon(Some(icon)); + } + WindowMessage::SetSkipTaskbar(_skip) => { + #[cfg(any(target_os = "windows", target_os = "linux"))] + window.set_skip_taskbar(_skip); + } + WindowMessage::DragWindow => { + let _ = window.drag_window(); + } + WindowMessage::UpdateMenuItem(id, update) => { + if let Some(menu_items) = webview.menu_items.as_mut() { + let item = menu_items.get_mut(&id).expect("menu item not found"); + match update { + MenuUpdate::SetEnabled(enabled) => item.set_enabled(enabled), + MenuUpdate::SetTitle(title) => item.set_title(&title), + MenuUpdate::SetSelected(selected) => item.set_selected(selected), + #[cfg(target_os = "macos")] + MenuUpdate::SetNativeImage(image) => { + item.set_native_image(NativeImageWrapper::from(image).0) + } + } + } + } + WindowMessage::RequestRedraw => { + window.request_redraw(); + } + } + } + } + Message::Webview(id, webview_message) => match webview_message { + WebviewMessage::EvaluateScript(script) => { + if let Some(WindowHandle::Webview(webview)) = windows + .lock() + .expect("poisoned webview collection") + .get(&id) + .map(|w| &w.inner) + { + if let Err(e) = webview.evaluate_script(&script) { + #[cfg(debug_assertions)] + eprintln!("{}", e); + } + } + } + WebviewMessage::Print => { + if let Some(WindowHandle::Webview(webview)) = windows + .lock() + .expect("poisoned webview collection") + .get(&id) + .map(|w| &w.inner) + { + let _ = webview.print(); + } + } + WebviewMessage::WebviewEvent(event) => { + if let Some(event) = WindowEventWrapper::from(&event).0 { + for handler in window_event_listeners + .lock() + .unwrap() + .get(&id) + .unwrap() + .lock() + .unwrap() + .values() + { + handler(&event); + } + } + } + }, + Message::CreateWebview(handler, sender) => match handler(event_loop, web_context) { + Ok(webview) => { + let window_id = webview.inner.window().id(); + windows + .lock() + .expect("poisoned webview collection") + .insert(window_id, webview); + sender.send(window_id).unwrap(); + } + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("{}", e); + } + }, + Message::CreateWindow(handler, sender) => { + let (label, builder) = handler(); + if let Ok(window) = builder.build(event_loop) { + let window_id = window.id(); + + window_event_listeners + .lock() + .unwrap() + .insert(window.id(), WindowEventListenersMap::default()); + + menu_event_listeners + .lock() + .unwrap() + .insert(window.id(), WindowMenuEventListeners::default()); + + let w = Arc::new(window); + + windows.lock().expect("poisoned webview collection").insert( + window_id, + WindowWrapper { + label, + inner: WindowHandle::Window(w.clone()), + menu_items: Default::default(), + }, + ); + sender.send(Ok(Arc::downgrade(&w))).unwrap(); + } else { + sender.send(Err(Error::CreateWindow)).unwrap(); + } + } + + #[cfg(feature = "system-tray")] + Message::Tray(tray_message) => match tray_message { + TrayMessage::UpdateItem(menu_id, update) => { + let mut tray = tray_context.items.as_ref().lock().unwrap(); + let item = tray.get_mut(&menu_id).expect("menu item not found"); + match update { + MenuUpdate::SetEnabled(enabled) => item.set_enabled(enabled), + MenuUpdate::SetTitle(title) => item.set_title(&title), + MenuUpdate::SetSelected(selected) => item.set_selected(selected), + #[cfg(target_os = "macos")] + MenuUpdate::SetNativeImage(image) => { + item.set_native_image(NativeImageWrapper::from(image).0) + } + } + } + TrayMessage::UpdateMenu(menu) => { + if let Some(tray) = &*tray_context.tray.lock().unwrap() { + let mut items = HashMap::new(); + tray + .lock() + .unwrap() + .set_menu(&to_wry_context_menu(&mut items, menu)); + *tray_context.items.lock().unwrap() = items; + } + } + TrayMessage::UpdateIcon(icon) => { + if let Some(tray) = &*tray_context.tray.lock().unwrap() { + tray.lock().unwrap().set_icon(icon.into_tray_icon()); + } + } + #[cfg(target_os = "macos")] + TrayMessage::UpdateIconAsTemplate(is_template) => { + if let Some(tray) = &*tray_context.tray.lock().unwrap() { + tray.lock().unwrap().set_icon_as_template(is_template); + } + } + TrayMessage::Close => { + *tray_context.tray.lock().unwrap() = None; + tray_context.listeners.lock().unwrap().clear(); + tray_context.items.lock().unwrap().clear(); + } + }, + Message::GlobalShortcut(message) => match message { + GlobalShortcutMessage::IsRegistered(accelerator, tx) => tx + .send( + global_shortcut_manager + .lock() + .unwrap() + .is_registered(&accelerator), + ) + .unwrap(), + GlobalShortcutMessage::Register(accelerator, tx) => tx + .send( + global_shortcut_manager + .lock() + .unwrap() + .register(accelerator) + .map(GlobalShortcutWrapper) + .map_err(|e| Error::GlobalShortcut(Box::new(e))), + ) + .unwrap(), + GlobalShortcutMessage::Unregister(shortcut, tx) => tx + .send( + global_shortcut_manager + .lock() + .unwrap() + .unregister(shortcut.0) + .map_err(|e| Error::GlobalShortcut(Box::new(e))), + ) + .unwrap(), + GlobalShortcutMessage::UnregisterAll(tx) => tx + .send( + global_shortcut_manager + .lock() + .unwrap() + .unregister_all() + .map_err(|e| Error::GlobalShortcut(Box::new(e))), + ) + .unwrap(), + }, + Message::Clipboard(message) => match message { + ClipboardMessage::WriteText(text, tx) => { + clipboard_manager.lock().unwrap().write_text(text); + tx.send(()).unwrap(); + } + ClipboardMessage::ReadText(tx) => tx + .send(clipboard_manager.lock().unwrap().read_text()) + .unwrap(), + }, + } + + let it = RunIteration { + window_count: windows.lock().expect("poisoned webview collection").len(), + }; + it +} + fn handle_event_loop( - event: Event, + event: Event<'_, Message>, event_loop: &EventLoopWindowTarget, control_flow: &mut ControlFlow, context: EventLoopIterationContext<'_>, @@ -1837,7 +2276,7 @@ fn handle_event_loop( ) -> RunIteration { let EventLoopIterationContext { callback, - mut windows, + windows, window_event_listeners, global_shortcut_manager, global_shortcut_manager_handle, @@ -1848,9 +2287,10 @@ fn handle_event_loop( } = context; if *control_flow == ControlFlow::Exit { return RunIteration { - window_count: windows.len(), + window_count: windows.lock().expect("poisoned webview collection").len(), }; } + *control_flow = ControlFlow::Wait; match event { @@ -1883,8 +2323,10 @@ fn handle_event_loop( let event = MenuEvent { menu_item_id: menu_id.0, }; - let listeners = menu_event_listeners.lock().unwrap(); - let window_menu_event_listeners = listeners.get(&window_id).cloned().unwrap_or_default(); + let window_menu_event_listeners = { + let listeners = menu_event_listeners.lock().unwrap(); + listeners.get(&window_id).cloned().unwrap_or_default() + }; for handler in window_menu_event_listeners.lock().unwrap().values() { handler(&event); } @@ -1925,50 +2367,59 @@ fn handle_event_loop( Event::WindowEvent { event, window_id, .. } => { + // NOTE(amrbashir): we handle this event here instead of `match` statement below because + // we want to focus the webview as soon as possible, especially on windows. if event == WryWindowEvent::Focused(true) { - if let Some(WindowHandle::Webview(webview)) = windows.get(&window_id).map(|w| &w.inner) { + if let Some(WindowHandle::Webview(webview)) = windows + .lock() + .expect("poisoned webview collection") + .get(&window_id) + .map(|w| &w.inner) + { webview.focus(); } } - if let Some(event) = WindowEventWrapper::from(&event).0 { - for handler in window_event_listeners - .lock() - .unwrap() - .get(&window_id) - .unwrap() - .lock() - .unwrap() - .values() - { - handler(&event); + { + let windows_lock = windows.lock().expect("poisoned webview collection"); + if let Some(window_handle) = windows_lock.get(&window_id).map(|w| &w.inner) { + if let Some(event) = WindowEventWrapper::parse(window_handle, &event).0 { + drop(windows_lock); + for handler in window_event_listeners + .lock() + .unwrap() + .get(&window_id) + .unwrap() + .lock() + .unwrap() + .values() + { + handler(&event); + } + } } } + match event { WryWindowEvent::CloseRequested => { - let (tx, rx) = channel(); - if let Some(w) = windows.get(&window_id) { - callback(RunEvent::CloseRequested { - label: w.label.clone(), - signal_tx: tx, - }); - if let Ok(true) = rx.try_recv() { - } else { - on_window_close( - callback, - window_id, - &mut windows, - control_flow, - #[cfg(target_os = "linux")] - window_event_listeners, - menu_event_listeners.clone(), - ); - } - } + on_close_requested( + callback, + window_id, + windows.clone(), + control_flow, + window_event_listeners, + menu_event_listeners.clone(), + ); } WryWindowEvent::Resized(_) => { - if let Some(WindowHandle::Webview(webview)) = windows.get(&window_id).map(|w| &w.inner) { + if let Some(WindowHandle::Webview(webview)) = windows + .lock() + .expect("poisoned webview collection") + .get(&window_id) + .map(|w| &w.inner) + { if let Err(e) = webview.resize() { + #[cfg(debug_assertions)] eprintln!("{}", e); } } @@ -1976,312 +2427,111 @@ fn handle_event_loop( _ => {} } } - Event::UserEvent(message) => match message { - Message::Task(task) => task(), - Message::Window(id, window_message) => { - if let Some(webview) = windows.get_mut(&id) { - let window = webview.inner.window(); - match window_message { - // Getters - WindowMessage::ScaleFactor(tx) => tx.send(window.scale_factor()).unwrap(), - WindowMessage::InnerPosition(tx) => tx - .send( - window - .inner_position() - .map(|p| PhysicalPositionWrapper(p).into()) - .map_err(|_| Error::FailedToSendMessage), - ) - .unwrap(), - WindowMessage::OuterPosition(tx) => tx - .send( - window - .outer_position() - .map(|p| PhysicalPositionWrapper(p).into()) - .map_err(|_| Error::FailedToSendMessage), - ) - .unwrap(), - WindowMessage::InnerSize(tx) => tx - .send(PhysicalSizeWrapper(window.inner_size()).into()) - .unwrap(), - WindowMessage::OuterSize(tx) => tx - .send(PhysicalSizeWrapper(window.outer_size()).into()) - .unwrap(), - WindowMessage::IsFullscreen(tx) => tx.send(window.fullscreen().is_some()).unwrap(), - WindowMessage::IsMaximized(tx) => tx.send(window.is_maximized()).unwrap(), - WindowMessage::IsDecorated(tx) => tx.send(window.is_decorated()).unwrap(), - WindowMessage::IsResizable(tx) => tx.send(window.is_resizable()).unwrap(), - WindowMessage::IsVisible(tx) => tx.send(window.is_visible()).unwrap(), - WindowMessage::IsMenuVisible(tx) => tx.send(window.is_menu_visible()).unwrap(), - WindowMessage::CurrentMonitor(tx) => tx.send(window.current_monitor()).unwrap(), - WindowMessage::PrimaryMonitor(tx) => tx.send(window.primary_monitor()).unwrap(), - WindowMessage::AvailableMonitors(tx) => { - tx.send(window.available_monitors().collect()).unwrap() - } - #[cfg(target_os = "macos")] - WindowMessage::NSWindow(tx) => tx.send(NSWindow(window.ns_window())).unwrap(), - #[cfg(windows)] - WindowMessage::Hwnd(tx) => tx.send(Hwnd(window.hwnd() as HWND)).unwrap(), - #[cfg(any( - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - ))] - WindowMessage::GtkWindow(tx) => { - tx.send(GtkWindow(window.gtk_window().clone())).unwrap() - } - // Setters - WindowMessage::Center(tx) => { - tx.send(center_window(window)).unwrap(); - } - WindowMessage::RequestUserAttention(request_type) => { - window.request_user_attention(request_type.map(|r| r.0)); - } - WindowMessage::SetResizable(resizable) => window.set_resizable(resizable), - WindowMessage::SetTitle(title) => window.set_title(&title), - WindowMessage::Maximize => window.set_maximized(true), - WindowMessage::Unmaximize => window.set_maximized(false), - WindowMessage::Minimize => window.set_minimized(true), - WindowMessage::Unminimize => window.set_minimized(false), - WindowMessage::ShowMenu => window.show_menu(), - WindowMessage::HideMenu => window.hide_menu(), - WindowMessage::Show => window.set_visible(true), - WindowMessage::Hide => window.set_visible(false), - WindowMessage::Close => { - on_window_close( - callback, - id, - &mut windows, - control_flow, - #[cfg(target_os = "linux")] - window_event_listeners, - menu_event_listeners.clone(), - ); - } - WindowMessage::SetDecorations(decorations) => window.set_decorations(decorations), - WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top), - WindowMessage::SetSize(size) => { - window.set_inner_size(SizeWrapper::from(size).0); - } - WindowMessage::SetMinSize(size) => { - window.set_min_inner_size(size.map(|s| SizeWrapper::from(s).0)); - } - WindowMessage::SetMaxSize(size) => { - window.set_max_inner_size(size.map(|s| SizeWrapper::from(s).0)); - } - WindowMessage::SetPosition(position) => { - window.set_outer_position(PositionWrapper::from(position).0) - } - WindowMessage::SetFullscreen(fullscreen) => { - if fullscreen { - window.set_fullscreen(Some(Fullscreen::Borderless(None))) - } else { - window.set_fullscreen(None) - } - } - WindowMessage::SetFocus => { - window.set_focus(); - } - WindowMessage::SetIcon(icon) => { - window.set_window_icon(Some(icon)); - } - WindowMessage::SetSkipTaskbar(_skip) => { - #[cfg(any(target_os = "windows", target_os = "linux"))] - window.set_skip_taskbar(_skip); - } - WindowMessage::DragWindow => { - let _ = window.drag_window(); - } - WindowMessage::UpdateMenuItem(id, update) => { - let item = webview - .menu_items - .get_mut(&id) - .expect("menu item not found"); - match update { - MenuUpdate::SetEnabled(enabled) => item.set_enabled(enabled), - MenuUpdate::SetTitle(title) => item.set_title(&title), - MenuUpdate::SetSelected(selected) => item.set_selected(selected), - #[cfg(target_os = "macos")] - MenuUpdate::SetNativeImage(image) => { - item.set_native_image(NativeImageWrapper::from(image).0) - } - } - } - } - } - } - Message::Webview(id, webview_message) => { - if let Some(WindowHandle::Webview(webview)) = windows.get(&id).map(|w| &w.inner) { - match webview_message { - WebviewMessage::EvaluateScript(script) => { - if let Err(e) = webview.evaluate_script(&script) { - eprintln!("{}", e); - } - } - WebviewMessage::Print => { - let _ = webview.print(); - } - WebviewMessage::WebviewEvent(event) => { - if let Some(event) = WindowEventWrapper::from(&event).0 { - for handler in window_event_listeners - .lock() - .unwrap() - .get(&id) - .unwrap() - .lock() - .unwrap() - .values() - { - handler(&event); - } - } - } - } - } - } - Message::CreateWebview(handler, sender) => match handler(event_loop, web_context) { - Ok(webview) => { - let window_id = webview.inner.window().id(); - windows.insert(window_id, webview); - sender.send(window_id).unwrap(); - } - Err(e) => { - eprintln!("{}", e); - } - }, - Message::CreateWindow(handler, sender) => { - let (label, builder) = handler(); - if let Ok(window) = builder.build(event_loop) { - let window_id = window.id(); - - context - .window_event_listeners - .lock() - .unwrap() - .insert(window.id(), WindowEventListenersMap::default()); - - context - .menu_event_listeners - .lock() - .unwrap() - .insert(window.id(), WindowMenuEventListeners::default()); - - let w = Arc::new(window); - - windows.insert( - window_id, - WindowWrapper { - label, - inner: WindowHandle::Window(w.clone()), - menu_items: Default::default(), - }, - ); - sender.send(Ok(w)).unwrap(); - } else { - sender.send(Err(Error::CreateWindow)).unwrap(); - } + Event::UserEvent(message) => { + if let Message::Window(id, WindowMessage::Close) = message { + on_window_close( + callback, + id, + windows.lock().expect("poisoned webview collection"), + control_flow, + #[cfg(target_os = "linux")] + window_event_listeners, + menu_event_listeners.clone(), + ); + } else { + return handle_user_message( + event_loop, + message, + UserMessageContext { + window_event_listeners, + global_shortcut_manager, + clipboard_manager, + menu_event_listeners, + windows, + #[cfg(feature = "system-tray")] + tray_context, + }, + web_context, + ); } - - #[cfg(feature = "system-tray")] - Message::Tray(tray_message) => match tray_message { - TrayMessage::UpdateItem(menu_id, update) => { - let mut tray = tray_context.items.as_ref().lock().unwrap(); - let item = tray.get_mut(&menu_id).expect("menu item not found"); - match update { - MenuUpdate::SetEnabled(enabled) => item.set_enabled(enabled), - MenuUpdate::SetTitle(title) => item.set_title(&title), - MenuUpdate::SetSelected(selected) => item.set_selected(selected), - #[cfg(target_os = "macos")] - MenuUpdate::SetNativeImage(image) => { - item.set_native_image(NativeImageWrapper::from(image).0) - } - } - } - TrayMessage::UpdateIcon(icon) => { - if let Some(tray) = &*tray_context.tray.lock().unwrap() { - tray.lock().unwrap().set_icon(icon.into_tray_icon()); - } - } - #[cfg(target_os = "macos")] - TrayMessage::UpdateIconAsTemplate(is_template) => { - if let Some(tray) = &*tray_context.tray.lock().unwrap() { - tray.lock().unwrap().set_icon_as_template(is_template); - } - } - }, - Message::GlobalShortcut(message) => match message { - GlobalShortcutMessage::IsRegistered(accelerator, tx) => tx - .send( - global_shortcut_manager - .lock() - .unwrap() - .is_registered(&accelerator), - ) - .unwrap(), - GlobalShortcutMessage::Register(accelerator, tx) => tx - .send( - global_shortcut_manager - .lock() - .unwrap() - .register(accelerator) - .map(GlobalShortcutWrapper) - .map_err(|e| Error::GlobalShortcut(Box::new(e))), - ) - .unwrap(), - GlobalShortcutMessage::Unregister(shortcut, tx) => tx - .send( - global_shortcut_manager - .lock() - .unwrap() - .unregister(shortcut.0) - .map_err(|e| Error::GlobalShortcut(Box::new(e))), - ) - .unwrap(), - GlobalShortcutMessage::UnregisterAll(tx) => tx - .send( - global_shortcut_manager - .lock() - .unwrap() - .unregister_all() - .map_err(|e| Error::GlobalShortcut(Box::new(e))), - ) - .unwrap(), - }, - Message::Clipboard(message) => match message { - ClipboardMessage::WriteText(text, tx) => { - clipboard_manager.lock().unwrap().write_text(text); - tx.send(()).unwrap(); - } - ClipboardMessage::ReadText(tx) => tx - .send(clipboard_manager.lock().unwrap().read_text()) - .unwrap(), - }, - }, + } _ => (), } - RunIteration { - window_count: windows.len(), + let it = RunIteration { + window_count: windows.lock().expect("poisoned webview collection").len(), + }; + it +} + +fn on_close_requested<'a>( + callback: &'a mut (dyn FnMut(RunEvent) + 'static), + window_id: WindowId, + windows: Arc>>, + control_flow: &mut ControlFlow, + window_event_listeners: &WindowEventListeners, + menu_event_listeners: MenuEventListeners, +) -> Option { + let (tx, rx) = channel(); + let windows_guard = windows.lock().expect("poisoned webview collection"); + if let Some(w) = windows_guard.get(&window_id) { + let label = w.label.clone(); + drop(windows_guard); + for handler in window_event_listeners + .lock() + .unwrap() + .get(&window_id) + .unwrap() + .lock() + .unwrap() + .values() + { + handler(&WindowEvent::CloseRequested { + label: label.clone(), + signal_tx: tx.clone(), + }); + } + callback(RunEvent::CloseRequested { + label, + signal_tx: tx, + }); + if let Ok(true) = rx.try_recv() { + None + } else { + on_window_close( + callback, + window_id, + windows.lock().expect("poisoned webview collection"), + control_flow, + #[cfg(target_os = "linux")] + window_event_listeners, + menu_event_listeners, + ) + } + } else { + None } } fn on_window_close<'a>( - callback: &'a (dyn Fn(RunEvent) + 'static), + callback: &'a mut (dyn FnMut(RunEvent) + 'static), window_id: WindowId, - windows: &mut MutexGuard<'a, HashMap>, + mut windows: MutexGuard<'a, HashMap>, control_flow: &mut ControlFlow, #[cfg(target_os = "linux")] window_event_listeners: &WindowEventListeners, menu_event_listeners: MenuEventListeners, -) { - if let Some(webview) = windows.remove(&window_id) { +) -> Option { + #[allow(unused_mut)] + let w = if let Some(mut webview) = windows.remove(&window_id) { + let is_empty = windows.is_empty(); + drop(windows); menu_event_listeners.lock().unwrap().remove(&window_id); callback(RunEvent::WindowClose(webview.label.clone())); - if windows.is_empty() { + if is_empty { let (tx, rx) = channel(); callback(RunEvent::ExitRequested { - window_label: webview.label, + window_label: webview.label.clone(), tx, }); @@ -2293,7 +2543,10 @@ fn on_window_close<'a>( callback(RunEvent::Exit); } } - } + Some(webview) + } else { + None + }; // TODO: tao does not fire the destroyed event properly #[cfg(target_os = "linux")] { @@ -2309,14 +2562,14 @@ fn on_window_close<'a>( handler(&WindowEvent::Destroyed); } } + w } -fn center_window(window: &Window) -> Result<()> { +fn center_window(window: &Window, window_size: WryPhysicalSize) -> Result<()> { if let Some(monitor) = window.current_monitor() { let screen_size = monitor.size(); - let window_size = window.inner_size(); - let x = (screen_size.width - window_size.width) / 2; - let y = (screen_size.height - window_size.height) / 2; + let x = (screen_size.width as i32 - window_size.width as i32) / 2; + let y = (screen_size.height as i32 - window_size.height as i32) / 2; window.set_outer_position(WryPhysicalPosition::new(x, y)); Ok(()) } else { @@ -2324,38 +2577,6 @@ fn center_window(window: &Window) -> Result<()> { } } -fn convert_menu_id(mut new_menu: Menu, menu: Menu) -> Menu { - for item in menu.items { - match item { - MenuEntry::CustomItem(c) => { - let mut item = CustomMenuItem::new(c.id_str, c.title); - #[cfg(target_os = "macos")] - if let Some(native_image) = c.native_image { - item = item.native_image(native_image); - } - if let Some(accelerator) = c.keyboard_accelerator { - item = item.accelerator(accelerator); - } - if !c.enabled { - item = item.disabled(); - } - if c.selected { - item = item.selected(); - } - new_menu = new_menu.add_item(item); - } - MenuEntry::NativeItem(i) => { - new_menu = new_menu.add_native_item(i); - } - MenuEntry::Submenu(submenu) => { - let new_submenu = convert_menu_id(Menu::new(), submenu.inner); - new_menu = new_menu.add_submenu(Submenu::new(submenu.title, new_submenu)); - } - } - } - new_menu -} - fn to_wry_menu( custom_menu_items: &mut HashMap, menu: Menu, @@ -2392,7 +2613,7 @@ fn to_wry_menu( fn create_webview( event_loop: &EventLoopWindowTarget, web_context: &WebContextStore, - context: DispatcherContext, + context: Context, pending: PendingWindow, ) -> Result { #[allow(unused_mut)] @@ -2400,19 +2621,23 @@ fn create_webview( webview_attributes, uri_scheme_protocols, mut window_builder, - rpc_handler, + ipc_handler, file_drop_handler, label, url, + menu_ids, + js_event_listeners, .. } = pending; let is_window_transparent = window_builder.inner.window.transparent; - let menu_items = { + let menu_items = if let Some(menu) = window_builder.menu { let mut menu_items = HashMap::new(); - let menu = to_wry_menu(&mut menu_items, window_builder.menu); + let menu = to_wry_menu(&mut menu_items, menu); window_builder.inner = window_builder.inner.with_menu(menu); - menu_items + Some(menu_items) + } else { + None }; let window = window_builder.inner.build(event_loop).unwrap(); @@ -2429,21 +2654,28 @@ fn create_webview( .insert(window.id(), WindowMenuEventListeners::default()); if window_builder.center { - let _ = center_window(&window); + let _ = center_window(&window, window.inner_size()); } let mut webview_builder = WebViewBuilder::new(window) .map_err(|e| Error::CreateWebview(Box::new(e)))? .with_url(&url) .unwrap() // safe to unwrap because we validate the URL beforehand .with_transparent(is_window_transparent); - if let Some(handler) = rpc_handler { - webview_builder = - webview_builder.with_rpc_handler(create_rpc_handler(context.clone(), label.clone(), handler)); + if let Some(handler) = ipc_handler { + webview_builder = webview_builder.with_ipc_handler(create_ipc_handler( + context.clone(), + label.clone(), + menu_ids.clone(), + js_event_listeners.clone(), + handler, + )); } if let Some(handler) = file_drop_handler { webview_builder = webview_builder.with_file_drop_handler(create_file_drop_handler( context, label.clone(), + menu_ids, + js_event_listeners, handler, )); } @@ -2459,32 +2691,45 @@ fn create_webview( webview_builder = webview_builder.with_initialization_script(&script); } - let webview = if let Ok("true") = std::env::var("TAURI_AUTOMATION").as_deref() { - let mut web_context = web_context.lock().expect("poisoned WebContext store"); - let is_first_context = web_context.is_empty(); - let web_context = match web_context.entry(webview_attributes.data_directory) { - Occupied(occupied) => occupied.into_mut(), - Vacant(vacant) => { - let mut web_context = WebContext::new(vacant.key().clone()); - web_context.set_allows_automation(match std::env::var("TAURI_AUTOMATION").as_deref() { - Ok("true") => is_first_context, - _ => false, - }); - vacant.insert(web_context) - } - }; - webview_builder - .with_web_context(web_context) - .build() - .map_err(|e| Error::CreateWebview(Box::new(e)))? - } else { - let mut context = WebContext::new(webview_attributes.data_directory); - webview_builder - .with_web_context(&mut context) - .build() - .map_err(|e| Error::CreateWebview(Box::new(e)))? + let mut web_context = web_context.lock().expect("poisoned WebContext store"); + let is_first_context = web_context.is_empty(); + let automation_enabled = std::env::var("TAURI_AUTOMATION").as_deref() == Ok("true"); + let web_context = match web_context.entry( + // force a unique WebContext when automation is false; + // the context must be stored on the HashMap because it must outlive the WebView on macOS + if automation_enabled { + webview_attributes.data_directory.clone() + } else { + // random unique key + Some(Uuid::new_v4().to_hyphenated().to_string().into()) + }, + ) { + Occupied(occupied) => occupied.into_mut(), + Vacant(vacant) => { + let mut web_context = WebContext::new(webview_attributes.data_directory); + web_context.set_allows_automation(if automation_enabled { + is_first_context + } else { + false + }); + vacant.insert(web_context) + } }; + if webview_attributes.clipboard { + webview_builder.webview.clipboard = true; + } + + #[cfg(any(debug_assertions, feature = "devtools"))] + { + webview_builder = webview_builder.with_dev_tool(true); + } + + let webview = webview_builder + .with_web_context(web_context) + .build() + .map_err(|e| Error::CreateWebview(Box::new(e)))?; + Ok(WindowWrapper { label, inner: WindowHandle::Webview(webview), @@ -2492,12 +2737,14 @@ fn create_webview( }) } -/// Create a wry rpc handler from a tauri rpc handler. -fn create_rpc_handler( - context: DispatcherContext, +/// Create a wry ipc handler from a tauri ipc handler. +fn create_ipc_handler( + context: Context, label: String, - handler: WebviewRpcHandler, -) -> Box Option + 'static> { + menu_ids: Arc>>, + js_event_listeners: Arc>>>, + handler: WebviewIpcHandler, +) -> Box { Box::new(move |window, request| { handler( DetachedWindow { @@ -2506,17 +2753,20 @@ fn create_rpc_handler( context: context.clone(), }, label: label.clone(), + menu_ids: menu_ids.clone(), + js_event_listeners: js_event_listeners.clone(), }, - RpcRequestWrapper(request).into(), + request, ); - None }) } /// Create a wry file drop handler from a tauri file drop handler. fn create_file_drop_handler( - context: DispatcherContext, + context: Context, label: String, + menu_ids: Arc>>, + js_event_listeners: Arc>>>, handler: FileDropHandler, ) -> Box bool + 'static> { Box::new(move |window, event| { @@ -2528,6 +2778,8 @@ fn create_file_drop_handler( context: context.clone(), }, label: label.clone(), + menu_ids: menu_ids.clone(), + js_event_listeners: js_event_listeners.clone(), }, ) }) diff --git a/core/tauri-runtime-wry/src/system_tray.rs b/core/tauri-runtime-wry/src/system_tray.rs index a7f8a6b16209..7ff96e557ef9 100644 --- a/core/tauri-runtime-wry/src/system_tray.rs +++ b/core/tauri-runtime-wry/src/system_tray.rs @@ -47,6 +47,12 @@ impl TrayHandle for SystemTrayHandle { .send_event(Message::Tray(TrayMessage::UpdateIcon(icon))) .map_err(|_| Error::FailedToSendMessage) } + fn set_menu(&self, menu: SystemTrayMenu) -> Result<()> { + self + .proxy + .send_event(Message::Tray(TrayMessage::UpdateMenu(menu))) + .map_err(|_| Error::FailedToSendMessage) + } fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> { self .proxy diff --git a/core/tauri-runtime/Cargo.toml b/core/tauri-runtime/Cargo.toml index b4e75534b543..77759a45f106 100644 --- a/core/tauri-runtime/Cargo.toml +++ b/core/tauri-runtime/Cargo.toml @@ -7,7 +7,8 @@ license = "Apache-2.0 OR MIT" homepage = "https://tauri.studio" repository = "https://github.com/tauri-apps/tauri" description = "Runtime for Tauri applications" -edition = "2018" +edition = "2021" +rust-version = "1.57" exclude = [ ".license_template", "CHANGELOG.md", "/target" ] readme = "README.md" @@ -32,10 +33,18 @@ http-range = "0.1.4" infer = "0.4" [target."cfg(windows)".dependencies] -winapi = "0.3" +webview2-com = "0.11.0" + +[target."cfg(windows)".dependencies.windows] +version = "0.30.0" +features = [ + "Win32_Foundation", +] [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] -gtk = { version = "0.14", features = [ "v3_20" ] } +gtk = { version = "0.15", features = [ "v3_20" ] } [features] +devtools = [ ] system-tray = [ ] +macos-private-api = [ ] diff --git a/core/tauri-runtime/src/http/mime_type.rs b/core/tauri-runtime/src/http/mime_type.rs index f818940f4bd8..d22a8d3fa6e7 100644 --- a/core/tauri-runtime/src/http/mime_type.rs +++ b/core/tauri-runtime/src/http/mime_type.rs @@ -22,7 +22,7 @@ pub enum MimeType { } impl std::fmt::Display for MimeType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mime = match self { MimeType::Css => "text/css", MimeType::Csv => "text/csv", diff --git a/core/tauri-runtime/src/http/response.rs b/core/tauri-runtime/src/http/response.rs index efe75736dfd3..7e25498347a6 100644 --- a/core/tauri-runtime/src/http/response.rs +++ b/core/tauri-runtime/src/http/response.rs @@ -7,7 +7,7 @@ use super::{ status::StatusCode, version::Version, }; -use std::{convert::TryFrom, fmt}; +use std::fmt; type Result = core::result::Result>; @@ -168,7 +168,8 @@ impl Builder { } /// Set the HTTP mimetype for this response. - pub fn mimetype(self, mimetype: &str) -> Builder { + #[must_use] + pub fn mimetype(self, mimetype: &str) -> Self { self.and_then(move |mut head| { head.mimetype = Some(mimetype.to_string()); Ok(head) @@ -176,7 +177,8 @@ impl Builder { } /// Set the HTTP status for this response. - pub fn status(self, status: T) -> Builder + #[must_use] + pub fn status(self, status: T) -> Self where StatusCode: TryFrom, >::Error: Into, @@ -193,7 +195,8 @@ impl Builder { /// will be returned from `Builder::build`. /// /// By default this is HTTP/1.1 - pub fn version(self, version: Version) -> Builder { + #[must_use] + pub fn version(self, version: Version) -> Self { self.and_then(move |mut head| { head.version = version; Ok(head) @@ -205,7 +208,8 @@ impl Builder { /// This function will append the provided key/value as a header to the /// internal `HeaderMap` being constructed. Essentially this is equivalent /// to calling `HeaderMap::append`. - pub fn header(self, key: K, value: V) -> Builder + #[must_use] + pub fn header(self, key: K, value: V) -> Self where HeaderName: TryFrom, >::Error: Into, diff --git a/core/tauri-runtime/src/lib.rs b/core/tauri-runtime/src/lib.rs index b7e4c59f253c..41338cc74149 100644 --- a/core/tauri-runtime/src/lib.rs +++ b/core/tauri-runtime/src/lib.rs @@ -11,7 +11,7 @@ use std::{fmt::Debug, path::PathBuf, sync::mpsc::Sender}; use uuid::Uuid; #[cfg(windows)] -use winapi::shared::windef::HWND; +use windows::Win32::Foundation::HWND; pub mod http; /// Create window and system tray menus. @@ -37,7 +37,7 @@ use crate::http::{ #[cfg(feature = "system-tray")] #[non_exhaustive] -#[derive(Debug)] +#[derive(Debug, Default)] pub struct SystemTray { pub icon: Option, pub menu: Option, @@ -45,18 +45,6 @@ pub struct SystemTray { pub icon_as_template: bool, } -#[cfg(feature = "system-tray")] -impl Default for SystemTray { - fn default() -> Self { - Self { - icon: None, - menu: None, - #[cfg(target_os = "macos")] - icon_as_template: false, - } - } -} - #[cfg(feature = "system-tray")] impl SystemTray { /// Creates a new system tray that only renders an icon. @@ -69,6 +57,7 @@ impl SystemTray { } /// Sets the tray icon. Must be a [`Icon::File`] on Linux and a [`Icon::Raw`] on Windows and macOS. + #[must_use] pub fn with_icon(mut self, icon: Icon) -> Self { self.icon.replace(icon); self @@ -76,12 +65,14 @@ impl SystemTray { /// Sets the tray icon as template. #[cfg(target_os = "macos")] + #[must_use] pub fn with_icon_as_template(mut self, is_template: bool) -> Self { self.icon_as_template = is_template; self } /// Sets the menu to show when the system tray is right clicked. + #[must_use] pub fn with_menu(mut self, menu: menu::SystemTrayMenu) -> Self { self.menu.replace(menu); self @@ -114,6 +105,9 @@ pub enum Error { /// Failed to send message to webview. #[error("failed to send message to the webview")] FailedToSendMessage, + /// Failed to receive message from webview. + #[error("failed to receive message from webview")] + FailedToReceiveMessage, /// Failed to serialize/deserialize. #[error("JSON error: {0}")] Json(#[from] serde_json::Error), @@ -267,6 +261,9 @@ pub trait RuntimeHandle: Debug + Send + Sized + Clone + 'static { pending: PendingWindow, ) -> crate::Result>; + /// Run a task on the main thread. + fn run_on_main_thread(&self, f: F) -> crate::Result<()>; + #[cfg(all(windows, feature = "system-tray"))] #[cfg_attr(doc_cfg, doc(cfg(all(windows, feature = "system-tray"))))] fn remove_system_tray(&self) -> crate::Result<()>; @@ -275,23 +272,9 @@ pub trait RuntimeHandle: Debug + Send + Sized + Clone + 'static { /// A global shortcut manager. pub trait GlobalShortcutManager: Debug { /// Whether the application has registered the given `accelerator`. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure. - /// - Panics when called on the main thread, usually on the `tauri::App#run`closure. - /// - /// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic. fn is_registered(&self, accelerator: &str) -> crate::Result; /// Register a global shortcut of `accelerator`. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure. - /// - Panics when called on the main thread, usually on the `tauri::App#run`closure. - /// - /// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic. fn register( &mut self, accelerator: &str, @@ -299,45 +282,17 @@ pub trait GlobalShortcutManager: Debug { ) -> crate::Result<()>; /// Unregister all accelerators registered by the manager instance. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure. - /// - Panics when called on the main thread, usually on the `tauri::App#run`closure. - /// - /// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic. fn unregister_all(&mut self) -> crate::Result<()>; /// Unregister the provided `accelerator`. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure. - /// - Panics when called on the main thread, usually on the `tauri::App#run`closure. - /// - /// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic. fn unregister(&mut self, accelerator: &str) -> crate::Result<()>; } /// Clipboard manager. pub trait ClipboardManager: Debug { /// Writes the text into the clipboard as plain text. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure. - /// - Panics when called on the main thread, usually on the `tauri::App#run`closure. - /// - /// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic. fn write_text>(&mut self, text: T) -> Result<()>; /// Read the content in the clipboard as plain text. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure. - /// - Panics when called on the main thread, usually on the `tauri::App#run`closure. - /// - /// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic. fn read_text(&self) -> Result>; } @@ -355,9 +310,14 @@ pub trait Runtime: Sized + 'static { #[cfg(feature = "system-tray")] type TrayHandler: menu::TrayHandle + Clone + Send; - /// Creates a new webview runtime. + /// Creates a new webview runtime. Must be used on the main thread. fn new() -> crate::Result; + /// Creates a new webview runtime on any thread. + #[cfg(any(windows, target_os = "linux"))] + #[cfg_attr(doc_cfg, doc(cfg(any(windows, target_os = "linux"))))] + fn new_any_thread() -> crate::Result; + /// Gets a runtime handle. fn handle(&self) -> Self::Handle; @@ -386,11 +346,10 @@ pub trait Runtime: Sized + 'static { fn set_activation_policy(&mut self, activation_policy: ActivationPolicy); /// Runs the one step of the webview runtime event loop and returns control flow to the caller. - #[cfg(any(target_os = "windows", target_os = "macos"))] fn run_iteration(&mut self, callback: F) -> RunIteration; /// Run the webview runtime. - fn run(self, callback: F); + fn run(self, callback: F); } /// Webview dispatcher. A thread-safe handle to the webview API. @@ -410,6 +369,9 @@ pub trait Dispatch: Debug + Clone + Send + Sized + 'static { /// Registers a window event handler. fn on_menu_event(&self, f: F) -> Uuid; + #[cfg(any(debug_assertions, feature = "devtools"))] + fn open_devtools(&self); + // GETTERS /// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa. diff --git a/core/tauri-runtime/src/menu.rs b/core/tauri-runtime/src/menu.rs index 2d6a2734818a..5e116f39d917 100644 --- a/core/tauri-runtime/src/menu.rs +++ b/core/tauri-runtime/src/menu.rs @@ -148,13 +148,14 @@ pub enum MenuUpdate { pub trait TrayHandle: fmt::Debug { fn set_icon(&self, icon: crate::Icon) -> crate::Result<()>; + fn set_menu(&self, menu: crate::menu::SystemTrayMenu) -> crate::Result<()>; fn update_item(&self, id: u16, update: MenuUpdate) -> crate::Result<()>; #[cfg(target_os = "macos")] fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()>; } /// A window menu. -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] #[non_exhaustive] pub struct Menu { pub items: Vec, @@ -179,31 +180,47 @@ impl Submenu { } } -impl Default for Menu { - fn default() -> Self { - Self { items: Vec::new() } - } -} - impl Menu { /// Creates a new window menu. pub fn new() -> Self { Default::default() } + /// Creates a new window menu with the given items. + /// + /// # Example + /// ``` + /// # use tauri_runtime::menu::{Menu, MenuItem, CustomMenuItem, Submenu}; + /// Menu::with_items([ + /// MenuItem::SelectAll.into(), + /// #[cfg(target_os = "macos")] + /// MenuItem::Redo.into(), + /// CustomMenuItem::new("toggle", "Toggle visibility").into(), + /// Submenu::new("View", Menu::new()).into(), + /// ]); + /// ``` + pub fn with_items>(items: I) -> Self { + Self { + items: items.into_iter().collect(), + } + } + /// Adds the custom menu item to the menu. + #[must_use] pub fn add_item(mut self, item: CustomMenuItem) -> Self { self.items.push(MenuEntry::CustomItem(item)); self } /// Adds a native item to the menu. + #[must_use] pub fn add_native_item(mut self, item: MenuItem) -> Self { self.items.push(MenuEntry::NativeItem(item)); self } /// Adds an entry with submenu. + #[must_use] pub fn add_submenu(mut self, submenu: Submenu) -> Self { self.items.push(MenuEntry::Submenu(submenu)); self @@ -241,6 +258,7 @@ impl CustomMenuItem { } /// Assign a keyboard shortcut to the menu action. + #[must_use] pub fn accelerator>(mut self, accelerator: T) -> Self { self.keyboard_accelerator.replace(accelerator.into()); self @@ -248,6 +266,7 @@ impl CustomMenuItem { #[cfg(target_os = "macos")] #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))] + #[must_use] /// A native image do render on the menu item. pub fn native_image(mut self, image: NativeImage) -> Self { self.native_image.replace(image); @@ -255,12 +274,14 @@ impl CustomMenuItem { } /// Mark the item as disabled. + #[must_use] pub fn disabled(mut self) -> Self { self.enabled = false; self } /// Mark the item as selected. + #[must_use] pub fn selected(mut self) -> Self { self.selected = true; self @@ -274,18 +295,12 @@ impl CustomMenuItem { } /// A system tray menu. -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] #[non_exhaustive] pub struct SystemTrayMenu { pub items: Vec, } -impl Default for SystemTrayMenu { - fn default() -> Self { - Self { items: Vec::new() } - } -} - #[derive(Debug, Clone)] #[non_exhaustive] pub struct SystemTraySubmenu { @@ -312,18 +327,21 @@ impl SystemTrayMenu { } /// Adds the custom menu item to the system tray menu. + #[must_use] pub fn add_item(mut self, item: CustomMenuItem) -> Self { self.items.push(SystemTrayMenuEntry::CustomItem(item)); self } /// Adds a native item to the system tray menu. + #[must_use] pub fn add_native_item(mut self, item: SystemTrayMenuItem) -> Self { self.items.push(SystemTrayMenuEntry::NativeItem(item)); self } /// Adds an entry with submenu. + #[must_use] pub fn add_submenu(mut self, submenu: SystemTraySubmenu) -> Self { self.items.push(SystemTrayMenuEntry::Submenu(submenu)); self @@ -360,6 +378,24 @@ pub enum MenuEntry { Submenu(Submenu), } +impl From for MenuEntry { + fn from(item: CustomMenuItem) -> Self { + Self::CustomItem(item) + } +} + +impl From for MenuEntry { + fn from(item: MenuItem) -> Self { + Self::NativeItem(item) + } +} + +impl From for MenuEntry { + fn from(submenu: Submenu) -> Self { + Self::Submenu(submenu) + } +} + /// A menu item, bound to a pre-defined action or `Custom` emit an event. Note that status bar only /// supports `Custom` menu item variants. And on the menu bar, some platforms might not support some /// of the variants. Unsupported variant will be no-op on such platform. diff --git a/core/tauri-runtime/src/webview.rs b/core/tauri-runtime/src/webview.rs index d1b181282b7c..efe70d1833f2 100644 --- a/core/tauri-runtime/src/webview.rs +++ b/core/tauri-runtime/src/webview.rs @@ -4,36 +4,23 @@ //! Items specific to the [`Runtime`](crate::Runtime)'s webview. -use crate::{window::DetachedWindow, Icon}; +use crate::{menu::Menu, window::DetachedWindow, Icon}; -use crate::menu::Menu; - -use serde::Deserialize; -use serde_json::Value as JsonValue; use tauri_utils::config::{WindowConfig, WindowUrl}; #[cfg(windows)] -use winapi::shared::windef::HWND; +use windows::Win32::Foundation::HWND; use std::{fmt, path::PathBuf}; /// The attributes used to create an webview. +#[derive(Debug)] pub struct WebviewAttributes { pub url: WindowUrl, pub initialization_scripts: Vec, pub data_directory: Option, pub file_drop_handler_enabled: bool, -} - -impl fmt::Debug for WebviewAttributes { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("WebviewAttributes") - .field("url", &self.url) - .field("initialization_scripts", &self.initialization_scripts) - .field("data_directory", &self.data_directory) - .field("file_drop_handler_enabled", &self.file_drop_handler_enabled) - .finish() - } + pub clipboard: bool, } impl WebviewAttributes { @@ -44,26 +31,40 @@ impl WebviewAttributes { initialization_scripts: Vec::new(), data_directory: None, file_drop_handler_enabled: true, + clipboard: false, } } /// Sets the init script. + #[must_use] pub fn initialization_script(mut self, script: &str) -> Self { self.initialization_scripts.push(script.to_string()); self } /// Data directory for the webview. + #[must_use] pub fn data_directory(mut self, data_directory: PathBuf) -> Self { self.data_directory.replace(data_directory); self } /// Disables the file drop handler. This is required to use drag and drop APIs on the front end on Windows. + #[must_use] pub fn disable_file_drop_handler(mut self) -> Self { self.file_drop_handler_enabled = false; self } + + /// Enables clipboard access for the page rendered on **Linux** and **Windows**. + /// + /// **macOS** doesn't provide such method and is always enabled by default, + /// but you still need to add menu item accelerators to use shortcuts. + #[must_use] + pub fn enable_clipboard_access(mut self) -> Self { + self.clipboard = true; + self + } } /// Do **NOT** implement this trait except for use in a custom [`Runtime`](crate::Runtime). @@ -83,55 +84,76 @@ pub trait WindowBuilder: WindowBuilderBase { fn with_config(config: WindowConfig) -> Self; /// Sets the menu for the window. + #[must_use] fn menu(self, menu: Menu) -> Self; /// Show window in the center of the screen. + #[must_use] fn center(self) -> Self; /// The initial position of the window's. + #[must_use] fn position(self, x: f64, y: f64) -> Self; /// Window size. + #[must_use] fn inner_size(self, min_width: f64, min_height: f64) -> Self; /// Window min inner size. + #[must_use] fn min_inner_size(self, min_width: f64, min_height: f64) -> Self; /// Window max inner size. + #[must_use] fn max_inner_size(self, max_width: f64, max_height: f64) -> Self; /// Whether the window is resizable or not. + #[must_use] fn resizable(self, resizable: bool) -> Self; /// The title of the window in the title bar. + #[must_use] fn title>(self, title: S) -> Self; /// Whether to start the window in fullscreen or not. + #[must_use] fn fullscreen(self, fullscreen: bool) -> Self; /// Whether the window will be initially hidden or focused. + #[must_use] fn focus(self) -> Self; /// Whether the window should be maximized upon creation. + #[must_use] fn maximized(self, maximized: bool) -> Self; /// Whether the window should be immediately visible upon creation. + #[must_use] fn visible(self, visible: bool) -> Self; /// Whether the the window should be transparent. If this is true, writing colors /// with alpha values different than `1.0` will produce a transparent window. + #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] + #[cfg_attr( + doc_cfg, + doc(cfg(any(not(target_os = "macos"), feature = "macos-private-api"))) + )] + #[must_use] fn transparent(self, transparent: bool) -> Self; /// Whether the window should have borders and bars. + #[must_use] fn decorations(self, decorations: bool) -> Self; /// Whether the window should always be on top of other windows. + #[must_use] fn always_on_top(self, always_on_top: bool) -> Self; /// Sets the window icon. fn icon(self, icon: Icon) -> crate::Result; /// Sets whether or not the window icon should be added to the taskbar. + #[must_use] fn skip_taskbar(self, skip: bool) -> Self; /// Sets a parent to the window to be created. @@ -140,6 +162,7 @@ pub trait WindowBuilder: WindowBuilderBase { /// /// For more information, see #[cfg(windows)] + #[must_use] fn parent_window(self, parent: HWND) -> Self; /// Set an owner to the window to be created. @@ -151,22 +174,14 @@ pub trait WindowBuilder: WindowBuilderBase { /// /// For more information, see #[cfg(windows)] + #[must_use] fn owner_window(self, owner: HWND) -> Self; /// Whether the icon was set or not. fn has_icon(&self) -> bool; - /// Whether the menu was set or not. - fn has_menu(&self) -> bool; -} - -/// Rpc request. -#[derive(Debug)] -pub struct RpcRequest { - /// RPC command. - pub command: String, - /// Params. - pub params: Option, + /// Gets the window menu. + fn get_menu(&self) -> Option<&Menu>; } /// The file drop event payload. @@ -181,21 +196,9 @@ pub enum FileDropEvent { Cancelled, } -/// Rpc handler. -pub type WebviewRpcHandler = Box, RpcRequest) + Send>; +/// IPC handler. +pub type WebviewIpcHandler = Box, String) + Send>; /// File drop handler callback /// Return `true` in the callback to block the OS' default behavior of handling a file drop. pub type FileDropHandler = Box) -> bool + Send>; - -#[derive(Debug, Deserialize)] -pub struct InvokePayload { - #[serde(rename = "__tauriModule")] - pub tauri_module: Option, - pub callback: String, - pub error: String, - #[serde(rename = "__invokeKey")] - pub key: u32, - #[serde(flatten)] - pub inner: JsonValue, -} diff --git a/core/tauri-runtime/src/window.rs b/core/tauri-runtime/src/window.rs index e77ed6de577d..77a2a4d9dec1 100644 --- a/core/tauri-runtime/src/window.rs +++ b/core/tauri-runtime/src/window.rs @@ -6,15 +6,17 @@ use crate::{ http::{Request as HttpRequest, Response as HttpResponse}, - webview::{FileDropHandler, WebviewAttributes, WebviewRpcHandler}, + menu::{Menu, MenuEntry, MenuHash, MenuId}, + webview::{FileDropHandler, WebviewAttributes, WebviewIpcHandler}, Dispatch, Runtime, WindowBuilder, }; use serde::Serialize; use tauri_utils::config::WindowConfig; use std::{ - collections::HashMap, + collections::{HashMap, HashSet}, hash::{Hash, Hasher}, + sync::{mpsc::Sender, Arc, Mutex}, }; type UriSchemeProtocol = @@ -32,7 +34,12 @@ pub enum WindowEvent { /// The position of the window has changed. Contains the window's new position. Moved(dpi::PhysicalPosition), /// The window has been requested to close. - CloseRequested, + CloseRequested { + /// The window label. + label: String, + /// A signal sender. If a `true` value is emitted, the window won't be closed. + signal_tx: Sender, + }, /// The window has been destroyed. Destroyed, /// The window gained or lost focus. @@ -61,6 +68,18 @@ pub struct MenuEvent { pub menu_item_id: u16, } +fn get_menu_ids(map: &mut HashMap, menu: &Menu) { + for item in &menu.items { + match item { + MenuEntry::CustomItem(c) => { + map.insert(c.id, c.id_str.clone()); + } + MenuEntry::Submenu(s) => get_menu_ids(map, &s.inner), + _ => {} + } + } +} + /// A webview window that has yet to be built. pub struct PendingWindow { /// The label that the window will be named. @@ -74,14 +93,33 @@ pub struct PendingWindow { pub uri_scheme_protocols: HashMap>, - /// How to handle RPC calls on the webview window. - pub rpc_handler: Option>, + /// How to handle IPC calls on the webview window. + pub ipc_handler: Option>, /// How to handle a file dropping onto the webview window. pub file_drop_handler: Option>, /// The resolved URL to load on the webview. pub url: String, + + /// Maps runtime id to a string menu id. + pub menu_ids: Arc>>, + + /// A HashMap mapping JS event names with associated listener ids. + pub js_event_listeners: Arc>>>, +} + +pub fn is_label_valid(label: &str) -> bool { + label + .chars() + .all(|c| char::is_alphanumeric(c) || c == '-' || c == '/' || c == ':' || c == '_') +} + +pub fn assert_label_is_valid(label: &str) { + assert!( + is_label_valid(label), + "Window label must include only alphanumeric characters, `-`, `/`, `:` and `_`." + ); } impl PendingWindow { @@ -91,14 +129,22 @@ impl PendingWindow { webview_attributes: WebviewAttributes, label: impl Into, ) -> Self { + let mut menu_ids = HashMap::new(); + if let Some(menu) = window_builder.get_menu() { + get_menu_ids(&mut menu_ids, menu); + } + let label = label.into(); + assert_label_is_valid(&label); Self { window_builder, webview_attributes, uri_scheme_protocols: Default::default(), - label: label.into(), - rpc_handler: None, + label, + ipc_handler: None, file_drop_handler: None, url: "tauri://localhost".to_string(), + menu_ids: Arc::new(Mutex::new(menu_ids)), + js_event_listeners: Default::default(), } } @@ -108,17 +154,35 @@ impl PendingWindow { webview_attributes: WebviewAttributes, label: impl Into, ) -> Self { + let window_builder = <::WindowBuilder>::with_config(window_config); + let mut menu_ids = HashMap::new(); + if let Some(menu) = window_builder.get_menu() { + get_menu_ids(&mut menu_ids, menu); + } + let label = label.into(); + assert_label_is_valid(&label); Self { - window_builder: <::WindowBuilder>::with_config(window_config), + window_builder, webview_attributes, uri_scheme_protocols: Default::default(), - label: label.into(), - rpc_handler: None, + label, + ipc_handler: None, file_drop_handler: None, url: "tauri://localhost".to_string(), + menu_ids: Arc::new(Mutex::new(menu_ids)), + js_event_listeners: Default::default(), } } + #[must_use] + pub fn set_menu(mut self, menu: Menu) -> Self { + let mut menu_ids = HashMap::new(); + get_menu_ids(&mut menu_ids, &menu); + *self.menu_ids.lock().unwrap() = menu_ids; + self.window_builder = self.window_builder.menu(menu); + self + } + pub fn register_uri_scheme_protocol< N: Into, H: Fn(&HttpRequest) -> Result> + Send + Sync + 'static, @@ -134,6 +198,15 @@ impl PendingWindow { } } +/// Key for a JS event listener. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct JsEventListenerKey { + /// The associated window label. + pub window_label: Option, + /// The event name. + pub event: String, +} + /// A webview window that is not yet managed by Tauri. #[derive(Debug)] pub struct DetachedWindow { @@ -142,6 +215,12 @@ pub struct DetachedWindow { /// The [`Dispatch`](crate::Dispatch) associated with the window. pub dispatcher: R::Dispatcher, + + /// Maps runtime id to a string menu id. + pub menu_ids: Arc>>, + + /// A HashMap mapping JS event names with associated listener ids. + pub js_event_listeners: Arc>>>, } impl Clone for DetachedWindow { @@ -149,6 +228,8 @@ impl Clone for DetachedWindow { Self { label: self.label.clone(), dispatcher: self.dispatcher.clone(), + menu_ids: self.menu_ids.clone(), + js_event_listeners: self.js_event_listeners.clone(), } } } diff --git a/core/tauri-utils/Cargo.toml b/core/tauri-utils/Cargo.toml index 0b52661d2eda..6bc445e6bb71 100644 --- a/core/tauri-utils/Cargo.toml +++ b/core/tauri-utils/Cargo.toml @@ -6,21 +6,42 @@ license = "Apache-2.0 OR MIT" homepage = "https://tauri.studio" repository = "https://github.com/tauri-apps/tauri" description = "Utilities for Tauri" -edition = "2018" +edition = "2021" +rust-version = "1.57" exclude = [ ".license_template", "CHANGELOG.md", "/target" ] readme = "README.md" [dependencies] serde = { version = "1.0", features = [ "derive" ] } serde_json = "1.0" -thiserror = "1.0.26" +thiserror = "1.0.30" phf = { version = "0.10", features = [ "macros" ] } -zstd = "0.9" +zstd = { version = "0.10", optional = true } url = { version = "2.2", features = [ "serde" ] } kuchiki = "0.8" html5ever = "0.25" proc-macro2 = { version = "1.0", optional = true } quote = { version = "1.0", optional = true } +schemars = { version = "0.8", features = ["url"], optional = true } +serde_with = "1.12" +aes-gcm = { version = "0.9", optional = true } +ring = { version = "0.16", optional = true, features = ["std"] } +once_cell = { version = "1.9", optional = true } +serialize-to-javascript = "=0.1.1" +ctor = "0.1" +json5 = { version = "0.4", optional = true } +json-patch = "0.2" +glob = { version = "0.3.0", optional = true } +walkdir = { version = "2", optional = true } + +[target."cfg(target_os = \"linux\")".dependencies] +heck = "0.4" [features] build = [ "proc-macro2", "quote" ] +compression = [ "zstd" ] +schema = ["schemars"] +isolation = [ "aes-gcm", "ring", "once_cell" ] +process-relaunch-dangerous-allow-symlink-macos = [] +config-json5 = [ "json5" ] +resources = [ "glob", "walkdir" ] diff --git a/core/tauri-utils/src/assets.rs b/core/tauri-utils/src/assets.rs index 6b784c890482..cd43489544d7 100644 --- a/core/tauri-utils/src/assets.rs +++ b/core/tauri-utils/src/assets.rs @@ -74,33 +74,106 @@ impl> From

for AssetKey { } } +/// A Content-Security-Policy hash value for a specific directive. +/// For more information see [the MDN page](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#directives). +#[non_exhaustive] +#[derive(Debug, Clone, Copy)] +pub enum CspHash<'a> { + /// The `script-src` directive. + Script(&'a str), + + /// The `style-src` directive. + Style(&'a str), +} + +impl CspHash<'_> { + /// The Content-Security-Policy directive this hash applies to. + pub fn directive(&self) -> &'static str { + match self { + Self::Script(_) => "script-src", + Self::Style(_) => "style-src", + } + } + + /// The value of the Content-Security-Policy hash. + pub fn hash(&self) -> &str { + match self { + Self::Script(hash) => hash, + Self::Style(hash) => hash, + } + } +} + /// Represents a container of file assets that are retrievable during runtime. pub trait Assets: Send + Sync + 'static { /// Get the content of the passed [`AssetKey`]. fn get(&self, key: &AssetKey) -> Option>; + + /// Gets the hashes for the CSP tag of the HTML on the given path. + fn csp_hashes(&self, html_path: &AssetKey) -> Box> + '_>; } /// [`Assets`] implementation that only contains compile-time compressed and embedded assets. #[derive(Debug)] -pub struct EmbeddedAssets(phf::Map<&'static str, &'static [u8]>); +pub struct EmbeddedAssets { + assets: phf::Map<&'static str, &'static [u8]>, + // Hashes that must be injected to the CSP of every HTML file. + global_hashes: &'static [CspHash<'static>], + // Hashes that are associated to the CSP of the HTML file identified by the map key (the HTML asset key). + html_hashes: phf::Map<&'static str, &'static [CspHash<'static>]>, +} impl EmbeddedAssets { - /// Wrap a [zstd] compressed [`phf::Map`]. - /// - /// [zstd]: https://facebook.github.io/zstd/ - pub const fn from_zstd(map: phf::Map<&'static str, &'static [u8]>) -> Self { - Self(map) + /// Creates a new instance from the given asset map and script hash list. + pub const fn new( + map: phf::Map<&'static str, &'static [u8]>, + global_hashes: &'static [CspHash<'static>], + html_hashes: phf::Map<&'static str, &'static [CspHash<'static>]>, + ) -> Self { + Self { + assets: map, + global_hashes, + html_hashes, + } } } impl Assets for EmbeddedAssets { + #[cfg(feature = "compression")] fn get(&self, key: &AssetKey) -> Option> { self - .0 + .assets .get(key.as_ref()) .copied() .map(zstd::decode_all) .and_then(Result::ok) .map(Cow::Owned) } + + #[cfg(not(feature = "compression"))] + fn get(&self, key: &AssetKey) -> Option> { + self + .assets + .get(key.as_ref()) + .copied() + .map(|a| Cow::Owned(a.to_vec())) + } + + fn csp_hashes(&self, html_path: &AssetKey) -> Box> + '_> { + Box::new( + self + .global_hashes + .iter() + .chain( + self + .html_hashes + .get(html_path.as_ref()) + .copied() + .into_iter() + .flatten() + .into_iter(), + ) + .copied(), + ) + } } diff --git a/core/tauri-utils/src/config.rs b/core/tauri-utils/src/config.rs index 8a5069993485..e9fec549d8e9 100644 --- a/core/tauri-utils/src/config.rs +++ b/core/tauri-utils/src/config.rs @@ -10,14 +10,28 @@ //! This is a core functionality that is not considered part of the stable API. //! If you use it, note that it may include breaking changes in the future. -use std::{collections::HashMap, path::PathBuf}; - -use serde::Deserialize; +#[cfg(target_os = "linux")] +use heck::ToKebabCase; +#[cfg(feature = "schema")] +use schemars::JsonSchema; +use serde::{ + de::{Deserializer, Error as DeError, Visitor}, + Deserialize, Serialize, +}; use serde_json::Value as JsonValue; +use serde_with::skip_serializing_none; use url::Url; -/// The window webview URL options. -#[derive(PartialEq, Debug, Clone, Deserialize)] +use std::{collections::HashMap, fmt, fs::read_to_string, path::PathBuf}; + +/// Items to help with parsing content into a [`Config`]. +pub mod parse; + +pub use self::parse::parse; + +/// An URL to open on a Tauri webview window. +#[derive(PartialEq, Debug, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] #[serde(untagged)] #[non_exhaustive] pub enum WindowUrl { @@ -27,197 +41,242 @@ pub enum WindowUrl { App(PathBuf), } +impl fmt::Display for WindowUrl { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::External(url) => write!(f, "{}", url), + Self::App(path) => write!(f, "{}", path.display()), + } + } +} + impl Default for WindowUrl { fn default() -> Self { Self::App("index.html".into()) } } -/// The window configuration object. -#[derive(PartialEq, Deserialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] -pub struct WindowConfig { - #[serde(default = "default_window_label")] - /// The window identifier. - pub label: String, - /// The window webview URL. - #[serde(default)] - pub url: WindowUrl, - /// Whether the file drop is enabled or not on the webview. By default it is enabled. - /// - /// Disabling it is required to use drag and drop on the frontend on Windows. - #[serde(default = "default_file_drop_enabled")] - pub file_drop_enabled: bool, - /// Center the window. - #[serde(default)] - pub center: bool, - /// The horizontal position of the window's top left corner - pub x: Option, - /// The vertical position of the window's top left corner - pub y: Option, - /// The window width. - #[serde(default = "default_width")] - pub width: f64, - /// The window height. - #[serde(default = "default_height")] - pub height: f64, - /// The min window width. - pub min_width: Option, - /// The min window height. - pub min_height: Option, - /// The max window width. - pub max_width: Option, - /// The max window height. - pub max_height: Option, - /// Whether the window is resizable or not. - #[serde(default = "default_resizable")] - pub resizable: bool, - /// The window title. - #[serde(default = "default_title")] - pub title: String, - /// Whether the window starts as fullscreen or not. - #[serde(default)] - pub fullscreen: bool, - /// Whether the window will be initially hidden or focused. - #[serde(default)] - pub focus: bool, - /// Whether the window is transparent or not. - #[serde(default)] - pub transparent: bool, - /// Whether the window is maximized or not. - #[serde(default)] - pub maximized: bool, - /// Whether the window is visible or not. - #[serde(default = "default_visible")] - pub visible: bool, - /// Whether the window should have borders and bars. - #[serde(default = "default_decorations")] - pub decorations: bool, - /// Whether the window should always be on top of other windows. - #[serde(default)] - pub always_on_top: bool, - /// Whether or not the window icon should be added to the taskbar. - #[serde(default)] - pub skip_taskbar: bool, -} - -fn default_window_label() -> String { - "main".to_string() -} - -fn default_width() -> f64 { - 800f64 -} - -fn default_height() -> f64 { - 600f64 +/// Targets to bundle. +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(untagged)] +pub enum BundleTarget { + /// A list of bundle targets. + All(Vec), + /// A single bundle target. + One(String), } -fn default_resizable() -> bool { - true +impl BundleTarget { + /// Gets the bundle targets as a [`Vec`]. + #[allow(dead_code)] + pub fn to_vec(&self) -> Vec { + match self { + Self::All(list) => list.clone(), + Self::One(i) => vec![i.clone()], + } + } } -fn default_visible() -> bool { - true +/// Configuration for Debian (.deb) bundles. +#[skip_serializing_none] +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct DebConfig { + /// The list of deb dependencies your application relies on. + pub depends: Option>, + /// Enable the boostrapper script. + #[serde(default)] + pub use_bootstrapper: bool, + /// The files to include on the package. + #[serde(default)] + pub files: HashMap, } -fn default_decorations() -> bool { - true +/// Configuration for the macOS bundles. +#[skip_serializing_none] +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct MacConfig { + /// A list of strings indicating any macOS X frameworks that need to be bundled with the application. + /// + /// If a name is used, ".framework" must be omitted and it will look for standard install locations. You may also use a path to a specific framework. + pub frameworks: Option>, + /// A version string indicating the minimum macOS X version that the bundled application supports. + pub minimum_system_version: Option, + /// Allows your application to communicate with the outside world. + /// It should be a lowercase, without port and protocol domain name. + pub exception_domain: Option, + /// The path to the license file to add to the DMG bundle. + pub license: Option, + /// Enable the boostrapper script. + #[serde(default)] + pub use_bootstrapper: bool, + /// Identity to use for code signing. + pub signing_identity: Option, + /// Provider short name for notarization. + pub provider_short_name: Option, + /// Path to the entitlements file. + pub entitlements: Option, } -fn default_title() -> String { - "Tauri App".to_string() +/// Configuration for a target language for the WiX build. +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct WixLanguageConfig { + /// The path to a locale (`.wxl`) file. See . + pub locale_path: Option, } -fn default_file_drop_enabled() -> bool { - true +/// The languages to build using WiX. +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(untagged)] +pub enum WixLanguage { + /// A single language to build, without configuration. + One(String), + /// A list of languages to build, without configuration. + List(Vec), + /// A map of languages and its configuration. + Localized(HashMap), } -impl Default for WindowConfig { +impl Default for WixLanguage { fn default() -> Self { - Self { - label: default_window_label(), - url: WindowUrl::default(), - file_drop_enabled: default_file_drop_enabled(), - center: false, - x: None, - y: None, - width: default_width(), - height: default_height(), - min_width: None, - min_height: None, - max_width: None, - max_height: None, - resizable: default_resizable(), - title: default_title(), - fullscreen: false, - focus: false, - transparent: false, - maximized: false, - visible: default_visible(), - decorations: default_decorations(), - always_on_top: false, - skip_taskbar: false, - } + Self::One("en-US".into()) } } -/// The Updater configuration object. -#[derive(PartialEq, Deserialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] -pub struct UpdaterConfig { - /// Whether the updater is active or not. +/// Configuration for the MSI bundle using WiX. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct WixConfig { + /// The installer languages to build. See . #[serde(default)] - pub active: bool, - /// Display built-in dialog or use event system if disabled. - #[serde(default = "default_updater_dialog")] - pub dialog: bool, - /// The updater endpoints. + pub language: WixLanguage, + /// A custom .wxs template to use. + pub template: Option, + /// A list of paths to .wxs files with WiX fragments to use. #[serde(default)] - pub endpoints: Option>, - /// Optional pubkey. + pub fragment_paths: Vec, + /// The ComponentGroup element ids you want to reference from the fragments. #[serde(default)] - pub pubkey: Option, -} - -fn default_updater_dialog() -> bool { - true -} + pub component_group_refs: Vec, + /// The Component element ids you want to reference from the fragments. + #[serde(default)] + pub component_refs: Vec, + /// The FeatureGroup element ids you want to reference from the fragments. + #[serde(default)] + pub feature_group_refs: Vec, + /// The Feature element ids you want to reference from the fragments. + #[serde(default)] + pub feature_refs: Vec, + /// The Merge element ids you want to reference from the fragments. + #[serde(default)] + pub merge_refs: Vec, + /// Disables the Webview2 runtime installation after app install. + #[serde(default)] + pub skip_webview_install: bool, + /// The path to the license file to render on the installer. + /// + /// Must be an RTF file, so if a different extension is provided, we convert it to the RTF format. + pub license: Option, + /// Create an elevated update task within Windows Task Scheduler. + #[serde(default)] + pub enable_elevated_update_task: bool, + /// Path to a bitmap file to use as the installation user interface banner. + /// This bitmap will appear at the top of all but the first page of the installer. + /// + /// The required dimensions are 493px × 58px. + pub banner_path: Option, + /// Path to a bitmap file to use on the installation user interface dialogs. + /// It is used on the welcome and completion dialogs. -impl Default for UpdaterConfig { - fn default() -> Self { - Self { - active: false, - dialog: true, - endpoints: None, - pubkey: None, - } - } + /// The required dimensions are 493px × 312px. + pub dialog_image_path: Option, } -/// Security configuration. -#[derive(PartialEq, Deserialize, Debug, Clone, Default)] -#[serde(rename_all = "camelCase")] -pub struct SecurityConfig { - /// Content security policy to inject to HTML files with `tauri://` and other user-defined custom protocols. - pub csp: Option, +/// Windows bundler configuration. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct WindowsConfig { + /// Specifies the file digest algorithm to use for creating file signatures. + /// Required for code signing. SHA-256 is recommended. + pub digest_algorithm: Option, + /// Specifies the SHA1 hash of the signing certificate. + pub certificate_thumbprint: Option, + /// Server to use during timestamping. + pub timestamp_url: Option, + /// Path to the webview fixed runtime to use. + /// + /// The fixed version can be downloaded [on the official website](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section). + /// The `.cab` file must be extracted to a folder and this folder path must be defined on this field. + pub webview_fixed_runtime_path: Option, + /// Configuration for the MSI generated with WiX. + pub wix: Option, } -/// Configuration for application system tray icon. -#[derive(PartialEq, Deserialize, Debug, Clone, Default)] -#[serde(rename_all = "camelCase")] -pub struct SystemTrayConfig { - /// Path to the icon to use on the system tray. - /// Automatically set to be an `.png` on macOS and Linux, and `.ico` on Windows. - pub icon_path: PathBuf, - /// A Boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS. +/// Configuration for tauri-bundler. +#[skip_serializing_none] +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct BundleConfig { + /// Whether we should build your app with tauri-bundler or plain `cargo build` #[serde(default)] - pub icon_as_template: bool, + pub active: bool, + /// The bundle targets, currently supports ["deb", "app", "msi", "appimage", "dmg"] or "all" + pub targets: Option, + /// The app's identifier + pub identifier: String, + /// The app's icons + #[serde(default)] + pub icon: Vec, + /// App resources to bundle. + /// Each resource is a path to a file or directory. + /// Glob patterns are supported. + pub resources: Option>, + /// A copyright string associated with your application. + pub copyright: Option, + /// The application kind. + pub category: Option, + /// A short description of your application. + pub short_description: Option, + /// A longer, multi-line description of the application. + pub long_description: Option, + /// Configuration for the Debian bundle. + #[serde(default)] + pub deb: DebConfig, + /// Configuration for the macOS bundles. + #[serde(rename = "macOS", default)] + pub macos: MacConfig, + /// A list of—either absolute or relative—paths to binaries to embed with your application. + /// + /// Note that Tauri will look for system-specific binaries following the pattern "binary-name{-target-triple}{.system-extension}". + /// + /// E.g. for the external binary "my-binary", Tauri looks for: + /// + /// - "my-binary-x86_64-pc-windows-msvc.exe" for Windows + /// - "my-binary-x86_64-apple-darwin" for macOS + /// - "my-binary-x86_64-unknown-linux-gnu" for Linux + /// + /// so don't forget to provide binaries for all targeted platforms. + pub external_bin: Option>, + /// Configuration for the Windows bundle. + #[serde(default)] + pub windows: WindowsConfig, } -/// A CLI argument definition -#[derive(PartialEq, Deserialize, Debug, Default, Clone)] -#[serde(rename_all = "camelCase")] +/// A CLI argument definition. +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct CliArg { /// The short version of the argument, without the preceding -. /// @@ -238,28 +297,40 @@ pub struct CliArg { /// - Using an equals and no space such as -o=value or --option=value /// - Use a short and no space such as -ovalue pub takes_value: Option, - /// Specifies that the argument may appear more than once. + /// Specifies that the argument may have an unknown number of multiple values. Without any other settings, this argument may appear only once. + /// + /// For example, --opt val1 val2 is allowed, but --opt val1 val2 --opt val3 is not. /// - /// - For flags, this results in the number of occurrences of the flag being recorded. - /// For example -ddd or -d -d -d would count as three occurrences. - /// - For options there is a distinct difference in multiple occurrences vs multiple values. - /// For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences. + /// NOTE: Setting this requires `takes_value` to be set to true. pub multiple: Option, + /// Specifies that the argument may appear more than once. + /// For flags, this results in the number of occurrences of the flag being recorded. For example -ddd or -d -d -d would count as three occurrences. + /// For options or arguments that take a value, this does not affect how many values they can accept. (i.e. only one at a time is allowed) /// + /// For example, --opt val1 --opt val2 is allowed, but --opt val1 val2 is not. pub multiple_occurrences: Option, + /// Specifies how many values are required to satisfy this argument. For example, if you had a + /// `-f ` argument where you wanted exactly 3 'files' you would set + /// `number_of_values = 3`, and this argument wouldn't be satisfied unless the user provided + /// 3 and only 3 values. + /// + /// **NOTE:** Does *not* require `multiple_occurrences = true` to be set. Setting + /// `multiple_occurrences = true` would allow `-f -f ` where + /// as *not* setting it would only allow one occurrence of this argument. /// - pub number_of_values: Option, + /// **NOTE:** implicitly sets `takes_value = true` and `multiple_values = true`. + pub number_of_values: Option, /// Specifies a list of possible values for this argument. /// At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message. pub possible_values: Option>, /// Specifies the minimum number of values for this argument. /// For example, if you had a -f argument where you wanted at least 2 'files', /// you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values. - pub min_values: Option, + pub min_values: Option, /// Specifies the maximum number of values are for this argument. /// For example, if you had a -f argument where you wanted up to 3 'files', /// you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values. - pub max_values: Option, + pub max_values: Option, /// Sets whether or not the argument is required by default. /// /// - Required by default means it is required, when no other conflicting rules have been evaluated @@ -299,12 +370,14 @@ pub struct CliArg { /// The index refers to position according to other positional argument. /// It does not define position in the argument list as a whole. When utilized with multiple=true, /// only the last positional argument may be defined as multiple (i.e. the one with the highest index). - pub index: Option, + pub index: Option, } -/// The CLI command definition. -#[derive(PartialEq, Deserialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] +/// describes a CLI configuration +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct CliConfig { /// Command description which will be shown on the help information. pub description: Option, @@ -335,151 +408,1420 @@ impl CliConfig { self.subcommands.as_ref() } - /// Command description which will be shown on the help information. - pub fn description(&self) -> Option<&String> { - self.description.as_ref() + /// Command description which will be shown on the help information. + pub fn description(&self) -> Option<&String> { + self.description.as_ref() + } + + /// Command long description which will be shown on the help information. + pub fn long_description(&self) -> Option<&String> { + self.description.as_ref() + } + + /// Adds additional help information to be displayed in addition to auto-generated help. + /// This information is displayed before the auto-generated help information. + /// This is often used for header information. + pub fn before_help(&self) -> Option<&String> { + self.before_help.as_ref() + } + + /// Adds additional help information to be displayed in addition to auto-generated help. + /// This information is displayed after the auto-generated help information. + /// This is often used to describe how to use the arguments, or caveats to be noted. + pub fn after_help(&self) -> Option<&String> { + self.after_help.as_ref() + } +} + +/// The window configuration object. +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct WindowConfig { + /// The window identifier. It must be alphanumeric. + #[serde(default = "default_window_label")] + pub label: String, + /// The window webview URL. + #[serde(default)] + pub url: WindowUrl, + /// Whether the file drop is enabled or not on the webview. By default it is enabled. + /// + /// Disabling it is required to use drag and drop on the frontend on Windows. + #[serde(default = "default_file_drop_enabled")] + pub file_drop_enabled: bool, + /// Whether or not the window starts centered or not. + #[serde(default)] + pub center: bool, + /// The horizontal position of the window's top left corner + pub x: Option, + /// The vertical position of the window's top left corner + pub y: Option, + /// The window width. + #[serde(default = "default_width")] + pub width: f64, + /// The window height. + #[serde(default = "default_height")] + pub height: f64, + /// The min window width. + pub min_width: Option, + /// The min window height. + pub min_height: Option, + /// The max window width. + pub max_width: Option, + /// The max window height. + pub max_height: Option, + /// Whether the window is resizable or not. + #[serde(default = "default_resizable")] + pub resizable: bool, + /// The window title. + #[serde(default = "default_title")] + pub title: String, + /// Whether the window starts as fullscreen or not. + #[serde(default)] + pub fullscreen: bool, + /// Whether the window will be initially hidden or focused. + #[serde(default = "default_focus")] + pub focus: bool, + /// Whether the window is transparent or not. + /// + /// Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri.conf.json > tauri > macosPrivateApi`. + /// WARNING: Using private APIs on `macOS` prevents your application from being accepted for the `App Store`. + #[serde(default)] + pub transparent: bool, + /// Whether the window is maximized or not. + #[serde(default)] + pub maximized: bool, + /// Whether the window is visible or not. + #[serde(default = "default_visible")] + pub visible: bool, + /// Whether the window should have borders and bars. + #[serde(default = "default_decorations")] + pub decorations: bool, + /// Whether the window should always be on top of other windows. + #[serde(default)] + pub always_on_top: bool, + /// Whether or not the window icon should be added to the taskbar. + #[serde(default)] + pub skip_taskbar: bool, +} + +impl Default for WindowConfig { + fn default() -> Self { + Self { + label: default_window_label(), + url: WindowUrl::default(), + file_drop_enabled: default_file_drop_enabled(), + center: false, + x: None, + y: None, + width: default_width(), + height: default_height(), + min_width: None, + min_height: None, + max_width: None, + max_height: None, + resizable: default_resizable(), + title: default_title(), + fullscreen: false, + focus: false, + transparent: false, + maximized: false, + visible: default_visible(), + decorations: default_decorations(), + always_on_top: false, + skip_taskbar: false, + } + } +} + +fn default_window_label() -> String { + "main".to_string() +} + +fn default_width() -> f64 { + 800f64 +} + +fn default_height() -> f64 { + 600f64 +} + +fn default_resizable() -> bool { + true +} + +fn default_title() -> String { + "Tauri App".to_string() +} + +fn default_focus() -> bool { + true +} + +fn default_visible() -> bool { + true +} + +fn default_decorations() -> bool { + true +} + +fn default_file_drop_enabled() -> bool { + true +} + +/// Security configuration. +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct SecurityConfig { + /// The Content Security Policy that will be injected on all HTML files on the built application. + /// If [`dev_csp`](SecurityConfig.dev_csp) is not specified, this value is also injected on dev. + /// + /// This is a really important part of the configuration since it helps you ensure your WebView is secured. + /// See . + pub csp: Option, + /// The Content Security Policy that will be injected on all HTML files on development. + /// + /// This is a really important part of the configuration since it helps you ensure your WebView is secured. + /// See . + pub dev_csp: Option, + /// Freeze the `Object.prototype` when using the custom protocol. + #[serde(default = "default_freeze_prototype")] + pub freeze_prototype: bool, +} + +impl Default for SecurityConfig { + fn default() -> Self { + Self { + csp: None, + dev_csp: None, + freeze_prototype: default_freeze_prototype(), + } + } +} + +fn default_freeze_prototype() -> bool { + true +} + +/// Defines an allowlist type. +pub trait Allowlist { + /// Returns all features associated with the allowlist struct. + fn all_features() -> Vec<&'static str>; + /// Returns the tauri features enabled on this allowlist. + fn to_features(&self) -> Vec<&'static str>; +} + +macro_rules! check_feature { + ($self:ident, $features:ident, $flag:ident, $feature_name: expr) => { + if $self.$flag { + $features.push($feature_name) + } + }; +} + +/// Filesystem scope definition. +/// It is a list of glob patterns that restrict the API access from the webview. +/// +/// Each pattern can start with a variable that resolves to a system base directory. +/// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, +/// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, +/// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$CWD`. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +pub struct FsAllowlistScope(pub Vec); + +/// Allowlist for the file system APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct FsAllowlistConfig { + /// The access scope for the filesystem APIs. + #[serde(default)] + pub scope: FsAllowlistScope, + /// Use this flag to enable all file system API features. + #[serde(default)] + pub all: bool, + /// Read file from local filesystem. + #[serde(default)] + pub read_file: bool, + /// Write file to local filesystem. + #[serde(default)] + pub write_file: bool, + /// Read directory from local filesystem. + #[serde(default)] + pub read_dir: bool, + /// Copy file from local filesystem. + #[serde(default)] + pub copy_file: bool, + /// Create directory from local filesystem. + #[serde(default)] + pub create_dir: bool, + /// Remove directory from local filesystem. + #[serde(default)] + pub remove_dir: bool, + /// Remove file from local filesystem. + #[serde(default)] + pub remove_file: bool, + /// Rename file from local filesystem. + #[serde(default)] + pub rename_file: bool, +} + +impl Allowlist for FsAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { + scope: Default::default(), + all: false, + read_file: true, + write_file: true, + read_dir: true, + copy_file: true, + create_dir: true, + remove_dir: true, + remove_file: true, + rename_file: true, + }; + let mut features = allowlist.to_features(); + features.push("fs-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["fs-all"] + } else { + let mut features = Vec::new(); + check_feature!(self, features, read_file, "fs-read-file"); + check_feature!(self, features, write_file, "fs-write-file"); + check_feature!(self, features, read_dir, "fs-read-dir"); + check_feature!(self, features, copy_file, "fs-copy-file"); + check_feature!(self, features, create_dir, "fs-create-dir"); + check_feature!(self, features, remove_dir, "fs-remove-dir"); + check_feature!(self, features, remove_file, "fs-remove-file"); + check_feature!(self, features, rename_file, "fs-rename-file"); + features + } + } +} + +/// Allowlist for the window APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct WindowAllowlistConfig { + /// Use this flag to enable all window API features. + #[serde(default)] + pub all: bool, + /// Allows dynamic window creation. + #[serde(default)] + pub create: bool, + /// Allows centering the window. + #[serde(default)] + pub center: bool, + /// Allows requesting user attention on the window. + #[serde(default)] + pub request_user_attention: bool, + /// Allows setting the resizable flag of the window. + #[serde(default)] + pub set_resizable: bool, + /// Allows changing the window title. + #[serde(default)] + pub set_title: bool, + /// Allows maximizing the window. + #[serde(default)] + pub maximize: bool, + /// Allows unmaximizing the window. + #[serde(default)] + pub unmaximize: bool, + /// Allows minimizing the window. + #[serde(default)] + pub minimize: bool, + /// Allows unminimizing the window. + #[serde(default)] + pub unminimize: bool, + /// Allows showing the window. + #[serde(default)] + pub show: bool, + /// Allows hiding the window. + #[serde(default)] + pub hide: bool, + /// Allows closing the window. + #[serde(default)] + pub close: bool, + /// Allows setting the decorations flag of the window. + #[serde(default)] + pub set_decorations: bool, + /// Allows setting the always_on_top flag of the window. + #[serde(default)] + pub set_always_on_top: bool, + /// Allows setting the window size. + #[serde(default)] + pub set_size: bool, + /// Allows setting the window minimum size. + #[serde(default)] + pub set_min_size: bool, + /// Allows setting the window maximum size. + #[serde(default)] + pub set_max_size: bool, + /// Allows changing the position of the window. + #[serde(default)] + pub set_position: bool, + /// Allows setting the fullscreen flag of the window. + #[serde(default)] + pub set_fullscreen: bool, + /// Allows focusing the window. + #[serde(default)] + pub set_focus: bool, + /// Allows changing the window icon. + #[serde(default)] + pub set_icon: bool, + /// Allows setting the skip_taskbar flag of the window. + #[serde(default)] + pub set_skip_taskbar: bool, + /// Allows start dragging on the window. + #[serde(default)] + pub start_dragging: bool, + /// Allows opening the system dialog to print the window content. + #[serde(default)] + pub print: bool, +} + +impl Allowlist for WindowAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { + all: false, + create: true, + center: true, + request_user_attention: true, + set_resizable: true, + set_title: true, + maximize: true, + unmaximize: true, + minimize: true, + unminimize: true, + show: true, + hide: true, + close: true, + set_decorations: true, + set_always_on_top: true, + set_size: true, + set_min_size: true, + set_max_size: true, + set_position: true, + set_fullscreen: true, + set_focus: true, + set_icon: true, + set_skip_taskbar: true, + start_dragging: true, + print: true, + }; + let mut features = allowlist.to_features(); + features.push("window-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["window-all"] + } else { + let mut features = Vec::new(); + check_feature!(self, features, create, "window-create"); + check_feature!(self, features, center, "window-center"); + check_feature!( + self, + features, + request_user_attention, + "window-request-user-attention" + ); + check_feature!(self, features, set_resizable, "window-set-resizable"); + check_feature!(self, features, set_title, "window-set-title"); + check_feature!(self, features, maximize, "window-maximize"); + check_feature!(self, features, unmaximize, "window-unmaximize"); + check_feature!(self, features, minimize, "window-minimize"); + check_feature!(self, features, unminimize, "window-unminimize"); + check_feature!(self, features, show, "window-show"); + check_feature!(self, features, hide, "window-hide"); + check_feature!(self, features, close, "window-close"); + check_feature!(self, features, set_decorations, "window-set-decorations"); + check_feature!( + self, + features, + set_always_on_top, + "window-set-always-on-top" + ); + check_feature!(self, features, set_size, "window-set-size"); + check_feature!(self, features, set_min_size, "window-set-min-size"); + check_feature!(self, features, set_max_size, "window-set-max-size"); + check_feature!(self, features, set_position, "window-set-position"); + check_feature!(self, features, set_fullscreen, "window-set-fullscreen"); + check_feature!(self, features, set_focus, "window-set-focus"); + check_feature!(self, features, set_icon, "window-set-icon"); + check_feature!(self, features, set_skip_taskbar, "window-set-skip-taskbar"); + check_feature!(self, features, start_dragging, "window-start-dragging"); + check_feature!(self, features, print, "window-print"); + features + } + } +} + +/// A command allowed to be executed by the webview API. +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +pub struct ShellAllowedCommand { + /// The name for this allowed shell command configuration. + /// + /// This name will be used inside of the webview API to call this command along with + /// any specified arguments. + pub name: String, + + /// The command name. + /// It can start with a variable that resolves to a system base directory. + /// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, + /// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, + /// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$CWD`. + #[serde(rename = "cmd")] + pub command: PathBuf, + + /// The allowed arguments for the command execution. + #[serde(default)] + pub args: ShellAllowedArgs, + + /// If this command is a sidecar command. + #[serde(default)] + pub sidecar: bool, +} + +/// A set of command arguments allowed to be executed by the webview API. +/// +/// A value of `true` will allow any arguments to be passed to the command. `false` will disable all +/// arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to +/// be passed to the attached command configuration. +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(untagged, deny_unknown_fields)] +#[non_exhaustive] +pub enum ShellAllowedArgs { + /// Use a simple boolean to allow all or disable all arguments to this command configuration. + Flag(bool), + + /// A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration. + List(Vec), +} + +impl Default for ShellAllowedArgs { + fn default() -> Self { + Self::Flag(false) + } +} + +/// A command argument allowed to be executed by the webview API. +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(untagged, deny_unknown_fields)] +#[non_exhaustive] +pub enum ShellAllowedArg { + /// A non-configurable argument that is passed to the command in the order it was specified. + Fixed(String), + + /// A variable that is set while calling the command from the webview API. + /// + Var { + /// [regex] validator to require passed values to conform to an expected input. + /// + /// This will require the argument value passed to this variable to match the `validator` regex + /// before it will be executed. + /// + /// [regex]: https://docs.rs/regex/latest/regex/#syntax + #[serde(default)] + validator: String, + }, +} + +/// Shell scope definition. +/// It is a list of command names and associated CLI arguments that restrict the API access from the webview. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +pub struct ShellAllowlistScope(pub Vec); + +/// Defines the `shell > open` api scope. +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(untagged, deny_unknown_fields)] +#[non_exhaustive] +pub enum ShellAllowlistOpen { + /// If the shell open API should be enabled. + /// + /// If enabled, the default validation regex (`^https?://`) is used. + Flag(bool), + + /// Enable the shell open API, with a custom regex that the opened path must match against. + /// + /// If using a custom regex to support a non-http(s) schema, care should be used to prevent values + /// that allow flag-like strings to pass validation. e.g. `--enable-debugging`, `-i`, `/R`. + Validate(String), +} + +impl Default for ShellAllowlistOpen { + fn default() -> Self { + Self::Flag(false) + } +} + +/// Allowlist for the shell APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct ShellAllowlistConfig { + /// Access scope for the binary execution APIs. + /// Sidecars are automatically enabled. + #[serde(default)] + pub scope: ShellAllowlistScope, + /// Use this flag to enable all shell API features. + #[serde(default)] + pub all: bool, + /// Enable binary execution. + #[serde(default)] + pub execute: bool, + /// Enable sidecar execution, allowing the JavaScript layer to spawn a sidecar command, + /// an executable that is shipped with the application. + /// For more information see . + #[serde(default)] + pub sidecar: bool, + /// Open URL with the user's default application. + #[serde(default)] + pub open: ShellAllowlistOpen, +} + +impl Allowlist for ShellAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { + scope: Default::default(), + all: false, + execute: true, + sidecar: true, + open: ShellAllowlistOpen::Flag(true), + }; + let mut features = allowlist.to_features(); + features.push("shell-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["shell-all"] + } else { + let mut features = Vec::new(); + check_feature!(self, features, execute, "shell-execute"); + check_feature!(self, features, sidecar, "shell-sidecar"); + + if !matches!(self.open, ShellAllowlistOpen::Flag(false)) { + features.push("shell-open") + } + + features + } + } +} + +/// Allowlist for the dialog APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct DialogAllowlistConfig { + /// Use this flag to enable all dialog API features. + #[serde(default)] + pub all: bool, + /// Allows the API to open a dialog window to pick files. + #[serde(default)] + pub open: bool, + /// Allows the API to open a dialog window to pick where to save files. + #[serde(default)] + pub save: bool, + /// Allows the API to show a message dialog window. + #[serde(default)] + pub message: bool, + /// Allows the API to show a dialog window with Yes/No buttons. + #[serde(default)] + pub ask: bool, + /// Allows the API to show a dialog window with Ok/Cancel buttons. + #[serde(default)] + pub confirm: bool, +} + +impl Allowlist for DialogAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { + all: false, + open: true, + save: true, + message: true, + ask: true, + confirm: true, + }; + let mut features = allowlist.to_features(); + features.push("dialog-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["dialog-all"] + } else { + let mut features = Vec::new(); + check_feature!(self, features, open, "dialog-open"); + check_feature!(self, features, save, "dialog-save"); + check_feature!(self, features, message, "dialog-message"); + check_feature!(self, features, ask, "dialog-ask"); + check_feature!(self, features, confirm, "dialog-confirm"); + features + } + } +} + +/// HTTP API scope definition. +/// It is a list of URLs that can be accessed by the webview when using the HTTP APIs. +/// The URL path is matched against the request URL using a glob pattern. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +pub struct HttpAllowlistScope(pub Vec); + +/// Allowlist for the HTTP APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct HttpAllowlistConfig { + /// The access scope for the HTTP APIs. + #[serde(default)] + pub scope: HttpAllowlistScope, + /// Use this flag to enable all HTTP API features. + #[serde(default)] + pub all: bool, + /// Allows making HTTP requests. + #[serde(default)] + pub request: bool, +} + +impl Allowlist for HttpAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { + scope: Default::default(), + all: false, + request: true, + }; + let mut features = allowlist.to_features(); + features.push("http-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["http-all"] + } else { + let mut features = Vec::new(); + check_feature!(self, features, request, "http-request"); + features + } + } +} + +/// Allowlist for the notification APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct NotificationAllowlistConfig { + /// Use this flag to enable all notification API features. + #[serde(default)] + pub all: bool, +} + +impl Allowlist for NotificationAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { all: false }; + let mut features = allowlist.to_features(); + features.push("notification-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["notification-all"] + } else { + vec![] + } + } +} + +/// Allowlist for the global shortcut APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct GlobalShortcutAllowlistConfig { + /// Use this flag to enable all global shortcut API features. + #[serde(default)] + pub all: bool, +} + +impl Allowlist for GlobalShortcutAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { all: false }; + let mut features = allowlist.to_features(); + features.push("global-shortcut-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["global-shortcut-all"] + } else { + vec![] + } + } +} + +/// Allowlist for the OS APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct OsAllowlistConfig { + /// Use this flag to enable all OS API features. + #[serde(default)] + pub all: bool, +} + +impl Allowlist for OsAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { all: false }; + let mut features = allowlist.to_features(); + features.push("os-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["os-all"] + } else { + vec![] + } + } +} + +/// Allowlist for the path APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct PathAllowlistConfig { + /// Use this flag to enable all path API features. + #[serde(default)] + pub all: bool, +} + +impl Allowlist for PathAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { all: false }; + let mut features = allowlist.to_features(); + features.push("path-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["path-all"] + } else { + vec![] + } + } +} + +/// Allowlist for the custom protocols. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct ProtocolAllowlistConfig { + /// The access scope for the asset protocol. + #[serde(default)] + pub asset_scope: FsAllowlistScope, + /// Use this flag to enable all custom protocols. + #[serde(default)] + pub all: bool, + /// Enables the asset protocol. + #[serde(default)] + pub asset: bool, +} + +impl Allowlist for ProtocolAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { + asset_scope: Default::default(), + all: false, + asset: true, + }; + let mut features = allowlist.to_features(); + features.push("protocol-all"); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["protocol-all"] + } else { + let mut features = Vec::new(); + check_feature!(self, features, asset, "protocol-asset"); + features + } + } +} + +/// Allowlist for the process APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct ProcessAllowlistConfig { + /// Use this flag to enable all process APIs. + #[serde(default)] + pub all: bool, + /// Enables the relaunch API. + #[serde(default)] + pub relaunch: bool, + /// Dangerous option that allows macOS to relaunch even if the binary contains a symlink. + /// + /// This is due to macOS having less symlink protection. Highly recommended to not set this flag + /// unless you have a very specific reason too, and understand the implications of it. + #[serde(default)] + pub relaunch_dangerous_allow_symlink_macos: bool, + /// Enables the exit API. + #[serde(default)] + pub exit: bool, +} + +impl Allowlist for ProcessAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { + all: false, + relaunch: true, + relaunch_dangerous_allow_symlink_macos: false, + exit: true, + }; + let mut features = allowlist.to_features(); + features.push("process-all"); + features } - /// Command long description which will be shown on the help information. - pub fn long_description(&self) -> Option<&String> { - self.description.as_ref() + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["process-all"] + } else { + let mut features = Vec::new(); + check_feature!(self, features, relaunch, "process-relaunch"); + check_feature!( + self, + features, + relaunch_dangerous_allow_symlink_macos, + "process-relaunch-dangerous-allow-symlink-macos" + ); + check_feature!(self, features, exit, "process-exit"); + features + } } +} - /// Adds additional help information to be displayed in addition to auto-generated help. - /// This information is displayed before the auto-generated help information. - /// This is often used for header information. - pub fn before_help(&self) -> Option<&String> { - self.before_help.as_ref() +/// Allowlist for the clipboard APIs. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct ClipboardAllowlistConfig { + /// Use this flag to enable all clipboard APIs. + #[serde(default)] + pub all: bool, + /// Enables the clipboard's `writeText` API. + #[serde(default)] + pub write_text: bool, + /// Enables the clipboard's `readText` API. + #[serde(default)] + pub read_text: bool, +} + +impl Allowlist for ClipboardAllowlistConfig { + fn all_features() -> Vec<&'static str> { + let allowlist = Self { + all: false, + write_text: true, + read_text: true, + }; + let mut features = allowlist.to_features(); + features.push("clipboard-all"); + features } - /// Adds additional help information to be displayed in addition to auto-generated help. - /// This information is displayed after the auto-generated help information. - /// This is often used to describe how to use the arguments, or caveats to be noted. - pub fn after_help(&self) -> Option<&String> { - self.after_help.as_ref() + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["clipboard-all"] + } else { + let mut features = Vec::new(); + check_feature!(self, features, write_text, "clipboard-write-text"); + check_feature!(self, features, read_text, "clipboard-read-text"); + features + } } } -/// The bundler configuration object. -#[derive(PartialEq, Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -pub struct BundleConfig { - /// The bundle identifier. - pub identifier: String, - /// The bundle icons. +/// Allowlist configuration. +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct AllowlistConfig { + /// Use this flag to enable all API features. #[serde(default)] - pub icon: Vec, + pub all: bool, + /// File system API allowlist. + #[serde(default)] + pub fs: FsAllowlistConfig, + /// Window API allowlist. + #[serde(default)] + pub window: WindowAllowlistConfig, + /// Shell API allowlist. + #[serde(default)] + pub shell: ShellAllowlistConfig, + /// Dialog API allowlist. + #[serde(default)] + pub dialog: DialogAllowlistConfig, + /// HTTP API allowlist. + #[serde(default)] + pub http: HttpAllowlistConfig, + /// Notification API allowlist. + #[serde(default)] + pub notification: NotificationAllowlistConfig, + /// Global shortcut API allowlist. + #[serde(default)] + pub global_shortcut: GlobalShortcutAllowlistConfig, + /// OS allowlist. + #[serde(default)] + pub os: OsAllowlistConfig, + /// Path API allowlist. + #[serde(default)] + pub path: PathAllowlistConfig, + /// Custom protocol allowlist. + #[serde(default)] + pub protocol: ProtocolAllowlistConfig, + /// Process API allowlist. + #[serde(default)] + pub process: ProcessAllowlistConfig, + /// Clipboard APIs allowlist. + #[serde(default)] + pub clipboard: ClipboardAllowlistConfig, } -impl Default for BundleConfig { - fn default() -> Self { - Self { - identifier: String::from(""), - icon: Vec::default(), +impl Allowlist for AllowlistConfig { + fn all_features() -> Vec<&'static str> { + let mut features = vec!["api-all"]; + features.extend(FsAllowlistConfig::all_features()); + features.extend(WindowAllowlistConfig::all_features()); + features.extend(ShellAllowlistConfig::all_features()); + features.extend(DialogAllowlistConfig::all_features()); + features.extend(HttpAllowlistConfig::all_features()); + features.extend(NotificationAllowlistConfig::all_features()); + features.extend(GlobalShortcutAllowlistConfig::all_features()); + features.extend(OsAllowlistConfig::all_features()); + features.extend(PathAllowlistConfig::all_features()); + features.extend(ProtocolAllowlistConfig::all_features()); + features.extend(ProcessAllowlistConfig::all_features()); + features.extend(ClipboardAllowlistConfig::all_features()); + features + } + + fn to_features(&self) -> Vec<&'static str> { + if self.all { + vec!["api-all"] + } else { + let mut features = Vec::new(); + features.extend(self.fs.to_features()); + features.extend(self.window.to_features()); + features.extend(self.shell.to_features()); + features.extend(self.dialog.to_features()); + features.extend(self.http.to_features()); + features.extend(self.notification.to_features()); + features.extend(self.global_shortcut.to_features()); + features.extend(self.os.to_features()); + features.extend(self.path.to_features()); + features.extend(self.protocol.to_features()); + features.extend(self.process.to_features()); + features.extend(self.clipboard.to_features()); + features } } } -fn default_window_config() -> Vec { - vec![Default::default()] +/// The application pattern. +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[serde(rename_all = "lowercase", tag = "use", content = "options")] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +pub enum PatternKind { + /// Brownfield pattern. + Brownfield, + /// Isolation pattern. Recommended for security purposes. + #[cfg(feature = "isolation")] + Isolation { + /// The dir containing the index.html file that contains the secure isolation application. + dir: PathBuf, + }, +} + +impl Default for PatternKind { + fn default() -> Self { + Self::Brownfield + } } /// The Tauri configuration object. -#[derive(PartialEq, Deserialize, Debug)] -#[serde(rename_all = "camelCase")] +#[skip_serializing_none] +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct TauriConfig { - /// The window configuration. - #[serde(default = "default_window_config")] + /// The pattern to use. + #[serde(default)] + pub pattern: PatternKind, + /// The windows configuration. + #[serde(default)] pub windows: Vec, /// The CLI configuration. - #[serde(default)] pub cli: Option, /// The bundler configuration. #[serde(default)] pub bundle: BundleConfig, - /// The updater configuration. + /// The allowlist configuration. #[serde(default)] - pub updater: UpdaterConfig, - /// The security configuration. + pub allowlist: AllowlistConfig, + /// Security configuration. #[serde(default)] pub security: SecurityConfig, - /// System tray configuration. + /// The updater configuration. #[serde(default)] + pub updater: UpdaterConfig, + /// Configuration for app system tray. pub system_tray: Option, + /// MacOS private API configuration. Enables the transparent background API and sets the `fullScreenEnabled` preference to `true`. + #[serde(rename = "macOSPrivateApi", default)] + pub macos_private_api: bool, +} + +impl TauriConfig { + /// Returns all Cargo features. + #[allow(dead_code)] + pub fn all_features() -> Vec<&'static str> { + let mut features = AllowlistConfig::all_features(); + features.extend(vec![ + "cli", + "updater", + "system-tray", + "macos-private-api", + "isolation", + ]); + features + } + + /// Returns the enabled Cargo features. + #[allow(dead_code)] + pub fn features(&self) -> Vec<&str> { + let mut features = self.allowlist.to_features(); + if self.cli.is_some() { + features.push("cli"); + } + if self.updater.active { + features.push("updater"); + } + if self.system_tray.is_some() { + features.push("system-tray"); + } + if self.macos_private_api { + features.push("macos-private-api"); + } + #[cfg(feature = "isolation")] + if let PatternKind::Isolation { .. } = self.pattern { + features.push("isolation"); + } + features.sort_unstable(); + features + } +} + +/// A URL to an updater server. +/// +/// The URL must use the `https` scheme on production. +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +pub struct UpdaterEndpoint(pub Url); + +impl std::fmt::Display for UpdaterEndpoint { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl<'de> Deserialize<'de> for UpdaterEndpoint { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let url = Url::deserialize(deserializer)?; + #[cfg(all(not(debug_assertions), not(feature = "schema")))] + { + if url.scheme() != "https" { + return Err(serde::de::Error::custom( + "The configured updater endpoint must use the `https` protocol.", + )); + } + } + Ok(Self(url)) + } +} + +/// The Updater configuration object. +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct UpdaterConfig { + /// Whether the updater is active or not. + #[serde(default)] + pub active: bool, + /// Display built-in dialog or use event system if disabled. + #[serde(default = "default_dialog")] + pub dialog: bool, + /// The updater endpoints. TLS is enforced on production. + pub endpoints: Option>, + /// Signature public key. + #[serde(default)] // use default just so the schema doesn't flag it as required + pub pubkey: String, +} + +impl<'de> Deserialize<'de> for UpdaterConfig { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct InnerUpdaterConfig { + #[serde(default)] + active: bool, + #[serde(default = "default_dialog")] + dialog: bool, + endpoints: Option>, + pubkey: Option, + } + + let config = InnerUpdaterConfig::deserialize(deserializer)?; + + if config.active && config.pubkey.is_none() { + return Err(DeError::custom( + "The updater `pubkey` configuration is required.", + )); + } + + Ok(UpdaterConfig { + active: config.active, + dialog: config.dialog, + endpoints: config.endpoints, + pubkey: config.pubkey.unwrap_or_default(), + }) + } } -impl Default for TauriConfig { +impl Default for UpdaterConfig { fn default() -> Self { Self { - windows: default_window_config(), - cli: None, - bundle: BundleConfig::default(), - updater: UpdaterConfig::default(), - security: SecurityConfig::default(), - system_tray: None, + active: false, + dialog: default_dialog(), + endpoints: None, + pubkey: "".into(), } } } +/// Configuration for application system tray icon. +#[skip_serializing_none] +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct SystemTrayConfig { + /// Path to the icon to use on the system tray. + /// + /// It is forced to be a `.png` file on Linux and macOS, and a `.ico` file on Windows. + pub icon_path: PathBuf, + /// A Boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS. + #[serde(default)] + pub icon_as_template: bool, +} + +// We enable the unnecessary_wraps because we need +// to use an Option for dialog otherwise the CLI schema will mark +// the dialog as a required field which is not as we default it to true. +fn default_dialog() -> bool { + true +} + /// The `dev_path` and `dist_dir` options. -#[derive(PartialEq, Debug, Clone, Deserialize)] -#[serde(untagged)] +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(untagged, deny_unknown_fields)] #[non_exhaustive] pub enum AppUrl { - /// A url or file path. + /// The app's external URL, or the path to the directory containing the app assets. Url(WindowUrl), - /// An array of files. + /// An array of files to embed on the app. Files(Vec), } +impl std::fmt::Display for AppUrl { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Url(url) => write!(f, "{}", url), + Self::Files(files) => write!(f, "{}", serde_json::to_string(files).unwrap()), + } + } +} + /// The Build configuration object. -#[derive(PartialEq, Deserialize, Debug)] -#[serde(rename_all = "camelCase")] +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct BuildConfig { - /// Directory path or URL to use on development. Default to `http://localhost:8080`. + /// The binary used to build and run the application. + pub runner: Option, + /// The path or URL to use on development. #[serde(default = "default_dev_path")] pub dev_path: AppUrl, - /// Distribution directory to use in release build. Default to `../dist`. - #[serde(default = "default_dist_path")] + /// The path to the app's dist dir. This path must contain your index.html file. + #[serde(default = "default_dist_dir")] pub dist_dir: AppUrl, + /// A shell command to run before `tauri dev` kicks in. + /// + /// The TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation. + pub before_dev_command: Option, + /// A shell command to run before `tauri build` kicks in. + /// + /// The TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation. + pub before_build_command: Option, + /// Features passed to `cargo` commands. + pub features: Option>, /// Whether we should inject the Tauri API on `window.__TAURI__` or not. #[serde(default)] pub with_global_tauri: bool, } +impl Default for BuildConfig { + fn default() -> Self { + Self { + runner: None, + dev_path: default_dev_path(), + dist_dir: default_dist_dir(), + before_dev_command: None, + before_build_command: None, + features: None, + with_global_tauri: false, + } + } +} + fn default_dev_path() -> AppUrl { AppUrl::Url(WindowUrl::External( Url::parse("http://localhost:8080").unwrap(), )) } -fn default_dist_path() -> AppUrl { +fn default_dist_dir() -> AppUrl { AppUrl::Url(WindowUrl::App("../dist".into())) } -impl Default for BuildConfig { - fn default() -> Self { - Self { - dev_path: default_dev_path(), - dist_dir: default_dist_path(), - with_global_tauri: false, +#[derive(Debug, PartialEq)] +struct PackageVersion(String); + +impl<'d> serde::Deserialize<'d> for PackageVersion { + fn deserialize>(deserializer: D) -> Result { + struct PackageVersionVisitor; + + impl<'d> Visitor<'d> for PackageVersionVisitor { + type Value = PackageVersion; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + formatter, + "a semver string or a path to a package.json file" + ) + } + + fn visit_str(self, value: &str) -> Result { + let path = PathBuf::from(value); + if path.exists() { + let json_str = read_to_string(&path) + .map_err(|e| DeError::custom(format!("failed to read version JSON file: {}", e)))?; + let package_json: serde_json::Value = serde_json::from_str(&json_str) + .map_err(|e| DeError::custom(format!("failed to read version JSON file: {}", e)))?; + if let Some(obj) = package_json.as_object() { + let version = obj + .get("version") + .ok_or_else(|| DeError::custom("JSON must contain a `version` field"))? + .as_str() + .ok_or_else(|| DeError::custom("`version` must be a string"))?; + Ok(PackageVersion(version.into())) + } else { + Err(DeError::custom("value is not a path to a JSON object")) + } + } else { + Ok(PackageVersion(value.into())) + } + } } + + deserializer.deserialize_string(PackageVersionVisitor {}) } } /// The package configuration. -#[derive(Debug, Default, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct PackageConfig { /// App name. pub product_name: Option, - /// App version. + /// App version. It is a semver version number or a path to a `package.json` file contaning the `version` field. + #[serde(deserialize_with = "version_deserializer", default)] pub version: Option, } +fn version_deserializer<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + Option::::deserialize(deserializer).map(|v| v.map(|v| v.0)) +} + +impl PackageConfig { + /// The binary name. + #[allow(dead_code)] + pub fn binary_name(&self) -> Option { + #[cfg(target_os = "linux")] + { + self.product_name.as_ref().map(|n| n.to_kebab_case()) + } + #[cfg(not(target_os = "linux"))] + { + self.product_name.clone() + } + } +} + /// The config type mapped to `tauri.conf.json`. -#[derive(Debug, Default, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] +#[skip_serializing_none] +#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct Config { /// Package settings. #[serde(default)] @@ -488,7 +1830,7 @@ pub struct Config { #[serde(default)] pub tauri: TauriConfig, /// The build configuration. - #[serde(default)] + #[serde(default = "default_build")] pub build: BuildConfig, /// The plugins config. #[serde(default)] @@ -496,9 +1838,22 @@ pub struct Config { } /// The plugin configs holds a HashMap mapping a plugin name to its configuration object. -#[derive(Debug, Clone, Default, PartialEq, Deserialize)] +#[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] pub struct PluginConfig(pub HashMap); +fn default_build() -> BuildConfig { + BuildConfig { + runner: None, + dev_path: default_dev_path(), + dist_dir: default_dist_dir(), + before_dev_command: None, + before_build_command: None, + features: None, + with_global_tauri: false, + } +} + /// Implement `ToTokens` for all config structs, allowing a literal `Config` to be built. /// /// This allows for a build script to output the values in a `Config` to a `TokenStream`, which can @@ -513,6 +1868,8 @@ mod build { use super::*; + use serde_json::Value as JsonValue; + /// Create a `String` constructor `TokenStream`. /// /// e.g. `"Hello World" -> String::from("Hello World"). @@ -555,12 +1912,17 @@ mod build { /// Create a `PathBuf` constructor `TokenStream`. /// /// e.g. `"Hello World" -> String::from("Hello World"). - /// This takes a `&String` to reduce casting all the `&String` -> `&str` manually. fn path_buf_lit(s: impl AsRef) -> TokenStream { let s = s.as_ref().to_string_lossy().into_owned(); quote! { ::std::path::PathBuf::from(#s) } } + /// Creates a `Url` constructor `TokenStream`. + fn url_lit(url: &Url) -> TokenStream { + let url = url.as_str(); + quote! { #url.parse().unwrap() } + } + /// Create a map constructor, mapping keys and values with other `TokenStream`s. /// /// This function is pretty generic because the types of keys AND values get transformed. @@ -666,8 +2028,8 @@ mod build { quote! { #prefix::App(#path) } } Self::External(url) => { - let url = url.as_str(); - quote! { #prefix::External(#url.parse().unwrap()) } + let url = url_lit(url); + quote! { #prefix::External(#url) } } }) } @@ -824,12 +2186,70 @@ mod build { } } + impl ToTokens for PatternKind { + fn to_tokens(&self, tokens: &mut TokenStream) { + let prefix = quote! { ::tauri::utils::config::PatternKind }; + + tokens.append_all(match self { + Self::Brownfield => quote! { #prefix::Brownfield }, + #[cfg(feature = "isolation")] + Self::Isolation { dir } => { + let dir = path_buf_lit(dir); + quote! { #prefix::Isolation { dir: #dir } } + } + }) + } + } + + impl ToTokens for WindowsConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let webview_fixed_runtime_path = opt_lit( + self + .webview_fixed_runtime_path + .as_ref() + .map(path_buf_lit) + .as_ref(), + ); + tokens.append_all(quote! { ::tauri::utils::config::WindowsConfig { + webview_fixed_runtime_path: #webview_fixed_runtime_path, + ..Default::default() + }}) + } + } + impl ToTokens for BundleConfig { fn to_tokens(&self, tokens: &mut TokenStream) { let identifier = str_lit(&self.identifier); let icon = vec_lit(&self.icon, str_lit); + let active = self.active; + let targets = quote!(None); + let resources = quote!(None); + let copyright = quote!(None); + let category = quote!(None); + let short_description = quote!(None); + let long_description = quote!(None); + let deb = quote!(Default::default()); + let macos = quote!(Default::default()); + let external_bin = opt_vec_str_lit(self.external_bin.as_ref()); + let windows = &self.windows; - literal_struct!(tokens, BundleConfig, identifier, icon); + literal_struct!( + tokens, + BundleConfig, + active, + identifier, + icon, + targets, + resources, + copyright, + category, + short_description, + long_description, + deb, + macos, + external_bin, + windows + ); } } @@ -854,8 +2274,22 @@ mod build { let dev_path = &self.dev_path; let dist_dir = &self.dist_dir; let with_global_tauri = self.with_global_tauri; + let runner = quote!(None); + let before_dev_command = quote!(None); + let before_build_command = quote!(None); + let features = quote!(None); - literal_struct!(tokens, BuildConfig, dev_path, dist_dir, with_global_tauri); + literal_struct!( + tokens, + BuildConfig, + runner, + dev_path, + dist_dir, + with_global_tauri, + before_dev_command, + before_build_command, + features + ); } } @@ -863,8 +2297,19 @@ mod build { fn to_tokens(&self, tokens: &mut TokenStream) { let active = self.active; let dialog = self.dialog; - let pubkey = opt_str_lit(self.pubkey.as_ref()); - let endpoints = opt_vec_str_lit(self.endpoints.as_ref()); + let pubkey = str_lit(&self.pubkey); + let endpoints = opt_lit( + self + .endpoints + .as_ref() + .map(|list| { + vec_lit(list, |url| { + let url = url.0.as_str(); + quote! { ::tauri::utils::config::UpdaterEndpoint(#url.parse().unwrap()) } + }) + }) + .as_ref(), + ); literal_struct!(tokens, UpdaterConfig, active, dialog, pubkey, endpoints); } @@ -873,8 +2318,10 @@ mod build { impl ToTokens for SecurityConfig { fn to_tokens(&self, tokens: &mut TokenStream) { let csp = opt_str_lit(self.csp.as_ref()); + let dev_csp = opt_str_lit(self.dev_csp.as_ref()); + let freeze_prototype = self.freeze_prototype; - literal_struct!(tokens, SecurityConfig, csp); + literal_struct!(tokens, SecurityConfig, csp, dev_csp, freeze_prototype); } } @@ -886,24 +2333,144 @@ mod build { } } + impl ToTokens for FsAllowlistScope { + fn to_tokens(&self, tokens: &mut TokenStream) { + let allowed_paths = vec_lit(&self.0, path_buf_lit); + tokens.append_all(quote! { ::tauri::utils::config::FsAllowlistScope(#allowed_paths) }) + } + } + + impl ToTokens for FsAllowlistConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let scope = &self.scope; + tokens.append_all(quote! { ::tauri::utils::config::FsAllowlistConfig { scope: #scope, ..Default::default() } }) + } + } + + impl ToTokens for ProtocolAllowlistConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let asset_scope = &self.asset_scope; + tokens.append_all(quote! { ::tauri::utils::config::ProtocolAllowlistConfig { asset_scope: #asset_scope, ..Default::default() } }) + } + } + + impl ToTokens for HttpAllowlistScope { + fn to_tokens(&self, tokens: &mut TokenStream) { + let allowed_urls = vec_lit(&self.0, url_lit); + tokens.append_all(quote! { ::tauri::utils::config::HttpAllowlistScope(#allowed_urls) }) + } + } + + impl ToTokens for HttpAllowlistConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let scope = &self.scope; + tokens.append_all(quote! { ::tauri::utils::config::HttpAllowlistConfig { scope: #scope, ..Default::default() } }) + } + } + + impl ToTokens for ShellAllowedCommand { + fn to_tokens(&self, tokens: &mut TokenStream) { + let name = str_lit(&self.name); + let command = path_buf_lit(&self.command); + let args = &self.args; + let sidecar = &self.sidecar; + + literal_struct!(tokens, ShellAllowedCommand, name, command, args, sidecar); + } + } + + impl ToTokens for ShellAllowedArgs { + fn to_tokens(&self, tokens: &mut TokenStream) { + let prefix = quote! { ::tauri::utils::config::ShellAllowedArgs }; + + tokens.append_all(match self { + Self::Flag(flag) => quote!(#prefix::Flag(#flag)), + Self::List(list) => { + let list = vec_lit(list, identity); + quote!(#prefix::List(#list)) + } + }) + } + } + + impl ToTokens for ShellAllowedArg { + fn to_tokens(&self, tokens: &mut TokenStream) { + let prefix = quote! { ::tauri::utils::config::ShellAllowedArg }; + + tokens.append_all(match self { + Self::Fixed(fixed) => { + let fixed = str_lit(fixed); + quote!(#prefix::Fixed(#fixed)) + } + Self::Var { validator } => { + let validator = str_lit(validator); + quote!(#prefix::Var { validator: #validator }) + } + }) + } + } + + impl ToTokens for ShellAllowlistOpen { + fn to_tokens(&self, tokens: &mut TokenStream) { + let prefix = quote! { ::tauri::utils::config::ShellAllowlistOpen }; + + tokens.append_all(match self { + Self::Flag(flag) => quote!(#prefix::Flag(#flag)), + Self::Validate(regex) => quote!(#prefix::Validate(#regex)), + }) + } + } + + impl ToTokens for ShellAllowlistScope { + fn to_tokens(&self, tokens: &mut TokenStream) { + let allowed_commands = vec_lit(&self.0, identity); + tokens.append_all(quote! { ::tauri::utils::config::ShellAllowlistScope(#allowed_commands) }) + } + } + + impl ToTokens for ShellAllowlistConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let scope = &self.scope; + tokens.append_all(quote! { ::tauri::utils::config::ShellAllowlistConfig { scope: #scope, ..Default::default() } }) + } + } + + impl ToTokens for AllowlistConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let fs = &self.fs; + let protocol = &self.protocol; + let http = &self.http; + let shell = &self.shell; + tokens.append_all( + quote! { ::tauri::utils::config::AllowlistConfig { fs: #fs, protocol: #protocol, http: #http, shell: #shell, ..Default::default() } }, + ) + } + } + impl ToTokens for TauriConfig { fn to_tokens(&self, tokens: &mut TokenStream) { + let pattern = &self.pattern; let windows = vec_lit(&self.windows, identity); let cli = opt_lit(self.cli.as_ref()); let bundle = &self.bundle; let updater = &self.updater; let security = &self.security; let system_tray = opt_lit(self.system_tray.as_ref()); + let allowlist = &self.allowlist; + let macos_private_api = self.macos_private_api; literal_struct!( tokens, TauriConfig, + pattern, windows, cli, bundle, updater, security, - system_tray + system_tray, + allowlist, + macos_private_api ); } } @@ -957,9 +2524,7 @@ mod test { // get default dev path let d_path = default_dev_path(); // get default window - let d_windows = default_window_config(); - // get default title - let d_title = default_title(); + let d_windows: Vec = vec![]; // get default bundle let d_bundle = BundleConfig::default(); // get default updater @@ -967,51 +2532,50 @@ mod test { // create a tauri config. let tauri = TauriConfig { - windows: vec![WindowConfig { - label: "main".to_string(), - url: WindowUrl::default(), - file_drop_enabled: true, - center: false, - x: None, - y: None, - width: 800f64, - height: 600f64, - min_width: None, - min_height: None, - max_width: None, - max_height: None, - resizable: true, - title: String::from("Tauri App"), - fullscreen: false, - focus: false, - transparent: false, - maximized: false, - visible: true, - decorations: true, - always_on_top: false, - skip_taskbar: false, - }], + pattern: Default::default(), + windows: vec![], bundle: BundleConfig { + active: false, + targets: None, identifier: String::from(""), icon: Vec::new(), + resources: None, + copyright: None, + category: None, + short_description: None, + long_description: None, + deb: Default::default(), + macos: Default::default(), + external_bin: None, + windows: Default::default(), }, cli: None, updater: UpdaterConfig { active: false, dialog: true, - pubkey: None, + pubkey: "".into(), endpoints: None, }, - security: SecurityConfig { csp: None }, + security: SecurityConfig { + csp: None, + dev_csp: None, + freeze_prototype: true, + }, + allowlist: AllowlistConfig::default(), system_tray: None, + macos_private_api: false, }; // create a build config let build = BuildConfig { + runner: None, dev_path: AppUrl::Url(WindowUrl::External( Url::parse("http://localhost:8080").unwrap(), )), dist_dir: AppUrl::Url(WindowUrl::App("../dist".into())), + before_dev_command: None, + before_build_command: None, + features: None, with_global_tauri: false, }; @@ -1026,7 +2590,6 @@ mod test { Url::parse("http://localhost:8080").unwrap() )) ); - assert_eq!(d_title, tauri.windows[0].title); assert_eq!(d_windows, tauri.windows); } } diff --git a/core/tauri-utils/src/config/parse.rs b/core/tauri-utils/src/config/parse.rs new file mode 100644 index 000000000000..6fa49f7fabc2 --- /dev/null +++ b/core/tauri-utils/src/config/parse.rs @@ -0,0 +1,236 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::config::Config; +use json_patch::merge; +use serde::de::DeserializeOwned; +use serde_json::Value; +use std::ffi::OsStr; +use std::path::{Path, PathBuf}; +use thiserror::Error; + +/// All extensions that are possibly supported, but perhaps not enabled. +pub const EXTENSIONS_SUPPORTED: &[&str] = &["json", "json5"]; + +/// All extensions that are currently enabled. +pub const EXTENSIONS_ENABLED: &[&str] = &[ + "json", + #[cfg(feature = "config-json5")] + "json5", +]; + +/// Represents all the errors that can happen while reading the config. +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum ConfigError { + /// Failed to parse from JSON. + #[error("unable to parse JSON Tauri config file at {path} because {error}")] + FormatJson { + /// The path that failed to parse into JSON. + path: PathBuf, + + /// The parsing [`serde_json::Error`]. + error: serde_json::Error, + }, + + /// Failed to parse from JSON5. + #[cfg(feature = "config-json5")] + #[error("unable to parse JSON5 Tauri config file at {path} because {error}")] + FormatJson5 { + /// The path that failed to parse into JSON5. + path: PathBuf, + + /// The parsing [`json5::Error`]. + error: ::json5::Error, + }, + + /// Unknown file extension encountered. + #[error("unsupported format encountered {0}")] + UnsupportedFormat(String), + + /// Known file extension encountered, but corresponding parser is not enabled (cargo features). + #[error("supported (but disabled) format encountered {extension} - try enabling `{feature}` ")] + DisabledFormat { + /// The extension encountered. + extension: String, + + /// The cargo feature to enable it. + feature: String, + }, + + /// A generic IO error with context of what caused it. + #[error("unable to read Tauri config file at {path} because {error}")] + Io { + /// The path the IO error occured on. + path: PathBuf, + + /// The [`std::io::Error`]. + error: std::io::Error, + }, +} + +/// Reads the configuration from the given root directory. +/// +/// It first looks for a `tauri.conf.json[5]` file on the given directory. The file must exist. +/// Then it looks for a platform-specific configuration file: +/// - `tauri.macos.conf.json[5]` on macOS +/// - `tauri.linux.conf.json[5]` on Linux +/// - `tauri.windows.conf.json[5]` on Windows +/// Merging the configurations using [JSON Merge Patch (RFC 7396)]. +/// +/// [JSON Merge Patch (RFC 7396)]: https://datatracker.ietf.org/doc/html/rfc7396. +pub fn read_from(root_dir: PathBuf) -> Result { + let mut config: Value = parse_value(root_dir.join("tauri.conf.json"))?; + + let platform_config_filename = if cfg!(target_os = "macos") { + "tauri.macos.conf.json" + } else if cfg!(windows) { + "tauri.windows.conf.json" + } else { + "tauri.linux.conf.json" + }; + let platform_config_path = root_dir.join(platform_config_filename); + if does_supported_extension_exist(&platform_config_path) { + let platform_config: Value = parse_value(platform_config_path)?; + merge(&mut config, &platform_config); + } + Ok(config) +} + +/// Check if a supported config file exists at path. +/// +/// The passed path is expected to be the path to the "default" configuration format, in this case +/// JSON with `.json`. +pub fn does_supported_extension_exist(path: impl Into) -> bool { + let path = path.into(); + EXTENSIONS_ENABLED + .iter() + .any(|ext| path.with_extension(ext).exists()) +} + +/// Parse the config from path, including alternative formats. +/// +/// Hierarchy: +/// 1. Check if `tauri.conf.json` exists +/// a. Parse it with `serde_json` +/// b. Parse it with `json5` if `serde_json` fails +/// c. Return original `serde_json` error if all above steps failed +/// 2. Check if `tauri.conf.json5` exists +/// a. Parse it with `json5` +/// b. Return error if all above steps failed +/// 3. Return error if all above steps failed +pub fn parse(path: impl Into) -> Result { + do_parse(path.into()) +} + +/// See [`parse`] for specifics, returns a JSON [`Value`] instead of [`Config`]. +pub fn parse_value(path: impl Into) -> Result { + do_parse(path.into()) +} + +fn do_parse(path: PathBuf) -> Result { + let json5 = path.with_extension("json5"); + let path_ext = path + .extension() + .map(OsStr::to_string_lossy) + .unwrap_or_default(); + + if path.exists() { + let raw = read_to_string(&path)?; + + // to allow us to easily use the compile-time #[cfg], we always bind + #[allow(clippy::let_and_return)] + let json = do_parse_json(&raw, &path); + + // we also want to support **valid** json5 in the .json extension if the feature is enabled. + // if the json5 is not valid the serde_json error for regular json will be returned. + // this could be a bit confusing, so we may want to encourage users using json5 to use the + // .json5 extension instead of .json + #[cfg(feature = "config-json5")] + let json = { + match do_parse_json5(&raw, &path) { + json5 @ Ok(_) => json5, + + // assume any errors from json5 in a .json file is because it's not json5 + Err(_) => json, + } + }; + + json + } else if json5.exists() { + #[cfg(feature = "config-json5")] + { + let raw = read_to_string(&json5)?; + do_parse_json5(&raw, &path) + } + + #[cfg(not(feature = "config-json5"))] + Err(ConfigError::DisabledFormat { + extension: ".json5".into(), + feature: "config-json5".into(), + }) + } else if !EXTENSIONS_SUPPORTED.contains(&path_ext.as_ref()) { + Err(ConfigError::UnsupportedFormat(path_ext.to_string())) + } else { + Err(ConfigError::Io { + path, + error: std::io::ErrorKind::NotFound.into(), + }) + } +} + +/// "Low-level" helper to parse JSON into a [`Config`]. +/// +/// `raw` should be the contents of the file that is represented by `path`. +pub fn parse_json(raw: &str, path: &Path) -> Result { + do_parse_json(raw, path) +} + +/// "Low-level" helper to parse JSON into a JSON [`Value`]. +/// +/// `raw` should be the contents of the file that is represented by `path`. +pub fn parse_json_value(raw: &str, path: &Path) -> Result { + do_parse_json(raw, path) +} + +fn do_parse_json(raw: &str, path: &Path) -> Result { + serde_json::from_str(raw).map_err(|error| ConfigError::FormatJson { + path: path.into(), + error, + }) +} + +/// "Low-level" helper to parse JSON5 into a [`Config`]. +/// +/// `raw` should be the contents of the file that is represented by `path`. This function requires +/// the `config-json5` feature to be enabled. +#[cfg(feature = "config-json5")] +pub fn parse_json5(raw: &str, path: &Path) -> Result { + do_parse_json5(raw, path) +} + +/// "Low-level" helper to parse JSON5 into a JSON [`Value`]. +/// +/// `raw` should be the contents of the file that is represented by `path`. This function requires +/// the `config-json5` feature to be enabled. +#[cfg(feature = "config-json5")] +pub fn parse_json5_value(raw: &str, path: &Path) -> Result { + do_parse_json5(raw, path) +} + +#[cfg(feature = "config-json5")] +fn do_parse_json5(raw: &str, path: &Path) -> Result { + ::json5::from_str(raw).map_err(|error| ConfigError::FormatJson5 { + path: path.into(), + error, + }) +} + +/// Helper function to wrap IO errors from [`std::fs::read_to_string`] into a [`ConfigError`]. +fn read_to_string(path: &Path) -> Result { + std::fs::read_to_string(path).map_err(|error| ConfigError::Io { + path: path.into(), + error, + }) +} diff --git a/core/tauri-utils/src/html.rs b/core/tauri-utils/src/html.rs index 482da68f9219..a6849dd73c8e 100644 --- a/core/tauri-utils/src/html.rs +++ b/core/tauri-utils/src/html.rs @@ -4,90 +4,76 @@ //! The module to process HTML in Tauri. -use html5ever::{interface::QualName, namespace_url, ns, LocalName}; -use kuchiki::{Attribute, ExpandedName, NodeRef}; +use std::path::{Path, PathBuf}; -/// Injects the invoke key token to each script on the document. -/// -/// The invoke key token is replaced at runtime with the actual invoke key value. -pub fn inject_invoke_key_token(document: &mut NodeRef) { - let mut targets = vec![]; - if let Ok(scripts) = document.select("script") { +use html5ever::{interface::QualName, namespace_url, ns, tendril::TendrilSink, LocalName}; +pub use kuchiki::NodeRef; +use kuchiki::{Attribute, ExpandedName}; +use serde::Serialize; +#[cfg(feature = "isolation")] +use serialize_to_javascript::DefaultTemplate; + +use crate::config::PatternKind; +#[cfg(feature = "isolation")] +use crate::pattern::isolation::IsolationJavascriptCodegen; + +/// The token used on the CSP tag content. +pub const CSP_TOKEN: &str = "__TAURI_CSP__"; +/// The token used for script nonces. +pub const SCRIPT_NONCE_TOKEN: &str = "__TAURI_SCRIPT_NONCE__"; +/// The token used for style nonces. +pub const STYLE_NONCE_TOKEN: &str = "__TAURI_STYLE_NONCE__"; + +/// Parses the given HTML string. +pub fn parse(html: String) -> NodeRef { + kuchiki::parse_html().one(html) +} + +fn with_head(document: &mut NodeRef, f: F) { + if let Ok(ref node) = document.select_first("head") { + f(node.as_node()) + } else { + let node = NodeRef::new_element( + QualName::new(None, ns!(html), LocalName::from("head")), + None, + ); + f(&node); + document.prepend(node) + } +} + +fn inject_nonce(document: &mut NodeRef, selector: &str, token: &str) { + if let Ok(scripts) = document.select(selector) { for target in scripts { - targets.push(target); - } - for target in targets { let node = target.as_node(); let element = node.as_element().unwrap(); - let attrs = element.attributes.borrow(); - // if the script is external (has `src`), we won't inject the token - if attrs.get("src").is_some() { + let mut attrs = element.attributes.borrow_mut(); + // if the node already has the `nonce` attribute, skip it + if attrs.get("nonce").is_some() { continue; } - - let replacement_node = match attrs.get("type") { - Some("module") | Some("application/ecmascript") => { - let replacement_node = NodeRef::new_element( - QualName::new(None, ns!(html), "script".into()), - element - .attributes - .borrow() - .clone() - .map - .into_iter() - .collect::>(), - ); - let script = node.text_contents(); - replacement_node.append(NodeRef::new_text(format!( - r#" - const __TAURI_INVOKE_KEY__ = __TAURI__INVOKE_KEY_TOKEN__; - {} - "#, - script - ))); - replacement_node - } - Some("application/javascript") | None => { - let replacement_node = NodeRef::new_element( - QualName::new(None, ns!(html), "script".into()), - element - .attributes - .borrow() - .clone() - .map - .into_iter() - .collect::>(), - ); - let script = node.text_contents(); - replacement_node.append(NodeRef::new_text( - script.replace("__TAURI_INVOKE_KEY__", "__TAURI__INVOKE_KEY_TOKEN__"), - )); - replacement_node - } - _ => { - continue; - } - }; - - node.insert_after(replacement_node); - node.detach(); + attrs.insert("nonce", token.into()); } } } +/// Inject nonce tokens to all scripts and styles. +pub fn inject_nonce_token(document: &mut NodeRef) { + inject_nonce(document, "script[src^='http']", SCRIPT_NONCE_TOKEN); + inject_nonce(document, "style", STYLE_NONCE_TOKEN); +} + /// Injects a content security policy to the HTML. pub fn inject_csp(document: &mut NodeRef, csp: &str) { - if let Ok(ref head) = document.select_first("head") { - head.as_node().append(create_csp_meta_tag(csp)); - } else { - let head = NodeRef::new_element( - QualName::new(None, ns!(html), LocalName::from("head")), - None, - ); + with_head(document, |head| { head.append(create_csp_meta_tag(csp)); - document.prepend(head); - } + }); +} + +/// Injects a content security policy token to the HTML. +pub fn inject_csp_token(document: &mut NodeRef) { + inject_csp(document, CSP_TOKEN) } fn create_csp_meta_tag(csp: &str) -> NodeRef { @@ -112,9 +98,102 @@ fn create_csp_meta_tag(csp: &str) -> NodeRef { ) } +/// The shape of the JavaScript Pattern config +#[derive(Debug, Serialize)] +#[serde(rename_all = "lowercase", tag = "pattern")] +pub enum PatternObject { + /// Brownfield pattern. + Brownfield, + /// Isolation pattern. Recommended for security purposes. + Isolation { + /// Which `IsolationSide` this `PatternObject` is getting injected into + side: IsolationSide, + }, +} + +impl From<&PatternKind> for PatternObject { + fn from(pattern_kind: &PatternKind) -> Self { + match pattern_kind { + PatternKind::Brownfield => Self::Brownfield, + #[cfg(feature = "isolation")] + PatternKind::Isolation { .. } => Self::Isolation { + side: IsolationSide::default(), + }, + } + } +} + +/// Where the JavaScript is injected to +#[derive(Debug, Serialize)] +#[serde(rename_all = "lowercase")] +pub enum IsolationSide { + /// Original frame, the Brownfield application + Original, + /// Secure frame, the isolation security application + Secure, +} + +impl Default for IsolationSide { + fn default() -> Self { + Self::Original + } +} + +/// Injects the Isolation JavaScript to a codegen time document. +/// +/// Note: This function is not considered part of the stable API. +#[cfg(feature = "isolation")] +pub fn inject_codegen_isolation_script(document: &mut NodeRef) { + with_head(document, |head| { + let script = NodeRef::new_element(QualName::new(None, ns!(html), "script".into()), None); + script.append(NodeRef::new_text( + IsolationJavascriptCodegen {} + .render_default(&Default::default()) + .expect("unable to render codegen isolation script template") + .into_string(), + )); + + head.prepend(script); + }); +} + +/// Temporary workaround for Windows not allowing requests +/// +/// Note: this does not prevent path traversal due to the isolation application expectation that it +/// is secure. +pub fn inline_isolation(document: &mut NodeRef, dir: &Path) { + for script in document + .select("script[src]") + .expect("unable to parse document for scripts") + { + let src = { + let attributes = script.attributes.borrow(); + attributes + .get(LocalName::from("src")) + .expect("script with src attribute has no src value") + .to_string() + }; + + let mut path = PathBuf::from(src); + if path.has_root() { + path = path + .strip_prefix("/") + .expect("Tauri \"Isolation\" Pattern only supports relative or absolute (`/`) paths.") + .into(); + } + + let file = std::fs::read_to_string(dir.join(path)).expect("unable to find isolation file"); + script.as_node().append(NodeRef::new_text(file)); + + let mut attributes = script.attributes.borrow_mut(); + attributes.remove(LocalName::from("src")); + } +} + #[cfg(test)] mod tests { use kuchiki::traits::*; + #[test] fn csp() { let htmls = vec![ @@ -123,13 +202,12 @@ mod tests { ]; for html in htmls { let mut document = kuchiki::parse_html().one(html); - let csp = "default-src 'self'; img-src https://*; child-src 'none';"; - super::inject_csp(&mut document, csp); + super::inject_csp_token(&mut document); assert_eq!( document.to_string(), format!( r#" "#, - csp + super::CSP_TOKEN ) ); } diff --git a/core/tauri-utils/src/lib.rs b/core/tauri-utils/src/lib.rs index 405c41570e79..8ff4e534ccfd 100644 --- a/core/tauri-utils/src/lib.rs +++ b/core/tauri-utils/src/lib.rs @@ -9,6 +9,12 @@ pub mod assets; pub mod config; pub mod html; pub mod platform; +/// Prepare application resources and sidecars. +#[cfg(feature = "resources")] +pub mod resources; + +/// Application pattern. +pub mod pattern; /// `tauri::App` package information. #[derive(Debug, Clone)] @@ -17,16 +23,75 @@ pub struct PackageInfo { pub name: String, /// App version pub version: String, + /// The crate authors. + pub authors: &'static str, + /// The crate description. + pub description: &'static str, } impl PackageInfo { /// Returns the application package name. /// On macOS and Windows it's the `name` field, and on Linux it's the `name` in `kebab-case`. pub fn package_name(&self) -> String { + #[cfg(target_os = "linux")] + { + use heck::ToKebabCase; + self.name.clone().to_kebab_case() + } + #[cfg(not(target_os = "linux"))] self.name.clone() } } +/// Information about environment variables. +#[derive(Debug, Clone)] +#[non_exhaustive] +pub struct Env { + /// The APPIMAGE environment variable. + #[cfg(target_os = "linux")] + pub appimage: Option, + /// The APPDIR environment variable. + #[cfg(target_os = "linux")] + pub appdir: Option, +} + +#[allow(clippy::derivable_impls)] +impl Default for Env { + fn default() -> Self { + #[cfg(target_os = "linux")] + { + let env = Self { + #[cfg(target_os = "linux")] + appimage: std::env::var_os("APPIMAGE"), + #[cfg(target_os = "linux")] + appdir: std::env::var_os("APPDIR"), + }; + if env.appimage.is_some() || env.appdir.is_some() { + // validate that we're actually running on an AppImage + // an AppImage is mounted to `/$TEMPDIR/.mount_${appPrefix}${hash}` + // see https://github.com/AppImage/AppImageKit/blob/1681fd84dbe09c7d9b22e13cdb16ea601aa0ec47/src/runtime.c#L501 + // note that it is safe to use `std::env::current_exe` here since we just loaded an AppImage. + let is_temp = std::env::current_exe() + .map(|p| { + p.display() + .to_string() + .starts_with(&format!("{}/.mount_", std::env::temp_dir().display())) + }) + .unwrap_or(true); + + if !is_temp { + panic!("`APPDIR` or `APPIMAGE` environment variable found but this application was not detected as an AppImage; this might be a security issue."); + } + } + env + } + #[cfg(not(target_os = "linux"))] + { + Self {} + } + } +} + /// The result type of `tauri-utils`. pub type Result = std::result::Result; @@ -58,4 +123,27 @@ pub enum Error { /// IO error #[error("{0}")] Io(#[from] std::io::Error), + /// Invalid pattern. + #[error("invalid pattern `{0}`. Expected either `brownfield` or `isolation`.")] + InvalidPattern(String), + /// Invalid glob pattern. + #[cfg(feature = "resources")] + #[error("{0}")] + GlobPattern(#[from] glob::PatternError), + /// Failed to use glob pattern. + #[cfg(feature = "resources")] + #[error("`{0}`")] + Glob(#[from] glob::GlobError), + /// Glob pattern did not find any results. + #[cfg(feature = "resources")] + #[error("path matching {0} not found.")] + GlobPathNotFound(String), + /// Error walking directory. + #[cfg(feature = "resources")] + #[error("{0}")] + WalkdirError(#[from] walkdir::Error), + /// Not allowed to walk dir. + #[cfg(feature = "resources")] + #[error("could not walk directory `{0}`, try changing `allow_walk` to true on the `ResourcePaths` constructor.")] + NotAllowedToWalkDir(std::path::PathBuf), } diff --git a/core/tauri-utils/src/pattern/isolation.js b/core/tauri-utils/src/pattern/isolation.js new file mode 100644 index 000000000000..42e2604ce5d8 --- /dev/null +++ b/core/tauri-utils/src/pattern/isolation.js @@ -0,0 +1,115 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +/** + * IMPORTANT: See ipc.js for the main frame implementation. + * main frame -> isolation frame = isolation payload + * isolation frame -> main frame = isolation message + */ + +;(async function () { + /** + * Sends the message to the isolation frame. + * @param {any} message + */ + function sendMessage(message) { + window.parent.postMessage(message, '*') + } + + /** + * @type {Uint8Array} - Injected by Tauri during runtime + */ + const aesGcmKeyRaw = new Uint8Array(__TEMPLATE_runtime_aes_gcm_key__) + + /** + * @type {CryptoKey} + */ + const aesGcmKey = await window.crypto.subtle.importKey( + 'raw', + aesGcmKeyRaw, + 'AES-GCM', + true, + ['encrypt'] + ) + + /** + * @param {object} data + * @return {Promise<{nonce: number[], payload: number[]}>} + */ + async function encrypt(data) { + let algorithm = Object.create(null) + algorithm.name = 'AES-GCM' + algorithm.iv = window.crypto.getRandomValues(new Uint8Array(12)) + + let encoder = new TextEncoder() + let payloadRaw = encoder.encode(JSON.stringify(data)) + + return window.crypto.subtle + .encrypt(algorithm, aesGcmKey, payloadRaw) + .then((payload) => { + let result = Object.create(null) + result.nonce = Array.from(new Uint8Array(algorithm.iv)) + result.payload = Array.from(new Uint8Array(payload)) + return result + }) + } + + /** + * Detect if a message event is a valid isolation payload. + * + * @param {MessageEvent} event - a message event that is expected to be an isolation payload + * @return boolean + */ + function isIsolationPayload(event) { + return ( + typeof event.data === 'object' && + 'callback' in event.data && + 'error' in event.data + ) + } + + /** + * Handle incoming payload events. + * @param {MessageEvent} event + */ + async function payloadHandler(event) { + if (!isIsolationPayload(event)) { + return + } + + let data = event.data + + if (typeof window.__TAURI_ISOLATION_HOOK__ === 'function') { + // await even if it's not async so that we can support async ones + data = await window.__TAURI_ISOLATION_HOOK__(data) + } + + const encrypted = await encrypt(data) + sendMessage(encrypted) + } + + window.addEventListener('message', payloadHandler, false) + + /** + * @type {number} - How many milliseconds to wait between ready checks + */ + const readyIntervalMs = 50 + + /** + * Wait until this Isolation context is ready to receive messages, and let the main frame know. + */ + function waitUntilReady() { + // consider either a function or an explicitly set null value as the ready signal + if ( + typeof window.__TAURI_ISOLATION_HOOK__ === 'function' || + window.__TAURI_ISOLATION_HOOK__ === null + ) { + sendMessage('__TAURI_ISOLATION_READY__') + } else { + setTimeout(waitUntilReady, readyIntervalMs) + } + } + + setTimeout(waitUntilReady, readyIntervalMs) +})() diff --git a/core/tauri-utils/src/pattern/isolation.rs b/core/tauri-utils/src/pattern/isolation.rs new file mode 100644 index 000000000000..8e3c8d581c39 --- /dev/null +++ b/core/tauri-utils/src/pattern/isolation.rs @@ -0,0 +1,164 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::array::TryFromSliceError; +use std::borrow::Cow; +use std::fmt::{Debug, Formatter}; +use std::string::FromUtf8Error; + +use aes_gcm::aead::Aead; +use aes_gcm::{aead::NewAead, Aes256Gcm, Nonce}; +use once_cell::sync::OnceCell; +use ring::error::Unspecified; +use ring::rand::SystemRandom; +use serialize_to_javascript::{default_template, Template}; + +/// Cryptographically secure pseudo-random number generator. +static RNG: OnceCell = OnceCell::new(); + +/// The style for the isolation iframe. +pub const IFRAME_STYLE: &str = "#__tauri_isolation__ { display: none !important }"; + +/// Errors that can occur during Isolation keys generation. +#[derive(Debug, thiserror::Error)] +#[non_exhaustive] +pub enum Error { + /// Something went wrong with the CSPRNG. + #[error("Unspecified CSPRNG error")] + Csprng, + + /// Something went wrong with decryping an AES-GCM payload + #[error("AES-GCM")] + Aes, + + /// Nonce was not 96 bits + #[error("Nonce: {0}")] + NonceSize(#[from] TryFromSliceError), + + /// Payload was not valid utf8 + #[error("{0}")] + Utf8(#[from] FromUtf8Error), + + /// Invalid json format + #[error("{0}")] + Json(#[from] serde_json::Error), +} + +impl From for Error { + fn from(_: Unspecified) -> Self { + Self::Csprng + } +} + +/// A formatted AES-GCM cipher instance along with the key used to initialize it. +#[derive(Clone)] +pub struct AesGcmPair { + raw: [u8; 32], + key: Aes256Gcm, +} + +impl Debug for AesGcmPair { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "AesGcmPair(...)") + } +} + +impl AesGcmPair { + fn new() -> Result { + let rng = RNG.get_or_init(SystemRandom::new); + let raw: [u8; 32] = ring::rand::generate(rng)?.expose(); + let key = aes_gcm::Key::from_slice(&raw); + Ok(Self { + raw, + key: Aes256Gcm::new(key), + }) + } + + /// The raw value used to create the AES-GCM key + pub fn raw(&self) -> &[u8; 32] { + &self.raw + } + + /// The formatted AES-GCM key + pub fn key(&self) -> &Aes256Gcm { + &self.key + } +} + +/// All cryptographic keys required for Isolation encryption +#[derive(Debug, Clone)] +pub struct Keys { + /// AES-GCM key + aes_gcm: AesGcmPair, +} + +impl Keys { + /// Securely generate required keys for Isolation encryption. + pub fn new() -> Result { + AesGcmPair::new() + .map(|aes_gcm| Self { aes_gcm }) + .map_err(Into::into) + } + + /// The AES-GCM data (and raw data). + pub fn aes_gcm(&self) -> &AesGcmPair { + &self.aes_gcm + } + + /// Decrypts a message using the generated keys. + pub fn decrypt(&self, raw: RawIsolationPayload<'_>) -> Result { + let RawIsolationPayload { nonce, payload } = raw; + let nonce: [u8; 12] = nonce.as_ref().try_into()?; + let bytes = self + .aes_gcm + .key + .decrypt(Nonce::from_slice(&nonce), payload.as_ref()) + .map_err(|_| self::Error::Aes)?; + + String::from_utf8(bytes).map_err(Into::into) + } +} + +/// Raw representation of +#[derive(Debug, serde::Deserialize)] +pub struct RawIsolationPayload<'a> { + nonce: Cow<'a, [u8]>, + payload: Cow<'a, [u8]>, +} + +impl<'a> TryFrom<&'a str> for RawIsolationPayload<'a> { + type Error = Error; + + fn try_from(value: &'a str) -> Result { + serde_json::from_str(value).map_err(Into::into) + } +} + +/// The Isolation JavaScript template meant to be injected during codegen. +/// +/// Note: This struct is not considered part of the stable API +#[derive(Template)] +#[default_template("isolation.js")] +pub struct IsolationJavascriptCodegen { + // this template intentionally does not include the runtime field +} + +/// The Isolation JavaScript template meant to be injected during runtime. +/// +/// Note: This struct is not considered part of the stable API +#[derive(Template)] +#[default_template("isolation.js")] +pub struct IsolationJavascriptRuntime<'a> { + /// The key used on the Rust backend and the Isolation Javascript + pub runtime_aes_gcm_key: &'a [u8; 32], +} + +#[cfg(test)] +mod test { + #[test] + fn create_keys() -> Result<(), Box> { + let _ = super::Keys::new()?; + Ok(()) + } +} diff --git a/core/tauri-utils/src/pattern/mod.rs b/core/tauri-utils/src/pattern/mod.rs new file mode 100644 index 000000000000..d0a1019b0337 --- /dev/null +++ b/core/tauri-utils/src/pattern/mod.rs @@ -0,0 +1,7 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +/// Handling the Tauri "Isolation" Pattern. +#[cfg(feature = "isolation")] +pub mod isolation; diff --git a/core/tauri-utils/src/platform.rs b/core/tauri-utils/src/platform.rs index e6e5cabea8bb..cabe9a99b55b 100644 --- a/core/tauri-utils/src/platform.rs +++ b/core/tauri-utils/src/platform.rs @@ -4,12 +4,87 @@ //! Platform helper functions. -use std::{ - env, - path::{PathBuf, MAIN_SEPARATOR}, -}; +use std::path::{PathBuf, MAIN_SEPARATOR}; -use crate::PackageInfo; +use crate::{Env, PackageInfo}; + +mod starting_binary; + +/// Retrieves the currently running binary's path, taking into account security considerations. +/// +/// The path is cached as soon as possible (before even `main` runs) and that value is returned +/// repeatedly instead of fetching the path every time. It is possible for the path to not be found, +/// or explicitly disabled (see following macOS specific behavior). +/// +/// # Platform-specific behavior +/// +/// On `macOS`, this function will return an error if the original path contained any symlinks +/// due to less protection on macOS regarding symlinks. This behavior can be disabled by setting the +/// `process-relaunch-dangerous-allow-symlink-macos` feature, although it is *highly discouraged*. +/// +/// # Security +/// +/// If the above platform-specific behavior does **not** take place, this function uses the +/// following resolution. +/// +/// We canonicalize the path we received from [`std::env::current_exe`] to resolve any soft links. +/// This avoids the usual issue of needing the file to exist at the passed path because a valid +/// current executable result for our purpose should always exist. Notably, +/// [`std::env::current_exe`] also has a security section that goes over a theoretical attack using +/// hard links. Let's cover some specific topics that relate to different ways an attacker might +/// try to trick this function into returning the wrong binary path. +/// +/// ## Symlinks ("Soft Links") +/// +/// [`std::path::Path::canonicalize`] is used to resolve symbolic links to the original path, +/// including nested symbolic links (`link2 -> link1 -> bin`). On macOS, any results that include +/// a symlink are rejected by default due to lesser symlink protections. This can be disabled, +/// **although discouraged**, with the `process-relaunch-dangerous-allow-symlink-macos` feature. +/// +/// ## Hard Links +/// +/// A [Hard Link] is a named entry that points to a file in the file system. +/// On most systems, this is what you would think of as a "file". The term is +/// used on filesystems that allow multiple entries to point to the same file. +/// The linked [Hard Link] Wikipedia page provides a decent overview. +/// +/// In short, unless the attacker was able to create the link with elevated +/// permissions, it should generally not be possible for them to hard link +/// to a file they do not have permissions to - with exception to possible +/// operating system exploits. +/// +/// There are also some platform-specific information about this below. +/// +/// ### Windows +/// +/// Windows requires a permission to be set for the user to create a symlink +/// or a hard link, regardless of ownership status of the target. Elevated +/// permissions users have the ability to create them. +/// +/// ### macOS +/// +/// macOS allows for the creation of symlinks and hard links to any file. +/// Accessing through those links will fail if the user who owns the links +/// does not have the proper permissions on the original file. +/// +/// ### Linux +/// +/// Linux allows for the creation of symlinks to any file. Accessing the +/// symlink will fail if the user who owns the symlink does not have the +/// proper permissions on the original file. +/// +/// Linux additionally provides a kernel hardening feature since version +/// 3.6 (30 September 2012). Most distributions since then have enabled +/// the protection (setting `fs.protected_hardlinks = 1`) by default, which +/// means that a vast majority of desktop Linux users should have it enabled. +/// **The feature prevents the creation of hardlinks that the user does not own +/// or have read/write access to.** [See the patch that enabled this]. +/// +/// [Hard Link]: https://en.wikipedia.org/wiki/Hard_link +/// [See the patch that enabled this]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=800179c9b8a1e796e441674776d11cd4c05d61d7 +pub fn current_exe() -> std::io::Result { + self::starting_binary::STARTING_BINARY.cloned() +} /// Try to determine the current target triple. /// @@ -76,8 +151,9 @@ pub fn target_triple() -> crate::Result { /// `${exe_dir}/../lib/${exe_name}`. /// /// On MacOS, it's `${exe_dir}../Resources` (inside .app). -pub fn resource_dir(package_info: &PackageInfo) -> crate::Result { - let exe = std::env::current_exe()?; +#[allow(unused_variables)] +pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> crate::Result { + let exe = current_exe()?; let exe_dir = exe.parent().expect("failed to get exe directory"); let curr_dir = exe_dir.display().to_string(); @@ -89,14 +165,19 @@ pub fn resource_dir(package_info: &PackageInfo) -> crate::Result { return Ok(exe_dir.to_path_buf()); } - if cfg!(target_os = "linux") { - if curr_dir.ends_with("/data/usr/bin") { + #[allow(unused_mut, unused_assignments)] + let mut res = Err(crate::Error::UnsupportedPlatform); + + #[cfg(target_os = "linux")] + { + res = if curr_dir.ends_with("/data/usr/bin") { // running from the deb bundle dir Ok(exe_dir.join(format!("../lib/{}", package_info.package_name()))) - } else if let Ok(appdir) = env::var("APPDIR") { + } else if let Some(appdir) = &env.appdir { + let appdir: &std::path::Path = appdir.as_ref(); Ok(PathBuf::from(format!( "{}/usr/lib/{}", - appdir, + appdir.display(), package_info.package_name() ))) } else { @@ -105,10 +186,13 @@ pub fn resource_dir(package_info: &PackageInfo) -> crate::Result { "/usr/lib/{}", package_info.package_name() ))) - } - } else if cfg!(target_os = "macos") { - Ok(exe_dir.join("../Resources")) - } else { - Err(crate::Error::UnsupportedPlatform) + }; } + + #[cfg(target_os = "macos")] + { + res = Ok(exe_dir.join("../Resources")); + } + + res } diff --git a/core/tauri-utils/src/platform/starting_binary.rs b/core/tauri-utils/src/platform/starting_binary.rs new file mode 100644 index 000000000000..3b06968dc87f --- /dev/null +++ b/core/tauri-utils/src/platform/starting_binary.rs @@ -0,0 +1,76 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use ctor::ctor; +use std::{ + io::{Error, ErrorKind, Result}, + path::{Path, PathBuf}, +}; + +/// A cached version of the current binary using [`ctor`] to cache it before even `main` runs. +#[ctor] +#[used] +pub(super) static STARTING_BINARY: StartingBinary = StartingBinary::new(); + +/// Represents a binary path that was cached when the program was loaded. +pub(super) struct StartingBinary(std::io::Result); + +impl StartingBinary { + /// Find the starting executable as safely as possible. + fn new() -> Self { + // see notes on current_exe() for security implications + let dangerous_path = match std::env::current_exe() { + Ok(dangerous_path) => dangerous_path, + error @ Err(_) => return Self(error), + }; + + // note: this only checks symlinks on problematic platforms, see implementation below + if let Some(symlink) = Self::has_symlink(&dangerous_path) { + return Self(Err(Error::new( + ErrorKind::InvalidData, + format!("StartingBinary found current_exe() that contains a symlink on a non-allowed platform: {}", symlink.display()), + ))); + } + + // we canonicalize the path to resolve any symlinks to the real exe path + Self(dangerous_path.canonicalize()) + } + + /// A clone of the [`PathBuf`] found to be the starting path. + /// + /// Because [`Error`] is not clone-able, it is recreated instead. + pub(super) fn cloned(&self) -> Result { + self + .0 + .as_ref() + .map(Clone::clone) + .map_err(|e| Error::new(e.kind(), e.to_string())) + } + + /// We only care about checking this on macOS currently, as it has the least symlink protections. + #[cfg(any( + not(target_os = "macos"), + feature = "process-relaunch-dangerous-allow-symlink-macos" + ))] + fn has_symlink(_: &Path) -> Option<&Path> { + None + } + + /// We only care about checking this on macOS currently, as it has the least symlink protections. + #[cfg(all( + target_os = "macos", + not(feature = "process-relaunch-dangerous-allow-symlink-macos") + ))] + fn has_symlink(path: &Path) -> Option<&Path> { + path.ancestors().find(|ancestor| { + matches!( + ancestor + .symlink_metadata() + .as_ref() + .map(std::fs::Metadata::is_symlink), + Ok(true) + ) + }) + } +} diff --git a/core/tauri-utils/src/resources.rs b/core/tauri-utils/src/resources.rs new file mode 100644 index 000000000000..4ae0219ae6ce --- /dev/null +++ b/core/tauri-utils/src/resources.rs @@ -0,0 +1,126 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::path::{Component, Path, PathBuf}; + +/// Given a path (absolute or relative) to a resource file, returns the +/// relative path from the bundle resources directory where that resource +/// should be stored. +pub fn resource_relpath(path: &Path) -> PathBuf { + let mut dest = PathBuf::new(); + for component in path.components() { + match component { + Component::Prefix(_) => {} + Component::RootDir => dest.push("_root_"), + Component::CurDir => {} + Component::ParentDir => dest.push("_up_"), + Component::Normal(string) => dest.push(string), + } + } + dest +} + +/// Parses the external binaries to bundle, adding the target triple suffix to each of them. +pub fn external_binaries(external_binaries: &[String], target_triple: &str) -> Vec { + let mut paths = Vec::new(); + for curr_path in external_binaries { + paths.push(format!( + "{}-{}{}", + curr_path, + target_triple, + if cfg!(windows) { ".exe" } else { "" } + )); + } + paths +} + +/// A helper to iterate through resources. +pub struct ResourcePaths<'a> { + /// the patterns to iterate. + pattern_iter: std::slice::Iter<'a, String>, + /// the glob iterator if the path from the current iteration is a glob pattern. + glob_iter: Option, + /// the walkdir iterator if the path from the current iteration is a directory. + walk_iter: Option, + /// whether the resource paths allows directories or not. + allow_walk: bool, + /// the pattern of the current iteration. + current_pattern: Option, + /// whether the current pattern is valid or not. + current_pattern_is_valid: bool, +} + +impl<'a> ResourcePaths<'a> { + /// Creates a new ResourcePaths from a slice of patterns to iterate + pub fn new(patterns: &'a [String], allow_walk: bool) -> ResourcePaths<'a> { + ResourcePaths { + pattern_iter: patterns.iter(), + glob_iter: None, + walk_iter: None, + allow_walk, + current_pattern: None, + current_pattern_is_valid: false, + } + } +} + +impl<'a> Iterator for ResourcePaths<'a> { + type Item = crate::Result; + + fn next(&mut self) -> Option> { + loop { + if let Some(ref mut walk_entries) = self.walk_iter { + if let Some(entry) = walk_entries.next() { + let entry = match entry { + Ok(entry) => entry, + Err(error) => return Some(Err(crate::Error::from(error))), + }; + let path = entry.path(); + if path.is_dir() { + continue; + } + self.current_pattern_is_valid = true; + return Some(Ok(path.to_path_buf())); + } + } + self.walk_iter = None; + if let Some(ref mut glob_paths) = self.glob_iter { + if let Some(glob_result) = glob_paths.next() { + let path = match glob_result { + Ok(path) => path, + Err(error) => return Some(Err(error.into())), + }; + if path.is_dir() { + if self.allow_walk { + let walk = walkdir::WalkDir::new(path); + self.walk_iter = Some(walk.into_iter()); + continue; + } else { + return Some(Err(crate::Error::NotAllowedToWalkDir(path))); + } + } + self.current_pattern_is_valid = true; + return Some(Ok(path)); + } else if let Some(current_path) = &self.current_pattern { + if !self.current_pattern_is_valid { + self.glob_iter = None; + return Some(Err(crate::Error::GlobPathNotFound(current_path.clone()))); + } + } + } + self.glob_iter = None; + if let Some(pattern) = self.pattern_iter.next() { + self.current_pattern = Some(pattern.to_string()); + self.current_pattern_is_valid = false; + let glob = match glob::glob(pattern) { + Ok(glob) => glob, + Err(error) => return Some(Err(error.into())), + }; + self.glob_iter = Some(glob); + continue; + } + return None; + } + } +} diff --git a/core/tauri/Cargo.toml b/core/tauri/Cargo.toml index 74fc9e80c6fd..02f1188e9769 100644 --- a/core/tauri/Cargo.toml +++ b/core/tauri/Cargo.toml @@ -1,80 +1,86 @@ [package] -name = "tauri" -version = "1.0.0-beta.8" -authors = [ "Tauri Programme within The Commons Conservancy" ] -categories = [ "gui", "web-programming" ] -license = "Apache-2.0 OR MIT" -homepage = "https://tauri.studio" -repository = "https://github.com/tauri-apps/tauri" +authors = ["Tauri Programme within The Commons Conservancy"] +categories = ["gui", "web-programming"] description = "Make tiny, secure apps for all desktop platforms with Tauri" -edition = "2018" +edition = "2021" +rust-version = "1.57" exclude = [ "/test", "/.scripts", ".license_template", "CHANGELOG.md", - "/target" + "/target", ] +homepage = "https://tauri.studio" +license = "Apache-2.0 OR MIT" +name = "tauri" readme = "README.md" +repository = "https://github.com/tauri-apps/tauri" +version = "1.0.0-beta.8" [package.metadata.docs.rs] -all-features = true +default-features = false +features = ["compression", "wry", "isolation", "custom-protocol", "api-all", "cli", "updater", "system-tray", "devtools", "dox"] rustdoc-args = [ "--cfg", "doc_cfg" ] default-target = "x86_64-unknown-linux-gnu" targets = [ "x86_64-pc-windows-msvc", "x86_64-unknown-linux-gnu", - "x86_64-apple-darwin" + "x86_64-apple-darwin", ] [package.metadata.cargo-udeps.ignore] -normal = [ "attohttpc" ] +normal = ["attohttpc"] [dependencies] serde_json = { version = "1.0", features = [ "raw_value" ] } serde = { version = "1.0", features = [ "derive" ] } -tokio = { version = "1.9", features = [ "rt", "rt-multi-thread", "sync", "fs", "io-util" ] } +tokio = { version = "1.16", features = [ "rt", "rt-multi-thread", "sync", "fs", "io-util" ] } futures = "0.3" uuid = { version = "0.8", features = [ "v4" ] } url = { version = "2.2" } thiserror = "1.0" -once_cell = "1.8" +once_cell = "1.9" tauri-runtime = { version = "0.2.1", path = "../tauri-runtime" } tauri-macros = { version = "1.0.0-beta.5", path = "../tauri-macros" } tauri-utils = { version = "1.0.0-beta.3", path = "../tauri-utils" } tauri-runtime-wry = { version = "0.2.1", path = "../tauri-runtime-wry", optional = true } rand = "0.8" -tempfile = "3" semver = "1.0" serde_repr = "0.1" +state = "0.5" +tar = "0.4" +tempfile = "3" zip = "0.5" ignore = "0.4" either = "1.6" -tar = "0.4" flate2 = "1.0" http = "0.2" -state = "0.5" bincode = "1.3" dirs-next = "2.0" percent-encoding = "2.1" base64 = { version = "0.13", optional = true } -clap = { version = "=3.0.0-beta.2", optional = true } +clap = { version = "3", optional = true } notify-rust = { version = "4.5", optional = true } reqwest = { version = "0.11", features = [ "json", "multipart" ], optional = true } bytes = { version = "1", features = [ "serde" ], optional = true } -attohttpc = { version = "0.17", features = [ "json", "form" ] } +attohttpc = { version = "0.18", features = [ "json", "form" ], optional = true } open = { version = "2.0", optional = true } -shared_child = { version = "0.3", optional = true } -os_pipe = { version = "0.9", optional = true } -rfd = { version = "0.4.3", features = [ "parent" ] } -raw-window-handle = "0.3.3" -minisign-verify = { version = "0.1", optional = true } -os_info = { version = "3.0.6", optional = true } +shared_child = { version = "1.0", optional = true } +os_pipe = { version = "1.0", optional = true } +rfd = { version = "0.7.0", features = [ "parent" ], optional = true } +raw-window-handle = "0.4.2" +minisign-verify = { version = "0.2", optional = true } +os_info = { version = "3.2.0", optional = true } futures-lite = "1.12" +regex = { version = "1.5", optional = true } +glob = "0.3" +data-url = { version = "0.1", optional = true } +serialize-to-javascript = "=0.1.1" [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] -gtk = { version = "0.14", features = [ "v3_20" ] } -glib = "0.14" +gtk = { version = "0.15", features = [ "v3_20" ] } +glib = "0.15" [target."cfg(target_os = \"macos\")".dependencies] embed_plist = "1.2" @@ -83,59 +89,151 @@ embed_plist = "1.2" cfg_aliases = "0.1.1" [dev-dependencies] +mockito = "0.30" proptest = "1.0.0" -serde_json = "1.0" -tauri = { path = "." } -serde = { version = "1.0", features = [ "derive" ] } quickcheck = "1.0.3" quickcheck_macros = "1.0.0" +serde = {version = "1.0", features = ["derive"]} +serde_json = "1.0" +tauri = {path = "."} tokio-test = "0.4.2" -tokio = { version = "1.9", features = [ "full" ] } -mockito = "0.30" +tokio = { version = "1.16", features = [ "full" ] } + +[target."cfg(windows)".dev-dependencies.windows] +version = "0.30.0" +features = [ + "Win32_Foundation", +] [features] -default = [ "wry" ] -dox = [ "tauri-runtime-wry/dox" ] -wry = [ "tauri-runtime-wry" ] -cli = [ "clap" ] -custom-protocol = [ "tauri-macros/custom-protocol" ] +default = [ "wry", "compression" ] +compression = [ "tauri-macros/compression", "tauri-utils/compression" ] +wry = ["tauri-runtime-wry"] +isolation = ["tauri-utils/isolation", "tauri-macros/isolation"] +custom-protocol = ["tauri-macros/custom-protocol"] +updater = ["minisign-verify", "base64", "http-api", "dialog-ask"] +http-api = ["attohttpc"] +shell-open-api = [ "open", "regex", "tauri-macros/shell-scope" ] +reqwest-client = ["reqwest", "bytes"] +command = ["shared_child", "os_pipe"] +dialog = ["rfd"] +notification = ["notify-rust"] +cli = ["clap"] +system-tray = ["tauri-runtime/system-tray", "tauri-runtime-wry/system-tray"] +devtools = ["tauri-runtime/devtools", "tauri-runtime-wry/devtools"] +dox = ["tauri-runtime-wry/dox"] +macos-private-api = ["tauri-runtime/macos-private-api", "tauri-runtime-wry/macos-private-api"] +window-data-url = ["data-url"] api-all = [ - "notification-all", + "clipboard-all", + "dialog-all", + "fs-all", "global-shortcut-all", - "shell-all", + "http-all", + "notification-all", "os-all", - "dialog-all", - "updater", - "path-all" + "path-all", + "process-all", + "protocol-all", + "shell-all", + "window-all" +] +clipboard-all = ["clipboard-write-text", "clipboard-read-text"] +clipboard-read-text = [] +clipboard-write-text = [] +dialog-all = ["dialog-open", "dialog-save", "dialog-message", "dialog-ask"] +dialog-ask = ["dialog"] +dialog-confirm = ["dialog"] +dialog-message = ["dialog"] +dialog-open = ["dialog"] +dialog-save = ["dialog"] +fs-all = [ + "fs-copy-file", + "fs-create-dir", + "fs-read-file", + "fs-read-dir", + "fs-remove-dir", + "fs-remove-file", + "fs-rename-file", + "fs-write-file" +] +fs-copy-file = [] +fs-create-dir = [] +fs-read-file = [] +fs-read-dir = [] +fs-remove-dir = [] +fs-remove-file = [] +fs-rename-file = [] +fs-write-file = [] +global-shortcut-all = [] +http-all = ["http-request"] +http-request = ["http-api"] +notification-all = ["notification", "dialog-ask"] +os-all = ["os_info"] +path-all = [] +process-all = ["process-relaunch", "process-exit"] +process-exit = [] +process-relaunch = [] +process-relaunch-dangerous-allow-symlink-macos = ["tauri-utils/process-relaunch-dangerous-allow-symlink-macos"] +protocol-all = ["protocol-asset"] +protocol-asset = [] +shell-all = ["shell-execute", "shell-sidecar", "shell-open"] +shell-execute = ["command", "regex", "tauri-macros/shell-scope"] +shell-sidecar = ["command", "regex", "tauri-macros/shell-scope"] +shell-open = ["shell-open-api"] +window-all = [ + "window-create", + "window-center", + "window-request-user-attention", + "window-set-resizable", + "window-set-title", + "window-maximize", + "window-unmaximize", + "window-minimize", + "window-unminimize", + "window-show", + "window-hide", + "window-close", + "window-set-decorations", + "window-set-always-on-top", + "window-set-size", + "window-set-min-size", + "window-set-max-size", + "window-set-position", + "window-set-fullscreen", + "window-set-focus", + "window-set-icon", + "window-set-skip-taskbar", + "window-start-dragging", + "window-print", ] -updater = [ "minisign-verify", "base64" ] -system-tray = [ "tauri-runtime/system-tray", "tauri-runtime-wry/system-tray" ] -reqwest-client = [ "reqwest", "bytes" ] -fs-all = [ "fs-write-binary-file" ] -fs-read-text-file = [ ] -fs-read-binary-file = [ ] -fs-write-file = [ ] -fs-write-binary-file = [ "base64" ] -fs-read-dir = [ ] -fs-copy-file = [ ] -fs-create-dir = [ ] -fs-remove-dir = [ ] -fs-remove-file = [ ] -fs-rename-file = [ ] -path-all = [ ] -window-all = [ ] window-create = [ ] -shell-all = [ "shell-open", "shell-execute" ] -shell-execute = [ "shared_child", "os_pipe" ] -shell-open = [ "open" ] -dialog-all = [ "dialog-open", "dialog-save" ] -dialog-open = [ ] -dialog-save = [ ] -http-all = [ ] -http-request = [ ] -notification-all = [ "notify-rust" ] -global-shortcut-all = [ ] -os-all = [ "os_info" ] +window-center = [ ] +window-request-user-attention = [ ] +window-set-resizable = [ ] +window-set-title = [ ] +window-maximize = [ ] +window-unmaximize = [ ] +window-minimize = [ ] +window-unminimize = [ ] +window-show = [ ] +window-hide = [ ] +window-close = [ ] +window-set-decorations = [ ] +window-set-always-on-top = [ ] +window-set-size = [ ] +window-set-min-size = [ ] +window-set-max-size = [ ] +window-set-position = [ ] +window-set-fullscreen = [ ] +window-set-focus = [ ] +window-set-icon = [ ] +window-set-skip-taskbar = [ ] +window-start-dragging = [ ] +window-print = [ ] + +# features unrelated to api/endpoints +config-json5 = [ "tauri-macros/config-json5" ] [[example]] name = "commands" @@ -148,10 +246,12 @@ path = "../../examples/helloworld/src-tauri/src/main.rs" [[example]] name = "multiwindow" path = "../../examples/multiwindow/src-tauri/src/main.rs" +required-features = [ "window-create" ] [[example]] name = "navigation" path = "../../examples/navigation/src-tauri/src/main.rs" +required-features = [ "window-create" ] [[example]] name = "splashscreen" @@ -161,10 +261,11 @@ path = "../../examples/splashscreen/src-tauri/src/main.rs" name = "state" path = "../../examples/state/src-tauri/src/main.rs" -[[example]] -name = "resources" -path = "../../examples/resources/src-tauri/src/main.rs" - [[example]] name = "streaming" path = "../../examples/streaming/src-tauri/src/main.rs" + +[[example]] +name = "isolation" +path = "../../examples/isolation/src-tauri/src/main.rs" +required-features = [ "isolation" ] diff --git a/core/tauri/build.rs b/core/tauri/build.rs index c95793273ad7..db4d11d16583 100644 --- a/core/tauri/build.rs +++ b/core/tauri/build.rs @@ -13,8 +13,7 @@ fn main() { // fs fs_all: { any(api_all, feature = "fs-all") }, - fs_read_text_file: { any(fs_all, feature = "fs-read-text-file") }, - fs_read_binary_file: { any(fs_all, feature = "fs-read-binary-file") }, + fs_read_file: { any(fs_all, feature = "fs-read-file") }, fs_write_file: { any(fs_all, feature = "fs-write-file") }, fs_write_binary_file: { any(fs_all, feature = "fs-write-binary-file") }, fs_read_dir: { any(fs_all, feature = "fs-read-dir") }, @@ -27,16 +26,45 @@ fn main() { // window window_all: { any(api_all, feature = "window-all") }, window_create: { any(window_all, feature = "window-create") }, + window_center: { any(window_all, feature = "window-center") }, + window_request_user_attention: { any(window_all, feature = "window-request-user-attention") }, + window_set_resizable: { any(window_all, feature = "window-set-resizable") }, + window_set_title: { any(window_all, feature = "window-set-title") }, + window_maximize: { any(window_all, feature = "window-maximize") }, + window_unmaximize: { any(window_all, feature = "window-unmaximize") }, + window_minimize: { any(window_all, feature = "window-minimize") }, + window_unminimize: { any(window_all, feature = "window-unminimize") }, + window_show: { any(window_all, feature = "window-show") }, + window_hide: { any(window_all, feature = "window-hide") }, + window_close: { any(window_all, feature = "window-close") }, + window_set_decorations: { any(window_all, feature = "window-set-decorations") }, + window_set_always_on_top: { any(window_all, feature = "window-set-always-on-top") }, + window_set_size: { any(window_all, feature = "window-set-size") }, + window_set_min_size: { any(window_all, feature = "window-set-min-size") }, + window_set_max_size: { any(window_all, feature = "window-set-max-size") }, + window_set_position: { any(window_all, feature = "window-set-position") }, + window_set_fullscreen: { any(window_all, feature = "window-set-fullscreen") }, + window_set_focus: { any(window_all, feature = "window-set-focus") }, + window_set_icon: { any(window_all, feature = "window-set-icon") }, + window_set_skip_taskbar: { any(window_all, feature = "window-set-skip-taskbar") }, + window_start_dragging: { any(window_all, feature = "window-start-dragging") }, + window_print: { any(window_all, feature = "window-print") }, // shell shell_all: { any(api_all, feature = "shell-all") }, - shell_open: { any(shell_all, feature = "shell-open") }, shell_execute: { any(shell_all, feature = "shell-execute") }, + shell_sidecar: { any(shell_all, feature = "shell-sidecar") }, + shell_open: { any(shell_all, feature = "shell-open") }, + // helper for the shell scope functionality + shell_scope: { any(shell_execute, shell_sidecar, feature = "shell-open-api") }, // dialog dialog_all: { any(api_all, feature = "dialog-all") }, dialog_open: { any(dialog_all, feature = "dialog-open") }, dialog_save: { any(dialog_all, feature = "dialog-save") }, + dialog_message: { any(dialog_all, feature = "dialog-message") }, + dialog_ask: { any(dialog_all, feature = "dialog-ask") }, + dialog_confirm: { any(dialog_all, feature = "dialog-confirm") }, // http http_all: { any(api_all, feature = "http-all") }, @@ -56,5 +84,20 @@ fn main() { // path path_all: { any(api_all, feature = "path-all") }, + + // protocol + protocol_all: { any(api_all, feature = "protocol-all") }, + protocol_asset: { any(protocol_all, feature = "protocol-asset") }, + + // process + process_all: { any(api_all, feature = "process-all") }, + process_relaunch: { any(protocol_all, feature = "process-relaunch") }, + process_relaunch_dangerous_allow_symlink_macos: { feature = "process-relaunch-dangerous-allow-symlink-macos" }, + process_exit: { any(protocol_all, feature = "process-exit") }, + + // clipboard + clipboard_all: { any(api_all, feature = "clipboard-all") }, + clipboard_write_text: { any(protocol_all, feature = "clipboard-write-text") }, + clipboard_read_text: { any(protocol_all, feature = "clipboard-read-text") }, } } diff --git a/core/tauri/scripts/bundle.js b/core/tauri/scripts/bundle.js index c5dc1841790c..204f81f47ec7 100644 --- a/core/tauri/scripts/bundle.js +++ b/core/tauri/scripts/bundle.js @@ -1 +1 @@ -function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&_setPrototypeOf(e,t)}function _setPrototypeOf(e,t){return(_setPrototypeOf=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function _createSuper(e){var t=_isNativeReflectConstruct();return function(){var r,n=_getPrototypeOf(e);if(t){var a=_getPrototypeOf(this).constructor;r=Reflect.construct(n,arguments,a)}else r=n.apply(this,arguments);return _possibleConstructorReturn(this,r)}}function _possibleConstructorReturn(e,t){return!t||"object"!==_typeof(t)&&"function"!=typeof t?_assertThisInitialized(e):t}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _isNativeReflectConstruct(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function _getPrototypeOf(e){return(_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function _createForOfIteratorHelper(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!r){if(Array.isArray(e)||(r=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,a=function(){};return{s:a,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i=!0,u=!1;return{s:function(){r=r.call(e)},n:function(){var e=r.next();return i=e.done,e},e:function(e){u=!0,o=e},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw o}}}}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0;--o){var i=this.tryEntries[o],u=i.completion;if("root"===i.tryLoc)return a("end");if(i.tryLoc<=this.prev){var s=n.call(i,"catchLoc"),c=n.call(i,"finallyLoc");if(s&&c){if(this.prev=0;--r){var a=this.tryEntries[r];if(a.tryLoc<=this.prev&&n.call(a,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),P(r),d}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var a=n.arg;P(r)}return a}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:O(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),d}},e}("object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports:{});try{regeneratorRuntime=t}catch(e){"object"===("undefined"==typeof globalThis?"undefined":_typeof(globalThis))?globalThis.regeneratorRuntime=t:Function("r","regeneratorRuntime = r")(t)}function r(e){for(var t=void 0,r=e[0],n=1;n1&&void 0!==arguments[1]&&arguments[1],a=n();return Object.defineProperty(window,a,{value:function(n){return t&&Reflect.deleteProperty(window,a),r([e,"optionalCall",function(e){return e(n)}])},writable:!1,configurable:!0}),a}function o(e){return i.apply(this,arguments)}function i(){return(i=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",new Promise((function(e,n){var o=a((function(t){e(t),Reflect.deleteProperty(window,i)}),!0),i=a((function(e){n(e),Reflect.deleteProperty(window,o)}),!0);window.rpc.notify(t,_objectSpread({__invokeKey:__TAURI_INVOKE_KEY__,callback:o,error:i},r))})));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var u=Object.freeze({__proto__:null,transformCallback:a,invoke:o,convertFileSrc:function(e){return navigator.userAgent.includes("Windows")?"https://asset.localhost/".concat(e):"asset://".concat(e)}});function s(e){return c.apply(this,arguments)}function c(){return(c=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",o("tauri",t));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function p(){return(p=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"App",message:{cmd:"getAppVersion"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function l(){return(l=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"App",message:{cmd:"getAppName"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function f(){return(f=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"App",message:{cmd:"getTauriVersion"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var h=Object.freeze({__proto__:null,getName:function(){return l.apply(this,arguments)},getVersion:function(){return p.apply(this,arguments)},getTauriVersion:function(){return f.apply(this,arguments)}});function m(){return(m=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Cli",message:{cmd:"cliMatches"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var d=Object.freeze({__proto__:null,getMatches:function(){return m.apply(this,arguments)}});function y(){return(y=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Clipboard",message:{cmd:"writeText",data:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function g(){return(g=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Clipboard",message:{cmd:"readText"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var _=Object.freeze({__proto__:null,writeText:function(e){return y.apply(this,arguments)},readText:function(){return g.apply(this,arguments)}});function v(){return(v=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t,r=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return"object"===_typeof(t=r.length>0&&void 0!==r[0]?r[0]:{})&&Object.freeze(t),e.abrupt("return",s({__tauriModule:"Dialog",message:{cmd:"openDialog",options:t}}));case 3:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function w(){return(w=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t,r=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return"object"===_typeof(t=r.length>0&&void 0!==r[0]?r[0]:{})&&Object.freeze(t),e.abrupt("return",s({__tauriModule:"Dialog",message:{cmd:"saveDialog",options:t}}));case 3:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var b=Object.freeze({__proto__:null,open:function(){return v.apply(this,arguments)},save:function(){return w.apply(this,arguments)}});function R(e,t,r){return k.apply(this,arguments)}function k(){return(k=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,s({__tauriModule:"Event",message:{cmd:"emit",event:t,windowLabel:r,payload:n}});case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function x(e){return T.apply(this,arguments)}function T(){return(T=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Event",message:{cmd:"unlisten",eventId:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function G(e,t){return P.apply(this,arguments)}function P(){return(P=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Event",message:{cmd:"listen",event:t,handler:a(r)}}).then((function(e){return _asyncToGenerator(regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.abrupt("return",x(e));case 1:case"end":return t.stop()}}),t)})))})));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function M(e,t){return O.apply(this,arguments)}function O(){return(O=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",G(t,(function(e){r(e),x(e.id).catch((function(){}))})));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function C(e,t){return j.apply(this,arguments)}function j(){return(j=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",R(t,void 0,r));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var S,A=Object.freeze({__proto__:null,listen:G,once:M,emit:C});function z(){return(z=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"readTextFile",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function D(){return(D=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"readBinaryFile",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function L(){return(L=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return"object"===_typeof(r=n.length>1&&void 0!==n[1]?n[1]:{})&&Object.freeze(r),"object"===_typeof(t)&&Object.freeze(t),e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"writeFile",path:t.path,contents:t.contents,options:r}}));case 4:case"end":return e.stop()}}),e)})))).apply(this,arguments)}!function(e){e[e.Audio=1]="Audio";e[e.Cache=2]="Cache";e[e.Config=3]="Config";e[e.Data=4]="Data";e[e.LocalData=5]="LocalData";e[e.Desktop=6]="Desktop";e[e.Document=7]="Document";e[e.Download=8]="Download";e[e.Executable=9]="Executable";e[e.Font=10]="Font";e[e.Home=11]="Home";e[e.Picture=12]="Picture";e[e.Public=13]="Public";e[e.Runtime=14]="Runtime";e[e.Template=15]="Template";e[e.Video=16]="Video";e[e.Resource=17]="Resource";e[e.App=18]="App";e[e.Current=19]="Current"}(S||(S={}));var E=65536;function F(e){var t=function(e){if(e.length1&&void 0!==n[1]?n[1]:{})&&Object.freeze(r),"object"===_typeof(t)&&Object.freeze(t),e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"writeBinaryFile",path:t.path,contents:F(t.contents),options:r}}));case 4:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function I(){return(I=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"readDir",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function N(){return(N=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"createDir",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function U(){return(U=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"removeDir",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function B(){return(B=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){var n,a=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=a.length>2&&void 0!==a[2]?a[2]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"copyFile",source:t,destination:r,options:n}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function V(){return(V=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"removeFile",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function q(){return(q=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){var n,a=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=a.length>2&&void 0!==a[2]?a[2]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"renameFile",oldPath:t,newPath:r,options:n}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var H=Object.freeze({__proto__:null,get BaseDirectory(){return S},get Dir(){return S},readTextFile:function(e){return z.apply(this,arguments)},readBinaryFile:function(e){return D.apply(this,arguments)},writeFile:function(e){return L.apply(this,arguments)},writeBinaryFile:function(e){return W.apply(this,arguments)},readDir:function(e){return I.apply(this,arguments)},createDir:function(e){return N.apply(this,arguments)},removeDir:function(e){return U.apply(this,arguments)},copyFile:function(e,t){return B.apply(this,arguments)},removeFile:function(e){return V.apply(this,arguments)},renameFile:function(e,t){return q.apply(this,arguments)}});function J(){return(J=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"register",shortcut:t,handler:a(r)}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function K(){return(K=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"registerAll",shortcuts:t,handler:a(r)}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Y(){return(Y=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"isRegistered",shortcut:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function $(){return($=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"unregister",shortcut:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Q(){return(Q=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"unregisterAll"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var X,Z=Object.freeze({__proto__:null,register:function(e,t){return J.apply(this,arguments)},registerAll:function(e,t){return K.apply(this,arguments)},isRegistered:function(e){return Y.apply(this,arguments)},unregister:function(e){return $.apply(this,arguments)},unregisterAll:function(){return Q.apply(this,arguments)}});function ee(e,t){return null!=e?e:t()}function te(e){for(var t=void 0,r=e[0],n=1;n=200&&this.status<300,this.headers=t.headers,this.data=t.data},ae=function(){function e(t){_classCallCheck(this,e),this.id=t}var t,r,n,a,o,i,u;return _createClass(e,[{key:"drop",value:(u=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Http",message:{cmd:"dropClient",client:this.id}}));case 1:case"end":return e.stop()}}),e,this)}))),function(){return u.apply(this,arguments)})},{key:"request",value:(i=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return(r=!t.responseType||t.responseType===X.JSON)&&(t.responseType=X.Text),e.abrupt("return",s({__tauriModule:"Http",message:{cmd:"httpRequest",client:this.id,options:t}}).then((function(e){var t=new ne(e);if(r){try{t.data=JSON.parse(t.data)}catch(e){if(t.ok)throw Error("Failed to parse response `".concat(t.data,"` as JSON: ").concat(e,";\n try setting the `responseType` option to `ResponseType.Text` or `ResponseType.Binary` if the API does not return a JSON response."))}return t}return t})));case 3:case"end":return e.stop()}}),e,this)}))),function(e){return i.apply(this,arguments)})},{key:"get",value:(o=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"GET",url:t},r)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t){return o.apply(this,arguments)})},{key:"post",value:(a=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"POST",url:t,body:r},n)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t,r){return a.apply(this,arguments)})},{key:"put",value:(n=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"PUT",url:t,body:r},n)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t,r){return n.apply(this,arguments)})},{key:"patch",value:(r=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"PATCH",url:t},r)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t){return r.apply(this,arguments)})},{key:"delete",value:(t=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"DELETE",url:t},r)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,r){return t.apply(this,arguments)})}]),e}();function oe(e){return ie.apply(this,arguments)}function ie(){return(ie=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Http",message:{cmd:"createClient",options:t}}).then((function(e){return new ae(e)})));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var ue=null;function se(){return(se=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!==ue){e.next=4;break}return e.next=3,oe();case 3:ue=e.sent;case 4:return e.abrupt("return",ue.request(_objectSpread({url:t,method:ee(te([r,"optionalAccess",function(e){return e.method}]),(function(){return"GET"}))},r)));case 5:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var ce=Object.freeze({__proto__:null,getClient:oe,fetch:function(e,t){return se.apply(this,arguments)},Body:re,Client:ae,Response:ne,get ResponseType(){return X}});function pe(){return(pe=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if("default"===window.Notification.permission){e.next=2;break}return e.abrupt("return",Promise.resolve("granted"===window.Notification.permission));case 2:return e.abrupt("return",s({__tauriModule:"Notification",message:{cmd:"isNotificationPermissionGranted"}}));case 3:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function le(){return(le=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",window.Notification.requestPermission());case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var fe=Object.freeze({__proto__:null,sendNotification:function(e){"string"==typeof e?new window.Notification(e):new window.Notification(e.title,e)},requestPermission:function(){return le.apply(this,arguments)},isPermissionGranted:function(){return pe.apply(this,arguments)}});function he(){return navigator.appVersion.includes("Win")}function me(){return(me=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.App}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function de(){return(de=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Audio}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ye(){return(ye=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Cache}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ge(){return(ge=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Config}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function _e(){return(_e=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Data}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ve(){return(ve=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Desktop}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function we(){return(we=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Document}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function be(){return(be=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Download}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Re(){return(Re=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Executable}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ke(){return(ke=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Font}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function xe(){return(xe=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Home}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Te(){return(Te=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.LocalData}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ge(){return(Ge=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Picture}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Pe(){return(Pe=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Public}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Me(){return(Me=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Resource}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Oe(){return(Oe=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Runtime}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ce(){return(Ce=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Template}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function je(){return(je=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Video}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Se(){return(Se=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:S.Current}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var Ae=he()?"\\":"/",ze=he()?";":":";function De(){return(De=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t,r,n,a=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:for(t=a.length,r=new Array(t),n=0;n0&&void 0!==r[0]?r[0]:0,e.abrupt("return",s({__tauriModule:"Process",message:{cmd:"exit",exitCode:t}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ve(){return(Ve=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Process",message:{cmd:"relaunch"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var qe=Object.freeze({__proto__:null,exit:function(){return Be.apply(this,arguments)},relaunch:function(){return Ve.apply(this,arguments)}});function He(e,t){return null!=e?e:t()}function Je(e,t,r,n){return Ke.apply(this,arguments)}function Ke(){return(Ke=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n,o){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return"object"===_typeof(n)&&Object.freeze(n),e.abrupt("return",s({__tauriModule:"Shell",message:{cmd:"execute",program:r,args:"string"==typeof n?[n]:n,options:o,onEventFn:a(t)}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var Ye=function(){function e(){_classCallCheck(this,e),e.prototype.__init.call(this)}return _createClass(e,[{key:"__init",value:function(){this.eventListeners=Object.create(null)}},{key:"addEventListener",value:function(e,t){e in this.eventListeners?this.eventListeners[e].push(t):this.eventListeners[e]=[t]}},{key:"_emit",value:function(e,t){if(e in this.eventListeners){var r,n=_createForOfIteratorHelper(this.eventListeners[e]);try{for(n.s();!(r=n.n()).done;){(0,r.value)(t)}}catch(e){n.e(e)}finally{n.f()}}}},{key:"on",value:function(e,t){return this.addEventListener(e,t),this}}]),e}(),$e=function(){function e(t){_classCallCheck(this,e),this.pid=t}var t,r;return _createClass(e,[{key:"write",value:(r=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Shell",message:{cmd:"stdinWrite",pid:this.pid,buffer:t}}));case 1:case"end":return e.stop()}}),e,this)}))),function(e){return r.apply(this,arguments)})},{key:"kill",value:(t=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Shell",message:{cmd:"killChild",pid:this.pid}}));case 1:case"end":return e.stop()}}),e,this)}))),function(){return t.apply(this,arguments)})}]),e}(),Qe=function(e){_inherits(a,e);var t,r,n=_createSuper(a);function a(e){var t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o=arguments.length>2?arguments[2]:void 0;return _classCallCheck(this,a),t=n.call(this),a.prototype.__init2.call(_assertThisInitialized(t)),a.prototype.__init3.call(_assertThisInitialized(t)),t.program=e,t.args="string"==typeof r?[r]:r,t.options=He(o,(function(){return{}})),t}return _createClass(a,[{key:"__init2",value:function(){this.stdout=new Ye}},{key:"__init3",value:function(){this.stderr=new Ye}},{key:"spawn",value:(r=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",Je((function(e){switch(e.event){case"Error":t._emit("error",e.payload);break;case"Terminated":t._emit("close",e.payload);break;case"Stdout":t.stdout._emit("data",e.payload);break;case"Stderr":t.stderr._emit("data",e.payload)}}),this.program,this.args,this.options).then((function(e){return new $e(e)})));case 1:case"end":return e.stop()}}),e,this)}))),function(){return r.apply(this,arguments)})},{key:"execute",value:(t=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",new Promise((function(e,r){t.on("error",r);var n=[],a=[];t.stdout.on("data",(function(e){n.push(e)})),t.stderr.on("data",(function(e){a.push(e)})),t.on("close",(function(t){e({code:t.code,signal:t.signal,stdout:n.join("\n"),stderr:a.join("\n")})})),t.spawn().catch(r)})));case 1:case"end":return e.stop()}}),e)}))),function(){return t.apply(this,arguments)})}],[{key:"sidecar",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=arguments.length>2?arguments[2]:void 0,n=new a(e,t,r);return n.options.sidecar=!0,n}}]),a}(Ye);function Xe(){return(Xe=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Shell",message:{cmd:"open",path:t,with:r}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var Ze=Object.freeze({__proto__:null,Command:Qe,Child:$e,open:function(e,t){return Xe.apply(this,arguments)}});function et(e){for(var t=void 0,r=e[0],n=1;n1&&void 0!==arguments[1]?arguments[1]:{};return _classCallCheck(this,r),n=t.call(this,e),at([a,"optionalAccess",function(e){return e.skip}])||s({__tauriModule:"Window",message:{cmd:"createWebview",data:{options:_objectSpread({label:e},a)}}}).then(_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",n.emit("tauri://created"));case 1:case"end":return e.stop()}}),e)})))).catch(function(){var e=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",n.emit("tauri://error",t));case 1:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),n}return _createClass(r,null,[{key:"getByLabel",value:function(e){return pt().some((function(t){return t.label===e}))?new r(e,{skip:!0}):null}}]),r}(ht),dt=new mt(null,{skip:!0});function yt(){return(yt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"currentMonitor"}}}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function gt(){return(gt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"primaryMonitor"}}}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function _t(){return(_t=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"availableMonitors"}}}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var vt=Object.freeze({__proto__:null,WebviewWindow:mt,WebviewWindowHandle:ft,WindowManager:ht,getCurrent:function(){return new mt(window.__TAURI__.__currentWindow.label,{skip:!0})},getAll:pt,appWindow:dt,LogicalSize:it,PhysicalSize:ut,LogicalPosition:st,PhysicalPosition:ct,get UserAttentionType(){return ot},currentMonitor:function(){return yt.apply(this,arguments)},primaryMonitor:function(){return gt.apply(this,arguments)},availableMonitors:function(){return _t.apply(this,arguments)}}),wt=he()?"\r\n":"\n";function bt(){return(bt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"platform"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Rt(){return(Rt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"version"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function kt(){return(kt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"type"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function xt(){return(xt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"arch"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Tt(){return(Tt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"tempdir"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var Gt=Object.freeze({__proto__:null,EOL:wt,platform:function(){return bt.apply(this,arguments)},version:function(){return Rt.apply(this,arguments)},type:function(){return kt.apply(this,arguments)},arch:function(){return xt.apply(this,arguments)},tempdir:function(){return Tt.apply(this,arguments)}}),Pt=o;e.app=h,e.cli=d,e.clipboard=_,e.dialog=b,e.event=A,e.fs=H,e.globalShortcut=Z,e.http=ce,e.invoke=Pt,e.notification=fe,e.os=Gt,e.path=Ue,e.process=qe,e.shell=Ze,e.tauri=u,e.updater=nt,e.window=vt,Object.defineProperty(e,"__esModule",{value:!0})})); +function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&_setPrototypeOf(e,t)}function _setPrototypeOf(e,t){return(_setPrototypeOf=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function _createSuper(e){var t=_isNativeReflectConstruct();return function(){var r,n=_getPrototypeOf(e);if(t){var a=_getPrototypeOf(this).constructor;r=Reflect.construct(n,arguments,a)}else r=n.apply(this,arguments);return _possibleConstructorReturn(this,r)}}function _possibleConstructorReturn(e,t){if(t&&("object"===_typeof(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return _assertThisInitialized(e)}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _isNativeReflectConstruct(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function _getPrototypeOf(e){return(_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function _createForOfIteratorHelper(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!r){if(Array.isArray(e)||(r=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,a=function(){};return{s:a,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i=!0,u=!1;return{s:function(){r=r.call(e)},n:function(){var e=r.next();return i=e.done,e},e:function(e){u=!0,o=e},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw o}}}}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0;--o){var i=this.tryEntries[o],u=i.completion;if("root"===i.tryLoc)return a("end");if(i.tryLoc<=this.prev){var s=n.call(i,"catchLoc"),c=n.call(i,"finallyLoc");if(s&&c){if(this.prev=0;--r){var a=this.tryEntries[r];if(a.tryLoc<=this.prev&&n.call(a,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),P(r),d}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var a=n.arg;P(r)}return a}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:O(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),d}},e}("object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports:{});try{regeneratorRuntime=t}catch(e){"object"===("undefined"==typeof globalThis?"undefined":_typeof(globalThis))?globalThis.regeneratorRuntime=t:Function("r","regeneratorRuntime = r")(t)}function r(e){for(var t=void 0,r=e[0],n=1;n1&&void 0!==arguments[1]&&arguments[1],a=n(),o="_".concat(a);return Object.defineProperty(window,o,{value:function(n){return t&&Reflect.deleteProperty(window,o),r([e,"optionalCall",function(e){return e(n)}])},writable:!1,configurable:!0}),a}function o(e){return i.apply(this,arguments)}function i(){return(i=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",new Promise((function(e,n){var o=a((function(t){e(t),Reflect.deleteProperty(window,i)}),!0),i=a((function(e){n(e),Reflect.deleteProperty(window,o)}),!0);window.__TAURI_IPC__(_objectSpread({cmd:t,callback:o,error:i},r))})));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var u=Object.freeze({__proto__:null,transformCallback:a,invoke:o,convertFileSrc:function(e){return navigator.userAgent.includes("Windows")?"https://asset.localhost/".concat(e):"asset://".concat(e)}});function s(e){return c.apply(this,arguments)}function c(){return(c=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",o("tauri",t));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function p(){return(p=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"App",message:{cmd:"getAppVersion"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function l(){return(l=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"App",message:{cmd:"getAppName"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function f(){return(f=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"App",message:{cmd:"getTauriVersion"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var h=Object.freeze({__proto__:null,getName:function(){return l.apply(this,arguments)},getVersion:function(){return p.apply(this,arguments)},getTauriVersion:function(){return f.apply(this,arguments)}});function m(){return(m=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Cli",message:{cmd:"cliMatches"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var d=Object.freeze({__proto__:null,getMatches:function(){return m.apply(this,arguments)}});function y(){return(y=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Clipboard",message:{cmd:"writeText",data:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function g(){return(g=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Clipboard",message:{cmd:"readText"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var _=Object.freeze({__proto__:null,writeText:function(e){return y.apply(this,arguments)},readText:function(){return g.apply(this,arguments)}});function w(){return(w=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t,r=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return"object"===_typeof(t=r.length>0&&void 0!==r[0]?r[0]:{})&&Object.freeze(t),e.abrupt("return",s({__tauriModule:"Dialog",message:{cmd:"openDialog",options:t}}));case 3:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function v(){return(v=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t,r=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return"object"===_typeof(t=r.length>0&&void 0!==r[0]?r[0]:{})&&Object.freeze(t),e.abrupt("return",s({__tauriModule:"Dialog",message:{cmd:"saveDialog",options:t}}));case 3:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function b(){return(b=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Dialog",message:{cmd:"messageDialog",message:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function R(){return(R=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Dialog",message:{cmd:"askDialog",title:r,message:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function k(){return(k=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Dialog",message:{cmd:"confirmDialog",title:r,message:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var x=Object.freeze({__proto__:null,open:function(){return w.apply(this,arguments)},save:function(){return v.apply(this,arguments)},message:function(e){return b.apply(this,arguments)},ask:function(e,t){return R.apply(this,arguments)},confirm:function(e,t){return k.apply(this,arguments)}});function T(e){return G.apply(this,arguments)}function G(){return(G=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Event",message:{cmd:"unlisten",eventId:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function P(e,t,r){return M.apply(this,arguments)}function M(){return(M=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,s({__tauriModule:"Event",message:{cmd:"emit",event:t,windowLabel:r,payload:"string"==typeof n?n:JSON.stringify(n)}});case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function O(e,t,r){return j.apply(this,arguments)}function j(){return(j=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Event",message:{cmd:"listen",event:t,windowLabel:r,handler:a(n)}}).then((function(e){return _asyncToGenerator(regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.abrupt("return",T(e));case 1:case"end":return t.stop()}}),t)})))})));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function A(e,t,r){return C.apply(this,arguments)}function C(){return(C=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",O(t,r,(function(e){n(e),T(e.id).catch((function(){}))})));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function S(e,t){return D.apply(this,arguments)}function D(){return(D=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",O(t,null,r));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function z(e,t){return L.apply(this,arguments)}function L(){return(L=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",A(t,null,r));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function E(e,t){return W.apply(this,arguments)}function W(){return(W=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",P(t,void 0,r));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var F,I=Object.freeze({__proto__:null,listen:S,once:z,emit:E});function N(){return(N=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"readFile",path:t,options:r}}).then((function(e){return(new TextDecoder).decode(new Uint8Array(e))})));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function U(){return(U=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n,a=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=a.length>1&&void 0!==a[1]?a[1]:{},e.next=3,s({__tauriModule:"Fs",message:{cmd:"readFile",path:t,options:r}});case 3:return n=e.sent,e.abrupt("return",Uint8Array.from(n));case 5:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function H(){return(H=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return"object"===_typeof(r=n.length>1&&void 0!==n[1]?n[1]:{})&&Object.freeze(r),"object"===_typeof(t)&&Object.freeze(t),e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"writeFile",path:t.path,contents:Array.from((new TextEncoder).encode(t.contents)),options:r}}));case 4:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function q(){return(q=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return"object"===_typeof(r=n.length>1&&void 0!==n[1]?n[1]:{})&&Object.freeze(r),"object"===_typeof(t)&&Object.freeze(t),e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"writeFile",path:t.path,contents:Array.from(t.contents),options:r}}));case 4:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function B(){return(B=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"readDir",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function V(){return(V=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"createDir",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function J(){return(J=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"removeDir",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function K(){return(K=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){var n,a=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=a.length>2&&void 0!==a[2]?a[2]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"copyFile",source:t,destination:r,options:n}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Y(){return(Y=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r,n=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=n.length>1&&void 0!==n[1]?n[1]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"removeFile",path:t,options:r}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function $(){return($=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){var n,a=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=a.length>2&&void 0!==a[2]?a[2]:{},e.abrupt("return",s({__tauriModule:"Fs",message:{cmd:"renameFile",oldPath:t,newPath:r,options:n}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}!function(e){e[e.Audio=1]="Audio";e[e.Cache=2]="Cache";e[e.Config=3]="Config";e[e.Data=4]="Data";e[e.LocalData=5]="LocalData";e[e.Desktop=6]="Desktop";e[e.Document=7]="Document";e[e.Download=8]="Download";e[e.Executable=9]="Executable";e[e.Font=10]="Font";e[e.Home=11]="Home";e[e.Picture=12]="Picture";e[e.Public=13]="Public";e[e.Runtime=14]="Runtime";e[e.Template=15]="Template";e[e.Video=16]="Video";e[e.Resource=17]="Resource";e[e.App=18]="App";e[e.Log=19]="Log"}(F||(F={}));var Q=Object.freeze({__proto__:null,get BaseDirectory(){return F},get Dir(){return F},readTextFile:function(e){return N.apply(this,arguments)},readBinaryFile:function(e){return U.apply(this,arguments)},writeFile:function(e){return H.apply(this,arguments)},writeBinaryFile:function(e){return q.apply(this,arguments)},readDir:function(e){return B.apply(this,arguments)},createDir:function(e){return V.apply(this,arguments)},removeDir:function(e){return J.apply(this,arguments)},copyFile:function(e,t){return K.apply(this,arguments)},removeFile:function(e){return Y.apply(this,arguments)},renameFile:function(e,t){return $.apply(this,arguments)}});function X(){return(X=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"register",shortcut:t,handler:a(r)}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Z(){return(Z=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"registerAll",shortcuts:t,handler:a(r)}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ee(){return(ee=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"isRegistered",shortcut:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function te(){return(te=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"unregister",shortcut:t}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function re(){return(re=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"GlobalShortcut",message:{cmd:"unregisterAll"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var ne,ae=Object.freeze({__proto__:null,register:function(e,t){return X.apply(this,arguments)},registerAll:function(e,t){return Z.apply(this,arguments)},isRegistered:function(e){return ee.apply(this,arguments)},unregister:function(e){return te.apply(this,arguments)},unregisterAll:function(){return re.apply(this,arguments)}});function oe(e,t){return null!=e?e:t()}function ie(e){for(var t=void 0,r=e[0],n=1;n=200&&this.status<300,this.headers=t.headers,this.rawHeaders=t.rawHeaders,this.data=t.data})),ce=function(){function e(t){_classCallCheck(this,e),this.id=t}var t,r,n,a,o,i,u;return _createClass(e,[{key:"drop",value:(u=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Http",message:{cmd:"dropClient",client:this.id}}));case 1:case"end":return e.stop()}}),e,this)}))),function(){return u.apply(this,arguments)})},{key:"request",value:(i=_asyncToGenerator(regeneratorRuntime.mark((function e(t){var r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return(r=!t.responseType||t.responseType===ne.JSON)&&(t.responseType=ne.Text),e.abrupt("return",s({__tauriModule:"Http",message:{cmd:"httpRequest",client:this.id,options:t}}).then((function(e){var t=new se(e);if(r){try{t.data=JSON.parse(t.data)}catch(e){if(t.ok&&""===t.data)t.data={};else if(t.ok)throw Error("Failed to parse response `".concat(t.data,"` as JSON: ").concat(e,";\n try setting the `responseType` option to `ResponseType.Text` or `ResponseType.Binary` if the API does not return a JSON response."))}return t}return t})));case 3:case"end":return e.stop()}}),e,this)}))),function(e){return i.apply(this,arguments)})},{key:"get",value:(o=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"GET",url:t},r)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t){return o.apply(this,arguments)})},{key:"post",value:(a=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"POST",url:t,body:r},n)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t,r){return a.apply(this,arguments)})},{key:"put",value:(n=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r,n){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"PUT",url:t,body:r},n)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t,r){return n.apply(this,arguments)})},{key:"patch",value:(r=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"PATCH",url:t},r)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,t){return r.apply(this,arguments)})},{key:"delete",value:(t=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",this.request(_objectSpread({method:"DELETE",url:t},r)));case 1:case"end":return e.stop()}}),e,this)}))),function(e,r){return t.apply(this,arguments)})}]),e}();function pe(e){return le.apply(this,arguments)}function le(){return(le=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Http",message:{cmd:"createClient",options:t}}).then((function(e){return new ce(e)})));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var fe=null;function he(){return(he=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!==fe){e.next=4;break}return e.next=3,pe();case 3:fe=e.sent;case 4:return e.abrupt("return",fe.request(_objectSpread({url:t,method:oe(ie([r,"optionalAccess",function(e){return e.method}]),(function(){return"GET"}))},r)));case 5:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var me=Object.freeze({__proto__:null,getClient:pe,fetch:function(e,t){return he.apply(this,arguments)},Body:ue,Client:ce,Response:se,get ResponseType(){return ne}});function de(){return(de=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if("default"===window.Notification.permission){e.next=2;break}return e.abrupt("return",Promise.resolve("granted"===window.Notification.permission));case 2:return e.abrupt("return",s({__tauriModule:"Notification",message:{cmd:"isNotificationPermissionGranted"}}));case 3:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ye(){return(ye=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",window.Notification.requestPermission());case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var ge=Object.freeze({__proto__:null,sendNotification:function(e){"string"==typeof e?new window.Notification(e):new window.Notification(e.title,e)},requestPermission:function(){return ye.apply(this,arguments)},isPermissionGranted:function(){return de.apply(this,arguments)}});function _e(){return navigator.appVersion.includes("Win")}function we(){return(we=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.App}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ve(){return(ve=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Audio}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function be(){return(be=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Cache}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Re(){return(Re=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Config}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ke(){return(ke=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Data}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function xe(){return(xe=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Desktop}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Te(){return(Te=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Document}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ge(){return(Ge=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Download}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Pe(){return(Pe=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Executable}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Me(){return(Me=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Font}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Oe(){return(Oe=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Home}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function je(){return(je=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.LocalData}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ae(){return(Ae=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Picture}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ce(){return(Ce=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Public}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Se(){return(Se=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Resource}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function De(){return(De=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Runtime}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function ze(){return(ze=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Template}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Le(){return(Le=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Video}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ee(){return(Ee=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:F.Log}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var We=_e()?"\\":"/",Fe=_e()?";":":";function Ie(){return(Ie=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t,r,n,a=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:for(t=a.length,r=new Array(t),n=0;n0&&void 0!==r[0]?r[0]:0,e.abrupt("return",s({__tauriModule:"Process",message:{cmd:"exit",exitCode:t}}));case 2:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ye(){return(Ye=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Process",message:{cmd:"relaunch"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var $e=Object.freeze({__proto__:null,exit:function(){return Ke.apply(this,arguments)},relaunch:function(){return Ye.apply(this,arguments)}});function Qe(e,t){return null!=e?e:t()}function Xe(e,t){return Ze.apply(this,arguments)}function Ze(){return(Ze=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){var n,o,i=arguments;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=i.length>2&&void 0!==i[2]?i[2]:[],o=i.length>3?i[3]:void 0,"object"===_typeof(n)&&Object.freeze(n),e.abrupt("return",s({__tauriModule:"Shell",message:{cmd:"execute",program:r,args:n,options:o,onEventFn:a(t)}}));case 4:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var et=function(){function e(){_classCallCheck(this,e),e.prototype.__init.call(this)}return _createClass(e,[{key:"__init",value:function(){this.eventListeners=Object.create(null)}},{key:"addEventListener",value:function(e,t){e in this.eventListeners?this.eventListeners[e].push(t):this.eventListeners[e]=[t]}},{key:"_emit",value:function(e,t){if(e in this.eventListeners){var r,n=_createForOfIteratorHelper(this.eventListeners[e]);try{for(n.s();!(r=n.n()).done;){(0,r.value)(t)}}catch(e){n.e(e)}finally{n.f()}}}},{key:"on",value:function(e,t){return this.addEventListener(e,t),this}}]),e}(),tt=function(){function e(t){_classCallCheck(this,e),this.pid=t}var t,r;return _createClass(e,[{key:"write",value:(r=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Shell",message:{cmd:"stdinWrite",pid:this.pid,buffer:"string"==typeof t?t:Array.from(t)}}));case 1:case"end":return e.stop()}}),e,this)}))),function(e){return r.apply(this,arguments)})},{key:"kill",value:(t=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Shell",message:{cmd:"killChild",pid:this.pid}}));case 1:case"end":return e.stop()}}),e,this)}))),function(){return t.apply(this,arguments)})}]),e}(),rt=function(e){_inherits(a,e);var t,r,n=_createSuper(a);function a(e){var t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o=arguments.length>2?arguments[2]:void 0;return _classCallCheck(this,a),t=n.call(this),a.prototype.__init2.call(_assertThisInitialized(t)),a.prototype.__init3.call(_assertThisInitialized(t)),t.program=e,t.args="string"==typeof r?[r]:r,t.options=Qe(o,(function(){return{}})),t}return _createClass(a,[{key:"__init2",value:function(){this.stdout=new et}},{key:"__init3",value:function(){this.stderr=new et}},{key:"spawn",value:(r=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",Xe((function(e){switch(e.event){case"Error":t._emit("error",e.payload);break;case"Terminated":t._emit("close",e.payload);break;case"Stdout":t.stdout._emit("data",e.payload);break;case"Stderr":t.stderr._emit("data",e.payload)}}),this.program,this.args,this.options).then((function(e){return new tt(e)})));case 1:case"end":return e.stop()}}),e,this)}))),function(){return r.apply(this,arguments)})},{key:"execute",value:(t=_asyncToGenerator(regeneratorRuntime.mark((function e(){var t=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",new Promise((function(e,r){t.on("error",r);var n=[],a=[];t.stdout.on("data",(function(e){n.push(e)})),t.stderr.on("data",(function(e){a.push(e)})),t.on("close",(function(t){e({code:t.code,signal:t.signal,stdout:n.join("\n"),stderr:a.join("\n")})})),t.spawn().catch(r)})));case 1:case"end":return e.stop()}}),e)}))),function(){return t.apply(this,arguments)})}],[{key:"sidecar",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=arguments.length>2?arguments[2]:void 0,n=new a(e,t,r);return n.options.sidecar=!0,n}}]),a}(et);function nt(){return(nt=_asyncToGenerator(regeneratorRuntime.mark((function e(t,r){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Shell",message:{cmd:"open",path:t,with:r}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var at=Object.freeze({__proto__:null,Command:rt,Child:tt,open:function(e,t){return nt.apply(this,arguments)}});function ot(e){for(var t=void 0,r=e[0],n=1;n1&&void 0!==arguments[1]?arguments[1]:{};return _classCallCheck(this,r),n=t.call(this,e),ct([a,"optionalAccess",function(e){return e.skip}])||s({__tauriModule:"Window",message:{cmd:"createWebview",data:{options:_objectSpread({label:e},a)}}}).then(_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",n.emit("tauri://created"));case 1:case"end":return e.stop()}}),e)})))).catch(function(){var e=_asyncToGenerator(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",n.emit("tauri://error",t));case 1:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),n}return _createClass(r,null,[{key:"getByLabel",value:function(e){return dt().some((function(t){return t.label===e}))?new r(e,{skip:!0}):null}}]),r}(_t),vt=new wt(window.__TAURI_METADATA__.__currentWindow.label,{skip:!0});function bt(){return(bt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"currentMonitor"}}}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Rt(){return(Rt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"primaryMonitor"}}}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function kt(){return(kt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"availableMonitors"}}}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var xt=Object.freeze({__proto__:null,WebviewWindow:wt,WebviewWindowHandle:gt,WindowManager:_t,getCurrent:function(){return new wt(window.__TAURI_METADATA__.__currentWindow.label,{skip:!0})},getAll:dt,appWindow:vt,LogicalSize:lt,PhysicalSize:ft,LogicalPosition:ht,PhysicalPosition:mt,get UserAttentionType(){return pt},currentMonitor:function(){return bt.apply(this,arguments)},primaryMonitor:function(){return Rt.apply(this,arguments)},availableMonitors:function(){return kt.apply(this,arguments)}}),Tt=_e()?"\r\n":"\n";function Gt(){return(Gt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"platform"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Pt(){return(Pt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"version"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Mt(){return(Mt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"osType"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Ot(){return(Ot=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"arch"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function jt(){return(jt=_asyncToGenerator(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",s({__tauriModule:"Os",message:{cmd:"tempdir"}}));case 1:case"end":return e.stop()}}),e)})))).apply(this,arguments)}var At=Object.freeze({__proto__:null,EOL:Tt,platform:function(){return Gt.apply(this,arguments)},version:function(){return Pt.apply(this,arguments)},type:function(){return Mt.apply(this,arguments)},arch:function(){return Ot.apply(this,arguments)},tempdir:function(){return jt.apply(this,arguments)}}),Ct=o;e.app=h,e.cli=d,e.clipboard=_,e.dialog=x,e.event=I,e.fs=Q,e.globalShortcut=ae,e.http=me,e.invoke=Ct,e.notification=ge,e.os=At,e.path=Je,e.process=$e,e.shell=at,e.tauri=u,e.updater=st,e.window=xt,Object.defineProperty(e,"__esModule",{value:!0})})); diff --git a/core/tauri/scripts/core.js b/core/tauri/scripts/core.js index 5e6aaf56125a..af90118b52b5 100644 --- a/core/tauri/scripts/core.js +++ b/core/tauri/scripts/core.js @@ -2,78 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -// polyfills -if (!String.prototype.startsWith) { - String.prototype.startsWith = function (searchString, position) { - position = position || 0 - return this.substr(position, searchString.length) === searchString - } -} - -; -(function () { +;(function () { function uid() { - const length = new Int8Array(1) - window.crypto.getRandomValues(length) - const array = new Uint8Array(Math.max(16, Math.abs(length[0]))) - window.crypto.getRandomValues(array) - return array.join('') - } - - function ownKeys(object, enumerableOnly) { - var keys = Object.keys(object) - if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(object) - if (enumerableOnly) - symbols = symbols.filter(function (sym) { - return Object.getOwnPropertyDescriptor(object, sym).enumerable - }) - keys.push.apply(keys, symbols) - } - return keys - } - - function _objectSpread(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i] != null ? arguments[i] : {} - if (i % 2) { - ownKeys(source, true).forEach(function (key) { - _defineProperty(target, key, source[key]) - }) - } else if (Object.getOwnPropertyDescriptors) { - Object.defineProperties( - target, - Object.getOwnPropertyDescriptors(source) - ) - } else { - ownKeys(source).forEach(function (key) { - Object.defineProperty( - target, - key, - Object.getOwnPropertyDescriptor(source, key) - ) - }) - } - } - return target - } - - function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }) - } else { - obj[key] = value - } - return obj + return window.crypto.getRandomValues(new Uint32Array(1))[0] } if (!window.__TAURI__) { - window.__TAURI__ = {} + Object.defineProperty(window, '__TAURI__', { + value: {} + }) } window.__TAURI__.transformCallback = function transformCallback( @@ -81,19 +18,37 @@ if (!String.prototype.startsWith) { once ) { var identifier = uid() + var prop = `_${identifier}` - window[identifier] = function (result) { - if (once) { - delete window[identifier] - } + Object.defineProperty(window, prop, { + value: (result) => { + if (once) { + Reflect.deleteProperty(window, prop) + } - return callback && callback(result) - } + return callback && callback(result) + }, + writable: false, + configurable: true + }) return identifier } - window.__TAURI_INVOKE__ = function invoke(cmd, args = {}, key = null) { + const ipcQueue = [] + let isWaitingForIpc = false + + function waitForIpc() { + if ('__TAURI_IPC__' in window) { + for (const action of ipcQueue) { + action() + } + } else { + setTimeout(waitForIpc, 50) + } + } + + window.__TAURI_INVOKE__ = function invoke(cmd, args = {}) { return new Promise(function (resolve, reject) { var callback = window.__TAURI__.transformCallback(function (r) { resolve(r) @@ -112,31 +67,22 @@ if (!String.prototype.startsWith) { return reject(new Error('Invalid argument type.')) } - if (window.rpc) { - window.rpc.notify( - cmd, - _objectSpread({ - callback: callback, - error: error, - __invokeKey: key || __TAURI_INVOKE_KEY__ - }, - args - ) - ) - } else { - window.addEventListener('DOMContentLoaded', function () { - window.rpc.notify( - cmd, - _objectSpread({ - callback: callback, - error: error, - __invokeKey: key || __TAURI_INVOKE_KEY__ - }, - args - ) - ) + const action = () => { + window.__TAURI_IPC__({ + ...args, + callback, + error: error }) } + if (window.__TAURI_IPC__) { + action() + } else { + ipcQueue.push(action) + if (!isWaitingForIpc) { + waitForIpc() + isWaitingForIpc = true + } + } }) } @@ -147,32 +93,26 @@ if (!String.prototype.startsWith) { function (e) { var target = e.target while (target != null) { - if ( - target.matches ? target.matches('a') : target.msMatchesSelector('a') - ) { + if (target.matches('a')) { if ( target.href && target.href.startsWith('http') && target.target === '_blank' ) { - window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Shell', - message: { - cmd: 'open', - path: target.href - } - }, - _KEY_VALUE_ - ) + window.__TAURI_INVOKE__('tauri', { + __tauriModule: 'Shell', + message: { + cmd: 'open', + path: target.href + } + }) e.preventDefault() } break } target = target.parentElement } - }, - true + } ) } @@ -195,41 +135,28 @@ if (!String.prototype.startsWith) { document.addEventListener('mousedown', (e) => { if (e.target.hasAttribute('data-tauri-drag-region') && e.buttons === 1) { // start dragging if the element has a `tauri-drag-region` data attribute and maximize on double-clicking it - window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Window', - message: { - cmd: 'manage', - data: { - cmd: { - type: e.detail === 2 ? '__toggleMaximize' : 'startDragging' - } + window.__TAURI_INVOKE__('tauri', { + __tauriModule: 'Window', + message: { + cmd: 'manage', + data: { + cmd: { + type: e.detail === 2 ? '__toggleMaximize' : 'startDragging' } } - }, - _KEY_VALUE_ - ) + } + }) } }) - window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Event', - message: { - cmd: 'listen', - event: 'tauri://window-created', - handler: window.__TAURI__.transformCallback(function (event) { - if (event.payload) { - var windowLabel = event.payload.label - window.__TAURI__.__windows.push({ - label: windowLabel - }) - } - }) - } - }, - _KEY_VALUE_ - ) + listen('tauri://window-created', function (event) { + if (event.payload) { + var windowLabel = event.payload.label + window.__TAURI_METADATA__.__windows.push({ + label: windowLabel + }) + } + }) let permissionSettable = false let permissionValue = 'default' @@ -238,15 +165,12 @@ if (!String.prototype.startsWith) { if (window.Notification.permission !== 'default') { return Promise.resolve(window.Notification.permission === 'granted') } - return window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Notification', - message: { - cmd: 'isNotificationPermissionGranted' - } - }, - _KEY_VALUE_ - ) + return window.__TAURI_INVOKE__('tauri', { + __tauriModule: 'Notification', + message: { + cmd: 'isNotificationPermissionGranted' + } + }) } function setNotificationPermission(value) { @@ -256,15 +180,13 @@ if (!String.prototype.startsWith) { } function requestPermission() { - return window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Notification', - message: { - cmd: 'requestNotificationPermission' - } - }, - _KEY_VALUE_ - ) + return window + .__TAURI_INVOKE__('tauri', { + __tauriModule: 'Notification', + message: { + cmd: 'requestNotificationPermission' + } + }) .then(function (permission) { setNotificationPermission(permission) return permission @@ -276,20 +198,16 @@ if (!String.prototype.startsWith) { Object.freeze(options) } - isPermissionGranted().then(function (permission) { - if (permission) { - return window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Notification', - message: { - cmd: 'notification', - options: typeof options === 'string' ? { - title: options - } : options + return window.__TAURI_INVOKE__('tauri', { + __tauriModule: 'Notification', + message: { + cmd: 'notification', + options: + typeof options === 'string' + ? { + title: options } - }, - _KEY_VALUE_ - ) + : options } }) } @@ -327,48 +245,39 @@ if (!String.prototype.startsWith) { }) window.alert = function (message) { - window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Dialog', - message: { - cmd: 'messageDialog', - message: message - } - }, - _KEY_VALUE_ - ) + window.__TAURI_INVOKE__('tauri', { + __tauriModule: 'Dialog', + message: { + cmd: 'messageDialog', + message: message + } + }) } window.confirm = function (message) { - return window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Dialog', - message: { - cmd: 'askDialog', - message: message - } - }, - _KEY_VALUE_ - ) + return window.__TAURI_INVOKE__('tauri', { + __tauriModule: 'Dialog', + message: { + cmd: 'confirmDialog', + message: message + } + }) } // window.print works on Linux/Windows; need to use the API on macOS if (navigator.userAgent.includes('Mac')) { window.print = function () { - return window.__TAURI_INVOKE__( - 'tauri', { - __tauriModule: 'Window', - message: { - cmd: 'manage', - data: { - cmd: { - type: 'print' - } + return window.__TAURI_INVOKE__('tauri', { + __tauriModule: 'Window', + message: { + cmd: 'manage', + data: { + cmd: { + type: 'print' } } - }, - _KEY_VALUE_ - ) + } + }) } } })() diff --git a/core/tauri/scripts/freeze_prototype.js b/core/tauri/scripts/freeze_prototype.js new file mode 100644 index 000000000000..6c17c8e79ae0 --- /dev/null +++ b/core/tauri/scripts/freeze_prototype.js @@ -0,0 +1,5 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +Object.freeze(Object.prototype) diff --git a/core/tauri/scripts/init.js b/core/tauri/scripts/init.js new file mode 100644 index 000000000000..c32fb50a16f3 --- /dev/null +++ b/core/tauri/scripts/init.js @@ -0,0 +1,28 @@ +;(function () { + if (window.location.origin.startsWith(__TEMPLATE_origin__)) { + __RAW_freeze_prototype__ + + __RAW_pattern_script__ + + __RAW_ipc_script__ + ;(function () { + __RAW_bundle_script__ + })() + + __RAW_listen_function__ + + __RAW_core_script__ + + __RAW_event_initialization_script__ + + if (window.ipc) { + window.__TAURI_INVOKE__('__initialized', { url: window.location.href }) + } else { + window.addEventListener('DOMContentLoaded', function () { + window.__TAURI_INVOKE__('__initialized', { url: window.location.href }) + }) + } + + __RAW_plugin_initialization_script__ + } +})() diff --git a/core/tauri/scripts/ipc.js b/core/tauri/scripts/ipc.js new file mode 100644 index 000000000000..c98967a1ed39 --- /dev/null +++ b/core/tauri/scripts/ipc.js @@ -0,0 +1,153 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +/** + * @typedef {{callback: string, error: string, data: *}} IsolationPayload - a valid isolation payload + */ + +; +(function () { + /** + * @type {string} + */ + const pattern = window.__TAURI_PATTERN__.pattern + + /** + * @type {string} + */ + const isolationOrigin = __TEMPLATE_isolation_origin__ + + /** + * @type {{queue: object[], ready: boolean, frame: HTMLElement | null}} + */ + const isolation = Object.create(null) + isolation.queue = [] + isolation.ready = false + isolation.frame = null + + /** + * Detects if a message event is a valid isolation message. + * + * @param {MessageEvent} event - a message event that is expected to be an isolation message + * @return {boolean} - if the event was a valid isolation message + */ + function isIsolationMessage(event) { + return ( + typeof event.data === 'object' && + 'nonce' in event.data && + 'payload' in event.data + ) + } + + /** + * Detects if data is able to transform into an isolation payload. + * + * @param {object} data - object that is expected to contain at least a callback and error identifier + * @return {boolean} - if the data is able to transform into an isolation payload + */ + function isIsolationPayload(data) { + return typeof data === 'object' && 'callback' in data && 'error' in data + } + + /** + * Sends a properly formatted message to the isolation frame. + * + * @param {IsolationPayload} data - data that has been validated to be an isolation payload + */ + function sendIsolationMessage(data) { + // set the frame dom element if it's not been set before + if (!isolation.frame) { + const frame = document.querySelector('iframe#__tauri_isolation__') + if (frame.src.startsWith(isolationOrigin)) { + isolation.frame = frame + } else { + console.error( + 'Tauri IPC found an isolation iframe, but it had the wrong origin' + ) + } + } + + // ensure we have the target to send the message to + if (!isolation.frame || !isolation.frame.contentWindow) { + console.error( + 'Tauri "Isolation" Pattern could not find the Isolation iframe window' + ) + return + } + + isolation.frame.contentWindow.postMessage( + data, + '*' /* todo: set this to the secure origin */ + ) + } + + Object.defineProperty(window, '__TAURI_IPC__', { + // todo: JSDoc this function + value: Object.freeze((message) => { + switch (pattern) { + case 'brownfield': + window.__TAURI_POST_MESSAGE__(message) + break + + case 'isolation': + if (!isIsolationPayload(message)) { + console.error( + 'Tauri "Isolation" Pattern found an invalid isolation message payload', + message + ) + break + } + + if (isolation.ready) { + sendIsolationMessage(message) + } else { + isolation.queue.push(message) + } + + break + + case 'error': + console.error( + 'Tauri IPC found a Tauri Pattern, but it was an error. Check for other log messages to find the cause.' + ) + break + + default: + console.error( + 'Tauri IPC did not find a Tauri Pattern that it understood.' + ) + break + } + }) + }) + + /** + * IMPORTANT: See isolation_secure.js for the isolation frame implementation. + * main frame -> isolation frame = isolation payload + * isolation frame -> main frame = isolation message + */ + if (pattern === 'isolation') { + window.addEventListener( + 'message', + (event) => { + // watch for the isolation frame being ready and flush any queued messages + if (event.data === '__TAURI_ISOLATION_READY__') { + isolation.ready = true + + for (const message of isolation.queue) { + sendIsolationMessage(message) + } + + isolation.queue = [] + return + } + + if (isIsolationMessage(event)) { + window.__TAURI_POST_MESSAGE__(event.data) + } + }, + false + ) + } +})() diff --git a/core/tauri/scripts/isolation.js b/core/tauri/scripts/isolation.js new file mode 100644 index 000000000000..7bb0e6df29b9 --- /dev/null +++ b/core/tauri/scripts/isolation.js @@ -0,0 +1,15 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +window.addEventListener('DOMContentLoaded', () => { + let style = document.createElement('style') + style.textContent = __TEMPLATE_style__ + document.head.append(style) + + let iframe = document.createElement('iframe') + iframe.id = '__tauri_isolation__' + iframe.sandbox.add('allow-scripts') + iframe.src = __TEMPLATE_isolation_src__ + document.body.append(iframe) +}) diff --git a/core/tauri/scripts/pattern.js b/core/tauri/scripts/pattern.js new file mode 100644 index 000000000000..dbdea97c214f --- /dev/null +++ b/core/tauri/scripts/pattern.js @@ -0,0 +1,21 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +;(function () { + function __tauriDeepFreeze(object) { + const props = Object.getOwnPropertyNames(object) + + for (const prop of props) { + if (typeof object[name] === 'object') { + __tauriDeepFreeze(object[name]) + } + } + + return Object.freeze(object) + } + + Object.defineProperty(window, '__TAURI_PATTERN__', { + value: __tauriDeepFreeze(__TEMPLATE_pattern__) + }) +})() diff --git a/core/tauri/src/api/cli.rs b/core/tauri/src/api/cli.rs index feda0e8240fa..27cdde1f3f46 100644 --- a/core/tauri/src/api/cli.rs +++ b/core/tauri/src/api/cli.rs @@ -4,11 +4,12 @@ //! Types and functions related to CLI arguments. -use crate::utils::config::{CliArg, CliConfig}; - -use clap::{ - crate_authors, crate_description, crate_name, crate_version, App, Arg, ArgMatches, ErrorKind, +use crate::{ + utils::config::{CliArg, CliConfig}, + PackageInfo, }; + +use clap::{App, Arg, ArgMatches, ErrorKind}; use serde::Serialize; use serde_json::Value; use std::collections::HashMap; @@ -63,12 +64,12 @@ impl Matches { } /// Gets the argument matches of the CLI definition. -pub fn get_matches(cli: &CliConfig) -> crate::api::Result { +pub fn get_matches(cli: &CliConfig, package_info: &PackageInfo) -> crate::api::Result { let about = cli .description() - .unwrap_or(&crate_description!().to_string()) + .unwrap_or(&package_info.description.to_string()) .to_string(); - let app = get_app(crate_name!(), Some(&about), cli); + let app = get_app(package_info, &package_info.name, Some(&about), cli); match app.try_get_matches() { Ok(matches) => Ok(get_matches_internal(cli, &matches)), Err(e) => match e.kind { @@ -142,10 +143,15 @@ fn map_matches(config: &CliConfig, matches: &ArgMatches, cli_matches: &mut Match } } -fn get_app<'a>(name: &str, about: Option<&'a String>, config: &'a CliConfig) -> App<'a> { - let mut app = App::new(name) - .author(crate_authors!()) - .version(crate_version!()); +fn get_app<'a>( + package_info: &'a PackageInfo, + command_name: &'a str, + about: Option<&'a String>, + config: &'a CliConfig, +) -> App<'a> { + let mut app = App::new(command_name) + .author(package_info.authors) + .version(&*package_info.version); if let Some(about) = about { app = app.about(&**about); @@ -169,7 +175,12 @@ fn get_app<'a>(name: &str, about: Option<&'a String>, config: &'a CliConfig) -> if let Some(subcommands) = config.subcommands() { for (subcommand_name, subcommand) in subcommands { - let clap_subcommand = get_app(subcommand_name, subcommand.description(), subcommand); + let clap_subcommand = get_app( + package_info, + subcommand_name, + subcommand.description(), + subcommand, + ); app = app.subcommand(clap_subcommand); } } @@ -178,16 +189,21 @@ fn get_app<'a>(name: &str, about: Option<&'a String>, config: &'a CliConfig) -> } fn get_arg<'a>(arg_name: &'a str, arg: &'a CliArg) -> Arg<'a> { - let mut clap_arg = Arg::new(arg_name).long(arg_name); + let mut clap_arg = Arg::new(arg_name); - if let Some(short) = arg.short { - clap_arg = clap_arg.short(short); + if arg.index.is_none() { + clap_arg = clap_arg.long(arg_name); + if let Some(short) = arg.short { + clap_arg = clap_arg.short(short); + } } - clap_arg = bind_string_arg!(arg, clap_arg, description, about); - clap_arg = bind_string_arg!(arg, clap_arg, long_description, long_about); + clap_arg = bind_string_arg!(arg, clap_arg, description, help); + clap_arg = bind_string_arg!(arg, clap_arg, long_description, long_help); clap_arg = bind_value_arg!(arg, clap_arg, takes_value); - clap_arg = bind_value_arg!(arg, clap_arg, multiple); + if let Some(value) = arg.multiple { + clap_arg = clap_arg.multiple_values(value); + } clap_arg = bind_value_arg!(arg, clap_arg, multiple_occurrences); clap_arg = bind_value_arg!(arg, clap_arg, number_of_values); clap_arg = bind_string_slice_arg!(arg, clap_arg, possible_values); @@ -203,9 +219,15 @@ fn get_arg<'a>(arg_name: &'a str, arg: &'a CliArg) -> Arg<'a> { clap_arg = bind_string_slice_arg!(arg, clap_arg, required_unless_present_all); clap_arg = bind_string_slice_arg!(arg, clap_arg, required_unless_present_any); clap_arg = bind_string_arg!(arg, clap_arg, conflicts_with, conflicts_with); - clap_arg = bind_string_slice_arg!(arg, clap_arg, conflicts_with_all); + if let Some(value) = &arg.conflicts_with_all { + let v: Vec<&str> = value.iter().map(|x| &**x).collect(); + clap_arg = clap_arg.conflicts_with_all(&v); + } clap_arg = bind_string_arg!(arg, clap_arg, requires, requires); - clap_arg = bind_string_slice_arg!(arg, clap_arg, requires_all); + if let Some(value) = &arg.requires_all { + let v: Vec<&str> = value.iter().map(|x| &**x).collect(); + clap_arg = clap_arg.requires_all(&v); + } clap_arg = bind_if_arg!(arg, clap_arg, requires_if); clap_arg = bind_if_arg!(arg, clap_arg, required_if_eq); clap_arg = bind_value_arg!(arg, clap_arg, require_equals); diff --git a/core/tauri/src/api/cli/macros.rs b/core/tauri/src/api/cli/macros.rs index 74483e3ec950..33ce701308d0 100644 --- a/core/tauri/src/api/cli/macros.rs +++ b/core/tauri/src/api/cli/macros.rs @@ -7,7 +7,7 @@ macro_rules! bind_string_arg { let arg = $arg; let mut clap_arg = $clap_arg; if let Some(value) = &arg.$arg_name { - clap_arg = clap_arg.$clap_field(value); + clap_arg = clap_arg.$clap_field(value.as_str()); } clap_arg }}; @@ -30,7 +30,7 @@ macro_rules! bind_string_slice_arg { let mut clap_arg = $clap_arg; if let Some(value) = &arg.$field { let v: Vec<&str> = value.iter().map(|x| &**x).collect(); - clap_arg = clap_arg.$field(&v); + clap_arg = clap_arg.$field(v); } clap_arg }}; diff --git a/core/tauri/src/api/dialog.rs b/core/tauri/src/api/dialog.rs index a95a723aad2c..fedadb99a342 100644 --- a/core/tauri/src/api/dialog.rs +++ b/core/tauri/src/api/dialog.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -//! Types and functions related to display dialog. +//! Use native message and file open/save dialogs. +//! +//! This module exposes non-blocking APIs on its root, relying on callback closures +//! to give results back. This is particularly useful when running dialogs from the main thread. +//! When using on asynchronous contexts such as async commands, the [`blocking`] APIs are recommended. -#[cfg(any(dialog_open, dialog_save))] -use std::path::{Path, PathBuf}; - -use crate::{Runtime, Window}; +pub use nonblocking::*; #[cfg(not(target_os = "linux"))] macro_rules! run_dialog { @@ -32,162 +33,457 @@ macro_rules! run_dialog { }}; } -/// Window parent definition. -#[cfg(any(windows, target_os = "macos"))] -#[cfg_attr(doc_cfg, doc(cfg(any(windows, target_os = "macos"))))] -pub struct WindowParent { - #[cfg(windows)] - hwnd: *mut std::ffi::c_void, - #[cfg(target_os = "macos")] - ns_window: *mut std::ffi::c_void, +macro_rules! run_dialog_sync { + ($e:expr) => {{ + let (tx, rx) = sync_channel(0); + let cb = move |response| { + tx.send(response).unwrap(); + }; + run_dialog!($e, cb); + rx.recv().unwrap() + }}; } -#[cfg(any(windows, target_os = "macos"))] -unsafe impl raw_window_handle::HasRawWindowHandle for WindowParent { - #[cfg(windows)] - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - let mut handle = raw_window_handle::windows::WindowsHandle::empty(); - handle.hwnd = self.hwnd; - raw_window_handle::RawWindowHandle::Windows(handle) - } +macro_rules! file_dialog_builder { + () => { + /// The file dialog builder. + /// + /// Constructs file picker dialogs that can select single/multiple files or directories. + #[derive(Debug, Default)] + pub struct FileDialogBuilder(rfd::FileDialog); - #[cfg(target_os = "macos")] - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - let mut handle = raw_window_handle::macos::MacOSHandle::empty(); - handle.ns_window = self.ns_window; - raw_window_handle::RawWindowHandle::MacOS(handle) - } -} + impl FileDialogBuilder { + /// Gets the default file dialog builder. + pub fn new() -> Self { + Default::default() + } -#[cfg(any(windows, target_os = "macos"))] -#[cfg_attr(doc_cfg, doc(cfg(any(windows, target_os = "macos"))))] -#[doc(hidden)] -pub fn window_parent(window: &Window) -> crate::Result { - #[cfg(windows)] - let w = WindowParent { - hwnd: window.hwnd()?, - }; - #[cfg(target_os = "macos")] - let w = WindowParent { - ns_window: window.ns_window()?, + /// Add file extension filter. Takes in the name of the filter, and list of extensions + #[must_use] + pub fn add_filter(mut self, name: impl AsRef, extensions: &[&str]) -> Self { + self.0 = self.0.add_filter(name.as_ref(), extensions); + self + } + + /// Set starting directory of the dialog. + #[must_use] + pub fn set_directory>(mut self, directory: P) -> Self { + self.0 = self.0.set_directory(directory); + self + } + + /// Set starting file name of the dialog. + #[must_use] + pub fn set_file_name(mut self, file_name: &str) -> Self { + self.0 = self.0.set_file_name(file_name); + self + } + + /// Sets the parent window of the dialog. + #[must_use] + pub fn set_parent(mut self, parent: &W) -> Self { + self.0 = self.0.set_parent(parent); + self + } + + /// Set the title of the dialog. + #[must_use] + pub fn set_title(mut self, title: &str) -> Self { + self.0 = self.0.set_title(title); + self + } + } }; - Ok(w) } -/// The file dialog builder. +/// Blocking interfaces for the dialog APIs. /// -/// Constructs file picker dialogs that can select single/multiple files or directories. -#[cfg(any(dialog_open, dialog_save))] -#[derive(Debug, Default)] -pub struct FileDialogBuilder(rfd::FileDialog); - -#[cfg(any(dialog_open, dialog_save))] -impl FileDialogBuilder { - /// Gets the default file dialog builder. - pub fn new() -> Self { - Default::default() - } +/// The blocking APIs will block the current thread to execute instead of relying on callback closures, +/// which makes them easier to use. +/// +/// **NOTE:** You cannot block the main thread when executing the dialog APIs, so you must use the [`crate::api::dialog`] methods instead. +/// Examples of main thread context are the [`crate::App::run`] closure and non-async commmands. +pub mod blocking { + use crate::{Runtime, Window}; + use std::path::{Path, PathBuf}; + use std::sync::mpsc::sync_channel; + + file_dialog_builder!(); + + impl FileDialogBuilder { + /// Shows the dialog to select a single file. + /// This is a blocking operation, + /// and should *NOT* be used when running on the main thread context. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::blocking::FileDialogBuilder; + /// #[tauri::command] + /// fn my_command() { + /// let file_path = FileDialogBuilder::new().pick_file(); + /// // do something with the optional file path here + /// // the file path is `None` if the user closed the dialog + /// } + /// ``` + pub fn pick_file(self) -> Option { + run_dialog_sync!(self.0.pick_file()) + } - /// Add file extension filter. Takes in the name of the filter, and list of extensions - pub fn add_filter(mut self, name: impl AsRef, extensions: &[&str]) -> Self { - self.0 = self.0.add_filter(name.as_ref(), extensions); - self + /// Shows the dialog to select multiple files. + /// This is a blocking operation, + /// and should *NOT* be used when running on the main thread context. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::blocking::FileDialogBuilder; + /// #[tauri::command] + /// fn my_command() { + /// let file_path = FileDialogBuilder::new().pick_files(); + /// // do something with the optional file paths here + /// // the file paths value is `None` if the user closed the dialog + /// } + /// ``` + pub fn pick_files(self) -> Option> { + run_dialog_sync!(self.0.pick_files()) + } + + /// Shows the dialog to select a single folder. + /// This is a blocking operation, + /// and should *NOT* be used when running on the main thread context. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::blocking::FileDialogBuilder; + /// #[tauri::command] + /// fn my_command() { + /// let folder_path = FileDialogBuilder::new().pick_folder(); + /// // do something with the optional folder path here + /// // the folder path is `None` if the user closed the dialog + /// } + /// ``` + pub fn pick_folder(self) -> Option { + run_dialog_sync!(self.0.pick_folder()) + } + + /// Shows the dialog to save a file. + /// This is a blocking operation, + /// and should *NOT* be used when running on the main thread context. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::blocking::FileDialogBuilder; + /// #[tauri::command] + /// fn my_command() { + /// let file_path = FileDialogBuilder::new().save_file(); + /// // do something with the optional file path here + /// // the file path is `None` if the user closed the dialog + /// } + /// ``` + pub fn save_file(self) -> Option { + run_dialog_sync!(self.0.save_file()) + } } - /// Set starting directory of the dialog. - pub fn set_directory>(mut self, directory: P) -> Self { - self.0 = self.0.set_directory(directory); - self + /// Displays a dialog with a message and an optional title with a "yes" and a "no" button and wait for it to be closed. + /// + /// This is a blocking operation, + /// and should *NOT* be used when running on the main thread context. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::blocking::ask; + /// # let app = tauri::Builder::default().build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")).unwrap(); + /// # let window = tauri::Manager::get_window(&app, "main").unwrap(); + /// let answer = ask(Some(&window), "Tauri", "Is Tauri awesome?"); + /// // do something with `answer` + /// ``` + #[allow(unused_variables)] + pub fn ask( + parent_window: Option<&Window>, + title: impl AsRef, + message: impl AsRef, + ) -> bool { + run_message_dialog(parent_window, title, message, rfd::MessageButtons::YesNo) } - /// Set starting file name of the dialog. - pub fn set_file_name(mut self, file_name: &str) -> Self { - self.0 = self.0.set_file_name(file_name); - self + /// Displays a dialog with a message and an optional title with an "ok" and a "cancel" button and wait for it to be closed. + /// + /// This is a blocking operation, + /// and should *NOT* be used when running on the main thread context. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::blocking::confirm; + /// # let app = tauri::Builder::default().build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")).unwrap(); + /// # let window = tauri::Manager::get_window(&app, "main").unwrap(); + /// let answer = confirm(Some(&window), "Tauri", "Are you sure?"); + /// // do something with `answer` + /// ``` + #[allow(unused_variables)] + pub fn confirm( + parent_window: Option<&Window>, + title: impl AsRef, + message: impl AsRef, + ) -> bool { + run_message_dialog(parent_window, title, message, rfd::MessageButtons::OkCancel) } - /// Sets the parent window of the dialog. - pub fn set_parent(mut self, parent: &W) -> Self { - self.0 = self.0.set_parent(parent); - self + /// Displays a message dialog and wait for it to be closed. + /// + /// This is a blocking operation, + /// and should *NOT* be used when running on the main thread context. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::blocking::message; + /// # let app = tauri::Builder::default().build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")).unwrap(); + /// # let window = tauri::Manager::get_window(&app, "main").unwrap(); + /// message(Some(&window), "Tauri", "Tauri is awesome!"); + /// ``` + #[allow(unused_variables)] + pub fn message( + parent_window: Option<&Window>, + title: impl AsRef, + message: impl AsRef, + ) { + let _ = run_message_dialog(parent_window, title, message, rfd::MessageButtons::Ok); } - /// Pick one file. - pub fn pick_file) + Send + 'static>(self, f: F) { - run_dialog!(self.0.pick_file(), f) + #[allow(unused_variables)] + fn run_message_dialog( + parent_window: Option<&Window>, + title: impl AsRef, + message: impl AsRef, + buttons: rfd::MessageButtons, + ) -> bool { + let (tx, rx) = sync_channel(1); + super::nonblocking::run_message_dialog( + parent_window, + title, + message, + buttons, + move |response| { + tx.send(response).unwrap(); + }, + ); + rx.recv().unwrap() } +} - /// Pick multiple files. - pub fn pick_files>) + Send + 'static>(self, f: F) { - run_dialog!(self.0.pick_files(), f) +mod nonblocking { + use crate::{Runtime, Window}; + use std::path::{Path, PathBuf}; + + file_dialog_builder!(); + + impl FileDialogBuilder { + /// Shows the dialog to select a single file. + /// This is not a blocking operation, + /// and should be used when running on the main thread to avoid deadlocks with the event loop. + /// + /// For usage in other contexts such as commands, prefer [`Self::pick_file`]. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::FileDialogBuilder; + /// tauri::Builder::default() + /// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("failed to build tauri app") + /// .run(|_app, _event| { + /// FileDialogBuilder::new().pick_file(|file_path| { + /// // do something with the optional file path here + /// // the file path is `None` if the user closed the dialog + /// }) + /// }) + /// ``` + pub fn pick_file) + Send + 'static>(self, f: F) { + run_dialog!(self.0.pick_file(), f) + } + + /// Shows the dialog to select multiple files. + /// This is not a blocking operation, + /// and should be used when running on the main thread to avoid deadlocks with the event loop. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::FileDialogBuilder; + /// tauri::Builder::default() + /// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("failed to build tauri app") + /// .run(|_app, _event| { + /// FileDialogBuilder::new().pick_files(|file_paths| { + /// // do something with the optional file paths here + /// // the file paths value is `None` if the user closed the dialog + /// }) + /// }) + /// ``` + pub fn pick_files>) + Send + 'static>(self, f: F) { + run_dialog!(self.0.pick_files(), f) + } + + /// Shows the dialog to select a single folder. + /// This is not a blocking operation, + /// and should be used when running on the main thread to avoid deadlocks with the event loop. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::FileDialogBuilder; + /// tauri::Builder::default() + /// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("failed to build tauri app") + /// .run(|_app, _event| { + /// FileDialogBuilder::new().pick_folder(|folder_path| { + /// // do something with the optional folder path here + /// // the folder path is `None` if the user closed the dialog + /// }) + /// }) + /// ``` + pub fn pick_folder) + Send + 'static>(self, f: F) { + run_dialog!(self.0.pick_folder(), f) + } + + /// Shows the dialog to save a file. + /// + /// This is not a blocking operation, + /// and should be used when running on the main thread to avoid deadlocks with the event loop. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::FileDialogBuilder; + /// tauri::Builder::default() + /// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("failed to build tauri app") + /// .run(|_app, _event| { + /// FileDialogBuilder::new().save_file(|file_path| { + /// // do something with the optional file path here + /// // the file path is `None` if the user closed the dialog + /// }) + /// }) + /// ``` + pub fn save_file) + Send + 'static>(self, f: F) { + run_dialog!(self.0.save_file(), f) + } } - /// Pick one folder. - pub fn pick_folder) + Send + 'static>(self, f: F) { - run_dialog!(self.0.pick_folder(), f) + /// Displays a non-blocking dialog with a message and an optional title with a "yes" and a "no" button. + /// + /// This is not a blocking operation, + /// and should be used when running on the main thread to avoid deadlocks with the event loop. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::ask; + /// # let app = tauri::Builder::default().build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")).unwrap(); + /// # let window = tauri::Manager::get_window(&app, "main").unwrap(); + /// ask(Some(&window), "Tauri", "Is Tauri awesome?", |answer| { + /// // do something with `answer` + /// }); + /// ``` + #[allow(unused_variables)] + pub fn ask( + parent_window: Option<&Window>, + title: impl AsRef, + message: impl AsRef, + f: F, + ) { + run_message_dialog(parent_window, title, message, rfd::MessageButtons::YesNo, f) } - /// Opens save file dialog. - pub fn save_file) + Send + 'static>(self, f: F) { - run_dialog!(self.0.save_file(), f) + /// Displays a non-blocking dialog with a message and an optional title with an "ok" and a "cancel" button. + /// + /// This is not a blocking operation, + /// and should be used when running on the main thread to avoid deadlocks with the event loop. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::confirm; + /// # let app = tauri::Builder::default().build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")).unwrap(); + /// # let window = tauri::Manager::get_window(&app, "main").unwrap(); + /// confirm(Some(&window), "Tauri", "Are you sure?", |answer| { + /// // do something with `answer` + /// }); + /// ``` + #[allow(unused_variables)] + pub fn confirm( + parent_window: Option<&Window>, + title: impl AsRef, + message: impl AsRef, + f: F, + ) { + run_message_dialog( + parent_window, + title, + message, + rfd::MessageButtons::OkCancel, + f, + ) } -} -/// Displays a dialog with a message and an optional title with a "yes" and a "no" button. -#[allow(unused_variables)] -pub fn ask( - parent_window: Option<&Window>, - title: impl AsRef, - message: impl AsRef, - f: F, -) { - let title = title.as_ref().to_string(); - let message = message.as_ref().to_string(); - #[allow(unused_mut)] - let mut builder = rfd::MessageDialog::new() - .set_title(&title) - .set_description(&message) - .set_buttons(rfd::MessageButtons::YesNo) - .set_level(rfd::MessageLevel::Info); - - #[cfg(any(windows, target_os = "macos"))] - { - if let Some(window) = parent_window { - if let Ok(parent) = window_parent(window) { - builder = builder.set_parent(&parent); - } - } + /// Displays a non-blocking message dialog. + /// + /// This is not a blocking operation, + /// and should be used when running on the main thread to avoid deadlocks with the event loop. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::api::dialog::message; + /// # let app = tauri::Builder::default().build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")).unwrap(); + /// # let window = tauri::Manager::get_window(&app, "main").unwrap(); + /// message(Some(&window), "Tauri", "Tauri is awesome!"); + /// ``` + #[allow(unused_variables)] + pub fn message( + parent_window: Option<&Window>, + title: impl AsRef, + message: impl AsRef, + ) { + run_message_dialog( + parent_window, + title, + message, + rfd::MessageButtons::Ok, + |_| {}, + ) } - run_dialog!(builder.show(), f) -} + #[allow(unused_variables)] + pub(crate) fn run_message_dialog( + parent_window: Option<&Window>, + title: impl AsRef, + message: impl AsRef, + buttons: rfd::MessageButtons, + f: F, + ) { + let title = title.as_ref().to_string(); + let message = message.as_ref().to_string(); + #[allow(unused_mut)] + let mut builder = rfd::MessageDialog::new() + .set_title(&title) + .set_description(&message) + .set_buttons(buttons) + .set_level(rfd::MessageLevel::Info); -/// Displays a message dialog. -#[allow(unused_variables)] -pub fn message( - parent_window: Option<&Window>, - title: impl AsRef, - message: impl AsRef, -) { - let title = title.as_ref().to_string(); - let message = message.as_ref().to_string(); - let cb = |_| {}; - - #[allow(unused_mut)] - let mut builder = rfd::MessageDialog::new() - .set_title(&title) - .set_description(&message) - .set_buttons(rfd::MessageButtons::Ok) - .set_level(rfd::MessageLevel::Info); - - #[cfg(any(windows, target_os = "macos"))] - { - if let Some(window) = parent_window { - if let Ok(parent) = window_parent(window) { - builder = builder.set_parent(&parent); + #[cfg(any(windows, target_os = "macos"))] + { + if let Some(window) = parent_window { + builder = builder.set_parent(window); } } - } - run_dialog!(builder.show(), cb) + run_dialog!(builder.show(), f) + } } diff --git a/core/tauri/src/api/error.rs b/core/tauri/src/api/error.rs index 6279232615a4..d5dd2bfa4c30 100644 --- a/core/tauri/src/api/error.rs +++ b/core/tauri/src/api/error.rs @@ -25,7 +25,7 @@ pub enum Error { #[error("user cancelled the dialog")] DialogCancelled, /// The network error. - #[cfg(not(feature = "reqwest-client"))] + #[cfg(all(feature = "http-api", not(feature = "reqwest-client")))] #[error("Network Error: {0}")] Network(#[from] attohttpc::Error), /// The network error. @@ -72,6 +72,9 @@ pub enum Error { #[cfg(notification_all)] #[error(transparent)] Notification(#[from] notify_rust::error::Error), + /// Url error. + #[error(transparent)] + Url(#[from] url::ParseError), /// failed to detect the current platform. #[error("failed to detect platform: {0}")] FailedToDetectPlatform(String), @@ -79,8 +82,18 @@ pub enum Error { #[cfg(feature = "cli")] #[cfg_attr(doc_cfg, doc(cfg(feature = "cli")))] #[error("failed to parse CLI arguments: {0}")] - ParseCliArguments(#[from] clap::Error), + ParseCliArguments(String), /// Shell error. #[error("shell error: {0}")] Shell(String), + /// Unknown program name. + #[error("unknown program name: {0}")] + UnknownProgramName(String), +} + +#[cfg(feature = "cli")] +impl From for Error { + fn from(error: clap::Error) -> Self { + Self::ParseCliArguments(error.to_string()) + } } diff --git a/core/tauri/src/api/file.rs b/core/tauri/src/api/file.rs index 5a85d857c560..b727909d6ac7 100644 --- a/core/tauri/src/api/file.rs +++ b/core/tauri/src/api/file.rs @@ -48,9 +48,8 @@ mod test { assert!(res.is_err()); + #[cfg(not(windows))] if let Error::Io(e) = res.unwrap_err() { - #[cfg(windows)] - assert_eq!(e.to_string(), "Access is denied. (os error 5)".to_string()); #[cfg(not(windows))] assert_eq!(e.to_string(), "Is a directory (os error 21)".to_string()); } @@ -88,9 +87,8 @@ mod test { assert!(res.is_err()); + #[cfg(not(windows))] if let Error::Io(e) = res.unwrap_err() { - #[cfg(windows)] - assert_eq!(e.to_string(), "Access is denied. (os error 5)".to_string()); #[cfg(not(windows))] assert_eq!(e.to_string(), "Is a directory (os error 21)".to_string()); } diff --git a/core/tauri/src/api/file/extract.rs b/core/tauri/src/api/file/extract.rs index 54c8ee85bf45..3b19a0328473 100644 --- a/core/tauri/src/api/file/extract.rs +++ b/core/tauri/src/api/file/extract.rs @@ -3,8 +3,11 @@ // SPDX-License-Identifier: MIT use either::{self, Either}; - -use std::{fs, io, path}; +use std::{ + fs, + io::{self, Read, Seek}, + path::{self, Path, PathBuf}, +}; /// The supported archive formats. #[derive(Debug, Clone, Copy, PartialEq)] @@ -28,49 +31,68 @@ pub enum Compression { /// The extract manager to retrieve files from archives. #[derive(Debug)] -pub struct Extract<'a> { - source: &'a path::Path, - archive_format: Option, +pub struct Extract { + reader: R, + archive_format: ArchiveFormat, } -fn detect_archive_type(path: &path::Path) -> ArchiveFormat { - match path.extension() { - Some(extension) if extension == std::ffi::OsStr::new("zip") => ArchiveFormat::Zip, - Some(extension) if extension == std::ffi::OsStr::new("tar") => ArchiveFormat::Tar(None), - Some(extension) if extension == std::ffi::OsStr::new("gz") => match path - .file_stem() - .map(|e| path::Path::new(e)) - .and_then(|f| f.extension()) - { - Some(extension) if extension == std::ffi::OsStr::new("tar") => { - ArchiveFormat::Tar(Some(Compression::Gz)) - } - _ => ArchiveFormat::Plain(Some(Compression::Gz)), - }, - _ => ArchiveFormat::Plain(None), +impl Extract { + /// Create archive from reader. + pub fn from_cursor(mut reader: R, archive_format: ArchiveFormat) -> Extract { + if reader.seek(io::SeekFrom::Start(0)).is_err() { + #[cfg(debug_assertions)] + eprintln!("Could not seek to start of the file"); + } + Extract { + reader, + archive_format, + } } -} -impl<'a> Extract<'a> { - /// Create an `Extractor from a source path - pub fn from_source(source: &'a path::Path) -> Extract<'a> { - Self { - source, - archive_format: None, + /// Get the archive content. + pub fn files(&mut self) -> crate::api::Result> { + let reader = &mut self.reader; + let mut all_files = Vec::new(); + if reader.seek(io::SeekFrom::Start(0)).is_err() { + #[cfg(debug_assertions)] + eprintln!("Could not seek to start of the file"); } - } + match self.archive_format { + ArchiveFormat::Plain(compression) | ArchiveFormat::Tar(compression) => { + let reader = Self::get_archive_reader(reader, compression); + match self.archive_format { + ArchiveFormat::Tar(_) => { + let mut archive = tar::Archive::new(reader); + for entry in archive.entries()?.flatten() { + if let Ok(path) = entry.path() { + all_files.push(path.to_path_buf()); + } + } + } + _ => unreachable!(), + }; + } - /// Specify an archive format of the source being extracted. If not specified, the - /// archive format will determined from the file extension. - pub fn archive_format(&mut self, format: ArchiveFormat) -> &mut Self { - self.archive_format = Some(format); - self + ArchiveFormat::Zip => { + let archive = zip::ZipArchive::new(reader)?; + for entry in archive.file_names() { + all_files.push(PathBuf::from(entry)); + } + } + } + + Ok(all_files) } + // Get the reader based on the compression type. fn get_archive_reader( - source: fs::File, + source: &mut R, compression: Option, - ) -> Either> { + ) -> Either<&mut R, flate2::read::GzDecoder<&mut R>> { + if source.seek(io::SeekFrom::Start(0)).is_err() { + #[cfg(debug_assertions)] + eprintln!("Could not seek to start of the file"); + } match compression { Some(Compression::Gz) => Either::Right(flate2::read::GzDecoder::new(source)), None => Either::Left(source), @@ -80,17 +102,16 @@ impl<'a> Extract<'a> { /// Extract an entire source archive into a specified path. If the source is a single compressed /// file and not an archive, it will be extracted into a file with the same name inside of /// `into_dir`. - pub fn extract_into(&self, into_dir: &path::Path) -> crate::api::Result<()> { - let source = fs::File::open(self.source)?; - let archive = self - .archive_format - .unwrap_or_else(|| detect_archive_type(self.source)); - - match archive { + pub fn extract_into(&mut self, into_dir: &path::Path) -> crate::api::Result<()> { + let reader = &mut self.reader; + if reader.seek(io::SeekFrom::Start(0)).is_err() { + #[cfg(debug_assertions)] + eprintln!("Could not seek to start of the file"); + } + match self.archive_format { ArchiveFormat::Plain(compression) | ArchiveFormat::Tar(compression) => { - let mut reader = Self::get_archive_reader(source, compression); - - match archive { + let mut reader = Self::get_archive_reader(reader, compression); + match self.archive_format { ArchiveFormat::Plain(_) => { match fs::create_dir_all(into_dir) { Ok(_) => (), @@ -100,12 +121,8 @@ impl<'a> Extract<'a> { } } } - let file_name = self.source.file_name().ok_or_else(|| { - crate::api::Error::Extract("Extractor source has no file-name".into()) - })?; - let mut out_path = into_dir.join(file_name); - out_path.set_extension(""); - let mut out_file = fs::File::create(&out_path)?; + + let mut out_file = fs::File::create(&into_dir)?; io::copy(&mut reader, &mut out_file)?; } ArchiveFormat::Tar(_) => { @@ -115,40 +132,57 @@ impl<'a> Extract<'a> { _ => unreachable!(), }; } + ArchiveFormat::Zip => { - let mut archive = zip::ZipArchive::new(source)?; + let mut archive = zip::ZipArchive::new(reader)?; for i in 0..archive.len() { let mut file = archive.by_index(i)?; - let path = into_dir.join(file.name()); - let mut output = fs::File::create(path)?; - io::copy(&mut file, &mut output)?; + // Decode the file name from raw bytes instead of using file.name() directly. + // file.name() uses String::from_utf8_lossy() which may return messy characters + // such as: τê▒Σ║ñµÿô.app/, that does not work as expected. + // Here we require the file name must be a valid UTF-8. + let file_name = String::from_utf8(file.name_raw().to_vec())?; + let out_path = into_dir.join(&file_name); + if file.is_dir() { + fs::create_dir_all(&out_path)?; + } else { + if let Some(out_path_parent) = out_path.parent() { + fs::create_dir_all(&out_path_parent)?; + } + let mut out_file = fs::File::create(&out_path)?; + io::copy(&mut file, &mut out_file)?; + } + // Get and Set permissions + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + if let Some(mode) = file.unix_mode() { + fs::set_permissions(&out_path, fs::Permissions::from_mode(mode))?; + } + } } } - }; + } Ok(()) } - /// Extract a single file from a source and save to a file of the same name in `into_dir`. - /// If the source is a single compressed file, it will be saved with the name `file_to_extract` - /// in the specified `into_dir`. + /// Extract a single file from a source and extract it `into_path`. + /// If it's a directory, the target will be created, if it's a file, it'll be extracted at this location. + /// Note: You need to include the complete path, with file name and extension. pub fn extract_file>( - &self, - into_dir: &path::Path, + &mut self, + into_path: &path::Path, file_to_extract: T, ) -> crate::api::Result<()> { let file_to_extract = file_to_extract.as_ref(); - let source = fs::File::open(self.source)?; - let archive = self - .archive_format - .unwrap_or_else(|| detect_archive_type(self.source)); + let reader = &mut self.reader; - match archive { + match self.archive_format { ArchiveFormat::Plain(compression) | ArchiveFormat::Tar(compression) => { - let mut reader = Self::get_archive_reader(source, compression); - - match archive { + let mut reader = Self::get_archive_reader(reader, compression); + match self.archive_format { ArchiveFormat::Plain(_) => { - match fs::create_dir_all(into_dir) { + match fs::create_dir_all(into_path) { Ok(_) => (), Err(e) => { if e.kind() != io::ErrorKind::AlreadyExists { @@ -156,11 +190,7 @@ impl<'a> Extract<'a> { } } } - let file_name = file_to_extract.file_name().ok_or_else(|| { - crate::api::Error::Extract("Extractor source has no file-name".into()) - })?; - let out_path = into_dir.join(file_name); - let mut out_file = fs::File::create(&out_path)?; + let mut out_file = fs::File::create(into_path)?; io::copy(&mut reader, &mut out_file)?; } ArchiveFormat::Tar(_) => { @@ -175,7 +205,27 @@ impl<'a> Extract<'a> { file_to_extract )) })?; - entry.unpack_in(into_dir)?; + + // determine if it's a file or a directory + if entry.header().entry_type() == tar::EntryType::Directory { + // this is a directory, lets create it + match fs::create_dir_all(into_path) { + Ok(_) => (), + Err(e) => { + if e.kind() != io::ErrorKind::AlreadyExists { + return Err(e.into()); + } + } + } + } else { + let mut out_file = fs::File::create(into_path)?; + io::copy(&mut entry, &mut out_file)?; + + // make sure we set permissions + if let Ok(mode) = entry.header().mode() { + set_perms(into_path, Some(&mut out_file), mode, true)?; + } + } } _ => { panic!("Unreasonable code"); @@ -183,16 +233,87 @@ impl<'a> Extract<'a> { }; } ArchiveFormat::Zip => { - let mut archive = zip::ZipArchive::new(source)?; + let mut archive = zip::ZipArchive::new(reader)?; let mut file = archive.by_name( file_to_extract .to_str() .expect("Could not convert file to str"), )?; - let mut output = fs::File::create(into_dir.join(file.name()))?; - io::copy(&mut file, &mut output)?; + + if file.is_dir() { + // this is a directory, lets create it + match fs::create_dir_all(into_path) { + Ok(_) => (), + Err(e) => { + if e.kind() != io::ErrorKind::AlreadyExists { + return Err(e.into()); + } + } + } + } else { + let mut out_file = fs::File::create(into_path)?; + io::copy(&mut file, &mut out_file)?; + } } - }; + } + Ok(()) } } + +fn set_perms( + dst: &Path, + f: Option<&mut std::fs::File>, + mode: u32, + preserve: bool, +) -> crate::api::Result<()> { + _set_perms(dst, f, mode, preserve).map_err(|_| { + crate::api::Error::Extract(format!( + "failed to set permissions to {:o} \ + for `{}`", + mode, + dst.display() + )) + }) +} + +#[cfg(unix)] +fn _set_perms( + dst: &Path, + f: Option<&mut std::fs::File>, + mode: u32, + preserve: bool, +) -> io::Result<()> { + use std::os::unix::prelude::*; + + let mode = if preserve { mode } else { mode & 0o777 }; + let perm = fs::Permissions::from_mode(mode as _); + match f { + Some(f) => f.set_permissions(perm), + None => fs::set_permissions(dst, perm), + } +} + +#[cfg(windows)] +fn _set_perms( + dst: &Path, + f: Option<&mut std::fs::File>, + mode: u32, + _preserve: bool, +) -> io::Result<()> { + if mode & 0o200 == 0o200 { + return Ok(()); + } + match f { + Some(f) => { + let mut perm = f.metadata()?.permissions(); + perm.set_readonly(true); + f.set_permissions(perm) + } + None => { + let mut perm = fs::metadata(dst)?.permissions(); + perm.set_readonly(true); + fs::set_permissions(dst, perm) + } + } +} diff --git a/core/tauri/src/api/http.rs b/core/tauri/src/api/http.rs index 2173b16f677c..3a3a18f25de1 100644 --- a/core/tauri/src/api/http.rs +++ b/core/tauri/src/api/http.rs @@ -8,6 +8,7 @@ use http::{header::HeaderName, Method}; use serde::{Deserialize, Serialize}; use serde_json::Value; use serde_repr::{Deserialize_repr, Serialize_repr}; +use url::Url; use std::{collections::HashMap, path::PathBuf, time::Duration}; @@ -28,12 +29,14 @@ impl ClientBuilder { } /// Sets the maximum number of redirections. + #[must_use] pub fn max_redirections(mut self, max_redirections: usize) -> Self { self.max_redirections = Some(max_redirections); self } /// Sets the connection timeout. + #[must_use] pub fn connect_timeout(mut self, connect_timeout: u64) -> Self { self.connect_timeout = Some(connect_timeout); self @@ -139,7 +142,7 @@ impl Client { pub async fn send(&self, request: HttpRequestBuilder) -> crate::api::Result { let method = Method::from_bytes(request.method.to_uppercase().as_bytes())?; - let mut request_builder = self.0.request(method, &request.url); + let mut request_builder = self.0.request(method, request.url.as_str()); if let Some(query) = request.query { request_builder = request_builder.query(&query); @@ -249,7 +252,7 @@ pub enum Body { /// .max_redirections(3) /// .build() /// .unwrap(); -/// let mut request_builder = HttpRequestBuilder::new("GET", "http://example.com"); +/// let mut request_builder = HttpRequestBuilder::new("GET", "http://example.com").unwrap(); /// let request = request_builder.response_type(ResponseType::Text); /// /// if let Ok(response) = client.send(request).await { @@ -265,7 +268,7 @@ pub struct HttpRequestBuilder { /// The request method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT or TRACE) pub method: String, /// The request URL - pub url: String, + pub url: Url, /// The request query params pub query: Option>, /// The request headers @@ -280,43 +283,48 @@ pub struct HttpRequestBuilder { impl HttpRequestBuilder { /// Initializes a new instance of the HttpRequestrequest_builder. - pub fn new(method: impl Into, url: impl Into) -> Self { - Self { + pub fn new(method: impl Into, url: impl AsRef) -> crate::api::Result { + Ok(Self { method: method.into(), - url: url.into(), + url: Url::parse(url.as_ref())?, query: None, headers: None, body: None, timeout: None, response_type: None, - } + }) } /// Sets the request parameters. + #[must_use] pub fn query(mut self, query: HashMap) -> Self { self.query = Some(query); self } /// Sets the request headers. + #[must_use] pub fn headers(mut self, headers: HashMap) -> Self { self.headers = Some(headers); self } /// Sets the request body. + #[must_use] pub fn body(mut self, body: Body) -> Self { self.body = Some(body); self } /// Sets the general request timeout. + #[must_use] pub fn timeout(mut self, timeout: u64) -> Self { self.timeout = Some(timeout); self } /// Sets the type of the response. Interferes with the way we read the response. + #[must_use] pub fn response_type(mut self, response_type: ResponseType) -> Self { self.response_type = Some(response_type); self @@ -330,7 +338,7 @@ pub struct Response(ResponseType, reqwest::Response); /// The HTTP response. #[cfg(not(feature = "reqwest-client"))] #[derive(Debug)] -pub struct Response(ResponseType, attohttpc::Response, String); +pub struct Response(ResponseType, attohttpc::Response, Url); impl Response { /// Reads the response as raw bytes. @@ -346,16 +354,27 @@ impl Response { /// Reads the response and returns its info. pub async fn read(self) -> crate::api::Result { #[cfg(feature = "reqwest-client")] - let url = self.1.url().to_string(); + let url = self.1.url().clone(); #[cfg(not(feature = "reqwest-client"))] let url = self.2; let mut headers = HashMap::new(); + let mut raw_headers = HashMap::new(); for (name, value) in self.1.headers() { headers.insert( name.as_str().to_string(), String::from_utf8(value.as_bytes().to_vec())?, ); + raw_headers.insert( + name.as_str().to_string(), + self + .1 + .headers() + .get_all(name) + .into_iter() + .map(|v| String::from_utf8(v.as_bytes().to_vec()).map_err(Into::into)) + .collect::>>()?, + ); } let status = self.1.status().as_u16(); @@ -377,6 +396,7 @@ impl Response { url, status, headers, + raw_headers, data, }) } @@ -398,11 +418,28 @@ pub struct RawResponse { #[non_exhaustive] pub struct ResponseData { /// Response URL. Useful if it followed redirects. - pub url: String, + pub url: Url, /// Response status code. pub status: u16, /// Response headers. pub headers: HashMap, + /// Response raw headers. + pub raw_headers: HashMap>, /// Response data. pub data: Value, } + +#[cfg(test)] +mod test { + use super::ClientBuilder; + use quickcheck::{Arbitrary, Gen}; + + impl Arbitrary for ClientBuilder { + fn arbitrary(g: &mut Gen) -> Self { + Self { + max_redirections: Option::arbitrary(g), + connect_timeout: Option::arbitrary(g), + } + } + } +} diff --git a/core/tauri/src/api/ipc.rs b/core/tauri/src/api/ipc.rs new file mode 100644 index 000000000000..e643ad444241 --- /dev/null +++ b/core/tauri/src/api/ipc.rs @@ -0,0 +1,314 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +//! Types and functions related to Inter Procedure Call(IPC). +//! +//! This module includes utilities to send messages to the JS layer of the webview. + +use serde::{Deserialize, Serialize}; +use serde_json::value::RawValue; +pub use serialize_to_javascript::Options as SerializeOptions; +use serialize_to_javascript::Serialized; + +/// The `Callback` type is the return value of the `transformCallback` JavaScript function. +#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)] +pub struct CallbackFn(pub usize); + +/// The information about this is quite limited. On Chrome/Edge and Firefox, [the maximum string size is approximately 1 GB](https://stackoverflow.com/a/34958490). +/// +/// [From MDN:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length#description) +/// +/// ECMAScript 2016 (ed. 7) established a maximum length of 2^53 - 1 elements. Previously, no maximum length was specified. +/// +/// In Firefox, strings have a maximum length of 2\*\*30 - 2 (~1GB). In versions prior to Firefox 65, the maximum length was 2\*\*28 - 1 (~256MB). +const MAX_JSON_STR_LEN: usize = usize::pow(2, 30) - 2; + +/// Minimum size JSON needs to be in order to convert it to JSON.parse with [`format_json`]. +// TODO: this number should be benchmarked and checked for optimal range, I set 10 KiB arbitrarily +// we don't want to lose the gained object parsing time to extra allocations preparing it +const MIN_JSON_PARSE_LEN: usize = 10_240; + +/// Transforms & escapes a JSON value. +/// +/// If it's an object or array, JSON.parse('{json}') is used, with the '{json}' string properly escaped. +/// The return value of this function can be safely used on [`eval`](crate::Window#method.eval) calls. +/// +/// Single quotes chosen because double quotes are already used in JSON. With single quotes, we only +/// need to escape strings that include backslashes or single quotes. If we used double quotes, then +/// there would be no cases that a string doesn't need escaping. +/// +/// The function takes a closure to handle the escaped string in order to avoid unnecessary allocations. +/// +/// # Safety +/// +/// The ability to safely escape JSON into a JSON.parse('{json}') relies entirely on 2 things. +/// +/// 1. `serde_json`'s ability to correctly escape and format json into a string. +/// 2. JavaScript engines not accepting anything except another unescaped, literal single quote +/// character to end a string that was opened with it. +/// +/// # Example +/// +/// ``` +/// use tauri::api::ipc::{serialize_js_with, SerializeOptions}; +/// #[derive(serde::Serialize)] +/// struct Foo { +/// bar: String, +/// } +/// let foo = Foo { bar: "x".repeat(20_000).into() }; +/// let value = serialize_js_with(&foo, SerializeOptions::default(), |v| format!("console.log({})", v)).unwrap(); +/// assert_eq!(value, format!("console.log(JSON.parse('{{\"bar\":\"{}\"}}'))", foo.bar)); +/// ``` +pub fn serialize_js_with String>( + value: &T, + options: SerializeOptions, + cb: F, +) -> crate::api::Result { + // get a raw &str representation of a serialized json value. + let string = serde_json::to_string(value)?; + let raw = RawValue::from_string(string)?; + + // from here we know json.len() > 1 because an empty string is not a valid json value. + let json = raw.get(); + let first = json.as_bytes()[0]; + + #[cfg(debug_assertions)] + if first == b'"' { + assert!( + json.len() < MAX_JSON_STR_LEN, + "passing a string larger than the max JavaScript literal string size" + ) + } + + let return_val = if json.len() > MIN_JSON_PARSE_LEN && (first == b'{' || first == b'[') { + let serialized = Serialized::new(&raw, &options).into_string(); + // only use JSON.parse('{arg}') for arrays and objects less than the limit + // smaller literals do not benefit from being parsed from json + if serialized.len() < MAX_JSON_STR_LEN { + cb(&serialized) + } else { + cb(json) + } + } else { + cb(json) + }; + + Ok(return_val) +} + +/// Transforms & escapes a JSON value. +/// +/// This is a convenience function for [`serialize_js_with`], simply allocating the result to a String. +/// +/// For usage in functions where performance is more important than code readability, see [`serialize_js_with`]. +/// +/// # Example +/// ```rust,no_run +/// use tauri::{Manager, api::ipc::serialize_js}; +/// use serde::Serialize; +/// +/// #[derive(Serialize)] +/// struct Foo { +/// bar: String, +/// } +/// +/// #[derive(Serialize)] +/// struct Bar { +/// baz: u32, +/// } +/// +/// tauri::Builder::default() +/// .setup(|app| { +/// let window = app.get_window("main").unwrap(); +/// window.eval(&format!( +/// "console.log({}, {})", +/// serialize_js(&Foo { bar: "bar".to_string() }).unwrap(), +/// serialize_js(&Bar { baz: 0 }).unwrap()), +/// ).unwrap(); +/// Ok(()) +/// }); +/// ``` +pub fn serialize_js(value: &T) -> crate::api::Result { + serialize_js_with(value, Default::default(), |v| v.into()) +} + +/// Formats a function name and argument to be evaluated as callback. +/// +/// This will serialize primitive JSON types (e.g. booleans, strings, numbers, etc.) as JavaScript literals, +/// but will serialize arrays and objects whose serialized JSON string is smaller than 1 GB and larger +/// than 10 KiB with `JSON.parse('...')`. +/// See [json-parse-benchmark](https://github.com/GoogleChromeLabs/json-parse-benchmark). +/// +/// # Examples +/// - With string literals: +/// ``` +/// use tauri::api::ipc::{CallbackFn, format_callback}; +/// // callback with a string argument +/// let cb = format_callback(CallbackFn(12345), &"the string response").unwrap(); +/// assert!(cb.contains(r#"window["_12345"]("the string response")"#)); +/// ``` +/// +/// - With types implement [`serde::Serialize`]: +/// ``` +/// use tauri::api::ipc::{CallbackFn, format_callback}; +/// use serde::Serialize; +/// +/// // callback with large JSON argument +/// #[derive(Serialize)] +/// struct MyResponse { +/// value: String +/// } +/// +/// let cb = format_callback( +/// CallbackFn(6789), +/// &MyResponse { value: String::from_utf8(vec![b'X'; 10_240]).unwrap() +/// }).expect("failed to serialize"); +/// +/// assert!(cb.contains(r#"window["_6789"](JSON.parse('{"value":"XXXXXXXXX"#)); +/// ``` +pub fn format_callback( + function_name: CallbackFn, + arg: &T, +) -> crate::api::Result { + serialize_js_with(arg, Default::default(), |arg| { + format!( + r#" + if (window["_{fn}"]) {{ + window["_{fn}"]({arg}) + }} else {{ + console.warn("[TAURI] Couldn't find callback id {fn} in window. This happens when the app is reloaded while Rust is running an asynchronous operation.") + }}"#, + fn = function_name.0, + arg = arg + ) + }) +} + +/// Formats a Result type to its Promise response. +/// Useful for Promises handling. +/// If the Result `is_ok()`, the callback will be the `success_callback` function name and the argument will be the Ok value. +/// If the Result `is_err()`, the callback will be the `error_callback` function name and the argument will be the Err value. +/// +/// * `result` the Result to check +/// * `success_callback` the function name of the Ok callback. Usually the `resolve` of the JS Promise. +/// * `error_callback` the function name of the Err callback. Usually the `reject` of the JS Promise. +/// +/// Note that the callback strings are automatically generated by the `invoke` helper. +/// +/// # Examples +/// ``` +/// use tauri::api::ipc::{CallbackFn, format_callback_result}; +/// let res: Result = Ok(5); +/// let cb = format_callback_result(res, CallbackFn(145), CallbackFn(0)).expect("failed to format"); +/// assert!(cb.contains(r#"window["_145"](5)"#)); +/// +/// let res: Result<&str, &str> = Err("error message here"); +/// let cb = format_callback_result(res, CallbackFn(2), CallbackFn(1)).expect("failed to format"); +/// assert!(cb.contains(r#"window["_1"]("error message here")"#)); +/// ``` +// TODO: better example to explain +pub fn format_callback_result( + result: Result, + success_callback: CallbackFn, + error_callback: CallbackFn, +) -> crate::api::Result { + match result { + Ok(res) => format_callback(success_callback, &res), + Err(err) => format_callback(error_callback, &err), + } +} + +#[cfg(test)] +mod test { + use crate::api::ipc::*; + use quickcheck::{Arbitrary, Gen}; + use quickcheck_macros::quickcheck; + + impl Arbitrary for CallbackFn { + fn arbitrary(g: &mut Gen) -> CallbackFn { + CallbackFn(usize::arbitrary(g)) + } + } + + #[test] + fn test_serialize_js() { + assert_eq!(serialize_js(&()).unwrap(), "null"); + assert_eq!(serialize_js(&5i32).unwrap(), "5"); + + #[derive(serde::Serialize)] + struct JsonObj { + value: String, + } + + let raw_str = "T".repeat(MIN_JSON_PARSE_LEN); + assert_eq!(serialize_js(&raw_str).unwrap(), format!("\"{}\"", raw_str)); + + assert_eq!( + serialize_js(&JsonObj { + value: raw_str.clone() + }) + .unwrap(), + format!("JSON.parse('{{\"value\":\"{}\"}}')", raw_str) + ); + + assert_eq!( + serialize_js(&JsonObj { + value: format!("\"{}\"", raw_str) + }) + .unwrap(), + format!("JSON.parse('{{\"value\":\"\\\\\"{}\\\\\"\"}}')", raw_str) + ); + + let dangerous_json = RawValue::from_string( + r#"{"test":"don\\🚀🐱‍👤\\'t forget to escape me!🚀🐱‍👤","te🚀🐱‍👤st2":"don't forget to escape me!","test3":"\\🚀🐱‍👤\\\\'''\\\\🚀🐱‍👤\\\\🚀🐱‍👤\\'''''"}"#.into() + ).unwrap(); + + let definitely_escaped_dangerous_json = format!( + "JSON.parse('{}')", + dangerous_json + .get() + .replace('\\', "\\\\") + .replace('\'', "\\'") + ); + let escape_single_quoted_json_test = + serialize_to_javascript::Serialized::new(&dangerous_json, &Default::default()).into_string(); + + let result = r#"JSON.parse('{"test":"don\\\\🚀🐱‍👤\\\\\'t forget to escape me!🚀🐱‍👤","te🚀🐱‍👤st2":"don\'t forget to escape me!","test3":"\\\\🚀🐱‍👤\\\\\\\\\'\'\'\\\\\\\\🚀🐱‍👤\\\\\\\\🚀🐱‍👤\\\\\'\'\'\'\'"}')"#; + assert_eq!(definitely_escaped_dangerous_json, result); + assert_eq!(escape_single_quoted_json_test, result); + } + + // check abritrary strings in the format callback function + #[quickcheck] + fn qc_formating(f: CallbackFn, a: String) -> bool { + // call format callback + let fc = format_callback(f, &a).unwrap(); + fc.contains(&format!( + r#"window["_{}"](JSON.parse('{}'))"#, + f.0, + serde_json::Value::String(a.clone()), + )) || fc.contains(&format!( + r#"window["_{}"]({})"#, + f.0, + serde_json::Value::String(a), + )) + } + + // check arbitrary strings in format_callback_result + #[quickcheck] + fn qc_format_res(result: Result, c: CallbackFn, ec: CallbackFn) -> bool { + let resp = + format_callback_result(result.clone(), c, ec).expect("failed to format callback result"); + let (function, value) = match result { + Ok(v) => (c, v), + Err(e) => (ec, e), + }; + + resp.contains(&format!( + r#"window["_{}"]({})"#, + function.0, + serde_json::Value::String(value), + )) + } +} diff --git a/core/tauri/src/api/mod.rs b/core/tauri/src/api/mod.rs index 732a155917cc..83aa6f414747 100644 --- a/core/tauri/src/api/mod.rs +++ b/core/tauri/src/api/mod.rs @@ -3,17 +3,20 @@ // SPDX-License-Identifier: MIT //! The Tauri API interface. -#![warn(missing_docs)] -// #![feature(const_int_pow)] +#[cfg(feature = "dialog")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "dialog")))] pub mod dialog; pub mod dir; pub mod file; +#[cfg(feature = "http-api")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "http-api")))] pub mod http; +pub mod ipc; pub mod path; pub mod process; -pub mod rpc; -#[cfg(shell_open)] +#[cfg(feature = "shell-open-api")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "shell-open-api")))] pub mod shell; pub mod version; @@ -25,7 +28,8 @@ pub mod cli; #[cfg_attr(doc_cfg, doc(cfg(feature = "cli")))] pub use clap; -#[cfg(notification_all)] +#[cfg(feature = "notification")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "notification")))] pub mod notification; mod error; diff --git a/core/tauri/src/api/notification.rs b/core/tauri/src/api/notification.rs index 75d23b310c14..e93076988b6f 100644 --- a/core/tauri/src/api/notification.rs +++ b/core/tauri/src/api/notification.rs @@ -43,18 +43,21 @@ impl Notification { } /// Sets the notification body. + #[must_use] pub fn body(mut self, body: impl Into) -> Self { self.body = Some(body.into()); self } /// Sets the notification title. + #[must_use] pub fn title(mut self, title: impl Into) -> Self { self.title = Some(title.into()); self } /// Sets the notification icon. + #[must_use] pub fn icon(mut self, icon: impl Into) -> Self { self.icon = Some(icon.into()); self @@ -74,7 +77,7 @@ impl Notification { } #[cfg(windows)] { - let exe = std::env::current_exe()?; + let exe = tauri_utils::platform::current_exe()?; let exe_dir = exe.parent().expect("failed to get exe directory"); let curr_dir = exe_dir.display().to_string(); // set the notification's System.AppUserModel.ID only when running the installed app diff --git a/core/tauri/src/api/path.rs b/core/tauri/src/api/path.rs index 2fc007353575..ab0ec5838e57 100644 --- a/core/tauri/src/api/path.rs +++ b/core/tauri/src/api/path.rs @@ -4,12 +4,9 @@ //! Types and functions related to file system path operations. -use std::{ - env, - path::{Component, Path, PathBuf}, -}; +use std::path::{Component, Path, PathBuf}; -use crate::{Config, PackageInfo}; +use crate::{Config, Env, PackageInfo}; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -60,8 +57,97 @@ pub enum BaseDirectory { /// The default App config directory. /// Resolves to [`BaseDirectory::Config`]. App, - /// The current working directory. - Current, + /// The Log directory. + /// Resolves to [`BaseDirectory::Home/Library/Logs/{bundle_identifier}`] on macOS + /// and [`BaseDirectory::Config/{bundle_identifier}/logs`] on linux and windows. + Log, +} + +impl BaseDirectory { + /// Gets the variable that represents this [`BaseDirectory`] for string paths. + pub fn variable(self) -> &'static str { + match self { + Self::Audio => "$AUDIO", + Self::Cache => "$CACHE", + Self::Config => "$CONFIG", + Self::Data => "$DATA", + Self::LocalData => "$LOCALDATA", + Self::Desktop => "$DESKTOP", + Self::Document => "$DOCUMENT", + Self::Download => "$DOWNLOAD", + Self::Executable => "$EXE", + Self::Font => "$FONT", + Self::Home => "$HOME", + Self::Picture => "$PICTURE", + Self::Public => "$PUBLIC", + Self::Runtime => "$RUNTIME", + Self::Template => "$TEMPLATE", + Self::Video => "$VIDEO", + Self::Resource => "$RESOURCE", + Self::App => "$APP", + Self::Log => "$LOG", + } + } + + /// Gets the [`BaseDirectory`] associated with the given variable, or [`None`] if the variable doesn't match any. + pub fn from_variable(variable: &str) -> Option { + let res = match variable { + "$AUDIO" => Self::Audio, + "$CACHE" => Self::Cache, + "$CONFIG" => Self::Config, + "$DATA" => Self::Data, + "$LOCALDATA" => Self::LocalData, + "$DESKTOP" => Self::Desktop, + "$DOCUMENT" => Self::Document, + "$DOWNLOAD" => Self::Download, + "$EXE" => Self::Executable, + "$FONT" => Self::Font, + "$HOME" => Self::Home, + "$PICTURE" => Self::Picture, + "$PUBLIC" => Self::Public, + "$RUNTIME" => Self::Runtime, + "$TEMPLATE" => Self::Template, + "$VIDEO" => Self::Video, + "$RESOURCE" => Self::Resource, + "$APP" => Self::App, + "$LOG" => Self::Log, + _ => return None, + }; + Some(res) + } +} + +/// Parse the given path, resolving a [`BaseDirectory`] variable if the path starts with one. +pub fn parse>( + config: &Config, + package_info: &PackageInfo, + env: &Env, + path: P, +) -> crate::api::Result { + let mut p = PathBuf::new(); + let mut components = path.as_ref().components(); + if let Some(Component::Normal(str)) = components.next() { + if let Some(base_directory) = BaseDirectory::from_variable(&str.to_string_lossy()) { + p.push(resolve_path( + config, + package_info, + env, + "", + Some(base_directory), + )?); + } else { + p.push(str); + } + } + + for component in components { + if let Component::ParentDir = component { + continue; + } + p.push(component); + } + + Ok(p) } /// Resolves the path with the optional base directory. @@ -76,7 +162,10 @@ pub enum BaseDirectory { /// &PackageInfo { /// name: "app".into(), /// version: "1.0.0".into(), +/// authors: "tauri", +/// description: "a tauri test", /// }, +/// &Default::default(), /// "path/to/something", /// Some(BaseDirectory::Config) /// ).expect("failed to resolve path"); @@ -85,6 +174,7 @@ pub enum BaseDirectory { pub fn resolve_path>( config: &Config, package_info: &PackageInfo, + env: &Env, path: P, dir: Option, ) -> crate::api::Result { @@ -107,9 +197,9 @@ pub fn resolve_path>( BaseDirectory::Runtime => runtime_dir(), BaseDirectory::Template => template_dir(), BaseDirectory::Video => video_dir(), - BaseDirectory::Resource => resource_dir(package_info), + BaseDirectory::Resource => resource_dir(package_info, env), BaseDirectory::App => app_dir(config), - BaseDirectory::Current => Some(env::current_dir()?), + BaseDirectory::Log => log_dir(config), }; if let Some(mut base_dir_path_value) = base_dir_path { // use the same path resolution mechanism as the bundler's resource injection algorithm @@ -222,11 +312,27 @@ pub fn video_dir() -> Option { } /// Returns the path to the resource directory of this app. -pub fn resource_dir(package_info: &PackageInfo) -> Option { - crate::utils::platform::resource_dir(package_info).ok() +pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> Option { + crate::utils::platform::resource_dir(package_info, env).ok() } /// Returns the path to the suggested directory for your app config files. pub fn app_dir(config: &Config) -> Option { dirs_next::config_dir().map(|dir| dir.join(&config.tauri.bundle.identifier)) } + +/// Returns the path to the suggested log directory. +pub fn log_dir(config: &Config) -> Option { + #[cfg(target_os = "macos")] + let path = dirs_next::home_dir().map(|dir| { + dir + .join("Library/Logs") + .join(&config.tauri.bundle.identifier) + }); + + #[cfg(not(target_os = "macos"))] + let path = + dirs_next::config_dir().map(|dir| dir.join(&config.tauri.bundle.identifier).join("logs")); + + path +} diff --git a/core/tauri/src/api/process.rs b/core/tauri/src/api/process.rs index fb3a55b47f6d..72544ea775fa 100644 --- a/core/tauri/src/api/process.rs +++ b/core/tauri/src/api/process.rs @@ -4,42 +4,60 @@ //! Types and functions related to child processes management. -use std::{ - env, - path::PathBuf, - process::{exit, Command as StdCommand}, -}; +use crate::Env; -#[cfg(shell_execute)] +use std::path::PathBuf; + +#[cfg(feature = "command")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "command")))] mod command; -#[cfg(shell_execute)] +#[cfg(feature = "command")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "command")))] pub use command::*; -/// Gets the current binary. -pub fn current_binary() -> Option { - let mut current_binary = None; - - // if we are running with an APP Image, we should return the app image path +/// Finds the current running binary's path. +/// +/// With exception to any following platform-specific behavior, the path is cached as soon as +/// possible, and then used repeatedly instead of querying for a new path every time this function +/// is called. +/// +/// # Platform-specific behavior +/// +/// ## Linux +/// +/// On Linux, this function will **attempt** to detect if it's currently running from a +/// valid [AppImage] and use that path instead. +/// +/// ## macOS +/// +/// On `macOS`, this function will return an error if the original path contained any symlinks +/// due to less protection on macOS regarding symlinks. This behavior can be disabled by setting the +/// `process-relaunch-dangerous-allow-symlink-macos` feature, although it is *highly discouraged*. +/// +/// # Security +/// +/// See [`tauri_utils::platform::current_exe`] for possible security implications. +/// +/// [AppImage]: https://appimage.org/ +pub fn current_binary(_env: &Env) -> std::io::Result { + // if we are running from an AppImage, we ONLY want the set AppImage path #[cfg(target_os = "linux")] - if let Some(app_image_path) = env::var_os("APPIMAGE") { - current_binary = Some(PathBuf::from(app_image_path)); + if let Some(app_image_path) = &_env.appimage { + return Ok(PathBuf::from(app_image_path)); } - // if we didn't extracted binary in previous step, - // let use the current_exe from current environment - if current_binary.is_none() { - if let Ok(current_process) = env::current_exe() { - current_binary = Some(current_process); - } - } - - current_binary + tauri_utils::platform::current_exe() } -/// Restarts the process. -pub fn restart() { - if let Some(path) = current_binary() { - StdCommand::new(path) +/// Restarts the currently running binary. +/// +/// See [`current_binary`] for platform specific behavior, and +/// [`tauri_utils::platform::current_exe`] for possible security implications. +pub fn restart(env: &Env) { + use std::process::{exit, Command}; + + if let Ok(path) = current_binary(env) { + Command::new(path) .spawn() .expect("application failed to start"); } diff --git a/core/tauri/src/api/process/command.rs b/core/tauri/src/api/process/command.rs index 8c83300c83f3..d81116aaf36a 100644 --- a/core/tauri/src/api/process/command.rs +++ b/core/tauri/src/api/process/command.rs @@ -150,26 +150,12 @@ pub struct Output { pub stderr: String, } -#[cfg(not(windows))] fn relative_command_path(command: String) -> crate::Result { - match std::env::current_exe()?.parent() { - Some(exe_dir) => Ok(format!( - "{}/{}", - exe_dir.to_string_lossy().to_string(), - command - )), - None => Err(crate::api::Error::Command("Could not evaluate executable dir".to_string()).into()), - } -} - -#[cfg(windows)] -fn relative_command_path(command: String) -> crate::Result { - match std::env::current_exe()?.parent() { - Some(exe_dir) => Ok(format!( - "{}/{}.exe", - exe_dir.to_string_lossy().to_string(), - command - )), + match platform::current_exe()?.parent() { + #[cfg(windows)] + Some(exe_dir) => Ok(format!("{}\\{}.exe", exe_dir.display(), command)), + #[cfg(not(windows))] + Some(exe_dir) => Ok(format!("{}/{}", exe_dir.display(), command)), None => Err(crate::api::Error::Command("Could not evaluate executable dir".to_string()).into()), } } @@ -191,15 +177,11 @@ impl Command { /// A sidecar program is a embedded external binary in order to make your application work /// or to prevent users having to install additional dependencies (e.g. Node.js, Python, etc). pub fn new_sidecar>(program: S) -> crate::Result { - let program = format!( - "{}-{}", - program.into(), - platform::target_triple().expect("unsupported platform") - ); - Ok(Self::new(relative_command_path(program)?)) + Ok(Self::new(relative_command_path(program.into())?)) } /// Appends arguments to the command. + #[must_use] pub fn args(mut self, args: I) -> Self where I: IntoIterator, @@ -212,18 +194,21 @@ impl Command { } /// Clears the entire environment map for the child process. + #[must_use] pub fn env_clear(mut self) -> Self { self.env_clear = true; self } /// Adds or updates multiple environment variable mappings. + #[must_use] pub fn envs(mut self, env: HashMap) -> Self { self.env = env; self } /// Sets the working directory for the child process. + #[must_use] pub fn current_dir(mut self, current_dir: PathBuf) -> Self { self.current_dir.replace(current_dir); self @@ -316,7 +301,7 @@ impl Command { /// Stdin, stdout and stderr are ignored. pub fn status(self) -> crate::api::Result { let (mut rx, _child) = self.spawn()?; - let code = crate::async_runtime::block_on(async move { + let code = crate::async_runtime::safe_block_on(async move { let mut code = None; #[allow(clippy::collapsible_match)] while let Some(event) = rx.recv().await { @@ -334,7 +319,7 @@ impl Command { pub fn output(self) -> crate::api::Result { let (mut rx, _child) = self.spawn()?; - let output = crate::async_runtime::block_on(async move { + let output = crate::async_runtime::safe_block_on(async move { let mut code = None; let mut stdout = String::new(); let mut stderr = String::new(); diff --git a/core/tauri/src/api/rpc.rs b/core/tauri/src/api/rpc.rs deleted file mode 100644 index 42fc2914bca3..000000000000 --- a/core/tauri/src/api/rpc.rs +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -//! Types and functions related to Remote Procedure Call(RPC). -//! -//! This module includes utilities to send messages to the JS layer of the webview. - -use serde::Serialize; -use serde_json::value::RawValue; - -/// The information about this is quite limited. On Chrome/Edge and Firefox, [the maximum string size is approximately 1 GB](https://stackoverflow.com/a/34958490). -/// -/// [From MDN:](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length#description) -/// -/// ECMAScript 2016 (ed. 7) established a maximum length of 2^53 - 1 elements. Previously, no maximum length was specified. -/// -/// In Firefox, strings have a maximum length of 2\*\*30 - 2 (~1GB). In versions prior to Firefox 65, the maximum length was 2\*\*28 - 1 (~256MB). -const MAX_JSON_STR_LEN: usize = usize::pow(2, 30) - 2; - -/// Minimum size JSON needs to be in order to convert it to JSON.parse with [`escape_json_parse`]. -// TODO: this number should be benchmarked and checked for optimal range, I set 10 KiB arbitrarily -// we don't want to lose the gained object parsing time to extra allocations preparing it -const MIN_JSON_PARSE_LEN: usize = 10_240; - -/// Transforms & escapes a JSON String -> JSON.parse('{json}') -/// -/// Single quotes chosen because double quotes are already used in JSON. With single quotes, we only -/// need to escape strings that include backslashes or single quotes. If we used double quotes, then -/// there would be no cases that a string doesn't need escaping. -/// -/// # Safety -/// -/// The ability to safely escape JSON into a JSON.parse('{json}') relies entirely on 2 things. -/// -/// 1. `serde_json`'s ability to correctly escape and format json into a string. -/// 2. JavaScript engines not accepting anything except another unescaped, literal single quote -/// character to end a string that was opened with it. -fn escape_json_parse(json: &RawValue) -> String { - let json = json.get(); - - // 14 chars in JSON.parse('') - // todo: should we increase the 14 by x to allow x amount of escapes before another allocation? - let mut s = String::with_capacity(json.len() + 14); - s.push_str("JSON.parse('"); - - // insert a backslash before any backslash or single quote characters. - let mut last = 0; - for (idx, _) in json.match_indices(|c| c == '\\' || c == '\'') { - s.push_str(&json[last..idx]); - s.push('\\'); - last = idx; - } - - // finish appending the trailing characters that don't need escaping - s.push_str(&json[last..]); - s.push_str("')"); - s -} - -/// Formats a function name and argument to be evaluated as callback. -/// -/// This will serialize primitive JSON types (e.g. booleans, strings, numbers, etc.) as JavaScript literals, -/// but will serialize arrays and objects whose serialized JSON string is smaller than 1 GB and larger -/// than 10 KiB with `JSON.parse('...')`. -/// See [json-parse-benchmark](https://github.com/GoogleChromeLabs/json-parse-benchmark). -/// -/// # Examples -/// - With string literals: -/// ``` -/// use tauri::api::rpc::format_callback; -/// // callback with a string argument -/// let cb = format_callback("callback-function-name", &"the string response").unwrap(); -/// assert!(cb.contains(r#"window["callback-function-name"]("the string response")"#)); -/// ``` -/// -/// - With types implement [`serde::Serialize`]: -/// ``` -/// use tauri::api::rpc::format_callback; -/// use serde::Serialize; -/// -/// // callback with large JSON argument -/// #[derive(Serialize)] -/// struct MyResponse { -/// value: String -/// } -/// -/// let cb = format_callback( -/// "callback-function-name", -/// &MyResponse { value: String::from_utf8(vec![b'X'; 10_240]).unwrap() -/// }).expect("failed to serialize"); -/// -/// assert!(cb.contains(r#"window["callback-function-name"](JSON.parse('{"value":"XXXXXXXXX"#)); -/// ``` -pub fn format_callback>( - function_name: S, - arg: &T, -) -> crate::api::Result { - macro_rules! format_callback { - ( $arg:expr ) => { - format!( - r#" - if (window["{fn}"]) {{ - window["{fn}"]({arg}) - }} else {{ - console.warn("[TAURI] Couldn't find callback id {fn} in window. This happens when the app is reloaded while Rust is running an asynchronous operation.") - }} - "#, - fn = function_name.as_ref(), - arg = $arg - ) - } - } - - // get a raw &str representation of a serialized json value. - let string = serde_json::to_string(arg)?; - let raw = RawValue::from_string(string)?; - - // from here we know json.len() > 1 because an empty string is not a valid json value. - let json = raw.get(); - let first = json.as_bytes()[0]; - - #[cfg(debug_assertions)] - if first == b'"' { - debug_assert!( - json.len() < MAX_JSON_STR_LEN, - "passing a callback string larger than the max JavaScript literal string size" - ) - } - - // only use JSON.parse('{arg}') for arrays and objects less than the limit - // smaller literals do not benefit from being parsed from json - Ok( - if json.len() > MIN_JSON_PARSE_LEN && (first == b'{' || first == b'[') { - let escaped = escape_json_parse(&raw); - if escaped.len() < MAX_JSON_STR_LEN { - format_callback!(escaped) - } else { - format_callback!(json) - } - } else { - format_callback!(json) - }, - ) -} - -/// Formats a Result type to its Promise response. -/// Useful for Promises handling. -/// If the Result `is_ok()`, the callback will be the `success_callback` function name and the argument will be the Ok value. -/// If the Result `is_err()`, the callback will be the `error_callback` function name and the argument will be the Err value. -/// -/// * `result` the Result to check -/// * `success_callback` the function name of the Ok callback. Usually the `resolve` of the JS Promise. -/// * `error_callback` the function name of the Err callback. Usually the `reject` of the JS Promise. -/// -/// Note that the callback strings are automatically generated by the `invoke` helper. -/// -/// # Examples -/// ``` -/// use tauri::api::rpc::format_callback_result; -/// let res: Result = Ok(5); -/// let cb = format_callback_result(res, "success_cb", "error_cb").expect("failed to format"); -/// assert!(cb.contains(r#"window["success_cb"](5)"#)); -/// -/// let res: Result<&str, &str> = Err("error message here"); -/// let cb = format_callback_result(res, "success_cb", "error_cb").expect("failed to format"); -/// assert!(cb.contains(r#"window["error_cb"]("error message here")"#)); -/// ``` -// TODO: better example to explain -pub fn format_callback_result( - result: Result, - success_callback: impl AsRef, - error_callback: impl AsRef, -) -> crate::api::Result { - match result { - Ok(res) => format_callback(success_callback, &res), - Err(err) => format_callback(error_callback, &err), - } -} - -#[cfg(test)] -mod test { - use crate::api::rpc::*; - use quickcheck_macros::quickcheck; - - #[test] - fn test_escape_json_parse() { - let dangerous_json = RawValue::from_string( - r#"{"test":"don\\🚀🐱‍👤\\'t forget to escape me!🚀🐱‍👤","te🚀🐱‍👤st2":"don't forget to escape me!","test3":"\\🚀🐱‍👤\\\\'''\\\\🚀🐱‍👤\\\\🚀🐱‍👤\\'''''"}"#.into() - ).unwrap(); - - let definitely_escaped_dangerous_json = format!( - "JSON.parse('{}')", - dangerous_json - .get() - .replace('\\', "\\\\") - .replace('\'', "\\'") - ); - let escape_single_quoted_json_test = escape_json_parse(&dangerous_json); - - let result = r#"JSON.parse('{"test":"don\\\\🚀🐱‍👤\\\\\'t forget to escape me!🚀🐱‍👤","te🚀🐱‍👤st2":"don\'t forget to escape me!","test3":"\\\\🚀🐱‍👤\\\\\\\\\'\'\'\\\\\\\\🚀🐱‍👤\\\\\\\\🚀🐱‍👤\\\\\'\'\'\'\'"}')"#; - assert_eq!(definitely_escaped_dangerous_json, result); - assert_eq!(escape_single_quoted_json_test, result); - } - - // check abritrary strings in the format callback function - #[quickcheck] - fn qc_formating(f: String, a: String) -> bool { - // can not accept empty strings - if !f.is_empty() && !a.is_empty() { - // call format callback - let fc = format_callback(f.clone(), &a).unwrap(); - fc.contains(&format!( - r#"window["{}"](JSON.parse('{}'))"#, - f, - serde_json::Value::String(a.clone()), - )) || fc.contains(&format!( - r#"window["{}"]({})"#, - f, - serde_json::Value::String(a), - )) - } else { - true - } - } - - // check arbitrary strings in format_callback_result - #[quickcheck] - fn qc_format_res(result: Result, c: String, ec: String) -> bool { - let resp = format_callback_result(result.clone(), c.clone(), ec.clone()) - .expect("failed to format callback result"); - let (function, value) = match result { - Ok(v) => (c, v), - Err(e) => (ec, e), - }; - - resp.contains(&format!( - r#"window["{}"]({})"#, - function, - serde_json::Value::String(value), - )) - } -} diff --git a/core/tauri/src/api/shell.rs b/core/tauri/src/api/shell.rs index c6a6bcafd282..075621e23932 100644 --- a/core/tauri/src/api/shell.rs +++ b/core/tauri/src/api/shell.rs @@ -4,15 +4,97 @@ //! Types and functions related to shell. -/// Opens path or URL with program specified in `with`, or system default if `None`. -pub fn open(path: String, with: Option) -> crate::api::Result<()> { - { - let exit_status = if let Some(with) = with { - open::with(&path, &with) - } else { - open::that(&path) +use crate::ShellScope; +use std::str::FromStr; + +/// Program to use on the [`open()`] call. +pub enum Program { + /// Use the `open` program. + Open, + /// Use the `start` program. + Start, + /// Use the `xdg-open` program. + XdgOpen, + /// Use the `gio` program. + Gio, + /// Use the `gnome-open` program. + GnomeOpen, + /// Use the `kde-open` program. + KdeOpen, + /// Use the `wslview` program. + WslView, + /// Use the `Firefox` program. + Firefox, + /// Use the `Google Chrome` program. + Chrome, + /// Use the `Chromium` program. + Chromium, + /// Use the `Safari` program. + Safari, +} + +impl FromStr for Program { + type Err = super::Error; + + fn from_str(s: &str) -> Result { + let p = match s.to_lowercase().as_str() { + "open" => Self::Open, + "start" => Self::Start, + "xdg-open" => Self::XdgOpen, + "gio" => Self::Gio, + "gnome-open" => Self::GnomeOpen, + "kde-open" => Self::KdeOpen, + "wslview" => Self::WslView, + "firefox" => Self::Firefox, + "chrome" | "google chrome" => Self::Chrome, + "chromium" => Self::Chromium, + "safari" => Self::Safari, + _ => return Err(super::Error::UnknownProgramName(s.to_string())), }; - exit_status - .map_err(|err| crate::api::Error::Shell(format!("failed to open: {}", err.to_string()))) + Ok(p) } } + +impl Program { + pub(crate) fn name(self) -> &'static str { + match self { + Self::Open => "open", + Self::Start => "start", + Self::XdgOpen => "xdg-open", + Self::Gio => "gio", + Self::GnomeOpen => "gnome-open", + Self::KdeOpen => "kde-open", + Self::WslView => "wslview", + + #[cfg(target_os = "macos")] + Self::Firefox => "Firefox", + #[cfg(not(target_os = "macos"))] + Self::Firefox => "firefox", + + #[cfg(target_os = "macos")] + Self::Chrome => "Google Chrome", + #[cfg(not(target_os = "macos"))] + Self::Chrome => "google-chrome", + + #[cfg(target_os = "macos")] + Self::Chromium => "Chromium", + #[cfg(not(target_os = "macos"))] + Self::Chromium => "chromium", + + #[cfg(target_os = "macos")] + Self::Safari => "Safari", + #[cfg(not(target_os = "macos"))] + Self::Safari => "safari", + } + } +} + +/// Opens path or URL with program specified in `with`, or system default if `None`. +/// +/// The path will be matched against the shell open validation regex, defaulting to `^https?://`. +/// A custom validation regex may be supplied in the config in `tauri > allowlist > scope > open`. +pub fn open(scope: &ShellScope, path: String, with: Option) -> crate::api::Result<()> { + scope + .open(&path, with) + .map_err(|err| crate::api::Error::Shell(format!("failed to open: {}", err))) +} diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index 530b5ceeeca4..3763531513aa 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -6,34 +6,40 @@ pub(crate) mod tray; use crate::{ + api::ipc::CallbackFn, command::{CommandArg, CommandItem}, - hooks::{InvokeHandler, OnPageLoad, PageLoadPayload, SetupHook}, - manager::{CustomProtocol, WindowManager}, + hooks::{ + window_invoke_responder, InvokeHandler, InvokeResponder, OnPageLoad, PageLoadPayload, SetupHook, + }, + manager::{Asset, CustomProtocol, WindowManager}, plugin::{Plugin, PluginStore}, runtime::{ http::{Request as HttpRequest, Response as HttpResponse}, webview::{WebviewAttributes, WindowBuilder}, window::{PendingWindow, WindowEvent}, - Dispatch, ExitRequestedEventAction, RunEvent, Runtime, + Dispatch, ExitRequestedEventAction, RunEvent as RuntimeRunEvent, Runtime, }, + scope::FsScope, sealed::{ManagerBase, RuntimeOrDispatch}, - utils::assets::Assets, utils::config::{Config, WindowUrl}, - Context, Invoke, InvokeError, Manager, StateManager, Window, + utils::{assets::Assets, Env}, + Context, Invoke, InvokeError, InvokeResponse, Manager, Scopes, StateManager, Window, }; +#[cfg(shell_scope)] +use crate::scope::ShellScope; + use tauri_macros::default_runtime; use tauri_utils::PackageInfo; use std::{ collections::HashMap, path::PathBuf, - sync::{mpsc::Sender, Arc}, + sync::{mpsc::Sender, Arc, Weak}, }; use crate::runtime::menu::{Menu, MenuId, MenuIdRef}; -#[cfg(all(windows, feature = "system-tray"))] use crate::runtime::RuntimeHandle; #[cfg(feature = "system-tray")] use crate::runtime::{Icon, SystemTrayEvent as RuntimeSystemTrayEvent}; @@ -74,7 +80,7 @@ impl CloseRequestApi { /// An application event, triggered from the event loop. #[derive(Debug)] #[non_exhaustive] -pub enum Event { +pub enum RunEvent { /// Event loop is exiting. Exit, /// The app is about to exit @@ -149,6 +155,7 @@ impl GlobalWindowEvent { /// The path resolver is a helper for the application-specific [`crate::api::path`] APIs. #[derive(Debug, Clone)] pub struct PathResolver { + env: Env, config: Arc, package_info: PackageInfo, } @@ -156,13 +163,31 @@ pub struct PathResolver { impl PathResolver { /// Returns the path to the resource directory of this app. pub fn resource_dir(&self) -> Option { - crate::api::path::resource_dir(&self.package_info) + crate::api::path::resource_dir(&self.package_info, &self.env) } /// Returns the path to the suggested directory for your app config files. pub fn app_dir(&self) -> Option { crate::api::path::app_dir(&self.config) } + + /// Returns the path to the suggested log directory. + pub fn log_dir(&self) -> Option { + crate::api::path::log_dir(&self.config) + } +} + +/// The asset resolver is a helper to access the [`tauri_utils::assets::Assets`] interface. +#[derive(Debug, Clone)] +pub struct AssetResolver { + manager: WindowManager, +} + +impl AssetResolver { + /// Gets the app asset associated with the given path. + pub fn get(&self, path: String) -> Option { + self.manager.get_asset(path).ok() + } } /// A handle to the currently running application. @@ -187,7 +212,7 @@ impl AppHandle { >( &self, f: F, - ) -> crate::Result> { + ) -> crate::Result> { self.runtime_handle.create_tao_window(f).map_err(Into::into) } @@ -225,6 +250,14 @@ impl<'de, R: Runtime> CommandArg<'de, R> for AppHandle { } impl AppHandle { + /// Runs the given closure on the main thread. + pub fn run_on_main_thread(&self, f: F) -> crate::Result<()> { + self + .runtime_handle + .run_on_main_thread(f) + .map_err(Into::into) + } + /// Removes the system tray. #[cfg(all(windows, feature = "system-tray"))] #[cfg_attr(doc_cfg, doc(cfg(all(windows, feature = "system-tray"))))] @@ -324,12 +357,14 @@ macro_rules! shared_app_impl { ($app: ty) => { impl $app { /// Creates a new webview window. + /// + /// Data URLs are only supported with the `window-data-url` feature flag. pub fn create_window( &self, label: impl Into, url: WindowUrl, setup: F, - ) -> crate::Result<()> + ) -> crate::Result> where F: FnOnce( ::WindowBuilder, @@ -347,8 +382,7 @@ macro_rules! shared_app_impl { window_builder, webview_attributes, label, - ))?; - Ok(()) + )) } #[cfg(feature = "system-tray")] @@ -364,6 +398,7 @@ macro_rules! shared_app_impl { /// The path resolver for the application. pub fn path_resolver(&self) -> PathResolver { PathResolver { + env: self.state::().inner().clone(), config: self.manager.config(), package_info: self.manager.package_info().clone(), } @@ -388,6 +423,13 @@ macro_rules! shared_app_impl { pub fn package_info(&self) -> &PackageInfo { self.manager.package_info() } + + /// The application's asset resolver. + pub fn asset_resolver(&self) -> AssetResolver { + AssetResolver { + manager: self.manager.clone(), + } + } } }; } @@ -404,15 +446,14 @@ impl App { /// Sets the activation policy for the application. It is set to `NSApplicationActivationPolicyRegular` by default. /// /// # Example - /// ```rust,ignore - /// fn main() { - /// let mut app = tauri::Builder::default() - /// .build(tauri::generate_context!()) - /// .expect("error while building tauri application"); - /// #[cfg(target_os = "macos")] - /// app.set_activation_policy(tauri::ActivationPolicy::Accessory); - /// app.run(|_app_handle, _event| {}); - /// } + /// ```rust,no_run + /// let mut app = tauri::Builder::default() + /// // on an actual app, remove the string argument + /// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("error while building tauri application"); + /// #[cfg(target_os = "macos")] + /// app.set_activation_policy(tauri::ActivationPolicy::Accessory); + /// app.run(|_app_handle, _event| {}); /// ``` #[cfg(target_os = "macos")] #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))] @@ -425,36 +466,36 @@ impl App { } /// Runs the application. - pub fn run, Event) + 'static>(mut self, callback: F) { + /// + /// # Example + /// ```rust,no_run + /// let app = tauri::Builder::default() + /// // on an actual app, remove the string argument + /// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("error while building tauri application"); + /// app.run(|_app_handle, event| match event { + /// tauri::RunEvent::ExitRequested { api, .. } => { + /// api.prevent_exit(); + /// } + /// _ => {} + /// }); + /// ``` + pub fn run, RunEvent) + 'static>(mut self, mut callback: F) { let app_handle = self.handle(); let manager = self.manager.clone(); self.runtime.take().unwrap().run(move |event| match event { - RunEvent::Exit => { + RuntimeRunEvent::Exit => { app_handle.cleanup_before_exit(); - callback(&app_handle, Event::Exit); - } - _ => { - on_event_loop_event(&event, &manager); - callback( + on_event_loop_event( &app_handle, - match event { - RunEvent::Exit => Event::Exit, - RunEvent::ExitRequested { window_label, tx } => Event::ExitRequested { - window_label, - api: ExitRequestApi(tx), - }, - RunEvent::CloseRequested { label, signal_tx } => Event::CloseRequested { - label, - api: CloseRequestApi(signal_tx), - }, - RunEvent::WindowClose(label) => Event::WindowClosed(label), - RunEvent::Ready => Event::Ready, - RunEvent::Resumed => Event::Resumed, - RunEvent::MainEventsCleared => Event::MainEventsCleared, - _ => unimplemented!(), - }, + RuntimeRunEvent::Exit, + &manager, + Some(&mut callback), ); } + _ => { + on_event_loop_event(&app_handle, event, &manager, Some(&mut callback)); + } }); } @@ -465,27 +506,29 @@ impl App { /// Additionally, the cleanup calls [AppHandle#remove_system_tray](`AppHandle#method.remove_system_tray`) (Windows only). /// /// # Example - /// ```rust,ignore - /// fn main() { - /// let mut app = tauri::Builder::default() - /// .build(tauri::generate_context!()) - /// .expect("error while building tauri application"); - /// loop { - /// let iteration = app.run_iteration(); - /// if iteration.webview_count == 0 { - /// break; - /// } + /// ```rust,no_run + /// let mut app = tauri::Builder::default() + /// // on an actual app, remove the string argument + /// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("error while building tauri application"); + /// loop { + /// let iteration = app.run_iteration(); + /// if iteration.window_count == 0 { + /// break; /// } /// } /// ``` - #[cfg(any(target_os = "windows", target_os = "macos"))] pub fn run_iteration(&mut self) -> crate::runtime::RunIteration { let manager = self.manager.clone(); - self - .runtime - .as_mut() - .unwrap() - .run_iteration(move |event| on_event_loop_event(&event, &manager)) + let app_handle = self.handle(); + self.runtime.as_mut().unwrap().run_iteration(move |event| { + on_event_loop_event( + &app_handle, + event, + &manager, + Option::<&mut Box, RunEvent)>>::None, + ) + }) } } @@ -545,11 +588,30 @@ impl App { } /// Builds a Tauri application. +/// +/// # Example +/// ```rust,no_run +/// tauri::Builder::default() +/// // on an actual app, remove the string argument +/// .run(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) +/// .expect("error while running tauri application"); +/// ``` #[allow(clippy::type_complexity)] pub struct Builder { + /// A flag indicating that the runtime must be started on an environment that supports the event loop not on the main thread. + #[cfg(any(windows, target_os = "linux"))] + #[cfg_attr(doc_cfg, doc(any(windows, target_os = "linux")))] + runtime_any_thread: bool, + /// The JS message handler. invoke_handler: Box>, + /// The JS message responder. + invoke_responder: Arc>, + + /// The script that initializes the `window.__TAURI_POST_MESSAGE__` function. + invoke_initialization_script: String, + /// The setup hook. setup: SetupHook, @@ -590,8 +652,13 @@ impl Builder { /// Creates a new App builder. pub fn new() -> Self { Self { + #[cfg(any(windows, target_os = "linux"))] + runtime_any_thread: false, setup: Box::new(|_| Ok(())), invoke_handler: Box::new(|_| ()), + invoke_responder: Arc::new(window_invoke_responder), + invoke_initialization_script: + "Object.defineProperty(window, '__TAURI_POST_MESSAGE__', { value: (message) => window.ipc.postMessage(JSON.stringify(message)) })".into(), on_page_load: Box::new(|_, _| ()), pending_windows: Default::default(), plugins: PluginStore::default(), @@ -607,7 +674,34 @@ impl Builder { } } + /// Builds a new Tauri application running on any thread, bypassing the main thread requirement. + /// + /// ## Platform-specific + /// + /// - **macOS**: on macOS the application *must* be executed on the main thread, so this function is not exposed. + #[cfg(any(windows, target_os = "linux"))] + #[cfg_attr(doc_cfg, doc(any(windows, target_os = "linux")))] + #[must_use] + pub fn any_thread(mut self) -> Self { + self.runtime_any_thread = true; + self + } + /// Defines the JS message handler callback. + /// + /// # Example + /// ```rust,no_run + /// #[tauri::command] + /// fn command_1() -> String { + /// return "hello world".to_string(); + /// } + /// tauri::Builder::default() + /// .invoke_handler(tauri::generate_handler![ + /// command_1, + /// // etc... + /// ]); + /// ``` + #[must_use] pub fn invoke_handler(mut self, invoke_handler: F) -> Self where F: Fn(Invoke) + Send + Sync + 'static, @@ -616,16 +710,48 @@ impl Builder { self } + /// Defines a custom JS message system. + /// + /// The `responder` is a function that will be called when a command has been executed and must send a response to the JS layer. + /// + /// The `initialization_script` is a script that initializes `window.__TAURI_POST_MESSAGE__`. + /// That function must take the `message: object` argument and send it to the backend. + #[must_use] + pub fn invoke_system(mut self, initialization_script: String, responder: F) -> Self + where + F: Fn(Window, InvokeResponse, CallbackFn, CallbackFn) + Send + Sync + 'static, + { + self.invoke_initialization_script = initialization_script; + self.invoke_responder = Arc::new(responder); + self + } + /// Defines the setup hook. + /// + /// # Example + /// ```rust,no_run + /// use tauri::Manager; + /// tauri::Builder::default() + /// .setup(|app| { + /// let main_window = app.get_window("main").unwrap(); + #[cfg_attr( + feature = "dialog", + doc = r#" tauri::api::dialog::blocking::message(Some(&main_window), "Hello", "Welcome back!");"# + )] + /// Ok(()) + /// }); + /// ``` + #[must_use] pub fn setup(mut self, setup: F) -> Self where - F: Fn(&mut App) -> Result<(), Box> + Send + 'static, + F: FnOnce(&mut App) -> Result<(), Box> + Send + 'static, { self.setup = Box::new(setup); self } /// Defines the page load hook. + #[must_use] pub fn on_page_load(mut self, on_page_load: F) -> Self where F: Fn(Window, PageLoadPayload) + Send + Sync + 'static, @@ -635,6 +761,7 @@ impl Builder { } /// Adds a plugin to the runtime. + #[must_use] pub fn plugin + 'static>(mut self, plugin: P) -> Self { self.plugins.register(plugin); self @@ -658,7 +785,7 @@ impl Builder { /// /// Since the managed state is global and must be [`Send`] + [`Sync`], mutations can only happen through interior mutability: /// - /// ```rust,ignore + /// ```rust,no_run /// use std::{collections::HashMap, sync::Mutex}; /// use tauri::State; /// // here we use Mutex to achieve interior mutability @@ -678,19 +805,18 @@ impl Builder { /// storage.0.lock().unwrap().insert(key, value); /// } /// - /// fn main() { - /// Builder::default() - /// .manage(Storage(Default::default())) - /// .manage(DbConnection(Default::default())) - /// .invoke_handler(tauri::generate_handler![connect, storage_insert]) - /// .run(tauri::generate_context!()) - /// .expect("error while running tauri application"); - /// } + /// tauri::Builder::default() + /// .manage(Storage(Default::default())) + /// .manage(DbConnection(Default::default())) + /// .invoke_handler(tauri::generate_handler![connect, storage_insert]) + /// // on an actual app, remove the string argument + /// .run(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("error while running tauri application"); /// ``` /// /// # Example /// - /// ```rust,ignore + /// ```rust,no_run /// use tauri::State; /// /// struct MyInt(isize); @@ -706,28 +832,44 @@ impl Builder { /// println!("state: {}", state.inner().0); /// } /// - /// fn main() { - /// tauri::Builder::default() - /// .manage(MyInt(10)) - /// .manage(MyString("Hello, managed state!".to_string())) - /// .invoke_handler(tauri::generate_handler![int_command, string_command]) - /// .run(tauri::generate_context!()) - /// .expect("error while running tauri application"); - /// } + /// tauri::Builder::default() + /// .manage(MyInt(10)) + /// .manage(MyString("Hello, managed state!".to_string())) + /// .invoke_handler(tauri::generate_handler![int_command, string_command]) + /// // on an actual app, remove the string argument + /// .run(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json")) + /// .expect("error while running tauri application"); /// ``` + #[must_use] pub fn manage(self, state: T) -> Self where T: Send + Sync + 'static, { let type_name = std::any::type_name::(); - if !self.state.set(state) { - panic!("state for type '{}' is already being managed", type_name); - } - + assert!( + self.state.set(state), + "state for type '{}' is already being managed", + type_name + ); self } /// Creates a new webview window. + /// + /// # Example + /// ```rust,no_run + /// use tauri::WindowBuilder; + /// tauri::Builder::default() + /// .create_window("main", tauri::WindowUrl::default(), |win, webview| { + /// let win = win + /// .title("My Main Window") + /// .resizable(true) + /// .inner_size(800.0, 550.0) + /// .min_inner_size(400.0, 200.0); + /// return (win, webview); + /// }); + /// ``` + #[must_use] pub fn create_window(mut self, label: impl Into, url: WindowUrl, setup: F) -> Self where F: FnOnce( @@ -753,18 +895,68 @@ impl Builder { /// Adds the icon configured on `tauri.conf.json` to the system tray with the specified menu items. #[cfg(feature = "system-tray")] #[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))] + #[must_use] pub fn system_tray(mut self, system_tray: tray::SystemTray) -> Self { self.system_tray.replace(system_tray); self } /// Sets the menu to use on all windows. + /// + /// # Example + /// ```rust,no_run + /// use tauri::{MenuEntry, Submenu, MenuItem, Menu, CustomMenuItem}; + /// + /// tauri::Builder::default() + /// .menu(Menu::with_items([ + /// MenuEntry::Submenu(Submenu::new( + /// "File", + /// Menu::with_items([ + /// MenuItem::CloseWindow.into(), + /// #[cfg(target_os = "macos")] + /// CustomMenuItem::new("hello", "Hello").into(), + /// ]), + /// )), + /// ])); + /// ``` + #[must_use] pub fn menu(mut self, menu: Menu) -> Self { self.menu.replace(menu); self } /// Registers a menu event handler for all windows. + /// + /// # Example + /// ```rust,no_run + /// use tauri::{Menu, MenuEntry, Submenu, CustomMenuItem, api, Manager}; + /// tauri::Builder::default() + /// .menu(Menu::with_items([ + /// MenuEntry::Submenu(Submenu::new( + /// "File", + /// Menu::with_items([ + /// CustomMenuItem::new("New", "New").into(), + /// CustomMenuItem::new("Learn More", "Learn More").into(), + /// ]), + /// )), + /// ])) + /// .on_menu_event(|event| { + /// match event.menu_item_id() { + /// "Learn More" => { + /// // open in browser (requires the `shell-open-api` feature) + #[cfg_attr( + feature = "shell-open-api", + doc = r#" api::shell::open(&event.window().shell_scope(), "https://github.com/tauri-apps/tauri".to_string(), None).unwrap();"# + )] + /// } + /// id => { + /// // do something with other events + /// println!("got menu event: {}", id); + /// } + /// } + /// }); + /// ``` + #[must_use] pub fn on_menu_event) + Send + Sync + 'static>( mut self, handler: F, @@ -774,6 +966,21 @@ impl Builder { } /// Registers a window event handler for all windows. + /// + /// # Example + /// ```rust,no_run + /// tauri::Builder::default() + /// .on_window_event(|event| match event.event() { + /// tauri::WindowEvent::Focused(focused) => { + /// // hide window whenever it loses focus + /// if !focused { + /// event.window().hide().unwrap(); + /// } + /// } + /// _ => {} + /// }); + /// ``` + #[must_use] pub fn on_window_event) + Send + Sync + 'static>( mut self, handler: F, @@ -783,8 +990,24 @@ impl Builder { } /// Registers a system tray event handler. + /// + /// # Example + /// ```rust,no_run + /// use tauri::Manager; + /// tauri::Builder::default() + /// .on_system_tray_event(|app, event| match event { + /// // show window with id "main" when the tray is left clicked + /// tauri::SystemTrayEvent::LeftClick { .. } => { + /// let window = app.get_window("main").unwrap(); + /// window.show().unwrap(); + /// window.set_focus().unwrap(); + /// } + /// _ => {} + /// }); + /// ``` #[cfg(feature = "system-tray")] #[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))] + #[must_use] pub fn on_system_tray_event< F: Fn(&AppHandle, tray::SystemTrayEvent) + Send + Sync + 'static, >( @@ -804,6 +1027,7 @@ impl Builder { /// /// * `uri_scheme` The URI scheme to register, such as `example`. /// * `protocol` the protocol associated with the given URI scheme. It's a function that takes an URL such as `example://localhost/asset.css`. + #[must_use] pub fn register_uri_scheme_protocol< N: Into, H: Fn(&AppHandle, &HttpRequest) -> Result> @@ -863,6 +1087,9 @@ impl Builder { .map(|t| t.icon_as_template) .unwrap_or_default(); + #[cfg(shell_scope)] + let shell_scope = context.shell_scope.clone(); + let manager = WindowManager::with_handlers( context, self.plugins, @@ -872,6 +1099,7 @@ impl Builder { self.state, self.window_event_listeners, (self.menu, self.menu_event_listeners), + (self.invoke_responder, self.invoke_initialization_script), ); // set up all the windows defined in the config @@ -892,7 +1120,15 @@ impl Builder { )); } + #[cfg(any(windows, target_os = "linux"))] + let runtime = if self.runtime_any_thread { + R::new_any_thread()? + } else { + R::new()? + }; + #[cfg(not(any(windows, target_os = "linux")))] let runtime = R::new()?; + let runtime_handle = runtime.handle(); let global_shortcut_manager = runtime.global_shortcut_manager(); let clipboard_manager = runtime.clipboard_manager(); @@ -914,26 +1150,46 @@ impl Builder { }, }; - app.manager.initialize_plugins(&app.handle())?; - - let pending_labels = self - .pending_windows - .iter() - .map(|p| p.label.clone()) - .collect::>(); - - #[cfg(feature = "updater")] - let mut main_window = None; + let env = Env::default(); + app.manage(Scopes { + fs: FsScope::for_fs_api( + &app.manager.config(), + app.package_info(), + &env, + &app.config().tauri.allowlist.fs.scope, + ), + #[cfg(protocol_asset)] + asset_protocol: FsScope::for_fs_api( + &app.manager.config(), + app.package_info(), + &env, + &app.config().tauri.allowlist.protocol.asset_scope, + ), + #[cfg(http_request)] + http: crate::scope::HttpScope::for_http_api(&app.config().tauri.allowlist.http.scope), + #[cfg(shell_scope)] + shell: ShellScope::new(shell_scope), + }); + app.manage(env); - for pending in self.pending_windows { - let pending = app + #[cfg(windows)] + { + if let Some(w) = &app .manager - .prepare_window(app.handle.clone(), pending, &pending_labels)?; - let detached = app.runtime.as_ref().unwrap().create_window(pending)?; - let _window = app.manager.attach_window(app.handle(), detached); - #[cfg(feature = "updater")] - if main_window.is_none() { - main_window = Some(_window); + .config() + .tauri + .bundle + .windows + .webview_fixed_runtime_path + { + if let Some(resource_dir) = app.path_resolver().resource_dir() { + std::env::set_var("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", resource_dir.join(w)); + } else { + #[cfg(debug_assertions)] + eprintln!( + "failed to resolve resource directory; fallback to the installed Webview2 runtime." + ); + } } } @@ -1020,13 +1276,34 @@ impl Builder { } }; let listener = listener.clone(); - crate::async_runtime::spawn(async move { - listener.lock().unwrap()(&app_handle, event); - }); + listener.lock().unwrap()(&app_handle, event); }); } } + app.manager.initialize_plugins(&app.handle())?; + + let window_labels = self + .pending_windows + .iter() + .map(|p| p.label.clone()) + .collect::>(); + + #[cfg(feature = "updater")] + let mut main_window = None; + + for pending in self.pending_windows { + let pending = app + .manager + .prepare_window(app.handle.clone(), pending, &window_labels)?; + let detached = app.runtime.as_ref().unwrap().create_window(pending)?; + let _window = app.manager.attach_window(app.handle(), detached); + #[cfg(feature = "updater")] + if main_window.is_none() { + main_window = Some(_window); + } + } + (self.setup)(&mut app).map_err(|e| crate::Error::Setup(e))?; #[cfg(feature = "updater")] @@ -1042,10 +1319,43 @@ impl Builder { } } -fn on_event_loop_event(event: &RunEvent, manager: &WindowManager) { - if let RunEvent::WindowClose(label) = event { +fn on_event_loop_event, RunEvent) + 'static>( + app_handle: &AppHandle, + event: RuntimeRunEvent, + manager: &WindowManager, + callback: Option<&mut F>, +) { + if let RuntimeRunEvent::WindowClose(label) = &event { manager.on_window_close(label); } + + let event = match event { + RuntimeRunEvent::Exit => RunEvent::Exit, + RuntimeRunEvent::ExitRequested { window_label, tx } => RunEvent::ExitRequested { + window_label, + api: ExitRequestApi(tx), + }, + RuntimeRunEvent::CloseRequested { label, signal_tx } => RunEvent::CloseRequested { + label, + api: CloseRequestApi(signal_tx), + }, + RuntimeRunEvent::WindowClose(label) => RunEvent::WindowClosed(label), + RuntimeRunEvent::Ready => RunEvent::Ready, + RuntimeRunEvent::Resumed => RunEvent::Resumed, + RuntimeRunEvent::MainEventsCleared => RunEvent::MainEventsCleared, + _ => unimplemented!(), + }; + + manager + .inner + .plugins + .lock() + .expect("poisoned plugin store") + .on_event(app_handle, &event); + + if let Some(c) = callback { + c(app_handle, event); + } } /// Make `Wry` the default `Runtime` for `Builder` @@ -1056,3 +1366,21 @@ impl Default for Builder { Self::new() } } + +#[cfg(test)] +mod tests { + #[test] + fn is_send_sync() { + crate::test_utils::assert_send::(); + crate::test_utils::assert_sync::(); + + #[cfg(feature = "wry")] + { + crate::test_utils::assert_send::>(); + crate::test_utils::assert_sync::>(); + } + + crate::test_utils::assert_send::(); + crate::test_utils::assert_sync::(); + } +} diff --git a/core/tauri/src/app/tray.rs b/core/tauri/src/app/tray.rs index 8cb8e1150905..7239b33cc77b 100644 --- a/core/tauri/src/app/tray.rs +++ b/core/tauri/src/app/tray.rs @@ -129,6 +129,11 @@ impl SystemTrayHandle { self.inner.set_icon(icon).map_err(Into::into) } + /// Updates the tray menu. + pub fn set_menu(&self, menu: SystemTrayMenu) -> crate::Result<()> { + self.inner.set_menu(menu).map_err(Into::into) + } + /// Support [macOS tray icon template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) to adjust automatically based on taskbar color. #[cfg(target_os = "macos")] pub fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()> { diff --git a/core/tauri/src/async_runtime.rs b/core/tauri/src/async_runtime.rs index e63de1ef61d4..0ee1e14c3d2f 100644 --- a/core/tauri/src/async_runtime.rs +++ b/core/tauri/src/async_runtime.rs @@ -12,9 +12,8 @@ use futures_lite::future::FutureExt; use once_cell::sync::OnceCell; -use tokio::runtime::Runtime; pub use tokio::{ - runtime::Handle, + runtime::{Handle as TokioHandle, Runtime as TokioRuntime}, sync::{ mpsc::{channel, Receiver, Sender}, Mutex, RwLock, @@ -23,63 +22,240 @@ pub use tokio::{ }; use std::{ - fmt, future::Future, pin::Pin, task::{Context, Poll}, }; -static RUNTIME: OnceCell = OnceCell::new(); +static RUNTIME: OnceCell = OnceCell::new(); -/// An owned permission to join on a task (await its termination). -#[derive(Debug)] -pub struct JoinHandle(TokioJoinHandle); +struct GlobalRuntime { + runtime: Option, + handle: RuntimeHandle, +} -impl Future for JoinHandle { - type Output = crate::Result; - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - self - .0 - .poll(cx) - .map_err(|e| crate::Error::JoinError(Box::new(e))) +impl GlobalRuntime { + fn handle(&self) -> RuntimeHandle { + if let Some(r) = &self.runtime { + r.handle() + } else { + self.handle.clone() + } + } + + fn spawn(&self, task: F) -> JoinHandle + where + F: Future + Send + 'static, + F::Output: Send + 'static, + { + if let Some(r) = &self.runtime { + r.spawn(task) + } else { + self.handle.spawn(task) + } + } + + pub fn spawn_blocking(&self, func: F) -> JoinHandle + where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, + { + if let Some(r) = &self.runtime { + r.spawn_blocking(func) + } else { + self.handle.spawn_blocking(func) + } + } + + fn block_on(&self, task: F) -> F::Output { + if let Some(r) = &self.runtime { + r.block_on(task) + } else { + self.handle.block_on(task) + } } } -/// Runtime handle definition. -pub trait RuntimeHandle: fmt::Debug + Clone + Sync + Sync { +/// A runtime used to execute asynchronous tasks. +pub enum Runtime { + /// The tokio runtime. + Tokio(TokioRuntime), +} + +impl Runtime { + /// Gets a reference to the [`TokioRuntime`]. + pub fn inner(&self) -> &TokioRuntime { + let Self::Tokio(r) = self; + r + } + + /// Returns a handle of the async runtime. + pub fn handle(&self) -> RuntimeHandle { + match self { + Self::Tokio(r) => RuntimeHandle::Tokio(r.handle().clone()), + } + } + /// Spawns a future onto the runtime. - fn spawn(&self, task: F) -> JoinHandle + pub fn spawn(&self, task: F) -> JoinHandle where F: Future + Send + 'static, - F::Output: Send + 'static; + F::Output: Send + 'static, + { + match self { + Self::Tokio(r) => JoinHandle::Tokio(r.spawn(task)), + } + } + + /// Runs the provided function on an executor dedicated to blocking operations. + pub fn spawn_blocking(&self, func: F) -> JoinHandle + where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, + { + match self { + Self::Tokio(r) => JoinHandle::Tokio(r.spawn_blocking(func)), + } + } /// Runs a future to completion on runtime. - fn block_on(&self, task: F) -> F::Output; + pub fn block_on(&self, task: F) -> F::Output { + match self { + Self::Tokio(r) => r.block_on(task), + } + } } -impl RuntimeHandle for Handle { - fn spawn(&self, task: F) -> JoinHandle +/// An owned permission to join on a task (await its termination). +#[derive(Debug)] +pub enum JoinHandle { + /// The tokio JoinHandle. + Tokio(TokioJoinHandle), +} + +impl JoinHandle { + /// Gets a reference to the [`TokioJoinHandle`]. + pub fn inner(&self) -> &TokioJoinHandle { + let Self::Tokio(t) = self; + t + } + + /// Abort the task associated with the handle. + /// + /// Awaiting a cancelled task might complete as usual if the task was + /// already completed at the time it was cancelled, but most likely it + /// will fail with a cancelled `JoinError`. + pub fn abort(&self) { + match self { + Self::Tokio(t) => t.abort(), + } + } +} + +impl Future for JoinHandle { + type Output = crate::Result; + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.get_mut() { + Self::Tokio(t) => t.poll(cx).map_err(|e| crate::Error::JoinError(Box::new(e))), + } + } +} + +/// A handle to the async runtime +#[derive(Clone)] +pub enum RuntimeHandle { + /// The tokio handle. + Tokio(TokioHandle), +} + +impl RuntimeHandle { + /// Gets a reference to the [`TokioHandle`]. + pub fn inner(&self) -> &TokioHandle { + let Self::Tokio(h) = self; + h + } + + /// Runs the provided function on an executor dedicated to blocking operations. + pub fn spawn_blocking(&self, func: F) -> JoinHandle + where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, + { + match self { + Self::Tokio(h) => JoinHandle::Tokio(h.spawn_blocking(func)), + } + } + + /// Spawns a future onto the runtime. + pub fn spawn(&self, task: F) -> JoinHandle where F: Future + Send + 'static, F::Output: Send + 'static, { - JoinHandle(self.spawn(task)) + match self { + Self::Tokio(h) => JoinHandle::Tokio(h.spawn(task)), + } } - fn block_on(&self, task: F) -> F::Output { - self.block_on(task) + /// Runs a future to completion on runtime. + pub fn block_on(&self, task: F) -> F::Output { + match self { + Self::Tokio(h) => h.block_on(task), + } } } +fn default_runtime() -> GlobalRuntime { + let runtime = Runtime::Tokio(TokioRuntime::new().unwrap()); + let handle = runtime.handle(); + GlobalRuntime { + runtime: Some(runtime), + handle, + } +} + +/// Sets the runtime to use to execute asynchronous tasks. +/// For convinience, this method takes a [`TokioHandle`]. +/// Note that you cannot drop the underlying [`TokioRuntime`]. +/// +/// # Example +/// +/// ```rust +/// #[tokio::main] +/// async fn main() { +/// // perform some async task before initializing the app +/// do_something().await; +/// // share the current runtime with Tauri +/// tauri::async_runtime::set(tokio::runtime::Handle::current()); +/// +/// // bootstrap the tauri app... +/// // tauri::Builder::default().run().unwrap(); +/// } +/// +/// async fn do_something() {} +/// ``` +/// +/// # Panics +/// +/// Panics if the runtime is already set. +pub fn set(handle: TokioHandle) { + RUNTIME + .set(GlobalRuntime { + runtime: None, + handle: RuntimeHandle::Tokio(handle), + }) + .unwrap_or_else(|_| panic!("runtime already initialized")) +} + /// Returns a handle of the async runtime. -pub fn handle() -> impl RuntimeHandle { - let runtime = RUNTIME.get_or_init(|| Runtime::new().unwrap()); - runtime.handle().clone() +pub fn handle() -> RuntimeHandle { + let runtime = RUNTIME.get_or_init(default_runtime); + runtime.handle() } /// Runs a future to completion on runtime. pub fn block_on(task: F) -> F::Output { - let runtime = RUNTIME.get_or_init(|| Runtime::new().unwrap()); + let runtime = RUNTIME.get_or_init(default_runtime); runtime.block_on(task) } @@ -89,13 +265,52 @@ where F: Future + Send + 'static, F::Output: Send + 'static, { - let runtime = RUNTIME.get_or_init(|| Runtime::new().unwrap()); - JoinHandle(runtime.spawn(task)) + let runtime = RUNTIME.get_or_init(default_runtime); + runtime.spawn(task) +} + +/// Runs the provided function on an executor dedicated to blocking operations. +pub fn spawn_blocking(func: F) -> JoinHandle +where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, +{ + let runtime = RUNTIME.get_or_init(default_runtime); + runtime.spawn_blocking(func) +} + +#[allow(dead_code)] +pub(crate) fn safe_block_on(task: F) -> F::Output +where + F: Future + Send + 'static, + F::Output: Send + 'static, +{ + if tokio::runtime::Handle::try_current().is_ok() { + let (tx, rx) = std::sync::mpsc::sync_channel(1); + spawn(async move { + tx.send(task.await).unwrap(); + }); + rx.recv().unwrap() + } else { + block_on(task) + } } #[cfg(test)] mod tests { use super::*; + + #[tokio::test] + async fn runtime_spawn() { + let join = spawn(async { 5 }); + assert_eq!(join.await.unwrap(), 5); + } + + #[test] + fn runtime_block_on() { + assert_eq!(block_on(async { 0 }), 0); + } + #[tokio::test] async fn handle_spawn() { let handle = handle(); @@ -108,4 +323,21 @@ mod tests { let handle = handle(); assert_eq!(handle.block_on(async { 0 }), 0); } + + #[tokio::test] + async fn handle_abort() { + let handle = handle(); + let join = handle.spawn(async { + // Here we sleep 1 second to ensure this task to be uncompleted when abort() invoked. + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + 5 + }); + join.abort(); + if let crate::Error::JoinError(raw_box) = join.await.unwrap_err() { + let raw_error = raw_box.downcast::().unwrap(); + assert!(raw_error.is_cancelled()); + } else { + panic!("Abort did not result in the expected `JoinError`"); + } + } } diff --git a/core/tauri/src/endpoints.rs b/core/tauri/src/endpoints.rs index 10805efe28e9..fd59d2357195 100644 --- a/core/tauri/src/endpoints.rs +++ b/core/tauri/src/endpoints.rs @@ -28,6 +28,24 @@ mod process; mod shell; mod window; +/// The context passed to the invoke handler. +pub struct InvokeContext { + pub window: Window, + pub config: Arc, + pub package_info: PackageInfo, +} + +#[cfg(test)] +impl Clone for InvokeContext { + fn clone(&self) -> Self { + Self { + window: self.window.clone(), + config: self.config.clone(), + package_info: self.package_info.clone(), + } + } +} + /// The response for a JS `invoke` call. pub struct InvokeResponse { json: crate::Result, @@ -68,86 +86,95 @@ impl Module { config: Arc, package_info: PackageInfo, ) { + let context = InvokeContext { + window, + config, + package_info, + }; match self { Self::App(cmd) => resolver.respond_async(async move { cmd - .run(package_info) + .run(context) + .and_then(|r| r.json) + .map_err(InvokeError::from) + }), + Self::Process(cmd) => resolver.respond_async(async move { + cmd + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), - Self::Process(cmd) => resolver - .respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }), Self::Fs(cmd) => resolver.respond_async(async move { cmd - .run(config, &package_info) + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), Self::Path(cmd) => resolver.respond_async(async move { cmd - .run(config, &package_info) + .run(context) + .and_then(|r| r.json) + .map_err(InvokeError::from) + }), + Self::Os(cmd) => resolver.respond_async(async move { + cmd + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), - Self::Os(cmd) => resolver - .respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }), Self::Window(cmd) => resolver.respond_async(async move { cmd - .run(window) + .run(context) .await .and_then(|r| r.json) .map_err(InvokeError::from) }), Self::Shell(cmd) => resolver.respond_async(async move { cmd - .run(window) + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), Self::Event(cmd) => resolver.respond_async(async move { cmd - .run(window) + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), Self::Dialog(cmd) => resolver.respond_async(async move { cmd - .run(window) + .run(context) + .and_then(|r| r.json) + .map_err(InvokeError::from) + }), + Self::Cli(cmd) => resolver.respond_async(async move { + cmd + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), - Self::Cli(cmd) => { - if let Some(cli_config) = config.tauri.cli.clone() { - resolver.respond_async(async move { - cmd - .run(&cli_config) - .and_then(|r| r.json) - .map_err(InvokeError::from) - }) - } - } Self::Notification(cmd) => resolver.respond_async(async move { cmd - .run(window, config, &package_info) + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), Self::Http(cmd) => resolver.respond_async(async move { cmd - .run() + .run(context) .await .and_then(|r| r.json) .map_err(InvokeError::from) }), Self::GlobalShortcut(cmd) => resolver.respond_async(async move { cmd - .run(window) + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), Self::Clipboard(cmd) => resolver.respond_async(async move { cmd - .run(window) + .run(context) .and_then(|r| r.json) .map_err(InvokeError::from) }), diff --git a/core/tauri/src/endpoints/app.rs b/core/tauri/src/endpoints/app.rs index 9c39d9d3bae3..8ff5cecb7b0a 100644 --- a/core/tauri/src/endpoints/app.rs +++ b/core/tauri/src/endpoints/app.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; -use crate::PackageInfo; +use super::InvokeContext; +use crate::Runtime; use serde::Deserialize; +use tauri_macros::CommandModule; /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] #[allow(clippy::enum_variant_names)] pub enum Cmd { @@ -20,11 +21,15 @@ pub enum Cmd { } impl Cmd { - pub fn run(self, package_info: PackageInfo) -> crate::Result { - match self { - Self::GetAppVersion => Ok(package_info.version.into()), - Self::GetAppName => Ok(package_info.name.into()), - Self::GetTauriVersion => Ok(env!("CARGO_PKG_VERSION").into()), - } + fn get_app_version(context: InvokeContext) -> crate::Result { + Ok(context.package_info.version) + } + + fn get_app_name(context: InvokeContext) -> crate::Result { + Ok(context.package_info.name) + } + + fn get_tauri_version(_context: InvokeContext) -> crate::Result<&'static str> { + Ok(env!("CARGO_PKG_VERSION")) } } diff --git a/core/tauri/src/endpoints/cli.rs b/core/tauri/src/endpoints/cli.rs index b5f34eb05858..c720f58f4113 100644 --- a/core/tauri/src/endpoints/cli.rs +++ b/core/tauri/src/endpoints/cli.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; -use crate::utils::config::CliConfig; +use super::{InvokeContext, InvokeResponse}; +use crate::Runtime; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { /// The get CLI matches API. @@ -15,20 +16,24 @@ pub enum Cmd { } impl Cmd { - #[allow(unused_variables)] - pub fn run(self, cli_config: &CliConfig) -> crate::Result { - match self { - #[allow(unused_variables)] - Self::CliMatches => { - #[cfg(cli)] - return crate::api::cli::get_matches(cli_config) - .map_err(Into::into) - .map(Into::into); - #[cfg(not(cli))] - Err(crate::Error::ApiNotEnabled( - "CLI definition not set under tauri.conf.json > tauri > cli (https://tauri.studio/docs/api/config#tauri.cli)".to_string(), - )) - } + #[module_command_handler(cli, "CLI definition not set under tauri.conf.json > tauri > cli (https://tauri.studio/docs/api/config#tauri.cli)")] + fn cli_matches(context: InvokeContext) -> crate::Result { + if let Some(cli) = &context.config.tauri.cli { + crate::api::cli::get_matches(cli, &context.package_info) + .map(Into::into) + .map_err(Into::into) + } else { + Err(crate::Error::ApiNotAllowlisted("CLI definition not set under tauri.conf.json > tauri > cli (https://tauri.studio/docs/api/config#tauri.cli)".into())) } } } + +#[cfg(test)] +mod tests { + #[tauri_macros::module_command_test(cli, "CLI definition not set under tauri.conf.json > tauri > cli (https://tauri.studio/docs/api/config#tauri.cli)")] + #[quickcheck_macros::quickcheck] + fn cli_matches() { + let res = super::Cmd::cli_matches(crate::test::mock_invoke_context()); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } +} diff --git a/core/tauri/src/endpoints/clipboard.rs b/core/tauri/src/endpoints/clipboard.rs index 62550553ff40..53b60a79c348 100644 --- a/core/tauri/src/endpoints/clipboard.rs +++ b/core/tauri/src/endpoints/clipboard.rs @@ -2,15 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; -use crate::{ - runtime::{ClipboardManager, Runtime}, - window::Window, -}; +use super::InvokeContext; +#[cfg(any(clipboard_write_text, clipboard_read_text))] +use crate::runtime::ClipboardManager; +use crate::Runtime; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", content = "data", rename_all = "camelCase")] pub enum Cmd { /// Write a text string to the clipboard. @@ -20,11 +20,40 @@ pub enum Cmd { } impl Cmd { - pub fn run(self, window: Window) -> crate::Result { - let mut clipboard = window.app_handle.clipboard_manager(); - match self { - Self::WriteText(text) => Ok(clipboard.write_text(text)?.into()), - Self::ReadText => Ok(clipboard.read_text()?.into()), - } + #[module_command_handler(clipboard_write_text, "clipboard > writeText")] + fn write_text(context: InvokeContext, text: String) -> crate::Result<()> { + Ok( + context + .window + .app_handle + .clipboard_manager() + .write_text(text)?, + ) + } + + #[module_command_handler(clipboard_read_text, "clipboard > readText")] + fn read_text(context: InvokeContext) -> crate::Result> { + Ok(context.window.app_handle.clipboard_manager().read_text()?) + } +} + +#[cfg(test)] +mod tests { + #[tauri_macros::module_command_test(clipboard_write_text, "clipboard > writeText")] + #[quickcheck_macros::quickcheck] + fn write_text(text: String) { + let ctx = crate::test::mock_invoke_context(); + super::Cmd::write_text(ctx.clone(), text.clone()).unwrap(); + assert_eq!(super::Cmd::read_text(ctx).unwrap(), Some(text)); + } + + #[tauri_macros::module_command_test(clipboard_read_text, "clipboard > readText")] + #[quickcheck_macros::quickcheck] + fn read_text() { + let ctx = crate::test::mock_invoke_context(); + assert_eq!(super::Cmd::read_text(ctx.clone()).unwrap(), None); + let text = "Tauri!".to_string(); + super::Cmd::write_text(ctx.clone(), text.clone()).unwrap(); + assert_eq!(super::Cmd::read_text(ctx).unwrap(), Some(text)); } } diff --git a/core/tauri/src/endpoints/dialog.rs b/core/tauri/src/endpoints/dialog.rs index 7d3097a41c89..9c72165ca348 100644 --- a/core/tauri/src/endpoints/dialog.rs +++ b/core/tauri/src/endpoints/dialog.rs @@ -2,22 +2,17 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; -#[cfg(any(windows, target_os = "macos"))] -use crate::api::dialog::window_parent; +use super::{InvokeContext, InvokeResponse}; #[cfg(any(dialog_open, dialog_save))] -use crate::api::dialog::FileDialogBuilder; -use crate::{ - api::dialog::{ask as ask_dialog, message as message_dialog}, - runtime::Runtime, - Window, -}; +use crate::api::dialog::blocking::FileDialogBuilder; +use crate::Runtime; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; -use std::{path::PathBuf, sync::mpsc::channel}; +use std::path::PathBuf; #[allow(dead_code)] -#[derive(Deserialize)] +#[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct DialogFilter { name: String, @@ -25,9 +20,11 @@ pub struct DialogFilter { } /// The options for the open dialog API. -#[derive(Deserialize)] +#[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct OpenDialogOptions { + /// The title of the dialog window. + pub title: Option, /// The filters of the dialog. #[serde(default)] pub filters: Vec, @@ -42,9 +39,11 @@ pub struct OpenDialogOptions { } /// The options for the save dialog API. -#[derive(Deserialize)] +#[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SaveDialogOptions { + /// The title of the dialog window. + pub title: Option, /// The filters of the dialog. #[serde(default)] pub filters: Vec, @@ -53,7 +52,7 @@ pub struct SaveDialogOptions { } /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] #[allow(clippy::enum_variant_names)] pub enum Cmd { @@ -72,48 +71,99 @@ pub enum Cmd { title: Option, message: String, }, + ConfirmDialog { + title: Option, + message: String, + }, } impl Cmd { + #[module_command_handler(dialog_open, "dialog > open")] #[allow(unused_variables)] - pub fn run(self, window: Window) -> crate::Result { - match self { - #[cfg(dialog_open)] - Self::OpenDialog { options } => open(&window, options), - #[cfg(not(dialog_open))] - Self::OpenDialog { .. } => Err(crate::Error::ApiNotAllowlisted("dialog > open".to_string())), - - #[cfg(dialog_save)] - Self::SaveDialog { options } => save(window, options), - #[cfg(not(dialog_save))] - Self::SaveDialog { .. } => Err(crate::Error::ApiNotAllowlisted("dialog > save".to_string())), - - Self::MessageDialog { message } => { - let exe = std::env::current_exe()?; - let app_name = exe - .file_stem() - .expect("failed to get binary filename") - .to_string_lossy() - .to_string(); - message_dialog(Some(&window), app_name, message); - Ok(().into()) - } - Self::AskDialog { title, message } => { - let exe = std::env::current_exe()?; - let answer = ask( - &window, - title.unwrap_or_else(|| { - exe - .file_stem() - .expect("failed to get binary filename") - .to_string_lossy() - .to_string() - }), - message, - )?; - Ok(answer) - } + fn open_dialog( + context: InvokeContext, + options: OpenDialogOptions, + ) -> crate::Result { + let mut dialog_builder = FileDialogBuilder::new(); + #[cfg(any(windows, target_os = "macos"))] + { + dialog_builder = dialog_builder.set_parent(&context.window); } + if let Some(default_path) = options.default_path { + dialog_builder = set_default_path(dialog_builder, default_path); + } + for filter in options.filters { + let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect(); + dialog_builder = dialog_builder.add_filter(filter.name, &extensions); + } + + let res = if options.directory { + dialog_builder.pick_folder().into() + } else if options.multiple { + dialog_builder.pick_files().into() + } else { + dialog_builder.pick_file().into() + }; + + Ok(res) + } + + #[module_command_handler(dialog_save, "dialog > save")] + #[allow(unused_variables)] + fn save_dialog( + context: InvokeContext, + options: SaveDialogOptions, + ) -> crate::Result> { + let mut dialog_builder = FileDialogBuilder::new(); + #[cfg(any(windows, target_os = "macos"))] + { + dialog_builder = dialog_builder.set_parent(&context.window); + } + if let Some(default_path) = options.default_path { + dialog_builder = set_default_path(dialog_builder, default_path); + } + for filter in options.filters { + let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect(); + dialog_builder = dialog_builder.add_filter(filter.name, &extensions); + } + + Ok(dialog_builder.save_file()) + } + + #[module_command_handler(dialog_message, "dialog > message")] + fn message_dialog(context: InvokeContext, message: String) -> crate::Result<()> { + crate::api::dialog::blocking::message( + Some(&context.window), + &context.window.app_handle.package_info().name, + message, + ); + Ok(()) + } + + #[module_command_handler(dialog_ask, "dialog > ask")] + fn ask_dialog( + context: InvokeContext, + title: Option, + message: String, + ) -> crate::Result { + Ok(crate::api::dialog::blocking::ask( + Some(&context.window), + title.unwrap_or_else(|| context.window.app_handle.package_info().name.clone()), + message, + )) + } + + #[module_command_handler(dialog_confirm, "dialog > confirm")] + fn confirm_dialog( + context: InvokeContext, + title: Option, + message: String, + ) -> crate::Result { + Ok(crate::api::dialog::blocking::confirm( + Some(&context.window), + title.unwrap_or_else(|| context.window.app_handle.package_info().name.clone()), + message, + )) } } @@ -135,73 +185,38 @@ fn set_default_path( } } -/// Shows an open dialog. -#[cfg(dialog_open)] -#[allow(unused_variables)] -pub fn open( - window: &Window, - options: OpenDialogOptions, -) -> crate::Result { - let mut dialog_builder = FileDialogBuilder::new(); - #[cfg(any(windows, target_os = "macos"))] - { - dialog_builder = dialog_builder.set_parent(&window_parent(window)?); - } - if let Some(default_path) = options.default_path { - if !default_path.exists() { - return Err(crate::Error::DialogDefaultPathNotExists(default_path)); +#[cfg(test)] +mod tests { + use super::{OpenDialogOptions, SaveDialogOptions}; + use quickcheck::{Arbitrary, Gen}; + + impl Arbitrary for OpenDialogOptions { + fn arbitrary(g: &mut Gen) -> Self { + Self { + filters: Vec::new(), + multiple: bool::arbitrary(g), + directory: bool::arbitrary(g), + default_path: Option::arbitrary(g), + title: Option::arbitrary(g), + } } - dialog_builder = set_default_path(dialog_builder, default_path); - } - for filter in options.filters { - let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect(); - dialog_builder = dialog_builder.add_filter(filter.name, &extensions); } - let (tx, rx) = channel(); - - if options.directory { - dialog_builder.pick_folder(move |p| tx.send(p.into()).unwrap()); - } else if options.multiple { - dialog_builder.pick_files(move |p| tx.send(p.into()).unwrap()); - } else { - dialog_builder.pick_file(move |p| tx.send(p.into()).unwrap()); + impl Arbitrary for SaveDialogOptions { + fn arbitrary(g: &mut Gen) -> Self { + Self { + filters: Vec::new(), + default_path: Option::arbitrary(g), + title: Option::arbitrary(g), + } + } } - Ok(rx.recv().unwrap()) -} - -/// Shows a save dialog. -#[cfg(dialog_save)] -#[allow(unused_variables)] -pub fn save( - window: Window, - options: SaveDialogOptions, -) -> crate::Result { - let mut dialog_builder = FileDialogBuilder::new(); - #[cfg(any(windows, target_os = "macos"))] - { - dialog_builder = dialog_builder.set_parent(&window_parent(&window)?); - } - if let Some(default_path) = options.default_path { - dialog_builder = set_default_path(dialog_builder, default_path); - } - for filter in options.filters { - let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect(); - dialog_builder = dialog_builder.add_filter(filter.name, &extensions); - } - let (tx, rx) = channel(); - dialog_builder.save_file(move |p| tx.send(p).unwrap()); - Ok(rx.recv().unwrap().into()) -} + #[tauri_macros::module_command_test(dialog_open, "dialog > open")] + #[quickcheck_macros::quickcheck] + fn open_dialog(_options: OpenDialogOptions) {} -/// Shows a dialog with a yes/no question. -pub fn ask( - window: &Window, - title: String, - message: String, -) -> crate::Result { - let (tx, rx) = channel(); - ask_dialog(Some(window), title, message, move |m| tx.send(m).unwrap()); - Ok(rx.recv().unwrap().into()) + #[tauri_macros::module_command_test(dialog_save, "dialog > save")] + #[quickcheck_macros::quickcheck] + fn save_dialog(_options: SaveDialogOptions) {} } diff --git a/core/tauri/src/endpoints/event.rs b/core/tauri/src/endpoints/event.rs index 5a025119bf88..1f4d806933be 100644 --- a/core/tauri/src/endpoints/event.rs +++ b/core/tauri/src/endpoints/event.rs @@ -2,15 +2,65 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::{endpoints::InvokeResponse, runtime::Runtime, sealed::ManagerBase, Manager, Window}; -use serde::Deserialize; +use super::InvokeContext; +use crate::{ + api::ipc::CallbackFn, + event::is_event_name_valid, + event::{listen_js, unlisten_js}, + runtime::window::is_label_valid, + sealed::ManagerBase, + Manager, Runtime, +}; +use serde::{de::Deserializer, Deserialize}; +use tauri_macros::CommandModule; + +pub struct EventId(String); + +impl<'de> Deserialize<'de> for EventId { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let event_id = String::deserialize(deserializer)?; + if is_event_name_valid(&event_id) { + Ok(EventId(event_id)) + } else { + Err(serde::de::Error::custom( + "Event name must include only alphanumeric characters, `-`, `/`, `:` and `_`.", + )) + } + } +} + +pub struct WindowLabel(String); + +impl<'de> Deserialize<'de> for WindowLabel { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let event_id = String::deserialize(deserializer)?; + if is_label_valid(&event_id) { + Ok(WindowLabel(event_id)) + } else { + Err(serde::de::Error::custom( + "Window label must include only alphanumeric characters, `-`, `/`, `:` and `_`.", + )) + } + } +} /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { /// Listen to an event. - Listen { event: String, handler: String }, + #[serde(rename_all = "camelCase")] + Listen { + event: EventId, + window_label: Option, + handler: CallbackFn, + }, /// Unlisten to an event. #[serde(rename_all = "camelCase")] Unlisten { event_id: u64 }, @@ -18,79 +68,61 @@ pub enum Cmd { /// If the window_label is omitted, the event will be triggered on all listeners. #[serde(rename_all = "camelCase")] Emit { - event: String, - window_label: Option, + event: EventId, + window_label: Option, payload: Option, }, } impl Cmd { - pub fn run(self, window: Window) -> crate::Result { - match self { - Self::Listen { event, handler } => { - let event_id = rand::random(); - window.eval(&listen_js(&window, event, event_id, handler))?; - Ok(event_id.into()) - } - Self::Unlisten { event_id } => { - window.eval(&unlisten_js(&window, event_id))?; - Ok(().into()) - } - Self::Emit { - event, - window_label, - payload, - } => { - // dispatch the event to Rust listeners - window.trigger(&event, payload.clone()); + fn listen( + context: InvokeContext, + event: EventId, + window_label: Option, + handler: CallbackFn, + ) -> crate::Result { + let event_id = rand::random(); - if let Some(target) = window_label { - window.emit_to(&target, &event, payload)?; - } else { - window.emit_all(&event, payload)?; - } - Ok(().into()) - } - } + let window_label = window_label.map(|l| l.0); + + context.window.eval(&listen_js( + context.window.manager().event_listeners_object_name(), + format!("'{}'", event.0), + event_id, + window_label.clone(), + format!("window['_{}']", handler.0), + ))?; + + context + .window + .register_js_listener(window_label, event.0, event_id); + + Ok(event_id) } -} -pub fn unlisten_js(window: &Window, event_id: u64) -> String { - format!( - " - for (var event in (window['{listeners}'] || {{}})) {{ - var listeners = (window['{listeners}'] || {{}})[event] - if (listeners) {{ - window['{listeners}'][event] = window['{listeners}'][event].filter(function (e) {{ return e.id !== {event_id} }}) - }} - }} - ", - listeners = window.manager().event_listeners_object_name(), - event_id = event_id, - ) -} + fn unlisten(context: InvokeContext, event_id: u64) -> crate::Result<()> { + context.window.eval(&unlisten_js( + context.window.manager().event_listeners_object_name(), + event_id, + ))?; + context.window.unregister_js_listener(event_id); + Ok(()) + } + + fn emit( + context: InvokeContext, + event: EventId, + window_label: Option, + payload: Option, + ) -> crate::Result<()> { + // dispatch the event to Rust listeners + context.window.trigger(&event.0, payload.clone()); -pub fn listen_js( - window: &Window, - event: String, - event_id: u64, - handler: String, -) -> String { - format!( - "if (window['{listeners}'] === void 0) {{ - window['{listeners}'] = Object.create(null) - }} - if (window['{listeners}']['{event}'] === void 0) {{ - window['{listeners}']['{event}'] = [] - }} - window['{listeners}']['{event}'].push({{ - id: {event_id}, - handler: window['{handler}'] - }}); - ", - listeners = window.manager().event_listeners_object_name(), - event = event, - event_id = event_id, - handler = handler - ) + if let Some(target) = window_label { + context.window.emit_to(&target.0, &event.0, payload)?; + } else { + context.window.emit_all(&event.0, payload)?; + } + Ok(()) + } } diff --git a/core/tauri/src/endpoints/file_system.rs b/core/tauri/src/endpoints/file_system.rs index 08a29a313b03..4d8bd7e21c76 100644 --- a/core/tauri/src/endpoints/file_system.rs +++ b/core/tauri/src/endpoints/file_system.rs @@ -2,21 +2,58 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; use crate::{ - api::{ - dir, file, - path::{resolve_path, BaseDirectory}, - }, - Config, PackageInfo, + api::{dir, file, path::BaseDirectory}, + scope::Scopes, + Config, Env, Manager, PackageInfo, Runtime, Window, +}; + +use super::InvokeContext; +use serde::{ + de::{Deserializer, Error as DeError}, + Deserialize, Serialize, +}; +use tauri_macros::{module_command_handler, CommandModule}; + +use std::fmt::{Debug, Formatter}; +use std::{ + fs, + fs::File, + io::Write, + path::{Component, Path}, + sync::Arc, }; -use serde::{Deserialize, Serialize}; +#[derive(Clone, Debug)] +pub struct SafePathBuf(std::path::PathBuf); + +impl AsRef for SafePathBuf { + fn as_ref(&self) -> &Path { + self.0.as_ref() + } +} -use std::{fs, fs::File, io::Write, path::PathBuf, sync::Arc}; +impl<'de> Deserialize<'de> for SafePathBuf { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let path = std::path::PathBuf::deserialize(deserializer)?; + if path.components().any(|x| { + matches!( + x, + Component::ParentDir | Component::RootDir | Component::Prefix(_) + ) + }) { + Err(DeError::custom("cannot traverse directory")) + } else { + Ok(SafePathBuf(path)) + } + } +} /// The options for the directory functions on the file system API. -#[derive(Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct DirOperationOptions { /// Whether the API should recursively perform the operation on the directory. #[serde(default)] @@ -27,7 +64,7 @@ pub struct DirOperationOptions { } /// The options for the file functions on the file system API. -#[derive(Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct FileOperationOptions { /// The base directory of the operation. /// The directory path of the BaseDirectory will be the prefix of the defined file path. @@ -35,424 +72,382 @@ pub struct FileOperationOptions { } /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { /// The read text file API. - ReadTextFile { - path: PathBuf, - options: Option, - }, - /// The read binary file API. - ReadBinaryFile { - path: PathBuf, + ReadFile { + path: SafePathBuf, options: Option, }, /// The write file API. WriteFile { - path: PathBuf, - contents: String, - options: Option, - }, - /// The write binary file API. - WriteBinaryFile { - path: PathBuf, - contents: String, + path: SafePathBuf, + contents: Vec, options: Option, }, /// The read dir API. ReadDir { - path: PathBuf, + path: SafePathBuf, options: Option, }, /// The copy file API. CopyFile { - source: PathBuf, - destination: PathBuf, + source: SafePathBuf, + destination: SafePathBuf, options: Option, }, /// The create dir API. CreateDir { - path: PathBuf, + path: SafePathBuf, options: Option, }, /// The remove dir API. RemoveDir { - path: PathBuf, + path: SafePathBuf, options: Option, }, /// The remove file API. RemoveFile { - path: PathBuf, + path: SafePathBuf, options: Option, }, /// The rename file API. #[serde(rename_all = "camelCase")] RenameFile { - old_path: PathBuf, - new_path: PathBuf, + old_path: SafePathBuf, + new_path: SafePathBuf, options: Option, }, } impl Cmd { - #[allow(unused_variables)] - pub fn run( - self, - config: Arc, - package_info: &PackageInfo, - ) -> crate::Result { - match self { - #[cfg(fs_read_text_file)] - Self::ReadTextFile { path, options } => { - read_text_file(&config, package_info, path, options).map(Into::into) - } - #[cfg(not(fs_read_text_file))] - Self::ReadTextFile { .. } => Err(crate::Error::ApiNotAllowlisted( - "fs > readTextFile".to_string(), - )), - - #[cfg(fs_read_binary_file)] - Self::ReadBinaryFile { path, options } => { - read_binary_file(&config, package_info, path, options).map(Into::into) - } - #[cfg(not(fs_read_binary_file))] - Self::ReadBinaryFile { .. } => Err(crate::Error::ApiNotAllowlisted( - "readBinaryFile".to_string(), - )), + #[module_command_handler(fs_read_file, "fs > readFile")] + fn read_file( + context: InvokeContext, + path: SafePathBuf, + options: Option, + ) -> crate::Result> { + file::read_binary(resolve_path( + &context.config, + &context.package_info, + &context.window, + path, + options.and_then(|o| o.dir), + )?) + .map_err(crate::Error::FailedToExecuteApi) + } - #[cfg(fs_write_file)] - Self::WriteFile { - path, - contents, - options, - } => write_file(&config, package_info, path, contents, options).map(Into::into), - #[cfg(not(fs_write_file))] - Self::WriteFile { .. } => Err(crate::Error::ApiNotAllowlisted( - "fs > writeFile".to_string(), - )), - - #[cfg(fs_write_binary_file)] - Self::WriteBinaryFile { - path, - contents, - options, - } => write_binary_file(&config, package_info, path, contents, options).map(Into::into), - #[cfg(not(fs_write_binary_file))] - Self::WriteBinaryFile { .. } => Err(crate::Error::ApiNotAllowlisted( - "writeBinaryFile".to_string(), - )), - - #[cfg(fs_read_dir)] - Self::ReadDir { path, options } => { - read_dir(&config, package_info, path, options).map(Into::into) - } - #[cfg(not(fs_read_dir))] - Self::ReadDir { .. } => Err(crate::Error::ApiNotAllowlisted("fs > readDir".to_string())), - - #[cfg(fs_copy_file)] - Self::CopyFile { - source, - destination, - options, - } => copy_file(&config, package_info, source, destination, options).map(Into::into), - #[cfg(not(fs_copy_file))] - Self::CopyFile { .. } => Err(crate::Error::ApiNotAllowlisted("fs > copyFile".to_string())), - - #[cfg(fs_create_dir)] - Self::CreateDir { path, options } => { - create_dir(&config, package_info, path, options).map(Into::into) - } - #[cfg(not(fs_create_dir))] - Self::CreateDir { .. } => Err(crate::Error::ApiNotAllowlisted( - "fs > createDir".to_string(), - )), - - #[cfg(fs_remove_dir)] - Self::RemoveDir { path, options } => { - remove_dir(&config, package_info, path, options).map(Into::into) - } - #[cfg(not(fs_remove_dir))] - Self::RemoveDir { .. } => Err(crate::Error::ApiNotAllowlisted( - "fs > removeDir".to_string(), - )), - - #[cfg(fs_remove_file)] - Self::RemoveFile { path, options } => { - remove_file(&config, package_info, path, options).map(Into::into) - } - #[cfg(not(fs_remove_file))] - Self::RemoveFile { .. } => Err(crate::Error::ApiNotAllowlisted( - "fs > removeFile".to_string(), - )), - - #[cfg(fs_rename_file)] - Self::RenameFile { - old_path, - new_path, - options, - } => rename_file(&config, package_info, old_path, new_path, options).map(Into::into), - #[cfg(not(fs_rename_file))] - Self::RenameFile { .. } => Err(crate::Error::ApiNotAllowlisted( - "fs > renameFile".to_string(), - )), - } + #[module_command_handler(fs_write_file, "fs > writeFile")] + fn write_file( + context: InvokeContext, + path: SafePathBuf, + contents: Vec, + options: Option, + ) -> crate::Result<()> { + File::create(resolve_path( + &context.config, + &context.package_info, + &context.window, + path, + options.and_then(|o| o.dir), + )?) + .map_err(Into::into) + .and_then(|mut f| f.write_all(&contents).map_err(|err| err.into())) } -} -/// Reads a directory. -#[cfg(fs_read_dir)] -pub fn read_dir( - config: &Config, - package_info: &PackageInfo, - path: PathBuf, - options: Option, -) -> crate::Result> { - let (recursive, dir) = if let Some(options_value) = options { - (options_value.recursive, options_value.dir) - } else { - (false, None) - }; - dir::read_dir(resolve_path(config, package_info, path, dir)?, recursive) + #[module_command_handler(fs_read_dir, "fs > readDir")] + fn read_dir( + context: InvokeContext, + path: SafePathBuf, + options: Option, + ) -> crate::Result> { + let (recursive, dir) = if let Some(options_value) = options { + (options_value.recursive, options_value.dir) + } else { + (false, None) + }; + dir::read_dir( + resolve_path( + &context.config, + &context.package_info, + &context.window, + path, + dir, + )?, + recursive, + ) .map_err(crate::Error::FailedToExecuteApi) -} + } -/// Copies a file. -#[cfg(fs_copy_file)] -pub fn copy_file( - config: &Config, - package_info: &PackageInfo, - source: PathBuf, - destination: PathBuf, - options: Option, -) -> crate::Result<()> { - let (src, dest) = match options.and_then(|o| o.dir) { - Some(dir) => ( - resolve_path(config, package_info, source, Some(dir.clone()))?, - resolve_path(config, package_info, destination, Some(dir))?, - ), - None => (source, destination), - }; - fs::copy(src, dest)?; - Ok(()) -} + #[module_command_handler(fs_copy_file, "fs > copyFile")] + fn copy_file( + context: InvokeContext, + source: SafePathBuf, + destination: SafePathBuf, + options: Option, + ) -> crate::Result<()> { + let (src, dest) = match options.and_then(|o| o.dir) { + Some(dir) => ( + resolve_path( + &context.config, + &context.package_info, + &context.window, + source, + Some(dir.clone()), + )?, + resolve_path( + &context.config, + &context.package_info, + &context.window, + destination, + Some(dir), + )?, + ), + None => (source, destination), + }; + fs::copy(src, dest)?; + Ok(()) + } -/// Creates a directory. -#[cfg(fs_create_dir)] -pub fn create_dir( - config: &Config, - package_info: &PackageInfo, - path: PathBuf, - options: Option, -) -> crate::Result<()> { - let (recursive, dir) = if let Some(options_value) = options { - (options_value.recursive, options_value.dir) - } else { - (false, None) - }; - let resolved_path = resolve_path(config, package_info, path, dir)?; - if recursive { - fs::create_dir_all(resolved_path)?; - } else { - fs::create_dir(resolved_path)?; + #[module_command_handler(fs_create_dir, "fs > createDir")] + fn create_dir( + context: InvokeContext, + path: SafePathBuf, + options: Option, + ) -> crate::Result<()> { + let (recursive, dir) = if let Some(options_value) = options { + (options_value.recursive, options_value.dir) + } else { + (false, None) + }; + let resolved_path = resolve_path( + &context.config, + &context.package_info, + &context.window, + path, + dir, + )?; + if recursive { + fs::create_dir_all(resolved_path)?; + } else { + fs::create_dir(resolved_path)?; + } + + Ok(()) } - Ok(()) -} + #[module_command_handler(fs_remove_dir, "fs > removeDir")] + fn remove_dir( + context: InvokeContext, + path: SafePathBuf, + options: Option, + ) -> crate::Result<()> { + let (recursive, dir) = if let Some(options_value) = options { + (options_value.recursive, options_value.dir) + } else { + (false, None) + }; + let resolved_path = resolve_path( + &context.config, + &context.package_info, + &context.window, + path, + dir, + )?; + if recursive { + fs::remove_dir_all(resolved_path)?; + } else { + fs::remove_dir(resolved_path)?; + } -/// Removes a directory. -#[cfg(fs_remove_dir)] -pub fn remove_dir( - config: &Config, - package_info: &PackageInfo, - path: PathBuf, - options: Option, -) -> crate::Result<()> { - let (recursive, dir) = if let Some(options_value) = options { - (options_value.recursive, options_value.dir) - } else { - (false, None) - }; - let resolved_path = resolve_path(config, package_info, path, dir)?; - if recursive { - fs::remove_dir_all(resolved_path)?; - } else { - fs::remove_dir(resolved_path)?; + Ok(()) } - Ok(()) -} + #[module_command_handler(fs_remove_file, "fs > removeFile")] + fn remove_file( + context: InvokeContext, + path: SafePathBuf, + options: Option, + ) -> crate::Result<()> { + let resolved_path = resolve_path( + &context.config, + &context.package_info, + &context.window, + path, + options.and_then(|o| o.dir), + )?; + fs::remove_file(resolved_path)?; + Ok(()) + } -/// Removes a file -#[cfg(fs_remove_file)] -pub fn remove_file( - config: &Config, - package_info: &PackageInfo, - path: PathBuf, - options: Option, -) -> crate::Result<()> { - let resolved_path = resolve_path(config, package_info, path, options.and_then(|o| o.dir))?; - fs::remove_file(resolved_path)?; - Ok(()) + #[module_command_handler(fs_rename_file, "fs > renameFile")] + fn rename_file( + context: InvokeContext, + old_path: SafePathBuf, + new_path: SafePathBuf, + options: Option, + ) -> crate::Result<()> { + let (old, new) = match options.and_then(|o| o.dir) { + Some(dir) => ( + resolve_path( + &context.config, + &context.package_info, + &context.window, + old_path, + Some(dir.clone()), + )?, + resolve_path( + &context.config, + &context.package_info, + &context.window, + new_path, + Some(dir), + )?, + ), + None => (old_path, new_path), + }; + fs::rename(old, new).map_err(crate::Error::Io) + } } -/// Renames a file. -#[cfg(fs_rename_file)] -pub fn rename_file( +#[allow(dead_code)] +fn resolve_path( config: &Config, package_info: &PackageInfo, - old_path: PathBuf, - new_path: PathBuf, - options: Option, -) -> crate::Result<()> { - let (old, new) = match options.and_then(|o| o.dir) { - Some(dir) => ( - resolve_path(config, package_info, old_path, Some(dir.clone()))?, - resolve_path(config, package_info, new_path, Some(dir))?, - ), - None => (old_path, new_path), - }; - fs::rename(old, new).map_err(crate::Error::Io) + window: &Window, + path: SafePathBuf, + dir: Option, +) -> crate::Result { + let env = window.state::().inner(); + match crate::api::path::resolve_path(config, package_info, env, path, dir) { + Ok(path) => { + if window.state::().fs.is_allowed(&path) { + Ok(SafePathBuf(path)) + } else { + Err(crate::Error::PathNotAllowed(path)) + } + } + Err(e) => Err(e.into()), + } } -/// Writes a text file. -#[cfg(fs_write_file)] -pub fn write_file( - config: &Config, - package_info: &PackageInfo, - path: PathBuf, - contents: String, - options: Option, -) -> crate::Result<()> { - File::create(resolve_path( - config, - package_info, - path, - options.and_then(|o| o.dir), - )?) - .map_err(crate::Error::Io) - .and_then(|mut f| f.write_all(contents.as_bytes()).map_err(|err| err.into()))?; - Ok(()) -} +#[cfg(test)] +mod tests { + use super::{BaseDirectory, DirOperationOptions, FileOperationOptions, SafePathBuf}; -/// Writes a binary file. -#[cfg(fs_write_binary_file)] -pub fn write_binary_file( - config: &Config, - package_info: &PackageInfo, - path: PathBuf, - contents: String, - options: Option, -) -> crate::Result<()> { - base64::decode(contents) - .map_err(crate::Error::Base64Decode) - .and_then(|c| { - File::create(resolve_path( - config, - package_info, - path, - options.and_then(|o| o.dir), - )?) - .map_err(Into::into) - .and_then(|mut f| f.write_all(&c).map_err(|err| err.into())) - })?; - Ok(()) -} + use quickcheck::{Arbitrary, Gen}; -/// Reads a text file. -#[cfg(fs_read_text_file)] -pub fn read_text_file( - config: &Config, - package_info: &PackageInfo, - path: PathBuf, - options: Option, -) -> crate::Result { - file::read_string(resolve_path( - config, - package_info, - path, - options.and_then(|o| o.dir), - )?) - .map_err(crate::Error::FailedToExecuteApi) -} + use std::path::PathBuf; -/// Reads a binary file. -#[cfg(fs_read_binary_file)] -pub fn read_binary_file( - config: &Config, - package_info: &PackageInfo, - path: PathBuf, - options: Option, -) -> crate::Result> { - file::read_binary(resolve_path( - config, - package_info, - path, - options.and_then(|o| o.dir), - )?) - .map_err(crate::Error::FailedToExecuteApi) -} + impl Arbitrary for super::SafePathBuf { + fn arbitrary(g: &mut Gen) -> Self { + Self(PathBuf::arbitrary(g)) + } -// test webview functionality. -#[cfg(test)] -mod test { - // use super::*; - // use web_view::*; - - // create a makeshift webview - // fn create_test_webview() -> crate::Result> { - // // basic html set into webview - // let content = r#" "#; - - // Ok( - // // use webview builder to create simple webview - // WebViewBuilder::new() - // .title("test") - // .size(800, 800) - // .resizable(true) - // .debug(true) - // .user_data(()) - // .invoke_handler(|_wv, _command, _arg| Ok(())) - // .content(Content::Html(content)) - // .build()?, - // ) - // } - - /* #[test] - #[cfg(not(any(target_os = "linux", target_os = "macos")))] - // test the file_write functionality - fn test_write_to_file() -> crate::Result<()> { - // import read_to_string and write to be able to manipulate the file. - use std::fs::{read_to_string, write}; - - // create the webview - let mut webview = create_test_webview()?; - - // setup the contents and the path. - let contents = String::from(r#"Write to the Test file"#); - let path = String::from("test/fixture/test.txt".to_string())); - - // clear the file by writing nothing to it. - write(&path, "")?; - - //call write file with the path and contents. - write_file( - &webview_manager, - path.clone(), - contents.clone(), - String::from(""), - String::from(""), + fn shrink(&self) -> Box> { + Box::new(self.0.shrink().map(SafePathBuf)) + } + } + + impl Arbitrary for BaseDirectory { + fn arbitrary(g: &mut Gen) -> Self { + if bool::arbitrary(g) { + BaseDirectory::App + } else { + BaseDirectory::Resource + } + } + } + + impl Arbitrary for FileOperationOptions { + fn arbitrary(g: &mut Gen) -> Self { + Self { + dir: Option::arbitrary(g), + } + } + } + + impl Arbitrary for DirOperationOptions { + fn arbitrary(g: &mut Gen) -> Self { + Self { + recursive: bool::arbitrary(g), + dir: Option::arbitrary(g), + } + } + } + + #[tauri_macros::module_command_test(fs_read_file, "fs > readFile")] + #[quickcheck_macros::quickcheck] + fn read_file(path: SafePathBuf, options: Option) { + let res = super::Cmd::read_file(crate::test::mock_invoke_context(), path, options); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } + + #[tauri_macros::module_command_test(fs_write_file, "fs > writeFile")] + #[quickcheck_macros::quickcheck] + fn write_file(path: SafePathBuf, contents: Vec, options: Option) { + let res = super::Cmd::write_file(crate::test::mock_invoke_context(), path, contents, options); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } + + #[tauri_macros::module_command_test(fs_read_dir, "fs > readDir")] + #[quickcheck_macros::quickcheck] + fn read_dir(path: SafePathBuf, options: Option) { + let res = super::Cmd::read_dir(crate::test::mock_invoke_context(), path, options); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } + + #[tauri_macros::module_command_test(fs_copy_file, "fs > copyFile")] + #[quickcheck_macros::quickcheck] + fn copy_file( + source: SafePathBuf, + destination: SafePathBuf, + options: Option, + ) { + let res = super::Cmd::copy_file( + crate::test::mock_invoke_context(), + source, + destination, + options, ); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } - // sleep the main thread to wait for the promise to execute. - std::thread::sleep(std::time::Duration::from_millis(200)); + #[tauri_macros::module_command_test(fs_create_dir, "fs > createDir")] + #[quickcheck_macros::quickcheck] + fn create_dir(path: SafePathBuf, options: Option) { + let res = super::Cmd::create_dir(crate::test::mock_invoke_context(), path, options); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } - // read from the file. - let data = read_to_string(path)?; + #[tauri_macros::module_command_test(fs_remove_dir, "fs > removeDir")] + #[quickcheck_macros::quickcheck] + fn remove_dir(path: SafePathBuf, options: Option) { + let res = super::Cmd::remove_dir(crate::test::mock_invoke_context(), path, options); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } - // check that the file contents is equal to the expected contents. - assert_eq!(data, contents); + #[tauri_macros::module_command_test(fs_remove_file, "fs > removeFile")] + #[quickcheck_macros::quickcheck] + fn remove_file(path: SafePathBuf, options: Option) { + let res = super::Cmd::remove_file(crate::test::mock_invoke_context(), path, options); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } - Ok(()) - } */ + #[tauri_macros::module_command_test(fs_rename_file, "fs > renameFile")] + #[quickcheck_macros::quickcheck] + fn rename_file( + old_path: SafePathBuf, + new_path: SafePathBuf, + options: Option, + ) { + let res = super::Cmd::rename_file( + crate::test::mock_invoke_context(), + old_path, + new_path, + options, + ); + assert!(!matches!(res, Err(crate::Error::ApiNotAllowlisted(_)))); + } } diff --git a/core/tauri/src/endpoints/global_shortcut.rs b/core/tauri/src/endpoints/global_shortcut.rs index c749458c7a02..416c48542df8 100644 --- a/core/tauri/src/endpoints/global_shortcut.rs +++ b/core/tauri/src/endpoints/global_shortcut.rs @@ -2,23 +2,27 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; -use crate::{Runtime, Window}; +use super::InvokeContext; +use crate::{api::ipc::CallbackFn, Runtime}; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; #[cfg(global_shortcut_all)] use crate::runtime::GlobalShortcutManager; /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { /// Register a global shortcut. - Register { shortcut: String, handler: String }, + Register { + shortcut: String, + handler: CallbackFn, + }, /// Register a list of global shortcuts. RegisterAll { shortcuts: Vec, - handler: String, + handler: CallbackFn, }, /// Unregister a global shortcut. Unregister { shortcut: String }, @@ -28,68 +32,128 @@ pub enum Cmd { IsRegistered { shortcut: String }, } +impl Cmd { + #[module_command_handler(global_shortcut_all, "globalShortcut > all")] + fn register( + context: InvokeContext, + shortcut: String, + handler: CallbackFn, + ) -> crate::Result<()> { + let mut manager = context.window.app_handle.global_shortcut_manager(); + register_shortcut(context.window, &mut manager, shortcut, handler)?; + Ok(()) + } + + #[module_command_handler(global_shortcut_all, "globalShortcut > all")] + fn register_all( + context: InvokeContext, + shortcuts: Vec, + handler: CallbackFn, + ) -> crate::Result<()> { + let mut manager = context.window.app_handle.global_shortcut_manager(); + for shortcut in shortcuts { + register_shortcut(context.window.clone(), &mut manager, shortcut, handler)?; + } + Ok(()) + } + + #[module_command_handler(global_shortcut_all, "globalShortcut > all")] + fn unregister(context: InvokeContext, shortcut: String) -> crate::Result<()> { + context + .window + .app_handle + .global_shortcut_manager() + .unregister(&shortcut)?; + Ok(()) + } + + #[module_command_handler(global_shortcut_all, "globalShortcut > all")] + fn unregister_all(context: InvokeContext) -> crate::Result<()> { + context + .window + .app_handle + .global_shortcut_manager() + .unregister_all()?; + Ok(()) + } + + #[module_command_handler(global_shortcut_all, "globalShortcut > all")] + fn is_registered(context: InvokeContext, shortcut: String) -> crate::Result { + Ok( + context + .window + .app_handle + .global_shortcut_manager() + .is_registered(&shortcut)?, + ) + } +} + #[cfg(global_shortcut_all)] fn register_shortcut( - window: Window, + window: crate::Window, manager: &mut R::GlobalShortcutManager, shortcut: String, - handler: String, + handler: CallbackFn, ) -> crate::Result<()> { let accelerator = shortcut.clone(); manager.register(&shortcut, move || { - let callback_string = crate::api::rpc::format_callback(handler.to_string(), &accelerator) + let callback_string = crate::api::ipc::format_callback(handler, &accelerator) .expect("unable to serialize shortcut string to json"); let _ = window.eval(callback_string.as_str()); })?; Ok(()) } -#[cfg(not(global_shortcut_all))] -impl Cmd { - pub fn run(self, _window: Window) -> crate::Result { - Err(crate::Error::ApiNotAllowlisted( - "globalShortcut > all".to_string(), - )) +#[cfg(test)] +mod tests { + use crate::api::ipc::CallbackFn; + + #[tauri_macros::module_command_test(global_shortcut_all, "globalShortcut > all")] + #[quickcheck_macros::quickcheck] + fn register(shortcut: String, handler: CallbackFn) { + let ctx = crate::test::mock_invoke_context(); + super::Cmd::register(ctx.clone(), shortcut.clone(), handler).unwrap(); + assert!(super::Cmd::is_registered(ctx, shortcut).unwrap()); } -} -#[cfg(global_shortcut_all)] -impl Cmd { - pub fn run(self, window: Window) -> crate::Result { - match self { - Self::Register { shortcut, handler } => { - let mut manager = window.app_handle.global_shortcut_manager(); - register_shortcut(window, &mut manager, shortcut, handler)?; - Ok(().into()) - } - Self::RegisterAll { shortcuts, handler } => { - let mut manager = window.app_handle.global_shortcut_manager(); - for shortcut in shortcuts { - register_shortcut(window.clone(), &mut manager, shortcut, handler.clone())?; - } - Ok(().into()) - } - Self::Unregister { shortcut } => { - window - .app_handle - .global_shortcut_manager() - .unregister(&shortcut)?; - Ok(().into()) - } - Self::UnregisterAll => { - window - .app_handle - .global_shortcut_manager() - .unregister_all()?; - Ok(().into()) - } - Self::IsRegistered { shortcut } => Ok( - window - .app_handle - .global_shortcut_manager() - .is_registered(&shortcut)? - .into(), - ), + #[tauri_macros::module_command_test(global_shortcut_all, "globalShortcut > all")] + #[quickcheck_macros::quickcheck] + fn register_all(shortcuts: Vec, handler: CallbackFn) { + let ctx = crate::test::mock_invoke_context(); + super::Cmd::register_all(ctx.clone(), shortcuts.clone(), handler).unwrap(); + for shortcut in shortcuts { + assert!(super::Cmd::is_registered(ctx.clone(), shortcut).unwrap(),); } } + + #[tauri_macros::module_command_test(global_shortcut_all, "globalShortcut > all")] + #[quickcheck_macros::quickcheck] + fn unregister(shortcut: String) { + let ctx = crate::test::mock_invoke_context(); + super::Cmd::register(ctx.clone(), shortcut.clone(), CallbackFn(0)).unwrap(); + super::Cmd::unregister(ctx.clone(), shortcut.clone()).unwrap(); + assert!(!super::Cmd::is_registered(ctx, shortcut).unwrap()); + } + + #[tauri_macros::module_command_test(global_shortcut_all, "globalShortcut > all")] + #[quickcheck_macros::quickcheck] + fn unregister_all() { + let shortcuts = vec!["CTRL+X".to_string(), "SUPER+C".to_string(), "D".to_string()]; + let ctx = crate::test::mock_invoke_context(); + super::Cmd::register_all(ctx.clone(), shortcuts.clone(), CallbackFn(0)).unwrap(); + super::Cmd::unregister_all(ctx.clone()).unwrap(); + for shortcut in shortcuts { + assert!(!super::Cmd::is_registered(ctx.clone(), shortcut).unwrap(),); + } + } + + #[tauri_macros::module_command_test(global_shortcut_all, "globalShortcut > all")] + #[quickcheck_macros::quickcheck] + fn is_registered(shortcut: String) { + let ctx = crate::test::mock_invoke_context(); + assert!(!super::Cmd::is_registered(ctx.clone(), shortcut.clone()).unwrap(),); + super::Cmd::register(ctx.clone(), shortcut.clone(), CallbackFn(0)).unwrap(); + assert!(super::Cmd::is_registered(ctx, shortcut).unwrap()); + } } diff --git a/core/tauri/src/endpoints/http.rs b/core/tauri/src/endpoints/http.rs index 84abe17efe59..59c693316a2e 100644 --- a/core/tauri/src/endpoints/http.rs +++ b/core/tauri/src/endpoints/http.rs @@ -2,27 +2,40 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; - -use crate::api::http::{Client, ClientBuilder, HttpRequestBuilder}; -use once_cell::sync::Lazy; +use super::InvokeContext; +use crate::Runtime; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; +#[cfg(http_request)] use std::{ collections::HashMap, sync::{Arc, Mutex}, }; +#[cfg(http_request)] +use crate::api::http::{ClientBuilder, HttpRequestBuilder, ResponseData}; +#[cfg(not(http_request))] +type ClientBuilder = (); +#[cfg(not(http_request))] +type HttpRequestBuilder = (); +#[cfg(not(http_request))] +type ResponseData = (); + type ClientId = u32; -type ClientStore = Arc>>; +#[cfg(http_request)] +type ClientStore = Arc>>; +#[cfg(http_request)] fn clients() -> &'static ClientStore { + use once_cell::sync::Lazy; static STORE: Lazy = Lazy::new(Default::default); &STORE } /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] +#[cmd(async)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { /// Create a new HTTP client. @@ -37,44 +50,86 @@ pub enum Cmd { } impl Cmd { - pub async fn run(self) -> crate::Result { - match self { - Self::CreateClient { options } => { - let client = options.unwrap_or_default().build()?; - let mut store = clients().lock().unwrap(); - let id = rand::random::(); - store.insert(id, client); - Ok(InvokeResponse::from(id)) - } - Self::DropClient { client } => { - let mut store = clients().lock().unwrap(); - store.remove(&client); - Ok(().into()) - } - #[cfg(http_request)] - Self::HttpRequest { client, options } => { - return make_request(client, *options).await.map(Into::into); - } - #[cfg(not(http_request))] - Self::HttpRequest { .. } => Err(crate::Error::ApiNotAllowlisted( - "http > request".to_string(), - )), + #[module_command_handler(http_request, "http > request")] + async fn create_client( + _context: InvokeContext, + options: Option, + ) -> crate::Result { + let client = options.unwrap_or_default().build()?; + let mut store = clients().lock().unwrap(); + let id = rand::random::(); + store.insert(id, client); + Ok(id) + } + + #[module_command_handler(http_request, "http > request")] + async fn drop_client( + _context: InvokeContext, + client: ClientId, + ) -> crate::Result<()> { + let mut store = clients().lock().unwrap(); + store.remove(&client); + Ok(()) + } + + #[module_command_handler(http_request, "http > request")] + async fn http_request( + context: InvokeContext, + client_id: ClientId, + options: Box, + ) -> crate::Result { + use crate::Manager; + if context + .window + .state::() + .http + .is_allowed(&options.url) + { + let client = clients() + .lock() + .unwrap() + .get(&client_id) + .ok_or(crate::Error::HttpClientNotInitialized)? + .clone(); + let response = client.send(*options).await?; + Ok(response.read().await?) + } else { + Err(crate::Error::UrlNotAllowed(options.url)) } } } -/// Makes an HTTP request and resolves the response to the webview -#[cfg(http_request)] -pub async fn make_request( - client_id: ClientId, - options: HttpRequestBuilder, -) -> crate::Result { - let client = clients() - .lock() - .unwrap() - .get(&client_id) - .ok_or(crate::Error::HttpClientNotInitialized)? - .clone(); - let response = client.send(options).await?; - Ok(response.read().await?) +#[cfg(test)] +mod tests { + use super::{ClientBuilder, ClientId}; + + #[tauri_macros::module_command_test(http_request, "http > request", async)] + #[quickcheck_macros::quickcheck] + fn create_client(options: Option) { + assert!(crate::async_runtime::block_on(super::Cmd::create_client( + crate::test::mock_invoke_context(), + options + )) + .is_ok()); + } + + #[tauri_macros::module_command_test(http_request, "http > request", async)] + #[quickcheck_macros::quickcheck] + fn drop_client(client_id: ClientId) { + crate::async_runtime::block_on(async move { + assert!( + super::Cmd::drop_client(crate::test::mock_invoke_context(), client_id) + .await + .is_ok() + ); + let id = super::Cmd::create_client(crate::test::mock_invoke_context(), None) + .await + .unwrap(); + assert!( + super::Cmd::drop_client(crate::test::mock_invoke_context(), id) + .await + .is_ok() + ); + }); + } } diff --git a/core/tauri/src/endpoints/notification.rs b/core/tauri/src/endpoints/notification.rs index 8a3fa6baf822..c0b4b78eb0a1 100644 --- a/core/tauri/src/endpoints/notification.rs +++ b/core/tauri/src/endpoints/notification.rs @@ -2,14 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; +use super::InvokeContext; +use crate::Runtime; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; #[cfg(notification_all)] -use crate::api::notification::Notification; -use crate::{Config, PackageInfo, Runtime, Window}; - -use std::sync::Arc; +use crate::{api::notification::Notification, Env, Manager}; // `Granted` response from `request_permission`. Matches the Web API return value. #[cfg(notification_all)] @@ -18,7 +17,7 @@ const PERMISSION_GRANTED: &str = "granted"; const PERMISSION_DENIED: &str = "denied"; /// The options for the notification API. -#[derive(Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct NotificationOptions { /// The notification title. pub title: String, @@ -29,7 +28,7 @@ pub struct NotificationOptions { } /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { /// The show notification API. @@ -41,93 +40,139 @@ pub enum Cmd { } impl Cmd { - #[allow(unused_variables)] - pub fn run( - self, - window: Window, - config: Arc, - package_info: &PackageInfo, - ) -> crate::Result { - match self { - #[cfg(notification_all)] - Self::Notification { options } => send(options, &config).map(Into::into), - #[cfg(not(notification_all))] - Self::Notification { .. } => Err(crate::Error::ApiNotAllowlisted("notification".to_string())), - Self::IsNotificationPermissionGranted => { - #[cfg(notification_all)] - return is_permission_granted(&config, package_info).map(Into::into); - #[cfg(not(notification_all))] - Ok(false.into()) - } - Self::RequestNotificationPermission => { - #[cfg(notification_all)] - return request_permission(&window, &config, package_info).map(Into::into); - #[cfg(not(notification_all))] - Ok(PERMISSION_DENIED.into()) - } + #[module_command_handler(notification_all, "notification > all")] + fn notification( + context: InvokeContext, + options: NotificationOptions, + ) -> crate::Result<()> { + let allowed = match is_permission_granted(&context) { + Some(p) => p, + None => request_permission(&context), + }; + if !allowed { + return Err(crate::Error::NotificationNotAllowed); + } + let mut notification = + Notification::new(context.config.tauri.bundle.identifier.clone()).title(options.title); + if let Some(body) = options.body { + notification = notification.body(body); + } + if let Some(icon) = options.icon { + notification = notification.icon(icon); } + notification.show()?; + Ok(()) } -} -#[cfg(notification_all)] -pub fn send(options: NotificationOptions, config: &Config) -> crate::Result { - let mut notification = - Notification::new(config.tauri.bundle.identifier.clone()).title(options.title); - if let Some(body) = options.body { - notification = notification.body(body); + #[cfg(notification_all)] + fn request_notification_permission( + context: InvokeContext, + ) -> crate::Result<&'static str> { + if request_permission(&context) { + Ok(PERMISSION_GRANTED) + } else { + Ok(PERMISSION_DENIED) + } } - if let Some(icon) = options.icon { - notification = notification.icon(icon); + + #[cfg(not(notification_all))] + fn request_notification_permission( + _context: InvokeContext, + ) -> crate::Result<&'static str> { + Ok(PERMISSION_DENIED) } - notification.show()?; - Ok(().into()) -} -#[cfg(notification_all)] -pub fn is_permission_granted( - config: &Config, - package_info: &PackageInfo, -) -> crate::Result { - let settings = crate::settings::read_settings(config, package_info); - if let Some(allow_notification) = settings.allow_notification { - Ok(allow_notification.into()) - } else { - Ok(().into()) + #[cfg(notification_all)] + fn is_notification_permission_granted( + context: InvokeContext, + ) -> crate::Result> { + if let Some(allow_notification) = is_permission_granted(&context) { + Ok(Some(allow_notification)) + } else { + Ok(None) + } + } + + #[cfg(not(notification_all))] + fn is_notification_permission_granted( + _context: InvokeContext, + ) -> crate::Result> { + Ok(Some(false)) } } #[cfg(notification_all)] -pub fn request_permission( - window: &Window, - config: &Config, - package_info: &PackageInfo, -) -> crate::Result { - let mut settings = crate::settings::read_settings(config, package_info); +fn request_permission(context: &InvokeContext) -> bool { + let mut settings = crate::settings::read_settings( + &context.config, + &context.package_info, + context.window.state::().inner(), + ); if let Some(allow_notification) = settings.allow_notification { - return Ok(if allow_notification { - PERMISSION_GRANTED.to_string() - } else { - PERMISSION_DENIED.to_string() - }); + return allow_notification; } - let (tx, rx) = std::sync::mpsc::channel(); - crate::api::dialog::ask( - Some(window), + let answer = crate::api::dialog::blocking::ask( + Some(&context.window), "Permissions", "This app wants to show notifications. Do you allow?", - move |answer| { - tx.send(answer).unwrap(); - }, ); - let answer = rx.recv().unwrap(); - settings.allow_notification = Some(answer); - crate::settings::write_settings(config, package_info, settings)?; + let _ = crate::settings::write_settings( + &context.config, + &context.package_info, + context.window.state::().inner(), + settings, + ); + + answer +} + +#[cfg(notification_all)] +fn is_permission_granted(context: &InvokeContext) -> Option { + crate::settings::read_settings( + &context.config, + &context.package_info, + context.window.state::().inner(), + ) + .allow_notification +} + +#[cfg(test)] +mod tests { + use super::NotificationOptions; - if answer { - Ok(PERMISSION_GRANTED.to_string()) - } else { - Ok(PERMISSION_DENIED.to_string()) + use quickcheck::{Arbitrary, Gen}; + + impl Arbitrary for NotificationOptions { + fn arbitrary(g: &mut Gen) -> Self { + Self { + title: String::arbitrary(g), + body: Option::arbitrary(g), + icon: Option::arbitrary(g), + } + } + } + + #[cfg(not(notification_all))] + #[test] + fn request_notification_permission() { + assert_eq!( + super::Cmd::request_notification_permission(crate::test::mock_invoke_context()).unwrap(), + super::PERMISSION_DENIED + ) + } + + #[cfg(not(notification_all))] + #[test] + fn is_notification_permission_granted() { + assert_eq!( + super::Cmd::is_notification_permission_granted(crate::test::mock_invoke_context()).unwrap(), + Some(false) + ); } + + #[tauri_macros::module_command_test(notification_all, "notification > all")] + #[quickcheck_macros::quickcheck] + fn notification(_options: NotificationOptions) {} } diff --git a/core/tauri/src/endpoints/operating_system.rs b/core/tauri/src/endpoints/operating_system.rs index 9ce802a1cb93..f5d373b5e88f 100644 --- a/core/tauri/src/endpoints/operating_system.rs +++ b/core/tauri/src/endpoints/operating_system.rs @@ -2,39 +2,87 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; +use super::InvokeContext; +use crate::Runtime; use serde::Deserialize; +use std::path::PathBuf; +use tauri_macros::{module_command_handler, CommandModule}; /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { Platform, Version, - Type, + OsType, Arch, Tempdir, } impl Cmd { - #[allow(unused_variables)] - pub fn run(self) -> crate::Result { - #[cfg(os_all)] - return match self { - Self::Platform => Ok(std::env::consts::OS.into()), - Self::Version => Ok(os_info::get().version().to_string().into()), - Self::Type => { - #[cfg(target_os = "linux")] - return Ok("Linux".into()); - #[cfg(target_os = "windows")] - return Ok("Windows_NT".into()); - #[cfg(target_os = "macos")] - return Ok("Darwing".into()); - } - Self::Arch => Ok(std::env::consts::ARCH.into()), - Self::Tempdir => Ok(std::env::temp_dir().into()), - }; - #[cfg(not(os_all))] - Err(crate::Error::ApiNotAllowlisted("os".into())) + #[module_command_handler(os_all, "os > all")] + fn platform(_context: InvokeContext) -> crate::Result<&'static str> { + Ok(os_platform()) } + + #[module_command_handler(os_all, "os > all")] + fn version(_context: InvokeContext) -> crate::Result { + Ok(os_info::get().version().to_string()) + } + + #[module_command_handler(os_all, "os > all")] + fn os_type(_context: InvokeContext) -> crate::Result<&'static str> { + Ok(os_type()) + } + + #[module_command_handler(os_all, "os > all")] + fn arch(_context: InvokeContext) -> crate::Result<&'static str> { + Ok(std::env::consts::ARCH) + } + + #[module_command_handler(os_all, "os > all")] + fn tempdir(_context: InvokeContext) -> crate::Result { + Ok(std::env::temp_dir()) + } +} + +#[cfg(os_all)] +fn os_type() -> &'static str { + #[cfg(target_os = "linux")] + return "Linux"; + #[cfg(target_os = "windows")] + return "Windows_NT"; + #[cfg(target_os = "macos")] + return "Darwin"; +} +#[cfg(os_all)] +fn os_platform() -> &'static str { + match std::env::consts::OS { + "windows" => "win32", + "macos" => "darwin", + _ => std::env::consts::OS, + } +} + +#[cfg(test)] +mod tests { + #[tauri_macros::module_command_test(os_all, "os > all")] + #[quickcheck_macros::quickcheck] + fn platform() {} + + #[tauri_macros::module_command_test(os_all, "os > all")] + #[quickcheck_macros::quickcheck] + fn version() {} + + #[tauri_macros::module_command_test(os_all, "os > all")] + #[quickcheck_macros::quickcheck] + fn os_type() {} + + #[tauri_macros::module_command_test(os_all, "os > all")] + #[quickcheck_macros::quickcheck] + fn arch() {} + + #[tauri_macros::module_command_test(os_all, "os > all")] + #[quickcheck_macros::quickcheck] + fn tempdir() {} } diff --git a/core/tauri/src/endpoints/path.rs b/core/tauri/src/endpoints/path.rs index 8d06b9a0de78..71f69ca8eeed 100644 --- a/core/tauri/src/endpoints/path.rs +++ b/core/tauri/src/endpoints/path.rs @@ -2,14 +2,19 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::InvokeResponse; -use crate::{api::path::BaseDirectory, Config, PackageInfo}; -use serde::Deserialize; +use crate::{api::path::BaseDirectory, Runtime}; +#[cfg(path_all)] +use crate::{Env, Manager}; +use std::path::PathBuf; #[cfg(path_all)] -use std::path::{Path, PathBuf}; -use std::sync::Arc; +use std::path::{Component, Path, MAIN_SEPARATOR}; + +use super::InvokeContext; +use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; + /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { ResolvePath { @@ -41,116 +46,242 @@ pub enum Cmd { } impl Cmd { - #[allow(unused_variables)] - pub fn run( - self, - config: Arc, - package_info: &PackageInfo, - ) -> crate::Result { - #[cfg(path_all)] - return match self { - Cmd::ResolvePath { directory, path } => { - resolve_path_handler(&config, package_info, path, directory).map(Into::into) - } - Cmd::Resolve { paths } => resolve(paths).map(Into::into), - Cmd::Normalize { path } => normalize(path).map(Into::into), - Cmd::Join { paths } => join(paths).map(Into::into), - Cmd::Dirname { path } => dirname(path).map(Into::into), - Cmd::Extname { path } => extname(path).map(Into::into), - Cmd::Basename { path, ext } => basename(path, ext).map(Into::into), - Cmd::IsAbsolute { path } => Ok(Path::new(&path).is_absolute()).map(Into::into), - }; - #[cfg(not(path_all))] - Err(crate::Error::ApiNotAllowlisted("path".into())) + #[module_command_handler(path_all, "path > all")] + fn resolve_path( + context: InvokeContext, + path: String, + directory: Option, + ) -> crate::Result { + crate::api::path::resolve_path( + &context.config, + &context.package_info, + context.window.state::().inner(), + path, + directory, + ) + .map_err(Into::into) } -} - -#[cfg(path_all)] -pub fn resolve_path_handler( - config: &Config, - package_info: &PackageInfo, - path: String, - directory: Option, -) -> crate::Result { - crate::api::path::resolve_path(config, package_info, path, directory).map_err(Into::into) -} -#[cfg(path_all)] -fn resolve(paths: Vec) -> crate::Result { - // start with the current directory - let mut resolved_path = PathBuf::new().join("."); - - for path in paths { - let path_buf = PathBuf::from(path); - - // if we encounter an absolute path, we use it as the starting path for next iteration - if path_buf.is_absolute() { - resolved_path = path_buf; - } else { - resolved_path = resolved_path.join(&path_buf); + #[module_command_handler(path_all, "path > all")] + fn resolve(_context: InvokeContext, paths: Vec) -> crate::Result { + // Start with current directory then start adding paths from the vector one by one using `PathBuf.push()` which + // will ensure that if an absolute path is encountered in the iteration, it will be used as the current full path. + // + // examples: + // 1. `vec!["."]` or `vec![]` will be equal to `std::env::current_dir()` + // 2. `vec!["/foo/bar", "/tmp/file", "baz"]` will be equal to `PathBuf::from("/tmp/file/baz")` + let mut path = std::env::current_dir()?; + for p in paths { + path.push(p); } + Ok(normalize_path(&path)) } - normalize(resolved_path.to_string_lossy().to_string()) -} + #[module_command_handler(path_all, "path > all")] + fn normalize(_context: InvokeContext, path: String) -> crate::Result { + let mut p = normalize_path_no_absolute(Path::new(&path)) + .to_string_lossy() + .to_string(); + Ok( + // Node.js behavior is to return `".."` for `normalize("..")` + // and `"."` for `normalize("")` or `normalize(".")` + if p.is_empty() && path == ".." { + "..".into() + } else if p.is_empty() && path == "." { + ".".into() + } else { + // Add a trailing separator if the path passed to this functions had a trailing separator. That's how Node.js behaves. + if (path.ends_with('/') || path.ends_with('\\')) + && (!p.ends_with('/') || !p.ends_with('\\')) + { + p.push(MAIN_SEPARATOR); + } + p + }, + ) + } -#[cfg(path_all)] -fn normalize(path: String) -> crate::Result { - let path = std::fs::canonicalize(path)?; - let path = path.to_string_lossy().to_string(); + #[module_command_handler(path_all, "path > all")] + fn join(_context: InvokeContext, mut paths: Vec) -> crate::Result { + let path = PathBuf::from( + paths + .iter_mut() + .map(|p| { + // Add a `MAIN_SEPARATOR` if it doesn't already have one. + // Doing this to ensure that the vector elements are separated in + // the resulting string so path.components() can work correctly when called + // in `normalize_path_no_absolute()` later on. + if !p.ends_with('/') && !p.ends_with('\\') { + p.push(MAIN_SEPARATOR); + } + p.to_string() + }) + .collect::(), + ); - // remove `\\\\?\\` on windows, UNC path - #[cfg(target_os = "windows")] - let path = path.replace("\\\\?\\", ""); + let p = normalize_path_no_absolute(&path) + .to_string_lossy() + .to_string(); + Ok(if p.is_empty() { ".".into() } else { p }) + } - Ok(path) -} + #[module_command_handler(path_all, "path > all")] + fn dirname(_context: InvokeContext, path: String) -> crate::Result { + match Path::new(&path).parent() { + Some(p) => Ok(p.to_path_buf()), + None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path( + "Couldn't get the parent directory".into(), + ))), + } + } -#[cfg(path_all)] -fn join(paths: Vec) -> crate::Result { - let mut joined_path = PathBuf::new(); - for path in paths { - joined_path = joined_path.join(path); + #[module_command_handler(path_all, "path > all")] + fn extname(_context: InvokeContext, path: String) -> crate::Result { + match Path::new(&path) + .extension() + .and_then(std::ffi::OsStr::to_str) + { + Some(p) => Ok(p.to_string()), + None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path( + "Couldn't get the extension of the file".into(), + ))), + } } - normalize(joined_path.to_string_lossy().to_string()) -} -#[cfg(path_all)] -fn dirname(path: String) -> crate::Result { - match Path::new(&path).parent() { - Some(path) => Ok(path.to_string_lossy().to_string()), - None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path( - "Couldn't get the parent directory".into(), - ))), + #[module_command_handler(path_all, "path > all")] + fn basename( + _context: InvokeContext, + path: String, + ext: Option, + ) -> crate::Result { + match Path::new(&path) + .file_name() + .and_then(std::ffi::OsStr::to_str) + { + Some(p) => Ok(if let Some(ext) = ext { + p.replace(ext.as_str(), "") + } else { + p.to_string() + }), + None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path( + "Couldn't get the basename".into(), + ))), + } + } + + #[module_command_handler(path_all, "path > all")] + fn is_absolute(_context: InvokeContext, path: String) -> crate::Result { + Ok(Path::new(&path).is_absolute()) } } +/// Normalize a path, removing things like `.` and `..`, this snippet is taken from cargo's paths util. +/// https://github.com/rust-lang/cargo/blob/46fa867ff7043e3a0545bf3def7be904e1497afd/crates/cargo-util/src/paths.rs#L73-L106 #[cfg(path_all)] -fn extname(path: String) -> crate::Result { - match Path::new(&path) - .extension() - .and_then(std::ffi::OsStr::to_str) - { - Some(path) => Ok(path.to_string()), - None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path( - "Couldn't get the extension of the file".into(), - ))), +fn normalize_path(path: &Path) -> PathBuf { + let mut components = path.components().peekable(); + let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { + components.next(); + PathBuf::from(c.as_os_str()) + } else { + PathBuf::new() + }; + + for component in components { + match component { + Component::Prefix(..) => unreachable!(), + Component::RootDir => { + ret.push(component.as_os_str()); + } + Component::CurDir => {} + Component::ParentDir => { + ret.pop(); + } + Component::Normal(c) => { + ret.push(c); + } + } } + ret } +/// Normalize a path, removing things like `.` and `..`, this snippet is taken from cargo's paths util but +/// slightly modified to not resolve absolute paths. +/// https://github.com/rust-lang/cargo/blob/46fa867ff7043e3a0545bf3def7be904e1497afd/crates/cargo-util/src/paths.rs#L73-L106 #[cfg(path_all)] -fn basename(path: String, ext: Option) -> crate::Result { - match Path::new(&path) - .file_name() - .and_then(std::ffi::OsStr::to_str) - { - Some(path) => Ok(if let Some(ext) = ext { - path.replace(ext.as_str(), "") - } else { - path.to_string() - }), - None => Err(crate::Error::FailedToExecuteApi(crate::api::Error::Path( - "Couldn't get the basename".into(), - ))), +fn normalize_path_no_absolute(path: &Path) -> PathBuf { + let mut components = path.components().peekable(); + let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { + components.next(); + PathBuf::from(c.as_os_str()) + } else { + PathBuf::new() + }; + + for component in components { + match component { + Component::Prefix(..) => unreachable!(), + Component::RootDir => { + ret.push(component.as_os_str()); + } + Component::CurDir => {} + Component::ParentDir => { + ret.pop(); + } + Component::Normal(c) => { + // Using PathBuf::push here will replace the whole path if an absolute path is encountered + // which is not the intended behavior, so instead of that, convert the current resolved path + // to a string and do simple string concatenation with the current component then convert it + // back to a PathBuf + let mut p = ret.to_string_lossy().to_string(); + // Only add a separator if it doesn't have one already or if current normalized path is empty, + // this ensures it won't have an unwanted leading separator + if !p.is_empty() && !p.ends_with('/') && !p.ends_with('\\') { + p.push(MAIN_SEPARATOR); + } + if let Some(c) = c.to_str() { + p.push_str(c); + } + ret = PathBuf::from(p); + } + } } + ret +} + +#[cfg(test)] +mod tests { + use crate::api::path::BaseDirectory; + + #[tauri_macros::module_command_test(path_all, "path > all")] + #[quickcheck_macros::quickcheck] + fn resolve_path(_path: String, _directory: Option) {} + + #[tauri_macros::module_command_test(path_all, "path > all")] + #[quickcheck_macros::quickcheck] + fn resolve(_paths: Vec) {} + + #[tauri_macros::module_command_test(path_all, "path > all")] + #[quickcheck_macros::quickcheck] + fn normalize(_path: String) {} + + #[tauri_macros::module_command_test(path_all, "path > all")] + #[quickcheck_macros::quickcheck] + fn join(_paths: Vec) {} + + #[tauri_macros::module_command_test(path_all, "path > all")] + #[quickcheck_macros::quickcheck] + fn dirname(_path: String) {} + + #[tauri_macros::module_command_test(path_all, "path > all")] + #[quickcheck_macros::quickcheck] + fn extname(_path: String) {} + + #[tauri_macros::module_command_test(path_all, "path > all")] + #[quickcheck_macros::quickcheck] + fn basename(_path: String, _ext: Option) {} + + #[tauri_macros::module_command_test(path_all, "path > all")] + #[quickcheck_macros::quickcheck] + fn is_absolute(_path: String) {} } diff --git a/core/tauri/src/endpoints/process.rs b/core/tauri/src/endpoints/process.rs index bb92d03318ff..be0495460c77 100644 --- a/core/tauri/src/endpoints/process.rs +++ b/core/tauri/src/endpoints/process.rs @@ -2,14 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use std::process::exit; - -use super::InvokeResponse; -use crate::api::process::restart; +use super::InvokeContext; +#[cfg(process_relaunch)] +use crate::Manager; +use crate::Runtime; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { /// Relaunch application @@ -20,18 +21,28 @@ pub enum Cmd { } impl Cmd { - pub fn run(self) -> crate::Result { - match self { - Self::Relaunch => Ok({ - restart(); - ().into() - }), - Self::Exit { exit_code } => { - // would be great if we can have a handler inside tauri - // who close all window and emit an event that user can catch - // if they want to process something before closing the app - exit(exit_code); - } - } + #[module_command_handler(process_relaunch, "process > relaunch")] + fn relaunch(context: InvokeContext) -> crate::Result<()> { + crate::api::process::restart(&context.window.state()); + Ok(()) + } + + #[module_command_handler(process_exit, "process > exit")] + fn exit(_context: InvokeContext, exit_code: i32) -> crate::Result<()> { + // would be great if we can have a handler inside tauri + // who close all window and emit an event that user can catch + // if they want to process something before closing the app + std::process::exit(exit_code); } } + +#[cfg(test)] +mod tests { + #[tauri_macros::module_command_test(process_relaunch, "process > relaunch")] + #[quickcheck_macros::quickcheck] + fn relaunch() {} + + #[tauri_macros::module_command_test(process_exit, "process > exit")] + #[quickcheck_macros::quickcheck] + fn exit(_exit_code: i32) {} +} diff --git a/core/tauri/src/endpoints/shell.rs b/core/tauri/src/endpoints/shell.rs index 1d90df7a6f96..e1c4082e20d1 100644 --- a/core/tauri/src/endpoints/shell.rs +++ b/core/tauri/src/endpoints/shell.rs @@ -2,25 +2,34 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::{endpoints::InvokeResponse, runtime::Runtime, Window}; +use super::InvokeContext; +use crate::{api::ipc::CallbackFn, Runtime}; +#[cfg(shell_scope)] +use crate::{Manager, Scopes}; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; -#[cfg(shell_execute)] +#[cfg(shell_scope)] +use crate::ExecuteArgs; +#[cfg(not(shell_scope))] +type ExecuteArgs = (); + +#[cfg(any(shell_execute, shell_sidecar))] use std::sync::{Arc, Mutex}; use std::{collections::HashMap, path::PathBuf}; type ChildId = u32; -#[cfg(shell_execute)] +#[cfg(any(shell_execute, shell_sidecar))] type ChildStore = Arc>>; -#[cfg(shell_execute)] +#[cfg(any(shell_execute, shell_sidecar))] fn command_childs() -> &'static ChildStore { use once_cell::sync::Lazy; static STORE: Lazy = Lazy::new(Default::default); &STORE } -#[derive(Deserialize)] +#[derive(Debug, Clone, Deserialize)] #[serde(untagged)] pub enum Buffer { Text(String), @@ -33,7 +42,7 @@ fn default_env() -> Option> { } #[allow(dead_code)] -#[derive(Default, Deserialize)] +#[derive(Debug, Clone, Default, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CommandOptions { #[serde(default)] @@ -46,15 +55,15 @@ pub struct CommandOptions { } /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { /// The execute script API. #[serde(rename_all = "camelCase")] Execute { program: String, - args: Vec, - on_event_fn: String, + args: ExecuteArgs, + on_event_fn: CallbackFn, #[serde(default)] options: CommandOptions, }, @@ -73,93 +82,211 @@ pub enum Cmd { impl Cmd { #[allow(unused_variables)] - pub fn run(self, window: Window) -> crate::Result { - match self { - Self::Execute { - program, - args, - on_event_fn, - options, - } => { - #[cfg(shell_execute)] - { - let mut command = if options.sidecar { - crate::api::process::Command::new_sidecar(program)? - } else { - crate::api::process::Command::new(program) - }; - command = command.args(args); - if let Some(cwd) = options.cwd { - command = command.current_dir(cwd); - } - if let Some(env) = options.env { - command = command.envs(env); - } else { - command = command.env_clear(); - } - let (mut rx, child) = command.spawn()?; - - let pid = child.pid(); - command_childs().lock().unwrap().insert(pid, child); - - crate::async_runtime::spawn(async move { - while let Some(event) = rx.recv().await { - if matches!(event, crate::api::process::CommandEvent::Terminated(_)) { - command_childs().lock().unwrap().remove(&pid); - } - let js = crate::api::rpc::format_callback(on_event_fn.clone(), &event) - .expect("unable to serialize CommandEvent"); - - let _ = window.eval(js.as_str()); - } - }); - - Ok(pid.into()) + fn execute( + context: InvokeContext, + program: String, + args: ExecuteArgs, + on_event_fn: CallbackFn, + options: CommandOptions, + ) -> crate::Result { + let mut command = if options.sidecar { + #[cfg(not(shell_sidecar))] + return Err(crate::Error::ApiNotAllowlisted( + "shell > sidecar".to_string(), + )); + #[cfg(shell_sidecar)] + { + let program = PathBuf::from(program); + let program_as_string = program.display().to_string(); + let program_no_ext_as_string = program.with_extension("").display().to_string(); + let is_configured = context + .config + .tauri + .bundle + .external_bin + .as_ref() + .map(|bins| { + bins + .iter() + .any(|b| b == &program_as_string || b == &program_no_ext_as_string) + }) + .unwrap_or_default(); + if is_configured { + context + .window + .state::() + .shell + .prepare(&program.to_string_lossy(), args, true) + .map_err(Box::new)? + } else { + return Err(crate::Error::SidecarNotAllowed(program)); } - #[cfg(not(shell_execute))] - Err(crate::Error::ApiNotAllowlisted( - "shell > execute".to_string(), - )) } - Self::KillChild { pid } => { - #[cfg(shell_execute)] - { - if let Some(child) = command_childs().lock().unwrap().remove(&pid) { - child.kill()?; - } - Ok(().into()) + } else { + #[cfg(not(shell_execute))] + return Err(crate::Error::ApiNotAllowlisted( + "shell > execute".to_string(), + )); + #[cfg(shell_execute)] + match context + .window + .state::() + .shell + .prepare(&program, args, false) + { + Ok(cmd) => cmd, + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("{}", e); + return Err(crate::Error::ProgramNotAllowed(PathBuf::from(program))); } - #[cfg(not(shell_execute))] - Err(crate::Error::ApiNotAllowlisted( - "shell > execute".to_string(), - )) } - Self::StdinWrite { pid, buffer } => { - #[cfg(shell_execute)] - { - if let Some(child) = command_childs().lock().unwrap().get_mut(&pid) { - match buffer { - Buffer::Text(t) => child.write(t.as_bytes())?, - Buffer::Raw(r) => child.write(&r)?, - } + }; + #[cfg(any(shell_execute, shell_sidecar))] + { + if let Some(cwd) = options.cwd { + command = command.current_dir(cwd); + } + if let Some(env) = options.env { + command = command.envs(env); + } else { + command = command.env_clear(); + } + let (mut rx, child) = command.spawn()?; + + let pid = child.pid(); + command_childs().lock().unwrap().insert(pid, child); + + crate::async_runtime::spawn(async move { + while let Some(event) = rx.recv().await { + if matches!(event, crate::api::process::CommandEvent::Terminated(_)) { + command_childs().lock().unwrap().remove(&pid); } - Ok(().into()) + let js = crate::api::ipc::format_callback(on_event_fn, &event) + .expect("unable to serialize CommandEvent"); + + let _ = context.window.eval(js.as_str()); } - #[cfg(not(shell_execute))] - Err(crate::Error::ApiNotAllowlisted( - "shell > execute".to_string(), - )) + }); + + Ok(pid) + } + } + + #[cfg(any(shell_execute, shell_sidecar))] + fn stdin_write( + _context: InvokeContext, + pid: ChildId, + buffer: Buffer, + ) -> crate::Result<()> { + if let Some(child) = command_childs().lock().unwrap().get_mut(&pid) { + match buffer { + Buffer::Text(t) => child.write(t.as_bytes())?, + Buffer::Raw(r) => child.write(&r)?, } - Self::Open { path, with } => { - #[cfg(shell_open)] - match crate::api::shell::open(path, with) { - Ok(_) => Ok(().into()), - Err(err) => Err(crate::Error::FailedToExecuteApi(err)), - } + } + Ok(()) + } - #[cfg(not(shell_open))] - Err(crate::Error::ApiNotAllowlisted("shell > open".to_string())) + #[cfg(not(any(shell_execute, shell_sidecar)))] + fn stdin_write( + _context: InvokeContext, + _pid: ChildId, + _buffer: Buffer, + ) -> crate::Result<()> { + Err(crate::Error::ApiNotAllowlisted( + "shell > execute or shell > sidecar".into(), + )) + } + + #[cfg(any(shell_execute, shell_sidecar))] + fn kill_child(_context: InvokeContext, pid: ChildId) -> crate::Result<()> { + if let Some(child) = command_childs().lock().unwrap().remove(&pid) { + child.kill()?; + } + Ok(()) + } + + #[cfg(not(any(shell_execute, shell_sidecar)))] + fn kill_child(_context: InvokeContext, _pid: ChildId) -> crate::Result<()> { + Err(crate::Error::ApiNotAllowlisted( + "shell > execute or shell > sidecar".into(), + )) + } + + /// Open a (url) path with a default or specific browser opening program. + /// + /// See [`crate::api::shell::open`] for how it handles security-related measures. + #[module_command_handler(shell_open, "shell > open")] + fn open( + context: InvokeContext, + path: String, + with: Option, + ) -> crate::Result<()> { + use std::str::FromStr; + + with + .as_deref() + // only allow pre-determined programs to be specified + .map(crate::api::shell::Program::from_str) + .transpose() + .map_err(Into::into) + // validate and open path + .and_then(|with| { + crate::api::shell::open(&context.window.state::().shell, path, with) + .map_err(Into::into) + }) + } +} + +#[cfg(test)] +mod tests { + use super::{Buffer, ChildId, CommandOptions, ExecuteArgs}; + use crate::api::ipc::CallbackFn; + use quickcheck::{Arbitrary, Gen}; + + impl Arbitrary for CommandOptions { + fn arbitrary(g: &mut Gen) -> Self { + Self { + sidecar: false, + cwd: Option::arbitrary(g), + env: Option::arbitrary(g), } } } + + impl Arbitrary for Buffer { + fn arbitrary(g: &mut Gen) -> Self { + Buffer::Text(String::arbitrary(g)) + } + } + + #[cfg(shell_scope)] + impl Arbitrary for ExecuteArgs { + fn arbitrary(_: &mut Gen) -> Self { + ExecuteArgs::None + } + } + + #[tauri_macros::module_command_test(shell_execute, "shell > execute")] + #[quickcheck_macros::quickcheck] + fn execute( + _program: String, + _args: ExecuteArgs, + _on_event_fn: CallbackFn, + _options: CommandOptions, + ) { + } + + #[tauri_macros::module_command_test(shell_execute, "shell > execute or shell > sidecar")] + #[quickcheck_macros::quickcheck] + fn stdin_write(_pid: ChildId, _buffer: Buffer) {} + + #[tauri_macros::module_command_test(shell_execute, "shell > execute or shell > sidecar")] + #[quickcheck_macros::quickcheck] + fn kill_child(_pid: ChildId) {} + + #[tauri_macros::module_command_test(shell_open, "shell > open")] + #[quickcheck_macros::quickcheck] + fn open(_path: String, _with: Option) {} } diff --git a/core/tauri/src/endpoints/window.rs b/core/tauri/src/endpoints/window.rs index 3e886092e2a4..1f33963e9d42 100644 --- a/core/tauri/src/endpoints/window.rs +++ b/core/tauri/src/endpoints/window.rs @@ -2,18 +2,19 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT +use super::{InvokeContext, InvokeResponse}; #[cfg(window_create)] use crate::runtime::{webview::WindowBuilder, Dispatch}; use crate::{ - endpoints::InvokeResponse, runtime::{ window::dpi::{Position, Size}, Runtime, UserAttentionType, }, utils::config::WindowConfig, - Manager, Window, + Manager, }; use serde::Deserialize; +use tauri_macros::{module_command_handler, CommandModule}; use crate::runtime::Icon; use std::path::PathBuf; @@ -85,12 +86,59 @@ pub enum WindowManagerCmd { InternalToggleMaximize, } +impl WindowManagerCmd { + fn into_allowlist_error(self) -> crate::Error { + match self { + Self::Center => crate::Error::ApiNotAllowlisted("window > center".to_string()), + Self::RequestUserAttention(_) => { + crate::Error::ApiNotAllowlisted("window > requestUserAttention".to_string()) + } + Self::SetResizable(_) => crate::Error::ApiNotAllowlisted("window > setResizable".to_string()), + Self::SetTitle(_) => crate::Error::ApiNotAllowlisted("window > setTitle".to_string()), + Self::Maximize => crate::Error::ApiNotAllowlisted("window > maximize".to_string()), + Self::Unmaximize => crate::Error::ApiNotAllowlisted("window > unmaximize".to_string()), + Self::ToggleMaximize => { + crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string()) + } + Self::Minimize => crate::Error::ApiNotAllowlisted("window > minimize".to_string()), + Self::Unminimize => crate::Error::ApiNotAllowlisted("window > unminimize".to_string()), + Self::Show => crate::Error::ApiNotAllowlisted("window > show".to_string()), + Self::Hide => crate::Error::ApiNotAllowlisted("window > hide".to_string()), + Self::Close => crate::Error::ApiNotAllowlisted("window > close".to_string()), + Self::SetDecorations(_) => { + crate::Error::ApiNotAllowlisted("window > setDecorations".to_string()) + } + Self::SetAlwaysOnTop(_) => { + crate::Error::ApiNotAllowlisted("window > setAlwaysOnTop".to_string()) + } + Self::SetSize(_) => crate::Error::ApiNotAllowlisted("window > setSize".to_string()), + Self::SetMinSize(_) => crate::Error::ApiNotAllowlisted("window > setMinSize".to_string()), + Self::SetMaxSize(_) => crate::Error::ApiNotAllowlisted("window > setMaxSize".to_string()), + Self::SetPosition(_) => crate::Error::ApiNotAllowlisted("window > setPosition".to_string()), + Self::SetFullscreen(_) => { + crate::Error::ApiNotAllowlisted("window > setFullscreen".to_string()) + } + Self::SetIcon { .. } => crate::Error::ApiNotAllowlisted("window > setIcon".to_string()), + Self::SetSkipTaskbar(_) => { + crate::Error::ApiNotAllowlisted("window > setSkipTaskbar".to_string()) + } + Self::StartDragging => crate::Error::ApiNotAllowlisted("window > startDragging".to_string()), + Self::Print => crate::Error::ApiNotAllowlisted("window > print".to_string()), + Self::InternalToggleMaximize => { + crate::Error::ApiNotAllowlisted("window > maximize and window > unmaximize".to_string()) + } + _ => crate::Error::ApiNotAllowlisted("window > all".to_string()), + } + } +} + /// The API descriptor. -#[derive(Deserialize)] +#[derive(Deserialize, CommandModule)] +#[cmd(async)] #[serde(tag = "cmd", content = "data", rename_all = "camelCase")] pub enum Cmd { CreateWebview { - options: WindowConfig, + options: Box, }, Manage { label: Option, @@ -98,102 +146,121 @@ pub enum Cmd { }, } -#[cfg(window_create)] -#[derive(Clone, serde::Serialize)] -struct WindowCreatedEvent { - label: String, -} - impl Cmd { - #[allow(dead_code)] - pub async fn run(self, window: Window) -> crate::Result { - match self { - #[cfg(not(window_create))] - Self::CreateWebview { .. } => { - return Err(crate::Error::ApiNotAllowlisted( - "window > create".to_string(), - )); - } - #[cfg(window_create)] - Self::CreateWebview { options } => { - let mut window = window; - let label = options.label.clone(); - let url = options.url.clone(); + #[module_command_handler(window_create, "window > create")] + async fn create_webview( + context: InvokeContext, + options: Box, + ) -> crate::Result<()> { + let mut window = context.window; + let label = options.label.clone(); + let url = options.url.clone(); + + window.create_window(label, url, |_, webview_attributes| { + ( + <::WindowBuilder>::with_config(*options), + webview_attributes, + ) + })?; - window - .create_window(label.clone(), url, |_, webview_attributes| { - ( - <::WindowBuilder>::with_config(options), - webview_attributes, - ) - })? - .emit_others("tauri://window-created", Some(WindowCreatedEvent { label }))?; + Ok(()) + } + + async fn manage( + context: InvokeContext, + label: Option, + cmd: WindowManagerCmd, + ) -> crate::Result { + let window = match label { + Some(l) if !l.is_empty() => context + .window + .get_window(&l) + .ok_or(crate::Error::WebviewNotFound)?, + _ => context.window, + }; + match cmd { + // Getters + WindowManagerCmd::ScaleFactor => return Ok(window.scale_factor()?.into()), + WindowManagerCmd::InnerPosition => return Ok(window.inner_position()?.into()), + WindowManagerCmd::OuterPosition => return Ok(window.outer_position()?.into()), + WindowManagerCmd::InnerSize => return Ok(window.inner_size()?.into()), + WindowManagerCmd::OuterSize => return Ok(window.outer_size()?.into()), + WindowManagerCmd::IsFullscreen => return Ok(window.is_fullscreen()?.into()), + WindowManagerCmd::IsMaximized => return Ok(window.is_maximized()?.into()), + WindowManagerCmd::IsDecorated => return Ok(window.is_decorated()?.into()), + WindowManagerCmd::IsResizable => return Ok(window.is_resizable()?.into()), + WindowManagerCmd::IsVisible => return Ok(window.is_visible()?.into()), + WindowManagerCmd::CurrentMonitor => return Ok(window.current_monitor()?.into()), + WindowManagerCmd::PrimaryMonitor => return Ok(window.primary_monitor()?.into()), + WindowManagerCmd::AvailableMonitors => return Ok(window.available_monitors()?.into()), + // Setters + #[cfg(window_center)] + WindowManagerCmd::Center => window.center()?, + #[cfg(window_request_user_attention)] + WindowManagerCmd::RequestUserAttention(request_type) => { + window.request_user_attention(request_type)? } - Self::Manage { label, cmd } => { - let window = if let Some(l) = label { - window.get_window(&l).ok_or(crate::Error::WebviewNotFound)? - } else { - window - }; - match cmd { - // Getters - WindowManagerCmd::ScaleFactor => return Ok(window.scale_factor()?.into()), - WindowManagerCmd::InnerPosition => return Ok(window.inner_position()?.into()), - WindowManagerCmd::OuterPosition => return Ok(window.outer_position()?.into()), - WindowManagerCmd::InnerSize => return Ok(window.inner_size()?.into()), - WindowManagerCmd::OuterSize => return Ok(window.outer_size()?.into()), - WindowManagerCmd::IsFullscreen => return Ok(window.is_fullscreen()?.into()), - WindowManagerCmd::IsMaximized => return Ok(window.is_maximized()?.into()), - WindowManagerCmd::IsDecorated => return Ok(window.is_decorated()?.into()), - WindowManagerCmd::IsResizable => return Ok(window.is_resizable()?.into()), - WindowManagerCmd::IsVisible => return Ok(window.is_visible()?.into()), - WindowManagerCmd::CurrentMonitor => return Ok(window.current_monitor()?.into()), - WindowManagerCmd::PrimaryMonitor => return Ok(window.primary_monitor()?.into()), - WindowManagerCmd::AvailableMonitors => return Ok(window.available_monitors()?.into()), - // Setters - WindowManagerCmd::Center => window.center()?, - WindowManagerCmd::RequestUserAttention(request_type) => { - window.request_user_attention(request_type)? - } - WindowManagerCmd::SetResizable(resizable) => window.set_resizable(resizable)?, - WindowManagerCmd::SetTitle(title) => window.set_title(&title)?, - WindowManagerCmd::Maximize => window.maximize()?, - WindowManagerCmd::Unmaximize => window.unmaximize()?, - WindowManagerCmd::ToggleMaximize => match window.is_maximized()? { + #[cfg(window_set_resizable)] + WindowManagerCmd::SetResizable(resizable) => window.set_resizable(resizable)?, + #[cfg(window_set_title)] + WindowManagerCmd::SetTitle(title) => window.set_title(&title)?, + #[cfg(window_maximize)] + WindowManagerCmd::Maximize => window.maximize()?, + #[cfg(window_unmaximize)] + WindowManagerCmd::Unmaximize => window.unmaximize()?, + #[cfg(all(window_maximize, window_unmaximize))] + WindowManagerCmd::ToggleMaximize => match window.is_maximized()? { + true => window.unmaximize()?, + false => window.maximize()?, + }, + #[cfg(window_minimize)] + WindowManagerCmd::Minimize => window.minimize()?, + #[cfg(window_unminimize)] + WindowManagerCmd::Unminimize => window.unminimize()?, + #[cfg(window_show)] + WindowManagerCmd::Show => window.show()?, + #[cfg(window_hide)] + WindowManagerCmd::Hide => window.hide()?, + #[cfg(window_close)] + WindowManagerCmd::Close => window.close()?, + #[cfg(window_set_decorations)] + WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?, + #[cfg(window_set_always_on_top)] + WindowManagerCmd::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top)?, + #[cfg(window_set_size)] + WindowManagerCmd::SetSize(size) => window.set_size(size)?, + #[cfg(window_set_min_size)] + WindowManagerCmd::SetMinSize(size) => window.set_min_size(size)?, + #[cfg(window_set_max_size)] + WindowManagerCmd::SetMaxSize(size) => window.set_max_size(size)?, + #[cfg(window_set_position)] + WindowManagerCmd::SetPosition(position) => window.set_position(position)?, + #[cfg(window_set_fullscreen)] + WindowManagerCmd::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?, + #[cfg(window_set_focus)] + WindowManagerCmd::SetFocus => window.set_focus()?, + #[cfg(window_set_icon)] + WindowManagerCmd::SetIcon { icon } => window.set_icon(icon.into())?, + #[cfg(window_set_skip_taskbar)] + WindowManagerCmd::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?, + #[cfg(window_start_dragging)] + WindowManagerCmd::StartDragging => window.start_dragging()?, + #[cfg(window_print)] + WindowManagerCmd::Print => window.print()?, + // internals + #[cfg(all(window_maximize, window_unmaximize))] + WindowManagerCmd::InternalToggleMaximize => { + if window.is_resizable()? { + match window.is_maximized()? { true => window.unmaximize()?, false => window.maximize()?, - }, - WindowManagerCmd::Minimize => window.minimize()?, - WindowManagerCmd::Unminimize => window.unminimize()?, - WindowManagerCmd::Show => window.show()?, - WindowManagerCmd::Hide => window.hide()?, - WindowManagerCmd::Close => window.close()?, - WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?, - WindowManagerCmd::SetAlwaysOnTop(always_on_top) => { - window.set_always_on_top(always_on_top)? - } - WindowManagerCmd::SetSize(size) => window.set_size(size)?, - WindowManagerCmd::SetMinSize(size) => window.set_min_size(size)?, - WindowManagerCmd::SetMaxSize(size) => window.set_max_size(size)?, - WindowManagerCmd::SetPosition(position) => window.set_position(position)?, - WindowManagerCmd::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?, - WindowManagerCmd::SetFocus => window.set_focus()?, - WindowManagerCmd::SetIcon { icon } => window.set_icon(icon.into())?, - WindowManagerCmd::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?, - WindowManagerCmd::StartDragging => window.start_dragging()?, - WindowManagerCmd::Print => window.print()?, - // internals - WindowManagerCmd::InternalToggleMaximize => { - if window.is_resizable()? { - match window.is_maximized()? { - true => window.unmaximize()?, - false => window.maximize()?, - } - } } } } + #[allow(unreachable_patterns)] + _ => return Err(cmd.into_allowlist_error()), } + #[allow(unreachable_code)] Ok(().into()) } } diff --git a/core/tauri/src/error.rs b/core/tauri/src/error.rs index 5a754521e258..8ee0c913d3af 100644 --- a/core/tauri/src/error.rs +++ b/core/tauri/src/error.rs @@ -42,7 +42,7 @@ pub enum Error { #[error("{0}")] Io(#[from] std::io::Error), /// Failed to decode base64. - #[cfg(any(fs_write_binary_file, feature = "updater"))] + #[cfg(feature = "updater")] #[error("Failed to decode base64 string: {0}")] Base64Decode(#[from] base64::DecodeError), /// Failed to load window icon. @@ -71,9 +71,6 @@ pub enum Error { /// Error initializing plugin. #[error("failed to initialize plugin `{0}`: {1}")] PluginInitialization(String, String), - /// `default_path` provided to dialog API doesn't exist. - #[error("failed to setup dialog: provided default path `{0}` doesn't exist")] - DialogDefaultPathNotExists(PathBuf), /// Encountered an error creating the app system tray, #[error("error encountered during tray setup: {0}")] SystemTray(Box), @@ -84,6 +81,32 @@ pub enum Error { /// Task join error. #[error(transparent)] JoinError(Box), + /// Path not allowed by the scope. + #[error("path not allowed on the configured scope: {0}")] + PathNotAllowed(PathBuf), + /// The user did not allow sending notifications. + #[error("sending notification was not allowed by the user")] + NotificationNotAllowed, + /// URL not allowed by the scope. + #[error("url not allowed on the configured scope: {0}")] + UrlNotAllowed(url::Url), + /// Sidecar not allowed by the configuration. + #[error("sidecar not configured under `tauri.conf.json > tauri > bundle > externalBin`: {0}")] + SidecarNotAllowed(PathBuf), + /// Sidecar was not found by the configuration. + #[cfg(shell_scope)] + #[error("sidecar configuration found, but unable to create a path to it: {0}")] + SidecarNotFound(#[from] Box), + /// Program not allowed by the scope. + #[error("program not allowed on the configured shell scope: {0}")] + ProgramNotAllowed(PathBuf), + /// An error happened inside the isolation pattern. + #[cfg(feature = "isolation")] + #[error("isolation pattern error: {0}")] + IsolationPattern(#[from] tauri_utils::pattern::isolation::Error), + /// An invalid window URL was provided. Includes details about the error. + #[error("invalid window url: {0}")] + InvalidWindowUrl(&'static str), } impl From for Error { diff --git a/core/tauri/src/event.rs b/core/tauri/src/event.rs index 0b12f9814cd3..d7214c5ee849 100644 --- a/core/tauri/src/event.rs +++ b/core/tauri/src/event.rs @@ -4,6 +4,7 @@ use std::{ boxed::Box, + cell::Cell, collections::HashMap, fmt, hash::Hash, @@ -11,6 +12,20 @@ use std::{ }; use uuid::Uuid; +/// Checks if an event name is valid. +pub fn is_event_name_valid(event: &str) -> bool { + event + .chars() + .all(|c| c.is_alphanumeric() || c == '-' || c == '/' || c == ':' || c == '_') +} + +pub fn assert_event_name_is_valid(event: &str) { + assert!( + is_event_name_valid(event), + "Event name must include only alphanumeric characters, `-`, `/`, `:` and `_`." + ); +} + /// Represents an event handler. #[derive(Debug, Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct EventHandler(Uuid); @@ -156,16 +171,21 @@ impl Listeners { } /// Listen to a JS event and immediately unlisten. - pub(crate) fn once( + pub(crate) fn once( &self, event: String, window: Option, handler: F, ) -> EventHandler { let self_ = self.clone(); + let handler = Cell::new(Some(handler)); + self.listen(event, window, move |event| { self_.unlisten(event.id); - handler(event); + let handler = handler + .take() + .expect("attempted to call handler more than once"); + handler(event) }) } @@ -279,3 +299,51 @@ mod test { } } } + +pub fn unlisten_js(listeners_object_name: String, event_id: u64) -> String { + format!( + " + for (var event in (window['{listeners}'] || {{}})) {{ + var listeners = (window['{listeners}'] || {{}})[event] + if (listeners) {{ + window['{listeners}'][event] = window['{listeners}'][event].filter(function (e) {{ return e.id !== {event_id} }}) + }} + }} + ", + listeners = listeners_object_name, + event_id = event_id, + ) +} + +pub fn listen_js( + listeners_object_name: String, + event: String, + event_id: u64, + window_label: Option, + handler: String, +) -> String { + format!( + "if (window['{listeners}'] === void 0) {{ + Object.defineProperty(window, '{listeners}', {{ value: Object.create(null) }}); + }} + if (window['{listeners}'][{event}] === void 0) {{ + Object.defineProperty(window['{listeners}'], {event}, {{ value: [] }}); + }} + window['{listeners}'][{event}].push({{ + id: {event_id}, + windowLabel: {window_label}, + handler: {handler} + }}); + ", + listeners = listeners_object_name, + event = event, + event_id = event_id, + window_label = if let Some(l) = window_label { + crate::runtime::window::assert_label_is_valid(&l); + format!("'{}'", l) + } else { + "null".to_owned() + }, + handler = handler + ) +} diff --git a/core/tauri/src/hooks.rs b/core/tauri/src/hooks.rs index 26ac93216e8e..8d7a5c93f192 100644 --- a/core/tauri/src/hooks.rs +++ b/core/tauri/src/hooks.rs @@ -3,27 +3,47 @@ // SPDX-License-Identifier: MIT use crate::{ - api::rpc::{format_callback, format_callback_result}, + api::ipc::{format_callback, format_callback_result, CallbackFn}, app::App, runtime::Runtime, StateManager, Window, }; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use serialize_to_javascript::{default_template, Template}; use std::{future::Future, sync::Arc}; use tauri_macros::default_runtime; /// A closure that is run when the Tauri application is setting up. pub type SetupHook = - Box) -> Result<(), Box> + Send>; + Box) -> Result<(), Box> + Send>; /// A closure that is run everytime Tauri receives a message it doesn't explicitly handle. pub type InvokeHandler = dyn Fn(Invoke) + Send + Sync + 'static; +/// A closure that is responsible for respond a JS message. +pub type InvokeResponder = + dyn Fn(Window, InvokeResponse, CallbackFn, CallbackFn) + Send + Sync + 'static; + /// A closure that is run once every time a window is created and loaded. pub type OnPageLoad = dyn Fn(Window, PageLoadPayload) + Send + Sync + 'static; +// todo: why is this derive broken but the output works manually? +#[derive(Template)] +#[default_template("../scripts/ipc.js")] +pub(crate) struct IpcJavascript<'a> { + pub(crate) isolation_origin: &'a str, +} + +#[cfg(feature = "isolation")] +#[derive(Template)] +#[default_template("../scripts/isolation.js")] +pub(crate) struct IsolationJavascript<'a> { + pub(crate) isolation_src: &'a str, + pub(crate) style: &'a str, +} + /// The payload for the [`OnPageLoad`] hook. #[derive(Debug, Clone, Deserialize)] pub struct PageLoadPayload { @@ -37,6 +57,23 @@ impl PageLoadPayload { } } +/// The payload used on the IPC invoke. +#[derive(Debug, Deserialize)] +pub struct InvokePayload { + /// The invoke command. + pub cmd: String, + #[serde(rename = "__tauriModule")] + #[doc(hidden)] + pub tauri_module: Option, + /// The success callback. + pub callback: CallbackFn, + /// The error callback. + pub error: CallbackFn, + /// The payload of the message. + #[serde(flatten)] + pub inner: JsonValue, +} + /// The message and resolver given to a custom command. #[default_runtime(crate::Wry, wry)] #[derive(Debug)] @@ -120,12 +157,12 @@ impl From for InvokeResponse { #[derive(Debug)] pub struct InvokeResolver { window: Window, - pub(crate) callback: String, - pub(crate) error: String, + pub(crate) callback: CallbackFn, + pub(crate) error: CallbackFn, } impl InvokeResolver { - pub(crate) fn new(window: Window, callback: String, error: String) -> Self { + pub(crate) fn new(window: Window, callback: CallbackFn, error: CallbackFn) -> Self { Self { window, callback, @@ -150,7 +187,7 @@ impl InvokeResolver { F: Future> + Send + 'static, { crate::async_runtime::spawn(async move { - Self::return_result(self.window, task.await.into(), self.callback, self.error); + Self::return_result(self.window, task.await.into(), self.callback, self.error) }); } @@ -159,15 +196,6 @@ impl InvokeResolver { Self::return_result(self.window, value.into(), self.callback, self.error) } - /// Reply to the invoke promise running the given closure. - pub fn respond_closure(self, f: F) - where - T: Serialize, - F: FnOnce() -> Result, - { - Self::return_closure(self.window, f, self.callback, self.error) - } - /// Resolve the invoke promise with a value. pub fn resolve(self, value: T) { Self::return_result(self.window, Ok(value).into(), self.callback, self.error) @@ -196,8 +224,8 @@ impl InvokeResolver { pub async fn return_task( window: Window, task: F, - success_callback: String, - error_callback: String, + success_callback: CallbackFn, + error_callback: CallbackFn, ) where T: Serialize, F: Future> + Send + 'static, @@ -209,8 +237,8 @@ impl InvokeResolver { pub(crate) fn return_closure Result>( window: Window, f: F, - success_callback: String, - error_callback: String, + success_callback: CallbackFn, + error_callback: CallbackFn, ) { Self::return_result(window, f().into(), success_callback, error_callback) } @@ -218,21 +246,27 @@ impl InvokeResolver { pub(crate) fn return_result( window: Window, response: InvokeResponse, - success_callback: String, - error_callback: String, + success_callback: CallbackFn, + error_callback: CallbackFn, ) { - let callback_string = match format_callback_result( - response.into_result(), - success_callback, - error_callback.clone(), - ) { + (window.invoke_responder())(window, response, success_callback, error_callback); + } +} + +pub fn window_invoke_responder( + window: Window, + response: InvokeResponse, + success_callback: CallbackFn, + error_callback: CallbackFn, +) { + let callback_string = + match format_callback_result(response.into_result(), success_callback, error_callback) { Ok(callback_string) => callback_string, Err(e) => format_callback(error_callback, &e.to_string()) - .expect("unable to serialize shortcut string to json"), + .expect("unable to serialize response string to json"), }; - let _ = window.eval(&callback_string); - } + let _ = window.eval(&callback_string); } /// An invoke message. @@ -243,7 +277,7 @@ pub struct InvokeMessage { pub(crate) window: Window, /// Application managed state. pub(crate) state: Arc, - /// The RPC command. + /// The IPC command. pub(crate) command: String, /// The JSON argument passed on the invoke message. pub(crate) payload: JsonValue, diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index 3f0a1d6e6385..309464077ccf 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -8,13 +8,124 @@ //! //! # Cargo features //! -//! The following are a list of Cargo features that can be enabled or disabled: +//! The following are a list of [Cargo features](https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section) that can be enabled or disabled: //! //! - **wry** *(enabled by default)*: Enables the [wry](https://github.com/tauri-apps/wry) runtime. Only disable it if you want a custom runtime. +//! - **isolation**: Enables the isolation pattern. Enabled by default if the `tauri > pattern > use` config option is set to `isolation` on the `tauri.conf.json` file. +//! - **custom-protocol**: Feature managed by the Tauri CLI. When enabled, Tauri assumes a production environment instead of a development one. +//! - **updater**: Enables the application auto updater. Enabled by default if the `updater` config is defined on the `tauri.conf.json` file. +//! - **devtools**: Enables the developer tools (Web inspector) and [`Window::open_devtools`]. Enabled by default on debug builds. +//! On macOS it uses private APIs, so you can't enable it if your app will be published to the App Store. +//! - **http-api**: Enables the [`api::http`] module. //! - **reqwest-client**: Uses `reqwest` as HTTP client on the `http` APIs. Improves performance, but increases the bundle size. +//! - **command**: Enables the [`api::process::Command`] APIs. +//! - **dialog**: Enables the [`api::dialog`] module. +//! - **notification**: Enables the [`api::notification`] module. //! - **cli**: Enables usage of `clap` for CLI argument parsing. Enabled by default if the `cli` config is defined on the `tauri.conf.json` file. //! - **system-tray**: Enables application system tray API. Enabled by default if the `systemTray` config is defined on the `tauri.conf.json` file. -//! - **updater**: Enables the application auto updater. Enabled by default if the `updater` config is defined on the `tauri.conf.json` file. +//! - **macos-private-api**: Enables features only available in **macOS**'s private APIs, currently the `transparent` window functionality and the `fullScreenEnabled` preference setting to `true`. Enabled by default if the `tauri > macosPrivateApi` config flag is set to `true` on the `tauri.conf.json` file. +//! - **window-data-url**: Enables usage of data URLs on the webview. +//! +//! ## Cargo allowlist features +//! +//! The following are a list of [Cargo features](https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section) that enables commands for Tauri's API package. +//! These features are automatically enabled by the Tauri CLI based on the `allowlist` configuration under `tauri.conf.json`. +//! +//! - **api-all**: Enables all API endpoints. +//! +//! ### Clipboard allowlist +//! +//! - **clipboard-all**: Enables all [Clipboard APIs](https://tauri.studio/en/docs/api/js/modules/clipboard/). +//! - **clipboard-read-text**: Enables the [`readText` API](https://tauri.studio/en/docs/api/js/modules/clipboard/#readtext). +//! - **clipboard-write-text**: Enables the [`writeText` API](https://tauri.studio/en/docs/api/js/modules/clipboard/#writetext). +//! +//! ### Dialog allowlist +//! +//! - **dialog-all**: Enables all [Dialog APIs](https://tauri.studio/en/docs/api/js/modules/dialog). +//! - **dialog-ask**: Enables the [`ask` API](https://tauri.studio/en/docs/api/js/modules/dialog#ask). +//! - **dialog-confirm**: Enables the [`confirm` API](https://tauri.studio/en/docs/api/js/modules/dialog#confirm). +//! - **dialog-message**: Enables the [`message` API](https://tauri.studio/en/docs/api/js/modules/dialog#message). +//! - **dialog-open**: Enables the [`open` API](https://tauri.studio/en/docs/api/js/modules/dialog#open). +//! - **dialog-save**: Enables the [`save` API](https://tauri.studio/en/docs/api/js/modules/dialog#save). +//! +//! ### Filesystem allowlist +//! +//! - **fs-all**: Enables all [Filesystem APIs](https://tauri.studio/en/docs/api/js/modules/fs). +//! - **fs-copy-file**: Enables the [`copyFile` API](https://tauri.studio/en/docs/api/js/modules/fs#copyfile). +//! - **fs-create-dir**: Enables the [`createDir` API](https://tauri.studio/en/docs/api/js/modules/fs#createdir). +//! - **fs-read-dir**: Enables the [`readDir` API](https://tauri.studio/en/docs/api/js/modules/fs#readdir). +//! - **fs-read-file**: Enables the [`readTextFile` API](https://tauri.studio/en/docs/api/js/modules/fs#readtextfile) and the [`readBinaryFile` API](https://tauri.studio/en/docs/api/js/modules/fs#readbinaryfile). +//! - **fs-remove-dir**: Enables the [`removeDir` API](https://tauri.studio/en/docs/api/js/modules/fs#removedir). +//! - **fs-remove-file**: Enables the [`removeFile` API](https://tauri.studio/en/docs/api/js/modules/fs#removefile). +//! - **fs-rename-file**: Enables the [`renameFile` API](https://tauri.studio/en/docs/api/js/modules/fs#renamefile). +//! - **fs-write-file**: Enables the [`writeFile` API](https://tauri.studio/en/docs/api/js/modules/fs#writefile) and the [`writeBinaryFile` API](https://tauri.studio/en/docs/api/js/modules/fs#writebinaryfile). +//! +//! ### Global shortcut allowlist +//! +//! - **global-shortcut-all**: Enables all [GlobalShortcut APIs](https://tauri.studio/en/docs/api/js/modules/globalShortcut). +//! +//! ### HTTP allowlist +//! +//! - **http-all**: Enables all [HTTP APIs](https://tauri.studio/en/docs/api/js/modules/http). +//! - **http-request**: Enables the [`request` APIs](https://tauri.studio/en/docs/api/js/classes/http.client/). +//! +//! ### Notification allowlist +//! +//! - **notification-all**: Enables all [Notification APIs](https://tauri.studio/en/docs/api/js/modules/notification). +//! +//! ### OS allowlist +//! +//! - **os-all**: Enables all [OS APIs](https://tauri.studio/en/docs/api/js/modules/os). +//! +//! ### Path allowlist +//! +//! - **path-all**: Enables all [Path APIs](https://tauri.studio/en/docs/api/js/modules/path). +//! +//! ### Process allowlist +//! +//! - **process-all**: Enables all [Process APIs](https://tauri.studio/en/docs/api/js/modules/process). +//! - **process-exit**: Enables the [`exit` API](https://tauri.studio/en/docs/api/js/modules/process#exit). +//! - **process-relaunch**: Enables the [`relaunch` API](https://tauri.studio/en/docs/api/js/modules/process#relaunch). +//! +//! ### Protocol allowlist +//! +//! - **protocol-all**: Enables all Protocol APIs. +//! - **protocol-asset**: Enables the `asset` custom protocol. +//! +//! ### Shell allowlist +//! +//! - **shell-all**: Enables all [Clipboard APIs](https://tauri.studio/en/docs/api/js/modules/shell). +//! - **shell-execute**: Enables [executing arbitrary programs](https://tauri.studio/en/docs/api/js/classes/shell.Command#constructor). +//! - **shell-sidecar**: Enables [executing a `sidecar` program](https://tauri.studio/en/docs/api/js/classes/shell.Command#sidecar). +//! - **shell-open**: Enables the [`open` API](https://tauri.studio/en/docs/api/js/modules/shell#open). +//! +//! ### Window allowlist +//! +//! - **window-all**: Enables all [Window APIs](https://tauri.studio/en/docs/api/js/modules/window). +//! - **window-create**: Enables the API used to [create new windows](https://tauri.studio/en/docs/api/js/classes/window.webviewwindow/). +//! - **window-center**: Enables the [`center` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#center). +//! - **window-request-user-attention**: Enables the [`requestUserAttention` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#requestuserattention). +//! - **window-set-resizable**: Enables the [`setResizable` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setresizable). +//! - **window-set-title**: Enables the [`setTitle` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#settitle). +//! - **window-maximize**: Enables the [`maximize` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#maximize). +//! - **window-unmaximize**: Enables the [`unmaximize` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#unmaximize). +//! - **window-minimize**: Enables the [`minimize` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#minimize). +//! - **window-unminimize**: Enables the [`unminimize` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#unminimize). +//! - **window-show**: Enables the [`show` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#show). +//! - **window-hide**: Enables the [`hide` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#hide). +//! - **window-close**: Enables the [`close` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#close). +//! - **window-set-decorations**: Enables the [`setDecorations` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setdecorations). +//! - **window-set-always-on-top**: Enables the [`setAlwaysOnTop` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setalwaysontop). +//! - **window-set-size**: Enables the [`setSize` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setsize). +//! - **window-set-min-size**: Enables the [`setMinSize` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setminsize). +//! - **window-set-max-size**: Enables the [`setMaxSize` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setmaxsize). +//! - **window-set-position**: Enables the [`setPosition` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setposition). +//! - **window-set-fullscreen**: Enables the [`setFullscreen` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setfullscreen). +//! - **window-set-focus**: Enables the [`setFocus` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setfocus). +//! - **window-set-icon**: Enables the [`setIcon` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#seticon). +//! - **window-set-skip-taskbar**: Enables the [`setSkipTaskbar` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#setskiptaskbar). +//! - **window-start-dragging**: Enables the [`startDragging` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#startdragging). +//! - **window-print**: Enables the [`print` API](https://tauri.studio/en/docs/api/js/classes/window.WebviewWindow#print). #![warn(missing_docs, rust_2018_idioms)] #![cfg_attr(doc_cfg, feature(doc_cfg))] @@ -24,6 +135,9 @@ pub use embed_plist; /// The Tauri error enum. pub use error::Error; +#[cfg(shell_scope)] +#[doc(hidden)] +pub use regex; pub use tauri_macros::{command, generate_handler}; pub mod api; @@ -36,9 +150,12 @@ mod error; mod event; mod hooks; mod manager; +mod pattern; pub mod plugin; pub mod window; -use tauri_runtime as runtime; +pub use tauri_runtime as runtime; +/// The allowlist scopes. +pub mod scope; pub mod settings; mod state; #[cfg(feature = "updater")] @@ -57,15 +174,12 @@ pub type Result = std::result::Result; /// A task to run on the main thread. pub type SyncTask = Box; -use crate::{ - event::{Event as EmittedEvent, EventHandler}, - runtime::window::PendingWindow, -}; +use crate::runtime::window::PendingWindow; use serde::Serialize; use std::{collections::HashMap, fmt, sync::Arc}; // Export types likely to be used by the application. -pub use runtime::{http, menu::CustomMenuItem}; +pub use runtime::http; #[cfg(target_os = "macos")] #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))] @@ -82,15 +196,20 @@ pub use { }; pub use { self::app::WindowMenuEvent, - self::runtime::menu::{Menu, MenuItem, Submenu}, + self::event::{Event, EventHandler}, + self::runtime::menu::{CustomMenuItem, Menu, MenuEntry, MenuItem, Submenu}, self::window::menu::MenuEvent, }; pub use { - self::app::{App, AppHandle, Builder, CloseRequestApi, Event, GlobalWindowEvent, PathResolver}, + self::app::{ + App, AppHandle, AssetResolver, Builder, CloseRequestApi, GlobalWindowEvent, PathResolver, + RunEvent, + }, self::hooks::{ - Invoke, InvokeError, InvokeHandler, InvokeMessage, InvokeResolver, InvokeResponse, OnPageLoad, - PageLoadPayload, SetupHook, + Invoke, InvokeError, InvokeHandler, InvokeMessage, InvokePayload, InvokeResolver, + InvokeResponder, InvokeResponse, OnPageLoad, PageLoadPayload, SetupHook, }, + self::manager::Asset, self::runtime::{ webview::{WebviewAttributes, WindowBuilder}, window::{ @@ -103,9 +222,10 @@ pub use { self::utils::{ assets::Assets, config::{Config, WindowUrl}, - PackageInfo, + Env, PackageInfo, }, self::window::{Monitor, Window}, + scope::*, }; /// Reads the config file at compile time and generates a [`Context`] based on its content. @@ -142,28 +262,36 @@ macro_rules! tauri_build_context { }; } +pub use pattern::Pattern; + /// User supplied data required inside of a Tauri application. /// /// # Stability -/// This is the output of the `tauri::generate_context!` macro, and is not considered part of the stable API. +/// This is the output of the [`generate_context`] macro, and is not considered part of the stable API. /// Unless you know what you are doing and are prepared for this type to have breaking changes, do not create it yourself. pub struct Context { pub(crate) config: Config, pub(crate) assets: Arc, pub(crate) default_window_icon: Option>, pub(crate) system_tray_icon: Option, - pub(crate) package_info: crate::PackageInfo, + pub(crate) package_info: PackageInfo, pub(crate) _info_plist: (), + pub(crate) pattern: Pattern, + #[cfg(shell_scope)] + pub(crate) shell_scope: scope::ShellScopeConfig, } impl fmt::Debug for Context { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Context") - .field("config", &self.config) + let mut d = f.debug_struct("Context"); + d.field("config", &self.config) .field("default_window_icon", &self.default_window_icon) .field("system_tray_icon", &self.system_tray_icon) .field("package_info", &self.package_info) - .finish() + .field("pattern", &self.pattern); + #[cfg(shell_scope)] + d.field("shell_scope", &self.shell_scope); + d.finish() } } @@ -218,25 +346,41 @@ impl Context { /// Package information. #[inline(always)] - pub fn package_info(&self) -> &crate::PackageInfo { + pub fn package_info(&self) -> &PackageInfo { &self.package_info } /// A mutable reference to the package information. #[inline(always)] - pub fn package_info_mut(&mut self) -> &mut crate::PackageInfo { + pub fn package_info_mut(&mut self) -> &mut PackageInfo { &mut self.package_info } + /// The application pattern. + #[inline(always)] + pub fn pattern(&self) -> &Pattern { + &self.pattern + } + + /// The scoped shell commands, where the `HashMap` key is the name each configuration. + #[cfg(shell_scope)] + #[inline(always)] + pub fn allowed_commands(&self) -> &scope::ShellScopeConfig { + &self.shell_scope + } + /// Create a new [`Context`] from the minimal required items. #[inline(always)] + #[allow(clippy::too_many_arguments)] pub fn new( config: Config, assets: Arc, default_window_icon: Option>, system_tray_icon: Option, - package_info: crate::PackageInfo, + package_info: PackageInfo, info_plist: (), + pattern: Pattern, + #[cfg(shell_scope)] shell_scope: scope::ShellScopeConfig, ) -> Self { Self { config, @@ -245,6 +389,9 @@ impl Context { system_tray_icon, package_info, _info_plist: info_plist, + pattern, + #[cfg(shell_scope)] + shell_scope, } } } @@ -259,20 +406,20 @@ pub trait Manager: sealed::ManagerBase { /// Emits a event to all windows. fn emit_all(&self, event: &str, payload: S) -> Result<()> { - self.manager().emit_filter(event, payload, |_| true) + self.manager().emit_filter(event, None, payload, |_| true) } /// Emits an event to a window with the specified label. fn emit_to(&self, label: &str, event: &str, payload: S) -> Result<()> { self .manager() - .emit_filter(event, payload, |w| label == w.label()) + .emit_filter(event, None, payload, |w| label == w.label()) } /// Listen to a global event. fn listen_global(&self, event: impl Into, handler: F) -> EventHandler where - F: Fn(EmittedEvent) + Send + 'static, + F: Fn(Event) + Send + 'static, { self.manager().listen(event.into(), None, handler) } @@ -280,7 +427,7 @@ pub trait Manager: sealed::ManagerBase { /// Listen to a global event only once. fn once_global(&self, event: impl Into, handler: F) -> EventHandler where - F: Fn(EmittedEvent) + Send + 'static, + F: FnOnce(Event) + Send + 'static, { self.manager().once(event.into(), None, handler) } @@ -319,7 +466,12 @@ pub trait Manager: sealed::ManagerBase { where T: Send + Sync + 'static, { - self.manager().inner.state.get() + self + .manager() + .inner + .state + .try_get() + .expect("state() called before manage() for given type") } /// Tries to get the managed state for the type `T`. Returns `None` if the type is not managed. @@ -329,6 +481,28 @@ pub trait Manager: sealed::ManagerBase { { self.manager().inner.state.try_get() } + + /// Gets the managed [`Env`]. + fn env(&self) -> Env { + self.state::().inner().clone() + } + + /// Gets the scope for the filesystem APIs. + fn fs_scope(&self) -> FsScope { + self.state::().inner().fs.clone() + } + + /// Gets the scope for the asset protocol. + #[cfg(protocol_asset)] + fn asset_protocol_scope(&self) -> FsScope { + self.state::().inner().asset_protocol.clone() + } + + /// Gets the scope for the shell execute APIs. + #[cfg(shell_scope)] + fn shell_scope(&self) -> ShellScope { + self.state::().inner().shell.clone() + } } /// Prevent implementation details from leaking out of the [`Manager`] trait. @@ -348,6 +522,11 @@ pub(crate) mod sealed { Dispatch(R::Dispatcher), } + #[derive(Clone, serde::Serialize)] + struct WindowCreatedEvent { + label: String, + } + /// Managed handle to the application runtime. pub trait ManagerBase { /// The manager behind the [`Managed`] item. @@ -366,24 +545,38 @@ pub(crate) mod sealed { let pending = self .manager() .prepare_window(self.app_handle(), pending, &labels)?; - match self.runtime() { - RuntimeOrDispatch::Runtime(runtime) => runtime.create_window(pending).map_err(Into::into), - RuntimeOrDispatch::RuntimeHandle(handle) => { - handle.create_window(pending).map_err(Into::into) - } - RuntimeOrDispatch::Dispatch(mut dispatcher) => { - dispatcher.create_window(pending).map_err(Into::into) - } + let window = match self.runtime() { + RuntimeOrDispatch::Runtime(runtime) => runtime.create_window(pending), + RuntimeOrDispatch::RuntimeHandle(handle) => handle.create_window(pending), + RuntimeOrDispatch::Dispatch(mut dispatcher) => dispatcher.create_window(pending), } - .map(|window| self.manager().attach_window(self.app_handle(), window)) + .map(|window| self.manager().attach_window(self.app_handle(), window))?; + + self.manager().emit_filter( + "tauri://window-created", + None, + Some(WindowCreatedEvent { + label: window.label().into(), + }), + |w| w != &window, + )?; + + Ok(window) } } } +/// Utilities for unit testing on Tauri applications. #[cfg(test)] -mod test { +pub mod test; + +#[cfg(test)] +mod test_utils { use proptest::prelude::*; + pub fn assert_send() {} + pub fn assert_sync() {} + proptest! { #![proptest_config(ProptestConfig::with_cases(10000))] #[test] diff --git a/core/tauri/src/manager.rs b/core/tauri/src/manager.rs index 11634f7f6277..8f8315f905ff 100644 --- a/core/tauri/src/manager.rs +++ b/core/tauri/src/manager.rs @@ -2,17 +2,43 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, + fmt, + fs::create_dir_all, + sync::{Arc, Mutex, MutexGuard}, +}; + +use serde::Serialize; +use serde_json::Value as JsonValue; +use serialize_to_javascript::{default_template, DefaultTemplate, Template}; +use url::Url; + +use tauri_macros::default_runtime; +#[cfg(feature = "isolation")] +use tauri_utils::pattern::isolation::RawIsolationPayload; +use tauri_utils::{ + assets::{AssetKey, CspHash}, + html::{SCRIPT_NONCE_TOKEN, STYLE_NONCE_TOKEN}, +}; + +use crate::app::{GlobalMenuEventListener, WindowMenuEvent}; +use crate::hooks::IpcJavascript; +#[cfg(feature = "isolation")] +use crate::hooks::IsolationJavascript; +use crate::pattern::{format_real_schema, PatternJavascript}; use crate::{ app::{AppHandle, GlobalWindowEvent, GlobalWindowEventListener}, - event::{Event, EventHandler, Listeners}, - hooks::{InvokeHandler, OnPageLoad, PageLoadPayload}, + event::{assert_event_name_is_valid, Event, EventHandler, Listeners}, + hooks::{InvokeHandler, InvokePayload, InvokeResponder, OnPageLoad, PageLoadPayload}, plugin::PluginStore, runtime::{ http::{ - HttpRange, MimeType, Request as HttpRequest, Response as HttpResponse, + MimeType, Request as HttpRequest, Response as HttpResponse, ResponseBuilder as HttpResponseBuilder, }, - webview::{FileDropEvent, FileDropHandler, InvokePayload, WebviewRpcHandler, WindowBuilder}, + webview::{FileDropEvent, FileDropHandler, WebviewIpcHandler, WindowBuilder}, window::{dpi::PhysicalSize, DetachedWindow, PendingWindow, WindowEvent}, Icon, Runtime, }, @@ -21,32 +47,13 @@ use crate::{ config::{AppUrl, Config, WindowUrl}, PackageInfo, }, - Context, Invoke, StateManager, Window, + Context, Invoke, Pattern, StateManager, Window, }; -#[cfg(target_os = "windows")] +#[cfg(any(target_os = "linux", target_os = "windows"))] use crate::api::path::{resolve_path, BaseDirectory}; -use crate::app::{GlobalMenuEventListener, WindowMenuEvent}; - -use crate::{ - runtime::menu::{Menu, MenuEntry, MenuHash, MenuId}, - MenuEvent, -}; - -use serde::Serialize; -use serde_json::Value as JsonValue; -use std::{ - borrow::Cow, - collections::{HashMap, HashSet}, - fmt, - fs::create_dir_all, - io::SeekFrom, - sync::{Arc, Mutex, MutexGuard}, -}; -use tauri_macros::default_runtime; -use tokio::io::{AsyncReadExt, AsyncSeekExt}; -use url::Url; +use crate::{runtime::menu::Menu, MenuEvent}; const WINDOW_RESIZED_EVENT: &str = "tauri://resize"; const WINDOW_MOVED_EVENT: &str = "tauri://move"; @@ -57,6 +64,136 @@ const WINDOW_BLUR_EVENT: &str = "tauri://blur"; const WINDOW_SCALE_FACTOR_CHANGED_EVENT: &str = "tauri://scale-change"; const MENU_EVENT: &str = "tauri://menu"; +#[derive(Default)] +/// Spaced and quoted Content-Security-Policy hash values. +struct CspHashStrings { + script: String, + style: String, +} + +/// Sets the CSP value to the asset HTML if needed (on Linux). +/// Returns the CSP string for access on the response header (on Windows and macOS). +fn set_csp( + asset: &mut String, + assets: Arc, + asset_path: &AssetKey, + #[allow(unused_variables)] manager: &WindowManager, + mut csp: String, +) -> String { + let hash_strings = + assets + .csp_hashes(asset_path) + .fold(CspHashStrings::default(), |mut acc, hash| { + match hash { + CspHash::Script(hash) => { + acc.script.push(' '); + acc.script.push_str(hash); + } + CspHash::Style(hash) => { + acc.style.push(' '); + acc.style.push_str(hash); + } + _csp_hash => { + #[cfg(debug_assertions)] + eprintln!("Unknown CspHash variant encountered: {:?}", _csp_hash) + } + } + + acc + }); + + replace_csp_nonce( + asset, + SCRIPT_NONCE_TOKEN, + &mut csp, + "script-src", + hash_strings.script, + ); + + replace_csp_nonce( + asset, + STYLE_NONCE_TOKEN, + &mut csp, + "style-src", + hash_strings.style, + ); + + #[cfg(feature = "isolation")] + if let Pattern::Isolation { schema, .. } = &manager.inner.pattern { + let default_src = format!("default-src {}", format_real_schema(schema)); + if csp.contains("default-src") { + csp = csp.replace("default-src", &default_src); + } else { + csp.push_str("; "); + csp.push_str(&default_src); + } + } + + #[cfg(target_os = "linux")] + { + *asset = asset.replacen(tauri_utils::html::CSP_TOKEN, &csp, 1); + } + csp +} + +// inspired by https://github.com/rust-lang/rust/blob/1be5c8f90912c446ecbdc405cbc4a89f9acd20fd/library/alloc/src/str.rs#L260-L297 +fn replace_with_callback String>( + original: &str, + pattern: &str, + mut replacement: F, +) -> String { + let mut result = String::new(); + let mut last_end = 0; + for (start, part) in original.match_indices(pattern) { + result.push_str(unsafe { original.get_unchecked(last_end..start) }); + result.push_str(&replacement()); + last_end = start + part.len(); + } + result.push_str(unsafe { original.get_unchecked(last_end..original.len()) }); + result +} + +fn replace_csp_nonce( + asset: &mut String, + token: &str, + csp: &mut String, + csp_attr: &str, + hashes: String, +) { + let mut nonces = Vec::new(); + *asset = replace_with_callback(asset, token, || { + let nonce = rand::random::(); + nonces.push(nonce); + nonce.to_string() + }); + + if !(nonces.is_empty() && hashes.is_empty()) { + let attr = format!( + "{} 'self'{}{}", + csp_attr, + if nonces.is_empty() { + "".into() + } else { + format!( + " {}", + nonces + .into_iter() + .map(|n| format!("'nonce-{}'", n)) + .collect::>() + .join(" ") + ) + }, + hashes + ); + if csp.contains(csp_attr) { + *csp = csp.replace(csp_attr, &attr); + } else { + csp.push_str("; "); + csp.push_str(&attr); + } + } +} + #[default_runtime(crate::Wry, wry)] pub struct InnerWindowManager { windows: Mutex>>, @@ -79,33 +216,42 @@ pub struct InnerWindowManager { uri_scheme_protocols: HashMap>>, /// The menu set to all windows. menu: Option, - /// Maps runtime id to a strongly typed menu id. - menu_ids: HashMap, /// Menu event listeners to all windows. menu_event_listeners: Arc>>, /// Window event listeners to all windows. window_event_listeners: Arc>>, + /// Responder for invoke calls. + invoke_responder: Arc>, + /// The script that initializes the invoke system. + invoke_initialization_script: String, + /// Application pattern. + pattern: Pattern, } impl fmt::Debug for InnerWindowManager { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s = f.debug_struct("InnerWindowManager"); - #[allow(unused_mut)] - let mut w = s + f.debug_struct("InnerWindowManager") .field("plugins", &self.plugins) .field("state", &self.state) .field("config", &self.config) .field("default_window_icon", &self.default_window_icon) - .field("package_info", &self.package_info); - { - w = w - .field("menu", &self.menu) - .field("menu_ids", &self.menu_ids); - } - w.finish() + .field("package_info", &self.package_info) + .field("menu", &self.menu) + .field("pattern", &self.pattern) + .finish() } } +/// A resolved asset. +pub struct Asset { + /// The asset bytes. + pub bytes: Vec, + /// The asset's mime type. + pub mime_type: String, + /// The `Content-Security-Policy` header value. + pub csp_header: Option, +} + /// Uses a custom URI scheme handler to resolve file requests pub struct CustomProtocol { /// Handler for protocol @@ -121,26 +267,12 @@ pub struct CustomProtocol { #[derive(Debug)] pub struct WindowManager { pub inner: Arc>, - invoke_keys: Arc>>, } impl Clone for WindowManager { fn clone(&self) -> Self { Self { inner: self.inner.clone(), - invoke_keys: self.invoke_keys.clone(), - } - } -} - -fn get_menu_ids(map: &mut HashMap, menu: &Menu) { - for item in &menu.items { - match item { - MenuEntry::CustomItem(c) => { - map.insert(c.id, c.id_str.clone()); - } - MenuEntry::Submenu(s) => get_menu_ids(map, &s.inner), - _ => {} } } } @@ -148,7 +280,7 @@ fn get_menu_ids(map: &mut HashMap, menu: &Menu) { impl WindowManager { #[allow(clippy::too_many_arguments)] pub(crate) fn with_handlers( - context: Context, + #[allow(unused_mut)] mut context: Context, plugins: PluginStore, invoke_handler: Box>, on_page_load: Box>, @@ -156,7 +288,14 @@ impl WindowManager { state: StateManager, window_event_listeners: Vec>, (menu, menu_event_listeners): (Option, Vec>), + (invoke_responder, invoke_initialization_script): (Arc>, String), ) -> Self { + // generate a random isolation key at runtime + #[cfg(feature = "isolation")] + if let Pattern::Isolation { ref mut key, .. } = &mut context.pattern { + *key = uuid::Uuid::new_v4().to_string(); + } + Self { inner: Arc::new(InnerWindowManager { windows: Mutex::default(), @@ -169,22 +308,21 @@ impl WindowManager { assets: context.assets, default_window_icon: context.default_window_icon, package_info: context.package_info, + pattern: context.pattern, uri_scheme_protocols, - menu_ids: { - let mut map = HashMap::new(); - if let Some(menu) = &menu { - get_menu_ids(&mut map, menu) - } - map - }, menu, menu_event_listeners: Arc::new(menu_event_listeners), window_event_listeners: Arc::new(window_event_listeners), + invoke_responder, + invoke_initialization_script, }), - invoke_keys: Default::default(), } } + pub(crate) fn pattern(&self) -> &Pattern { + &self.inner.pattern + } + /// Get a locked handle to the windows. pub(crate) fn windows_lock(&self) -> MutexGuard<'_, HashMap>> { self.inner.windows.lock().expect("poisoned window manager") @@ -195,9 +333,9 @@ impl WindowManager { self.inner.state.clone() } - /// Get the menu ids mapper. - pub(crate) fn menu_ids(&self) -> HashMap { - self.inner.menu_ids.clone() + /// The invoke responder. + pub(crate) fn invoke_responder(&self) -> Arc> { + self.inner.invoke_responder.clone() } /// Get the base path to serve data from. @@ -224,24 +362,40 @@ impl WindowManager { } } - fn generate_invoke_key(&self) -> u32 { - let key = rand::random(); - self.invoke_keys.lock().unwrap().push(key); - key + /// Get the origin as it will be seen in the webview. + fn get_browser_origin(&self) -> Cow<'_, str> { + match self.base_path() { + AppUrl::Url(WindowUrl::External(url)) => { + let mut url = url.to_string(); + if url.ends_with('/') { + url.pop(); + } + Cow::Owned(url) + } + _ => Cow::Owned(format_real_schema("tauri")), + } } - /// Checks whether the invoke key is valid or not. - /// - /// An invoke key is valid if it was generated by this manager instance. - pub(crate) fn verify_invoke_key(&self, key: u32) -> bool { - self.invoke_keys.lock().unwrap().contains(&key) + fn csp(&self) -> Option { + if cfg!(feature = "custom-protocol") { + self.inner.config.tauri.security.csp.clone() + } else { + self + .inner + .config + .tauri + .security + .dev_csp + .clone() + .or_else(|| self.inner.config.tauri.security.csp.clone()) + } } fn prepare_pending_window( &self, mut pending: PendingWindow, label: &str, - pending_labels: &[String], + window_labels: &[String], app_handle: AppHandle, ) -> crate::Result> { let is_init_global = self.inner.config.build.with_global_tauri; @@ -252,24 +406,54 @@ impl WindowManager { .expect("poisoned plugin store") .initialization_script(); + let pattern_init = PatternJavascript { + pattern: self.pattern().into(), + } + .render_default(&Default::default())?; + + let ipc_init = IpcJavascript { + isolation_origin: &match self.pattern() { + #[cfg(feature = "isolation")] + Pattern::Isolation { schema, .. } => crate::pattern::format_real_schema(schema), + _ => "".to_string(), + }, + } + .render_default(&Default::default())?; + let mut webview_attributes = pending.webview_attributes; + + let mut window_labels = window_labels.to_vec(); + let l = label.to_string(); + if !window_labels.contains(&l) { + window_labels.push(l); + } webview_attributes = webview_attributes - .initialization_script(&self.initialization_script(&plugin_init, is_init_global)) + .initialization_script(&self.inner.invoke_initialization_script) .initialization_script(&format!( r#" - window.__TAURI__.__windows = {window_labels_array}.map(function (label) {{ return {{ label: label }} }}); - window.__TAURI__.__currentWindow = {{ label: {current_window_label} }} + Object.defineProperty(window, '__TAURI_METADATA__', {{ + value: {{ + __windows: {window_labels_array}.map(function (label) {{ return {{ label: label }} }}), + __currentWindow: {{ label: {current_window_label} }} + }} + }}) "#, - window_labels_array = serde_json::to_string(pending_labels)?, + window_labels_array = serde_json::to_string(&window_labels)?, current_window_label = serde_json::to_string(&label)?, - )); - - #[cfg(dev)] - { - webview_attributes = webview_attributes.initialization_script(&format!( - "window.__TAURI_INVOKE_KEY__ = {}", - self.generate_invoke_key() - )); + )) + .initialization_script(&self.initialization_script(&ipc_init.into_string(),&pattern_init.into_string(),&plugin_init, is_init_global)?) + ; + + #[cfg(feature = "isolation")] + if let Pattern::Isolation { schema, .. } = self.pattern() { + webview_attributes = webview_attributes.initialization_script( + &IsolationJavascript { + isolation_src: &crate::pattern::format_real_schema(schema), + style: tauri_utils::pattern::isolation::IFRAME_STYLE, + } + .render_default(&Default::default())? + .into_string(), + ); } pending.webview_attributes = webview_attributes; @@ -281,9 +465,9 @@ impl WindowManager { } } - if !pending.window_builder.has_menu() { + if pending.window_builder.get_menu().is_none() { if let Some(menu) = &self.inner.menu { - pending.window_builder = pending.window_builder.menu(menu.clone()); + pending = pending.set_menu(menu.clone()); } } @@ -302,98 +486,226 @@ impl WindowManager { pending.register_uri_scheme_protocol("tauri", self.prepare_uri_scheme_protocol()); registered_scheme_protocols.push("tauri".into()); } + + #[cfg(protocol_asset)] if !registered_scheme_protocols.contains(&"asset".into()) { + use tokio::io::{AsyncReadExt, AsyncSeekExt}; + use url::Position; + let asset_scope = self.state().get::().asset_protocol.clone(); + let window_url = Url::parse(&pending.url).unwrap(); + let window_origin = + if cfg!(windows) && window_url.scheme() != "http" && window_url.scheme() != "https" { + format!("https://{}.localhost", window_url.scheme()) + } else { + format!( + "{}://{}{}", + window_url.scheme(), + window_url.host().unwrap(), + if let Some(port) = window_url.port() { + format!(":{}", port) + } else { + "".into() + } + ) + }; pending.register_uri_scheme_protocol("asset", move |request| { + let parsed_path = Url::parse(request.uri())?; + let filtered_path = &parsed_path[..Position::AfterPath]; #[cfg(target_os = "windows")] - let path = request.uri().replace("asset://localhost/", ""); + let path = filtered_path.replace("asset://localhost/", ""); #[cfg(not(target_os = "windows"))] - let path = request.uri().replace("asset://", ""); + let path = filtered_path.replace("asset://", ""); let path = percent_encoding::percent_decode(path.as_bytes()) .decode_utf8_lossy() .to_string(); - let path_for_data = path.clone(); + + if !asset_scope.is_allowed(&path) { + #[cfg(debug_assertions)] + eprintln!("asset protocol not configured to allow the path: {}", path); + return HttpResponseBuilder::new().status(403).body(Vec::new()); + } + + let path_ = path.clone(); + + let mut response = + HttpResponseBuilder::new().header("Access-Control-Allow-Origin", &window_origin); // handle 206 (partial range) http request - if let Some(range) = request.headers().get("range") { - let mut status_code = 200; - let path_for_data = path_for_data.clone(); - let mut response = HttpResponseBuilder::new(); - let (response, status_code, data) = crate::async_runtime::block_on(async move { + if let Some(range) = request + .headers() + .get("range") + .and_then(|r| r.to_str().map(|r| r.to_string()).ok()) + { + let (headers, status_code, data) = crate::async_runtime::safe_block_on(async move { + let mut headers = HashMap::new(); let mut buf = Vec::new(); - let mut file = tokio::fs::File::open(path_for_data.clone()).await.unwrap(); + // open the file + let mut file = match tokio::fs::File::open(path_.clone()).await { + Ok(file) => file, + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("Failed to open asset: {}", e); + return (headers, 404, buf); + } + }; // Get the file size - let file_size = file.metadata().await.unwrap().len(); + let file_size = match file.metadata().await { + Ok(metadata) => metadata.len(), + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("Failed to read asset metadata: {}", e); + return (headers, 404, buf); + } + }; // parse the range - let range = HttpRange::parse(range.to_str().unwrap(), file_size).unwrap(); + let range = match crate::runtime::http::HttpRange::parse(&range, file_size) { + Ok(r) => r, + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("Failed to parse range: {:?}", e); + return (headers, 400, buf); + } + }; // FIXME: Support multiple ranges // let support only 1 range for now - let first_range = range.first(); - if let Some(range) = first_range { + let status_code = if let Some(range) = range.first() { let mut real_length = range.length; // prevent max_length; // specially on webview2 if range.length > file_size / 3 { // max size sent (400ko / request) // as it's local file system we can afford to read more often - real_length = 1024 * 400; + real_length = std::cmp::min(file_size - range.start, 1024 * 400); } // last byte we are reading, the length of the range include the last byte // who should be skipped on the header let last_byte = range.start + real_length - 1; + + headers.insert("Connection", "Keep-Alive".into()); + headers.insert("Accept-Ranges", "bytes".into()); + headers.insert("Content-Length", real_length.to_string()); + headers.insert( + "Content-Range", + format!("bytes {}-{}/{}", range.start, last_byte, file_size), + ); + + if let Err(e) = file.seek(std::io::SeekFrom::Start(range.start)).await { + #[cfg(debug_assertions)] + eprintln!("Failed to seek file to {}: {}", range.start, e); + return (headers, 422, buf); + } + + if let Err(e) = file.take(real_length).read_to_end(&mut buf).await { + #[cfg(debug_assertions)] + eprintln!("Failed read file: {}", e); + return (headers, 422, buf); + } // partial content - status_code = 206; - - response = response - .header("Connection", "Keep-Alive") - .header("Accept-Ranges", "bytes") - .header("Content-Length", real_length) - .header( - "Content-Range", - format!("bytes {}-{}/{}", range.start, last_byte, file_size), - ); - - file.seek(SeekFrom::Start(range.start)).await.unwrap(); - file.take(real_length).read_to_end(&mut buf).await.unwrap(); - } + 206 + } else { + 200 + }; - (response, status_code, buf) + (headers, status_code, buf) }); - if !data.is_empty() { - let mime_type = MimeType::parse(&data, &path); - return response.mimetype(&mime_type).status(status_code).body(data); + for (k, v) in headers { + response = response.header(k, v); + } + + let mime_type = MimeType::parse(&data, &path); + response.mimetype(&mime_type).status(status_code).body(data) + } else { + match crate::async_runtime::safe_block_on(async move { tokio::fs::read(path_).await }) { + Ok(data) => { + let mime_type = MimeType::parse(&data, &path); + response.mimetype(&mime_type).body(data) + } + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("Failed to read file: {}", e); + response.status(404).body(Vec::new()) + } } } + }); + } - let data = - crate::async_runtime::block_on(async move { tokio::fs::read(path_for_data).await })?; - let mime_type = MimeType::parse(&data, &path); - HttpResponseBuilder::new().mimetype(&mime_type).body(data) + #[cfg(feature = "isolation")] + if let Pattern::Isolation { + assets, + schema, + key: _, + crypto_keys, + } = &self.inner.pattern + { + let assets = assets.clone(); + let schema_ = schema.clone(); + let url_base = format!("{}://localhost", schema_); + let aes_gcm_key = *crypto_keys.aes_gcm().raw(); + + pending.register_uri_scheme_protocol(schema, move |request| { + match request_to_path(request, &url_base).as_str() { + "index.html" => match assets.get(&"index.html".into()) { + Some(asset) => { + let asset = String::from_utf8_lossy(asset.as_ref()); + let template = tauri_utils::pattern::isolation::IsolationJavascriptRuntime { + runtime_aes_gcm_key: &aes_gcm_key, + }; + match template.render(asset.as_ref(), &Default::default()) { + Ok(asset) => HttpResponseBuilder::new() + .mimetype("text/html") + .body(asset.into_string().as_bytes().to_vec()), + Err(_) => HttpResponseBuilder::new() + .status(500) + .mimetype("text/plain") + .body(Vec::new()), + } + } + + None => HttpResponseBuilder::new() + .status(404) + .mimetype("text/plain") + .body(Vec::new()), + }, + _ => HttpResponseBuilder::new() + .status(404) + .mimetype("text/plain") + .body(Vec::new()), + } }); } Ok(pending) } - fn prepare_rpc_handler(&self, app_handle: AppHandle) -> WebviewRpcHandler { + fn prepare_ipc_handler(&self, app_handle: AppHandle) -> WebviewIpcHandler { let manager = self.clone(); - Box::new(move |window, request| { + Box::new(move |window, #[allow(unused_mut)] mut request| { let window = Window::new(manager.clone(), window, app_handle.clone()); - let command = request.command.clone(); - let arg = request - .params - .unwrap() - .as_array_mut() - .unwrap() - .first_mut() - .unwrap_or(&mut JsonValue::Null) - .take(); - match serde_json::from_value::(arg) { + #[cfg(feature = "isolation")] + if let Pattern::Isolation { crypto_keys, .. } = manager.pattern() { + match RawIsolationPayload::try_from(request.as_str()) + .and_then(|raw| crypto_keys.decrypt(raw)) + { + Ok(json) => request = json, + Err(e) => { + let error: crate::Error = e.into(); + let _ = window.eval(&format!( + r#"console.error({})"#, + JsonValue::String(error.to_string()) + )); + return; + } + } + } + + match serde_json::from_str::(&request) { Ok(message) => { - let _ = window.on_message(command, message); + let _ = window.on_message(message); } Err(e) => { let error: crate::Error = e.into(); @@ -406,157 +718,213 @@ impl WindowManager { }) } + pub fn get_asset(&self, mut path: String) -> Result> { + let assets = &self.inner.assets; + if path.ends_with('/') { + path.pop(); + } + path = percent_encoding::percent_decode(path.as_bytes()) + .decode_utf8_lossy() + .to_string(); + let path = if path.is_empty() { + // if the url is `tauri://localhost`, we should load `index.html` + "index.html".to_string() + } else { + // skip leading `/` + path.chars().skip(1).collect::() + }; + let is_html = path.ends_with(".html"); + + let mut asset_path = AssetKey::from(path.as_str()); + + let asset_response = assets + .get(&path.as_str().into()) + .or_else(|| { + let fallback = format!("{}/index.html", path.as_str()).into(); + let asset = assets.get(&fallback); + asset_path = fallback; + asset + }) + .or_else(|| { + #[cfg(debug_assertions)] + eprintln!("Asset `{}` not found; fallback to index.html", path); // TODO log::error! + let fallback = AssetKey::from("index.html"); + let asset = assets.get(&fallback); + asset_path = fallback; + asset + }) + .ok_or_else(|| crate::Error::AssetNotFound(path.clone())) + .map(Cow::into_owned); + + let mut csp_header = None; + + match asset_response { + Ok(asset) => { + let final_data = if is_html { + let mut asset = String::from_utf8_lossy(&asset).into_owned(); + if let Some(csp) = self.csp() { + csp_header.replace(set_csp( + &mut asset, + self.inner.assets.clone(), + &asset_path, + self, + csp, + )); + } + + asset.as_bytes().to_vec() + } else { + asset + }; + let mime_type = MimeType::parse(&final_data, &path); + Ok(Asset { + bytes: final_data.to_vec(), + mime_type, + csp_header, + }) + } + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("{:?}", e); // TODO log::error! + Err(Box::new(e)) + } + } + } + #[allow(clippy::type_complexity)] fn prepare_uri_scheme_protocol( &self, ) -> Box Result> + Send + Sync> { - let assets = self.inner.assets.clone(); let manager = self.clone(); Box::new(move |request| { - let mut path = request + let path = request .uri() .split(&['?', '#'][..]) - // ignore query string + // ignore query string and fragment .next() .unwrap() .to_string() .replace("tauri://localhost", ""); - if path.ends_with('/') { - path.pop(); - } - path = percent_encoding::percent_decode(path.as_bytes()) - .decode_utf8_lossy() - .to_string(); - let path = if path.is_empty() { - // if the url is `tauri://localhost`, we should load `index.html` - "index.html".to_string() - } else { - // skip leading `/` - path.chars().skip(1).collect::() - }; - let is_javascript = path.ends_with(".js") || path.ends_with(".cjs") || path.ends_with(".mjs"); - let is_html = path.ends_with(".html"); - - let asset_response = assets - .get(&path.as_str().into()) - .or_else(|| assets.get(&format!("{}/index.html", path.as_str()).into())) - .or_else(|| { - #[cfg(debug_assertions)] - eprintln!("Asset `{}` not found; fallback to index.html", path); // TODO log::error! - assets.get(&"index.html".into()) - }) - .ok_or_else(|| crate::Error::AssetNotFound(path.clone())) - .map(Cow::into_owned); - - match asset_response { - Ok(asset) => { - let final_data = match is_javascript || is_html { - true => String::from_utf8_lossy(&asset) - .into_owned() - .replacen( - "__TAURI__INVOKE_KEY_TOKEN__", - &manager.generate_invoke_key().to_string(), - 1, - ) - .as_bytes() - .to_vec(), - false => asset, - }; - - let mime_type = MimeType::parse(&final_data, &path); - Ok( - HttpResponseBuilder::new() - .mimetype(&mime_type) - .body(final_data)?, - ) - } - Err(e) => { - #[cfg(debug_assertions)] - eprintln!("{:?}", e); // TODO log::error! - Err(Box::new(e)) - } + let asset = manager.get_asset(path)?; + let mut response = HttpResponseBuilder::new().mimetype(&asset.mime_type); + if let Some(csp) = asset.csp_header { + response = response.header("Content-Security-Policy", csp); } + response.body(asset.bytes) }) } fn prepare_file_drop(&self, app_handle: AppHandle) -> FileDropHandler { let manager = self.clone(); Box::new(move |event, window| { - let manager = manager.clone(); - let app_handle = app_handle.clone(); - crate::async_runtime::block_on(async move { - let window = Window::new(manager.clone(), window, app_handle); - let _ = match event { - FileDropEvent::Hovered(paths) => window.emit("tauri://file-drop-hover", Some(paths)), - FileDropEvent::Dropped(paths) => window.emit("tauri://file-drop", Some(paths)), - FileDropEvent::Cancelled => window.emit("tauri://file-drop-cancelled", Some(())), - _ => unimplemented!(), - }; - }); + let window = Window::new(manager.clone(), window, app_handle.clone()); + let _ = match event { + FileDropEvent::Hovered(paths) => window.emit_and_trigger("tauri://file-drop-hover", paths), + FileDropEvent::Dropped(paths) => window.emit_and_trigger("tauri://file-drop", paths), + FileDropEvent::Cancelled => window.emit_and_trigger("tauri://file-drop-cancelled", ()), + _ => unimplemented!(), + }; true }) } fn initialization_script( &self, + ipc_script: &str, + pattern_script: &str, plugin_initialization_script: &str, with_global_tauri: bool, - ) -> String { - let key = self.generate_invoke_key(); - format!( - r#" - (function () {{ - const __TAURI_INVOKE_KEY__ = {key}; - {bundle_script} - }})() - {core_script} - {event_initialization_script} - if (window.rpc) {{ - window.__TAURI_INVOKE__("__initialized", {{ url: window.location.href }}, {key}) - }} else {{ - window.addEventListener('DOMContentLoaded', function () {{ - window.__TAURI_INVOKE__("__initialized", {{ url: window.location.href }}, {key}) - }}) - }} - {plugin_initialization_script} - "#, - key = key, - core_script = include_str!("../scripts/core.js").replace("_KEY_VALUE_", &key.to_string()), - bundle_script = if with_global_tauri { - include_str!("../scripts/bundle.js") - } else { - "" - }, - event_initialization_script = self.event_initialization_script(), - plugin_initialization_script = plugin_initialization_script - ) + ) -> crate::Result { + #[derive(Template)] + #[default_template("../scripts/init.js")] + struct InitJavascript<'a> { + origin: Cow<'a, str>, + #[raw] + pattern_script: &'a str, + #[raw] + ipc_script: &'a str, + #[raw] + bundle_script: &'a str, + // A function to immediately listen to an event. + #[raw] + listen_function: &'a str, + #[raw] + core_script: &'a str, + #[raw] + event_initialization_script: &'a str, + #[raw] + plugin_initialization_script: &'a str, + #[raw] + freeze_prototype: &'a str, + } + + let bundle_script = if with_global_tauri { + include_str!("../scripts/bundle.js") + } else { + "" + }; + + let freeze_prototype = if self.inner.config.tauri.security.freeze_prototype { + include_str!("../scripts/freeze_prototype.js") + } else { + "" + }; + + InitJavascript { + origin: self.get_browser_origin(), + pattern_script, + ipc_script, + bundle_script, + listen_function: &format!( + "function listen(eventName, cb) {{ {} }}", + crate::event::listen_js( + self.event_listeners_object_name(), + "eventName".into(), + 0, + None, + "window['_' + window.__TAURI__.transformCallback(cb) ]".into() + ) + ), + core_script: include_str!("../scripts/core.js"), + event_initialization_script: &self.event_initialization_script(), + plugin_initialization_script, + freeze_prototype, + } + .render_default(&Default::default()) + .map(|s| s.into_string()) + .map_err(Into::into) } fn event_initialization_script(&self) -> String { return format!( " - window['{function}'] = function (eventData) {{ - const listeners = (window['{listeners}'] && window['{listeners}'][eventData.event]) || [] - - for (let i = listeners.length - 1; i >= 0; i--) {{ - const listener = listeners[i] - eventData.id = listener.id - listener.handler(eventData) - }} - }} + Object.defineProperty(window, '{function}', {{ + value: function (eventData) {{ + const listeners = (window['{listeners}'] && window['{listeners}'][eventData.event]) || [] + + for (let i = listeners.length - 1; i >= 0; i--) {{ + const listener = listeners[i] + if (listener.windowLabel === null || listener.windowLabel === eventData.windowLabel) {{ + eventData.id = listener.id + listener.handler(eventData) + }} + }} + }} + }}); ", - function = self.inner.listeners.function_name(), - listeners = self.inner.listeners.listeners_object_name() + function = self.event_emit_function_name(), + listeners = self.event_listeners_object_name() ); } } #[cfg(test)] mod test { - use super::WindowManager; use crate::{generate_context, plugin::PluginStore, StateManager, Wry}; + use super::WindowManager; + #[test] fn check_get_url() { let context = generate_context!("test/fixture/src-tauri/tauri.conf.json", crate); @@ -569,6 +937,7 @@ mod test { StateManager::new(), Default::default(), Default::default(), + (std::sync::Arc::new(|_, _, _, _| ()), "".into()), ); #[cfg(custom_protocol)] @@ -616,12 +985,13 @@ impl WindowManager { &self, app_handle: AppHandle, mut pending: PendingWindow, - pending_labels: &[String], + window_labels: &[String], ) -> crate::Result> { if self.windows_lock().contains_key(&pending.label) { return Err(crate::Error::WindowLabelAlreadyExists(pending.label)); } - let (is_local, url) = match &pending.webview_attributes.url { + #[allow(unused_mut)] // mut url only for the data-url parsing + let (is_local, mut url) = match &pending.webview_attributes.url { WindowUrl::App(path) => { let url = self.get_url(); ( @@ -630,36 +1000,61 @@ impl WindowManager { if path.to_str() != Some("index.html") { url .join(&*path.to_string_lossy()) - .map_err(crate::Error::InvalidUrl)? - .to_string() + .map_err(crate::Error::InvalidUrl) + // this will never fail + .unwrap() } else { - url.to_string() + url.into_owned() }, ) } - WindowUrl::External(url) => (url.scheme() == "tauri", url.to_string()), + WindowUrl::External(url) => (url.scheme() == "tauri", url.clone()), _ => unimplemented!(), }; + #[cfg(not(feature = "window-data-url"))] + if url.scheme() == "data" { + return Err(crate::Error::InvalidWindowUrl( + "data URLs are not supported without the `window-data-url` feature.", + )); + } + + #[cfg(feature = "window-data-url")] + if let Some(csp) = self.csp() { + if url.scheme() == "data" { + if let Ok(data_url) = data_url::DataUrl::process(url.as_str()) { + let (body, _) = data_url.decode_to_vec().unwrap(); + let html = String::from_utf8_lossy(&body).into_owned(); + // naive way to check if it's an html + if html.contains('<') && html.contains('>') { + let mut document = tauri_utils::html::parse(html); + tauri_utils::html::inject_csp(&mut document, &csp); + url.set_path(&format!("text/html,{}", document.to_string())); + } + } + } + } + + pending.url = url.to_string(); + if is_local { let label = pending.label.clone(); - pending = self.prepare_pending_window(pending, &label, pending_labels, app_handle.clone())?; - pending.rpc_handler = Some(self.prepare_rpc_handler(app_handle.clone())); + pending = self.prepare_pending_window(pending, &label, window_labels, app_handle.clone())?; + pending.ipc_handler = Some(self.prepare_ipc_handler(app_handle.clone())); } if pending.webview_attributes.file_drop_handler_enabled { pending.file_drop_handler = Some(self.prepare_file_drop(app_handle)); } - pending.url = url; - // in `Windows`, we need to force a data_directory // but we do respect user-specification - #[cfg(target_os = "windows")] + #[cfg(any(target_os = "linux", target_os = "windows"))] if pending.webview_attributes.data_directory.is_none() { let local_app_data = resolve_path( &self.inner.config, &self.inner.package_info, + self.inner.state.get::().inner(), &self.inner.config.tauri.bundle.identifier, Some(BaseDirectory::LocalData), ); @@ -731,16 +1126,23 @@ impl WindowManager { self.windows_lock().remove(label); } - pub fn emit_filter(&self, event: &str, payload: S, filter: F) -> crate::Result<()> + pub fn emit_filter( + &self, + event: &str, + source_window_label: Option<&str>, + payload: S, + filter: F, + ) -> crate::Result<()> where S: Serialize + Clone, F: Fn(&Window) -> bool, { + assert_event_name_is_valid(event); self .windows_lock() .values() .filter(|&w| filter(w)) - .try_for_each(|window| window.emit(event, payload.clone())) + .try_for_each(|window| window.emit_internal(event, source_window_label, payload.clone())) } pub fn labels(&self) -> HashSet { @@ -760,6 +1162,7 @@ impl WindowManager { } pub fn trigger(&self, event: &str, window: Option, data: Option) { + assert_event_name_is_valid(event); self.inner.listeners.trigger(event, window, data) } @@ -769,14 +1172,17 @@ impl WindowManager { window: Option, handler: F, ) -> EventHandler { + assert_event_name_is_valid(&event); self.inner.listeners.listen(event, window, handler) } - pub fn once( + + pub fn once( &self, event: String, window: Option, handler: F, ) -> EventHandler { + assert_event_name_is_valid(&event); self.inner.listeners.once(event, window, handler) } @@ -803,46 +1209,52 @@ fn on_window_event( event: &WindowEvent, ) -> crate::Result<()> { match event { - WindowEvent::Resized(size) => window.emit(WINDOW_RESIZED_EVENT, Some(size))?, - WindowEvent::Moved(position) => window.emit(WINDOW_MOVED_EVENT, Some(position))?, - WindowEvent::CloseRequested => { - window.emit(WINDOW_CLOSE_REQUESTED_EVENT, Some(()))?; + WindowEvent::Resized(size) => window.emit_and_trigger(WINDOW_RESIZED_EVENT, size)?, + WindowEvent::Moved(position) => window.emit_and_trigger(WINDOW_MOVED_EVENT, position)?, + WindowEvent::CloseRequested { + label: _, + signal_tx, + } => { + if window.has_js_listener(Some(window.label().into()), WINDOW_CLOSE_REQUESTED_EVENT) { + signal_tx.send(true).unwrap(); + } + window.emit_and_trigger(WINDOW_CLOSE_REQUESTED_EVENT, ())?; } WindowEvent::Destroyed => { - window.emit(WINDOW_DESTROYED_EVENT, Some(()))?; + window.emit_and_trigger(WINDOW_DESTROYED_EVENT, ())?; let label = window.label(); for window in manager.inner.windows.lock().unwrap().values() { window.eval(&format!( - r#"window.__TAURI__.__windows = window.__TAURI__.__windows.filter(w => w.label !== "{}");"#, + r#"window.__TAURI_METADATA__.__windows = window.__TAURI_METADATA__.__windows.filter(w => w.label !== "{}");"#, label ))?; } } - WindowEvent::Focused(focused) => window.emit( + WindowEvent::Focused(focused) => window.emit_and_trigger( if *focused { WINDOW_FOCUS_EVENT } else { WINDOW_BLUR_EVENT }, - Some(()), + (), )?, WindowEvent::ScaleFactorChanged { scale_factor, new_inner_size, .. - } => window.emit( + } => window.emit_and_trigger( WINDOW_SCALE_FACTOR_CHANGED_EVENT, - Some(ScaleFactorChanged { + ScaleFactorChanged { scale_factor: *scale_factor, size: *new_inner_size, - }), + }, )?, _ => unimplemented!(), } Ok(()) } -#[derive(Serialize)] +#[derive(Clone, Serialize)] #[serde(rename_all = "camelCase")] struct ScaleFactorChanged { scale_factor: f64, @@ -850,5 +1262,54 @@ struct ScaleFactorChanged { } fn on_menu_event(window: &Window, event: &MenuEvent) -> crate::Result<()> { - window.emit(MENU_EVENT, Some(event.menu_item_id.clone())) + window.emit_and_trigger(MENU_EVENT, event.menu_item_id.clone()) +} + +#[cfg(feature = "isolation")] +fn request_to_path(request: &tauri_runtime::http::Request, replace: &str) -> String { + let mut path = request + .uri() + .split(&['?', '#'][..]) + // ignore query string + .next() + .unwrap() + .to_string() + .replace(replace, ""); + + if path.ends_with('/') { + path.pop(); + } + + let path = percent_encoding::percent_decode(path.as_bytes()) + .decode_utf8_lossy() + .to_string(); + + if path.is_empty() { + // if the url has no path, we should load `index.html` + "index.html".to_string() + } else { + // skip leading `/` + path.chars().skip(1).collect() + } +} + +#[cfg(test)] +mod tests { + use super::replace_with_callback; + + #[test] + fn string_replace_with_callback() { + let mut tauri_index = 0; + for (src, pattern, replacement, result) in [( + "tauri is awesome, tauri is amazing", + "tauri", + || { + tauri_index += 1; + tauri_index.to_string() + }, + "1 is awesome, 2 is amazing", + )] { + assert_eq!(replace_with_callback(src, pattern, replacement), result); + } + } } diff --git a/core/tauri/src/pattern.rs b/core/tauri/src/pattern.rs new file mode 100644 index 000000000000..19b3713033ea --- /dev/null +++ b/core/tauri/src/pattern.rs @@ -0,0 +1,94 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::marker::PhantomData; +#[cfg(feature = "isolation")] +use std::sync::Arc; + +use serde::Serialize; +use serialize_to_javascript::{default_template, Template}; + +use tauri_utils::assets::{Assets, EmbeddedAssets}; + +/// An application pattern. +#[derive(Debug, Clone)] +pub enum Pattern { + /// The brownfield pattern. + Brownfield(PhantomData), + /// Isolation pattern. Recommended for security purposes. + #[cfg(feature = "isolation")] + Isolation { + /// The HTML served on `isolation://index.html`. + assets: Arc, + + /// The schema used for the isolation frames. + schema: String, + + /// A random string used to ensure that the message went through the isolation frame. + /// + /// This should be regenerated at runtime. + key: String, + + /// Cryptographically secure keys + crypto_keys: Box, + }, +} + +/// The shape of the JavaScript Pattern config +#[derive(Debug, Serialize)] +#[serde(rename_all = "lowercase", tag = "pattern")] +pub(crate) enum PatternObject { + /// Brownfield pattern. + Brownfield, + /// Isolation pattern. Recommended for security purposes. + #[cfg(feature = "isolation")] + Isolation { + /// Which `IsolationSide` this `PatternObject` is getting injected into + side: IsolationSide, + }, +} + +impl From<&Pattern> for PatternObject { + fn from(pattern: &Pattern) -> Self { + match pattern { + Pattern::Brownfield(_) => Self::Brownfield, + #[cfg(feature = "isolation")] + Pattern::Isolation { .. } => Self::Isolation { + side: IsolationSide::default(), + }, + } + } +} + +/// Where the JavaScript is injected to +#[derive(Debug, Serialize)] +#[serde(rename_all = "lowercase")] +pub(crate) enum IsolationSide { + /// Original frame, the Brownfield application + Original, + /// Secure frame, the isolation security application + #[allow(dead_code)] + Secure, +} + +impl Default for IsolationSide { + fn default() -> Self { + Self::Original + } +} + +#[derive(Template)] +#[default_template("../scripts/pattern.js")] +pub(crate) struct PatternJavascript { + pub(crate) pattern: PatternObject, +} + +#[allow(dead_code)] +pub(crate) fn format_real_schema(schema: &str) -> String { + if cfg!(windows) { + format!("https://{}.localhost", schema) + } else { + format!("{}://localhost", schema) + } +} diff --git a/core/tauri/src/plugin.rs b/core/tauri/src/plugin.rs index 26f12156d6cf..d8f2a6c18017 100644 --- a/core/tauri/src/plugin.rs +++ b/core/tauri/src/plugin.rs @@ -5,8 +5,10 @@ //! The Tauri plugin extension to expand Tauri functionality. use crate::{ - runtime::Runtime, utils::config::PluginConfig, AppHandle, Invoke, PageLoadPayload, Window, + runtime::Runtime, utils::config::PluginConfig, AppHandle, Invoke, InvokeHandler, OnPageLoad, + PageLoadPayload, RunEvent, Window, }; +use serde::de::DeserializeOwned; use serde_json::Value as JsonValue; use tauri_macros::default_runtime; @@ -43,11 +45,211 @@ pub trait Plugin: Send { #[allow(unused_variables)] fn on_page_load(&mut self, window: Window, payload: PageLoadPayload) {} + /// Callback invoked when the event loop receives a new event. + #[allow(unused_variables)] + fn on_event(&mut self, app: &AppHandle, event: &RunEvent) {} + /// Extend commands to [`crate::Builder::invoke_handler`]. #[allow(unused_variables)] fn extend_api(&mut self, invoke: Invoke) {} } +type SetupHook = dyn Fn(&AppHandle) -> Result<()> + Send + Sync; +type SetupWithConfigHook = dyn Fn(&AppHandle, T) -> Result<()> + Send + Sync; +type OnWebviewReady = dyn Fn(Window) + Send + Sync; +type OnEvent = dyn Fn(&AppHandle, &RunEvent) + Send + Sync; + +/// Builds a [`TauriPlugin`]. +pub struct Builder { + name: &'static str, + invoke_handler: Box>, + setup: Box>, + setup_with_config: Option>>, + js_init_script: Option, + on_page_load: Box>, + on_webview_ready: Box>, + on_event: Box>, +} + +impl Builder { + /// Creates a new Plugin builder. + pub fn new(name: &'static str) -> Self { + Self { + name, + setup: Box::new(|_| Ok(())), + setup_with_config: None, + js_init_script: None, + invoke_handler: Box::new(|_| ()), + on_page_load: Box::new(|_, _| ()), + on_webview_ready: Box::new(|_| ()), + on_event: Box::new(|_, _| ()), + } + } + + /// Defines the JS message handler callback. + #[must_use] + pub fn invoke_handler(mut self, invoke_handler: F) -> Self + where + F: Fn(Invoke) + Send + Sync + 'static, + { + self.invoke_handler = Box::new(invoke_handler); + self + } + + /// The JS script to evaluate on webview initialization. + /// The script is wrapped into its own context with `(function () { /* your script here */ })();`, + /// so global variables must be assigned to `window` instead of implicity declared. + /// + /// It's guaranteed that this script is executed before the page is loaded. + #[must_use] + pub fn js_init_script(mut self, js_init_script: String) -> Self { + self.js_init_script = Some(js_init_script); + self + } + + /// Define a closure that runs when the app is built. + /// + /// This is a convenience function around [setup_with_config], without the need to specify a configuration object. + /// + /// The closure gets called before the [setup_with_config] closure. + /// + /// [setup_with_config]: struct.Builder.html#method.setup_with_config + #[must_use] + pub fn setup(mut self, setup: F) -> Self + where + F: Fn(&AppHandle) -> Result<()> + Send + Sync + 'static, + { + self.setup = Box::new(setup); + self + } + + /// Define a closure that runs when the app is built, accepting a configuration object set on `tauri.conf.json > plugins > yourPluginName`. + /// + /// If your plugin is not pulling a configuration object from `tauri.conf.json`, use [setup]. + /// + /// The closure gets called after the [setup] closure. + /// + /// # Example + /// + /// ```rust,no_run + /// #[derive(serde::Deserialize)] + /// struct Config { + /// api_url: String, + /// } + /// + /// fn get_plugin() -> tauri::plugin::TauriPlugin { + /// tauri::plugin::Builder::::new("api") + /// .setup_with_config(|_app, config| { + /// println!("config: {:?}", config.api_url); + /// Ok(()) + /// }) + /// .build() + /// } + /// + /// tauri::Builder::default().plugin(get_plugin()); + /// ``` + /// + /// [setup]: struct.Builder.html#method.setup + #[must_use] + pub fn setup_with_config(mut self, setup_with_config: F) -> Self + where + F: Fn(&AppHandle, C) -> Result<()> + Send + Sync + 'static, + { + self.setup_with_config.replace(Box::new(setup_with_config)); + self + } + + /// Callback invoked when the webview performs a navigation to a page. + #[must_use] + pub fn on_page_load(mut self, on_page_load: F) -> Self + where + F: Fn(Window, PageLoadPayload) + Send + Sync + 'static, + { + self.on_page_load = Box::new(on_page_load); + self + } + + /// Callback invoked when the webview is created. + #[must_use] + pub fn on_webview_ready(mut self, on_webview_ready: F) -> Self + where + F: Fn(Window) + Send + Sync + 'static, + { + self.on_webview_ready = Box::new(on_webview_ready); + self + } + + /// Callback invoked when the event loop receives a new event. + #[must_use] + pub fn on_event(mut self, on_event: F) -> Self + where + F: Fn(&AppHandle, &RunEvent) + Send + Sync + 'static, + { + self.on_event = Box::new(on_event); + self + } + + /// Builds the [TauriPlugin]. + pub fn build(self) -> TauriPlugin { + TauriPlugin { + name: self.name, + invoke_handler: self.invoke_handler, + setup: self.setup, + setup_with_config: self.setup_with_config, + js_init_script: self.js_init_script, + on_page_load: self.on_page_load, + on_webview_ready: self.on_webview_ready, + on_event: self.on_event, + } + } +} + +/// Plugin struct that is returned by the [`Builder`]. Should only be constructed through the builder. +pub struct TauriPlugin { + name: &'static str, + invoke_handler: Box>, + setup: Box>, + setup_with_config: Option>>, + js_init_script: Option, + on_page_load: Box>, + on_webview_ready: Box>, + on_event: Box>, +} + +impl Plugin for TauriPlugin { + fn name(&self) -> &'static str { + self.name + } + + fn initialize(&mut self, app: &AppHandle, config: JsonValue) -> Result<()> { + (self.setup)(app)?; + if let Some(s) = &self.setup_with_config { + (s)(app, serde_json::from_value(config)?)?; + } + Ok(()) + } + + fn initialization_script(&self) -> Option { + self.js_init_script.clone() + } + + fn created(&mut self, window: Window) { + (self.on_webview_ready)(window) + } + + fn on_page_load(&mut self, window: Window, payload: PageLoadPayload) { + (self.on_page_load)(window, payload) + } + + fn on_event(&mut self, app: &AppHandle, event: &RunEvent) { + (self.on_event)(app, event) + } + + fn extend_api(&mut self, invoke: Invoke) { + (self.invoke_handler)(invoke) + } +} + /// Plugin collection type. #[default_runtime(crate::Wry, wry)] pub(crate) struct PluginStore { @@ -121,6 +323,14 @@ impl PluginStore { .for_each(|plugin| plugin.on_page_load(window.clone(), payload.clone())) } + /// Runs the on_event hook for all plugins in the store. + pub(crate) fn on_event(&mut self, app: &AppHandle, event: &RunEvent) { + self + .store + .values_mut() + .for_each(|plugin| plugin.on_event(app, event)) + } + pub(crate) fn extend_api(&mut self, mut invoke: Invoke) { let command = invoke.message.command.replace("plugin:", ""); let mut tokens = command.split('|'); diff --git a/core/tauri/src/scope/fs.rs b/core/tauri/src/scope/fs.rs new file mode 100644 index 000000000000..9c9dffcb5323 --- /dev/null +++ b/core/tauri/src/scope/fs.rs @@ -0,0 +1,75 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::{fmt, path::Path}; + +use glob::Pattern; +use tauri_utils::{ + config::{Config, FsAllowlistScope}, + Env, PackageInfo, +}; + +use crate::api::path::parse as parse_path; + +/// Scope for filesystem access. +#[derive(Clone)] +pub struct Scope { + allow_patterns: Vec, +} + +impl fmt::Debug for Scope { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Scope") + .field( + "allow_patterns", + &self + .allow_patterns + .iter() + .map(|p| p.as_str()) + .collect::>(), + ) + .finish() + } +} + +impl Scope { + /// Creates a new scope from a `FsAllowlistScope` configuration. + pub fn for_fs_api( + config: &Config, + package_info: &PackageInfo, + env: &Env, + scope: &FsAllowlistScope, + ) -> Self { + let mut allow_patterns = Vec::new(); + for path in &scope.0 { + if let Ok(path) = parse_path(config, package_info, env, path) { + allow_patterns.push(Pattern::new(&path.to_string_lossy()).expect("invalid glob pattern")); + #[cfg(windows)] + { + allow_patterns.push( + Pattern::new(&format!("\\\\?\\{}", path.display())).expect("invalid glob pattern"), + ); + } + } + } + Self { allow_patterns } + } + + /// Determines if the given path is allowed on this scope. + pub fn is_allowed>(&self, path: P) -> bool { + let path = path.as_ref(); + let path = if !path.exists() { + crate::Result::Ok(path.to_path_buf()) + } else { + std::fs::canonicalize(path).map_err(Into::into) + }; + + if let Ok(path) = path { + let allowed = self.allow_patterns.iter().any(|p| p.matches_path(&path)); + allowed + } else { + false + } + } +} diff --git a/core/tauri/src/scope/http.rs b/core/tauri/src/scope/http.rs new file mode 100644 index 000000000000..a17849e4e2e5 --- /dev/null +++ b/core/tauri/src/scope/http.rs @@ -0,0 +1,77 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use tauri_utils::config::HttpAllowlistScope; +use url::Url; + +/// Scope for filesystem access. +#[derive(Debug, Clone)] +pub struct Scope { + allowed_urls: Vec, +} + +impl Scope { + /// Creates a new scope from the allowlist's `http` scope configuration. + pub fn for_http_api(scope: &HttpAllowlistScope) -> Self { + Self { + allowed_urls: scope.0.clone(), + } + } + + /// Determines if the given URL is allowed on this scope. + pub fn is_allowed(&self, url: &Url) -> bool { + self.allowed_urls.iter().any(|allowed| { + let origin_matches = allowed.scheme() == url.scheme() + && allowed.host() == url.host() + && allowed.port() == url.port(); + let allowed_path_pattern = glob::Pattern::new(allowed.path()) + .unwrap_or_else(|_| panic!("invalid glob pattern on URL `{}` path", allowed)); + origin_matches && allowed_path_pattern.matches(url.path()) + }) + } +} + +#[cfg(test)] +mod tests { + use tauri_utils::config::HttpAllowlistScope; + + #[test] + fn is_allowed() { + // plain URL + let scope = super::Scope::for_http_api(&HttpAllowlistScope(vec!["http://localhost:8080" + .parse() + .unwrap()])); + assert!(scope.is_allowed(&"http://localhost:8080".parse().unwrap())); + assert!(scope.is_allowed(&"http://localhost:8080/".parse().unwrap())); + + assert!(!scope.is_allowed(&"http://localhost:8080/file".parse().unwrap())); + assert!(!scope.is_allowed(&"http://localhost:8080/path/to/asset.png".parse().unwrap())); + assert!(!scope.is_allowed(&"https://localhost:8080".parse().unwrap())); + assert!(!scope.is_allowed(&"http://localhost:8081".parse().unwrap())); + assert!(!scope.is_allowed(&"http://local:8080".parse().unwrap())); + + // URL with fixed path + let scope = + super::Scope::for_http_api(&HttpAllowlistScope(vec!["http://localhost:8080/file.png" + .parse() + .unwrap()])); + + assert!(scope.is_allowed(&"http://localhost:8080/file.png".parse().unwrap())); + + assert!(!scope.is_allowed(&"http://localhost:8080".parse().unwrap())); + assert!(!scope.is_allowed(&"http://localhost:8080/file".parse().unwrap())); + assert!(!scope.is_allowed(&"http://localhost:8080/file.png/other.jpg".parse().unwrap())); + + // URL with glob pattern + let scope = + super::Scope::for_http_api(&HttpAllowlistScope(vec!["http://localhost:8080/*.png" + .parse() + .unwrap()])); + + assert!(scope.is_allowed(&"http://localhost:8080/file.png".parse().unwrap())); + assert!(scope.is_allowed(&"http://localhost:8080/assets/file.png".parse().unwrap())); + + assert!(!scope.is_allowed(&"http://localhost:8080/file.jpeg".parse().unwrap())); + } +} diff --git a/core/tauri/src/scope/mod.rs b/core/tauri/src/scope/mod.rs new file mode 100644 index 000000000000..65b9511b6fa4 --- /dev/null +++ b/core/tauri/src/scope/mod.rs @@ -0,0 +1,27 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +mod fs; +mod http; +#[cfg(shell_scope)] +mod shell; + +pub use self::http::Scope as HttpScope; +pub use fs::Scope as FsScope; +#[cfg(shell_scope)] +pub use shell::{ + ExecuteArgs, Scope as ShellScope, ScopeAllowedArg as ShellScopeAllowedArg, + ScopeAllowedCommand as ShellScopeAllowedCommand, ScopeConfig as ShellScopeConfig, + ScopeError as ShellScopeError, +}; + +pub(crate) struct Scopes { + pub fs: FsScope, + #[cfg(protocol_asset)] + pub asset_protocol: FsScope, + #[cfg(http_request)] + pub http: HttpScope, + #[cfg(shell_scope)] + pub shell: ShellScope, +} diff --git a/core/tauri/src/scope/shell.rs b/core/tauri/src/scope/shell.rs new file mode 100644 index 000000000000..c61848f06c20 --- /dev/null +++ b/core/tauri/src/scope/shell.rs @@ -0,0 +1,287 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +#[cfg(any(shell_execute, shell_sidecar))] +use crate::api::process::Command; +#[cfg(feature = "shell-open-api")] +use crate::api::shell::Program; + +use regex::Regex; + +use std::collections::HashMap; + +/// Allowed representation of `Execute` command arguments. +#[derive(Debug, Clone, serde::Deserialize)] +#[serde(untagged, deny_unknown_fields)] +#[non_exhaustive] +pub enum ExecuteArgs { + /// No arguments + None, + + /// A single string argument + Single(String), + + /// Multiple string arguments + List(Vec), +} + +impl ExecuteArgs { + /// Whether the argument list is empty or not. + pub fn is_empty(&self) -> bool { + match self { + Self::None => true, + Self::Single(s) if s.is_empty() => true, + Self::List(l) => l.is_empty(), + _ => false, + } + } +} + +impl From<()> for ExecuteArgs { + fn from(_: ()) -> Self { + Self::None + } +} + +impl From for ExecuteArgs { + fn from(string: String) -> Self { + Self::Single(string) + } +} + +impl From> for ExecuteArgs { + fn from(vec: Vec) -> Self { + Self::List(vec) + } +} + +/// Shell scope configuration. +#[derive(Debug, Clone)] +pub struct ScopeConfig { + /// The validation regex that `shell > open` paths must match against. + pub open: Option, + + /// All allowed commands, using their unique command name as the keys. + pub scopes: HashMap, +} + +/// A configured scoped shell command. +#[derive(Debug, Clone)] +pub struct ScopeAllowedCommand { + /// The shell command to be called. + pub command: std::path::PathBuf, + + /// The arguments the command is allowed to be called with. + pub args: Option>, + + /// If this command is a sidecar command. + pub sidecar: bool, +} + +/// A configured argument to a scoped shell command. +#[derive(Debug, Clone)] +pub enum ScopeAllowedArg { + /// A non-configurable argument. + Fixed(String), + + /// An argument with a value to be evaluated at runtime, must pass a regex validation. + Var { + /// The validation that the variable value must pass in order to be called. + validator: Regex, + }, +} + +impl ScopeAllowedArg { + /// If the argument is fixed. + pub fn is_fixed(&self) -> bool { + matches!(self, Self::Fixed(_)) + } + + /// If the argument is a variable value. + pub fn is_var(&self) -> bool { + matches!(self, Self::Var { .. }) + } +} + +/// Scope for filesystem access. +#[derive(Clone)] +pub struct Scope(ScopeConfig); + +/// All errors that can happen while validating a scoped command. +#[derive(Debug, thiserror::Error)] +pub enum ScopeError { + /// At least one argument did not pass input validation. + #[cfg(any(shell_execute, shell_sidecar))] + #[cfg_attr( + doc_cfg, + doc(cfg(any(feature = "shell-execute", feature = "shell-sidecar"))) + )] + #[error("The scoped command was called with the improper sidecar flag set")] + BadSidecarFlag, + + /// The sidecar program validated but failed to find the sidecar path. + /// + /// Note: This can be called on `shell-execute` feature too due to [`Scope::prepare`] checking if + /// it's a sidecar from the config. + #[cfg(any(shell_execute, shell_sidecar))] + #[cfg_attr( + doc_cfg, + doc(cfg(any(feature = "shell-execute", feature = "shell-sidecar"))) + )] + #[error( + "The scoped sidecar command was validated, but failed to create the path to the command: {0}" + )] + Sidecar(crate::Error), + + /// The named command was not found in the scoped config. + #[error("Scoped command {0} not found")] + #[cfg(any(shell_execute, shell_sidecar))] + #[cfg_attr( + doc_cfg, + doc(cfg(any(feature = "shell-execute", feature = "shell-sidecar"))) + )] + NotFound(String), + + /// A command variable has no value set in the arguments. + #[error( + "Scoped command argument at position {0} must match regex validation {1} but it was not found" + )] + #[cfg(any(shell_execute, shell_sidecar))] + #[cfg_attr( + doc_cfg, + doc(cfg(any(feature = "shell-execute", feature = "shell-sidecar"))) + )] + MissingVar(usize, String), + + /// At least one argument did not pass input validation. + #[cfg(shell_scope)] + #[cfg_attr( + doc_cfg, + doc(cfg(any(feature = "shell-execute", feature = "shell-open"))) + )] + #[error("Scoped command argument at position {index} was found, but failed regex validation {validation}")] + Validation { + /// Index of the variable. + index: usize, + + /// Regex that the variable value failed to match. + validation: String, + }, + + /// The format of the passed input does not match the expected shape. + /// + /// This can happen from passing a string or array of strings to a command that is expecting + /// named variables, and vice-versa. + #[cfg(any(shell_execute, shell_sidecar))] + #[cfg_attr( + doc_cfg, + doc(cfg(any(feature = "shell-execute", feature = "shell-sidecar"))) + )] + #[error("Scoped command {0} received arguments in an unexpected format")] + InvalidInput(String), + + /// A generic IO error that occurs while executing specified shell commands. + #[cfg(shell_scope)] + #[cfg_attr( + doc_cfg, + doc(cfg(any(feature = "shell-execute", feature = "shell-sidecar"))) + )] + #[error("Scoped shell IO error: {0}")] + Io(#[from] std::io::Error), +} + +impl Scope { + /// Creates a new shell scope. + pub fn new(scope: ScopeConfig) -> Self { + Self(scope) + } + + /// Validates argument inputs and creates a Tauri [`Command`]. + #[cfg(any(shell_execute, shell_sidecar))] + pub fn prepare( + &self, + command_name: &str, + args: ExecuteArgs, + sidecar: bool, + ) -> Result { + let command = match self.0.scopes.get(command_name) { + Some(command) => command, + None => return Err(ScopeError::NotFound(command_name.into())), + }; + + if command.sidecar != sidecar { + return Err(ScopeError::BadSidecarFlag); + } + + let args = match (&command.args, args) { + (None, ExecuteArgs::None) => Ok(vec![]), + (None, ExecuteArgs::List(list)) => Ok(list), + (None, ExecuteArgs::Single(string)) => Ok(vec![string]), + (Some(list), ExecuteArgs::List(args)) => list + .iter() + .enumerate() + .map(|(i, arg)| match arg { + ScopeAllowedArg::Fixed(fixed) => Ok(fixed.to_string()), + ScopeAllowedArg::Var { validator } => { + let value = args + .get(i) + .ok_or_else(|| ScopeError::MissingVar(i, validator.to_string()))? + .to_string(); + if validator.is_match(&value) { + Ok(value) + } else { + Err(ScopeError::Validation { + index: i, + validation: validator.to_string(), + }) + } + } + }) + .collect(), + (Some(list), arg) if arg.is_empty() && list.iter().all(ScopeAllowedArg::is_fixed) => list + .iter() + .map(|arg| match arg { + ScopeAllowedArg::Fixed(fixed) => Ok(fixed.to_string()), + _ => unreachable!(), + }) + .collect(), + (Some(list), _) if list.is_empty() => Err(ScopeError::InvalidInput(command_name.into())), + (Some(_), _) => Err(ScopeError::InvalidInput(command_name.into())), + }?; + + let command_s = command.command.to_string_lossy(); + let command = if command.sidecar { + Command::new_sidecar(command_s).map_err(ScopeError::Sidecar)? + } else { + Command::new(command_s) + }; + + Ok(command.args(args)) + } + + /// Open a path in the default (or specified) browser. + /// + /// The path is validated against the `tauri > allowlist > shell > open` validation regex, which + /// defaults to `^https?://`. + #[cfg(feature = "shell-open-api")] + pub fn open(&self, path: &str, with: Option) -> Result<(), ScopeError> { + // ensure we pass validation if the configuration has one + if let Some(regex) = &self.0.open { + if !regex.is_match(path) { + return Err(ScopeError::Validation { + index: 0, + validation: regex.as_str().into(), + }); + } + } + + // The prevention of argument escaping is handled by the usage of std::process::Command::arg by + // the `open` dependency. This behavior should be re-confirmed during upgrades of `open`. + match with.map(Program::name) { + Some(program) => ::open::with(&path, program), + None => ::open::that(&path), + } + .map_err(Into::into) + } +} diff --git a/core/tauri/src/settings.rs b/core/tauri/src/settings.rs index 82017e4c6ce1..f61b15e71aa5 100644 --- a/core/tauri/src/settings.rs +++ b/core/tauri/src/settings.rs @@ -11,7 +11,7 @@ use crate::{ file::read_binary, path::{resolve_path, BaseDirectory}, }, - Config, PackageInfo, + Config, Env, PackageInfo, }; use serde::{Deserialize, Serialize}; use std::{ @@ -30,10 +30,15 @@ pub struct Settings { } /// Gets the path to the settings file. -fn get_settings_path(config: &Config, package_info: &PackageInfo) -> crate::api::Result { +fn get_settings_path( + config: &Config, + package_info: &PackageInfo, + env: &Env, +) -> crate::api::Result { resolve_path( config, package_info, + env, ".tauri-settings", Some(BaseDirectory::App), ) @@ -44,9 +49,10 @@ fn get_settings_path(config: &Config, package_info: &PackageInfo) -> crate::api: pub(crate) fn write_settings( config: &Config, package_info: &PackageInfo, + env: &Env, settings: Settings, ) -> crate::Result<()> { - let settings_path = get_settings_path(config, package_info)?; + let settings_path = get_settings_path(config, package_info, env)?; let settings_folder = Path::new(&settings_path).parent().unwrap(); if !settings_folder.exists() { std::fs::create_dir(settings_folder)?; @@ -60,8 +66,8 @@ pub(crate) fn write_settings( } /// Reads the settings from the file system. -pub fn read_settings(config: &Config, package_info: &PackageInfo) -> Settings { - if let Ok(settings_path) = get_settings_path(config, package_info) { +pub fn read_settings(config: &Config, package_info: &PackageInfo, env: &Env) -> Settings { + if let Ok(settings_path) = get_settings_path(config, package_info, env) { if settings_path.exists() { read_binary(settings_path) .and_then(|settings| bincode::deserialize(&settings).map_err(Into::into)) diff --git a/core/tauri/src/state.rs b/core/tauri/src/state.rs index 44db4e953780..84d9894108a8 100644 --- a/core/tauri/src/state.rs +++ b/core/tauri/src/state.rs @@ -40,7 +40,12 @@ impl Clone for State<'_, T> { impl<'r, 'de: 'r, T: Send + Sync + 'static, R: Runtime> CommandArg<'de, R> for State<'r, T> { /// Grabs the [`State`] from the [`CommandItem`]. This will never fail. fn from_command(command: CommandItem<'de, R>) -> Result { - Ok(command.message.state_ref().get()) + Ok(command.message.state_ref().try_get().unwrap_or_else(|| { + panic!( + "state not managed for field `{}` on command `{}`. You muse call `.manage()` before using this command", + command.key, command.name + ) + })) } } @@ -59,7 +64,12 @@ impl StateManager { /// Gets the state associated with the specified type. pub fn get(&self) -> State<'_, T> { - State(self.0.get()) + State( + self + .0 + .try_get() + .expect("state: get() called before set() for given type"), + ) } /// Gets the state associated with the specified type. diff --git a/core/tauri/src/test/mock_runtime.rs b/core/tauri/src/test/mock_runtime.rs new file mode 100644 index 000000000000..a2e284926603 --- /dev/null +++ b/core/tauri/src/test/mock_runtime.rs @@ -0,0 +1,587 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +#![allow(dead_code)] + +use tauri_runtime::{ + menu::{Menu, MenuUpdate, SystemTrayMenu, TrayHandle}, + monitor::Monitor, + webview::{WindowBuilder, WindowBuilderBase}, + window::{ + dpi::{PhysicalPosition, PhysicalSize, Position, Size}, + DetachedWindow, MenuEvent, PendingWindow, WindowEvent, + }, + ClipboardManager, Dispatch, GlobalShortcutManager, Icon, Result, RunEvent, Runtime, + RuntimeHandle, UserAttentionType, +}; +#[cfg(feature = "system-tray")] +use tauri_runtime::{SystemTray, SystemTrayEvent}; +use tauri_utils::config::WindowConfig; +use uuid::Uuid; + +#[cfg(windows)] +use windows::Win32::Foundation::HWND; + +use std::{ + collections::HashMap, + fmt, + sync::{Arc, Mutex}, +}; + +type ShortcutMap = HashMap>; + +#[derive(Clone)] +pub struct RuntimeContext { + shortcuts: Arc>, + clipboard: Arc>>, +} + +impl fmt::Debug for RuntimeContext { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("RuntimeContext") + .field("clipboard", &self.clipboard) + .finish() + } +} + +#[derive(Debug, Clone)] +pub struct MockRuntimeHandle { + context: RuntimeContext, +} + +impl RuntimeHandle for MockRuntimeHandle { + type Runtime = MockRuntime; + /// Create a new webview window. + fn create_window( + &self, + pending: PendingWindow, + ) -> Result> { + Ok(DetachedWindow { + label: pending.label, + dispatcher: MockDispatcher { + context: self.context.clone(), + }, + menu_ids: Default::default(), + js_event_listeners: Default::default(), + }) + } + + /// Run a task on the main thread. + fn run_on_main_thread(&self, f: F) -> Result<()> { + unimplemented!() + } + + #[cfg(all(windows, feature = "system-tray"))] + #[cfg_attr(doc_cfg, doc(cfg(all(windows, feature = "system-tray"))))] + fn remove_system_tray(&self) -> Result<()> { + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct MockDispatcher { + context: RuntimeContext, +} + +#[derive(Debug, Clone)] +pub struct MockGlobalShortcutManager { + context: RuntimeContext, +} + +impl GlobalShortcutManager for MockGlobalShortcutManager { + fn is_registered(&self, accelerator: &str) -> Result { + Ok( + self + .context + .shortcuts + .lock() + .unwrap() + .contains_key(accelerator), + ) + } + + fn register(&mut self, accelerator: &str, handler: F) -> Result<()> { + self + .context + .shortcuts + .lock() + .unwrap() + .insert(accelerator.into(), Box::new(handler)); + Ok(()) + } + + fn unregister_all(&mut self) -> Result<()> { + *self.context.shortcuts.lock().unwrap() = Default::default(); + Ok(()) + } + + fn unregister(&mut self, accelerator: &str) -> Result<()> { + self.context.shortcuts.lock().unwrap().remove(accelerator); + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct MockClipboardManager { + context: RuntimeContext, +} + +impl ClipboardManager for MockClipboardManager { + fn write_text>(&mut self, text: T) -> Result<()> { + self.context.clipboard.lock().unwrap().replace(text.into()); + Ok(()) + } + + fn read_text(&self) -> Result> { + Ok(self.context.clipboard.lock().unwrap().clone()) + } +} + +#[derive(Debug, Clone)] +pub struct MockWindowBuilder {} + +impl WindowBuilderBase for MockWindowBuilder {} + +impl WindowBuilder for MockWindowBuilder { + fn new() -> Self { + Self {} + } + + fn with_config(config: WindowConfig) -> Self { + Self {} + } + + fn menu(self, menu: Menu) -> Self { + self + } + + fn center(self) -> Self { + self + } + + fn position(self, x: f64, y: f64) -> Self { + self + } + + fn inner_size(self, min_width: f64, min_height: f64) -> Self { + self + } + + fn min_inner_size(self, min_width: f64, min_height: f64) -> Self { + self + } + + fn max_inner_size(self, max_width: f64, max_height: f64) -> Self { + self + } + + fn resizable(self, resizable: bool) -> Self { + self + } + + fn title>(self, title: S) -> Self { + self + } + + fn fullscreen(self, fullscreen: bool) -> Self { + self + } + + fn focus(self) -> Self { + self + } + + fn maximized(self, maximized: bool) -> Self { + self + } + + fn visible(self, visible: bool) -> Self { + self + } + + #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] + #[cfg_attr( + doc_cfg, + doc(cfg(any(not(target_os = "macos"), feature = "macos-private-api"))) + )] + fn transparent(self, transparent: bool) -> Self { + self + } + + fn decorations(self, decorations: bool) -> Self { + self + } + + fn always_on_top(self, always_on_top: bool) -> Self { + self + } + + fn icon(self, icon: Icon) -> Result { + Ok(self) + } + + fn skip_taskbar(self, skip: bool) -> Self { + self + } + + #[cfg(windows)] + fn parent_window(self, parent: HWND) -> Self { + self + } + + #[cfg(windows)] + fn owner_window(self, owner: HWND) -> Self { + self + } + + fn has_icon(&self) -> bool { + false + } + + fn get_menu(&self) -> Option<&Menu> { + None + } +} + +impl Dispatch for MockDispatcher { + type Runtime = MockRuntime; + + type WindowBuilder = MockWindowBuilder; + + fn run_on_main_thread(&self, f: F) -> Result<()> { + Ok(()) + } + + fn on_window_event(&self, f: F) -> Uuid { + Uuid::new_v4() + } + + fn on_menu_event(&self, f: F) -> Uuid { + Uuid::new_v4() + } + + #[cfg(any(debug_assertions, feature = "devtools"))] + fn open_devtools(&self) {} + + fn scale_factor(&self) -> Result { + Ok(1.0) + } + + fn inner_position(&self) -> Result> { + Ok(PhysicalPosition { x: 0, y: 0 }) + } + + fn outer_position(&self) -> Result> { + Ok(PhysicalPosition { x: 0, y: 0 }) + } + + fn inner_size(&self) -> Result> { + Ok(PhysicalSize { + width: 0, + height: 0, + }) + } + + fn outer_size(&self) -> Result> { + Ok(PhysicalSize { + width: 0, + height: 0, + }) + } + + fn is_fullscreen(&self) -> Result { + Ok(false) + } + + fn is_maximized(&self) -> Result { + Ok(false) + } + + fn is_decorated(&self) -> Result { + Ok(false) + } + + fn is_resizable(&self) -> Result { + Ok(false) + } + + fn is_visible(&self) -> Result { + Ok(true) + } + + fn is_menu_visible(&self) -> Result { + Ok(true) + } + + fn current_monitor(&self) -> Result> { + Ok(None) + } + + fn primary_monitor(&self) -> Result> { + Ok(None) + } + + fn available_monitors(&self) -> Result> { + Ok(Vec::new()) + } + + #[cfg(windows)] + fn hwnd(&self) -> Result { + unimplemented!() + } + + #[cfg(target_os = "macos")] + fn ns_window(&self) -> Result<*mut std::ffi::c_void> { + unimplemented!() + } + + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + ))] + fn gtk_window(&self) -> Result { + unimplemented!() + } + + fn center(&self) -> Result<()> { + Ok(()) + } + + fn print(&self) -> Result<()> { + Ok(()) + } + + fn request_user_attention(&self, request_type: Option) -> Result<()> { + Ok(()) + } + + fn create_window( + &mut self, + pending: PendingWindow, + ) -> Result> { + unimplemented!() + } + + fn set_resizable(&self, resizable: bool) -> Result<()> { + Ok(()) + } + + fn set_title>(&self, title: S) -> Result<()> { + Ok(()) + } + + fn maximize(&self) -> Result<()> { + Ok(()) + } + + fn unmaximize(&self) -> Result<()> { + Ok(()) + } + + fn minimize(&self) -> Result<()> { + Ok(()) + } + + fn unminimize(&self) -> Result<()> { + Ok(()) + } + + fn show_menu(&self) -> Result<()> { + Ok(()) + } + + fn hide_menu(&self) -> Result<()> { + Ok(()) + } + + fn show(&self) -> Result<()> { + Ok(()) + } + + fn hide(&self) -> Result<()> { + Ok(()) + } + + fn close(&self) -> Result<()> { + Ok(()) + } + + fn set_decorations(&self, decorations: bool) -> Result<()> { + Ok(()) + } + + fn set_always_on_top(&self, always_on_top: bool) -> Result<()> { + Ok(()) + } + + fn set_size(&self, size: Size) -> Result<()> { + Ok(()) + } + + fn set_min_size(&self, size: Option) -> Result<()> { + Ok(()) + } + + fn set_max_size(&self, size: Option) -> Result<()> { + Ok(()) + } + + fn set_position(&self, position: Position) -> Result<()> { + Ok(()) + } + + fn set_fullscreen(&self, fullscreen: bool) -> Result<()> { + Ok(()) + } + + fn set_focus(&self) -> Result<()> { + Ok(()) + } + + fn set_icon(&self, icon: Icon) -> Result<()> { + Ok(()) + } + + fn set_skip_taskbar(&self, skip: bool) -> Result<()> { + Ok(()) + } + + fn start_dragging(&self) -> Result<()> { + Ok(()) + } + + fn eval_script>(&self, script: S) -> Result<()> { + Ok(()) + } + + fn update_menu_item(&self, id: u16, update: MenuUpdate) -> Result<()> { + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct MockTrayHandler { + context: RuntimeContext, +} + +impl TrayHandle for MockTrayHandler { + fn set_icon(&self, icon: Icon) -> Result<()> { + Ok(()) + } + fn set_menu(&self, menu: SystemTrayMenu) -> Result<()> { + Ok(()) + } + fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> { + Ok(()) + } + #[cfg(target_os = "macos")] + fn set_icon_as_template(&self, is_template: bool) -> Result<()> { + Ok(()) + } +} + +pub struct MockRuntime { + pub context: RuntimeContext, + global_shortcut_manager: MockGlobalShortcutManager, + clipboard_manager: MockClipboardManager, + #[cfg(feature = "system-tray")] + tray_handler: MockTrayHandler, +} + +impl MockRuntime { + fn init() -> Self { + let context = RuntimeContext { + shortcuts: Default::default(), + clipboard: Default::default(), + }; + Self { + global_shortcut_manager: MockGlobalShortcutManager { + context: context.clone(), + }, + clipboard_manager: MockClipboardManager { + context: context.clone(), + }, + #[cfg(feature = "system-tray")] + tray_handler: MockTrayHandler { + context: context.clone(), + }, + context, + } + } +} + +impl Runtime for MockRuntime { + type Dispatcher = MockDispatcher; + type Handle = MockRuntimeHandle; + type GlobalShortcutManager = MockGlobalShortcutManager; + type ClipboardManager = MockClipboardManager; + #[cfg(feature = "system-tray")] + type TrayHandler = MockTrayHandler; + + fn new() -> Result { + Ok(Self::init()) + } + + #[cfg(any(windows, target_os = "linux"))] + fn new_any_thread() -> Result { + Ok(Self::init()) + } + + fn handle(&self) -> Self::Handle { + MockRuntimeHandle { + context: self.context.clone(), + } + } + + fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager { + self.global_shortcut_manager.clone() + } + + fn clipboard_manager(&self) -> Self::ClipboardManager { + self.clipboard_manager.clone() + } + + fn create_window(&self, pending: PendingWindow) -> Result> { + Ok(DetachedWindow { + label: pending.label, + dispatcher: MockDispatcher { + context: self.context.clone(), + }, + menu_ids: Default::default(), + js_event_listeners: Default::default(), + }) + } + + #[cfg(feature = "system-tray")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))] + fn system_tray(&self, system_tray: SystemTray) -> Result { + Ok(self.tray_handler.clone()) + } + + #[cfg(feature = "system-tray")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))] + fn on_system_tray_event(&mut self, f: F) -> Uuid { + Uuid::new_v4() + } + + #[cfg(target_os = "macos")] + #[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))] + fn set_activation_policy(&mut self, activation_policy: tauri_runtime::ActivationPolicy) {} + + fn run_iteration( + &mut self, + callback: F, + ) -> tauri_runtime::RunIteration { + Default::default() + } + + fn run(self, callback: F) { + loop { + std::thread::sleep(std::time::Duration::from_secs(1)); + } + } +} diff --git a/core/tauri/src/test/mod.rs b/core/tauri/src/test/mod.rs new file mode 100644 index 000000000000..7f95994bf1ab --- /dev/null +++ b/core/tauri/src/test/mod.rs @@ -0,0 +1,99 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +#![allow(unused_variables)] + +mod mock_runtime; +pub use mock_runtime::*; + +#[cfg(shell_scope)] +use std::collections::HashMap; +use std::{borrow::Cow, sync::Arc}; + +#[cfg(shell_scope)] +use crate::ShellScopeConfig; +use crate::{Manager, Pattern}; +use tauri_utils::{ + assets::{AssetKey, Assets, CspHash}, + config::{CliConfig, Config, PatternKind, TauriConfig}, +}; + +pub struct NoopAsset { + csp_hashes: Vec>, +} + +impl Assets for NoopAsset { + fn get(&self, key: &AssetKey) -> Option> { + None + } + + fn csp_hashes(&self, html_path: &AssetKey) -> Box> + '_> { + Box::new(self.csp_hashes.iter().copied()) + } +} + +pub fn noop_assets() -> NoopAsset { + NoopAsset { + csp_hashes: Default::default(), + } +} + +pub fn mock_context(assets: A) -> crate::Context { + crate::Context { + config: Config { + package: Default::default(), + tauri: TauriConfig { + pattern: PatternKind::Brownfield, + windows: vec![Default::default()], + cli: Some(CliConfig { + description: None, + long_description: None, + before_help: None, + after_help: None, + args: None, + subcommands: None, + }), + bundle: Default::default(), + allowlist: Default::default(), + security: Default::default(), + updater: Default::default(), + system_tray: None, + macos_private_api: false, + }, + build: Default::default(), + plugins: Default::default(), + }, + assets: Arc::new(assets), + default_window_icon: None, + system_tray_icon: None, + package_info: crate::PackageInfo { + name: "test".into(), + version: "0.1.0".into(), + authors: "Tauri", + description: "Tauri test", + }, + _info_plist: (), + pattern: Pattern::Brownfield(std::marker::PhantomData), + #[cfg(shell_scope)] + shell_scope: ShellScopeConfig { + open: None, + scopes: HashMap::new(), + }, + } +} + +pub fn mock_app() -> crate::App { + crate::Builder::::new() + .build(mock_context(noop_assets())) + .unwrap() +} + +pub(crate) fn mock_invoke_context() -> crate::endpoints::InvokeContext { + let app = mock_app(); + crate::endpoints::InvokeContext { + window: app.get_window("main").unwrap(), + config: app.config(), + package_info: app.package_info().clone(), + } +} diff --git a/core/tauri/src/updater/core.rs b/core/tauri/src/updater/core.rs index 9202fdf7e802..69c7da8ef0fb 100644 --- a/core/tauri/src/updater/core.rs +++ b/core/tauri/src/updater/core.rs @@ -3,33 +3,35 @@ // SPDX-License-Identifier: MIT use super::error::{Error, Result}; -use crate::api::{file::Extract, version}; +use crate::api::{ + file::{ArchiveFormat, Extract, Move}, + http::{ClientBuilder, HttpRequestBuilder}, + version, +}; use base64::decode; use http::StatusCode; use minisign_verify::{PublicKey, Signature}; +use tauri_utils::{platform::current_exe, Env}; + use std::{ collections::HashMap, env, - ffi::OsStr, - fs::{read_dir, remove_file, File, OpenOptions}, - io::{prelude::*, BufReader, Read}, + io::{Cursor, Read, Seek}, path::{Path, PathBuf}, str::from_utf8, - time::{SystemTime, UNIX_EPOCH}, }; -#[cfg(target_os = "macos")] -use std::fs::rename; #[cfg(not(target_os = "macos"))] -use std::process::Command; +use std::ffi::OsStr; -#[cfg(target_os = "macos")] -use crate::api::file::Move; - -use crate::api::http::{ClientBuilder, HttpRequestBuilder}; +#[cfg(not(target_os = "windows"))] +use crate::api::file::Compression; #[cfg(target_os = "windows")] -use std::process::exit; +use std::{ + fs::read_dir, + process::{exit, Command}, +}; #[derive(Debug)] pub struct RemoteRelease { @@ -171,6 +173,8 @@ impl RemoteRelease { #[derive(Debug)] pub struct UpdateBuilder<'a> { + /// Environment information. + pub env: Env, /// Current version we are running to compare with announced version pub current_version: &'a str, /// The URLs to checks updates. We suggest at least one fallback on a different domain. @@ -181,22 +185,17 @@ pub struct UpdateBuilder<'a> { pub executable_path: Option, } -impl<'a> Default for UpdateBuilder<'a> { - fn default() -> Self { +// Create new updater instance and return an Update +impl<'a> UpdateBuilder<'a> { + pub fn new(env: Env) -> Self { UpdateBuilder { + env, urls: Vec::new(), target: None, executable_path: None, current_version: env!("CARGO_PKG_VERSION"), } } -} - -// Create new updater instance and return an Update -impl<'a> UpdateBuilder<'a> { - pub fn new() -> Self { - UpdateBuilder::default() - } #[allow(dead_code)] pub fn url(mut self, url: String) -> Self { @@ -249,25 +248,18 @@ impl<'a> UpdateBuilder<'a> { // set current version if not set let current_version = self.current_version; - // If no executable path provided, we use current_exe from rust - let executable_path = if let Some(v) = &self.executable_path { - v.clone() - } else { - // we expect it to fail if we can't find the executable path - // without this path we can't continue the update process. - env::current_exe()? - }; + // If no executable path provided, we use current_exe from tauri_utils + let executable_path = self.executable_path.unwrap_or(current_exe()?); // Did the target is provided by the config? // Should be: linux, darwin, win32 or win64 - let target = if let Some(t) = &self.target { - t.clone() - } else { - get_updater_target().ok_or(Error::UnsupportedPlatform)? - }; + let target = self + .target + .or_else(get_updater_target) + .ok_or(Error::UnsupportedPlatform)?; // Get the extract_path from the provided executable_path - let extract_path = extract_path_from_executable(&executable_path); + let extract_path = extract_path_from_executable(&self.env, &executable_path); // Set SSL certs for linux if they aren't available. // We do not require to recheck in the download_and_install as we use @@ -305,7 +297,7 @@ impl<'a> UpdateBuilder<'a> { let resp = ClientBuilder::new() .build()? .send( - HttpRequestBuilder::new("GET", &fixed_link) + HttpRequestBuilder::new("GET", &fixed_link)? .headers(headers) // wait 20sec for the firewall .timeout(20), @@ -317,7 +309,10 @@ impl<'a> UpdateBuilder<'a> { if let Ok(res) = resp { let res = res.read().await?; // got status code 2XX - if StatusCode::from_u16(res.status).unwrap().is_success() { + if StatusCode::from_u16(res.status) + .map_err(|e| Error::Builder(e.to_string()))? + .is_success() + { // if we got 204 if StatusCode::NO_CONTENT.as_u16() == res.status { // return with `UpToDate` error @@ -357,6 +352,7 @@ impl<'a> UpdateBuilder<'a> { // create our new updater Ok(Update { + env: self.env, target, extract_path, should_update, @@ -372,12 +368,14 @@ impl<'a> UpdateBuilder<'a> { } } -pub fn builder<'a>() -> UpdateBuilder<'a> { - UpdateBuilder::new() +pub fn builder<'a>(env: Env) -> UpdateBuilder<'a> { + UpdateBuilder::new(env) } #[derive(Debug, Clone)] pub struct Update { + /// Environment information. + pub env: Env, /// Update description pub body: Option, /// Should we update or not @@ -389,6 +387,7 @@ pub struct Update { /// Update publish date pub date: String, /// Target + #[allow(dead_code)] target: String, /// Extract path extract_path: PathBuf, @@ -405,11 +404,11 @@ pub struct Update { impl Update { // Download and install our update // @todo(lemarier): Split into download and install (two step) but need to be thread safe - pub async fn download_and_install(&self, pub_key: Option) -> Result { + pub async fn download_and_install(&self, pub_key: String) -> Result { // download url for selected release - let url = self.download_url.clone(); + let url = self.download_url.as_str(); // extract path - let extract_path = self.extract_path.clone(); + let extract_path = &self.extract_path; // make sure we can install the update on linux // We fail here because later we can add more linux support @@ -417,35 +416,10 @@ impl Update { // be set with our APPIMAGE env variable, we don't need to do // anythin with it yet #[cfg(target_os = "linux")] - if env::var_os("APPIMAGE").is_none() { + if self.env.appimage.is_none() { return Err(Error::UnsupportedPlatform); } - // used for temp file name - // if we cant extract app name, we use unix epoch duration - let current_time = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Unable to get Unix Epoch") - .subsec_nanos() - .to_string(); - - // get the current app name - let bin_name = std::env::current_exe() - .ok() - .and_then(|pb| pb.file_name().map(|s| s.to_os_string())) - .and_then(|s| s.into_string().ok()) - .unwrap_or_else(|| current_time.clone()); - - // tmp dir for extraction - let tmp_dir = tempfile::Builder::new() - .prefix(&format!("{}_{}_download", bin_name, current_time)) - .tempdir()?; - - // tmp directories are used to create backup of current application - // if something goes wrong, we can restore to previous state - let tmp_archive_path = tmp_dir.path().join(detect_archive_in_url(&url)); - let mut tmp_archive = File::create(&tmp_archive_path)?; - // set our headers let mut headers = HashMap::new(); headers.insert("Accept".into(), "application/octet-stream".into()); @@ -455,7 +429,7 @@ impl Update { let resp = ClientBuilder::new() .build()? .send( - HttpRequestBuilder::new("GET", &url) + HttpRequestBuilder::new("GET", url)? .headers(headers) // wait 20sec for the firewall .timeout(20), @@ -465,39 +439,37 @@ impl Update { .await?; // make sure it's success - if !StatusCode::from_u16(resp.status).unwrap().is_success() { + if !StatusCode::from_u16(resp.status) + .map_err(|e| Error::Network(e.to_string()))? + .is_success() + { return Err(Error::Network(format!( "Download request failed with status: {}", resp.status ))); } - tmp_archive.write_all(&resp.data)?; - - // Validate signature ONLY if pubkey is available in tauri.conf.json - if let Some(pub_key) = pub_key { - // We need an announced signature by the server - // if there is no signature, bail out. - if let Some(signature) = self.signature.clone() { - // we make sure the archive is valid and signed with the private key linked with the publickey - verify_signature(&tmp_archive_path, signature, &pub_key)?; - } else { - // We have a public key inside our source file, but not announced by the server, - // we assume this update is NOT valid. - return Err(Error::PubkeyButNoSignature); - } + // create memory buffer from our archive (Seek + Read) + let mut archive_buffer = Cursor::new(resp.data); + + // We need an announced signature by the server + // if there is no signature, bail out. + if let Some(signature) = &self.signature { + // we make sure the archive is valid and signed with the private key linked with the publickey + verify_signature(&mut archive_buffer, signature, &pub_key)?; + } else { + // We have a public key inside our source file, but not announced by the server, + // we assume this update is NOT valid. + return Err(Error::MissingUpdaterSignature); } - // extract using tauri api inside a tmp path - Extract::from_source(&tmp_archive_path).extract_into(tmp_dir.path())?; - // Remove archive (not needed anymore) - remove_file(&tmp_archive_path)?; + // we copy the files depending of the operating system // we run the setup, appimage re-install or overwrite the // macos .app #[cfg(target_os = "windows")] - copy_files_and_run(tmp_dir, extract_path, self.with_elevated_task)?; + copy_files_and_run(archive_buffer, extract_path, self.with_elevated_task)?; #[cfg(not(target_os = "windows"))] - copy_files_and_run(tmp_dir, extract_path)?; + copy_files_and_run(archive_buffer, extract_path)?; // We are done! Ok(()) } @@ -514,25 +486,28 @@ impl Update { // the extract_path is the current AppImage path // tmp_dir is where our new AppImage is found #[cfg(target_os = "linux")] -fn copy_files_and_run(tmp_dir: tempfile::TempDir, extract_path: PathBuf) -> Result { - // we delete our current AppImage (we'll create a new one later) - remove_file(&extract_path)?; - - // In our tempdir we expect 1 directory (should be the .app) - let paths = read_dir(&tmp_dir)?; - - for path in paths { - let found_path = path?.path(); - // make sure it's our .AppImage - if found_path.extension() == Some(OsStr::new("AppImage")) { - // Simply overwrite our AppImage (we use the command) - // because it prevent failing of bytes stream - Command::new("mv") - .arg("-f") - .arg(&found_path) - .arg(&extract_path) - .status()?; - +fn copy_files_and_run(archive_buffer: R, extract_path: &Path) -> Result { + let tmp_dir = tempfile::Builder::new() + .prefix("tauri_current_app") + .tempdir()?; + + let tmp_app_image = &tmp_dir.path().join("current_app.AppImage"); + + // create a backup of our current app image + Move::from_source(extract_path).to_dest(tmp_app_image)?; + + // extract the buffer to the tmp_dir + // we extract our signed archive into our final directory without any temp file + let mut extractor = + Extract::from_cursor(archive_buffer, ArchiveFormat::Tar(Some(Compression::Gz))); + + for file in extractor.files()? { + if file.extension() == Some(OsStr::new("AppImage")) { + // if something went wrong during the extraction, we should restore previous app + if let Err(err) = extractor.extract_file(extract_path, &file) { + Move::from_source(tmp_app_image).to_dest(extract_path)?; + return Err(Error::Extract(err.to_string())); + } // early finish we have everything we need here return Ok(()); } @@ -557,17 +532,31 @@ fn copy_files_and_run(tmp_dir: tempfile::TempDir, extract_path: PathBuf) -> Resu // Update server can provide a custom EXE (installer) who can run any task. #[cfg(target_os = "windows")] #[allow(clippy::unnecessary_wraps)] -fn copy_files_and_run( - tmp_dir: tempfile::TempDir, - _extract_path: PathBuf, +fn copy_files_and_run( + archive_buffer: R, + _extract_path: &Path, with_elevated_task: bool, ) -> Result { - use crate::api::file::Move; + // FIXME: We need to create a memory buffer with the MSI and then run it. + // (instead of extracting the MSI to a temp path) + // + // The tricky part is the MSI need to be exposed and spawned so the memory allocation + // shouldn't drop but we should be able to pass the reference so we can drop it once the installation + // is done, otherwise we have a huge memory leak. + + let tmp_dir = tempfile::Builder::new().tempdir()?.into_path(); + + // extract the buffer to the tmp_dir + // we extract our signed archive into our final directory without any temp file + let mut extractor = Extract::from_cursor(archive_buffer, ArchiveFormat::Zip); + + // extract the msi + extractor.extract_into(&tmp_dir)?; let paths = read_dir(&tmp_dir)?; // This consumes the TempDir without deleting directory on the filesystem, // meaning that the directory will no longer be automatically deleted. - let tmp_path = tmp_dir.into_path(); + for path in paths { let found_path = path?.path(); // we support 2 type of files exe & msi for now @@ -581,7 +570,7 @@ fn copy_files_and_run( exit(0); } else if found_path.extension() == Some(OsStr::new("msi")) { if with_elevated_task { - if let Some(bin_name) = std::env::current_exe() + if let Some(bin_name) = current_exe() .ok() .and_then(|pb| pb.file_name().map(|s| s.to_os_string())) .and_then(|s| s.into_string().ok()) @@ -598,7 +587,7 @@ fn copy_files_and_run( { if status.success() { // Rename the MSI to the match file name the Skip UAC task is expecting it to be - let temp_msi = tmp_path.with_file_name(bin_name).with_extension("msi"); + let temp_msi = tmp_dir.with_file_name(bin_name).with_extension("msi"); Move::from_source(&found_path) .to_dest(&temp_msi) .expect("Unable to move update MSI"); @@ -635,17 +624,6 @@ fn copy_files_and_run( Ok(()) } -// Get the current app name in the path -// Example; `/Applications/updater-example.app/Contents/MacOS/updater-example` -// Should return; `updater-example.app` -#[cfg(target_os = "macos")] -fn macos_app_name_in_path(extract_path: &Path) -> String { - let components = extract_path.components(); - let app_name = components.last().unwrap(); - let app_name = app_name.as_os_str().to_str().unwrap(); - app_name.to_string() -} - // MacOS // ### Expected structure: // ├── [AppName]_[version]_x64.app.tar.gz # GZ generated by tauri-bundler @@ -654,41 +632,44 @@ fn macos_app_name_in_path(extract_path: &Path) -> String { // │ └── ... // └── ... #[cfg(target_os = "macos")] -fn copy_files_and_run(tmp_dir: tempfile::TempDir, extract_path: PathBuf) -> Result { - // In our tempdir we expect 1 directory (should be the .app) - let paths = read_dir(&tmp_dir)?; - - // current app name in /Applications/.app - let app_name = macos_app_name_in_path(&extract_path); - - for path in paths { - let mut found_path = path?.path(); - // make sure it's our .app - if found_path.extension() == Some(OsStr::new("app")) { - let found_app_name = macos_app_name_in_path(&found_path); - // make sure the app name in the archive matche the installed app name on path - if found_app_name != app_name { - // we need to replace the app name in the updater archive to match - // installed app name - let new_path = found_path.parent().unwrap().join(app_name); - rename(&found_path, &new_path)?; - - found_path = new_path; +fn copy_files_and_run(archive_buffer: R, extract_path: &Path) -> Result { + let mut extracted_files: Vec = Vec::new(); + + // extract the buffer to the tmp_dir + // we extract our signed archive into our final directory without any temp file + let mut extractor = + Extract::from_cursor(archive_buffer, ArchiveFormat::Tar(Some(Compression::Gz))); + // the first file in the tar.gz will always be + // /Contents + let all_files = extractor.files()?; + let tmp_dir = tempfile::Builder::new() + .prefix("tauri_current_app") + .tempdir()?; + + // create backup of our current app + Move::from_source(extract_path).to_dest(tmp_dir.path())?; + + // extract all the files + for file in all_files { + // skip the first folder (should be the app name) + let collected_path: PathBuf = file.iter().skip(1).collect(); + let extraction_path = extract_path.join(collected_path); + + // if something went wrong during the extraction, we should restore previous app + if let Err(err) = extractor.extract_file(&extraction_path, &file) { + for file in extracted_files { + // delete all the files we extracted + if file.is_dir() { + std::fs::remove_dir(file)?; + } else { + std::fs::remove_file(file)?; + } } - - let sandbox_app_path = tempfile::Builder::new() - .prefix("tauri_current_app_sandbox") - .tempdir()?; - - // Replace the whole application to make sure the - // code signature is following - Move::from_source(&found_path) - .replace_using_temp(sandbox_app_path.path()) - .to_dest(&extract_path)?; - - // early finish we have everything we need here - return Ok(()); + Move::from_source(tmp_dir.path()).to_dest(extract_path)?; + return Err(Error::Extract(err.to_string())); } + + extracted_files.push(extraction_path); } Ok(()) @@ -717,7 +698,8 @@ pub fn get_updater_target() -> Option { } /// Get the extract_path from the provided executable_path -pub fn extract_path_from_executable(executable_path: &Path) -> PathBuf { +#[allow(unused_variables)] +pub fn extract_path_from_executable(env: &Env, executable_path: &Path) -> PathBuf { // Return the path of the current executable by default // Example C:\Program Files\My App\ let extract_path = executable_path @@ -747,40 +729,16 @@ pub fn extract_path_from_executable(executable_path: &Path) -> PathBuf { // We should use APPIMAGE exposed env variable // This is where our APPIMAGE should sit and should be replaced #[cfg(target_os = "linux")] - if let Some(app_image_path) = env::var_os("APPIMAGE") { + if let Some(app_image_path) = &env.appimage { return PathBuf::from(app_image_path); } extract_path } -// Return the archive type to save on disk -fn detect_archive_in_url(path: &str) -> String { - path - .split('/') - .next_back() - .unwrap_or(&default_archive_name_by_os()) - .to_string() -} - -// Fallback archive name by os -// The main objective is to provide the right extension based on the target -// if we cant extract the archive type in the url we'll fallback to this value -fn default_archive_name_by_os() -> String { - #[cfg(target_os = "windows")] - { - "update.zip".into() - } - - #[cfg(not(target_os = "windows"))] - { - "update.tar.gz".into() - } -} - // Convert base64 to string and prevent failing fn base64_to_string(base64_string: &str) -> Result { - let decoded_string = &decode(base64_string.to_owned())?; + let decoded_string = &decode(base64_string)?; let result = from_utf8(decoded_string)?.to_string(); Ok(result) } @@ -788,29 +746,28 @@ fn base64_to_string(base64_string: &str) -> Result { // Validate signature // need to be public because its been used // by our tests in the bundler -pub fn verify_signature( - archive_path: &Path, - release_signature: String, +// +// NOTE: The buffer position is not reset. +pub fn verify_signature( + archive_reader: &mut R, + release_signature: &str, pub_key: &str, -) -> Result { +) -> Result +where + R: Read, +{ // we need to convert the pub key - let pub_key_decoded = &base64_to_string(pub_key)?; - let public_key = PublicKey::decode(pub_key_decoded)?; - let signature_base64_decoded = base64_to_string(&release_signature)?; - + let pub_key_decoded = base64_to_string(pub_key)?; + let public_key = PublicKey::decode(&pub_key_decoded)?; + let signature_base64_decoded = base64_to_string(release_signature)?; let signature = Signature::decode(&signature_base64_decoded)?; - // We need to open the file and extract the datas to make sure its not corrupted - let file_open = OpenOptions::new().read(true).open(&archive_path)?; - - let mut file_buff: BufReader = BufReader::new(file_open); - - // read all bytes since EOF in the buffer - let mut data = vec![]; - file_buff.read_to_end(&mut data)?; + // read all bytes until EOF in the buffer + let mut data = Vec::new(); + archive_reader.read_to_end(&mut data)?; // Validate signature or bail out - public_key.verify(&data, &signature)?; + public_key.verify(&data, &signature, true)?; Ok(true) } @@ -818,11 +775,7 @@ pub fn verify_signature( mod test { use super::*; #[cfg(target_os = "macos")] - use std::env::current_exe; - #[cfg(target_os = "macos")] use std::fs::File; - #[cfg(target_os = "macos")] - use std::path::Path; macro_rules! block { ($e:expr) => { @@ -901,17 +854,6 @@ mod test { }"#.into() } - #[cfg(target_os = "macos")] - #[test] - fn test_app_name_in_path() { - let executable = extract_path_from_executable(Path::new( - "/Applications/updater-example.app/Contents/MacOS/updater-example", - )); - let app_name = macos_app_name_in_path(&executable); - assert!(executable.ends_with("updater-example.app")); - assert_eq!(app_name, "updater-example.app".to_string()); - } - #[test] fn simple_http_updater() { let _m = mockito::mock("GET", "/") @@ -920,7 +862,7 @@ mod test { .with_body(generate_sample_raw_json()) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .current_version("0.0.0") .url(mockito::server_url()) .build()); @@ -939,7 +881,7 @@ mod test { .with_body(generate_sample_raw_json()) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .current_version("0.0.0") .url(mockito::server_url()) .build()); @@ -958,7 +900,7 @@ mod test { .with_body(generate_sample_raw_json()) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .current_version("0.0.0") .target("win64") .url(mockito::server_url()) @@ -984,7 +926,7 @@ mod test { .with_body(generate_sample_raw_json()) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .current_version("10.0.0") .url(mockito::server_url()) .build()); @@ -1007,7 +949,7 @@ mod test { )) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .current_version("1.0.0") .url(format!( "{}/darwin/{{{{current_version}}}}", @@ -1034,7 +976,7 @@ mod test { )) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .current_version("1.0.0") .url(format!( "{}/win64/{{{{current_version}}}}", @@ -1060,7 +1002,7 @@ mod test { )) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .current_version("10.0.0") .url(format!( "{}/darwin/{{{{current_version}}}}", @@ -1082,7 +1024,7 @@ mod test { .with_body(generate_sample_raw_json()) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .url("http://badurl.www.tld/1".into()) .url(mockito::server_url()) .current_version("0.0.1") @@ -1102,7 +1044,7 @@ mod test { .with_body(generate_sample_raw_json()) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .urls(&["http://badurl.www.tld/1".into(), mockito::server_url(),]) .current_version("0.0.1") .build()); @@ -1121,7 +1063,7 @@ mod test { .with_body(generate_sample_bad_json()) .create(); - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .url(mockito::server_url()) .current_version("0.0.1") .build()); @@ -1131,13 +1073,23 @@ mod test { // run complete process on mac only for now as we don't have // server (api) that we can use to test - #[cfg(target_os = "macos")] #[test] + #[cfg(target_os = "macos")] fn http_updater_complete_process() { - let good_archive_url = format!("{}/archive.tar.gz", mockito::server_url()); + #[cfg(target_os = "macos")] + let archive_file = "archive.macos.tar.gz"; + #[cfg(target_os = "linux")] + let archive_file = "archive.linux.tar.gz"; + #[cfg(target_os = "windows")] + let archive_file = "archive.windows.zip"; - let mut signature_file = File::open("./test/updater/fixture/archives/archive.tar.gz.sig") - .expect("Unable to open signature"); + let good_archive_url = format!("{}/{}", mockito::server_url(), archive_file); + + let mut signature_file = File::open(format!( + "./test/updater/fixture/archives/{}.sig", + archive_file + )) + .expect("Unable to open signature"); let mut signature = String::new(); signature_file .read_to_string(&mut signature) @@ -1151,10 +1103,10 @@ mod test { .expect("Unable to read signature as string"); // add sample file - let _m = mockito::mock("GET", "/archive.tar.gz") + let _m = mockito::mock("GET", format!("/{}", archive_file).as_str()) .with_status(200) .with_header("content-type", "application/octet-stream") - .with_body_from_file("./test/updater/fixture/archives/archive.tar.gz") + .with_body_from_file(format!("./test/updater/fixture/archives/{}", archive_file)) .create(); // sample mock for update file @@ -1184,16 +1136,28 @@ mod test { let tmp_dir_unwrap = tmp_dir.expect("Can't find tmp_dir"); let tmp_dir_path = tmp_dir_unwrap.path(); + #[cfg(target_os = "linux")] + let my_executable = &tmp_dir_path.join("updater-example_0.1.0_amd64.AppImage"); + #[cfg(target_os = "macos")] + let my_executable = &tmp_dir_path.join("my_app"); + #[cfg(target_os = "windows")] + let my_executable = &tmp_dir_path.join("my_app.exe"); + // configure the updater - let check_update = block!(builder() + let check_update = block!(builder(Default::default()) .url(mockito::server_url()) // It should represent the executable path, that's why we add my_app.exe in our // test path -- in production you shouldn't have to provide it - .executable_path(&tmp_dir_path.join("my_app.exe")) + .executable_path(my_executable) // make sure we force an update .current_version("1.0.0") .build()); + #[cfg(target_os = "linux")] + { + env::set_var("APPIMAGE", my_executable); + } + // make sure the process worked assert!(check_update.is_ok()); @@ -1206,13 +1170,19 @@ mod test { assert_eq!(updater.version, "2.0.1"); // download, install and validate signature - let install_process = block!(updater.download_and_install(Some(pubkey))); + let install_process = block!(updater.download_and_install(pubkey)); assert!(install_process.is_ok()); // make sure the extraction went well (it should have skipped the main app.app folder) // as we can't extract in /Applications directly + #[cfg(target_os = "macos")] let bin_file = tmp_dir_path.join("Contents").join("MacOS").join("app"); - let bin_file_exist = Path::new(&bin_file).exists(); - assert!(bin_file_exist); + #[cfg(target_os = "linux")] + // linux should extract at same place as the executable path + let bin_file = my_executable; + #[cfg(target_os = "windows")] + let bin_file = tmp_dir_path.join("with").join("long").join("path.json"); + + assert!(bin_file.exists()); } } diff --git a/core/tauri/src/updater/error.rs b/core/tauri/src/updater/error.rs index a259cb927f7d..f1c6d964f17e 100644 --- a/core/tauri/src/updater/error.rs +++ b/core/tauri/src/updater/error.rs @@ -38,12 +38,15 @@ pub enum Error { /// Error building updater. #[error("Unable to prepare the updater: {0}")] Builder(String), + /// Error building updater. + #[error("Unable to extract the new version: {0}")] + Extract(String), /// Updater is not supported for current operating system or platform. #[error("Unsuported operating system or platform")] UnsupportedPlatform, /// Public key found in `tauri.conf.json` but no signature announced remotely. - #[error("Signature not available but public key provided, skipping update")] - PubkeyButNoSignature, + #[error("Signature not available, skipping update")] + MissingUpdaterSignature, /// Triggered when there is NO error and the two versions are equals. /// On client side, it's important to catch this error. #[error("No updates available")] diff --git a/core/tauri/src/updater/mod.rs b/core/tauri/src/updater/mod.rs index 7c36c191375e..4c04652160dd 100644 --- a/core/tauri/src/updater/mod.rs +++ b/core/tauri/src/updater/mod.rs @@ -293,7 +293,7 @@ //! To generate your keys you need to use the Tauri cli. //! //! ```bash -//! tauri sign -g -w ~/.tauri/myapp.key +//! tauri signer sign -g -w ~/.tauri/myapp.key //! ``` //! //! You have multiple options available @@ -301,7 +301,7 @@ //! Tauri updates signer. //! //! USAGE: -//! tauri sign [FLAGS] [OPTIONS] +//! tauri signer sign [FLAGS] [OPTIONS] //! //! FLAGS: //! --force Overwrite private key even if it exists on the specified path @@ -333,14 +333,12 @@ mod error; pub use self::error::Error; use crate::{ - api::{dialog::ask, process::restart}, + api::{dialog::blocking::ask, process::restart}, runtime::Runtime, utils::config::UpdaterConfig, - Window, + Env, Manager, Window, }; -use std::sync::mpsc::channel; - /// Check for new updates pub const EVENT_CHECK_UPDATE: &str = "tauri://update"; /// New update available @@ -381,8 +379,13 @@ pub(crate) async fn check_update_with_dialog( window: Window, ) { if let Some(endpoints) = updater_config.endpoints.clone() { + let endpoints = endpoints + .iter() + .map(|e| e.to_string()) + .collect::>(); + let env = window.state::().inner().clone(); // check updates - match self::core::builder() + match self::core::builder(env) .urls(&endpoints[..]) .current_version(&package_info.version) .build() @@ -439,7 +442,9 @@ pub(crate) fn listener( .endpoints .as_ref() .expect("Something wrong with endpoints") - .clone(); + .iter() + .map(|e| e.to_string()) + .collect::>(); let pubkey = updater_config.pubkey.clone(); @@ -448,8 +453,9 @@ pub(crate) fn listener( let window = window.clone(); let window_isolation = window.clone(); let pubkey = pubkey.clone(); + let env = window.state::().inner().clone(); - match self::core::builder() + match self::core::builder(env) .urls(&endpoints[..]) .current_version(&package_info.version) .build() @@ -461,20 +467,19 @@ pub(crate) fn listener( let body = updater.body.clone().unwrap_or_else(|| String::from("")); // Emit `tauri://update-available` - let _ = window.emit( + let _ = window.emit_and_trigger( EVENT_UPDATE_AVAILABLE, - Some(UpdateManifest { + UpdateManifest { body, date: updater.date.clone(), version: updater.version.clone(), - }), + }, ); // Listen for `tauri://update-install` window.once(EVENT_INSTALL_UPDATE, move |_msg| { let window = window_isolation.clone(); let updater = updater.clone(); - let pubkey = pubkey.clone(); // Start installation crate::async_runtime::spawn(async move { @@ -510,12 +515,12 @@ pub(crate) fn listener( // Send a status update via `tauri://update-status` event. fn send_status_update(window: Window, status: &str, error: Option) { - let _ = window.emit( + let _ = window.emit_and_trigger( EVENT_STATUS_UPDATE, - Some(StatusEvent { + StatusEvent { error, status: String::from(status), - }), + }, ); } @@ -526,16 +531,14 @@ async fn prompt_for_install( updater: &self::core::Update, app_name: &str, body: &str, - pubkey: Option, + pubkey: String, ) -> crate::Result<()> { // remove single & double quote let escaped_body = body.replace(&['\"', '\''][..], ""); - let (tx, rx) = channel(); - // todo(lemarier): We should review this and make sure we have // something more conventional. - ask( + let should_install = ask( Some(&window), format!(r#"A new version of {} is available! "#, app_name), format!( @@ -547,10 +550,9 @@ Release Notes: {}"#, app_name, updater.version, updater.current_version, escaped_body, ), - move |should_install| tx.send(should_install).unwrap(), ); - if rx.recv().unwrap() { + if should_install { // Launch updater download process // macOS we display the `Ready to restart dialog` asking to restart // Windows is closing the current App and launch the downloaded MSI when ready (the process stop here) @@ -558,16 +560,15 @@ Release Notes: updater.download_and_install(pubkey.clone()).await?; // Ask user if we need to restart the application - ask( + let env = window.state::().inner().clone(); + let should_exit = ask( Some(&window), "Ready to Restart", "The installation was successful, do you want to restart the application now?", - |should_exit| { - if should_exit { - restart(); - } - }, ); + if should_exit { + restart(&env); + } } Ok(()) diff --git a/core/tauri/src/window.rs b/core/tauri/src/window.rs index 3a7b8aa65b13..f86b5be23fd2 100644 --- a/core/tauri/src/window.rs +++ b/core/tauri/src/window.rs @@ -12,13 +12,14 @@ use crate::{ app::AppHandle, command::{CommandArg, CommandItem}, event::{Event, EventHandler}, + hooks::{InvokePayload, InvokeResponder}, manager::WindowManager, runtime::{ monitor::Monitor as RuntimeMonitor, - webview::{InvokePayload, WebviewAttributes, WindowBuilder}, + webview::{WebviewAttributes, WindowBuilder}, window::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, - DetachedWindow, PendingWindow, WindowEvent, + DetachedWindow, JsEventListenerKey, PendingWindow, WindowEvent, }, Dispatch, Icon, Runtime, UserAttentionType, }, @@ -32,7 +33,10 @@ use serde::Serialize; use tauri_macros::default_runtime; -use std::hash::{Hash, Hasher}; +use std::{ + hash::{Hash, Hasher}, + sync::Arc, +}; /// Monitor descriptor. #[derive(Debug, Clone, Serialize)] @@ -93,6 +97,26 @@ pub struct Window { pub(crate) app_handle: AppHandle, } +#[cfg(any(windows, target_os = "macos"))] +#[cfg_attr(doc_cfg, doc(cfg(any(windows, target_os = "macos"))))] +unsafe impl raw_window_handle::HasRawWindowHandle for Window { + #[cfg(windows)] + fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { + let mut handle = raw_window_handle::Win32Handle::empty(); + handle.hwnd = self.hwnd().expect("failed to get window `hwnd`"); + raw_window_handle::RawWindowHandle::Win32(handle) + } + + #[cfg(target_os = "macos")] + fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { + let mut handle = raw_window_handle::AppKitHandle::empty(); + handle.ns_window = self + .ns_window() + .expect("failed to get window's `ns_window`"); + raw_window_handle::RawWindowHandle::AppKit(handle) + } +} + impl Clone for Window { fn clone(&self) -> Self { Self { @@ -155,6 +179,8 @@ impl Window { } /// Creates a new webview window. + /// + /// Data URLs are only supported with the `window-data-url` feature flag. pub fn create_window( &mut self, label: String, @@ -181,13 +207,17 @@ impl Window { )) } + pub(crate) fn invoke_responder(&self) -> Arc> { + self.manager.invoke_responder() + } + /// The current window's dispatcher. pub(crate) fn dispatcher(&self) -> R::Dispatcher { self.window.dispatcher.clone() } - #[allow(dead_code)] - pub(crate) fn run_on_main_thread(&self, f: F) -> crate::Result<()> { + /// Runs the given closure on the main thread. + pub fn run_on_main_thread(&self, f: F) -> crate::Result<()> { self .window .dispatcher @@ -196,9 +226,9 @@ impl Window { } /// How to handle this window receiving an [`InvokeMessage`]. - pub(crate) fn on_message(self, command: String, payload: InvokePayload) -> crate::Result<()> { + pub fn on_message(self, payload: InvokePayload) -> crate::Result<()> { let manager = self.manager.clone(); - match command.as_str() { + match payload.cmd.as_str() { "__initialized" => { let payload: PageLoadPayload = serde_json::from_value(payload.inner)?; manager.run_on_page_load(self, payload); @@ -207,25 +237,19 @@ impl Window { let message = InvokeMessage::new( self.clone(), manager.state(), - command.to_string(), + payload.cmd.to_string(), payload.inner, ); let resolver = InvokeResolver::new(self, payload.callback, payload.error); + let invoke = Invoke { message, resolver }; - if manager.verify_invoke_key(payload.key) { - if let Some(module) = &payload.tauri_module { - let module = module.to_string(); - crate::endpoints::handle(module, invoke, manager.config(), manager.package_info()); - } else if command.starts_with("plugin:") { - manager.extend_api(invoke); - } else { - manager.run_invoke_handler(invoke); - } + if let Some(module) = &payload.tauri_module { + let module = module.to_string(); + crate::endpoints::handle(module, invoke, manager.config(), manager.package_info()); + } else if payload.cmd.starts_with("plugin:") { + manager.extend_api(invoke); } else { - panic!( - r#"The invoke key "{}" is invalid. This means that an external, possible malicious script is trying to access the system interface."#, - payload.key - ); + manager.run_invoke_handler(invoke); } } } @@ -238,24 +262,49 @@ impl Window { &self.window.label } - /// Emits an event to the current window. - pub fn emit(&self, event: &str, payload: S) -> crate::Result<()> { + /// Emits an event to both the JavaScript and the Rust listeners. + pub fn emit_and_trigger( + &self, + event: &str, + payload: S, + ) -> crate::Result<()> { + self.trigger(event, Some(serde_json::to_string(&payload)?)); + self.emit(event, payload) + } + + pub(crate) fn emit_internal( + &self, + event: &str, + source_window_label: Option<&str>, + payload: S, + ) -> crate::Result<()> { self.eval(&format!( - "window['{}']({{event: {}, payload: {}}})", + "window['{}']({{event: {}, windowLabel: {}, payload: {}}})", self.manager.event_emit_function_name(), serde_json::to_string(event)?, + serde_json::to_string(&source_window_label)?, serde_json::to_value(payload)?, ))?; - Ok(()) } - /// Emits an event on all windows except this one. - pub fn emit_others(&self, event: &str, payload: S) -> crate::Result<()> { - self.manager.emit_filter(event, payload, |w| w != self) + /// Emits an event to the JavaScript listeners on the current window. + /// + /// The event is only delivered to listeners that used the `WebviewWindow#listen` method on the @tauri-apps/api `window` module. + pub fn emit(&self, event: &str, payload: S) -> crate::Result<()> { + self + .manager + .emit_filter(event, Some(self.label()), payload, |w| { + w.has_js_listener(None, event) || w.has_js_listener(Some(self.label().into()), event) + })?; + Ok(()) } /// Listen to an event on this window. + /// + /// This listener only receives events that are triggered using the + /// [`trigger`](Window#method.trigger) and [`emit_and_trigger`](Window#method.emit_and_trigger) methods or + /// the `appWindow.emit` function from the @tauri-apps/api `window` module. pub fn listen(&self, event: impl Into, handler: F) -> EventHandler where F: Fn(Event) + Send + 'static, @@ -264,16 +313,23 @@ impl Window { self.manager.listen(event.into(), Some(label), handler) } - /// Listen to a an event on this window a single time. + /// Unlisten to an event on this window. + pub fn unlisten(&self, handler_id: EventHandler) { + self.manager.unlisten(handler_id) + } + + /// Listen to an event on this window a single time. pub fn once(&self, event: impl Into, handler: F) -> EventHandler where - F: Fn(Event) + Send + 'static, + F: FnOnce(Event) + Send + 'static, { let label = self.window.label.clone(); self.manager.once(event.into(), Some(label), handler) } - /// Triggers an event on this window. + /// Triggers an event to the Rust listeners on this window. + /// + /// The event is only delivered to listeners that used the [`listen`](Window#method.listen) method. pub fn trigger(&self, event: &str, data: Option) { let label = self.window.label.clone(); self.manager.trigger(event, Some(label), data) @@ -291,56 +347,110 @@ impl Window { /// Registers a menu event listener. pub fn on_menu_event(&self, f: F) -> uuid::Uuid { - let menu_ids = self.manager.menu_ids(); + let menu_ids = self.window.menu_ids.clone(); self.window.dispatcher.on_menu_event(move |event| { f(MenuEvent { - menu_item_id: menu_ids.get(&event.menu_item_id).unwrap().clone(), + menu_item_id: menu_ids + .lock() + .unwrap() + .get(&event.menu_item_id) + .unwrap() + .clone(), }) }) } + pub(crate) fn register_js_listener(&self, window_label: Option, event: String, id: u64) { + self + .window + .js_event_listeners + .lock() + .unwrap() + .entry(JsEventListenerKey { + window_label, + event, + }) + .or_insert_with(Default::default) + .insert(id); + } + + pub(crate) fn unregister_js_listener(&self, id: u64) { + let mut empty = None; + let mut js_listeners = self.window.js_event_listeners.lock().unwrap(); + for (key, ids) in js_listeners.iter_mut() { + if ids.contains(&id) { + ids.remove(&id); + if ids.is_empty() { + empty.replace(key.clone()); + } + break; + } + } + + if let Some(key) = empty { + js_listeners.remove(&key); + } + } + + /// Whether this window registered a listener to an event from the given window and event name. + pub(crate) fn has_js_listener(&self, window_label: Option, event: &str) -> bool { + self + .window + .js_event_listeners + .lock() + .unwrap() + .contains_key(&JsEventListenerKey { + window_label, + event: event.into(), + }) + } + + /// Opens the developer tools window (Web Inspector). + /// The devtools is only enabled on debug builds or with the `devtools` feature flag. + /// + /// ## Platform-specific + /// + /// - **macOS**: This is a private API on macOS, + /// so you cannot use this if your application will be published on the App Store. + /// + /// # Example + /// + /// ```rust,no_run + /// use tauri::Manager; + /// tauri::Builder::default() + /// .setup(|app| { + /// #[cfg(debug_assertions)] + /// app.get_window("main").unwrap().open_devtools(); + /// Ok(()) + /// }); + /// ``` + #[cfg(any(debug_assertions, feature = "devtools"))] + #[cfg_attr(doc_cfg, doc(cfg(any(debug_assertions, feature = "devtools"))))] + pub fn open_devtools(&self) { + self.window.dispatcher.open_devtools(); + } + // Getters /// Gets a handle to the window menu. pub fn menu_handle(&self) -> MenuHandle { MenuHandle { - ids: self.manager.menu_ids(), + ids: self.window.menu_ids.clone(), dispatcher: self.dispatcher(), } } /// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn scale_factor(&self) -> crate::Result { self.window.dispatcher.scale_factor().map_err(Into::into) } /// Returns the position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn inner_position(&self) -> crate::Result> { self.window.dispatcher.inner_position().map_err(Into::into) } /// Returns the position of the top-left hand corner of the window relative to the top-left hand corner of the desktop. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn outer_position(&self) -> crate::Result> { self.window.dispatcher.outer_position().map_err(Into::into) } @@ -348,13 +458,6 @@ impl Window { /// Returns the physical size of the window's client area. /// /// The client area is the content of the window, excluding the title bar and borders. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn inner_size(&self) -> crate::Result> { self.window.dispatcher.inner_size().map_err(Into::into) } @@ -362,73 +465,31 @@ impl Window { /// Returns the physical size of the entire window. /// /// These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn outer_size(&self) -> crate::Result> { self.window.dispatcher.outer_size().map_err(Into::into) } /// Gets the window's current fullscreen state. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn is_fullscreen(&self) -> crate::Result { self.window.dispatcher.is_fullscreen().map_err(Into::into) } /// Gets the window's current maximized state. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn is_maximized(&self) -> crate::Result { self.window.dispatcher.is_maximized().map_err(Into::into) } /// Gets the window’s current decoration state. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn is_decorated(&self) -> crate::Result { self.window.dispatcher.is_decorated().map_err(Into::into) } /// Gets the window’s current resizable state. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn is_resizable(&self) -> crate::Result { self.window.dispatcher.is_resizable().map_err(Into::into) } /// Gets the window's current vibility state. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn is_visible(&self) -> crate::Result { self.window.dispatcher.is_visible().map_err(Into::into) } @@ -436,17 +497,6 @@ impl Window { /// Returns the monitor on which the window currently resides. /// /// Returns None if current monitor can't be detected. - /// - /// ## Platform-specific - /// - /// - **Linux:** Unsupported - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn current_monitor(&self) -> crate::Result> { self .window @@ -459,17 +509,6 @@ impl Window { /// Returns the primary monitor of the system. /// /// Returns None if it can't identify any monitor as a primary one. - /// - /// ## Platform-specific - /// - /// - **Linux:** Unsupported - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn primary_monitor(&self) -> crate::Result> { self .window @@ -480,17 +519,6 @@ impl Window { } /// Returns the list of all the monitors available on the system. - /// - /// ## Platform-specific - /// - /// - **Linux:** Unsupported - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn available_monitors(&self) -> crate::Result> { self .window @@ -501,32 +529,18 @@ impl Window { } /// Returns the native handle that is used by this window. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. #[cfg(target_os = "macos")] pub fn ns_window(&self) -> crate::Result<*mut std::ffi::c_void> { self.window.dispatcher.ns_window().map_err(Into::into) } /// Returns the native handle that is used by this window. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. #[cfg(windows)] pub fn hwnd(&self) -> crate::Result<*mut std::ffi::c_void> { self .window .dispatcher .hwnd() - .map(|hwnd| hwnd as *mut _) + .map(|hwnd| hwnd.0 as *mut _) .map_err(Into::into) } @@ -561,6 +575,7 @@ impl Window { /// ## Platform-specific /// /// - **macOS:** `None` has no effect. + /// - **Linux:** Urgency levels have the same effect. pub fn request_user_attention( &self, request_type: Option, @@ -628,6 +643,12 @@ impl Window { } /// Closes this window. + /// # Panics + /// + /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. + /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. + /// + /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn close(&self) -> crate::Result<()> { self.window.dispatcher.close().map_err(Into::into) } @@ -721,3 +742,12 @@ impl Window { self.window.dispatcher.start_dragging().map_err(Into::into) } } + +#[cfg(test)] +mod tests { + #[test] + fn window_is_send_sync() { + crate::test_utils::assert_send::(); + crate::test_utils::assert_sync::(); + } +} diff --git a/core/tauri/src/window/menu.rs b/core/tauri/src/window/menu.rs index bd3561575ce5..b9b346aaac1a 100644 --- a/core/tauri/src/window/menu.rs +++ b/core/tauri/src/window/menu.rs @@ -9,7 +9,10 @@ use crate::runtime::{ use tauri_macros::default_runtime; -use std::collections::HashMap; +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; /// The window menu event. #[derive(Debug, Clone)] @@ -28,7 +31,7 @@ impl MenuEvent { #[default_runtime(crate::Wry, wry)] #[derive(Debug)] pub struct MenuHandle { - pub(crate) ids: HashMap, + pub(crate) ids: Arc>>, pub(crate) dispatcher: R::Dispatcher, } @@ -61,7 +64,7 @@ impl Clone for MenuItemHandle { impl MenuHandle { /// Gets a handle to the menu item that has the specified `id`. pub fn get_item(&self, id: MenuIdRef<'_>) -> MenuItemHandle { - for (raw, item_id) in self.ids.iter() { + for (raw, item_id) in self.ids.lock().unwrap().iter() { if item_id == id { return MenuItemHandle { id: *raw, @@ -83,25 +86,11 @@ impl MenuHandle { } /// Whether the menu is visible or not. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn is_visible(&self) -> crate::Result { self.dispatcher.is_menu_visible().map_err(Into::into) } /// Toggles the menu visibility. - /// - /// # Panics - /// - /// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure. - /// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure. - /// - /// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic. pub fn toggle(&self) -> crate::Result<()> { if self.is_visible()? { self.hide() diff --git a/core/tauri/test/updater/fixture/archives/archive.linux.tar.gz b/core/tauri/test/updater/fixture/archives/archive.linux.tar.gz new file mode 100644 index 000000000000..dcb6e145b25f Binary files /dev/null and b/core/tauri/test/updater/fixture/archives/archive.linux.tar.gz differ diff --git a/core/tauri/test/updater/fixture/archives/archive.linux.tar.gz.sig b/core/tauri/test/updater/fixture/archives/archive.linux.tar.gz.sig new file mode 100644 index 000000000000..4b47343df3a1 --- /dev/null +++ b/core/tauri/test/updater/fixture/archives/archive.linux.tar.gz.sig @@ -0,0 +1 @@ +dW50cnVzdGVkIGNvbW1lbnQ6IHNpZ25hdHVyZSBmcm9tIHRhdXJpIHNlY3JldCBrZXkKUldSWTRKaFRZQmJER2NJZ21zb1RObVMwZmdkQUZ2OFFxM2dYdVhLRXpSNFp1VW03Zml2THlDRldpSmJPRkYyQlQ4QzltdkYxTG5MbzdWODZwdFN4aUNoWXY1V0lMem55T3djPQp0cnVzdGVkIGNvbW1lbnQ6IHRpbWVzdGFtcDoxNjI5OTE2MjIwCWZpbGU6YXJjaGl2ZS5saW51eC50YXIuZ3oKZXExb3FCVGlxVkc3YThBVklQeVdhS0psOWROT3p4aVcwaE1ZaE9SRWVFU2lBdnRTVFd1SnJ4QjlTWW90d045UXFZZ1VROE1mUFJhUWxaUjVSaXAwREE9PQo= \ No newline at end of file diff --git a/core/tauri/test/updater/fixture/archives/archive.tar.gz b/core/tauri/test/updater/fixture/archives/archive.macos.tar.gz similarity index 100% rename from core/tauri/test/updater/fixture/archives/archive.tar.gz rename to core/tauri/test/updater/fixture/archives/archive.macos.tar.gz diff --git a/core/tauri/test/updater/fixture/archives/archive.tar.gz.sig b/core/tauri/test/updater/fixture/archives/archive.macos.tar.gz.sig similarity index 100% rename from core/tauri/test/updater/fixture/archives/archive.tar.gz.sig rename to core/tauri/test/updater/fixture/archives/archive.macos.tar.gz.sig diff --git a/core/tauri/test/updater/fixture/archives/archive.tar.gz.badsig b/core/tauri/test/updater/fixture/archives/archive.tar.gz.badsig deleted file mode 100644 index cd6483c53b45..000000000000 --- a/core/tauri/test/updater/fixture/archives/archive.tar.gz.badsig +++ /dev/null @@ -1 +0,0 @@ -dW90cnVzdGVkIGIvbW1lbnQ6IHNpZ25hdHVyZSBmcm1tIHRhdXJpIHNlY3JldCBrZXkKUldUTE3QzWxkQolZOVVDaC92ZnhXN0IrVm4rVW9GKzdoSFF6NEtFc3J3c004YUhQTFR0Njg5MGtuZkZqeVh1cTlwZ1dmWG9aSkx5d0t1WTBkS04wK1RBeEI2K2pka2tsT3drPQp0cnVzdGVkIGNvbW1lbnQ6IHRpbWVzdGFtcDoxNTkxODg2NjU2CWZpbGU6L1VzZXJzL2RhdmlkL2Rldi90YXVyaV91cGRhdGVyL3RhdXJpLXVwZGF0ZXIvdGVzdC9maXh0dXJlL2FyY2hpdmVzL2FyY2hpdmUudGFyLmd6CjNmMC9XdmYyzDtCM3ZoaWhEbHVVL08vV2tLejQ0Wlg5SkNGTys2N1ZMTHQvUENrK0svMlgzNE22UkQ0OG1sZ0RqTGZXNzA0OGxocmg4ODljM3BGOEJnPT0K \ No newline at end of file diff --git a/core/tauri/test/updater/fixture/archives/archive.zip b/core/tauri/test/updater/fixture/archives/archive.windows.zip similarity index 100% rename from core/tauri/test/updater/fixture/archives/archive.zip rename to core/tauri/test/updater/fixture/archives/archive.windows.zip diff --git a/core/tauri/test/updater/fixture/archives/archive.zip.sig b/core/tauri/test/updater/fixture/archives/archive.windows.zip.sig similarity index 100% rename from core/tauri/test/updater/fixture/archives/archive.zip.sig rename to core/tauri/test/updater/fixture/archives/archive.windows.zip.sig diff --git a/core/tauri/tests/restart.rs b/core/tauri/tests/restart.rs new file mode 100644 index 000000000000..464659444b6e --- /dev/null +++ b/core/tauri/tests/restart.rs @@ -0,0 +1,164 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::io; +use std::path::{Path, PathBuf}; +use std::process::Command; + +/// Helper for generic catch-all errors. +type Result = std::result::Result<(), Box>; + +/// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--1300-1699- +#[cfg(windows)] +const ERROR_PRIVILEGE_NOT_HELD: i32 = 1314; + +/// Represents a successfully created symlink. +enum Symlink { + /// Path to the created symlink + Created(PathBuf), + + /// A symlink that failed due to missing permissions (Windows). + #[allow(dead_code)] + Privilege, +} + +/// Compile the nested restart binary so that we have access to it during the test. +/// +/// This is compiled inside of this test so that we always have a literal binary file we can use +/// for some filesystem related tests. Because of how integration tests work, the current working +/// directory should be the same as the manifest of the crate (not workspace) this integration test +/// is a part of. +fn compile_restart_test_binary() -> io::Result { + let project = PathBuf::from("tests").join("restart"); + + let mut cargo = Command::new("cargo"); + cargo.arg("build"); + cargo.arg("--manifest-path"); + cargo.arg(project.join("Cargo.toml")); + + // enable the dangerous macos flag on tauri if the test runner has the feature enabled + if cfg!(feature = "process-relaunch-dangerous-allow-symlink-macos") { + cargo.args([ + "--features", + "tauri/process-relaunch-dangerous-allow-symlink-macos", + ]); + } + + let status = cargo.status()?; + if !status.success() { + return Err(io::Error::new( + io::ErrorKind::Other, + "Unable to compile restart test cargo project inside restart integration test", + )); + } + + let profile = if cfg!(debug_assertions) { + "debug" + } else { + "release" + }; + + let bin = if cfg!(windows) { + "restart.exe" + } else { + "restart" + }; + + Ok(project.join("target").join(profile).join(bin)) +} + +/// Compile the test binary, run it, and compare it with expected output. +/// +/// Failing to create a symlink due to permissions issues is also a success +/// for the purpose of this runner. +fn symlink_runner(create_symlinks: impl Fn(&Path) -> io::Result) -> Result { + let compiled_binary = compile_restart_test_binary()?; + + // set up all the temporary file paths + let temp = tempfile::TempDir::new()?; + let bin = temp.path().canonicalize()?.join("restart.exe"); + + // copy the built restart test binary to our temporary directory + std::fs::copy(compiled_binary, &bin)?; + + if let Symlink::Created(link) = create_symlinks(&bin)? { + // run the command from the symlink, so that we can test if restart resolves it correctly + let mut cmd = Command::new(link); + + // add the restart parameter so that the invocation will call tauri::api::process::restart + cmd.arg("restart"); + + let output = cmd.output()?; + + // run `TempDir` destructors to prevent resource leaking if the assertion fails + drop(temp); + + if output.status.success() { + // gather the output into a string + let stdout = String::from_utf8(output.stdout)?; + + // we expect the output to be the bin path, twice + assert_eq!(stdout, format!("{bin}\n{bin}\n", bin = bin.display())); + } else if cfg!(all( + target_os = "macos", + not(feature = "process-relaunch-dangerous-allow-symlink-macos") + )) { + // we expect this to fail on macOS without the dangerous symlink flag set + let stderr = String::from_utf8(output.stderr)?; + + // make sure it's the error that we expect + assert!(stderr.contains( + "StartingBinary found current_exe() that contains a symlink on a non-allowed platform" + )); + } else { + // we didn't expect the program to fail in this configuration, just panic + panic!("restart integration test runner failed for unknown reason"); + } + } + + Ok(()) +} + +/// Cross-platform way to create a symlink +/// +/// Symlinks that failed to create due to permissions issues (like on Windows) +/// are also seen as successful for the purpose of this testing suite. +fn create_symlink(original: &Path, link: PathBuf) -> io::Result { + #[cfg(unix)] + return std::os::unix::fs::symlink(original, &link).map(|()| Symlink::Created(link)); + + #[cfg(windows)] + return match std::os::windows::fs::symlink_file(original, &link) { + Ok(()) => Ok(Symlink::Created(link)), + Err(e) => match e.raw_os_error() { + Some(ERROR_PRIVILEGE_NOT_HELD) => Ok(Symlink::Privilege), + _ => Err(e), + }, + }; +} + +#[test] +fn symlink() -> Result { + symlink_runner(|bin| { + let mut link = bin.to_owned(); + link.set_file_name("symlink"); + link.set_extension("exe"); + create_symlink(bin, link) + }) +} + +#[test] +fn nested_symlinks() -> Result { + symlink_runner(|bin| { + let mut link1 = bin.to_owned(); + link1.set_file_name("symlink1"); + link1.set_extension("exe"); + create_symlink(bin, link1.clone())?; + + let mut link2 = bin.to_owned(); + link2.set_file_name("symlink2"); + link2.set_extension("exe"); + create_symlink(&link1, link2) + }) +} diff --git a/core/tauri/tests/restart/.license_template b/core/tauri/tests/restart/.license_template new file mode 120000 index 000000000000..d1662c6c9b2d --- /dev/null +++ b/core/tauri/tests/restart/.license_template @@ -0,0 +1 @@ +../../../../.license_template \ No newline at end of file diff --git a/core/tauri/tests/restart/Cargo.lock b/core/tauri/tests/restart/Cargo.lock new file mode 100644 index 000000000000..02943f2b78af --- /dev/null +++ b/core/tauri/tests/restart/Cargo.lock @@ -0,0 +1,3216 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "atk" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a83b21d2aa75e464db56225e1bda2dd5993311ba1095acaa8fa03d1ae67026ba" +dependencies = [ + "atk-sys", + "bitflags", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake3" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.1", + "rayon", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cairo-rs" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b5725979db0c586d98abad2193cdb612dd40ef95cd26bd99851bf93b3cb482" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b448b876970834fda82ba3aeaccadbd760206b75388fc5c1b02f1e343b697570" +dependencies = [ + "glib-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfb" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca453e8624711b2f0f4eb47076a318feda166252a827ee25d067b43de83dcba0" +dependencies = [ + "byteorder", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cocoa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + +[[package]] +name = "darling" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +dependencies = [ + "darling_core 0.13.1", + "darling_macro 0.13.1", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.9.3", + "syn", +] + +[[package]] +name = "darling_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core 0.10.2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +dependencies = [ + "darling_core 0.13.1", + "quote", + "syn", +] + +[[package]] +name = "data-url" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193" +dependencies = [ + "matches", +] + +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +dependencies = [ + "block-buffer 0.10.0", + "crypto-common", + "generic-array", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dtoa-short" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +dependencies = [ + "dtoa", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "field-offset" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +dependencies = [ + "memoffset", + "rustc_version 0.3.3", +] + +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" + +[[package]] +name = "futures-executor" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" + +[[package]] +name = "futures-task" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" + +[[package]] +name = "futures-util" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d749dcfc00d8de0d7c3a289e04a04293eb5ba3d8a4e64d64911d481fa9933b" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gdk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps 3.2.0", +] + +[[package]] +name = "gdkx11-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cefbc8ac7be19c9b51f54fbd7cef48b70495a4cb23a812e2137e75b484b29d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps 3.2.0", + "x11", +] + +[[package]] +name = "generator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "winapi", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gio" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711c3632b3ebd095578a9c091418d10fed492da9443f58ebc8f45efbeb215cb0" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", + "winapi", +] + +[[package]] +name = "glib" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c515f1e62bf151ef6635f528d05b02c11506de986e43b34a5c920ef0b3796a4" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" +dependencies = [ + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "globset" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "gobject-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" +dependencies = [ + "glib-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gtk" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb51122dd3317e9327ec1e4faa151d1fa0d95664cd8fb8dcfacf4d4d29ac70c" +dependencies = [ + "atk", + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps 3.2.0", +] + +[[package]] +name = "gtk3-macros" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "html5ever" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.1", +] + +[[package]] +name = "http-range" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee9694f83d9b7c09682fdb32213682939507884e5bcf227be9aff5d644b90dc" + +[[package]] +name = "ico" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" +dependencies = [ + "byteorder", + "png 0.11.0", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "infer" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92b41dab759f9e8427c03f519c344a14655490b8db548dac1e57a75b3258391" +dependencies = [ + "cfb", +] + +[[package]] +name = "inflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" +dependencies = [ + "adler32", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "javascriptcore-rs" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e207780c1d1cd3c36056695e44010a19dd481574a2106cd2540edda4128a9794" +dependencies = [ + "bitflags", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2adf2de824b178d76c6017da59f4e7e95de49a766b584c59d47821a6c3dce9e2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "kuchiki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +dependencies = [ + "cssparser", + "html5ever", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "565dbd88872dbe4cc8a46e527f26483c1d1f7afa6b884a3bd6cd893d4f98da74" + +[[package]] +name = "lock_api" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "loom" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +dependencies = [ + "log", + "phf 0.8.0", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "ndk" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-glue" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk", + "ndk-macro", + "ndk-sys", +] + +[[package]] +name = "ndk-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +dependencies = [ + "darling 0.10.2", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pango" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546fd59801e5ca735af82839007edd226fe7d3bb06433ec48072be4439c28581" +dependencies = [ + "bitflags", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.4", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "png" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" +dependencies = [ + "bitflags", + "deflate 0.7.20", + "inflate", + "num-iter", +] + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.8.6", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76" +dependencies = [ + "libc", + "raw-window-handle 0.4.2", +] + +[[package]] +name = "raw-window-handle" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba75eee94a9d5273a68c9e1e105d9cffe1ef700532325788389e5a83e2522b7" +dependencies = [ + "cty", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.4", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "restart" +version = "0.1.0" +dependencies = [ + "tauri", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.4", +] + +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +dependencies = [ + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_with" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6056b4cb69b6e43e3a0f055def223380baecc99da683884f205bf347f7c4b3" +dependencies = [ + "rustversion", + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" +dependencies = [ + "darling 0.13.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.0" +source = "git+https://github.com/chippers/serialize-to-javascript#38d5026f371bfba4f5197ed143a6667a09375fbd" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.0" +source = "git+https://github.com/chippers/serialize-to-javascript#38d5026f371bfba4f5197ed143a6667a09375fbd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "siphasher" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "soup2-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f056675eda9a7417163e5f742bb119e8e1d385edd2ada8f7031a7230a3ec10a" +dependencies = [ + "bitflags", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923f0f39b6267d37d23ce71ae7235602134b250ace715dd2c90421998ddac0c6" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.8.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" + +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "sys-info" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "system-deps" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" +dependencies = [ + "anyhow", + "cfg-expr 0.8.1", + "heck", + "itertools", + "pkg-config", + "strum", + "strum_macros", + "thiserror", + "toml", + "version-compare", +] + +[[package]] +name = "system-deps" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" +dependencies = [ + "cfg-expr 0.9.1", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.5.2" +source = "git+https://github.com/tauri-apps/tao?branch=next#7811284e464f983485977b06010b6d1db134ca4e" +dependencies = [ + "bitflags", + "cairo-rs", + "cc", + "cocoa", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys", + "gtk", + "instant", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-glue", + "ndk-sys", + "objc", + "parking_lot", + "raw-window-handle 0.4.2", + "scopeguard", + "serde", + "tao-core-video-sys", + "unicode-segmentation", + "windows", + "windows_macros", + "x11-dl", +] + +[[package]] +name = "tao-core-video-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271450eb289cb4d8d0720c6ce70c72c8c858c93dd61fc625881616752e6b98f6" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "objc", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tauri" +version = "1.0.0-beta.8" +dependencies = [ + "bincode", + "cfg_aliases", + "data-url", + "dirs-next", + "either", + "embed_plist", + "flate2", + "futures", + "futures-lite", + "glib", + "glob", + "gtk", + "http", + "ignore", + "once_cell", + "percent-encoding", + "rand 0.8.4", + "raw-window-handle 0.3.4", + "regex", + "semver 1.0.4", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "state", + "tar", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "tempfile", + "thiserror", + "tokio", + "url", + "uuid", + "zip", +] + +[[package]] +name = "tauri-codegen" +version = "1.0.0-beta.4" +dependencies = [ + "base64", + "blake3", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "sha2", + "tauri-utils", + "thiserror", + "uuid", + "walkdir", + "zstd", +] + +[[package]] +name = "tauri-macros" +version = "1.0.0-beta.5" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", + "tauri-codegen", +] + +[[package]] +name = "tauri-runtime" +version = "0.2.1" +dependencies = [ + "gtk", + "http", + "http-range", + "infer", + "serde", + "serde_json", + "tauri-utils", + "thiserror", + "uuid", + "webview2-com", + "windows", +] + +[[package]] +name = "tauri-runtime-wry" +version = "0.2.1" +dependencies = [ + "gtk", + "ico", + "infer", + "png 0.16.8", + "tauri-runtime", + "tauri-utils", + "uuid", + "webview2-com", + "windows", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "1.0.0-beta.3" +dependencies = [ + "base64", + "ctor", + "heck", + "html5ever", + "kuchiki", + "phf 0.10.1", + "proc-macro2", + "quote", + "serde", + "serde_json", + "serde_with", + "serialize-to-javascript", + "sha2", + "thiserror", + "url", + "zstd", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tendril" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" +dependencies = [ + "bytes", + "memchr", + "num_cpus", + "pin-project-lite", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5312f325fe3588e277415f5a6cca1f4ccad0f248c4cd5a4bd33032d7286abc22" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "webkit2gtk" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07654baccd8874fc7c99cc33c27052fb02804276102dff0f78f981669316e0e9" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854a0cbf3570541bf13df70aac23826da7cd88f27a722b7b2043f32637373113" +dependencies = [ + "atk-sys", + "bitflags", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pango-sys", + "pkg-config", + "soup2-sys", + "system-deps 5.0.0", +] + +[[package]] +name = "webview2-com" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "381febeeb86214fd262941a2b26322c33c38bf8b565b0ddfd4a7a8d4003053a9" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows_macros", +] + +[[package]] +name = "webview2-com-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515c6c82fcee93f6edaacc72c8e233dbe4ff3ca569dce1901dfc36c404a3e99" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "webview2-com-sys" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2e3542bb16fe61e951f87c9146571344f1e773327498efa65704a4cff472662" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows", + "windows-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-bindgen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "944c545fcae9dd66488308f8b69aa3ba34f53714416ecfcdcbbfa4b6821e27c6" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca" + +[[package]] +name = "windows_gen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30dff4d91d22520628bb94b66f2bb313cb16a09a515a32320a84a1b449bc94c0" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_i686_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8" + +[[package]] +name = "windows_i686_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6" + +[[package]] +name = "windows_macros" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ae44ab917e9005fe710d99d52d227ca0164b10a09be90649142cc3fab825d3" +dependencies = [ + "syn", + "windows_gen", + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_quote" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71f02c51a77e6248c1206aaa920802c32d50a05205e229b118d7f3afd3036667" + +[[package]] +name = "windows_reader" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e44e6df0da993cda589c5ac852272fbb2a0ead67a031a017dd3eac11528a2d72" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1" + +[[package]] +name = "wry" +version = "0.12.2" +source = "git+ssh://git@github.com/tauri-sec/wry?branch=next#3a0076eb06aa249d9ef32dac993e3683a769165e" +dependencies = [ + "cocoa", + "core-graphics", + "gdk", + "gio", + "glib", + "gtk", + "http", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sys-info", + "tao", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows_macros", +] + +[[package]] +name = "x11" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd0565fa8bfba8c5efe02725b14dff114c866724eff2cfd44d76cea74bcd87a" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +dependencies = [ + "lazy_static", + "libc", + "pkg-config", +] + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "bzip2", + "crc32fast", + "flate2", + "thiserror", + "time", +] + +[[package]] +name = "zstd" +version = "0.9.2+zstd.1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2390ea1bf6c038c39674f22d95f0564725fc06034a47129179810b2fc58caa54" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "4.1.3+zstd.1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e99d81b99fb3c2c2c794e3fe56c305c63d5173a16a46b5850b07c935ffc7db79" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.6.2+zstd.1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2daf2f248d9ea44454bfcb2516534e8b8ad2fc91bf818a1885495fc42bc8ac9f" +dependencies = [ + "cc", + "libc", +] diff --git a/core/tauri/tests/restart/Cargo.toml b/core/tauri/tests/restart/Cargo.toml new file mode 100644 index 000000000000..2ab1786d69f4 --- /dev/null +++ b/core/tauri/tests/restart/Cargo.toml @@ -0,0 +1,10 @@ +[workspace] +[package] +name = "restart" +version = "0.1.0" +authors = [ "Tauri Programme within The Commons Conservancy" ] +license = "Apache-2.0 OR MIT" +edition = "2021" + +[dependencies.tauri] +path = "../.." diff --git a/core/tauri/tests/restart/LICENSE.spdx b/core/tauri/tests/restart/LICENSE.spdx new file mode 120000 index 000000000000..cc563bd76897 --- /dev/null +++ b/core/tauri/tests/restart/LICENSE.spdx @@ -0,0 +1 @@ +../../../../LICENSE.spdx \ No newline at end of file diff --git a/core/tauri/tests/restart/LICENSE_APACHE-2.0 b/core/tauri/tests/restart/LICENSE_APACHE-2.0 new file mode 120000 index 000000000000..1f7a8da6ec1b --- /dev/null +++ b/core/tauri/tests/restart/LICENSE_APACHE-2.0 @@ -0,0 +1 @@ +../../../../LICENSE_APACHE-2.0 \ No newline at end of file diff --git a/core/tauri/tests/restart/LICENSE_MIT b/core/tauri/tests/restart/LICENSE_MIT new file mode 120000 index 000000000000..dd01abfbba9d --- /dev/null +++ b/core/tauri/tests/restart/LICENSE_MIT @@ -0,0 +1 @@ +../../../../LICENSE_MIT \ No newline at end of file diff --git a/core/tauri/tests/restart/src/main.rs b/core/tauri/tests/restart/src/main.rs new file mode 100644 index 000000000000..79fe1bf2f4d0 --- /dev/null +++ b/core/tauri/tests/restart/src/main.rs @@ -0,0 +1,24 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +fn main() { + let mut argv = std::env::args(); + let argc = argv.len(); + if argc == 0 || argc > 2 { + panic!("restart test binary expect either no arguments or `restart`.") + } + + println!( + "{}", + tauri::api::process::current_binary(&Default::default()) + .expect("tauri::api::process::current_binary could not resolve") + .display() + ); + + match argv.nth(1).as_deref() { + Some("restart") => tauri::api::process::restart(&Default::default()), + Some(invalid) => panic!("only argument `restart` is allowed, {} is invalid", invalid), + None => {} + }; +} diff --git a/docs/api/cli.md b/docs/api/cli.md deleted file mode 100644 index dc776052ea6f..000000000000 --- a/docs/api/cli.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: cli -title: CLI ---- - -import Command from '@theme/Command' -import Alert from '@theme/Alert' - - -The tauri.js cli is composed in TypeScript and published as JavaScript. - -## `info` - - - -``` - Description - Returns the known state of tauri dependencies and configuration -``` - -It shows a concise list of information about the environment, Rust, Node.js and their versions as well as some relevant configurations. - - -This command is pretty helpful when you need to have a quick overview of your application. When requesting some help, it can be useful that you share this report with us. - - -## `init` - - - -``` - Description - Inits the Tauri template. If Tauri cannot find the src-tauri/tauri.conf.json - it will create one. - Usage - $ tauri init - Options - --help, -h Displays this message - --force, -f Force init to overwrite [conf|template|all] - --log, -l Logging [boolean] - --directory, -d Set target directory for init - --tauriPath, -t Path of the Tauri project to use (relative to the cwd) -``` - -## `dev` - - - -``` - Description - Tauri dev. - Usage - $ tauri dev - Options - --help, -h Displays this message -``` - -This command will open the WebView in development mode. It makes use of the `build.devPath` property from your `src-tauri/tauri.conf.json` file. - -If you have entered a command to the `build.beforeDevCommand` property, this one will be executed before the `dev` command. - -See more about the configuration.

- - - -If you're not using `build.beforeDevCommand`, make sure your `build.devPath` is correct and, if using a development server, that it's started before using this command. - - -## `deps` - - - -```sh - Description - Tauri dependency management script - Usage - $ tauri deps [install|update] -``` - - -## `build` - - - -``` - Description - Tauri build. - Usage - $ tauri build - Options - --help, -h Displays this message - --debug, -d Build a tauri app with debugging -``` - -This command will bundle your application, either in production mode or debug mode if you used the `--debug` flag. It makes use of the `build.distDir` property from your `src-tauri/tauri.conf.json` file. - -If you have entered a command to the `build.beforeBuildCommand` property, this one will be executed before the `build` command. - -See more about the configuration. - -## `icon` - - - -``` - Description - Create all the icons you need for your Tauri app. - - Usage - $ tauri icon - - Options - --help, -h Displays this message - --log, -l Logging [boolean] - --icon, -i Source icon (png, 1240x1240 with transparency) - --target, -t Target folder (default: 'src-tauri/icons') - --compression, -c Compression type [pngquant|optipng|zopfli] -``` - -This command will generate a set of icons, based on the source icon you've entered. - -## `version` - - - -``` - Description - Returns the current version of tauri -``` - -This command will show the current version of Tauri. - -## CLI usage - -See more about the usage through this [complete guide](/docs/usage/development/integration). - diff --git a/docs/api/config.md b/docs/api/config.md deleted file mode 100644 index bdee120e5902..000000000000 --- a/docs/api/config.md +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: Configuration ---- - -import Properties from '@theme/Properties' -import Array from '@theme/Array' -import Alert from '@theme/Alert' - -The `tauri.conf.json` is a file generated by the `tauri init` command (see here) that lives in your Tauri application source directory (src-tauri). - -Once generated, you may modify it at will to customize your Tauri application. - -# Platform-specific configuration - -In addition to the JSON defined on the `tauri.conf.json` file, Tauri reads a platform-specific configuration on `tauri.linux.conf.json`, `tauri.windows.conf.json` and `tauri.macos.conf.json` and merges it with the main `tauri.conf.json` configuration. - -# Configuration structure - -`tauri.conf.json` is composed of the following properties: - -## `build` - - - The target directory must contain an index.html file. -`}, -{property: "devPath", type: "string", description: `Can be a path to a folder (either absolute or relative to tauri.conf.json) or a URL (like a live reload server).`}, -{property: "beforeDevCommand", optional: true, type: "string", description: `A command to run before starting Tauri in dev mode.`}, -{property: "beforeBuildCommand", optional: true, type: "string", description: `A command to run before starting Tauri in build mode.`}, -{property: "withGlobalTauri", optional: true, type: "boolean", description: "Enables the API injection to the window.__TAURI__ object. Useful if you're using Vanilla JS instead of importing the API using Rollup or Webpack. Reduces the command security since any external code can access it, so be careful with XSS attacks."} -]}/> - -```js title=Example -"build": { - "distDir": "../dist", - "devPath": "http://localhost:4000", - "beforeDevCommand": "npm run dev", - "beforeBuildCommand": "npm run build", - "withGlobalTauri": false -} -``` - -## `package` - - - -## `tauri` - - - Any leading hyphen will be stripped, and only the first non hyphen character will be used as the short version. - ` }, - { property: "name", type: "string", description: `The unique argument name.` }, - { property: "description", optional: true, type: "string", description: `The argument description which will be shown on the help information. Typically, this is a short (one line) description of the arg.` }, - { property: "longDescription", optional: true, type: "string", description: `The argument long description which will be shown on the help information. - Typically, this a more detailed (multi-line) message that describes the argument` }, - { property: "takesValue", optional: true, type: "boolean", description: `Specifies that the argument takes a value at runtime. - ` - }, - { property: "index", type: "number", optional: true, description: `The positional argument index, starting at 1. - ` - }, - { property: "multiple", optional: true, type: "boolean", description: `Specifies that the argument may appear more than once. - For flags, this results in the number of occurrences of the flag being recorded. For example -ddd or -d -d -d would count as three occurrences. - For options, there is a distinct difference in multiple occurrences vs multiple values. For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences.` }, - { property: "possibleValues", optional: true, type: "string[]", description: `Specifies a list of possible values for this argument. At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.` }, - { property: "minValues", optional: true, type: "number", description: `Specifies the minimum number of values for this argument. - For example, if you had a -f <file> argument where you wanted at least 2 "files" you would set minValues: 2, and this argument would be satisfied if the user provided, 2 or more values.` }, - { property: "maxValues", optional: true, type: "number", description: `Specifies the maximum number of values for this argument. - For example, if you had a -f <file> argument where you wanted up to 3 "files" you would set max_values: 3, and this argument would be satisfied if the user provided, 1, 2, or 3 values.` }, - { property: "required", optional: true, type: "boolean", description: `Sets whether or not the argument is required by default. - "required by default" means it is required, when no other conflicting rules have been evaluated - conflicting rules take precedence over being required.` }, - { property: "requiredUnless", optional: true, type: "string", description: `Sets an arg that overrides this arg's required setting.
- i.e. this arg will be required unless this other argument is present.` }, - { property: "requiredUnlessAll", optional: true, type: "string[]", description: `Sets args that override this arg's required setting.
- i.e. this arg will be required unless all these other arguments are present.` }, - { property: "requiredUnlessOne", optional: true, type: "string[]", description: `Sets args that override this arg's required setting.
- i.e. this arg will be required unless at least one of these other arguments are present.` }, - { property: "conflictsWith", optional: true, type: "string", description: `Sets a conflicting argument by name - i.e. when using this argument, the following argument can't be present and vice versa.` }, - { property: "conflictsWithAll", optional: true, type: "string", description: `The same as "conflictsWith" but allows specifying multiple two-way conflicts per argument.` }, - { property: "requires", optional: true, type: "string", description: `Sets an argument by name that is required when this one is present.
- i.e. when using this argument, the following argument must be present.` }, - { property: "requiresAll", optional: true, type: "string[]", description: `Sets multiple arguments by names that are required when this one is present.
- i.e. when using this argument, the following arguments must be present.` }, - { property: "requiresIf", optional: true, type: "[string, string]", description: `Allows a conditional requirement with the signature [arg: string, value: string]. - - ` }, - { property: "requiredIf", optional: true, type: "[string, string]", description: `Allows specifying that an argument is required conditionally with the signature [arg: string, value: string]. - - ` }, - { property: "requireEquals", optional: true, type: "boolean", description: `Requires that options use the --option=val syntax.
- i.e. an equals between the option and associated value.` }, - ]} /> }, - { property: "description", optional: true, type: "string", description: `Command description which will be shown on the help information.` }, - { property: "longDescription", optional: true, type: "string", description: `Command long description which will be shown on the help information.` }, - { property: "beforeHelp", optional: true, type: "string", description: `Adds additional help information to be displayed in addition to auto-generated help.
- This information is displayed before the auto-generated help information.
- This is often used for header information.` }, - { property: "afterHelp", optional: true, type: "string", description: `Adds additional help information to be displayed in addition to auto-generated help.
- This information is displayed after the auto-generated help information.
- This is often used to describe how to use the arguments, or caveats to be noted.` }, - { property: "subcommands", optional: true, type: "{ [name: string]: CliConfig }", description: `List of subcommands of this command.
- Subcommands are effectively sub-apps, because they can contain their own arguments, subcommands, usage, etc.
- They also function just like the app command, in that they get their own auto generated help and usage.` }, - ]} /> - }, - { - property: "bundle", type: "object", - child: cargo build.` }, - { property: "targets", optional: true, type: "string | string[]", description: `An array of the bundles you want to generate; e.g. ["deb", "app", "msi", "appimage", "dmg"] or the string 'all' to make every supported bundle. By default we bundle everything your target supports (app/dmg on mac, deb/appimage on linux, msi on windows).` }, - { property: "identifier", type: "string", description: `A string that uniquely identifies your application, in reverse-DNS form (for example, "com.example.appname" or "io.github.username.project"). For OS X and iOS, this is used as the bundle's CFBundleIdentifier value; for Windows, this is hashed to create an application GUID.` }, - { property: "icon", optional: true, type: "string[]", description: `A list of (relative to src-tauri) icon paths to use for your application bundle.` }, - { property: "resources", optional: true, type: "string[]", description: `A list of files or directories which will be copied to the resources section of the bundle. Globs are supported.` }, - { property: "externalBin", optional: true, type: "string[]", description: `A list of—either absolute or relative—paths to binaries to embed with your application. - ` }, - { property: "copyright", optional: true, type: "string", description: `A copyright string associated with your application.` }, - { property: "category", optional: true, type: "string", description: `What kind of application this is. - Should be one among the following list:
- Business, DeveloperTool, Education, Entertainment, Finance, Game, ActionGame, AdventureGame, ArcadeGame, BoardGame, CardGame, CasinoGame, DiceGame, EducationalGame, FamilyGame, KidsGame, MusicGame, PuzzleGame, RacingGame, RolePlayingGame, SimulationGame, SportsGame, StrategyGame, TriviaGame, WordGame, GraphicsAndDesign, HealthcareAndFitness, Lifestyle, Medical, Music, News, Photography, Productivity, Reference, SocialNetworking, Sports, Travel, Utility, Video, Weather. - ` }, - { property: "shortDescription", optional: true, type: "string", description: `A short description of your application.` }, - { property: "longDescription", optional: true, type: "string", description: `A longer, multi-line description of the application.` }, - { property: "deb", optional: true, type: "object", child: boostrapper script.` }, - { property: "files", optional: true, type: "{ [path: string]: string }", description: `The files to include on the package. See the debian guide.` }]} /> - }, - { property: "windows", optional: true, type: "object", child: - } - ]} /> - }, - { property: "macOS", optional: true, type: "object", child: boostrapper script.` }, - { property: "exceptionDomain", optional: true, type: "string", description: `Allows your application to communicate with the outside world. - - ` }, - { property: "signingIdentity", optional: true, type: "string", description: `Identity to use for code signing.` }, - { property: "entitlements", optional: true, type: "string", description: `Path to the entitlements file.` }, - ]} /> }, - ]} /> - }, - { - property: "allowlist", type: "object", - child: - }, - { - property: "window", optional: true, type: "object", child: - }, - { - property: "shell", optional: true, type: "object", child: - }, - { - property: "dialog", optional: true, type: "object", child: - }, - { - property: "http", optional: true, type: "object", child: - }, - { - property: "notification", optional: true, type: "object", child: - }, - { - property: "globalShortcut", optional: true, type: "object", child: - }, - { - property: "os", optional: true, type: "object", child: - }, - { - property: "path", optional: true, type: "object", child: - }, - ]} /> - }, - { - property: "windows", type: "WindowConfig[]", - child: - - }, - { - property: "security", type: "object", - child: - This is a really important part of the configuration since it helps you ensure your WebView is secured. See more on Mozilla. -` }, - ]} /> - }, -]} /> - - -
- - -Instead of launching the app directly, we configure the bundled app to run a script that tries to expose the environment variables to the app; without that you'll have trouble using system CLI apps like Node.js. - - -```js title=Example -"tauri": { - "cli": { - "description": "Tauri communication example", - "longDescription": null, - "beforeHelp": null, - "afterHelp": null, - "args": [{ - "short": "c", - "name": "config", - "takesValue": true, - "description": "Config path" - }, { - "short": "t", - "name": "theme", - "takesValue": true, - "description": "App theme", - "possibleValues": ["light", "dark", "system"] - }, { - "short": "v", - "name": "verbose", - "multipleOccurrences": true, - "description": "Verbosity level" - }], - "subcommands": { - "update": { - "description": "Updates the app", - "longDescription": null, - "beforeHelp": null, - "afterHelp": null, - "args": [{ - "short": "b", - "name": "background", - "description": "Update in background" - }], - "subcommands": null - } - } - }, - "bundle": { - "active": true, - "targets": ["deb"], - "identifier": "com.tauri.dev", - "icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"], - "resources": [], - "externalBin": [], - "copyright": "", - "category": "DeveloperTool", - "shortDescription": "", - "longDescription": "", - "deb": { - "depends": [] - }, - "macOS": { - "frameworks": [], - "minimumSystemVersion": "", - "exceptionDomain": "" - } - }, - "allowlist": { - "all": true - }, - "windows": [{ - "title": "Tauri App", - "width": 800, - "height": 600, - "resizable": true, - "fullscreen": false - }], - "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" - } -} -``` diff --git a/docs/getting-started/intro.md b/docs/getting-started/intro.md deleted file mode 100644 index 7c4c4bfc62a4..000000000000 --- a/docs/getting-started/intro.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Introduction ---- - -import OSList from '@theme/OSList' - -Welcome to Tauri! - -Tauri is a polyglot and generic system that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of [Rust](https://www.rust-lang.org/) tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. - -Anything that can be displayed on a website, can be displayed in a Tauri webview app! - -Developers are free to build the web front-end displayed in a Webview through Tauri with any web frameworks of their choice! -**Developers can even extend the default API** with their own functionality and bridge the Webview and Rust-based backend easily! - -The Architecture is more fully described in [Architecture](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md). - -This guide will help you create your first Tauri app. It should only take about 10 minutes, although it could take longer if you have a slower internet connection. - -If you find an error or something unclear, or would like to propose an improvement, you have several options: - -1. Open an issue on our [Github Repo](https://github.com/tauri-apps/tauri-docs) -2. Visit our [Discord server](https://discord.gg/tauri) and raise your concern -3. Request to join the education working group on Discord to gain access to its discussion channel - -## Steps - -1. Install and configure system prerequisites -2. Create a web app with your frontend framework of choice -3. Use the Tauri CLI to setup Tauri in your app -4. Write native Rust code to add functionality or improve performance (totally optional) -5. Use `tauri dev` to develop your app with features like hot module reloading and webview devtools -6. Use `tauri build` to package your app into a tiny installer - -### Setting up Your Environment - -Before creating an app, you'll have to install and configure some developer tools. This guide assumes that you know what the command line is, how to install packages on your operating system, and generally know your way around the development side of computing. - -Follow the platform-specific guides to get started: - - - -After that, you'll be ready to [add Tauri to your project!](/docs/usage/development/integration) diff --git a/docs/getting-started/setup-linux.md b/docs/getting-started/setup-linux.md deleted file mode 100644 index c350718f9543..000000000000 --- a/docs/getting-started/setup-linux.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: Setup for Linux ---- - -import Alert from '@theme/Alert' -import Icon from '@theme/Icon' -import { Intro } from '@theme/SetupDocs' -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - - -## 1. System Dependencies  - - - - -```sh -$ sudo apt update && sudo apt install libwebkit2gtk-4.0-dev \ - build-essential \ - curl \ - wget \ - libssl-dev \ - libgtk-3-dev \ - libappindicator3-dev \ - patchelf \ - librsvg2-dev -``` - - - - -```sh -$ sudo pacman -Syy && sudo pacman -S webkit2gtk \ - base-devel \ - curl \ - wget \ - openssl \ - appmenu-gtk-module \ - gtk3 \ - libappindicator-gtk3 \ - patchelf \ - librsvg \ - libvips -``` - - - - -```sh -$ sudo dnf check-update && sudo dnf install webkit2gtk3-devel.x86_64 \ - openssl-devel \ - curl \ - wget \ - libappindicator-gtk3 \ # - patchelf \ - librsvg2-devel \ - && sudo dnf group install "C Development Tools and Libraries" -``` - - - - -### Optional dependencies: - -- `libappindicator`: needed to use the system tray feature. -- `patchelf` and `librsvg`: needed to bundle `AppImage`. - -## 2. Node.js Runtime and Package Manager  - -### Node.js (npm included) - -We recommend using nvm to manage your Node.js runtime. It allows you to easily switch versions and update Node.js. - -```sh -$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash -``` - - -We have audited this bash script, and it does what it says it is supposed to do. Nevertheless, before blindly curl-bashing a script, it is always wise to look at it first. Here is the file as a mere download link. - - -Once nvm is installed, close and reopen your terminal, then install the latest version of Node.js and npm: - -```sh -$ nvm install node --latest-npm -$ nvm use node -``` - -If you have any problems with nvm, please consult their project readme. - -### Optional Node.js Package Manager - -You may want to use an alternative to npm: - -- Yarn, is preferred by Tauri's team -- pnpm - -## 3. Rustc and Cargo Package Manager  - -The following command will install rustup, the official installer for Rust. - -```bash -$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` - - -We have audited this bash script, and it does what it says it is supposed to do. Nevertheless, before blindly curl-bashing a script, it is always wise to look at it first. Here is the file as a mere download link. - - -To make sure that Rust has been installed successfully, run the following command: - -```sh -$ rustc --version -latest update on 2019-12-19, rust version 1.40.0 -``` - -You may need to restart your terminal if the command does not work. - -## 4. For Windows Subsystem for Linux (WSL) Users  - -In order to run a graphical application with WSL, you need to download **one** of these X servers: Xming, Cygwin X, and vcXsrv. -Since vcXsrv has been used internally, it's the one we recommend to install. - -### WSL Version 1 - -Open the X server and then run `export DISPLAY=:0` in the terminal. You should now be able to run any graphical application via the terminal. - -### WSL Version 2 - -You'll need to run a command that is slightly more complex than WSL 1: `export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0` and you need to add `-ac` to the X server as an argument. Note: if for some reason this command doesn't work you can use an alternative command such as: `export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | sed 's/.* //g'):0` or you can manually find the Address using `cat /etc/resolve.conf | grep nameserver`. - - - -Don't forget that you'll have to use the "export" command anytime you want to use a graphical application, for each newly opened terminal. - -You can download some examples to try with `sudo apt-get install x11-apps`. xeyes is always a good one. It can be handy when troubleshooting WSL issues. - - -## Continue - -Now that you have set up the Linux-specific dependencies for Tauri, learn how to [add Tauri to your project](/docs/usage/development/integration). diff --git a/docs/getting-started/setup-macos.md b/docs/getting-started/setup-macos.md deleted file mode 100644 index b012675f7203..000000000000 --- a/docs/getting-started/setup-macos.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Setup for macOS ---- - -import Alert from '@theme/Alert' -import { Intro } from '@theme/SetupDocs' -import Icon from '@theme/Icon' - - - -## 1. System Dependencies  - - -You will need to have Homebrew installed to run the following command. - -```sh -$ brew install gcc -``` - -You will also need to make sure `xcode` is installed. - -```sh -$ xcode-select --install -``` - -## 2. Node.js Runtime and Package Manager  - -### Node.js (npm included) - -We recommend using nvm to manage your Node.js runtime. It allows you to easily switch versions and update Node.js. - -```sh -$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash -``` - - -We have audited this bash script, and it does what it says it is supposed to do. Nevertheless, before blindly curl-bashing a script, it is always wise to look at it first. Here is the file as a mere download link. - - -Once nvm is installed, close and reopen your terminal, then install the latest version of Node.js and npm: - -```sh -$ nvm install node --latest-npm -$ nvm use node -``` - -If you have any problems with nvm, please consult their project readme. - -### Optional Node.js Package Manager - -You may want to use an alternative to npm: - -- Yarn, is preferred by Tauri's team -- pnpm - -## 3. Rustc and Cargo Package Manager  - -The following command will install rustup, the official installer for Rust. - -``` -$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` - - -We have audited this bash script, and it does what it says it is supposed to do. Nevertheless, before blindly curl-bashing a script, it is always wise to look at it first. Here is the file as a mere download link. - - -To make sure that Rust has been installed successfully, run the following command: - -```sh -$ rustc --version -latest update on 2019-12-19, rust version 1.40.0 -``` - -You may need to restart your terminal if the command does not work. - -## Continue - -Now that you have set up the macOS-specific dependencies for Tauri, learn how to [add Tauri to your project](/docs/usage/development/integration). diff --git a/docs/getting-started/setup-windows.md b/docs/getting-started/setup-windows.md deleted file mode 100644 index 171f40ab8f76..000000000000 --- a/docs/getting-started/setup-windows.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: Setup for Windows ---- - -import Alert from '@theme/Alert' -import Icon from '@theme/Icon' -import { Intro } from '@theme/SetupDocs' - - - -For those using the Windows Subsystem for Linux (WSL) please refer to our [Linux specific instructions](/docs/getting-started/setup-linux) instead. - - - - -## 1. System Dependencies  - -You'll need to install Microsoft Visual Studio C++ build tools. Download the installer here, and then run it. When it asks you what packages you would like to install, select C++ Build Tools. - - -This is a big download (over 1GB) and takes the most time, so go grab a coffee. - - - -You may need to uninstall the 2017 version of the build tools if you have them. There are reports of Tauri not working with both the 2017 and 2019 versions installed. - - -## 2. Node.js Runtime and Package Manager  - -### Node.js (npm included) - -We recommend using nvm-windows to manage your Node.js runtime. It allows you to easily switch versions and update Node.js. - -Then run the following from an Administrative PowerShell and press Y when prompted: - -```powershell -# BE SURE YOU ARE IN AN ADMINISTRATIVE PowerShell! -nvm install latest -nvm use {{latest}} # Replace with your latest downloaded version -``` - -This will install the most recent version of Node.js with npm. - -### Optional Node.js Package Manager - -You may want to use an alternative to npm: - -- Yarn, is preferred by Tauri's team -- pnpm - -## 3. Rustc and Cargo Package Manager  - -Now you will need to install Rust. The easiest way to do this is to use rustup, the official installer. - -- 64-bit download link -- 32-bit download link - -Download and install the proper variant for your computer's architecture. - -## 4. Install WebView2 - - -WebView2 is pre-installed in Windows 11. - - -Finally, you will need to install WebView2. The best way to do this is to download and run the Evergreen Bootstrapper from [this page](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section). - -## Continue - -Now that you have set up the Windows-specific dependencies for Tauri, learn how to [add Tauri to your project](/docs/usage/development/integration). diff --git a/docs/sidebar.json b/docs/sidebar.json deleted file mode 100644 index 36df2441f8c8..000000000000 --- a/docs/sidebar.json +++ /dev/null @@ -1,123 +0,0 @@ -[ - { - "label": "Getting started", - "type": "category", - "items": [ - "getting-started/intro", - "getting-started/setup-linux", - "getting-started/setup-macos", - "getting-started/setup-windows" - ] - }, - { - "label": "Usage", - "type": "category", - "items": [ - "usage/intro", - { - "label": "Development", - "type": "category", - "items": [ - "usage/development/integration", - "usage/development/development", - "usage/development/debugging", - "usage/development/publishing", - "usage/development/updating" - ] - }, - { - "label": "Patterns", - "type": "category", - "items": [ - "usage/patterns/about-patterns", - "usage/patterns/hermit", - "usage/patterns/bridge", - "usage/patterns/cloudish", - "usage/patterns/cloudbridge", - "usage/patterns/lockdown", - "usage/patterns/multiwin", - "usage/patterns/glui" - ] - }, - { - "label": "Guides", - "type": "category", - "items": [ - "usage/guides/migration", - { - "label": "Bundler", - "type": "category", - "items": [ - "usage/guides/bundler/introduction", - "usage/guides/bundler/anti-bloat", - "usage/guides/bundler/sidecar", - "usage/guides/bundler/debian" - ] - }, - "usage/guides/cli", - "usage/guides/command", - "usage/guides/events", - "usage/guides/plugin", - "usage/guides/updater", - { - "label": "Visual", - "type": "category", - "items": [ - "usage/guides/visual/icons", - "usage/guides/visual/splashscreen", - "usage/guides/visual/window-customization", - "usage/guides/visual/menu", - "usage/guides/visual/system-tray" - ] - }, - { - "label": "WebDriver Testing", - "type": "category", - "items": [ - "usage/guides/webdriver/introduction", - { - "label": "Example Application", - "type": "category", - "items": [ - "usage/guides/webdriver/example/setup", - "usage/guides/webdriver/example/webdriverio", - "usage/guides/webdriver/example/selenium" - ] - }, - "usage/guides/webdriver/ci" - ] - } - ] - }, - { - "label": "CI/CD", - "type": "category", - "items": ["usage/ci-cd/workflow", "usage/ci-cd/cross-platform"] - }, - "usage/contributor-guide" - ] - }, - { - "label": "Tips", - "type": "category", - "items": [] - }, - { - "label": "API", - "type": "category", - "items": [ - "api/config", - "api/cli", - { - "label": "Rust", - "type": "category", - "items": [] - }, - { - "label": "JavaScript", - "type": "category", - "items": [] - } - ] - } -] diff --git a/docs/usage/ci-cd/cross-platform.md b/docs/usage/ci-cd/cross-platform.md deleted file mode 100644 index fc7ada90f18b..000000000000 --- a/docs/usage/ci-cd/cross-platform.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Cross-Platform Compilation ---- - -How to use GH Action for Building: a glance at Tauri Action. \ No newline at end of file diff --git a/docs/usage/ci-cd/signing-macos.md b/docs/usage/ci-cd/signing-macos.md deleted file mode 100644 index 3958bc8daa34..000000000000 --- a/docs/usage/ci-cd/signing-macos.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Signing for macOS ---- - -Signing for macOS \ No newline at end of file diff --git a/docs/usage/ci-cd/workflow.md b/docs/usage/ci-cd/workflow.md deleted file mode 100644 index 0392383c4dbd..000000000000 --- a/docs/usage/ci-cd/workflow.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: workflow -title: Workflow ---- - -## Continuous Integration - -Github Actions has two triggers of which we make heavy use: `push` and `pull_request`. Every commit that made to the repo is a `push`. When you open a pull request from a branch (call it `great_feature`) to another branch (our working branch, `dev`), each commit to `great_feature` would possibly trigger both of these events. We can use a filter to focus on the events we care about though. In our workflows, we only PR (pull request) the `dev` and `master` branches. This means that if we filter to only the `dev` and `master` branches on commit, we will only run that workflow when we _merge_ a PR. A merged PR typically only occurs once a day or less so this will be a good fit for the longer running tests, e.g. the smoke tests in our case. Below is how that might look. - -Unit tests: - -```yml -# these run fast so we can have them run on any commit -name: unit tests -on: - pull_request: - push: - branches: - - dev - - master -``` - -Smoke tests: - -```yml -# these run slower so we run only on merges to dev or master branch -name: smoke tests -on: - push: - branches: - - dev - - master -``` - -Tauri operates off the `dev` branch as default, and merges to `master` for release. With these Github Actions set up, we will run the unit tests on every commit to an open PR (see `pull_request`). When that PR is merged into `dev`, we will run both the unit tests and the smoke tests. - -## Continuous Deployment - -### Introduction to immutable checksum - -It is not only possible, but trivial to modify release notes and artifacts after it has been published on Github. While there are very valid reasons for doing this, it is not exactly a totally trustworthy method - i.e. you have no guarantee that what you are reading is really reflective of the underlying truth or the tarballs. It is technically possible to change downloads over the wire or in the box or change checksums in targeted attacks. What we are seeking to accomplish is a best case scenario where: - -1. Human error is reduced to a minimum, but humans are still integral in the actual release -2. Machine built assets, changelogs and attached security audits are verifiable with checksums that are published in an immutable, globally available store. - -To this end we fashioned a workflow shown below. As it stands now, we have #3 through #6 implemented. We manually do #2 which then feeds into #3 and kicks off the rest of the automatic workflow. - -1. a human pushes to dev through a pull request (can happen any number of times) - - pull request includes a changeset file describing the change and required version bump -2. a pull request is created (or updated) to include the change and version bump - - this pull request stays open and will be force pushed until it gets merged (and published) - - increase the version number based on changesets - - delete all changeset files -3. a codeowner merges the publish PR to dev (no direct push permissible for anyone) - - all tests (unit, e2e, smoke tests) are run on the PR - - failures prevent the publish so they must pass before merge -4. merge to dev triggers release sequence - - changes are squashed and a PR is opened against master -5. when PR to master is merged... - - vulnerability audit (crates and yarn) and output saved - - checksums and metadata and output saved - - packages are published on npm/cargo, tarball/zip created - - release is created for each package that had updates (if version isn't changed, build skips the publish steps) - - output from audit/checksums is piped into the release body - - tarball / zip attached to release - - async process to publish to IOTA tangle (feeless) via release tag [note: still have things to resolve here] -6. release is complete - - master has updated code and tagged - - GitHub release has tarballs, checksums, and changelog (may have multiple releases if more than one package published) [note: is part of step 2 and is not yet implemented] - -### Next Steps - -Next steps may include transferring and publishing the built assets to additional places: - -1. Tauri's private verdaccio -2. IPFS -3. PureOS Gitlab -4. GitHub Packages - -We can also do some interesting things like signing our releases, including a hash in the release and/or even publishing this information on a blockchain that it can be easily verified. Publishing on the blockchain is another avenue to increase the confidence that what is seen on GitHub matches what you have downloaded. The IOTA foundation created a Github Action which will publish a release to their blockchain. This has shown promise, but he gave a couple errors to tackle still. diff --git a/docs/usage/contributor-guide.md b/docs/usage/contributor-guide.md deleted file mode 100644 index f6397d06c792..000000000000 --- a/docs/usage/contributor-guide.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Contributor Guide ---- - -todo: make this friendlier and more complete - -Tauri is a polyglot system that uses: - -- git -- Node.js -- Rust -- GitHub actions - -It can be developed on macOS, Linux and Windows. - -## Contribution Flow - -1. File an Issue -2. Fork the Repository -3. Make Your Changes -4. Make a PR - -### A Note About Contributions to the Rust Libraries - -When contributing to the Rust libraries `tauri`, `tauri-api`, and `tauri-updater`; you will want to setup an environment for RLS (the Rust Language Server). In the Tauri root directory, there is a `.scripts` folder that contains a set of scripts to automate adding a couple temporary environment variables to your shell/terminal. These environment variables point to directories in the test fixture which will prevent RLS from crashing on compile-time. This is a necessary step for setting up a development environment for Tauri's Rust libraries. - -##### _Example Instructions_ - -1. Navigate to the Tauri Root directory. -2. Execute a script based on your Operating System from this folder: `.scripts/init_env.bat` for Windows Cmd, `.scripts/init_env.ps1` for Windows Powershell, `. .scripts/init_env.sh` for Linux/macOS bash (note the first `.` in this command). -3. Open your text editor/IDE from this shell/terminal. - -## Hands On Example - -Let's make a new example. That's a great way to learn. We are going to assume you are on a nixy type of environment like Linux or macOS and have all of your development dependencies like rust and node already sorted out. - -```sh -git clone git@github.com:tauri-apps/tauri.git -cd tauri/cli/tauri.js -yarn -mkdir ../../examples/vanillajs && cd "$_" -``` - -```json - "tauri:source": "node ../../../cli/tauri.js/bin/tauri", -``` - -```ini - [dependencies.tauri] - path = "../../../../core/tauri" - features = [ "all-api" ] -``` diff --git a/docs/usage/development/debugging.md b/docs/usage/development/debugging.md deleted file mode 100644 index d3626e841b05..000000000000 --- a/docs/usage/development/debugging.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: App Debugging -sidebar_label: 'App Debugging (3/4)' ---- - -import Alert from '@theme/Alert' -import Command from '@theme/Command' - -With all the moving pieces in Tauri, you may run into a problem that requires debugging. There are a handful of locations where error details are printed, and Tauri includes some tools to make the debugging process easier. - -## Rust Console - -When you run a Tauri app in development mode you will have a Rust console available. This is in the terminal where you ran e.g. `tauri dev`. You can use the following code to print something to that console from within a Rust file: - -```rust -println!("Message from Rust: {}", msg); -``` - -Sometimes you may have an error in your Rust code, and the Rust compiler can give you lots of information. If, for example, `tauri dev` crashes, you can rerun it like this on Linux and macOS: - -```sh -RUST_DEBUG=1 tauri dev -``` - -or like this on MS Windows: - -```sh -set RUST_DEBUG=1 -tauri dev -``` - -This will give you a granular stack trace. Generally speaking, the Rust compiler will help you by -giving you detailed information about the issue, such as: - -``` -error[E0425]: cannot find value `sun` in this scope - --> src/main.rs:11:5 - | -11 | sun += i.to_string().parse::().unwrap(); - | ^^^ help: a local variable with a similar name exists: `sum` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0425`. -``` - -## WebView JS Console - -Right click in the WebView, and choose `Inspect Element`. This will open up a web-inspector similar to the Chrome or Firefox dev tools you are used to. - -## Create a Debug Build - -There are cases where you might need to inspect the JS console in the final bundle, so Tauri provides a simple command to create a debugging bundle: - - - -Like the normal build and dev processes, the first time you run this it will take more time than subsequent runs. The final bundled app will be placed in `src-tauri/target/debug/bundle`. That app will ship with the development console enabled. - -## Run Your App From the Terminal - -You can also run a built app from the terminal, which will also give you the Rust compiler notes (in case of errors) or your `println` messages. Just find the file `src-tauri/target/(release|debug)/[app name]` and either double click it (but be warned, the terminal will close on errors) or just run it in directly in your console. diff --git a/docs/usage/development/development.md b/docs/usage/development/development.md deleted file mode 100644 index 5e717bd31e11..000000000000 --- a/docs/usage/development/development.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: App Development -sidebar_label: 'App Development (2/4)' ---- - -import Alert from '@theme/Alert' -import Command from '@theme/Command' - -### 1. Start Your Devserver - -Now that you have everything setup, you should start your application development server provided by your UI framework or bundler (assuming you're using one, of course). - - -Every framework has its own development tooling. It is outside of the scope of this document to treat them all or keep them up to date. - - -### 2. Start Tauri Development Window - - - -The first time you run this command, it will take several minutes for the Rust package manager to download and build all the required packages. Since they are cached, subsequent builds will be much faster, as only your code will need rebuilding. - -Once Rust has finished building, the webview will open and it should display your web app. You can make changes to your web app, and if your tooling enables it, the webview should update automatically just like a browser. When you make changes to your Rust files, they will be rebuilt automatically and your app will restart. - - - In your project repository, you SHOULD commit the "src-tauri/Cargo.toml" to git because you want it to be deterministic. You SHOULD NOT commit the "src-tauri/target" folder or any of its contents. - diff --git a/docs/usage/development/integration.md b/docs/usage/development/integration.md deleted file mode 100644 index 653056981d2d..000000000000 --- a/docs/usage/development/integration.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Tauri Integration -sidebar_label: 'Tauri Integration (1/4)' ---- - -import Alert from '@theme/Alert' -import Command from '@theme/Command' -import Link from '@docusaurus/Link' - - - You must have completed all the steps required for setting up the development environment on your machine. If you haven't done this yet, please see the setup page for your operating system. - - -### 1. Install Tauri CLI Package as a Dev Dependency: - -```bash -cd project-folder - -# Not required if you already have a package.json: -# yarn init -# OR -# npm init - -yarn add -D @tauri-apps/cli -# OR -npm install -D @tauri-apps/cli -``` - - - You can install Tauri as both a local and a global dependency, but we recommend installing it locally. - - -If you decide to use Tauri as a local package with npm (not yarn), you will have to define a custom script to your package.json: - -```js title=package.json -{ - // This content is just a sample - "scripts": { - "tauri": "tauri" - } -} -``` - -### 1. Install Tauri API Package as a Dependency (optional): - -The `@tauri-apps/api` package is recommended for projects using ES modules or modern build tools such as Webpack or Vite. It is the most secure way to access the Tauri APIs. - -```bash -yarn add @tauri-apps/api -# OR -npm install @tauri-apps/api -``` - -### 2. Initialize Tauri in Your App - - - -This command will place a new folder in your current working directory, `src-tauri`. - -```sh -└── src-tauri - ├── .gitignore - ├── Cargo.toml - ├── rustfmt.toml - ├── tauri.conf.json - ├── icons - │ ├── 128x128.png - │ ├── 128x128@2x.png - │ ├── 32x32.png - │ ├── Square107x107Logo.png - │ ├── Square142x142Logo.png - │ ├── Square150x150Logo.png - │ ├── Square284x284Logo.png - │ ├── Square30x30Logo.png - │ ├── Square310x310Logo.png - │ ├── Square44x44Logo.png - │ ├── Square71x71Logo.png - │ ├── Square89x89Logo.png - │ ├── StoreLogo.png - │ ├── icon.icns - │ ├── icon.ico - │ └── icon.png - └── src - ├── build.rs - ├── cmd.rs - └── main.rs -``` - -### 3. Check `tauri info` to Make Sure Everything Is Set up Properly: - - - -Which should return something like: - -``` -Operating System - Darwin(16.7.0) - darwin/x64 - -Node.js environment - Node.js - 12.16.3 - @tauri-apps/cli - 1.0.0-beta.2 - @tauri-apps/api - 1.0.0-beta.1 - -Global packages - npm - 6.14.4 - yarn - 1.22.4 - -Rust environment - rustc - 1.52.1 - cargo - 1.52.0 - -App directory structure -/node_modules -/src-tauri -/src -/public - -App - tauri.rs - 1.0.0-beta.1 - build-type - bundle - CSP - default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self' - distDir - ../public - devPath - ../public - framework - Svelte - bundler - Rollup -``` - -This information can be very helpful when triaging problems. - -### Patterns - -We've also defined prebuilt configurations called "Patterns". They may help you to customize Tauri to fit your needs. -[See more about patterns](/docs/usage/patterns/about-patterns). - -## Vue CLI Plugin Tauri - -If you are using Vue CLI, it is recommended to use the official [CLI plugin](https://github.com/tauri-apps/vue-cli-plugin-tauri). diff --git a/docs/usage/development/publishing.md b/docs/usage/development/publishing.md deleted file mode 100644 index 4eac134ed540..000000000000 --- a/docs/usage/development/publishing.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: App Publishing -sidebar_label: 'App Publishing (4/4)' ---- - -import Alert from '@theme/Alert' -import Command from '@theme/Command' - -### 1. Build Your Web App - -Now that you are ready to package your project, you will need to run your framework's or bundler's build command (assuming you're using one, of course). - - -Every framework has its own publishing tooling. It is outside of the scope of this document to treat them all or keep them up to date. - - -### 2. Bundle your application with Tauri - - - -This command will embed your web assets into a single binary with your Rust code. The binary itself will be located in `src-tauri/target/release/[app name]`, and installers will be located in `src-tauri/target/release/bundle/`. - -Like the `tauri dev` command, the first time you run this, it will take some time to collect the Rust crates and build everything - but on subsequent runs it will only need to rebuild your code, which is much quicker. diff --git a/docs/usage/development/updating.md b/docs/usage/development/updating.md deleted file mode 100644 index a2d3a687c486..000000000000 --- a/docs/usage/development/updating.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Updating ---- -import Alert from '@theme/Alert' - - - Especially during the alpha and beta phases, you are expected to keep all Tauri dependencies and toolchains up to date. There is no support for any versions other than latest. - - -## Automatic updates - -The Tauri JS CLI has a command to install and update all needed dependencies, just run `tauri deps install` or `tauri deps update`. - -## Manual updates - -### Update NPM Packages - -If you are using the `tauri` package: -```bash -$ yarn upgrade @tauri-apps/cli @tauri-apps/api --latest -$ npm install @tauri-apps/cli@latest @tauri-apps/api@latest -``` -You can also detect what the latest version of Tauri is on the command line, using: -- `npm outdated @tauri-apps/cli` -- `yarn outdated @tauri-apps/cli` - -Alternatively, if you are using the `vue-cli-plugin-tauri` approach: -```bash -$ yarn upgrade vue-cli-plugin-tauri --latest -$ npm install vue-cli-plugin-tauri@latest -``` - -### Update Cargo Packages -Go to `src-tauri/Cargo.toml` and change `tauri` to -`tauri = { version = "%version%" }` where `%version%` is the version number shown above. (You can just use the `MAJOR.MINOR`) version, like `0.9`. - -Then do the following: -```bash -$ cd src-tauri -$ cargo update -p tauri -``` -You can also run `cargo outdated -r tauri` to get direct information about the core library's latest version. diff --git a/docs/usage/guides/bundler/anti-bloat.md b/docs/usage/guides/bundler/anti-bloat.md deleted file mode 100644 index 7f50073f20ba..000000000000 --- a/docs/usage/guides/bundler/anti-bloat.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: Anti Bloat ---- - -import Alert from '@theme/Alert' - -The following links have tutorials on reducing the size of your installers: - -- https://github.com/RazrFalcon/cargo-bloat -- https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html -- https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections - -### Rust Compression Features - -Add this to your `src-tauri/Cargo.toml` - - [profile.release] - panic = "abort" - codegen-units = 1 - lto = true - incremental = false - opt-level = "s" - - - -There is also `opt-level = "z"` available to try to reduce the resulting binary size. `"s"` and `"z"` can sometimes be smaller than the other, so test it with your own application! - -We've seen smaller binary sizes from `"s"` for Tauri example applications, but real world applications can always differ. - - -#### Unstable Rust Compression Features - - -The following suggestions are all unstable features and require a nightly toolchain. See the Unstable Features documentation for more information of what this involves. - - -The following methods involve using unstable compiler features and require having a rust nightly toolchain installed. If you don't have the nightly toolchain + `rust-src` nightly component added, try the following: - - $ rustup toolchain install nightly - $ rustup component add rust-src --toolchain nightly - -The Rust Standard Library comes precompiled. You can instead apply the optimization options used for the rest of your binary + dependencies to the std with an unstable flag. This flag requires specifying your target, so know the target triple that you are targeting. - - $ cargo +nightly build --release -Z build-std --target x86_64-unknown-linux-gnu - -If you are using `panic = "abort"` in your release profile optimizations, then you need to make sure the `panic_abort` crate is compiled with std. Additionally, an extra std feature can be used to further reduce the binary size. The following applies both: - - $ cargo +nightly build --release -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-unknown-linux-gnu - -See the unstable documentation for more details about [`-Z build-std`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std) and [`-Z build-std-features`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std-features). - -### Stripping - -Binary size can easily be reduced by stripping out debugging information from binaries that ship to end users. This is not good for debuggable builds, but means good binary size savings for end user binaries. The easiest way is to use the famous `strip` utility to remove this debugging information. - - $ strip target/release/my_application - -See your local `strip` manpage for more information and flags that can be used to specify what information gets stripped out from the binary. - -### Allowlist config - -You can also reduce the application size with the `allowlist` config, and only enabling what you need. Sometimes this is useful with Tauri's [Bridge-Pattern](/docs/usage/patterns/bridge) or others, depending on needs. - -For example in `tauri.conf.json` file: - -```json -{ - "tauri": { - "allowlist": { - "all": false, - "fs": { - "writeFile": true, - "writeBinaryFile": true - }, - "shell": { - "execute": true - }, - "dialog": { - "save": true - } - } - } -} -``` - -### UPX - -UPX, **Ultimate Packer for eXecutables**, is a dinosaur amongst the binary packers. This 23-year old, well-maintained piece of kit is GPL-v2 licensed with a pretty liberal usage declaration. Our understanding of the licensing is that you can use it for any purposes (commercial or otherwise) without needing to change your license unless you modify the source code of UPX. - -Basically it compresses the binary and decompresses it at runtime. It should work for pretty much any binary type out there. Read more: https://github.com/upx/upx - - -You should know that this technique might flag your binary as a virus on Windows and macOS - so use at your own discretion, and as always validate with [Frida](https://frida.re/docs/home/) and do real distribution testing! - - -#### Usage on macOS - - $ brew install upx - $ yarn tauri build - $ upx --ultra-brute src-tauri/target/release/bundle/macos/app.app/Contents/macOS/app - Ultimate Packer for eXecutables - Copyright (C) 1996 - 2018 - UPX 3.95 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 26th 2018 - - File size Ratio Format Name - -------------------- ------ ----------- ----------- - 963140 -> 274448 28.50% macho/amd64 app diff --git a/docs/usage/guides/bundler/debian.md b/docs/usage/guides/bundler/debian.md deleted file mode 100644 index 5d581d2b96e0..000000000000 --- a/docs/usage/guides/bundler/debian.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Debian packages ---- - -import Alert from '@theme/Alert' - -Tauri allows your app to be packaged as a `.deb` (Debian package) file. - -# Bootstrapper - -Instead of launching the app directly, you can configure the bundled app to run a script that tries to expose the environment variables to the app; without that you'll have trouble using system programs because the `PATH` environment variable isn't correct. Enable it with the `useBootstrapper` config. - -# Custom files - -To include custom files to the debian package, you can configure a mapping on `tauri.conf.json > tauri > bundle > deb > files` as follows: - -```json -{ - "tauri": { - "bundle": { - "deb": { - "files": { - "/usr/lib/README.md": "../README.md", // copies the README.md file to /usr/lib/README.md - "usr/lib/assets": "../public/" // copies the entire public directory to /usr/lib/assets - } - } - } - } -} -``` - - -Each `files` object key is the path on the debian package, and the value is a path to a file or directory relative to the `tauri.conf.json` file. - diff --git a/docs/usage/guides/bundler/introduction.md b/docs/usage/guides/bundler/introduction.md deleted file mode 100644 index ba24668c624d..000000000000 --- a/docs/usage/guides/bundler/introduction.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Introduction ---- - -The Tauri Bundler is a Rust harness for compiling your binary, packaging assets, and preparing a final bundle. - -It will detect your operating system and build a bundle accordingly. It currently supports: - -- Linux: .deb, .appimage -- macOS: .app, .dmg -- Windows: .exe, .msi \ No newline at end of file diff --git a/docs/usage/guides/bundler/sidecar.md b/docs/usage/guides/bundler/sidecar.md deleted file mode 100644 index bc4b7997bad4..000000000000 --- a/docs/usage/guides/bundler/sidecar.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Sidecar (Embedding External Binaries) -sidebar_label: Sidecar ---- - -import Alert from '@theme/Alert' - -You may need to embed depending binaries in order to make your application work or to prevent users having to install additional dependencies (e.g. Node.js, Python, etc). - -To bundle the binaries of your choice, you can add the `externalBin` property to the `tauri > bundle` object in your `tauri.conf.json`. - -See more about tauri.conf.json configuration here. - -`externalBin` expects a list of strings targeting binaries either with absolute or relative paths. - -Here is a sample to illustrate the configuration, this is not a complete `tauri.conf.json` file: - -```json -{ - "tauri": { - "bundle": { - "externalBin": ["/absolute/path/to/app", "relative/path/to/binary", "bin/python"] - } - } -} -``` - -A binary with the same name and a `-$TARGET_TRIPLE` suffix must exist on the specified path. For instance, `"externalBin": ["bin/python"]` requires a `src-tauri/bin/python-x86_64-unknown-linux-gnu` executable on Linux. You can find the current platform's target triple running the following command: - -```bash -RUSTC_BOOTSTRAP=1 rustc -Z unstable-options --print target-spec-json -``` - -Here's a Node.js script to append the target triple to a binary: - -```javascript -const execa = require('execa') -const fs = require('fs') - -let extension = '' -if (process.platform === 'win32') { - extension = '.exe' -} - -async function main() { - const rustInfo = (await execa('rustc', ['-vV'])).stdout - const targetTriple = /host: (\S+)/g.exec(rustInfo)[1] - if (!targetTriple) { - console.error('Failed to determine platform target triple') - } - fs.renameSync( - `src-tauri/binaries/app${extension}`, - `src-tauri/binaries/app-${targetTriple}${extension}` - ) -} - -main().catch((e) => { - throw e -}) - -``` - -## Running the sidecar binary on JavaScript - -On the JavaScript code, import the `Command` class on the `shell` module and use the `sidecar` static method: - -```javascript -import { Command } from '@tauri-apps/api/shell' -// alternatively, use `window.__TAURI__.shell.Command` -// `my-sidecar` is the value specified on `tauri.conf.json > tauri > bundle > externalBin` -const command = Command.sidecar('my-sidecar') -const output = await command.execute() -``` - -## Running the sidecar binary on Rust - -On the Rust code, import the `Command` struct from the `tauri::api::process` module: - -```rust -let (mut rx, mut child) = Command::new_sidecar("my-sidecar") - .expect("failed to create `my-sidecar` binary command") - .spawn() - .expect("Failed to spawn sidecar"); - -tauri::async_runtime::spawn(async move { - // read events such as stdout - while let Some(event) = rx.recv().await { - if let CommandEvent::Stdout(line) = event { - window - .emit("message", Some(format!("'{}'", line))) - .expect("failed to emit event"); - // write to stdin - child.write("message from Rust\n".as_bytes()).unwrap(); - } - } -}); -``` - -## Using Node.js on a sidecar - -The Tauri [sidecar example](https://github.com/tauri-apps/tauri/tree/dev/examples/sidecar) demonstrates how to use the sidecar API to run a Node.js application on Tauri. -It compiles the Node.js code using [pkg](https://github.com/vercel/pkg) and uses the scripts above to run it. diff --git a/docs/usage/guides/cli.md b/docs/usage/guides/cli.md deleted file mode 100644 index f712c6a4c40c..000000000000 --- a/docs/usage/guides/cli.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: Make your own CLI ---- - -import Alert from '@theme/Alert' - -Tauri enables your app to have a CLI through clap, a robust command line argument parser. With a simple CLI definition in your `tauri.conf.json` file, you can define your interface and read its argument matches map on JavaScript and/or Rust. - -## Base Configuration - -Under `tauri.conf.json`, you have the following structure to configure the interface: - -```js title=src-tauri/tauri.conf.json -{ - "tauri": { - "cli": { - "description": "", // command description that's shown on help - "longDescription": "", // command long description that's shown on help - "beforeHelp": "", // content to show before the help text - "afterHelp": "", // content to show after the help text - "args": [], // list of arguments of the command, we'll explain it later - "subcommands": { - "subcommand-name": { - // configures a subcommand that is accessible - // with `$ ./app subcommand-name --arg1 --arg2 --etc` - // configuration as above, with "description", "args", etc. - } - } - } - } -} -``` - - - All JSON configurations here are just samples, many other fields have been omitted for the sake of clarity. - - -## Adding Arguments - -The `args` array represents the list of arguments accepted by its command or subcommand. You can find more details about the way to configure them here. - -### Positional Arguments - -A positional argument is identified by its position in the list of arguments. With the following configuration: - -```json title=src-tauri/tauri.conf.json:tauri.cli -{ - "args": [ - { - "name": "source", - "index": 1 - }, - { - "name": "destination", - "index": 2 - } - ] -} -``` - -Users can run your app as `$ ./app tauri.txt dest.txt` and the arg matches map will define `source` as `"tauri.txt"` and `destination` as `"dest.txt"`. - -### Named Arguments - -A named argument is a (key, value) pair where the key identifies the value. With the following configuration: - -```json title=src-tauri/tauri.conf.json:tauri.cli -{ - "args": [ - { - "name": "type", - "short": "t", - "takesValue": true, - "multiple": true, - "possibleValues": ["foo", "bar"] - } - ] -} -``` - -Users can run your app as `$ ./app --type foo bar`, `$ ./app -t foo -t bar` or `$ ./app --type=foo,bar` and the arg matches map will define `type` as `["foo", "bar"]`. - -### Flag Arguments - -A flag argument is a standalone key whose presence or absence provides information to your application. With the following configuration: - -```js title=src-tauri/tauri.conf.json:tauri.cli -{ - "args": [ - "name": "verbose", - "short": "v", - "multipleOccurrences": true - ] -} -``` - -Users can run your app as `$ ./app -v -v -v`, `$ ./app --verbose --verbose --verbose` or `$ ./app -vvv` and the arg matches map will define `verbose` as `true`, with `occurrences = 3`. - -## Subcommands - -Some CLI applications has additional interfaces as subcommands. For instance, the `git` CLI has `git branch`, `git commit` and `git push`. You can define additional nested interfaces with the `subcommands` array: - -```js title=src-tauri/tauri.conf.json:tauri -{ - "cli": { - ... - "subcommands": { - "branch": { - "args": [] - }, - "push": { - "args": [] - } - } - } -} -``` - -Its configuration is the same as the root application configuration, with the `description`, `longDescription`, `args`, etc. - -## Reading the matches - -### Rust - -```rust -use tauri::api::cli::get_matches; - -fn main() { - let context = tauri::generate_context!(); - let cli_config = context.config().tauri.cli.clone().unwrap(); - - match get_matches(&cli_config) { - // `matches` here is a Struct with { args, subcommand }. - // `args` is `HashMap` where `ArgData` is a struct with { value, occurances }. - // `subcommand` is `Option>` where `SubcommandMatches` is a struct with { name, matches }. - Ok(matches) => { - println!("{:?}", matches) - } - Err(_) => {} - }; - - tauri::Builder::default() - .run(context) - .expect("error while running tauri application"); -} -``` - -### JavaScript - -```js -import { getMatches } from '@tauri-apps/api/cli' - -getMatches().then((matches) => { - // do something with the { args, subcommand } matches -}) -``` - -## Complete documentation - -You can find more about the CLI configuration here. diff --git a/docs/usage/guides/command.md b/docs/usage/guides/command.md deleted file mode 100644 index dd21875b44a4..000000000000 --- a/docs/usage/guides/command.md +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: Create Rust Commands ---- - -import Alert from '@theme/Alert' - -Tauri provides a simple yet powerful "command" system for calling Rust functions from your web app. Commands can accept arguments and return values. They can also return errors and be `async`. - -## Basic Example - -Commands are defined in your `src-tauri/src/main.rs` file. To create a command, just add a function and annotate it with `#[tauri::command]`: - -```rust -#[tauri::command] -fn my_custom_command() { - println!("I was invoked from JS!"); -} -``` - -You will have to provide a list of your commands to the builder function like so: - -```rust -// Also in main.rs -fn main() { - tauri::Builder::default() - // This is where you pass in your commands - .invoke_handler(tauri::generate_handler![my_custom_command]) - .run(tauri::generate_context!()) - .expect("failed to run app"); -} -``` - -Now, you can invoke the command from your JS code: - -```js -// With the Tauri API npm package: -import { invoke } from '@tauri-apps/api/tauri' -// With the Tauri global script, enabled when `tauri.conf.json > build > withGlobalTauri` is set to true: -const invoke = window.__TAURI__.invoke - -// Invoke the command -invoke('my_custom_command') -``` - -## Passing Arguments - -Your command handlers can take arguments: - -```rust -#[tauri::command] -fn my_custom_command(invoke_message: String) { - println!("I was invoked from JS, with this message: {}", invoke_message); -} -``` - -Arguments should be passed as a JSON object with camelCase keys: - -```js -invoke('my_custom_command', { invokeMessage: 'Hello!' }) -``` - -Arguments can be of any type, as long as they implement [serde::Deserialize](https://serde.rs/derive.html). - -## Returning Data - -Command handlers can return data as well: - -```rust -#[tauri::command] -fn my_custom_command() -> String { - "Hello from Rust!".into() -} -``` - -The `invoke` function returns a promise that resolves with the returned value: - -```js -invoke('my_custom_command').then((message) => console.log(message)) -``` - -Returned data can be of any type, as long as it implements [Serde::Serialize](https://serde.rs/derive.html). - -## Error Handling - -If your handler could fail and needs to be able to return an error, have the function return a `Result`: - -```rust -#[tauri::command] -fn my_custom_command() -> Result { - // If something fails - Err("This failed!".into()) - // If it worked - Ok("This worked!".into()) -} -``` - -If the command returns an error, the promise will reject, otherwise it resolves: - -```js -invoke('my_custom_command') - .then((message) => console.log(message)) - .catch((error) => console.error(error)) -``` - -## Async Commands - - -Async commands are executed on a separate thread using the async runtime. -Commands without the async keyword are executed on the main thread, unless defined with #[tauri::command(async)]. - - -If your command needs to run asynchronously, simply declare it as `async`: - -```rust -#[tauri::command] -async fn my_custom_command() { - // Call another async function and wait for it to finish - let result = some_async_function().await; - println!("Result: {}", result); -} -``` - -Since invoking the command from JS already returns a promise, it works just like any other command: - -```js -invoke('my_custom_command').then(() => console.log('Completed!')) -``` - -## Accessing the Window in Commands - -Commands can access the `Window` instance that invoked the message: - -```rust -#[tauri::command] -async fn my_custom_command(window: tauri::Window) { - println!("Window: {}", window.label()); -} -``` - -## Accessing an AppHandle in Commands - -Commands can access an `AppHandle` instance: - -```rust -#[tauri::command] -async fn my_custom_command(app_handle: tauri::AppHandle) { - let app_dir = app_handle.path_resolver().app_dir(); - use tauri::GlobalShortcutManager; - app_handle.global_shortcut_manager().register("CTRL + U", move || {}); -} -``` - -## Accessing managed state - -Tauri can manage state using the `manage` function on `tauri::Builder`. -The state can be accessed on a command using `tauri::State`: - -```rust -struct MyState(String); - -#[tauri::command] -fn my_custom_command(state: tauri::State) { - assert_eq!(state.0 == "some state value", true); -} - -fn main() { - tauri::Builder::default() - .manage(MyState("some state value".into())) - .invoke_handler(tauri::generate_handler![my_custom_command]) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -## Creating Multiple Commands - -The `tauri::generate_handler!` macro takes an array of commands. To register -multiple commands, you cannot call invoke_handler multiple times. Only the last -call will be used. You must pass each command to a single call of -`tauri::generate_handler!`. - -```rust -#[tauri::command] -fn cmd_a() -> String { - "Command a" -} -#[tauri::command] -fn cmd_b() -> String { - "Command b" -} - -fn main() { - tauri::Builder::default() - .invoke_handler(tauri::generate_handler![cmd_a, cmd_b]) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -## Complete Example - -Any or all of the above features can be combined: - -```rust title=main.rs -// Definition in main.rs - -struct Database; - -#[derive(serde::Serialize)] -struct CustomResponse { - message: String, - other_val: usize, -} - -async fn some_other_function() -> Option { - Some("response".into()) -} - -#[tauri::command] -async fn my_custom_command( - window: tauri::Window, - number: usize, - database: tauri::State<'_, Database>, -) -> Result { - println!("Called from {}", window.label()); - let result: Option = some_other_function().await; - if let Some(message) = result { - Ok(CustomResponse { - message, - other_val: 42 + number, - }) - } else { - Err("No result".into()) - } -} - -fn main() { - tauri::Builder::default() - .manage(Database {}) - .invoke_handler(tauri::generate_handler![my_custom_command]) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -```js -// Invocation from JS - -invoke('my_custom_command', { - number: 42, -}) - .then((res) => - console.log(`Message: ${res.message}, Other Val: ${res.other_val}`) - ) - .catch((e) => console.error(e)) -``` diff --git a/docs/usage/guides/events.md b/docs/usage/guides/events.md deleted file mode 100644 index 2a9ba17aaaec..000000000000 --- a/docs/usage/guides/events.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Events ---- - -The Tauri event system is a multi-producer multi-consumer communication primitive that allows message passing between the frontend and the backend. -It is analogous to the command system, but payload type check must be written on the event handler and it simplifies communication from the backend to the frontend, working like a channel. - -A Tauri application can listen and emit to global and window-specific events. Usage from the frontend and the backend are described below. - -## Frontend - -The event system is accessible on the frontend on the `event` and `window` modules of the `@tauri-apps/api` package. - -### Global events - -To use the global event channel, import the `event` module and use the `emit` and `listen` functions: - -```ts -import { emit, listen } from '@tauri-apps/api/event' - -// listen to the `click` event and get a function to remove the event listener -// there's also a `once` function that subscribes to an event and automatically unsubscribes the listener on the first event -const unlisten = await listen('click', event => { - // event.event is the event name (useful if you want to use a single callback fn for multiple event types) - // event.payload is the payload object -}) - -// emits the `click` event with the object payload -emit('click', { - theMessage: 'Tauri is awesome!' -}) -``` - -### Window-specific events - -Window-specific events are exposed on the `window` module. - -```ts -import { getCurrent, WebviewWindow } from '@tauri-apps/api/window' - -// emit an event that are only visible to the current window -const current = getCurrent() -current.emit('event', { message: 'Tauri is awesome!' }) - -// create a new webview window and emit an event only to that window -const webview = new WebviewWindow('window') -webview.emit('event') - -``` - -## Backend - -On the backend, the global event channel is exposed on the `App` struct, and window-specific events can be emitted using the `Window` trait. - -### Global events - -```rust -use tauri::Manager; - -// the payload type must implement `Serialize`. -// for global events, it also must implement `Clone`. -#[derive(Clone, serde::Serialize)] -struct Payload { - message: String, -} - -fn main() { - tauri::Builder::default() - .setup(|app| { - // listen to the `event-name` (emitted on any window) - let id = app.listen_global("event-name", |event| { - println!("got event-name with payload {:?}", event.payload()); - }); - // unlisten to the event using the `id` returned on the `listen_global` function - // an `once_global` API is also exposed on the `App` struct - app.unlisten(id); - - // emit the `event-name` event to all webview windows on the frontend - app.emit_all("event-name", Payload { message: "Tauri is awesome!".into() }).unwrap(); - Ok(()) - }) - .run(tauri::generate_context!()) - .expect("failed to run app"); -} -``` - -### Window-specific events - -To use the window-specific event channel, a `Window` object can be obtained on a command handler or with the `get_window` function: - -```rust -use tauri::{Manager, Window}; - -// the payload type must implement `Serialize`. -#[derive(serde::Serialize)] -struct Payload { - message: String, -} - -// init a background process on the command, and emit periodic events only to the window that used the command -#[tauri::command] -fn init_process(window: Window) { - std::thread::spawn(move || { - loop { - window.emit("event-name", Payload { message: "Tauri is awesome!".into() }).unwrap(); - } - }); -} - -fn main() { - tauri::Builder::default() - .setup(|app| { - // `main` here is the window label; it is defined on the window creation or under `tauri.conf.json` - // the default value is `main`. note that it must be unique - let main_window = app.get_window("main").unwrap(); - - // listen to the `event-name` (emitted on the `main` window) - let id = main_window.listen("event-name", |event| { - println!("got window event-name with payload {:?}", event.payload()); - }); - // unlisten to the event using the `id` returned on the `listen` function - // an `once` API is also exposed on the `Window` struct - main_window.unlisten(id); - - // emit the `event-name` event to the `main` window - main_window.emit("event-name", Payload { message: "Tauri is awesome!".into() }).unwrap(); - Ok(()) - }) - .invoke_handler(tauri::generate_handler![init_process]) - .run(tauri::generate_context!()) - .expect("failed to run app"); -} -``` diff --git a/docs/usage/guides/migration.md b/docs/usage/guides/migration.md deleted file mode 100644 index 63c9b889cf11..000000000000 --- a/docs/usage/guides/migration.md +++ /dev/null @@ -1,335 +0,0 @@ ---- -title: Migrating from 0.x ---- - -First of all if you still have `tauri` as dependency in your `package.json` -replace it with a recent version of `@tauri-apps/cli` (make sure to also change -the import path in your JavaScript/TypeScript files, see [JavaScript](#javascript)). - -For example: - -```diff -- "tauri": "^0.14.1" -+ "@tauri-apps/cli": "^1.0.0-beta-rc.4" -``` - -Next update your `Cargo.toml`: - -- add `tauri-build` as a new build-dependency and remove `winres`, e.g.: - - ```diff - + [build-dependencies] - + tauri-build = { version = "1.0.0-beta-rc.0" } - - - [target."cfg(windows)".build-dependencies] - - winres = "0.1" - ``` - -- update the version of `tauri` to e.g. `1.0.0-beta-rc.4` -- remove all old features of the `tauri` dependency -- remove all features, that tauri added and add `custom-protocol` as a new one: - - ```diff - [features] - - embedded-server = [ "tauri/embedded-server" ] - - no-server = [ "tauri/no-server" ] - + custom-protocol = [ "tauri/custom-protocol" ] - + default = [ "custom-protocol" ] - ``` - -Update your `tauri.conf.json` like this: - -- remove `ctx` -- remove the `embeddedServer` -- rename `osx` to `macOS` and add some fields: - - `"exceptionDomain": ""` - - `"signingIdentity": null` - - `"entitlements": null` -- remove the `exceptionDomain` -- add a configuration for `windows`: - - `"certificateThumbprint": null` - - `"digestAlgorithm": "sha256"` - - `"timestampUrl": ""` -- make the `window` definition into an array and call it `windows` -- remove `inliner` - -> for more information about the config see [here](../../api/config.md) - -```diff - { -- "ctx": {}, - "tauri": { -- "embeddedServer": { -- "active": true -- }, - "bundle": { -- "osx": { -+ "macOS": { - "frameworks": [], - "minimumSystemVersion": "", -- "useBootstrapper": false -+ "useBootstrapper": false, -+ "exceptionDomain": "", -+ "signingIdentity": null, -+ "entitlements": null - }, -- "exceptionDomain": "" -+ "windows": { -+ "certificateThumbprint": null, -+ "digestAlgorithm": "sha256", -+ "timestampUrl": "" -+ } - }, -+ "updater": { -+ "active": false -+ }, -- "window": { -+ "windows": [ - { - "title": "Calciumdibromid", - "width": 800, - "height": 600, - "resizable": true, - "fullscreen": false - } -+ ], -- "inliner": { -- "active": true -- } - } - } -``` - -## Commands - -The following example is taken from the previous documentation. - -In the new version of Tauri there is no distinction between synchronous and -asynchronous commands, the only difference in your code is a call of -`tauri::execute_promise()`, that isn't there in a synchronous command. - -### Rust - -Here is the complete example code of the "old" version: - -```rust -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize)] -struct DoSomethingPayload { - state: String, - data: u64, -} - -#[derive(Deserialize)] -#[serde(tag = "cmd", rename_all = "camelCase")] -enum Cmd { - DoSomething { - count: u64, - payload: DoSomethingPayload, - callback: String, - error: String, - }, -} - -#[derive(Serialize)] -struct Response<'a> { - value: u64, - message: &'a str, -} - -#[derive(Debug, Clone)] -struct CommandError<'a> { - message: &'a str, -} - -impl<'a> CommandError<'a> { - fn new(message: &'a str) -> Self { - Self { message } - } -} - -impl<'a> std::fmt::Display for CommandError<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.message) - } -} - -impl<'a> std::error::Error for CommandError<'a> {} - -fn main() { - tauri::AppBuilder::new() - .invoke_handler(|_webview, arg| { - use Cmd::*; - match serde_json::from_str(arg) { - Err(e) => Err(e.to_string()), - Ok(command) => { - match command { - DoSomething { count, payload, callback, error } => tauri::execute_promise( - _webview, - move || { - if count > 5 { - let response = Response { - value: 5, - message: "async response!", - }; - Ok(response) - } else { - Err(CommandError::new("count should be > 5").into()) - } - }, - callback, - error, - ), - } - Ok(()) - } - } - }) - .build() - .run(); -} -``` - -Complete the following steps to migrate your code: - -- create a new function for every `Cmd` enum variant -- wrap the new function with the `#[tauri::command]` macro -- use the fields of the enum as arguments (`callback` and `error` can be deleted) -- as function body use the code inside the `match` block of the enum variant -- add a return type -- rename `AppBuilder` to `Builder` in `main()` -- replace the big `invoke_handler` with the new syntax - -The old example code should look like this now: - -```rust -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize)] -struct DoSomethingPayload { - state: String, - data: u64, -} - -#[derive(Serialize)] -struct Response<'a> { - value: u64, - message: &'a str, -} - -#[derive(Debug, Clone, Serialize)] -struct CommandError<'a> { - message: &'a str, -} - -impl<'a> CommandError<'a> { - fn new(message: &'a str) -> Self { - Self { message } - } -} - -impl<'a> std::fmt::Display for CommandError<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.message) - } -} - -impl<'a> std::error::Error for CommandError<'a> {} - -#[tauri::command] -fn do_something(count: u64, payload: DoSomethingPayload) -> Result { - if count > 5 { - let response = Response { - value: 5, - message: "async response!", - }; - Ok(response) - } else { - Err(CommandError::new("count should be > 5").into()) - } -} - -fn main() { - tauri::Builder::new() - .invoke_handler(tauri::generate_handler![do_something]) - .run(tauri::generate_context!()); -} -``` - -### JavaScript - -Like mentioned above there is also no distinction between synchronous and -asynchronous commands in JavaScript. -You only have to use `invoke` and optionally use the results. - -Here is an example of the "old" code: - -```js -invoke({ - cmd: 'doSomething', - count: 5, - payload: { - state: 'some string data', - data: 17 - } -}); - -promisified({ - cmd: 'doSomething', - count: 5, - payload: { - state: 'some string data', - data: 17 - } -}).then(response => { - console.log(response); -}).catch(error => { - console.error(error); -}); -``` - -Complete the following steps to migrate your code: - -- replace all `promisified`-calls with `invoke`-calls -- extract the `cmd` attribute of the argument object as first parameter - (you may have to rename it to `snake_case` as the `cmd` parameter is now the - name of the function in Rust) -- if you import parts of the tauri-api with `tauri/api/*` replace it with `@tauri-apps/api/*`, e.g.: - - ```diff - - import { invoke } from 'tauri/api/tauri'; - + import { invoke } from '@tauri-apps/api/tauri'; - ``` - -The old example code should look like this now: - -```js -invoke( - 'do_something', - { - count: 5, - payload: { - state: 'some string data', - data: 17 - } - } -); - -invoke( - 'do_something', - { - count: 5, - payload: { - state: 'some string data', - data: 17 - } - } -).then(response => { - console.log(response); -}).catch(error => { - console.error(error); -}); -``` - -For more information on commands read [Create Rust Commands](command.md). diff --git a/docs/usage/guides/plugin.md b/docs/usage/guides/plugin.md deleted file mode 100644 index e4216b5dcc46..000000000000 --- a/docs/usage/guides/plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: Write Tauri Plugins ---- - -import Alert from '@theme/Alert' - - -Tauri will soon offer Plugin starter kits so the process of writing a Plugin crate will be simplified. - -For now it's recommended to follow the [official Tauri plugins](#official-tauri-plugins). - - -Plugins allow you to hook into the Tauri application lifecycle and introduce new commands. - -## Writing a Plugin - -To write a plugin you just need to implement the `tauri::plugin::Plugin` trait: - -```rust -use tauri::{plugin::{Plugin, Result as PluginResult}, Runtime, PageLoadPayload, Window, Invoke, AppHandle}; - -struct MyAwesomePlugin { - invoke_handler: Box) + Send + Sync>, - // plugin state, configuration fields -} - -// the plugin custom command handlers if you choose to extend the API. -#[tauri::command] -// this will be accessible with `invoke('plugin:awesome|initialize')`. -// where `awesome` is the plugin name. -fn initialize() {} - -#[tauri::command] -// this will be accessible with `invoke('plugin:awesome|do_something')`. -fn do_something() {} - -impl MyAwesomePlugin { - // you can add configuration fields here, - // see https://doc.rust-lang.org/1.0.0/style/ownership/builders.html - pub fn new() -> Self { - Self { - invoke_handler: Box::new(tauri::generate_handler![initialize, do_something]), - } - } -} - -impl Plugin for MyAwesomePlugin { - /// The plugin name. Must be defined and used on the `invoke` calls. - fn name(&self) -> &'static str { - "awesome" - } - - /// The JS script to evaluate on initialization. - /// Useful when your plugin is accessible through `window` - /// or needs to perform a JS task on app initialization - /// e.g. "window.awesomePlugin = { ... the plugin interface }" - fn initialization_script(&self) -> Option { - None - } - - /// initialize plugin with the config provided on `tauri.conf.json > plugins > $yourPluginName` or the default value. - fn initialize(&mut self, app: &AppHandle, config: serde_json::Value) -> PluginResult<()> { - Ok(()) - } - - /// Callback invoked when the Window is created. - fn created(&mut self, window: Window) {} - - /// Callback invoked when the webview performs a navigation. - fn on_page_load(&mut self, window: Window, payload: PageLoadPayload) {} - - /// Extend the invoke handler. - fn extend_api(&mut self, message: Invoke) { - (self.invoke_handler)(message) - } -} -``` - -Note that each function on the `Plugin` trait is optional, except the `name` function. - -## Using a plugin - -To use a plugin, just pass an instance of the `MyAwesomePlugin` struct to the App's `plugin` method: - -```rust -fn main() { - let awesome_plugin = MyAwesomePlugin::new(); - tauri::Builder::default() - .plugin(awesome_plugin) - .run(tauri::generate_context!()) - .expect("failed to run app"); -} -``` - -## Official Tauri Plugins - -- [Stronghold (WIP)](https://github.com/tauri-apps/tauri-plugin-stronghold) -- [Authenticator (WIP)](https://github.com/tauri-apps/tauri-plugin-authenticator) -- [Logging (WIP)](https://github.com/tauri-apps/tauri-plugin-log) -- [SQL (WIP)](https://github.com/tauri-apps/tauri-plugin-sql) diff --git a/docs/usage/guides/updater.md b/docs/usage/guides/updater.md deleted file mode 100644 index bbd29cf85f45..000000000000 --- a/docs/usage/guides/updater.md +++ /dev/null @@ -1,308 +0,0 @@ ---- -title: Updater ---- - -# Configuration - -Once you have your Tauri project ready, you need to configure the updater. - -Add this in tauri.conf.json -```json -"updater": { - "active": true, - "endpoints": [ - "https://releases.myapp.com/{{target}}/{{current_version}}" - ], - "dialog": true, - "pubkey": "" -} -``` - -The required keys are "active" and "endpoints", others are optional. - -"active" must be a boolean. By default, it's set to false. - -"endpoints" must be an array. The string `{{target}}` and `{{current_version}}` are automatically replaced in the URL allowing you determine [server-side](#update-server-json-format) if an update is available. If multiple endpoints are specified, the updater will fallback if a server is not responding within the pre-defined timeout. - -"dialog" if present must be a boolean. By default, it's set to true. If enabled, [events](#events) are turned-off as the updater will handle everything. If you need the custom events, you MUST turn off the built-in dialog. - -"pubkey" if present must be a valid public-key generated with Tauri cli. See [Signing updates](#signing-updates). - -## Update Requests - -Tauri is indifferent to the request the client application provides for update checking. - -`Accept: application/json` is added to the request headers because Tauri is responsible for parsing the response. - -For the requirements imposed on the responses and the body format of an update, response see [Server Support](#server-support). - -Your update request must *at least* include a version identifier so that the server can determine whether an update for this specific version is required. - -It may also include other identifying criteria such as operating system version, to allow the server to deliver as fine-grained an update as you would like. - -How you include the version identifier or other criteria is specific to the server that you are requesting updates from. A common approach is to use query parameters, [Configuration](#configuration) shows an example of this. - -## Built-in dialog - -By default, updater uses a built-in dialog API from Tauri. - -![New Update](https://i.imgur.com/UMilB5A.png) - -The dialog release notes is represented by the update `note` provided by the [server](#server-support). - -If the user accepts, the download and install are initialized. The user will be then prompted to restart the application. - -## Javascript API - -**Attention, you need to _disable built-in dialog_ in your [tauri configuration](#configuration), otherwise, events aren't emitted and the javascript API will NOT work.** - - -```js -import { checkUpdate, installUpdate } from "@tauri-apps/api/updater"; -import { relaunch } from "@tauri-apps/api/process"; -try { - const {shouldUpdate, manifest} = await checkUpdate(); - if (shouldUpdate) { - // display dialog - await installUpdate(); - // install complete, restart app - await relaunch(); - } -} catch(error) { - console.log(error); -} -``` - -## Events - -**Attention, you need to _disable built-in dialog_ in your [tauri configuration](#configuration), otherwise, events aren't emitted.** - -To know when an update is ready to be installed, you can subscribe to these events: - -### Initialize updater and check if a new version is available - -#### If a new version is available, the event `tauri://update-available` is emitted. - -Event: `tauri://update` - -### Rust -```rust -window.emit("tauri://update".to_string(), None); -``` - -### Javascript -```js -import { emit } from "@tauri-apps/api/event"; -emit("tauri://update"); -``` - -### Listen New Update Available - -Event: `tauri://update-available` - -Emitted data: -```none -version Version announced by the server -date Date announced by the server -body Note announced by the server -``` - -### Rust -```rust -window.listen("tauri://update-available".to_string(), move |msg| { - println!("New version available: {:?}", msg); -}) -``` - -### Javascript -```js -import { listen } from "@tauri-apps/api/event"; -listen("tauri://update-available", function (res) { - console.log("New version available: ", res); -}); -``` - -### Emit Install and Download - -You need to emit this event to initialize the download and listen to the [install progress](#listen-install-progress). - -Event: `tauri://update-install` - -### Rust -```rust -window.emit("tauri://update-install".to_string(), None); -``` - -### Javascript -```js -import { emit } from "@tauri-apps/api/event"; -emit("tauri://update-install"); -``` - -### Listen Install Progress - -Event: `tauri://update-status` - -Emitted data: -```none -status [ERROR/PENDING/DONE] -error String/null -``` - -PENDING is emitted when the download is started and DONE when the install is complete. You can then ask to restart the application. - -ERROR is emitted when there is an error with the updater. We suggest to listen to this event even if the dialog is enabled. - -### Rust -```rust -window.listen("tauri://update-status".to_string(), move |msg| { - println!("New status: {:?}", msg); -}) -``` - -### Javascript -```js -import { listen } from "@tauri-apps/api/event"; -listen("tauri://update-status", function (res) { - console.log("New status: ", res); -}); -``` - -# Server Support - -Your server should determine whether an update is required based on the [Update Request](#update-requests) your client issues. - -If an update is required your server should respond with a status code of [200 OK](http://tools.ietf.org/html/rfc2616#section-10.2.1) and include the [update JSON](#update-server-json-format) in the body. To save redundantly downloading the same version multiple times your server must not inform the client to update. - -If no update is required your server must respond with a status code of [204 No Content](http://tools.ietf.org/html/rfc2616#section-10.2.5). - -## Update Server JSON Format - -When an update is available, Tauri expects the following schema in response to the update request provided: - -```json -{ - "url": "https://mycompany.example.com/myapp/releases/myrelease.tar.gz", - "version": "0.0.1", - "notes": "Theses are some release notes", - "pub_date": "2020-09-18T12:29:53+01:00", - "signature": "" -} -``` - -The only required keys are "url" and "version", the others are optional. - -"pub_date" if present must be formatted according to ISO 8601. - -"signature" if present must be a valid signature generated with Tauri cli. See [Signing updates](#signing-updates). - -## Update File JSON Format - -The alternate update technique uses a plain JSON file meaning you can store your update metadata on S3, gist, or another static file store. Tauri will check against the name/version field and if the version is smaller than the current one and the platform is available, the update will be triggered. The format of this file is detailed below: - -```json -{ - "name":"v1.0.0", - "notes":"Test version", - "pub_date":"2020-06-22T19:25:57Z", - "platforms": { - "darwin": { - "signature":"", - "url":"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.app.tar.gz" - }, - "linux": { - "signature":"", - "url":"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.AppImage.tar.gz" - }, - "win64": { - "signature":"", - "url":"https://github.com/lemarier/tauri-test/releases/download/v1.0.0/app.x64.msi.zip" - } - } -} -``` - -# Bundler (Artifacts) - -The Tauri bundler will automatically generate update artifacts if the updater is enabled in `tauri.conf.json` - -If the bundler can locate your private and pubkey, your update artifacts will be automatically signed. - -The signature can be found in the `sig` file. The signature can be uploaded to GitHub safely or made public as long as your private key is secure. - -You can see how it's [bundled with the CI](https://github.com/tauri-apps/tauri/blob/5b6c7bb6ee3661f5a42917ce04a89d94f905c949/.github/workflows/artifacts-updater.yml#L44) and a [sample tauri.conf.json](https://github.com/tauri-apps/tauri/blob/5b6c7bb6ee3661f5a42917ce04a89d94f905c949/examples/updater/src-tauri/tauri.conf.json#L52) - -## macOS - -On MACOS we create a .tar.gz from the whole application. (.app) - -```none -target/release/bundle -└── osx - └── app.app - └── app.app.tar.gz (update bundle) - └── app.app.tar.gz.sig (if signature enabled) -``` - -## Windows - -On Windows we create a .zip from the MSI, when downloaded and validated, we run the MSI install. - -```none -target/release -└── app.x64.msi -└── app.x64.msi.zip (update bundle) -└── app.x64.msi.zip.sig (if signature enabled) -``` - -## Linux - -On Linux, we create a .tar.gz from the AppImage. - -```none -target/release/bundle -└── appimage - └── app.AppImage - └── app.AppImage.tar.gz (update bundle) - └── app.AppImage.tar.gz.sig (if signature enabled) -``` - -# Signing updates - -We offer a built-in signature to ensure your update is safe to be installed. - -To sign your updates, you need two things. - -The *Public-key* (pubkey) should be added inside your `tauri.conf.json` to validate the update archive before installing. - -The *Private key* (privkey) is used to sign your update and should NEVER be shared with anyone. Also, if you lost this key, you'll NOT be able to publish a new update to the current user base (if pubkey is set in tauri.conf.json). It's important to save it at a safe place and you can always access it. - -To generate your keys you need to use the Tauri cli. - -```bash -tauri sign -g -w ~/.tauri/myapp.key -``` - -You have multiple options available -```bash -Tauri updates signer. -USAGE: - tauri sign [FLAGS] [OPTIONS] -FLAGS: - --force Overwrite private key even if it exists on the specified path - -g, --generate Generate keypair to sign files - -h, --help Prints help information - --no-password Set empty password for your private key - -V, --version Prints version information -OPTIONS: - -p, --password Set private key password when signing - -k, --private-key Load the private key from a string - -f, --private-key-path Load the private key from a file - --sign-file Sign the specified file - -w, --write-keys Write private key to a file -``` -*** -Environment variables used to sign with the Tauri `bundler`: -If they are set, and `tauri.conf.json` expose the public key, the bundler will automatically generate and sign the updater artifacts. -`TAURI_PRIVATE_KEY` Path or String of your private key -`TAURI_KEY_PASSWORD` Your private key password (optional) diff --git a/docs/usage/guides/utils/multiwindow.md b/docs/usage/guides/utils/multiwindow.md deleted file mode 100644 index 46b84b35625f..000000000000 --- a/docs/usage/guides/utils/multiwindow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Multiwindow ---- - -Manage multiple windows on a single application. diff --git a/docs/usage/guides/visual/icons.md b/docs/usage/guides/visual/icons.md deleted file mode 100644 index b5333e079cf5..000000000000 --- a/docs/usage/guides/visual/icons.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Icons ---- - -import Command from '@theme/Command' -import Alert from '@theme/Alert' - -Tauri ships with a default iconset based on its logo. This is probably NOT what you want when you ship your application. To remedy this common situation, Tauri provides the `icon` command that will take an input file and create all the icons needed for the various platforms: - - - -```sh -Options - --help, -h Displays this message - --log, l Logging [boolean] - --icon, i Source icon (png, 1240x1240 with transparency) - --target, t Target folder (default: 'src-tauri/icons') - --compression, c Compression type [pngquant|optipng|zopfli] -``` - -These will be placed in your `src-tauri/icons` folder where they will automatically be included in your built app. - -If you need to source your icons from some other location, you can edit this part of the `src-tauri/tauri.conf.json` file: - -```json -{ - "tauri": { - "bundle": { - "icon": [ - "icons/32x32.png", - "icons/128x128.png", - "icons/128x128@2x.png", - "icons/icon.icns", - "icons/icon.ico" - ] - } - } -} -``` - - - - - icon.icns = macOS - - icon.ico = MS Windows - - \*.png = Linux - - diff --git a/docs/usage/guides/visual/menu.md b/docs/usage/guides/visual/menu.md deleted file mode 100644 index b82a2dcc8371..000000000000 --- a/docs/usage/guides/visual/menu.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: Window Menu ---- - -Native application menus can be attached to a window. - -### Creating a menu - -To create a native window menu, import the `Menu`, `Submenu`, `MenuItem` and `CustomMenuItem` types. -The `MenuItem` enum contains a collection of platform-specific items (currently not implemented on Windows). -The `CustomMenuItem` allows you to create your own menu items and add special functionality to them. - -```rust -use tauri::{CustomMenuItem, Menu, MenuItem, Submenu}; -``` - -Create a `Menu` instance: - -```rust -// here `"quit".to_string()` defines the menu item id, and the second parameter is the menu item label. -let quit = CustomMenuItem::new("quit".to_string(), "Quit"); -let close = CustomMenuItem::new("close".to_string(), "Close"); -let submenu = Submenu::new("File", Menu::new().add_item(quit).add_item(close)); -let menu = Menu::new() - .add_native_item(MenuItem::Copy) - .add_item(CustomMenuItem::new("hide", "Hide")) - .add_submenu(submenu); -``` - -### Adding the menu to all windows - -The defined menu can be set to all windows using the `menu` API on the `tauri::Builder` struct: - -```rust -use tauri::{CustomMenuItem, Menu, MenuItem, Submenu}; - -fn main() { - let menu = Menu::new(); // configure the menu - tauri::Builder::default() - .menu(menu) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -### Adding the menu to a specific window - -You can create a window and set the menu to be used. This allows defining a specific menu set for each application window. - -```rust -use tauri::{CustomMenuItem, Menu, MenuItem, Submenu}; -use tauri::WindowBuilder; - -fn main() { - let menu = Menu::new(); // configure the menu - tauri::Builder::default() - .create_window( - "main-window".to_string(), - tauri::WindowUrl::App("index.html".into()), - move |window_builder, webview_attributes| { - (window_builder.menu(menu), webview_attributes) - }, - ) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -### Listening to events on custom menu items - -Each `CustomMenuItem` triggers an event when clicked. Use the `on_menu_event` API to handle them, either on the global `tauri::Builder` or on an specific window. - -#### Listening to events on global menus - -```rust -use tauri::{CustomMenuItem, Menu, MenuItem}; - -fn main() { - let menu = vec![]; // insert the menu array here - tauri::Builder::default() - .menu(menu) - .on_menu_event(|event| { - match event.menu_item_id() { - "quit" => { - std::process::exit(0); - } - "close" => { - event.window().close().unwrap(); - } - _ => {} - } - }) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -#### Listening to events on window menus - -```rust -use tauri::{CustomMenuItem, Menu, MenuItem}; -use tauri::{Manager, WindowBuilder}; - -fn main() { - let menu = vec![]; // insert the menu array here - tauri::Builder::default() - .create_window( - "main-window".to_string(), - tauri::WindowUrl::App("index.html".into()), - move |window_builder, webview_attributes| { - (window_builder.menu(menu), webview_attributes) - }, - ) - .setup(|app| { - let window = app.get_window("main-window").unwrap(); - let window_ = window.clone(); - window.on_menu_event(move |event| { - match event.menu_item_id().as_str() { - "quit" => { - std::process::exit(0); - } - "close" => { - window_.close().unwrap(); - } - _ => {} - } - }); - Ok(()) - }) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -### Updating menu items - -The `Window` struct has a `menu_handle` method, which allows updating menu items: - -```rust -fn main() { - tauri::Builder::default() - .setup(|app| { - let main_window = app.get_window("main").unwrap(); - let menu_handle = main_window.menu_handle(); - std::thread::spawn(move || { - // you can also `set_selected`, `set_enabled` and `set_native_image` (macOS only). - menu_handle.get_item("item_id").set_title("New title"); - }) - Ok(()) - }) -} -``` diff --git a/docs/usage/guides/visual/splashscreen.md b/docs/usage/guides/visual/splashscreen.md deleted file mode 100644 index a2738fb8722e..000000000000 --- a/docs/usage/guides/visual/splashscreen.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: Splashscreen ---- - -import Link from '@docusaurus/Link' - -If your webpage could take some time to load, or if you need to run an initialization procedure in Rust before displaying your main window, a splashscreen could improve the loading experience for the user. - -### Setup - -First, create a `splashscreen.html` in your `distDir` that contains the HTML code for a splashscreen. Then, update your `tauri.conf.json` like so: - -```diff -"windows": [ - { - "title": "Tauri App", - "width": 800, - "height": 600, - "resizable": true, - "fullscreen": false, -+ "visible": false // Hide the main window by default - }, - // Add the splashscreen window -+ { -+ "width": 400, -+ "height": 200, -+ "decorations": false, -+ "url": "splashscreen.html", -+ "label": "splashscreen" -+ } -] -``` - -Now, your main window will be hidden and the splashscreen window will show when your app is launched. Next, you'll need a way to close the splashscreen and show the main window when your app is ready. How you do this depends on what you are waiting for before closing the splashscreen. - -### Waiting for Webpage - -If you are waiting for your web code, you'll want to create a `close_splashscreen` [command](../command.md). - -```rust title=src-tauri/main.rs -use tauri::Manager; -// Create the command: -#[tauri::command] -fn close_splashscreen(window: tauri::Window) { - // Close splashscreen - if let Some(splashscreen) = window.get_window("splashscreen") { - splashscreen.close().unwrap(); - } - // Show main window - window.get_window("main").unwrap().show().unwrap(); -} - -// Register the command: -fn main() { - tauri::Builder::default() - // Add this line - .invoke_handler(tauri::generate_handler![close_splashscreen]) - .run(tauri::generate_context!()) - .expect("failed to run app"); -} - -``` - -Then, you can call it from your JS: - -```js -// With the Tauri API npm package: -import { invoke } from '@tauri-apps/api/tauri' -// With the Tauri global script: -const invoke = window.__TAURI__.invoke - -document.addEventListener('DOMContentLoaded', () => { - // This will wait for the window to load, but you could - // run this function on whatever trigger you want - invoke('close_splashscreen') -}) -``` - -### Waiting for Rust - -If you are waiting for Rust code to run, put it in the `setup` function handler so you have access to the `App` instance: - -```rust title=src-tauri/main.rs -use tauri::Manager; -fn main() { - tauri::Builder::default() - .setup(|app| { - let splashscreen_window = app.get_window("splashscreen").unwrap(); - let main_window = app.get_window("main").unwrap(); - // we perform the initialization code on a new task so the app doesn't freeze - tauri::async_runtime::spawn(async move { - // initialize your app here instead of sleeping :) - println!("Initializing..."); - std::thread::sleep(std::time::Duration::from_secs(2)); - println!("Done initializing."); - - // After it's done, close the splashscreen and display the main window - splashscreen_window.close().unwrap(); - main_window.show().unwrap(); - }); - Ok(()) - }) - .run(tauri::generate_context!()) - .expect("failed to run app"); -} -``` diff --git a/docs/usage/guides/visual/system-tray.md b/docs/usage/guides/visual/system-tray.md deleted file mode 100644 index 7b613b7e237f..000000000000 --- a/docs/usage/guides/visual/system-tray.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -title: System Tray ---- - -Native application system tray. - -### Setup - -Configure the `systemTray` object on `tauri.conf.json`: - -```json -{ - "tauri": { - "systemTray": { - "iconPath": "icons/icon.png", - "iconAsTemplate": true, - } - } -} -``` - -The `iconPath` is pointed to a PNG file on macOS and Linux, and a `.ico` file must exist for Windows support. - -The `iconAsTemplate` is a boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS. - - -### Creating a system tray - -To create a native system tray, import the `SystemTray` type: - -```rust -use tauri::SystemTray; -``` - -Initialize a new tray instance: - -```rust -let tray = SystemTray::new(); -``` - -### Configuring a system tray context menu - -Optionally you can add a context menu that is visible when the tray icon is right clicked. Import the `SystemTrayMenu`, `SystemTrayMenuItem` and `CustomMenuItem` types: - -```rust -use tauri::{CustomMenuItem, SystemTrayMenu, SystemTrayMenuItem}; -``` - -Create the `SystemTrayMenu`: - -```rust -// here `"quit".to_string()` defines the menu item id, and the second parameter is the menu item label. -let quit = CustomMenuItem::new("quit".to_string(), "Quit"); -let hide = CustomMenuItem::new("hide".to_string(), "Hide"); -let tray_menu = SystemTrayMenu::new() - .add_item(quit) - .add_native_item(SystemTrayMenuItem::Separator) - .add_item(hide); -``` - -Add the tray menu to the `SystemTray` instance: - -```rust -let tray = SystemTray::new().with_menu(tray_menu); -``` - -### Configure the app system tray - -The created `SystemTray` instance can be set using the `system_tray` API on the `tauri::Builder` struct: - -```rust -use tauri::{CustomMenuItem, SystemTray, SystemTrayMenu}; - -fn main() { - let tray_menu = SystemTrayMenu::new(); // insert the menu items here - let system_tray = SystemTray::new() - .with_menu(tray_menu); - tauri::Builder::default() - .system_tray(system_tray) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -### Listening to system tray events - -Each `CustomMenuItem` triggers an event when clicked. -Also, Tauri emits tray icon click events. -Use the `on_system_tray_event` API to handle them: - -```rust -use tauri::{CustomMenuItem, SystemTray, SystemTrayMenu}; -use tauri::Manager; - -fn main() { - let tray_menu = SystemTrayMenu::new(); // insert the menu items here - tauri::Builder::default() - .system_tray(SystemTray::new().with_menu(tray_menu)) - .on_system_tray_event(|app, event| match event { - SystemTrayEvent::LeftClick { - position: _, - size: _, - .. - } => { - println!("system tray received a left click"); - } - SystemTrayEvent::RightClick { - position: _, - size: _, - .. - } => { - println!("system tray received a right click"); - } - SystemTrayEvent::DoubleClick { - position: _, - size: _, - .. - } => { - println!("system tray received a double click"); - } - SystemTrayEvent::MenuItemClick { id, .. } => { - match id.as_str() { - "quit" => { - std::process::exit(0); - } - "hide" => { - let window = app.get_window("main").unwrap(); - window.hide().unwrap(); - } - _ => {} - } - } - _ => {} - }) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -### Updating system tray - -The `AppHandle` struct has a `tray_handle` method, which returns a handle to the system tray allowing updating tray icon and context menu items: - -#### Updating context menu items - -```rust -use tauri::{CustomMenuItem, SystemTray, SystemTrayMenu}; -use tauri::Manager; - -fn main() { - let tray_menu = SystemTrayMenu::new(); // insert the menu items here - tauri::Builder::default() - .system_tray(SystemTray::new().with_menu(tray_menu)) - .on_system_tray_event(|app, event| match event { - SystemTrayEvent::MenuItemClick { id, .. } => { - // get a handle to the clicked menu item - // note that `tray_handle` can be called anywhere, - // just get a `AppHandle` instance with `app.handle()` on the setup hook - // and move it to another function or thread - let item_handle = app.tray_handle().get_item(&id); - match id.as_str() { - "hide" => { - let window = app.get_window("main").unwrap(); - window.hide().unwrap(); - // you can also `set_selected`, `set_enabled` and `set_native_image` (macOS only). - item_handle.set_title("Show").unwrap(); - } - _ => {} - } - } - _ => {} - }) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} -``` - -#### Updating tray icon - -Note that `tauri::Icon` must be a `Path` variant on Linux, and `Raw` variant on Windows and macOS. - -```rust -app.tray_handle().set_icon(tauri::Icon::Raw(include_bytes!("../path/to/myicon.ico"))).unwrap(); -``` diff --git a/docs/usage/guides/visual/window-customization.md b/docs/usage/guides/visual/window-customization.md deleted file mode 100644 index 95750aeb34cf..000000000000 --- a/docs/usage/guides/visual/window-customization.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: Window Customization ---- - -Tauri provides lots of options for customizing the look and feel of your app's window. You can create custom titlebars, have transparent windows, enforce size constraints, and more. - -## Configuration - -There are three ways to change the window configuration: - -- [Through tauri.conf.json](https://tauri.studio/en/docs/api/config/#tauri.windows) -- [Through the JS API](https://tauri.studio/en/docs/api/js/classes/window.windowmanager) -- [Through the Window in Rust](https://tauri.studio/en/docs/api/rust/tauri/window/struct.window) - -## Creating a Custom Titlebar - -A common use of these window features is creating a custom titlebar. This short tutorial will guide you through that process. - -### CSS - -You'll need to add some CSS for the titlebar to keep it at the top of the screen and style the buttons: - -```css -.titlebar { - height: 30px; - background: #329ea3; - user-select: none; - display: flex; - justify-content: flex-end; - position: fixed; - top: 0; - left: 0; - right: 0; -} -.titlebar-button { - display: inline-flex; - justify-content: center; - align-items: center; - width: 30px; - height: 30px; -} -.titlebar-button:hover { - background: #5bbec3; -} -``` - -### HTML - -Now, you'll need to add the HTML for the titlebar. Put this at the top of your `` tag: - -```html -
-
- minimize -
-
- maximize -
-
- close -
-
-``` - -Note that you may need to move the rest of your content down so that the titlebar doesn't cover it. - -### JS - -Finally, you'll need to make the buttons work: - - -```js -import { appWindow } from '@tauri-apps/api/window' -document - .getElementById('titlebar-minimize') - .addEventListener('click', () => appWindow.minimize()) -document - .getElementById('titlebar-maximize') - .addEventListener('click', () => appWindow.toggleMaximize()) -document - .getElementById('titlebar-close') - .addEventListener('click', () => appWindow.close()) -``` diff --git a/docs/usage/guides/webdriver/ci.md b/docs/usage/guides/webdriver/ci.md deleted file mode 100644 index 5aba5c94be29..000000000000 --- a/docs/usage/guides/webdriver/ci.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: Continuous Integration ---- - -Utilizing Linux and some programs to create a fake display, it is possible to run [WebDriver] tests with -[`tauri-driver`] on your CI. The following example will use the [WebdriverIO] example we [previously built together] and -GitHub Actions. - -This means the following assumptions: - -1. The Tauri application is in the repository root and the binary builds when running `cargo build --release`. -2. The [WebDriverIO] test runner is in the `webdriver/webdriverio` directory and runs when `yarn test` is used in that - directory. - -The following is a commented GitHub Actions workflow file at `.github/workflows/webdriver.yml` - -```yaml -# run this action when the repository is pushed to -on: [ push ] - -# the name of our workflow -name: WebDriver - -jobs: - # a single job named test - test: - # the display name the test job - name: WebDriverIO Test Runner - - # we want to run on the latest linux environment - runs-on: ubuntu-latest - - # the steps our job runs **in order** - steps: - # checkout the code on the workflow runner - - uses: actions/checkout@v2 - - # install system dependencies that Tauri needs to compile on Linux. - # note the extra dependencies for `tauri-driver` to run which are `webkit2gtk-driver` and `xvfb` - - name: Tauri dependencies - run: >- - sudo apt-get update && - sudo apt-get install -y - libgtk-3-dev - libgtksourceview-3.0-dev - webkit2gtk-4.0 - libappindicator3-dev - webkit2gtk-driver - xvfb - - # install the latest Rust stable - - name: Rust stable - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - # we run our rust tests before the webdriver tests to avoid testing a broken application - - name: Cargo test - uses: actions-rs/cargo@v1 - with: - command: test - - # build a release build of our application to be used during our WebdriverIO tests - - name: Cargo build - uses: actions-rs/cargo@v1 - with: - command: build - args: --release - - # install the latest stable node version at the time of writing - - name: Node v16 - uses: actions/setup-node@v1 - with: - node-version: 16.x - - # install our Node.js dependencies with Yarn - - name: Yarn install - run: yarn install - working-directory: webdriver/webdriverio - - # install the latest version of `tauri-driver`. - # note: the tauri-driver version is independent of any other Tauri versions - - name: Install tauri-driver - uses: actions-rs/cargo@v1 - with: - command: install - args: tauri-driver - - # run the WebdriverIO test suite. - # we run it through `xvfb-run` (the dependency we installed earlier) to have a fake - # display server which allows our application to run headless without any changes to the code - - name: WebdriverIO - run: xvfb-run yarn test - working-directory: webdriver/webdriverio -``` - -[WebDriver]: https://www.w3.org/TR/webdriver/ -[`tauri-driver`]: https://crates.io/crates/tauri-driver -[WebdriverIO]: https://webdriver.io/ -[previously built together]: example/webdriverio diff --git a/docs/usage/guides/webdriver/example/selenium.md b/docs/usage/guides/webdriver/example/selenium.md deleted file mode 100644 index 361973dda356..000000000000 --- a/docs/usage/guides/webdriver/example/selenium.md +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: Selenium ---- -import Alert from '@theme/Alert' -import Tabs from '@theme/Tabs' -import TabItem from '@theme/TabItem' - - - -This [Selenium] guide expects you to have already gone through the [example Application setup] in order to follow -step-by-step. The general information may still be useful otherwise. - - -This WebDriver testing example will use [Selenium] and a popular Node.js testing suite. It is expected to already have -Node.js installed, along with `npm` or `yarn` although the [finished example project] uses `yarn`. - -## Create a Directory for the Tests - -Let's start off by creating a space in our project to write these tests. We are going to be using a nested directory for -this example project as we will later also go over other frameworks, but typically you will only need to use one. Create -the directory we will use with `mkdir -p webdriver/selenium`. The rest of this guide will assume you are inside the -`webdriver/selenium` directory. - -## Initializing a Selenium Project - -We will be using a pre-existing `package.json` to bootstrap this test suite because we have already chosen specific -dependencies to use and want to showcase a simple working solution. The bottom of this section has a collapsed -guide on how to set it up from scratch. - -`package.json`: -```json -{ - "name": "selenium", - "version": "1.0.0", - "private": true, - "scripts": { - "test": "mocha" - }, - "dependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "selenium-webdriver": "^4.0.0-beta.4" - } -} -``` - -We have a script which runs [Mocha] as a test framework exposed as the `test` command. We also have various dependencies -that we will be using to run the tests. [Mocha] as the testing framework, [Chai] as the assertion library, and -[`selenium-webdriver`] which is the Node.js [Selenium] package. - -
Click me if you want to see how to set a project up from scratch - -If you wanted to install the dependencies from scratch, just run the following command. - - - - -```sh -npm install mocha chai selenium-webdriver -``` - - - - - -```sh -yarn add mocha chai selenium-webdriver -``` - - - - -I suggest also adding a `"test": "mocha"` item in the `package.json` `"scripts"` key so that running mocha can be called -simply with - - - - -```sh -npm test -``` - - - - - -```sh -yarn test -``` - - - - -
- -## Testing - -Unlike the [WebdriverIO Test Suite](webdriverio#config), Selenium does not come out of the box with a Test Suite and -leaves it up to the developer to build those out. We chose [Mocha] which is pretty neutral, and not related to WebDrivers -at all, so our script will need to do a bit of work to set up everything for us in the right order. [Mocha] expects a -testing file at `test/test.js` by default, so let's create that file now. - -`test/test.js`: -```js -const os = require("os"); -const path = require("path"); -const { expect } = require("chai"); -const { spawn, spawnSync } = require("child_process"); -const { Builder, By, Capabilities } = require("selenium-webdriver"); - -// create the path to the expected application binary -const application = path.resolve( - __dirname, - "..", - "..", - "..", - "target", - "release", - "hello-tauri-webdriver" -); - -// keep track of the webdriver instance we create -let driver; - -// keep track of the tauri-driver process we start -let tauriDriver; - -before(async function() { - // set timeout to 2 minutes to allow the program to build if it needs to - this.timeout(120000) - - // ensure the program has been built - spawnSync("cargo", ["build", "--release"]); - - // start tauri-driver - tauriDriver = spawn( - path.resolve(os.homedir(), ".cargo", "bin", "tauri-driver"), - [], - { stdio: [null, process.stdout, process.stderr] } - ); - - const capabilities = new Capabilities(); - capabilities.set("tauri:options", { application }); - capabilities.setBrowserName("wry"); - - // start the webdriver client - driver = await new Builder() - .withCapabilities(capabilities) - .usingServer("http://localhost:4444/") - .build(); -}); - -after(async function() { - // stop the webdriver session - await driver.quit(); - - // kill the tauri-driver process - tauriDriver.kill(); -}); - -describe("Hello Tauri", () => { - it("should be cordial", async () => { - const text = await driver.findElement(By.css("body > h1")).getText(); - expect(text).to.match(/^[hH]ello/); - }); - - it("should be excited", async () => { - const text = await driver.findElement(By.css("body > h1")).getText(); - expect(text).to.match(/!$/); - }); - - it("should be easy on the eyes", async () => { - // selenium returns color css values as rgb(r, g, b) - const text = await driver.findElement(By.css("body")).getCssValue("background-color"); - - const rgb = text.match(/^rgb\((?\d+), (?\d+), (?\d+)\)$/).groups; - expect(rgb).to.have.all.keys('r','g','b'); - - const luma = 0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b ; - expect(luma).to.be.lessThan(100) - }); -}); -``` - -If you are familiar with JS testing frameworks, `describe`, `it`, and `expect` should look familiar. We also have -semi-complex `before()` and `after()` callbacks to setup and teardown mocha. Lines that are not the tests themselves -have comments explaining what the setup and teardown code is doing. If you were familiar with the Spec file from the -[WebdriverIO example](webdriverio#spec), you will notice a lot more code that isn't tests, as we have to set up a few -more WebDriver related items. - -## Running the Test Suite - -Now that we are all set up with our dependencies and our test script, lets run it! - - - - -```sh -npm test -``` - - - - - -```sh -yarn test -``` - - - - -We should see output the following output: - -```text -➜ selenium git:(main) ✗ yarn test -yarn run v1.22.11 -$ mocha - - - Hello Tauri - ✔ should be cordial (120ms) - ✔ should be excited - ✔ should be easy on the eyes - - - 3 passing (588ms) - -Done in 0.93s. -``` - -We can see that our `Hello Tauri` sweet we created with `decribe` had all 3 items we created with `it` pass their -tests! - -With [Selenium] and some hooking up to a test suite, we just enabled e2e testing without modifying our Tauri -application at all! - - -[Selenium]: https://selenium.dev/ -[finished example project]: https://github.com/chippers/hello_tauri -[example Application setup]: setup -[Mocha]: https://mochajs.org/ -[Chai]: https://www.chaijs.com/ -[`selenium-webdriver`]: https://www.npmjs.com/package/selenium-webdriver diff --git a/docs/usage/guides/webdriver/example/setup.md b/docs/usage/guides/webdriver/example/setup.md deleted file mode 100644 index a2ff6de28e83..000000000000 --- a/docs/usage/guides/webdriver/example/setup.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: Setup Example ---- - -import HelloTauriWebdriver from '@site/static/img/webdriver/hello-tauri-webdriver.png' - -This example application is going to solely focus on adding WebDriver testing to an already existing project. To have a -project to test on in the next two sections, we are going to set up an extremely minimal Tauri application for use in -our testing. We will not use the Tauri CLI, any frontend dependencies or build steps, and not be bundling the -application afterwards. This is to showcase exactly a minimal suite to show off adding WebDriver testing to an existing -application. - -If you just want to see the finished example project that utilizes what will be shown in this example guide, then you -can see https://github.com/chippers/hello_tauri. - -## Initializing a Cargo Project - -We want to create a new binary Cargo project to house this example application. We can easily do this from the command -line with `cargo new hello-tauri-webdriver --bin` which will scaffold a minimal binary Cargo project for us. This -directory will serve as the working directory for the rest of this guide, so make sure commands you run are inside this -new `hello-tauri-webdriver/` directory. - -## Creating a Minimal Frontend - -We will create a minimal HTML file to act as the frontend to our example application. We will also be using a few things -from this frontend later during our WebDriver tests. - -First, let's create our Tauri `distDir` that we know we will need once building the Tauri portion of the application. -`mkdir dist` should create a new directory called `dist/` in which we will be placing the following `index.html` file. - -`dist/index.html`: - -```html - - - - - Hello Tauri! - - - -

Hello, Tauri!

- - -``` - -## Adding Tauri to the Cargo Project - -Next, we will add some necessary items to make our Cargo project into a Tauri project. First, is adding the dependencies -to the Cargo Manifest (`Cargo.toml`) so that Cargo knows to pull in our dependencies while building. - -`Cargo.toml`: - -```toml -[package] -name = "hello-tauri-webdriver" -version = "0.1.0" -edition = "2018" - -# Needed to set up some things for Tauri at build time -[build-dependencies] -tauri-build = "1.0.0-beta.4" - -# The actual Tauri dependency, along with `custom-protocol` to serve the pages. -[dependencies] -tauri = { version = "1.0.0-beta.6", features = ["custom-protocol"] } - -# Make --release build a binary that is small (opt-level = "s") and fast (lto = true). -# This is completely optional, but shows that testing the application as close to the -# typical release settings is possible. Note: this will slow down compilation. -[profile.release] -incremental = false -codegen-units = 1 -panic = "abort" -opt-level = "s" -lto = true -``` - -As you may have noticed, we added a `[build-dependency]`. To use the build dependency, we must use it from a build -script. We will create one now at `build.rs`. - -`build.rs`: - -```rust -fn main() { - // Only watch the `dist/` directory for recompiling, preventing unnecessary - // changes when we change files in other project subdirectories. - println!("cargo:rerun-if-changed=dist"); - - // Run the Tauri build-time helpers - tauri_build::build() -} -``` - -With all that setup, our Cargo Project now knows how to pull in and build our Tauri dependencies. Let's finish making -this minimal example a Tauri application by setting up Tauri in the actual project code. We will be editing -the `src/main.rs` -file to add this Tauri functionality. - -`src/main.rs`: - -```rust -fn main() { - tauri::Builder::default() - .run(tauri::generate_context!()) - .expect("unable to run Tauri application"); -} -``` - -Pretty simple, right? - -## Tauri Configuration - -We are going to need 2 things to successfully build the application. First, we need an icon file. You can use any PNG -for this next part and copy it into `icon.png`. Typically, this will be provided as part of the scaffolding when you use -the Tauri CLI to create a project. To get the default Tauri icon, we can download the icon used by the Hello Tauri -example repository with the -command `curl -L "https://github.com/chippers/hello_tauri/raw/main/icon.png" --output icon.png`. - -The second thing we will need is a `tauri.conf.json` to specify some important configuration values to Tauri. Again, -this would typically come from the `tauri init` scaffolding command, but we will be creating our own minimal config -here. - -`tauri.conf.json`: - -```json -{ - "build": { - "distDir": "dist" - }, - "tauri": { - "bundle": { - "identifier": "studio.tauri.hello_tauri_webdriver", - "icon": [ - "icon.png" - ] - }, - "allowlist": { - "all": false - }, - "windows": [ - { - "width": 800, - "height": 600, - "resizable": true, - "fullscreen": false - } - ] - } -} -``` - -I'll go over some of these. You can see the `dist/` directory we created earlier specified as the `distDir` property. We -set a bundle identifier so that the built application has a unique id, along with setting the `icon.png` as the only -icon. We aren't using any Tauri apis or features, so we just disable all them in `allowlist` by setting `"all": false`. -The window values just sets a single window to be created with some reasonable default values. - -At this point, we have a basic Hello World application that when ran, should display a simple greeting. - -## Running the Example Application - -To make sure we did it right, let's build this application! We will run this as a `--release` application because we -will also run our WebDriver tests with a release profile. Run `cargo run --release` and after some compiling we should -see the following application pop up. - -
- -
- -_Note: If you are modifying the application and want to use the Devtools, then run it without `--release` and "Inspect -Element" should be available in the right click menu._ - -We should now be ready to start testing this application with some WebDriver frameworks. This guide will go over both -[WebdriverIO](webdriverio) and [Selenium](selenium) in that order. \ No newline at end of file diff --git a/docs/usage/guides/webdriver/example/webdriverio.md b/docs/usage/guides/webdriver/example/webdriverio.md deleted file mode 100644 index 3697f914c4d3..000000000000 --- a/docs/usage/guides/webdriver/example/webdriverio.md +++ /dev/null @@ -1,275 +0,0 @@ ---- -title: WebdriverIO ---- -import Alert from '@theme/Alert' -import Tabs from '@theme/Tabs' -import TabItem from '@theme/TabItem' - - - -This [WebdriverIO] guide expects you to have already gone through the [example Application setup] in order to follow -step-by-step. The general information may still be useful otherwise. - - -This WebDriver testing example will use [WebdriverIO] and its testing suite. It is expected to already have Node.js -installed, along with `npm` or `yarn` although the [finished example project] uses `yarn`. - -## Create a Directory for the Tests - -Let's start off by creating a space in our project to write these tests. We are going to be using a nested directory for -this example project as we will later also go over other frameworks, but typically you will only need to use one. Create -the directory we will use with `mkdir -p webdriver/webdriverio`. The rest of this guide will assume you are inside the -`webdriver/webdriverio` directory. - -## Initializing a WebdriverIO Project - -We will be using a pre-existing `package.json` to bootstrap this test suite because we have already chosen specific -[WebdriverIO] config options and want to showcase a simple working solution. The bottom of this section has a collapsed -guide on how to set it up from scratch. - -`package.json`: -```json -{ - "name": "webdriverio", - "version": "1.0.0", - "private": true, - "scripts": { - "test": "wdio run wdio.conf.js" - }, - "dependencies": { - "@wdio/cli": "^7.9.1" - }, - "devDependencies": { - "@wdio/local-runner": "^7.9.1", - "@wdio/mocha-framework": "^7.9.1", - "@wdio/spec-reporter": "^7.9.0" - } -} -``` - -We have a script which runs a [WebdriverIO] config as a test suite exposed as the `test` command. We also have various -dependencies that were added by the `@wdio/cli` command when we first set it up. In short, these dependencies are for -the most simple setup using a local WebDriver runner, [Mocha] as the test framework, and a simple Spec Reporter. - -
Click me if you want to see how to set a project up from scratch - -The CLI is interactive, and you may choose the tools to work with yourself. Note that you will likely diverge from -the rest of the guide, and need to set up the differences yourself. - -Let's add the [WebdriverIO] CLI to this npm project. - - - - -```sh -npm install @wdio/cli -``` - - - - - -```sh -yarn add @wdio/cli -``` - - - - -To then run the interactive config command to set up a [WebdriverIO] test suite, you can then run: - - - - -```sh -npx wdio config -``` - - - - - -```sh -yarn wdio config -``` - - - - -
- -## Config - -You may have noticed that the `test` script in our `package.json` mentions a file `wdio.conf.js`. That's the [WebdriverIO] -config file which controls most aspects of our testing suite. - -`wdio.conf.js`: -```js -const os = require("os"); -const path = require("path"); -const { spawn, spawnSync } = require("child_process"); - -// keep track of the `tauri-driver` child process -let tauriDriver; - -exports.config = { - specs: ["./test/specs/**/*.js"], - maxInstances: 1, - capabilities: [ - { - maxInstances: 1, - "tauri:options": { - application: "../../target/release/hello-tauri-webdriver", - }, - }, - ], - reporters: ["spec"], - framework: "mocha", - mochaOpts: { - ui: "bdd", - timeout: 60000, - }, - - // ensure the rust project is built since we expect this binary to exist for the webdriver sessions - onPrepare: () => spawnSync("cargo", ["build", "--release"]), - - // ensure we are running `tauri-driver` before the session starts so that we can proxy the webdriver requests - beforeSession: () => - (tauriDriver = spawn( - path.resolve(os.homedir(), ".cargo", "bin", "tauri-driver"), - [], - { stdio: [null, process.stdout, process.stderr] } - )), - - // clean up the `tauri-driver` process we spawned at the start of the session - afterSession: () => tauriDriver.kill(), -}; -``` - -If you are interested in the properties on `exports.config` object, then I [suggest reading the documentation] for it. -For non-WDIO specific items, there are comments explaining why we are running commands in `onPrepare`, `beforeSession`, -and `afterSession`. We also have our specs set to `"./test/specs/**/*.js"`, so let's create a spec now. - -## Spec - -A spec contains the code that is testing your actual application. The test runner will load these specs and automatically -run them as it sees fit. Let's create our spec now in the directory we specified. - -`test/specs/example.e2e.js`: -```js -// calculates the luma from a hex color `#abcdef` -function luma(hex) { - if (hex.startsWith("#")) { - hex = hex.substring(1); - } - - const rgb = parseInt(hex, 16); - const r = (rgb >> 16) & 0xff; - const g = (rgb >> 8) & 0xff; - const b = (rgb >> 0) & 0xff; - return 0.2126 * r + 0.7152 * g + 0.0722 * b; -} - -describe("Hello Tauri", () => { - it("should be cordial", async () => { - const header = await $("body > h1"); - const text = await header.getText(); - expect(text).toMatch(/^[hH]ello/); - }); - - it("should be excited", async () => { - const header = await $("body > h1"); - const text = await header.getText(); - expect(text).toMatch(/!$/); - }); - - it("should be easy on the eyes", async () => { - const body = await $("body"); - const backgroundColor = await body.getCSSProperty("background-color"); - expect(luma(backgroundColor.parsed.hex)).toBeLessThan(100); - }); -}); -``` - -The `luma` function on top is just a helper function for one of our tests and is not related to the actual testing of -the application. If you are familiar with other testing frameworks, you may notice similar functions being exposed that -are used such as `describe`, `it`, and `expect`. The other APIs, such as items like `$` and the methods it exposes is -covered by the [WebdriverIO API docs](https://webdriver.io/docs/api). - -## Running the Test Suite - -Now that we are all set up with a config and a spec, let's run it! - - - - -```sh -npm test -``` - - - - - -```sh -yarn test -``` - - - - -We should see output the following output: - -```text -➜ webdriverio git:(main) ✗ yarn test -yarn run v1.22.11 -$ wdio run wdio.conf.js - -Execution of 1 workers started at 2021-08-17T08:06:10.279Z - -[0-0] RUNNING in undefined - /test/specs/example.e2e.js -[0-0] PASSED in undefined - /test/specs/example.e2e.js - - "spec" Reporter: ------------------------------------------------------------------- -[wry 0.12.1 linux #0-0] Running: wry (v0.12.1) on linux -[wry 0.12.1 linux #0-0] Session ID: 81e0107b-4d38-4eed-9b10-ee80ca47bb83 -[wry 0.12.1 linux #0-0] -[wry 0.12.1 linux #0-0] » /test/specs/example.e2e.js -[wry 0.12.1 linux #0-0] Hello Tauri -[wry 0.12.1 linux #0-0] ✓ should be cordial -[wry 0.12.1 linux #0-0] ✓ should be excited -[wry 0.12.1 linux #0-0] ✓ should be easy on the eyes -[wry 0.12.1 linux #0-0] -[wry 0.12.1 linux #0-0] 3 passing (244ms) - - -Spec Files: 1 passed, 1 total (100% completed) in 00:00:01 - -Done in 1.98s. -``` - -We see the Spec Reporter tell us that all 3 tests from the `test/specs/example.e2e.js` file, along with the final report -`Spec Files: 1 passed, 1 total (100% completed) in 00:00:01`. - -Using the [WebdriverIO] test suite, we just easily enabled e2e testing for our Tauri application from just a few lines -of configuration and a single command to run it! Even better, we didn't have to modify the application at all. - - -[WebdriverIO]: https://webdriver.io/ -[finished example project]: https://github.com/chippers/hello_tauri -[example Application setup]: setup -[Mocha]: https://mochajs.org/ -[suggest reading the documentation]: (https://webdriver.io/docs/configurationfile) diff --git a/docs/usage/guides/webdriver/introduction.md b/docs/usage/guides/webdriver/introduction.md deleted file mode 100644 index dc87ecd2de01..000000000000 --- a/docs/usage/guides/webdriver/introduction.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Introduction ---- -import Alert from '@theme/Alert' - - - -Webdriver support for Tauri is still in pre-alpha. Tooling that is dedicated to it such as [tauri-driver] is still in -active development and may change as necessary over time. Additionally, only Windows and Linux are currently supported. - - -[WebDriver] is a standardized interface to interact with web documents that is primarily intended for automated testing. -Tauri supports the [WebDriver] interface by leveraging the native platform's [WebDriver] server underneath a -cross-platform wrapper [`tauri-driver`]. - -## System Dependencies - -Install the latest [`tauri-driver`] or update an existing installation by running: - -```sh -cargo install tauri-driver -``` - -Because we currently utilize the platform's native [WebDriver] server, there are some requirements for running -[`tauri-driver`] on supported platforms. Platform support is currently limited to Linux and Windows. - -### Linux - -We use `WebKitWebDriver` on linux platforms. Check if this binary exists already (command `which WebKitWebDriver`) as -some distributions bundle it with the regular webkit package. Other platforms may have a separate package for them such -as `webkit2gtk-driver` on Debian based distributions. - -### Windows - -Make sure to grab the version of [Microsoft Edge Driver] that matches your Windows' Edge version that the application is -being built and tested on. On up-to-date Window installs, this should almost always be the latest stable version. If the -two versions do not match, you may experience your WebDriver testing suite hanging while trying to connect. - -The download contains a binary called `msedgedriver.exe`. [`tauri-driver`] looks for that binary in the `$PATH` so make -sure it's either available on the path or use the `--native-driver` option on [`tauri-driver`]. On Windows CI machines, -you may want to download this automatically as part of the CI setup process to ensure the Edge and Edge Driver versions -stay in sync. A guide on how to do this may be added at a later date. - -## Example Application - -The [next section](example/setup) of the guide will show step-by-step how to create a minimal example application that -is tested with WebDriver. - -If you prefer to just see the result of the guide and look over a finished minimal codebase that utilizes it then you -can look at https://github.com/chippers/hello_tauri. That example also comes with a CI script to test with GitHub -actions, but you may still be interested in the [WebDriver CI](ci) guide as it explains the concept a bit more. - -[WebDriver]: https://www.w3.org/TR/webdriver/ -[`tauri-driver`]: https://crates.io/crates/tauri-driver -[tauri-driver]: https://crates.io/crates/tauri-driver -[Microsoft Edge Driver]: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ diff --git a/docs/usage/intro.md b/docs/usage/intro.md deleted file mode 100644 index 7cf3267d0b93..000000000000 --- a/docs/usage/intro.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Introduction ---- - -This part of the documentation is dedicated to learning how to use Tauri. - -Tauri provides a [CLI](/docs/api/cli), a Rust API, and a [JavaScript API](/docs/api/js/index) that you can use in your project. Because raw docs can be quite scary to newcomers (especially people who have never played with Rust before), we've created this "learn by example" section. - -Here you will find guides and techniques to add to your own project in order to fulfill your goals. - -## A Step Further - -- [Understanding Tauri Patterns](/docs/usage/patterns/about-patterns) -- [Add Tauri to my existing project](/docs/usage/development/integration) -- [Tauri Development Cycle](/docs/usage/development/development) - -## Guides - -- [How to embed custom binaries](/docs/usage/guides/bundler/sidecar) -- [How to customize app icons](/docs/usage/guides/visual/icons) diff --git a/docs/usage/patterns/about-patterns.md b/docs/usage/patterns/about-patterns.md deleted file mode 100644 index 3577f79f8178..000000000000 --- a/docs/usage/patterns/about-patterns.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -id: about-patterns -title: "A word on patterns" -sidebar_label: A word on patterns ---- - -Tauri patterns are descriptions of use-cases that are entirely configurable within the `src-tauri/tauri.conf.json` file. These are not the limits of what Tauri can do, and there are probably more out there. If you discover one, why not get in touch and help us update this collection! - -If you haven't read about the general design of Tauri, then it would make the most sense for you to visit the ["Getting started"](/docs/getting-started/intro) and become familiar with the basic architecture and terminology used in these patterns. diff --git a/docs/usage/patterns/bridge.md b/docs/usage/patterns/bridge.md deleted file mode 100644 index ea9fb7a9cfe2..000000000000 --- a/docs/usage/patterns/bridge.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Bridge ---- - -import Rater from '@theme/Rater' -import useBaseUrl from '@docusaurus/useBaseUrl' - -
-
- - - - - - - - - - - - - - - - - -
Ease of Use
Extensibility
Performance
Security
-
-
- Bridge -
-
- Pros: -
    -
  • Highly configurable
  • -
  • No Rust skills required
  • -
- Cons: -
    -
  • Some WebAPIs unavailable
  • -
  • Challenge to implement
  • -
-
-
- -## Description - -The Bridge recipe is a secure pattern where messages are passed between brokers via an implicit bridge using the API. It isolates functionality to scope and passes messages instead of functionality. - -## Diagram - -import Mermaid, { colors } from '@theme/Mermaid' - -F - subgraph WEBVIEW - F-.-E - end - D-->E - E-->D - B-->D - D-->B - subgraph RUST - A==>H - A-->B - B-.-C - B-.-G - end - A[Binary] - B{Rust Broker} - C[Subprocess 2] - G[Subprocess 1] - D(( API BRIDGE )) - E{JS Broker} - F[Window] - H{Bootstrap} - style D fill:#ccc,stroke:#333,stroke-width:4px,color:white - style RUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px - style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`} /> - -## Configuration - -Here's what you need to add to your tauri.conf.json file: -```json -"tauri": { - "allowlist": { // all API values are default false - "all": false, // use this flag to enable all API features - "shell": { - "execute": false, // enable application execution - "open": false, // open link/path in the default app - }, - "fs": { - "listFiles": false, // list files in a directory - "readBinaryFile": false, // read binary file from local filesystem - "readTextFile": false, // read text file from local filesystem - "setTitle": false, // set the window title - "writeFile": false // write file to local filesystem - } - } -} - -``` diff --git a/docs/usage/patterns/cloudbridge.md b/docs/usage/patterns/cloudbridge.md deleted file mode 100644 index 73ec4bdab3d8..000000000000 --- a/docs/usage/patterns/cloudbridge.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Cloudbridge ---- - -import Rater from '@theme/Rater' -import useBaseUrl from '@docusaurus/useBaseUrl' - -
-
- - - - - - - - - - - - - - - - - -
Ease of Use
Extensibility
Performance
Security
-
-
- Cloudbridge -
-
- Pros: -
    -
  • All available features
  • -
  • No Rust skills required
  • -
- Cons: -
    -
  • Largest bundle size
  • -
  • Hard to separate concerns
  • -
-
-
- -## Description - -The Cloudbridge recipe combines the flexibility of a localhost and the security of the bridge. With so many features, it can be easy to get lost. - -## Diagram - -import Mermaid, { colors } from '@theme/Mermaid' - -F2 - H==>D2 - D2-->F2 - F2-->D2 - B-->D - D-->B - E2-->D - D-->E2 - subgraph WEBVIEW - F2 - E2 - end - subgraph SERVER - D2 - E-->D2 - end - subgraph RUST - A==>H - A-->B - B-.-C - end - A[Binary] - B{Rust Broker} - C[Subprocess] - D(( API BRIDGE )) - E{JS Broker} - D2(( localhost )) - E[bundled resources] - E2{JS Broker} - F2[Window] - H{Bootstrap} - style D fill:#ccc,stroke:#333,stroke-width:4px,color:white - style RUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px - style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px - style SERVER fill:#49A24A,stroke:#2B6063,stroke-width:4px - `} /> - - -## Configuration - -Here's what you need to add to your tauri.conf.json file: -```json -"tauri": { - "allowlist": { - "all": true // enable entire API - } -} -``` diff --git a/docs/usage/patterns/cloudish.md b/docs/usage/patterns/cloudish.md deleted file mode 100644 index 4e511b8d269c..000000000000 --- a/docs/usage/patterns/cloudish.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: Cloudish ---- - -import Rater from '@theme/Rater' -import useBaseUrl from '@docusaurus/useBaseUrl' - -
-
- - - - - - - - - - - - - - - - - -
Ease of Use
Extensibility
Performance
Security
-
-
- Cloudish -
-
- Pros: -
    -
  • Similar to a SPA web-app
  • -
  • No Rust skills required
  • -
- Cons: -
    -
  • No access to Rust API
  • -
  • Uses a localhost server
  • -
-
-
- -## Description - -The Cloudish recipe is a pattern for maximum flexibility and app performance. It uses a localhost server, which means that your app will technically be available to other processes, like browsers and potentially other devices on the network. All of your assets are baked into the binary, but served as if they were distinct files. - -## Diagram - -import Mermaid, { colors } from '@theme/Mermaid' - -F - H==>D - D-->F - F-->D - subgraph RUST - A==>H - end - subgraph WEBVIEW - F - end - subgraph SERVER - D - E-->D - end - A[Binary] - D(( localhost )) - E[bundled resources] - F[Window] - H{Bootstrap} - style RUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px - style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px - style SERVER fill:#49A24A,stroke:#2B6063,stroke-width:4px`} /> - - -## Configuration - -Here's what you need to add to your tauri.conf.json file: -```json -"tauri": { - "allowlist": { - "all": false // disable entire API - } -} - -``` diff --git a/docs/usage/patterns/glui.md b/docs/usage/patterns/glui.md deleted file mode 100644 index 82504e37a41a..000000000000 --- a/docs/usage/patterns/glui.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: GLUI ---- - -import Alert from '@theme/Alert' -import useBaseUrl from '@docusaurus/useBaseUrl' - - -This pattern is not available for now. - - -import Rater from '@theme/Rater' - -
-
- - - - - - - - - - - - - - - - - -
Ease of Use
Extensibility
Performance
Security
-
-
- GLUI -
-
- Pros: -
    -
  • Framebuffer FTW
  • -
  • Window events rigged
  • -
- Cons: -
    -
  • Broken on your machine
  • -
-
-
- -## Description - -The GLUI is a research pattern that we will use internally to test approaches using a GLUTIN window. We’re not sure yet if it will make the final cut as a bona fide alternative to WebView, although early tests with transparent and multiwindow are exciting. - -## Diagram - -import Mermaid, { colors } from '@theme/Mermaid' - -H - H==>G - A-->D - D-->G - subgraph GLUTIN - G - end - subgraph RUST - A - end - A[Binary] - D(Framebuffer) - G[GL Window] - H{Bootstrap} - style GLUTIN stroke:${colors.blue.dark},stroke-width:4px - style RUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px`} /> - - -## Configuration - -Here's what you need to add to your tauri.conf.json file: -```json -"tauri": { - "allowlist": { // all API endpoints are default false - "all": false, // disable the api - }, - "window": { // not yet normative - "glutin": true, - "webview": false - } -} -``` diff --git a/docs/usage/patterns/hermit.md b/docs/usage/patterns/hermit.md deleted file mode 100644 index 659281f0120d..000000000000 --- a/docs/usage/patterns/hermit.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Hermit ---- - -import Rater from '@theme/Rater' -import useBaseUrl from '@docusaurus/useBaseUrl' - -
-
- - - - - - - - - - - - - - - - - -
Ease of Use
Extensibility
Performance
Security
-
-
- Hermit -
-
- Pros: -
    -
  • Quick to make
  • -
  • Smallest size
  • -
- Cons: -
    -
  • No remote resources
  • -
  • No access to API
  • -
-
-
- -## Description - -The Hermit recipe is a pattern for ultimate application isolation where all logic is self-contained in the Window and the binary exists merely to bootstrap the Window. There is no communication back to Rust from the Window, there is no localhost server, and the Window has no access to any remote resources. The Hermit is great for interactive Kiosk Mode and standalone HTML based games. - -## Diagram - -import Mermaid, { colors } from '@theme/Mermaid' - -H - H==>F - subgraph WEBVIEW - F - end - subgraph RUST - A - end - A[fa:fa-cog Binary ] - F[fa:fa-window-maximize Window] - H{Bootstrap} - style RUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px - style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`} /> - -## Configuration - -Here's what you need to add to your tauri.conf.json file: - -```json -"tauri": { - "allowlist": { - "all": false, // disable and tree-shake all api functions - } -} -``` diff --git a/docs/usage/patterns/lockdown.md b/docs/usage/patterns/lockdown.md deleted file mode 100644 index 75dfbd4e5703..000000000000 --- a/docs/usage/patterns/lockdown.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: Lockdown ---- - -import Rater from '@theme/Rater' -import useBaseUrl from '@docusaurus/useBaseUrl' - -
-
- - - - - - - - - - - - - - - - - -
Ease of Use
Extensibility
Performance
Security
-
-
- Lockdown -
-
- Pros: -
    -
  • Highest security rating
  • -
  • Elegant and powerful
  • -
- Cons: -
    -
  • Rust skills required
  • -
  • No remote resources
  • -
-
-
- - -## Description - -The Lockdown recipe is a minimal usage of the [Bridge pattern](/docs/usage/patterns/bridge), which only allows interaction between Rust and the Window via expiring JS Promise Closures that are injected into the Window by Rust and nulled as part of the callback. - -## Diagram - -import Mermaid, { colors } from '@theme/Mermaid' - -F - G-.->B - B-->G - subgraph WEBVIEW - G-->F - end - subgraph RUST - A-->B - A==>H - end - A[Binary] - B[API:Event] - F[Window] - G((Promise Closure)) - H{Bootstrap} - style RUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px - style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`} /> - - -## Configuration - -Here's what you need to add to your tauri.conf.json file: -```json -"tauri": { - "allowlist": {} // all API endpoints are default false -} -``` diff --git a/docs/usage/patterns/multiwin.md b/docs/usage/patterns/multiwin.md deleted file mode 100644 index 5d890623ac4f..000000000000 --- a/docs/usage/patterns/multiwin.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Multiwin ---- - -import Alert from '@theme/Alert' -import useBaseUrl from '@docusaurus/useBaseUrl' - -import Rater from '@theme/Rater' - -
-
- - - - - - - - - - - - - - - - - -
Ease of Use
Extensibility
Performance
Security
-
-
- Multiwin -
-
- Pros: -
    -
  • Windows can be spawned or destroyed at runtime
  • -
  • Separation of concerns
  • -
- Cons: -
    -
  • Somewhat complex
  • -
-
-
- -## Description - -The Multiwin recipe will allow you to have multiple windows. - -## Diagram - -import Mermaid, { colors } from '@theme/Mermaid' - -H - H==>F - H==>G - subgraph WEBVIEW - F - end - subgraph WINIT - G - end - subgraph RUST - A - end - A[Binary] - F[Window] - G[Window] - H{Bootstrap} - style WINIT stroke:${colors.blue.dark},stroke-width:4px - style RUST fill:${colors.orange.light},stroke:${colors.orange.dark},stroke-width:4px - style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`} /> - - -## Configuration - -Here's what you need to add to your tauri.conf.json file: -```json -"tauri": { - "allowlist": {}, // all API endpoints are default false - "windows": [{ - "title": "Window1", - "label": "main", - }, { - "title": "Splash", - "label": "splashscreen" - }] -} - -``` diff --git a/examples/.icons/icon.icns b/examples/.icons/icon.icns index 43c73bda9674..8254645a797e 100644 Binary files a/examples/.icons/icon.icns and b/examples/.icons/icon.icns differ diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 000000000000..3db0e7ea6a77 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,5 @@ +# Examples + +Following directories contain examples of tauri app functionality. + +There are different execution steps depending on the example. See each directory `README.md` for execution method. diff --git a/examples/api/.gitignore b/examples/api/.gitignore index da93220bc349..7c9b894420ed 100644 --- a/examples/api/.gitignore +++ b/examples/api/.gitignore @@ -1,4 +1,3 @@ /node_modules/ -/public/build/ - +/.vscode/ .DS_Store diff --git a/examples/api/README.md b/examples/api/README.md index 2fcfe4bc4018..d9fe94b1f479 100644 --- a/examples/api/README.md +++ b/examples/api/README.md @@ -5,21 +5,13 @@ In the future, this app will be used on Tauri's integration tests. ![App screenshot](./screenshot.png?raw=true) ## Running the example -- Install dependencies (Run inside of this folder tauri/examples/api/) -```bash -# with yarn -$ yarn -# with npm -$ npm install -``` - -- Compile tauri -go to root of the tauri repo and run +- Compile Tauri +go to root of the Tauri repo and run: Linux / Mac: ``` # choose to install node cli (1) -sh .scripts/setup.sh +bash .scripts/setup.sh ``` Windows: @@ -27,7 +19,15 @@ Windows: ./.scripts/setup.ps1 ``` -- Compile the app (Run inside of this folder tauri/examples/api/) +- Install dependencies (Run inside of this folder `examples/api/`) +```bash +# with yarn +$ yarn +# with npm +$ npm install +``` + +- Run the app in development mode (Run inside of this folder `examples/api/`) ```bash # with yarn $ yarn tauri dev @@ -35,7 +35,8 @@ $ yarn tauri dev $ npm run tauri dev ``` -- Run the app +- Build an run the release app (Run inside of this folder `examples/api/`) ```bash +$ yarn tauri build $ ./src-tauri/target/release/app ``` diff --git a/examples/api/dist/assets/index.css b/examples/api/dist/assets/index.css new file mode 100644 index 000000000000..bb235641fc94 --- /dev/null +++ b/examples/api/dist/assets/index.css @@ -0,0 +1 @@ +#dialog-filter.svelte-1eg58yg{width:260px}#request-body.svelte-1xfmj7b{width:100%;margin-right:10px;font-size:12px}form.svelte-1tppwwz.svelte-1tppwwz{margin-top:24px}.flex-row.svelte-1tppwwz.svelte-1tppwwz{flex-direction:row}.grow.svelte-1tppwwz.svelte-1tppwwz{flex-grow:1}.window-controls.svelte-1tppwwz input.svelte-1tppwwz{width:50px}.window-property.svelte-1tppwwz.svelte-1tppwwz{margin-top:12px}.window-property.svelte-1tppwwz span.svelte-1tppwwz{font-size:.8rem}.env-vars.svelte-1g38c1n{width:300px}.container.svelte-1fam3xt{margin:1em}.view-container.svelte-1fam3xt{width:15em;margin-left:.5em}#response.svelte-1fam3xt{white-space:pre-line} diff --git a/examples/api/dist/assets/index.js b/examples/api/dist/assets/index.js new file mode 100644 index 000000000000..e97cd6f2a1bd --- /dev/null +++ b/examples/api/dist/assets/index.js @@ -0,0 +1,39 @@ +var Io=Object.defineProperty,qo=Object.defineProperties;var No=Object.getOwnPropertyDescriptors;var Fi=Object.getOwnPropertySymbols;var Bo=Object.prototype.hasOwnProperty,Go=Object.prototype.propertyIsEnumerable;var Hi=(e,t,n)=>t in e?Io(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Ui=(e,t)=>{for(var n in t||(t={}))Bo.call(t,n)&&Hi(e,n,t[n]);if(Fi)for(var n of Fi(t))Go.call(t,n)&&Hi(e,n,t[n]);return e},Ii=(e,t)=>qo(e,No(t));import{S as K,i as X,s as Y,e as u,a as v,t as S,b as a,c as O,d as r,l as T,f as G,n as I,g as W,r as x,o as $e,h as On,j as E,p as Ke,k as de,m as Vo,q as qi,u as Xe,v as Ni,w as J,x as Bi,y as Gi,z as Vi,A as Ji,B as $i,C as Ki,D as Jo,E as Xi,F as Yi,G as $o,H as Ko,I as Xo}from"./vendor.js";const Yo=function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const l of o)if(l.type==="childList")for(const s of l.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&i(s)}).observe(document,{childList:!0,subtree:!0});function n(o){const l={};return o.integrity&&(l.integrity=o.integrity),o.referrerpolicy&&(l.referrerPolicy=o.referrerpolicy),o.crossorigin==="use-credentials"?l.credentials="include":o.crossorigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function i(o){if(o.ep)return;o.ep=!0;const l=n(o);fetch(o.href,l)}};Yo();/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */var Qi=function(e,t){return(Qi=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,i){n.__proto__=i}||function(n,i){for(var o in i)Object.prototype.hasOwnProperty.call(i,o)&&(n[o]=i[o])})(e,t)};function Wn(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}Qi(e,t),e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var dt=function(){return(dt=Object.assign||function(e){for(var t,n=1,i=arguments.length;n0&&o[o.length-1])||f[0]!==6&&f[0]!==2)){s=0;continue}if(f[0]===3&&(!o||f[1]>o[0]&&f[1]{n(2,l=p)}),eo().then(p=>{n(0,i=p)}),io().then(p=>{n(1,o=p)});async function s(){await oo()}async function c(){await En()}return[i,o,l,s,c]}class tr extends K{constructor(t){super();X(this,t,xo,Zo,Y,{})}}function ro(){return _(this,void 0,void 0,function(){return g(this,function(e){return[2,z({__tauriModule:"Cli",message:{cmd:"cliMatches"}})]})})}Object.freeze({__proto__:null,getMatches:ro});function er(e){let t,n,i,o,l,s,c,p,h,f,M;return{c(){t=u("div"),n=S(`This binary can be run on the terminal and takes the following arguments: + `),i=u("ul"),i.innerHTML=`
  • --config PATH
  • +
  • --theme light|dark|system
  • +
  • --verbose
  • `,o=S(` + Additionally, it has a `),l=u("i"),l.textContent="update --background",s=S(` subcommand. + Note that the arguments are only parsed, not implemented. + `),c=u("br"),p=v(),h=u("button"),h.textContent="Get matches",a(h,"class","button"),a(h,"id","cli-matches")},m(m,d){O(m,t,d),r(t,n),r(t,i),r(t,o),r(t,l),r(t,s),r(t,c),r(t,p),r(t,h),f||(M=T(h,"click",e[0]),f=!0)},p:I,i:I,o:I,d(m){m&&W(t),f=!1,M()}}}function nr(e,t,n){let{onMessage:i}=t;function o(){ro().then(i).catch(i)}return e.$$set=l=>{"onMessage"in l&&n(1,i=l.onMessage)},[o,i]}class ir extends K{constructor(t){super();X(this,t,nr,er,Y,{onMessage:1})}}function lo(e){return _(this,void 0,void 0,function(){return g(this,function(t){return[2,z({__tauriModule:"Event",message:{cmd:"unlisten",eventId:e}})]})})}function so(e,t,n){return _(this,void 0,void 0,function(){return g(this,function(i){switch(i.label){case 0:return[4,z({__tauriModule:"Event",message:{cmd:"emit",event:e,windowLabel:t,payload:typeof n=="string"?n:JSON.stringify(n)}})];case 1:return i.sent(),[2]}})})}function Dn(e,t,n){return _(this,void 0,void 0,function(){var i=this;return g(this,function(o){return[2,z({__tauriModule:"Event",message:{cmd:"listen",event:e,windowLabel:t,handler:Wt(n)}}).then(function(l){return function(){return _(i,void 0,void 0,function(){return g(this,function(s){return[2,lo(l)]})})}})]})})}function uo(e,t,n){return _(this,void 0,void 0,function(){return g(this,function(i){return[2,Dn(e,t,function(o){n(o),lo(o.id).catch(function(){})})]})})}function pe(e,t){return _(this,void 0,void 0,function(){return g(this,function(n){return[2,Dn(e,null,t)]})})}function ao(e,t){return _(this,void 0,void 0,function(){return g(this,function(n){return[2,uo(e,null,t)]})})}function Ye(e,t){return _(this,void 0,void 0,function(){return g(this,function(n){return[2,so(e,void 0,t)]})})}Object.freeze({__proto__:null,listen:pe,once:ao,emit:Ye});function or(e){let t,n,i,o,l,s,c,p;return{c(){t=u("div"),n=u("button"),n.textContent="Call Log API",i=v(),o=u("button"),o.textContent="Call Request (async) API",l=v(),s=u("button"),s.textContent="Send event to Rust",a(n,"class","button"),a(n,"id","log"),a(o,"class","button"),a(o,"id","request"),a(s,"class","button"),a(s,"id","event")},m(h,f){O(h,t,f),r(t,n),r(t,i),r(t,o),r(t,l),r(t,s),c||(p=[T(n,"click",e[0]),T(o,"click",e[1]),T(s,"click",e[2])],c=!0)},p:I,i:I,o:I,d(h){h&&W(t),c=!1,x(p)}}}function rr(e,t,n){let{onMessage:i}=t,o;$e(async()=>{o=await pe("rust-event",i)}),On(()=>{o&&o()});function l(){fe("log_operation",{event:"tauri-click",payload:"this payload is optional because we used Option in Rust"})}function s(){fe("perform_request",{endpoint:"dummy endpoint arg",body:{id:5,name:"test"}}).then(i).catch(i)}function c(){Ye("js-event","this is the payload string")}return e.$$set=p=>{"onMessage"in p&&n(3,i=p.onMessage)},[l,s,c,i]}class lr extends K{constructor(t){super();X(this,t,rr,or,Y,{onMessage:3})}}function Rn(e){return e===void 0&&(e={}),_(this,void 0,void 0,function(){return g(this,function(t){return typeof e=="object"&&Object.freeze(e),[2,z({__tauriModule:"Dialog",message:{cmd:"openDialog",options:e}})]})})}function co(e){return e===void 0&&(e={}),_(this,void 0,void 0,function(){return g(this,function(t){return typeof e=="object"&&Object.freeze(e),[2,z({__tauriModule:"Dialog",message:{cmd:"saveDialog",options:e}})]})})}function sr(e){return _(this,void 0,void 0,function(){return g(this,function(t){return[2,z({__tauriModule:"Dialog",message:{cmd:"messageDialog",message:e}})]})})}function ur(e,t){return _(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"Dialog",message:{cmd:"askDialog",title:t,message:e}})]})})}function ar(e,t){return _(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"Dialog",message:{cmd:"confirmDialog",title:t,message:e}})]})})}Object.freeze({__proto__:null,open:Rn,save:co,message:sr,ask:ur,confirm:ar});var Bt;function cr(e,t){return t===void 0&&(t={}),_(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"Fs",message:{cmd:"readFile",path:e,options:t}}).then(function(i){return new TextDecoder().decode(new Uint8Array(i))})]})})}function jn(e,t){return t===void 0&&(t={}),_(this,void 0,void 0,function(){var n;return g(this,function(i){switch(i.label){case 0:return[4,z({__tauriModule:"Fs",message:{cmd:"readFile",path:e,options:t}})];case 1:return n=i.sent(),[2,Uint8Array.from(n)]}})})}function dr(e,t){return t===void 0&&(t={}),_(this,void 0,void 0,function(){return g(this,function(n){return typeof t=="object"&&Object.freeze(t),typeof e=="object"&&Object.freeze(e),[2,z({__tauriModule:"Fs",message:{cmd:"writeFile",path:e.path,contents:Array.from(new TextEncoder().encode(e.contents)),options:t}})]})})}function fr(e,t){return t===void 0&&(t={}),_(this,void 0,void 0,function(){return g(this,function(n){return typeof t=="object"&&Object.freeze(t),typeof e=="object"&&Object.freeze(e),[2,z({__tauriModule:"Fs",message:{cmd:"writeFile",path:e.path,contents:Array.from(e.contents),options:t}})]})})}function fo(e,t){return t===void 0&&(t={}),_(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"Fs",message:{cmd:"readDir",path:e,options:t}})]})})}function pr(e,t){return t===void 0&&(t={}),_(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"Fs",message:{cmd:"createDir",path:e,options:t}})]})})}function hr(e,t){return t===void 0&&(t={}),_(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"Fs",message:{cmd:"removeDir",path:e,options:t}})]})})}function mr(e,t,n){return n===void 0&&(n={}),_(this,void 0,void 0,function(){return g(this,function(i){return[2,z({__tauriModule:"Fs",message:{cmd:"copyFile",source:e,destination:t,options:n}})]})})}function vr(e,t){return t===void 0&&(t={}),_(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"Fs",message:{cmd:"removeFile",path:e,options:t}})]})})}function _r(e,t,n){return n===void 0&&(n={}),_(this,void 0,void 0,function(){return g(this,function(i){return[2,z({__tauriModule:"Fs",message:{cmd:"renameFile",oldPath:e,newPath:t,options:n}})]})})}(function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Desktop=6]="Desktop",e[e.Document=7]="Document",e[e.Download=8]="Download",e[e.Executable=9]="Executable",e[e.Font=10]="Font",e[e.Home=11]="Home",e[e.Picture=12]="Picture",e[e.Public=13]="Public",e[e.Runtime=14]="Runtime",e[e.Template=15]="Template",e[e.Video=16]="Video",e[e.Resource=17]="Resource",e[e.App=18]="App",e[e.Log=19]="Log"})(Bt||(Bt={}));Object.freeze({__proto__:null,get BaseDirectory(){return Bt},get Dir(){return Bt},readTextFile:cr,readBinaryFile:jn,writeFile:dr,writeBinaryFile:fr,readDir:fo,createDir:pr,removeDir:hr,copyFile:mr,removeFile:vr,renameFile:_r});function gr(e){let t,n,i,o,l,s,c,p,h,f,M,m,d,b,k,w,P,C,j,F;return{c(){t=u("div"),n=u("input"),i=v(),o=u("input"),l=v(),s=u("div"),c=u("input"),p=v(),h=u("label"),h.textContent="Multiple",f=v(),M=u("div"),m=u("input"),d=v(),b=u("label"),b.textContent="Directory",k=v(),w=u("button"),w.textContent="Open dialog",P=v(),C=u("button"),C.textContent="Open save dialog",a(n,"id","dialog-default-path"),a(n,"placeholder","Default path"),a(o,"id","dialog-filter"),a(o,"placeholder","Extensions filter, comma-separated"),a(o,"class","svelte-1eg58yg"),a(c,"type","checkbox"),a(c,"id","dialog-multiple"),a(h,"for","dialog-multiple"),a(m,"type","checkbox"),a(m,"id","dialog-directory"),a(b,"for","dialog-directory"),a(w,"class","button"),a(w,"id","open-dialog"),a(C,"class","button"),a(C,"id","save-dialog")},m(H,A){O(H,t,A),r(t,n),E(n,e[0]),r(t,i),r(t,o),E(o,e[1]),r(t,l),r(t,s),r(s,c),c.checked=e[2],r(s,p),r(s,h),r(t,f),r(t,M),r(M,m),m.checked=e[3],r(M,d),r(M,b),r(t,k),r(t,w),r(t,P),r(t,C),j||(F=[T(n,"input",e[8]),T(o,"input",e[9]),T(c,"change",e[10]),T(m,"change",e[11]),T(w,"click",e[4]),T(C,"click",e[5])],j=!0)},p(H,[A]){A&1&&n.value!==H[0]&&E(n,H[0]),A&2&&o.value!==H[1]&&E(o,H[1]),A&4&&(c.checked=H[2]),A&8&&(m.checked=H[3])},i:I,o:I,d(H){H&&W(t),j=!1,x(F)}}}function br(e,t){var n=new Blob([e],{type:"application/octet-binary"}),i=new FileReader;i.onload=function(o){var l=o.target.result;t(l.substr(l.indexOf(",")+1))},i.readAsDataURL(n)}function wr(e,t,n){let{onMessage:i}=t,{insecureRenderHtml:o}=t,l=null,s=null,c=!1,p=!1;function h(){Rn({title:"My wonderful open dialog",defaultPath:l,filters:s?[{name:"Tauri Example",extensions:s.split(",").map(k=>k.trim())}]:[],multiple:c,directory:p}).then(function(k){if(Array.isArray(k))i(k);else{var w=k,P=w.match(/\S+\.\S+$/g);jn(w).then(function(C){P&&(w.includes(".png")||w.includes(".jpg"))?br(new Uint8Array(C),function(j){var F="data:image/png;base64,"+j;o('')}):i(k)}).catch(i(k))}}).catch(i)}function f(){co({title:"My wonderful save dialog",defaultPath:l,filters:s?[{name:"Tauri Example",extensions:s.split(",").map(k=>k.trim())}]:[]}).then(i).catch(i)}function M(){l=this.value,n(0,l)}function m(){s=this.value,n(1,s)}function d(){c=this.checked,n(2,c)}function b(){p=this.checked,n(3,p)}return e.$$set=k=>{"onMessage"in k&&n(6,i=k.onMessage),"insecureRenderHtml"in k&&n(7,o=k.insecureRenderHtml)},[l,s,c,p,h,f,i,o,M,m,d,b]}class yr extends K{constructor(t){super();X(this,t,wr,gr,Y,{onMessage:6,insecureRenderHtml:7})}}function po(e,t,n){const i=e.slice();return i[9]=t[n],i}function ho(e){let t,n=e[9][0]+"",i,o;return{c(){t=u("option"),i=S(n),t.__value=o=e[9][1],t.value=t.__value},m(l,s){O(l,t,s),r(t,i)},p:I,d(l){l&&W(t)}}}function Mr(e){let t,n,i,o,l,s,c,p,h,f,M,m,d,b=e[2],k=[];for(let w=0;wisNaN(parseInt(m))).map(m=>[m,Bt[m]]);function p(){const m=l.match(/\S+\.\S+$/g),d={dir:mo()};(m?jn(l,d):fo(l,d)).then(function(k){if(m)if(l.includes(".png")||l.includes(".jpg"))kr(new Uint8Array(k),function(w){const P="data:image/png;base64,"+w;o('')});else{const w=String.fromCharCode.apply(null,k);o(''),setTimeout(()=>{const P=document.getElementById("file-response");P.value=w,document.getElementById("file-save").addEventListener("click",function(){writeFile({file:l,contents:P.value},{dir:mo()}).catch(i)})})}else i(k)}).catch(i)}function h(){n(1,s.src=Zi(l),s)}function f(){l=this.value,n(0,l)}function M(m){Vo[m?"unshift":"push"](()=>{s=m,n(1,s)})}return e.$$set=m=>{"onMessage"in m&&n(5,i=m.onMessage),"insecureRenderHtml"in m&&n(6,o=m.insecureRenderHtml)},[l,s,c,p,h,i,o,f,M]}class Tr extends K{constructor(t){super();X(this,t,zr,Mr,Y,{onMessage:5,insecureRenderHtml:6})}}var he;(function(e){e[e.JSON=1]="JSON",e[e.Text=2]="Text",e[e.Binary=3]="Binary"})(he||(he={}));var Fn=function(){function e(t,n){this.type=t,this.payload=n}return e.form=function(t){var n={};for(var i in t){var o=t[i];n[i]=typeof o=="string"?o:Array.from(o)}return new e("Form",n)},e.json=function(t){return new e("Json",t)},e.text=function(t){return new e("Text",t)},e.bytes=function(t){return new e("Bytes",Array.from(t))},e}(),vo=function(e){this.url=e.url,this.status=e.status,this.ok=this.status>=200&&this.status<300,this.headers=e.headers,this.rawHeaders=e.rawHeaders,this.data=e.data},_o=function(){function e(t){this.id=t}return e.prototype.drop=function(){return _(this,void 0,void 0,function(){return g(this,function(t){return[2,z({__tauriModule:"Http",message:{cmd:"dropClient",client:this.id}})]})})},e.prototype.request=function(t){return _(this,void 0,void 0,function(){var n;return g(this,function(i){return(n=!t.responseType||t.responseType===he.JSON)&&(t.responseType=he.Text),[2,z({__tauriModule:"Http",message:{cmd:"httpRequest",client:this.id,options:t}}).then(function(o){var l=new vo(o);if(n){try{l.data=JSON.parse(l.data)}catch(s){if(l.ok&&l.data==="")l.data={};else if(l.ok)throw Error("Failed to parse response `".concat(l.data,"` as JSON: ").concat(s,";\n try setting the `responseType` option to `ResponseType.Text` or `ResponseType.Binary` if the API does not return a JSON response."))}return l}return l})]})})},e.prototype.get=function(t,n){return _(this,void 0,void 0,function(){return g(this,function(i){return[2,this.request(dt({method:"GET",url:t},n))]})})},e.prototype.post=function(t,n,i){return _(this,void 0,void 0,function(){return g(this,function(o){return[2,this.request(dt({method:"POST",url:t,body:n},i))]})})},e.prototype.put=function(t,n,i){return _(this,void 0,void 0,function(){return g(this,function(o){return[2,this.request(dt({method:"PUT",url:t,body:n},i))]})})},e.prototype.patch=function(t,n){return _(this,void 0,void 0,function(){return g(this,function(i){return[2,this.request(dt({method:"PATCH",url:t},n))]})})},e.prototype.delete=function(t,n){return _(this,void 0,void 0,function(){return g(this,function(i){return[2,this.request(dt({method:"DELETE",url:t},n))]})})},e}();function Hn(e){return _(this,void 0,void 0,function(){return g(this,function(t){return[2,z({__tauriModule:"Http",message:{cmd:"createClient",options:e}}).then(function(n){return new _o(n)})]})})}var Un=null;function Cr(e,t){var n;return _(this,void 0,void 0,function(){return g(this,function(i){switch(i.label){case 0:return Un!==null?[3,2]:[4,Hn()];case 1:Un=i.sent(),i.label=2;case 2:return[2,Un.request(dt({url:e,method:(n=t==null?void 0:t.method)!==null&&n!==void 0?n:"GET"},t))]}})})}Object.freeze({__proto__:null,getClient:Hn,fetch:Cr,Body:Fn,Client:_o,Response:vo,get ResponseType(){return he}});function Sr(e){let t,n,i,o,l,s,c,p,h,f,M,m,d,b,k,w,P;return{c(){t=u("form"),n=u("select"),i=u("option"),i.textContent="GET",o=u("option"),o.textContent="POST",l=u("option"),l.textContent="PUT",s=u("option"),s.textContent="PATCH",c=u("option"),c.textContent="DELETE",p=v(),h=u("input"),f=v(),M=u("br"),m=v(),d=u("textarea"),b=v(),k=u("button"),k.textContent="Make request",i.__value="GET",i.value=i.__value,o.__value="POST",o.value=o.__value,l.__value="PUT",l.value=l.__value,s.__value="PATCH",s.value=s.__value,c.__value="DELETE",c.value=c.__value,a(n,"class","button"),a(n,"id","request-method"),e[0]===void 0&&qi(()=>e[5].call(n)),a(h,"id","request-url"),a(h,"placeholder","Type the request URL..."),a(d,"id","request-body"),a(d,"placeholder","Request body"),a(d,"rows","5"),a(d,"class","svelte-1xfmj7b"),a(k,"class","button"),a(k,"id","make-request")},m(C,j){O(C,t,j),r(t,n),r(n,i),r(n,o),r(n,l),r(n,s),r(n,c),Xe(n,e[0]),r(t,p),r(t,h),E(h,e[1]),r(t,f),r(t,M),r(t,m),r(t,d),E(d,e[2]),r(t,b),r(t,k),w||(P=[T(n,"change",e[5]),T(h,"input",e[6]),T(d,"input",e[7]),T(t,"submit",Ke(e[3]))],w=!0)},p(C,[j]){j&1&&Xe(n,C[0]),j&2&&h.value!==C[1]&&E(h,C[1]),j&4&&E(d,C[2])},i:I,o:I,d(C){C&&W(t),w=!1,x(P)}}}function Pr(e,t,n){let i="GET",o="https://jsonplaceholder.typicode.com/todos/1",l="",{onMessage:s}=t;async function c(){const M=await Hn().catch(k=>{throw s(k),k}),b={url:o||""||"",method:i||"GET"||"GET"};l.startsWith("{")&&l.endsWith("}")||l.startsWith("[")&&l.endsWith("]")?b.body=Fn.json(JSON.parse(l)):l!==""&&(b.body=Fn.text(l)),M.request(b).then(s).catch(s)}function p(){i=Ni(this),n(0,i)}function h(){o=this.value,n(1,o)}function f(){l=this.value,n(2,l)}return e.$$set=M=>{"onMessage"in M&&n(4,s=M.onMessage)},[i,o,l,c,s,p,h,f]}class Or extends K{constructor(t){super();X(this,t,Pr,Sr,Y,{onMessage:4})}}function Wr(e){let t,n,i;return{c(){t=u("button"),t.textContent="Send test notification",a(t,"class","button"),a(t,"id","notification")},m(o,l){O(o,t,l),n||(i=T(t,"click",Ar),n=!0)},p:I,i:I,o:I,d(o){o&&W(t),n=!1,i()}}}function Ar(){new Notification("Notification title",{body:"This is the notification body"})}function Lr(e,t,n){let{onMessage:i}=t;return e.$$set=o=>{"onMessage"in o&&n(0,i=o.onMessage)},[i]}class Er extends K{constructor(t){super();X(this,t,Lr,Wr,Y,{onMessage:0})}}var me,Qe=function(e,t){this.type="Logical",this.width=e,this.height=t},Gt=function(){function e(t,n){this.type="Physical",this.width=t,this.height=n}return e.prototype.toLogical=function(t){return new Qe(this.width/t,this.height/t)},e}(),go=function(e,t){this.type="Logical",this.x=e,this.y=t},Vt=function(){function e(t,n){this.type="Physical",this.x=t,this.y=n}return e.prototype.toLogical=function(t){return new go(this.x/t,this.y/t)},e}();function Dr(){return new ve(window.__TAURI_METADATA__.__currentWindow.label,{skip:!0})}function bo(){return window.__TAURI_METADATA__.__windows.map(function(e){return new ve(e.label,{skip:!0})})}(function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"})(me||(me={}));var wo=["tauri://created","tauri://error"],yo=function(){function e(t){this.label=t,this.listeners=Object.create(null)}return e.prototype.listen=function(t,n){return _(this,void 0,void 0,function(){var i=this;return g(this,function(o){return this._handleTauriEvent(t,n)?[2,Promise.resolve(function(){var l=i.listeners[t];l.splice(l.indexOf(n),1)})]:[2,Dn(t,this.label,n)]})})},e.prototype.once=function(t,n){return _(this,void 0,void 0,function(){var i=this;return g(this,function(o){return this._handleTauriEvent(t,n)?[2,Promise.resolve(function(){var l=i.listeners[t];l.splice(l.indexOf(n),1)})]:[2,uo(t,this.label,n)]})})},e.prototype.emit=function(t,n){return _(this,void 0,void 0,function(){var i,o;return g(this,function(l){if(wo.includes(t)){for(i=0,o=this.listeners[t]||[];ie[31].call(n)),a(s,"type","checkbox"),a(f,"type","checkbox"),a(d,"title","Unminimizes after 2 seconds"),a(k,"title","Unminimizes after 2 seconds"),a(P,"title","Visible again after 2 seconds"),a(F,"type","checkbox"),a(N,"type","checkbox"),a(B,"type","checkbox"),a(Q,"type","checkbox"),a(it,"type","number"),a(it,"min","0"),a(it,"class","svelte-1tppwwz"),a(ot,"type","number"),a(ot,"min","0"),a(ot,"class","svelte-1tppwwz"),a(ft,"class","flex col grow svelte-1tppwwz"),a(rt,"type","number"),a(rt,"min","400"),a(rt,"class","svelte-1tppwwz"),a(lt,"type","number"),a(lt,"min","400"),a(lt,"class","svelte-1tppwwz"),a(pt,"class","flex col grow svelte-1tppwwz"),a(ht,"type","number"),a(ht,"class","svelte-1tppwwz"),a(mt,"type","number"),a(mt,"class","svelte-1tppwwz"),a(q,"class","flex col grow svelte-1tppwwz"),a(at,"type","number"),a(at,"min","400"),a(at,"class","svelte-1tppwwz"),a(ct,"type","number"),a(ct,"min","400"),a(ct,"class","svelte-1tppwwz"),a(jt,"class","flex col grow svelte-1tppwwz"),a(et,"class","window-controls flex flex-row svelte-1tppwwz"),a(t,"class","flex col"),a($t,"class","svelte-1tppwwz"),a(Kt,"class","svelte-1tppwwz"),a(vt,"class","grow window-property svelte-1tppwwz"),a(Xt,"class","svelte-1tppwwz"),a(Yt,"class","svelte-1tppwwz"),a(_t,"class","grow window-property svelte-1tppwwz"),a(Ft,"class","flex"),a(Qt,"class","svelte-1tppwwz"),a(Zt,"class","svelte-1tppwwz"),a(gt,"class","grow window-property svelte-1tppwwz"),a(xt,"class","svelte-1tppwwz"),a(te,"class","svelte-1tppwwz"),a(bt,"class","grow window-property svelte-1tppwwz"),a(Ht,"class","flex"),a(ee,"class","svelte-1tppwwz"),a(ne,"class","svelte-1tppwwz"),a(wt,"class","grow window-property svelte-1tppwwz"),a(ie,"class","svelte-1tppwwz"),a(oe,"class","svelte-1tppwwz"),a(yt,"class","grow window-property svelte-1tppwwz"),a(Ut,"class","flex"),a(re,"class","svelte-1tppwwz"),a(le,"class","svelte-1tppwwz"),a(Mt,"class","grow window-property svelte-1tppwwz"),a(se,"class","svelte-1tppwwz"),a(ue,"class","svelte-1tppwwz"),a(kt,"class","grow window-property svelte-1tppwwz"),a(It,"class","flex"),a(St,"id","title"),a(ae,"class","button"),a(ae,"type","submit"),a(zt,"class","svelte-1tppwwz"),a(Pt,"id","url"),a(ce,"class","button"),a(ce,"id","open-url"),a(Tt,"class","svelte-1tppwwz"),a(Ot,"class","button"),a(Ot,"title","Minimizes the window, requests attention for 3s and then resets it"),a(qt,"class","button")},m(y,L){O(y,t,L),r(t,n);for(let V=0;V{typeof q=="string"&&o[i].setIcon(q)})}function ge(){const q=Math.random().toString().replace(".",""),Ct=new ve(q);n(1,o[q]=Ct,o),Ct.once("tauri://error",function(){l("Error creating new webview")})}function At(){o[i].innerSize().then(q=>{n(20,N=q),n(7,d=N.width),n(8,b=N.height)}),o[i].outerSize().then(q=>{n(21,tt=q)})}function be(){o[i].innerPosition().then(q=>{n(18,A=q)}),o[i].outerPosition().then(q=>{n(19,U=q),n(13,j=U.x),n(14,F=U.y)})}async function Jt(q){ut&&ut(),$&&$(),$=await q.listen("tauri://move",be),ut=await q.listen("tauri://resize",At)}async function et(){await o[i].minimize(),await o[i].requestUserAttention(me.Critical),await new Promise(q=>setTimeout(q,3e3)),await o[i].requestUserAttention(null)}function ft(){i=Ni(this),n(0,i),n(1,o)}function Lt(){c=this.checked,n(2,c)}function we(){p=this.checked,n(3,p)}const it=()=>o[i].center();function ye(){h=this.checked,n(16,h)}function Et(){f=this.checked,n(4,f)}function Me(){M=this.checked,n(5,M)}function ot(){m=this.checked,n(6,m)}function ke(){j=J(this.value),n(13,j)}function pt(){F=J(this.value),n(14,F)}function Dt(){d=J(this.value),n(7,d)}function ze(){b=J(this.value),n(8,b)}function rt(){k=J(this.value),n(9,k)}function Te(){w=J(this.value),n(10,w)}function Rt(){P=J(this.value),n(11,P)}function Ce(){C=J(this.value),n(12,C)}function lt(){B=this.value,n(22,B)}function Se(){s=this.value,n(15,s)}return e.$$set=q=>{"onMessage"in q&&n(30,l=q.onMessage)},e.$$.update=()=>{e.$$.dirty[0]&7&&o[i].setResizable(c),e.$$.dirty[0]&11&&(p?o[i].maximize():o[i].unmaximize()),e.$$.dirty[0]&19&&o[i].setDecorations(f),e.$$.dirty[0]&35&&o[i].setAlwaysOnTop(M),e.$$.dirty[0]&67&&o[i].setFullscreen(m),e.$$.dirty[0]&387&&o[i].setSize(new Gt(d,b)),e.$$.dirty[0]&1539&&(k&&w?o[i].setMinSize(new Qe(k,w)):o[i].setMinSize(null)),e.$$.dirty[0]&6147&&(P&&C?o[i].setMaxSize(new Qe(P,C)):o[i].setMaxSize(null)),e.$$.dirty[0]&24579&&o[i].setPosition(new Vt(j,F)),e.$$.dirty[0]&3&&o[i].scaleFactor().then(q=>n(17,H=q)),e.$$.dirty[0]&3&&Jt(o[i])},[i,o,c,p,f,M,m,d,b,k,w,P,C,j,F,s,h,H,A,U,N,tt,B,R,nt,D,Q,_e,ge,et,l,ft,Lt,we,it,ye,Et,Me,ot,ke,pt,Dt,ze,rt,Te,Rt,Ce,lt,Se]}class Ir extends K{constructor(t){super();X(this,t,Ur,Hr,Y,{onMessage:30},[-1,-1])}}function To(e,t){return _(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"GlobalShortcut",message:{cmd:"register",shortcut:e,handler:Wt(t)}})]})})}function qr(e,t){return _(this,void 0,void 0,function(){return g(this,function(n){return[2,z({__tauriModule:"GlobalShortcut",message:{cmd:"registerAll",shortcuts:e,handler:Wt(t)}})]})})}function Nr(e){return _(this,void 0,void 0,function(){return g(this,function(t){return[2,z({__tauriModule:"GlobalShortcut",message:{cmd:"isRegistered",shortcut:e}})]})})}function Co(e){return _(this,void 0,void 0,function(){return g(this,function(t){return[2,z({__tauriModule:"GlobalShortcut",message:{cmd:"unregister",shortcut:e}})]})})}function So(){return _(this,void 0,void 0,function(){return g(this,function(e){return[2,z({__tauriModule:"GlobalShortcut",message:{cmd:"unregisterAll"}})]})})}Object.freeze({__proto__:null,register:To,registerAll:qr,isRegistered:Nr,unregister:Co,unregisterAll:So});function Po(e,t,n){const i=e.slice();return i[9]=t[n],i}function Oo(e){let t,n=e[9]+"",i,o,l,s,c;function p(){return e[8](e[9])}return{c(){t=u("div"),i=S(n),o=v(),l=u("button"),l.textContent="Unregister",a(l,"type","button")},m(h,f){O(h,t,f),r(t,i),r(t,o),r(t,l),s||(c=T(l,"click",p),s=!0)},p(h,f){e=h,f&2&&n!==(n=e[9]+"")&&G(i,n)},d(h){h&&W(t),s=!1,c()}}}function Wo(e){let t,n,i;return{c(){t=u("button"),t.textContent="Unregister all",a(t,"type","button")},m(o,l){O(o,t,l),n||(i=T(t,"click",e[5]),n=!0)},p:I,d(o){o&&W(t),n=!1,i()}}}function Br(e){let t,n,i,o,l,s,c,p,h,f,M=e[1],m=[];for(let b=0;bn(1,i=m));let s="CmdOrControl+X";function c(){const m=s;To(m,()=>{o(`Shortcut ${m} triggered`)}).then(()=>{l.update(d=>[...d,m]),o(`Shortcut ${m} registered successfully`)}).catch(o)}function p(m){const d=m;Co(d).then(()=>{l.update(b=>b.filter(k=>k!==d)),o(`Shortcut ${d} unregistered`)}).catch(o)}function h(){So().then(()=>{l.update(()=>[]),o("Unregistered all shortcuts")}).catch(o)}function f(){s=this.value,n(0,s)}const M=m=>p(m);return e.$$set=m=>{"onMessage"in m&&n(6,o=m.onMessage)},[s,i,l,c,p,h,o,f,M]}class Vr extends K{constructor(t){super();X(this,t,Gr,Br,Y,{onMessage:6})}}function Ao(e){let t,n,i,o,l;return{c(){t=u("input"),n=v(),i=u("button"),i.textContent="Write",a(t,"placeholder","write to stdin"),a(i,"class","button")},m(s,c){O(s,t,c),E(t,e[3]),O(s,n,c),O(s,i,c),o||(l=[T(t,"input",e[10]),T(i,"click",e[7])],o=!0)},p(s,c){c&8&&t.value!==s[3]&&E(t,s[3])},d(s){s&&W(t),s&&W(n),s&&W(i),o=!1,x(l)}}}function Jr(e){let t,n,i,o,l,s,c,p,h,f,M,m,d,b,k,w=e[4]&&Ao(e);return{c(){t=u("div"),n=u("div"),i=u("input"),o=v(),l=u("button"),l.textContent="Run",s=v(),c=u("button"),c.textContent="Kill",p=v(),w&&w.c(),h=v(),f=u("div"),M=u("input"),m=v(),d=u("input"),a(l,"class","button"),a(c,"class","button"),a(M,"placeholder","Working directory"),a(d,"class","env-vars svelte-1g38c1n"),a(d,"placeholder","Environment variables")},m(P,C){O(P,t,C),r(t,n),r(n,i),E(i,e[0]),r(n,o),r(n,l),r(n,s),r(n,c),r(n,p),w&&w.m(n,null),r(t,h),r(t,f),r(f,M),E(M,e[1]),r(f,m),r(f,d),E(d,e[2]),b||(k=[T(i,"input",e[9]),T(l,"click",e[5]),T(c,"click",e[6]),T(M,"input",e[11]),T(d,"input",e[12])],b=!0)},p(P,[C]){C&1&&i.value!==P[0]&&E(i,P[0]),P[4]?w?w.p(P,C):(w=Ao(P),w.c(),w.m(n,null)):w&&(w.d(1),w=null),C&2&&M.value!==P[1]&&E(M,P[1]),C&4&&d.value!==P[2]&&E(d,P[2])},i:I,o:I,d(P){P&&W(t),w&&w.d(),b=!1,x(k)}}}function $r(e,t,n){const i=navigator.userAgent.includes("Windows");let o=i?"cmd":"sh",l=i?["/C"]:["-c"],{onMessage:s}=t,c='echo "hello world"',p=null,h="SOMETHING=value ANOTHER=2",f="",M;function m(){return h.split(" ").reduce((F,H)=>{let[A,U]=H.split("=");return Ii(Ui({},F),{[A]:U})},{})}function d(){n(4,M=null);const F=new to(o,[...l,c],{cwd:p||null,env:m()});F.on("close",H=>{s(`command finished with code ${H.code} and signal ${H.signal}`),n(4,M=null)}),F.on("error",H=>s(`command error: "${H}"`)),F.stdout.on("data",H=>s(`command stdout: "${H}"`)),F.stderr.on("data",H=>s(`command stderr: "${H}"`)),F.spawn().then(H=>{n(4,M=H)}).catch(s)}function b(){M.kill().then(()=>s("killed child process")).catch(s)}function k(){M.write(f).catch(s)}function w(){c=this.value,n(0,c)}function P(){f=this.value,n(3,f)}function C(){p=this.value,n(1,p)}function j(){h=this.value,n(2,h)}return e.$$set=F=>{"onMessage"in F&&n(8,s=F.onMessage)},[c,p,h,f,M,d,b,k,s,w,P,C,j]}class Kr extends K{constructor(t){super();X(this,t,$r,Jr,Y,{onMessage:8})}}function Lo(){return _(this,void 0,void 0,function(){function e(){t&&t(),t=void 0}var t;return g(this,function(n){return[2,new Promise(function(i,o){pe("tauri://update-status",function(l){var s;(s=l==null?void 0:l.payload).error?(e(),o(s.error)):s.status==="DONE"&&(e(),i())}).then(function(l){t=l}).catch(function(l){throw e(),l}),Ye("tauri://update-install").catch(function(l){throw e(),l})})]})})}function Eo(){return _(this,void 0,void 0,function(){function e(){t&&t(),t=void 0}var t;return g(this,function(n){return[2,new Promise(function(i,o){ao("tauri://update-available",function(l){var s;s=l==null?void 0:l.payload,e(),i({manifest:s,shouldUpdate:!0})}).catch(function(l){throw e(),l}),pe("tauri://update-status",function(l){var s;(s=l==null?void 0:l.payload).error?(e(),o(s.error)):s.status==="UPTODATE"&&(e(),i({shouldUpdate:!1}))}).then(function(l){t=l}).catch(function(l){throw e(),l}),Ye("tauri://update").catch(function(l){throw e(),l})})]})})}Object.freeze({__proto__:null,installUpdate:Lo,checkUpdate:Eo});function Xr(e){let t,n,i,o,l,s;return{c(){t=u("div"),n=u("button"),n.textContent="Check update",i=v(),o=u("button"),o.textContent="Install update",a(n,"class","button"),a(n,"id","check_update"),a(o,"class","button hidden"),a(o,"id","start_update")},m(c,p){O(c,t,p),r(t,n),r(t,i),r(t,o),l||(s=[T(n,"click",e[0]),T(o,"click",e[1])],l=!0)},p:I,i:I,o:I,d(c){c&&W(t),l=!1,x(s)}}}function Yr(e,t,n){let{onMessage:i}=t,o;$e(async()=>{o=await pe("tauri://update-status",i)}),On(()=>{o&&o()});async function l(){try{document.getElementById("check_update").classList.add("hidden");const{shouldUpdate:c,manifest:p}=await Eo();i(`Should update: ${c}`),i(p),c&&document.getElementById("start_update").classList.remove("hidden")}catch(c){i(c)}}async function s(){try{document.getElementById("start_update").classList.add("hidden"),await Lo(),i("Installation complete, restart required."),await En()}catch(c){i(c)}}return e.$$set=c=>{"onMessage"in c&&n(2,i=c.onMessage)},[l,s,i]}class Qr extends K{constructor(t){super();X(this,t,Yr,Xr,Y,{onMessage:2})}}function Do(e){return _(this,void 0,void 0,function(){return g(this,function(t){return[2,z({__tauriModule:"Clipboard",message:{cmd:"writeText",data:e}})]})})}function Ro(){return _(this,void 0,void 0,function(){return g(this,function(e){return[2,z({__tauriModule:"Clipboard",message:{cmd:"readText"}})]})})}Object.freeze({__proto__:null,writeText:Do,readText:Ro});function Zr(e){let t,n,i,o,l,s,c,p,h;return{c(){t=u("div"),n=u("div"),i=u("input"),o=v(),l=u("button"),l.textContent="Write",s=v(),c=u("button"),c.textContent="Read",a(i,"placeholder","Text to write to the clipboard"),a(l,"type","button"),a(c,"type","button")},m(f,M){O(f,t,M),r(t,n),r(n,i),E(i,e[0]),r(n,o),r(n,l),r(t,s),r(t,c),p||(h=[T(i,"input",e[4]),T(l,"click",e[1]),T(c,"click",e[2])],p=!0)},p(f,[M]){M&1&&i.value!==f[0]&&E(i,f[0])},i:I,o:I,d(f){f&&W(t),p=!1,x(h)}}}function xr(e,t,n){let{onMessage:i}=t,o="clipboard message";function l(){Do(o).then(()=>{i("Wrote to the clipboard")}).catch(i)}function s(){Ro().then(p=>{i(`Clipboard contents: ${p}`)}).catch(i)}function c(){o=this.value,n(0,o)}return e.$$set=p=>{"onMessage"in p&&n(3,i=p.onMessage)},[o,l,s,i,c]}class tl extends K{constructor(t){super();X(this,t,xr,Zr,Y,{onMessage:3})}}function el(e){let t;return{c(){t=u("div"),t.innerHTML=`

    Not available for Linux

    + `},m(n,i){O(n,t,i)},p:I,i:I,o:I,d(n){n&&W(t)}}}function nl(e,t,n){let{onMessage:i}=t;const o=window.constraints={audio:!0,video:!0};function l(c){const p=document.querySelector("video"),h=c.getVideoTracks();i("Got stream with constraints:",o),i(`Using video device: ${h[0].label}`),window.stream=c,p.srcObject=c}function s(c){if(c.name==="ConstraintNotSatisfiedError"){const p=o.video;i(`The resolution ${p.width.exact}x${p.height.exact} px is not supported by your device.`)}else c.name==="PermissionDeniedError"&&i("Permissions have not been granted to use your camera and microphone, you need to allow the page access to your devices in order for the demo to work.");i(`getUserMedia error: ${c.name}`,c)}return $e(async()=>{try{const c=await navigator.mediaDevices.getUserMedia(o);l(c)}catch(c){s(c)}}),On(()=>{window.stream.getTracks().forEach(function(c){c.stop()})}),e.$$set=c=>{"onMessage"in c&&n(0,i=c.onMessage)},[i]}class il extends K{constructor(t){super();X(this,t,nl,el,Y,{onMessage:0})}}function ol(e){let t,n,i,o,l,s,c,p,h,f,M,m;return{c(){t=u("input"),n=v(),i=u("input"),o=v(),l=u("button"),l.textContent="Post it.",s=v(),c=u("p"),c.textContent="Result:",p=v(),h=u("pre"),f=S(e[2]),a(l,"type","button")},m(d,b){O(d,t,b),E(t,e[0]),O(d,n,b),O(d,i,b),E(i,e[1]),O(d,o,b),O(d,l,b),O(d,s,b),O(d,c,b),O(d,p,b),O(d,h,b),r(h,f),M||(m=[T(t,"input",e[4]),T(i,"input",e[5]),T(l,"click",e[3])],M=!0)},p(d,[b]){b&1&&t.value!==d[0]&&E(t,d[0]),b&2&&i.value!==d[1]&&E(i,d[1]),b&4&&G(f,d[2])},i:I,o:I,d(d){d&&W(t),d&&W(n),d&&W(i),d&&W(o),d&&W(l),d&&W(s),d&&W(c),d&&W(p),d&&W(h),M=!1,x(m)}}}function rl(e,t,n){let i="baz",o="qux",l=null;async function s(){let h=navigator.userAgent.includes("Windows")?"https://customprotocol.test/example.html":"customprotocol://test/example.html";const M=await(await fetch(h,{method:"POST",body:JSON.stringify({foo:i,bar:o})})).json();n(2,l=JSON.stringify(M))}function c(){i=this.value,n(0,i)}function p(){o=this.value,n(1,o)}return[i,o,l,s,c,p]}class ll extends K{constructor(t){super();X(this,t,rl,ol,Y,{})}}function jo(e,t,n){const i=e.slice();return i[10]=t[n],i}function Fo(e,t,n){const i=e.slice();return i[13]=t[n],i}function Ho(e){let t,n=e[13].label+"",i,o,l,s,c;function p(){return e[9](e[13])}return{c(){t=u("p"),i=S(n),o=v(),a(t,"class",l="nv noselect "+(e[0]===e[13]?"nv_selected":""))},m(h,f){O(h,t,f),r(t,i),r(t,o),s||(c=T(t,"click",p),s=!0)},p(h,f){e=h,f&1&&l!==(l="nv noselect "+(e[0]===e[13]?"nv_selected":""))&&a(t,"class",l)},d(h){h&&W(t),s=!1,c()}}}function sl(e){let t,n=e[10].html+"",i;return{c(){i=Vi(),t=new Xo(i)},m(o,l){t.m(n,o,l),O(o,i,l)},p(o,l){l&2&&n!==(n=o[10].html+"")&&t.p(n)},d(o){o&&W(i),o&&t.d()}}}function ul(e){let t,n=e[10].text+"",i;return{c(){t=u("p"),i=S(n)},m(o,l){O(o,t,l),r(t,i)},p(o,l){l&2&&n!==(n=o[10].text+"")&&G(i,n)},d(o){o&&W(t)}}}function Uo(e){let t;function n(l,s){return l[10].text?ul:sl}let i=n(e),o=i(e);return{c(){o.c(),t=Vi()},m(l,s){o.m(l,s),O(l,t,s)},p(l,s){i===(i=n(l))&&o?o.p(l,s):(o.d(1),o=i(l),o&&(o.c(),o.m(t.parentNode,t)))},d(l){o.d(l),l&&W(t)}}}function al(e){let t,n,i,o,l,s,c,p,h,f,M,m,d,b,k,w,P,C,j,F,H,A,U=e[2],N=[];for(let R=0;RDocumentation + Github + Source`,c=v(),p=u("div"),h=u("div");for(let R=0;R{Yi(D,1)}),Jo()}tt?(m=new tt(ut(R)),Ji(m.$$.fragment),Xi(m.$$.fragment,1),$i(m,M,null)):m=null}if(nt&2){$=R[1];let D;for(D=0;D<$.length;D+=1){const Q=jo(R,$,D);B[D]?B[D].p(Q,nt):(B[D]=Uo(Q),B[D].c(),B[D].m(b,null))}for(;D{Ko(cl,()=>{fe("menu_toggle")})});const o=[{label:"Welcome",component:tr},{label:"Messages",component:lr},{label:"CLI",component:ir},{label:"Dialog",component:yr},{label:"File system",component:Tr},{label:"HTTP",component:Or},{label:"HTTP Form",component:ll},{label:"Notifications",component:Er},{label:"Window",component:Ir},{label:"Shortcuts",component:Vr},{label:"Shell",component:Kr},{label:"Updater",component:Qr},{label:"Clipboard",component:tl},{label:"WebRTC",component:il}];let l=o[0],s=Gi([]);Bi(e,s,d=>n(1,i=d));function c(d){n(0,l=d)}function p(d){s.update(b=>[{text:`[${new Date().toLocaleTimeString()}]: `+(typeof d=="string"?d:JSON.stringify(d))},...b])}function h(d){s.update(b=>[{html:d},...b])}function f(){s.update(()=>[])}function M(){Ln("https://tauri.studio/")}return[l,i,o,s,c,p,h,f,M,d=>c(d)]}class fl extends K{constructor(t){super();X(this,t,dl,al,Y,{})}}new fl({target:document.body}); diff --git a/examples/api/dist/assets/vendor.js b/examples/api/dist/assets/vendor.js new file mode 100644 index 000000000000..3a009e0cb5cd --- /dev/null +++ b/examples/api/dist/assets/vendor.js @@ -0,0 +1,9 @@ +function w(){}function U(e){return e()}function z(){return Object.create(null)}function K(e){e.forEach(U)}function se(e){return typeof e=="function"}function fe(e,t){return e!=e?t==t:e!==t||e&&typeof e=="object"||typeof e=="function"}function oe(e){return Object.keys(e).length===0}function ae(e,...t){if(e==null)return w;const n=e.subscribe(...t);return n.unsubscribe?()=>n.unsubscribe():n}function Ae(e,t,n){e.$$.on_destroy.push(ae(t,n))}function Se(e,t){e.appendChild(t)}function ue(e,t,n){e.insertBefore(t,n||null)}function F(e){e.parentNode.removeChild(e)}function je(e,t){for(let n=0;ne.removeEventListener(t,n,i)}function Le(e){return function(t){return t.preventDefault(),e.call(this,t)}}function Te(e,t,n){n==null?e.removeAttribute(t):e.getAttribute(t)!==n&&e.setAttribute(t,n)}function Be(e){return e===""?null:+e}function le(e){return Array.from(e.childNodes)}function De(e,t){t=""+t,e.wholeText!==t&&(e.data=t)}function He(e,t){e.value=t==null?"":t}function Ne(e,t){for(let n=0;n{S.delete(e),i&&(n&&e.d(1),i())}),e.o(t)}}function Xe(e){e&&e.c()}function ye(e,t,n,i){const{fragment:r,on_mount:c,on_destroy:o,after_update:f}=e.$$;r&&r.m(t,n),i||P(()=>{const s=c.map(U).filter(se);o?o.push(...s):K(s),e.$$.on_mount=[]}),f.forEach(P)}function ge(e,t){const n=e.$$;n.fragment!==null&&(K(n.on_destroy),n.fragment&&n.fragment.d(t),n.on_destroy=n.fragment=null,n.ctx=[])}function _e(e,t){e.$$.dirty[0]===-1&&(O.push(e),pe(),e.$$.dirty.fill(0)),e.$$.dirty[t/31|0]|=1<{const y=m.length?m[0]:h;return s.ctx&&r(s.ctx[a],s.ctx[a]=y)&&(!s.skip_bound&&s.bound[a]&&s.bound[a](y),l&&_e(e,a)),h}):[],s.update(),l=!0,K(s.before_update),s.fragment=i?i(s.ctx):!1,t.target){if(t.hydrate){const a=le(t.target);s.fragment&&s.fragment.l(a),a.forEach(F)}else s.fragment&&s.fragment.c();t.intro&&me(e.$$.fragment),ye(e,t.target,t.anchor,t.customElement),J()}C(f)}class Qe{$destroy(){ge(this,1),this.$destroy=w}$on(t,n){const i=this.$$.callbacks[t]||(this.$$.callbacks[t]=[]);return i.push(n),()=>{const r=i.indexOf(n);r!==-1&&i.splice(r,1)}}$set(t){this.$$set&&!oe(t)&&(this.$$.skip_bound=!0,this.$$set(t),this.$$.skip_bound=!1)}}const x=[];function We(e,t=w){let n;const i=[];function r(f){if(fe(e,f)&&(e=f,n)){const s=!x.length;for(let l=0;l{const a=i.indexOf(l);a!==-1&&i.splice(a,1),i.length===0&&(n(),n=null)}}return{set:r,update:c,subscribe:o}}/*! + * hotkeys-js v3.8.5 + * A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies. + * + * Copyright (c) 2021 kenny wong + * http://jaywcjlove.github.io/hotkeys + * + * Licensed under the MIT license. + */var B=typeof navigator!="undefined"?navigator.userAgent.toLowerCase().indexOf("firefox")>0:!1;function D(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on".concat(t),function(){n(window.event)})}function Q(e,t){for(var n=t.slice(0,t.length-1),i=0;i=0;)t[n-1]+=",",t.splice(n,1),n=t.lastIndexOf("");return t}function be(e,t){for(var n=e.length>=t.length?e:t,i=e.length>=t.length?t:e,r=!0,c=0;c=0&&u.splice(n,1),e.key&&e.key.toLowerCase()==="meta"&&u.splice(0,u.length),(t===93||t===224)&&(t=91),t in p){p[t]=!1;for(var i in v)v[i]===t&&(_[i]=!1)}}function $e(e){if(!e)Object.keys(d).forEach(function(o){return delete d[o]});else if(Array.isArray(e))e.forEach(function(o){o.key&&H(o)});else if(typeof e=="object")e.key&&H(e);else if(typeof e=="string"){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i1?Q(v,l):[];d[m]=d[m].map(function(g){var re=r?g.method===r:!0;return re&&g.scope===i&&be(g.mods,y)?{}:g})}})};function ne(e,t,n){var i;if(t.scope===n||t.scope==="all"){i=t.mods.length>0;for(var r in p)Object.prototype.hasOwnProperty.call(p,r)&&(!p[r]&&t.mods.indexOf(+r)>-1||p[r]&&t.mods.indexOf(+r)===-1)&&(i=!1);(t.mods.length===0&&!p[16]&&!p[18]&&!p[17]&&!p[91]||i||t.shortcut==="*")&&t.method(e,t)===!1&&(e.preventDefault?e.preventDefault():e.returnValue=!1,e.stopPropagation&&e.stopPropagation(),e.cancelBubble&&(e.cancelBubble=!0))}}function ie(e){var t=d["*"],n=e.keyCode||e.which||e.charCode;if(!!_.filter.call(this,e)){if((n===93||n===224)&&(n=91),u.indexOf(n)===-1&&n!==229&&u.push(n),["ctrlKey","altKey","shiftKey","metaKey"].forEach(function(y){var g=Z[y];e[y]&&u.indexOf(g)===-1?u.push(g):!e[y]&&u.indexOf(g)>-1?u.splice(u.indexOf(g),1):y==="metaKey"&&e[y]&&u.length===3&&(e.ctrlKey||e.shiftKey||e.altKey||(u=u.slice(u.indexOf(g))))}),n in p){p[n]=!0;for(var i in v)v[i]===n&&(_[i]=!0);if(!t)return}for(var r in p)Object.prototype.hasOwnProperty.call(p,r)&&(p[r]=e[Z[r]]);e.getModifierState&&!(e.altKey&&!e.ctrlKey)&&e.getModifierState("AltGraph")&&(u.indexOf(17)===-1&&u.push(17),u.indexOf(18)===-1&&u.push(18),p[17]=!0,p[18]=!0);var c=$();if(t)for(var o=0;o-1}function _(e,t,n){u=[];var i=W(e),r=[],c="all",o=document,f=0,s=!1,l=!0,a="+";for(n===void 0&&typeof t=="function"&&(n=t),Object.prototype.toString.call(t)==="[object Object]"&&(t.scope&&(c=t.scope),t.element&&(o=t.element),t.keyup&&(s=t.keyup),t.keydown!==void 0&&(l=t.keydown),typeof t.splitKey=="string"&&(a=t.splitKey)),typeof t=="string"&&(c=t);f1&&(r=Q(v,e)),e=e[e.length-1],e=e==="*"?"*":k(e),e in d||(d[e]=[]),d[e].push({keyup:s,keydown:l,scope:c,mods:r,shortcut:i[f],method:n,key:i[f],splitKey:a});typeof o!="undefined"&&!Ee(o)&&window&&(ee.push(o),D(o,"keydown",function(h){ie(h)}),D(window,"focus",function(){u=[]}),D(o,"keyup",function(h){ie(h),Oe(h)}))}var N={setScope:te,getScope:$,deleteScope:Ke,getPressedKeyCodes:ve,isPressed:xe,filter:we,unbind:$e};for(var q in N)Object.prototype.hasOwnProperty.call(N,q)&&(_[q]=N[q]);if(typeof window!="undefined"){var Ce=window.hotkeys;_.noConflict=function(e){return e&&window.hotkeys===_&&(window.hotkeys=Ce),_},window.hotkeys=_}export{Xe as A,ye as B,Ve as C,Re as D,me as E,ge as F,Ge as G,_ as H,Ue as I,Qe as S,ke as a,Te as b,ue as c,Se as d,ce as e,De as f,F as g,Fe as h,Je as i,He as j,je as k,Pe as l,V as m,w as n,ze as o,Le as p,P as q,K as r,fe as s,G as t,Ne as u,qe as v,Be as w,Ae as x,We as y,Me as z}; diff --git a/examples/api/dist/global.css b/examples/api/dist/global.css new file mode 100644 index 000000000000..3645dd44467e --- /dev/null +++ b/examples/api/dist/global.css @@ -0,0 +1,192 @@ +@import url('https://fonts.googleapis.com/css2?family=Tauri&display=swap'); + +* { + font-family: Tauri, Arial, Helvetica, sans-serif; +} + +body { + background: rgb(24, 25, 26, 0.8); +} + +.noselect { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.logo-container { + width: 95%; + margin: 0px auto; +} + +.logo-link { + font-weight: 700; + position: absolute; + top: 150px; + right: 10px; +} + +.logo { + cursor: pointer; +} + +#response { + height: 100%; + max-height: 100%; + margin-top: 1em; + background: rgb(36, 37, 38, 0.8); + color: #f0f4f5; + border: solid 1px rgba(255, 255, 255, 0.055); + box-shadow: 0 1px 5px 0 rgb(0 0 0 / 20%); + font-family: 'Courier New', Courier, monospace; + font-size: 12px; + word-wrap: break-word; + padding: 0px 15px; + overflow-y: auto; +} + +input, +select, +textarea { + background: rgb(53, 53, 53, 0.9); + color: #fff; + font-family: system-ui, sans-serif; + border: none !important; + border-radius: 0.25rem; + font-size: 1rem; + line-height: 1.2; + padding: 0.25rem 0.5rem; + margin: 0.25rem; + transition: 0.2s ease; +} + +button:hover, +button:focus { + background: #ffe07a; +} + +button:focus { + outline: 1px solid #fff; + outline-offset: -4px; +} + +button:active { + transform: scale(0.99); +} + +.button { + border: 0; + border-radius: 0.25rem; + background: #67d6ed; + color: rgb(0, 0, 0); + font-family: system-ui, sans-serif; + font-size: 1rem; + line-height: 1.2; + white-space: nowrap; + text-decoration: none; + padding: 0.25rem 0.5rem; + margin: 0.25rem; + cursor: pointer; + transition: 0.2s ease; +} + +.dark-link { + color: white; + text-decoration: none !important; + padding: 0.5em; + background: rgb(36, 37, 38); + transition: 0.2s ease; + border: solid 1px rgba(255, 255, 255, 0.055); + box-shadow: 0 1px 5px 0 rgb(0 0 0 / 20%); +} + +.dark-link:hover { + background: #3d392a; +} + +.nv { + color: #fff; + cursor: pointer; + transition: 0.25s ease; +} + +.nv:hover { + color: #ffe07a; + padding-left: 8px; + border-left: solid 5px #ffe07a; +} + +.nv_selected { + color: #67d6ed; + padding-left: 8px; + border-left: solid 5px #67d6ed; +} + +.content { + background: rgb(36, 37, 38, 0.5); + color: #f0f4f5; + padding: 20px; + width: 100%; + border: solid 1px rgba(255, 255, 255, 0.055); + box-shadow: 0 1px 5px 0 rgb(0 0 0 / 20%); +} + +main { + height: 100%; +} + +[type='radio']:checked ~ label { + background: rgb(36, 37, 38); + color: #67d6ed; + border-bottom: 1px solid transparent; + z-index: 2; +} + +[type='radio']:checked ~ label ~ .content { + z-index: 1; +} + +.flex { + display: flex; +} + +.row { + flex-direction: row; +} + +.col { + flex-direction: column; +} + +.just-around { + justify-content: space-between; +} + +.hidden { + display: none; +} + +.alert { + width: auto; + height: 40px; + display: flex; + justify-content: left; + align-items: center; + border-radius: 5px; + padding-left: 10px; + padding-right: 40px; + font-size: 15px; + color: #000; + margin-bottom: 10px; + margin-top: 10px; + box-shadow: rgba(0, 0, 0, 0.06) 0px 0px 10px; + border-left: 6px solid #ff0000; + background: #f0f4f5; +} + +#file-response { + height: 400px; +} diff --git a/examples/api/dist/index.html b/examples/api/dist/index.html new file mode 100644 index 000000000000..988c1f27a1b9 --- /dev/null +++ b/examples/api/dist/index.html @@ -0,0 +1,17 @@ + + + + + + + Svelte + Vite App + + + + + + +
    + + + diff --git a/examples/api/dist/tauri logo.png b/examples/api/dist/tauri logo.png new file mode 100644 index 000000000000..2c53b8c4bd72 Binary files /dev/null and b/examples/api/dist/tauri logo.png differ diff --git a/examples/api/index.html b/examples/api/index.html new file mode 100644 index 000000000000..c2847e399947 --- /dev/null +++ b/examples/api/index.html @@ -0,0 +1,14 @@ + + + + + + + Svelte + Vite App + + + +
    + + + diff --git a/examples/api/isolation-dist/index.html b/examples/api/isolation-dist/index.html new file mode 100644 index 000000000000..1a12b0bc4607 --- /dev/null +++ b/examples/api/isolation-dist/index.html @@ -0,0 +1,10 @@ + + + + + Isolation Secure Script + + + + + diff --git a/examples/api/isolation-dist/index.js b/examples/api/isolation-dist/index.js new file mode 100644 index 000000000000..f3a30af5d778 --- /dev/null +++ b/examples/api/isolation-dist/index.js @@ -0,0 +1,3 @@ +window.__TAURI_ISOLATION_HOOK__= (payload) => { + return payload +} diff --git a/examples/api/jsconfig.json b/examples/api/jsconfig.json new file mode 100644 index 000000000000..42585941e160 --- /dev/null +++ b/examples/api/jsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "target": "esnext", + "module": "esnext", + /** + * svelte-preprocess cannot figure out whether you have + * a value or a type, so tell TypeScript to enforce using + * `import type` instead of `import` for Types. + */ + "importsNotUsedAsValues": "error", + "isolatedModules": true, + "resolveJsonModule": true, + /** + * To have warnings / errors of the Svelte compiler at the + * correct position, enable source maps by default. + */ + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable this if you'd like to use dynamic types. + */ + "checkJs": true + }, + /** + * Use global.d.ts instead of compilerOptions.types + * to avoid limiting type declarations. + */ + "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] +} diff --git a/examples/api/package.json b/examples/api/package.json index a5dd720483a9..53f0c67dc713 100644 --- a/examples/api/package.json +++ b/examples/api/package.json @@ -1,24 +1,20 @@ { "name": "svelte-app", "version": "1.0.0", + "type": "module", "scripts": { - "build": "rollup -c", - "dev": "rollup -c -w", - "start": "sirv public", - "tauri": "node ../../tooling/cli.js/bin/tauri" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "17.1.0", - "@rollup/plugin-node-resolve": "11.2.0", - "rollup": "2.40.0", - "rollup-plugin-livereload": "2.0.0", - "rollup-plugin-svelte": "7.1.0", - "rollup-plugin-terser": "7.0.2", - "svelte": "3.35.0" + "dev": "vite --clearScreen false --port 5000", + "build": "vite build", + "serve": "vite preview", + "tauri": "node ../../tooling/cli/node/tauri.js" }, "dependencies": { - "@tauri-apps/api": "link:../../tooling/api/dist", - "hotkeys-js": "^3.8.5", - "sirv-cli": "1.0.11" + "@tauri-apps/api": "../../tooling/api/dist", + "hotkeys-js": "^3.8.5" + }, + "devDependencies": { + "svelte": "3.35.0", + "@sveltejs/vite-plugin-svelte": "^1.0.0-next.11", + "vite": "^2.6.4" } -} +} \ No newline at end of file diff --git a/examples/api/public/build/bundle.js b/examples/api/public/build/bundle.js deleted file mode 100644 index 20f3b666bf5e..000000000000 --- a/examples/api/public/build/bundle.js +++ /dev/null @@ -1,11 +0,0 @@ -var app=function(){"use strict";function e(){}function t(e){return e()}function n(){return Object.create(null)}function i(e){e.forEach(t)}function o(e){return"function"==typeof e}function a(e,t){return e!=e?t==t:e!==t||e&&"object"==typeof e||"function"==typeof e}function s(t,n,i){t.$$.on_destroy.push(function(t,...n){if(null==t)return e;const i=t.subscribe(...n);return i.unsubscribe?()=>i.unsubscribe():i}(n,i))}function r(e,t){e.appendChild(t)}function c(e,t,n){e.insertBefore(t,n||null)}function l(e){e.parentNode.removeChild(e)}function u(e,t){for(let n=0;ne.removeEventListener(t,n,i)}function f(e){return function(t){return t.preventDefault(),e.call(this,t)}}function g(e,t,n){null==n?e.removeAttribute(t):e.getAttribute(t)!==n&&e.setAttribute(t,n)}function y(e){return""===e?null:+e}function b(e,t){t=""+t,e.wholeText!==t&&(e.data=t)}function v(e,t){e.value=null==t?"":t}function _(e,t,n,i){e.style.setProperty(t,n,i?"important":"")}function w(e,t){for(let n=0;n{U.delete(e),i&&(n&&e.d(1),i())})),e.o(t)}}function K(e){e&&e.c()}function B(e,n,a,s){const{fragment:r,on_mount:c,on_destroy:l,after_update:u}=e.$$;r&&r.m(n,a),s||j((()=>{const n=c.map(t).filter(o);l?l.push(...n):i(n),e.$$.on_mount=[]})),u.forEach(j)}function H(e,t){const n=e.$$;null!==n.fragment&&(i(n.on_destroy),n.fragment&&n.fragment.d(t),n.on_destroy=n.fragment=null,n.ctx=[])}function G(e,t){-1===e.$$.dirty[0]&&(S.push(e),W||(W=!0,A.then(F)),e.$$.dirty.fill(0)),e.$$.dirty[t/31|0]|=1<{const o=i.length?i[0]:n;return p.ctx&&r(p.ctx[e],p.ctx[e]=o)&&(!p.skip_bound&&p.bound[e]&&p.bound[e](o),h&&G(t,e)),n})):[],p.update(),h=!0,i(p.before_update),p.fragment=!!s&&s(p.ctx),o.target){if(o.hydrate){const e=function(e){return Array.from(e.childNodes)}(o.target);p.fragment&&p.fragment.l(e),e.forEach(l)}else p.fragment&&p.fragment.c();o.intro&&I(t.$$.fragment),B(t,o.target,o.anchor,o.customElement),F()}$(d)}class J{$destroy(){H(this,1),this.$destroy=e}$on(e,t){const n=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return n.push(t),()=>{const e=n.indexOf(t);-1!==e&&n.splice(e,1)}}$set(e){var t;this.$$set&&(t=e,0!==Object.keys(t).length)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const X=[];function Y(t,n=e){let i;const o=[];function s(e){if(a(t,e)&&(t=e,i)){const e=!X.length;for(let e=0;e{const e=o.indexOf(c);-1!==e&&o.splice(e,1),0===o.length&&(i(),i=null)}}}} -/*! - * hotkeys-js v3.8.5 - * A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies. - * - * Copyright (c) 2021 kenny wong - * http://jaywcjlove.github.io/hotkeys - * - * Licensed under the MIT license. - */var Q="undefined"!=typeof navigator&&navigator.userAgent.toLowerCase().indexOf("firefox")>0;function Z(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent&&e.attachEvent("on".concat(t),(function(){n(window.event)}))}function ee(e,t){for(var n=t.slice(0,t.length-1),i=0;i=0;)t[n-1]+=",",t.splice(n,1),n=t.lastIndexOf("");return t}for(var ne={backspace:8,tab:9,clear:12,enter:13,return:13,esc:27,escape:27,space:32,left:37,up:38,right:39,down:40,del:46,delete:46,ins:45,insert:45,home:36,end:35,pageup:33,pagedown:34,capslock:20,num_0:96,num_1:97,num_2:98,num_3:99,num_4:100,num_5:101,num_6:102,num_7:103,num_8:104,num_9:105,num_multiply:106,num_add:107,num_enter:108,num_subtract:109,num_decimal:110,num_divide:111,"⇪":20,",":188,".":190,"/":191,"`":192,"-":Q?173:189,"=":Q?61:187,";":Q?59:186,"'":222,"[":219,"]":221,"\\":220},ie={"⇧":16,shift:16,"⌥":18,alt:18,option:18,"⌃":17,ctrl:17,control:17,"⌘":91,cmd:91,command:91},oe={16:"shiftKey",18:"altKey",17:"ctrlKey",91:"metaKey",shiftKey:16,ctrlKey:17,altKey:18,metaKey:91},ae={16:!1,18:!1,17:!1,91:!1},se={},re=1;re<20;re++)ne["f".concat(re)]=111+re;var ce=[],le="all",ue=[],de=function(e){return ne[e.toLowerCase()]||ie[e.toLowerCase()]||e.toUpperCase().charCodeAt(0)};function pe(e){le=e||"all"}function he(){return le||"all"}var me=function(e){var t=e.key,n=e.scope,i=e.method,o=e.splitKey,a=void 0===o?"+":o;te(t).forEach((function(e){var t=e.split(a),o=t.length,s=t[o-1],r="*"===s?"*":de(s);if(se[r]){n||(n=he());var c=o>1?ee(ie,t):[];se[r]=se[r].map((function(e){return(!i||e.method===i)&&e.scope===n&&function(e,t){for(var n=e.length>=t.length?e:t,i=e.length>=t.length?t:e,o=!0,a=0;a0,ae)Object.prototype.hasOwnProperty.call(ae,o)&&(!ae[o]&&t.mods.indexOf(+o)>-1||ae[o]&&-1===t.mods.indexOf(+o))&&(i=!1);(0!==t.mods.length||ae[16]||ae[18]||ae[17]||ae[91])&&!i&&"*"!==t.shortcut||!1===t.method(e,t)&&(e.preventDefault?e.preventDefault():e.returnValue=!1,e.stopPropagation&&e.stopPropagation(),e.cancelBubble&&(e.cancelBubble=!0))}}function ge(e){var t=se["*"],n=e.keyCode||e.which||e.charCode;if(ye.filter.call(this,e)){if(93!==n&&224!==n||(n=91),-1===ce.indexOf(n)&&229!==n&&ce.push(n),["ctrlKey","altKey","shiftKey","metaKey"].forEach((function(t){var n=oe[t];e[t]&&-1===ce.indexOf(n)?ce.push(n):!e[t]&&ce.indexOf(n)>-1?ce.splice(ce.indexOf(n),1):"metaKey"===t&&e[t]&&3===ce.length&&(e.ctrlKey||e.shiftKey||e.altKey||(ce=ce.slice(ce.indexOf(n))))})),n in ae){for(var i in ae[n]=!0,ie)ie[i]===n&&(ye[i]=!0);if(!t)return}for(var o in ae)Object.prototype.hasOwnProperty.call(ae,o)&&(ae[o]=e[oe[o]]);e.getModifierState&&(!e.altKey||e.ctrlKey)&&e.getModifierState("AltGraph")&&(-1===ce.indexOf(17)&&ce.push(17),-1===ce.indexOf(18)&&ce.push(18),ae[17]=!0,ae[18]=!0);var a=he();if(t)for(var s=0;s1&&(o=ee(ie,e)),(e="*"===(e=e[e.length-1])?"*":de(e))in se||(se[e]=[]),se[e].push({keyup:c,keydown:l,scope:a,mods:o,shortcut:i[r],method:n,key:i[r],splitKey:u});void 0!==s&&!function(e){return ue.indexOf(e)>-1}(s)&&window&&(ue.push(s),Z(s,"keydown",(function(e){ge(e)})),Z(window,"focus",(function(){ce=[]})),Z(s,"keyup",(function(e){ge(e),function(e){var t=e.keyCode||e.which||e.charCode,n=ce.indexOf(t);if(n>=0&&ce.splice(n,1),e.key&&"meta"===e.key.toLowerCase()&&ce.splice(0,ce.length),93!==t&&224!==t||(t=91),t in ae)for(var i in ae[t]=!1,ie)ie[i]===t&&(ye[i]=!1)}(e)})))}var be,ve,_e={setScope:pe,getScope:he,deleteScope:function(e,t){var n,i;for(var o in e||(e=he()),se)if(Object.prototype.hasOwnProperty.call(se,o))for(n=se[o],i=0;i1?t-1:0),i=1;i(t&&Reflect.deleteProperty(window,n),e?.(i)),writable:!1,configurable:!0}),n}async function ke(e,t={}){return new Promise(((n,i)=>{const o=Me((e=>{n(e),Reflect.deleteProperty(window,a)}),!0),a=Me((e=>{i(e),Reflect.deleteProperty(window,o)}),!0);window.rpc.notify(e,{__invokeKey:__TAURI_INVOKE_KEY__,callback:o,error:a,...t})}))}function $e(e){return navigator.userAgent.includes("Windows")?`https://asset.${e}`:`asset://${e}`}async function Ce(e){return ke("tauri",e)}Object.freeze({__proto__:null,transformCallback:Me,invoke:ke,convertFileSrc:$e});class Te{constructor(){this.eventListeners=Object.create(null)}addEventListener(e,t){e in this.eventListeners?this.eventListeners[e].push(t):this.eventListeners[e]=[t]}_emit(e,t){if(e in this.eventListeners){const n=this.eventListeners[e];for(const e of n)e(t)}}on(e,t){return this.addEventListener(e,t),this}}class Oe{constructor(e){this.pid=e}async write(e){return Ce({__tauriModule:"Shell",message:{cmd:"stdinWrite",pid:this.pid,buffer:e}})}async kill(){return Ce({__tauriModule:"Shell",message:{cmd:"killChild",pid:this.pid}})}}class Se extends Te{constructor(e,t=[],n){super(),this.stdout=new Te,this.stderr=new Te,this.program=e,this.args="string"==typeof t?[t]:t,this.options=n??{}}static sidecar(e,t=[],n){const i=new Se(e,t,n);return i.options.sidecar=!0,i}async spawn(){return async function(e,t,n,i){return"object"==typeof n&&Object.freeze(n),Ce({__tauriModule:"Shell",message:{cmd:"execute",program:t,args:"string"==typeof n?[n]:n,options:i,onEventFn:Me(e)}})}((e=>{switch(e.event){case"Error":this._emit("error",e.payload);break;case"Terminated":this._emit("close",e.payload);break;case"Stdout":this.stdout._emit("data",e.payload);break;case"Stderr":this.stderr._emit("data",e.payload)}}),this.program,this.args,this.options).then((e=>new Oe(e)))}async execute(){return new Promise(((e,t)=>{this.on("error",t);const n=[],i=[];this.stdout.on("data",(e=>{n.push(e)})),this.stderr.on("data",(e=>{i.push(e)})),this.on("close",(t=>{e({code:t.code,signal:t.signal,stdout:n.join("\n"),stderr:i.join("\n")})})),this.spawn().catch(t)}))}}async function Ee(e,t){return Ce({__tauriModule:"Shell",message:{cmd:"open",path:e,with:t}})}async function Pe(){return Ce({__tauriModule:"App",message:{cmd:"getAppVersion"}})}async function ze(){return Ce({__tauriModule:"App",message:{cmd:"getAppName"}})}async function Ae(){return Ce({__tauriModule:"App",message:{cmd:"getTauriVersion"}})}async function We(e=0){return Ce({__tauriModule:"Process",message:{cmd:"exit",exitCode:e}})}async function je(){return Ce({__tauriModule:"Process",message:{cmd:"relaunch"}})}function Le(t){let n,o,a,s,u,f,y,v,_,w,x,M,k,$,C,T,O,S,E,P,z;return{c(){n=d("h1"),n.textContent="Welcome",o=h(),a=d("p"),a.textContent="Tauri's API capabilities using the ` @tauri-apps/api ` package. It's used as\n the main validation app, serving as the testbed of our development process. In\n the future, this app will be used on Tauri's integration tests.",s=h(),u=d("p"),f=p("Current App version: "),y=p(t[0]),v=h(),_=d("p"),w=p("Current Tauri version: "),x=p(t[1]),M=h(),k=d("p"),$=p("Current App name: "),C=p(t[2]),T=h(),O=d("button"),O.textContent="Close application",S=h(),E=d("button"),E.textContent="Relaunch application",g(O,"class","button"),g(E,"class","button")},m(e,i){c(e,n,i),c(e,o,i),c(e,a,i),c(e,s,i),c(e,u,i),r(u,f),r(u,y),c(e,v,i),c(e,_,i),r(_,w),r(_,x),c(e,M,i),c(e,k,i),r(k,$),r(k,C),c(e,T,i),c(e,O,i),c(e,S,i),c(e,E,i),P||(z=[m(O,"click",t[3]),m(E,"click",t[4])],P=!0)},p(e,[t]){1&t&&b(y,e[0]),2&t&&b(x,e[1]),4&t&&b(C,e[2])},i:e,o:e,d(e){e&&l(n),e&&l(o),e&&l(a),e&&l(s),e&&l(u),e&&l(v),e&&l(_),e&&l(M),e&&l(k),e&&l(T),e&&l(O),e&&l(S),e&&l(E),P=!1,i(z)}}}function De(e,t,n){let i=0,o=0,a="Unknown";return ze().then((e=>{n(2,a=e)})),Pe().then((e=>{n(0,i=e)})),Ae().then((e=>{n(1,o=e)})),[i,o,a,async function(){await We()},async function(){await je()}]}Object.freeze({__proto__:null,Command:Se,Child:Oe,open:Ee}),Object.freeze({__proto__:null,getName:ze,getVersion:Pe,getTauriVersion:Ae}),Object.freeze({__proto__:null,exit:We,relaunch:je});class Fe extends J{constructor(e){super(),V(this,e,De,Le,a,{})}}async function Re(){return Ce({__tauriModule:"Cli",message:{cmd:"cliMatches"}})}function Ue(t){let n,i,o,a,s,u,f,y,b,v,_;return{c(){n=d("div"),i=p("This binary can be run on the terminal and takes the following arguments:\n "),o=d("ul"),o.innerHTML="
  • --config PATH
  • \n
  • --theme light|dark|system
  • \n
  • --verbose
  • ",a=p("\n Additionally, it has a "),s=d("i"),s.textContent="update --background",u=p(" subcommand.\n Note that the arguments are only parsed, not implemented.\n "),f=d("br"),y=h(),b=d("button"),b.textContent="Get matches",g(b,"class","button"),g(b,"id","cli-matches")},m(e,l){c(e,n,l),r(n,i),r(n,o),r(n,a),r(n,s),r(n,u),r(n,f),r(n,y),r(n,b),v||(_=m(b,"click",t[0]),v=!0)},p:e,i:e,o:e,d(e){e&&l(n),v=!1,_()}}}function Ne(e,t,n){let{onMessage:i}=t;return e.$$set=e=>{"onMessage"in e&&n(1,i=e.onMessage)},[function(){Re().then(i).catch(i)},i]}Object.freeze({__proto__:null,getMatches:Re});class Ie extends J{constructor(e){super(),V(this,e,Ne,Ue,a,{onMessage:1})}}async function qe(e,t,n){await Ce({__tauriModule:"Event",message:{cmd:"emit",event:e,windowLabel:t,payload:n}})}async function Ke(e){return Ce({__tauriModule:"Event",message:{cmd:"unlisten",eventId:e}})}async function Be(e,t){return Ce({__tauriModule:"Event",message:{cmd:"listen",event:e,handler:Me(t)}}).then((e=>async()=>Ke(e)))}async function He(e,t){return Be(e,(e=>{t(e),Ke(e.id).catch((()=>{}))}))}async function Ge(e,t){return qe(e,void 0,t)}function Ve(t){let n,o,a,s,u,p,f,y;return{c(){n=d("div"),o=d("button"),o.textContent="Call Log API",a=h(),s=d("button"),s.textContent="Call Request (async) API",u=h(),p=d("button"),p.textContent="Send event to Rust",g(o,"class","button"),g(o,"id","log"),g(s,"class","button"),g(s,"id","request"),g(p,"class","button"),g(p,"id","event")},m(e,i){c(e,n,i),r(n,o),r(n,a),r(n,s),r(n,u),r(n,p),f||(y=[m(o,"click",t[0]),m(s,"click",t[1]),m(p,"click",t[2])],f=!0)},p:e,i:e,o:e,d(e){e&&l(n),f=!1,i(y)}}}function Je(e,t,n){let i,{onMessage:o}=t;return T((async()=>{i=await Be("rust-event",o)})),O((()=>{i&&i()})),e.$$set=e=>{"onMessage"in e&&n(3,o=e.onMessage)},[function(){ke("log_operation",{event:"tauri-click",payload:"this payload is optional because we used Option in Rust"})},function(){ke("perform_request",{endpoint:"dummy endpoint arg",body:{id:5,name:"test"}}).then(o).catch(o)},function(){Ge("js-event","this is the payload string")},o]}Object.freeze({__proto__:null,listen:Be,once:He,emit:Ge});class Xe extends J{constructor(e){super(),V(this,e,Je,Ve,a,{onMessage:3})}}async function Ye(e={}){return"object"==typeof e&&Object.freeze(e),Ce({__tauriModule:"Dialog",message:{cmd:"openDialog",options:e}})}async function Qe(e={}){return"object"==typeof e&&Object.freeze(e),Ce({__tauriModule:"Dialog",message:{cmd:"saveDialog",options:e}})}async function Ze(e,t={}){return Ce({__tauriModule:"Fs",message:{cmd:"readBinaryFile",path:e,options:t}})}function et(e){const t=function(e){if(e.length<65536)return String.fromCharCode.apply(null,Array.from(e));let t="";const n=e.length;for(let i=0;i{"onMessage"in e&&n(6,i=e.onMessage)},[o,a,s,r,function(){Ye({defaultPath:o,filters:a?[{name:"Tauri Example",extensions:a.split(",").map((e=>e.trim()))}]:[],multiple:s,directory:r}).then((function(e){if(Array.isArray(e))i(e);else{var t=e,n=t.match(/\S+\.\S+$/g);Ze(t).then((function(o){var a,s,r,c;n&&(t.includes(".png")||t.includes(".jpg"))?(a=new Uint8Array(o),s=function(e){i('')},r=new Blob([a],{type:"application/octet-binary"}),(c=new FileReader).onload=function(e){var t=e.target.result;s(t.substr(t.indexOf(",")+1))},c.readAsDataURL(r)):i(e)})).catch(i(e))}})).catch(i)},function(){Qe({defaultPath:o,filters:a?[{name:"Tauri Example",extensions:a.split(",").map((e=>e.trim()))}]:[]}).then(i).catch(i)},i,function(){o=this.value,n(0,o)},function(){a=this.value,n(1,a)},function(){s=this.checked,n(2,s)},function(){r=this.checked,n(3,r)}]}Object.freeze({__proto__:null,open:Ye,save:Qe}),function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Desktop=6]="Desktop",e[e.Document=7]="Document",e[e.Download=8]="Download",e[e.Executable=9]="Executable",e[e.Font=10]="Font",e[e.Home=11]="Home",e[e.Picture=12]="Picture",e[e.Public=13]="Public",e[e.Runtime=14]="Runtime",e[e.Template=15]="Template",e[e.Video=16]="Video",e[e.Resource=17]="Resource",e[e.App=18]="App",e[e.Current=19]="Current"}(be||(be={})),Object.freeze({__proto__:null,get BaseDirectory(){return be},get Dir(){return be},readTextFile:async function(e,t={}){return Ce({__tauriModule:"Fs",message:{cmd:"readTextFile",path:e,options:t}})},readBinaryFile:Ze,writeFile:async function(e,t={}){return"object"==typeof t&&Object.freeze(t),"object"==typeof e&&Object.freeze(e),Ce({__tauriModule:"Fs",message:{cmd:"writeFile",path:e.path,contents:e.contents,options:t}})},writeBinaryFile:async function(e,t={}){return"object"==typeof t&&Object.freeze(t),"object"==typeof e&&Object.freeze(e),Ce({__tauriModule:"Fs",message:{cmd:"writeBinaryFile",path:e.path,contents:et(e.contents),options:t}})},readDir:tt,createDir:async function(e,t={}){return Ce({__tauriModule:"Fs",message:{cmd:"createDir",path:e,options:t}})},removeDir:async function(e,t={}){return Ce({__tauriModule:"Fs",message:{cmd:"removeDir",path:e,options:t}})},copyFile:async function(e,t,n={}){return Ce({__tauriModule:"Fs",message:{cmd:"copyFile",source:e,destination:t,options:n}})},removeFile:async function(e,t={}){return Ce({__tauriModule:"Fs",message:{cmd:"removeFile",path:e,options:t}})},renameFile:async function(e,t,n={}){return Ce({__tauriModule:"Fs",message:{cmd:"renameFile",oldPath:e,newPath:t,options:n}})}});class ot extends J{constructor(e){var t;super(),document.getElementById("svelte-1eg58yg-style")||((t=d("style")).id="svelte-1eg58yg-style",t.textContent="#dialog-filter.svelte-1eg58yg{width:260px}",r(document.head,t)),V(this,e,it,nt,a,{onMessage:6})}}function at(e,t,n){const i=e.slice();return i[8]=t[n],i}function st(t){let n,i,o=t[8][0]+"";return{c(){n=d("option"),i=p(o),n.__value=t[8][1],n.value=n.__value},m(e,t){c(e,n,t),r(n,i)},p:e,d(e){e&&l(n)}}}function rt(t){let n,o,a,s,p,y,b,_,w,x,M,k,$,C=t[2],T=[];for(let e=0;eisNaN(parseInt(e)))).map((e=>[e,be[e]]));return e.$$set=e=>{"onMessage"in e&&n(5,o=e.onMessage)},[a,i,s,function(){const e=a.match(/\S+\.\S+$/g),t={dir:ct()};(e?Ze(a,t):tt(a,t)).then((function(t){if(e)if(a.includes(".png")||a.includes(".jpg"))!function(e,t){const n=new Blob([e],{type:"application/octet-binary"}),i=new FileReader;i.onload=function(e){const n=e.target.result;t(n.substr(n.indexOf(",")+1))},i.readAsDataURL(n)}(new Uint8Array(t),(function(e){o('')}));else{const e=String.fromCharCode.apply(null,t);o(''),setTimeout((()=>{const t=document.getElementById("file-response");t.value=e,document.getElementById("file-save").addEventListener("click",(function(){writeFile({file:a,contents:t.value},{dir:ct()}).catch(o)}))}))}else o(t)})).catch(o)},function(){n(1,i.src=$e(a),i)},o,function(){a=this.value,n(0,a)},function(e){E[e?"unshift":"push"]((()=>{i=e,n(1,i)}))}]}class ut extends J{constructor(e){super(),V(this,e,lt,rt,a,{onMessage:5})}}!function(e){e[e.JSON=1]="JSON",e[e.Text=2]="Text",e[e.Binary=3]="Binary"}(ve||(ve={}));class dt{constructor(e,t){this.type=e,this.payload=t}static form(e){return new dt("Form",e)}static json(e){return new dt("Json",e)}static text(e){return new dt("Text",e)}static bytes(e){return new dt("Bytes",e)}}class pt{constructor(e){this.url=e.url,this.status=e.status,this.ok=this.status>=200&&this.status<300,this.headers=e.headers,this.data=e.data}}class ht{constructor(e){this.id=e}async drop(){return Ce({__tauriModule:"Http",message:{cmd:"dropClient",client:this.id}})}async request(e){const t=!e.responseType||e.responseType===ve.JSON;return t&&(e.responseType=ve.Text),Ce({__tauriModule:"Http",message:{cmd:"httpRequest",client:this.id,options:e}}).then((e=>{const n=new pt(e);if(t){try{n.data=JSON.parse(n.data)}catch(e){if(n.ok)throw Error(`Failed to parse response \`${n.data}\` as JSON: ${e};\n try setting the \`responseType\` option to \`ResponseType.Text\` or \`ResponseType.Binary\` if the API does not return a JSON response.`)}return n}return n}))}async get(e,t){return this.request({method:"GET",url:e,...t})}async post(e,t,n){return this.request({method:"POST",url:e,body:t,...n})}async put(e,t,n){return this.request({method:"PUT",url:e,body:t,...n})}async patch(e,t){return this.request({method:"PATCH",url:e,...t})}async delete(e,t){return this.request({method:"DELETE",url:e,...t})}}async function mt(e){return Ce({__tauriModule:"Http",message:{cmd:"createClient",options:e}}).then((e=>new ht(e)))}let ft=null;function gt(t){let n,o,a,s,u,p,y,b,x,M,k,$,C,T,O,S,E;return{c(){n=d("form"),o=d("select"),a=d("option"),a.textContent="GET",s=d("option"),s.textContent="POST",u=d("option"),u.textContent="PUT",p=d("option"),p.textContent="PATCH",y=d("option"),y.textContent="DELETE",b=h(),x=d("input"),M=h(),k=d("br"),$=h(),C=d("textarea"),T=h(),O=d("button"),O.textContent="Make request",a.__value="GET",a.value=a.__value,s.__value="POST",s.value=s.__value,u.__value="PUT",u.value=u.__value,p.__value="PATCH",p.value=p.__value,y.__value="DELETE",y.value=y.__value,g(o,"class","button"),g(o,"id","request-method"),void 0===t[0]&&j((()=>t[5].call(o))),g(x,"id","request-url"),g(x,"placeholder","Type the request URL..."),g(C,"id","request-body"),g(C,"placeholder","Request body"),g(C,"rows","5"),_(C,"width","100%"),_(C,"margin-right","10px"),_(C,"font-size","12px"),g(O,"class","button"),g(O,"id","make-request")},m(e,i){c(e,n,i),r(n,o),r(o,a),r(o,s),r(o,u),r(o,p),r(o,y),w(o,t[0]),r(n,b),r(n,x),v(x,t[1]),r(n,M),r(n,k),r(n,$),r(n,C),v(C,t[2]),r(n,T),r(n,O),S||(E=[m(o,"change",t[5]),m(x,"input",t[6]),m(C,"input",t[7]),m(n,"submit",f(t[3]))],S=!0)},p(e,[t]){1&t&&w(o,e[0]),2&t&&x.value!==e[1]&&v(x,e[1]),4&t&&v(C,e[2])},i:e,o:e,d(e){e&&l(n),S=!1,i(E)}}}function yt(e,t,n){let i="GET",o="https://jsonplaceholder.typicode.com/todos/1",a="",{onMessage:s}=t;return e.$$set=e=>{"onMessage"in e&&n(4,s=e.onMessage)},[i,o,a,async function(){const e=await mt(),t={url:o||""||"",method:i||"GET"||"GET"};a.startsWith("{")&&a.endsWith("}")||a.startsWith("[")&&a.endsWith("]")?t.body=dt.json(JSON.parse(a)):""!==a&&(t.body=dt.text(a)),e.request(t).then(s).catch(s)},s,function(){i=x(this),n(0,i)},function(){o=this.value,n(1,o)},function(){a=this.value,n(2,a)}]}Object.freeze({__proto__:null,getClient:mt,fetch:async function(e,t){return null===ft&&(ft=await mt()),ft.request({url:e,method:t?.method??"GET",...t})},Body:dt,Client:ht,Response:pt,get ResponseType(){return ve}});class bt extends J{constructor(e){super(),V(this,e,yt,gt,a,{onMessage:4})}}function vt(t){let n,i,o;return{c(){n=d("button"),n.textContent="Send test notification",g(n,"class","button"),g(n,"id","notification")},m(e,a){c(e,n,a),i||(o=m(n,"click",t[0]),i=!0)},p:e,i:e,o:e,d(e){e&&l(n),i=!1,o()}}}function _t(){new Notification("Notification title",{body:"This is the notification body"})}function wt(e,t,n){let{onMessage:i}=t;return e.$$set=e=>{"onMessage"in e&&n(1,i=e.onMessage)},[function(){"default"===Notification.permission?Notification.requestPermission().then((function(e){"granted"===e?_t():i("Permission is "+e)})).catch(i):"granted"===Notification.permission?_t():i("Permission is denied")},i]}class xt extends J{constructor(e){super(),V(this,e,wt,vt,a,{onMessage:1})}}class Mt{constructor(e,t){this.type="Logical",this.width=e,this.height=t}}class kt{constructor(e,t){this.type="Logical",this.x=e,this.y=t}}var $t;function Ct(){return new Pt(window.__TAURI__.__currentWindow.label,{skip:!0})}function Tt(){return window.__TAURI__.__windows.map((e=>new Pt(e.label,{skip:!0})))}!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}($t||($t={}));const Ot=["tauri://created","tauri://error"];class St{constructor(e){this.label=e,this.listeners=Object.create(null)}async listen(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const n=this.listeners[e];n.splice(n.indexOf(t),1)})):Be(e,t)}async once(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const n=this.listeners[e];n.splice(n.indexOf(t),1)})):He(e,t)}async emit(e,t){if(Ot.includes(e)){for(const n of this.listeners[e]||[])n({event:e,id:-1,payload:t});return Promise.resolve()}return qe(e,this.label,t)}_handleTauriEvent(e,t){return!!Ot.includes(e)&&(e in this.listeners?this.listeners[e].push(t):this.listeners[e]=[t],!0)}}class Et extends St{async scaleFactor(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"scaleFactor"}}}})}async innerPosition(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"innerPosition"}}}})}async outerPosition(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"outerPosition"}}}})}async innerSize(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"innerSize"}}}})}async outerSize(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"outerSize"}}}})}async isFullscreen(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isFullscreen"}}}})}async isMaximized(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMaximized"}}}})}async isDecorated(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isDecorated"}}}})}async isResizable(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isResizable"}}}})}async isVisible(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isVisible"}}}})}async center(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"center"}}}})}async requestUserAttention(e){let t=null;return e&&(t=e===$t.Critical?{type:"Critical"}:{type:"Informational"}),Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"requestUserAttention",payload:t}}}})}async setResizable(e){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setResizable",payload:e}}}})}async setTitle(e){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setTitle",payload:e}}}})}async maximize(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"maximize"}}}})}async unmaximize(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"unmaximize"}}}})}async toggleMaximize(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"toggleMaximize"}}}})}async minimize(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"minimize"}}}})}async unminimize(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"unminimize"}}}})}async show(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"show"}}}})}async hide(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"hide"}}}})}async close(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"close"}}}})}async setDecorations(e){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setDecorations",payload:e}}}})}async setAlwaysOnTop(e){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setAlwaysOnTop",payload:e}}}})}async setSize(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setSize",payload:{type:e.type,data:{width:e.width,height:e.height}}}}}})}async setMinSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMinSize",payload:e?{type:e.type,data:{width:e.width,height:e.height}}:null}}}})}async setMaxSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMaxSize",payload:e?{type:e.type,data:{width:e.width,height:e.height}}:null}}}})}async setPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setPosition",payload:{type:e.type,data:{x:e.x,y:e.y}}}}}})}async setFullscreen(e){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setFullscreen",payload:e}}}})}async setFocus(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setFocus"}}}})}async setIcon(e){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setIcon",payload:{icon:e}}}}})}async setSkipTaskbar(e){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setSkipTaskbar",payload:e}}}})}async startDragging(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"startDragging"}}}})}}class Pt extends Et{constructor(e,t={}){super(e),t?.skip||Ce({__tauriModule:"Window",message:{cmd:"createWebview",data:{options:{label:e,...t}}}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static getByLabel(e){return Tt().some((t=>t.label===e))?new Pt(e,{skip:!0}):null}}const zt=new Pt(null,{skip:!0});function At(e,t,n){const i=e.slice();return i[44]=t[n],i}function Wt(e){let t,n,i,o=e[44]+"";return{c(){t=d("option"),n=p(o),t.__value=i=e[44],t.value=t.__value},m(e,i){c(e,t,i),r(t,n)},p(e,a){2&a[0]&&o!==(o=e[44]+"")&&b(n,o),2&a[0]&&i!==(i=e[44])&&(t.__value=i,t.value=t.__value)},d(e){e&&l(t)}}}function jt(t){let n,o,a,s,b,x,M,k,$,C,T,O,S,E,P,z,A,W,L,D,F,R,U,N,I,q,K,B,H,G,V,J,X,Y,Q,Z,ee,te,ne,ie,oe,ae,se,re,ce,le,ue,de,pe,he,me,fe,ge,ye,be,ve,_e,we,xe,Me,ke,$e,Ce,Te,Oe,Se,Ee,Pe,ze,Ae,We,je,Le,De,Fe,Re,Ue,Ne,Ie,qe,Ke,Be,He,Ge,Ve,Je,Xe,Ye,Qe,Ze=Object.keys(t[1]),et=[];for(let e=0;et[26].call(o))),g(x,"type","checkbox"),g(C,"type","checkbox"),g(S,"title","Unminimizes after 2 seconds"),g(P,"title","Unminimizes after 2 seconds"),g(A,"title","Visible again after 2 seconds"),g(D,"type","checkbox"),g(N,"type","checkbox"),g(B,"type","checkbox"),g(J,"type","checkbox"),g(ae,"type","number"),g(ae,"min","0"),g(ae,"class","svelte-b76pvm"),g(le,"type","number"),g(le,"min","0"),g(le,"class","svelte-b76pvm"),g(ne,"class","flex col grow svelte-b76pvm"),g(me,"type","number"),g(me,"min","400"),g(me,"class","svelte-b76pvm"),g(be,"type","number"),g(be,"min","400"),g(be,"class","svelte-b76pvm"),g(de,"class","flex col grow svelte-b76pvm"),g(Me,"type","number"),g(Me,"class","svelte-b76pvm"),g(Te,"type","number"),g(Te,"class","svelte-b76pvm"),g(_e,"class","flex col grow svelte-b76pvm"),g(ze,"type","number"),g(ze,"min","400"),g(ze,"class","svelte-b76pvm"),g(Le,"type","number"),g(Le,"min","400"),g(Le,"class","svelte-b76pvm"),g(Se,"class","flex col grow svelte-b76pvm"),g(te,"class","window-controls flex flex-row svelte-b76pvm"),g(n,"class","flex col"),g(Re,"id","title"),g(Ne,"class","button"),g(Ne,"type","submit"),_(Fe,"margin-top","24px"),g(Ke,"id","url"),g(He,"class","button"),g(He,"id","open-url"),_(qe,"margin-top","24px"),g(Ve,"class","button"),g(Ve,"title","Minimizes the window, requests attention for 3s and then resets it"),g(Xe,"class","button")},m(e,i){c(e,n,i),r(n,o);for(let e=0;e{"onMessage"in e&&n(25,a=e.onMessage)},e.$$.update=()=>{7&e.$$.dirty[0]&&o[i].setResizable(r),11&e.$$.dirty[0]&&(c?o[i].maximize():o[i].unmaximize()),19&e.$$.dirty[0]&&o[i].setDecorations(u),35&e.$$.dirty[0]&&o[i].setAlwaysOnTop(d),67&e.$$.dirty[0]&&o[i].setFullscreen(p),387&e.$$.dirty[0]&&o[i].setSize(new Mt(h,m)),1539&e.$$.dirty[0]&&(f&&g?o[i].setMinSize(new Mt(f,g)):o[i].setMinSize(null)),6147&e.$$.dirty[0]&&(b&&v?o[i].setMaxSize(new Mt(b,v)):o[i].setMaxSize(null)),24579&e.$$.dirty[0]&&o[i].setPosition(new kt(_,w))},[i,o,r,c,u,d,p,h,m,f,g,b,v,_,w,s,l,M,function(){Ee(s)},function(){o[i].setTitle(M)},function(){o[i].hide(),setTimeout(o[i].show,2e3)},function(){o[i].minimize(),setTimeout(o[i].unminimize,2e3)},function(){Ye({multiple:!1}).then(o[i].setIcon)},function(){const e=Math.random().toString(),t=new Pt(e);n(1,o[e]=t,o),t.once("tauri://error",(function(){a("Error creating new webview")}))},async function(){await o[i].minimize(),await o[i].requestUserAttention($t.Critical),await new Promise((e=>setTimeout(e,3e3))),await o[i].requestUserAttention(null)},a,function(){i=x(this),n(0,i),n(1,o)},function(){r=this.checked,n(2,r)},function(){c=this.checked,n(3,c)},()=>o[i].center(),function(){l=this.checked,n(16,l)},function(){u=this.checked,n(4,u)},function(){d=this.checked,n(5,d)},function(){p=this.checked,n(6,p)},function(){_=y(this.value),n(13,_)},function(){w=y(this.value),n(14,w)},function(){h=y(this.value),n(7,h)},function(){m=y(this.value),n(8,m)},function(){f=y(this.value),n(9,f)},function(){g=y(this.value),n(10,g)},function(){b=y(this.value),n(11,b)},function(){v=y(this.value),n(12,v)},function(){M=this.value,n(17,M)},function(){s=this.value,n(15,s)}]}Object.freeze({__proto__:null,WebviewWindow:Pt,WebviewWindowHandle:St,WindowManager:Et,getCurrent:Ct,getAll:Tt,appWindow:zt,LogicalSize:Mt,PhysicalSize:class{constructor(e,t){this.type="Physical",this.width=e,this.height=t}toLogical(e){return new Mt(this.width/e,this.height/e)}},LogicalPosition:kt,PhysicalPosition:class{constructor(e,t){this.type="Physical",this.x=e,this.y=t}toLogical(e){return new kt(this.x/e,this.y/e)}},get UserAttentionType(){return $t},currentMonitor:async function(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"currentMonitor"}}}})},primaryMonitor:async function(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"primaryMonitor"}}}})},availableMonitors:async function(){return Ce({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"availableMonitors"}}}})}});class Dt extends J{constructor(e){var t;super(),document.getElementById("svelte-b76pvm-style")||((t=d("style")).id="svelte-b76pvm-style",t.textContent=".flex-row.svelte-b76pvm.svelte-b76pvm{flex-direction:row}.grow.svelte-b76pvm.svelte-b76pvm{flex-grow:1}.window-controls.svelte-b76pvm input.svelte-b76pvm{width:50px}",r(document.head,t)),V(this,e,Lt,jt,a,{onMessage:25},[-1,-1])}}async function Ft(e,t){return Ce({__tauriModule:"GlobalShortcut",message:{cmd:"register",shortcut:e,handler:Me(t)}})}async function Rt(e){return Ce({__tauriModule:"GlobalShortcut",message:{cmd:"unregister",shortcut:e}})}async function Ut(){return Ce({__tauriModule:"GlobalShortcut",message:{cmd:"unregisterAll"}})}function Nt(e,t,n){const i=e.slice();return i[9]=t[n],i}function It(e){let t,n,i,o,a,s,u=e[9]+"";function f(){return e[8](e[9])}return{c(){t=d("div"),n=p(u),i=h(),o=d("button"),o.textContent="Unregister",g(o,"type","button")},m(e,l){c(e,t,l),r(t,n),r(t,i),r(t,o),a||(s=m(o,"click",f),a=!0)},p(t,i){e=t,2&i&&u!==(u=e[9]+"")&&b(n,u)},d(e){e&&l(t),a=!1,s()}}}function qt(t){let n,i,o;return{c(){n=d("button"),n.textContent="Unregister all",g(n,"type","button")},m(e,a){c(e,n,a),i||(o=m(n,"click",t[5]),i=!0)},p:e,d(e){e&&l(n),i=!1,o()}}}function Kt(t){let n,o,a,s,p,f,y,b,_,w,x=t[1],M=[];for(let e=0;en(1,i=e)));let r="CmdOrControl+X";function c(e){const t=e;Rt(t).then((()=>{a.update((e=>e.filter((e=>e!==t)))),o(`Shortcut ${t} unregistered`)})).catch(o)}return e.$$set=e=>{"onMessage"in e&&n(6,o=e.onMessage)},[r,i,a,function(){const e=r;Ft(e,(()=>{o(`Shortcut ${e} triggered`)})).then((()=>{a.update((t=>[...t,e])),o(`Shortcut ${e} registered successfully`)})).catch(o)},c,function(){Ut().then((()=>{a.update((()=>[])),o("Unregistered all shortcuts")})).catch(o)},o,function(){r=this.value,n(0,r)},e=>c(e)]}Object.freeze({__proto__:null,register:Ft,registerAll:async function(e,t){return Ce({__tauriModule:"GlobalShortcut",message:{cmd:"registerAll",shortcuts:e,handler:Me(t)}})},isRegistered:async function(e){return Ce({__tauriModule:"GlobalShortcut",message:{cmd:"isRegistered",shortcut:e}})},unregister:Rt,unregisterAll:Ut});class Ht extends J{constructor(e){super(),V(this,e,Bt,Kt,a,{onMessage:6})}}function Gt(e){let t,n,o,a,s;return{c(){t=d("input"),n=h(),o=d("button"),o.textContent="Write",g(t,"placeholder","write to stdin"),g(o,"class","button")},m(i,r){c(i,t,r),v(t,e[3]),c(i,n,r),c(i,o,r),a||(s=[m(t,"input",e[10]),m(o,"click",e[7])],a=!0)},p(e,n){8&n&&t.value!==e[3]&&v(t,e[3])},d(e){e&&l(t),e&&l(n),e&&l(o),a=!1,i(s)}}}function Vt(t){let n,o,a,s,u,p,f,y,b,w,x,M,k,$,C,T=t[4]&&Gt(t);return{c(){n=d("div"),o=d("div"),a=d("input"),s=h(),u=d("button"),u.textContent="Run",p=h(),f=d("button"),f.textContent="Kill",y=h(),T&&T.c(),b=h(),w=d("div"),x=d("input"),M=h(),k=d("input"),g(u,"class","button"),g(f,"class","button"),g(x,"placeholder","Working directory"),g(k,"placeholder","Environment variables"),_(k,"width","300px")},m(e,i){c(e,n,i),r(n,o),r(o,a),v(a,t[0]),r(o,s),r(o,u),r(o,p),r(o,f),r(o,y),T&&T.m(o,null),r(n,b),r(n,w),r(w,x),v(x,t[1]),r(w,M),r(w,k),v(k,t[2]),$||(C=[m(a,"input",t[9]),m(u,"click",t[5]),m(f,"click",t[6]),m(x,"input",t[11]),m(k,"input",t[12])],$=!0)},p(e,[t]){1&t&&a.value!==e[0]&&v(a,e[0]),e[4]?T?T.p(e,t):(T=Gt(e),T.c(),T.m(o,null)):T&&(T.d(1),T=null),2&t&&x.value!==e[1]&&v(x,e[1]),4&t&&k.value!==e[2]&&v(k,e[2])},i:e,o:e,d(e){e&&l(n),T&&T.d(),$=!1,i(C)}}}function Jt(e,t,n){const i=navigator.userAgent.includes("Windows");let o,a=i?"cmd":"sh",s=i?["/C"]:["-c"],{onMessage:r}=t,c='echo "hello world"',l=null,u="SOMETHING=value ANOTHER=2",d="";return e.$$set=e=>{"onMessage"in e&&n(8,r=e.onMessage)},[c,l,u,d,o,function(){n(4,o=null);const e=new Se(a,[...s,c],{cwd:l||null,env:u.split(" ").reduce(((e,t)=>{let[n,i]=t.split("=");return{...e,[n]:i}}),{})});e.on("close",(e=>{r(`command finished with code ${e.code} and signal ${e.signal}`),n(4,o=null)})),e.on("error",(e=>r(`command error: "${e}"`))),e.stdout.on("data",(e=>r(`command stdout: "${e}"`))),e.stderr.on("data",(e=>r(`command stderr: "${e}"`))),e.spawn().then((e=>{n(4,o=e)})).catch(r)},function(){o.kill().then((()=>r("killed child process"))).catch(r)},function(){o.write(d).catch(r)},r,function(){c=this.value,n(0,c)},function(){d=this.value,n(3,d)},function(){l=this.value,n(1,l)},function(){u=this.value,n(2,u)}]}class Xt extends J{constructor(e){super(),V(this,e,Jt,Vt,a,{onMessage:8})}}async function Yt(){let e;function t(){e&&e(),e=void 0}return new Promise(((n,i)=>{Be("tauri://update-status",(e=>{var o;(o=e?.payload).error?(t(),i(o.error)):"DONE"===o.status&&(t(),n())})).then((t=>{e=t})).catch((e=>{throw t(),e})),Ge("tauri://update-install").catch((e=>{throw t(),e}))}))}async function Qt(){let e;function t(){e&&e(),e=void 0}return new Promise(((n,i)=>{He("tauri://update-available",(e=>{var i;i=e?.payload,t(),n({manifest:i,shouldUpdate:!0})})).catch((e=>{throw t(),e})),Be("tauri://update-status",(e=>{var o;(o=e?.payload).error?(t(),i(o.error)):"UPTODATE"===o.status&&(t(),n({shouldUpdate:!1}))})).then((t=>{e=t})).catch((e=>{throw t(),e})),Ge("tauri://update").catch((e=>{throw t(),e}))}))}function Zt(t){let n,o,a,s,u,p;return{c(){n=d("div"),o=d("button"),o.textContent="Check update",a=h(),s=d("button"),s.textContent="Install update",g(o,"class","button"),g(o,"id","check_update"),g(s,"class","button hidden"),g(s,"id","start_update")},m(e,i){c(e,n,i),r(n,o),r(n,a),r(n,s),u||(p=[m(o,"click",t[0]),m(s,"click",t[1])],u=!0)},p:e,i:e,o:e,d(e){e&&l(n),u=!1,i(p)}}}function en(e,t,n){let i,{onMessage:o}=t;return T((async()=>{i=await Be("tauri://update-status",o)})),O((()=>{i&&i()})),e.$$set=e=>{"onMessage"in e&&n(2,o=e.onMessage)},[async function(){try{document.getElementById("check_update").classList.add("hidden");const{shouldUpdate:e,manifest:t}=await Qt();o(`Should update: ${e}`),o(t),e&&document.getElementById("start_update").classList.remove("hidden")}catch(e){o(e)}},async function(){try{document.getElementById("start_update").classList.add("hidden"),await Yt(),o("Installation complete, restart required."),await je()}catch(e){o(e)}},o]}Object.freeze({__proto__:null,installUpdate:Yt,checkUpdate:Qt});class tn extends J{constructor(e){super(),V(this,e,en,Zt,a,{onMessage:2})}}async function nn(e){return Ce({__tauriModule:"Clipboard",message:{cmd:"writeText",data:e}})}async function on(){return Ce({__tauriModule:"Clipboard",message:{cmd:"readText"}})}function an(t){let n,o,a,s,u,p,f,y,b;return{c(){n=d("div"),o=d("div"),a=d("input"),s=h(),u=d("button"),u.textContent="Write",p=h(),f=d("button"),f.textContent="Read",g(a,"placeholder","Text to write to the clipboard"),g(u,"type","button"),g(f,"type","button")},m(e,i){c(e,n,i),r(n,o),r(o,a),v(a,t[0]),r(o,s),r(o,u),r(n,p),r(n,f),y||(b=[m(a,"input",t[4]),m(u,"click",t[1]),m(f,"click",t[2])],y=!0)},p(e,[t]){1&t&&a.value!==e[0]&&v(a,e[0])},i:e,o:e,d(e){e&&l(n),y=!1,i(b)}}}function sn(e,t,n){let{onMessage:i}=t,o="clipboard message";return e.$$set=e=>{"onMessage"in e&&n(3,i=e.onMessage)},[o,function(){nn(o).then((()=>{i("Wrote to the clipboard")})).catch(i)},function(){on().then((e=>{i(`Clipboard contents: ${e}`)})).catch(i)},i,function(){o=this.value,n(0,o)}]}Object.freeze({__proto__:null,writeText:nn,readText:on});class rn extends J{constructor(e){super(),V(this,e,sn,an,a,{onMessage:3})}}function cn(t){let n;return{c(){n=d("div"),n.innerHTML='

    Not available for Linux

    \n '},m(e,t){c(e,n,t)},p:e,i:e,o:e,d(e){e&&l(n)}}}function ln(e,t,n){let{onMessage:i}=t;const o=window.constraints={audio:!0,video:!0};return T((async()=>{try{!function(e){const t=document.querySelector("video"),n=e.getVideoTracks();i("Got stream with constraints:",o),i(`Using video device: ${n[0].label}`),window.stream=e,t.srcObject=e}(await navigator.mediaDevices.getUserMedia(o))}catch(e){!function(e){if("ConstraintNotSatisfiedError"===e.name){const e=o.video;i(`The resolution ${e.width.exact}x${e.height.exact} px is not supported by your device.`)}else"PermissionDeniedError"===e.name&&i("Permissions have not been granted to use your camera and microphone, you need to allow the page access to your devices in order for the demo to work.");i(`getUserMedia error: ${e.name}`,e)}(e)}})),O((()=>{window.stream.getTracks().forEach((function(e){e.stop()}))})),e.$$set=e=>{"onMessage"in e&&n(0,i=e.onMessage)},[i]}class un extends J{constructor(e){super(),V(this,e,ln,cn,a,{onMessage:0})}}function dn(t){let n,o,a,s,u,f,y,_,w,x,M,k;return{c(){n=d("input"),o=h(),a=d("input"),s=h(),u=d("button"),u.textContent="Post it.",f=h(),y=d("p"),y.textContent="Result:",_=h(),w=d("pre"),x=p(t[2]),g(u,"type","button")},m(e,i){c(e,n,i),v(n,t[0]),c(e,o,i),c(e,a,i),v(a,t[1]),c(e,s,i),c(e,u,i),c(e,f,i),c(e,y,i),c(e,_,i),c(e,w,i),r(w,x),M||(k=[m(n,"input",t[4]),m(a,"input",t[5]),m(u,"click",t[3])],M=!0)},p(e,[t]){1&t&&n.value!==e[0]&&v(n,e[0]),2&t&&a.value!==e[1]&&v(a,e[1]),4&t&&b(x,e[2])},i:e,o:e,d(e){e&&l(n),e&&l(o),e&&l(a),e&&l(s),e&&l(u),e&&l(f),e&&l(y),e&&l(_),e&&l(w),M=!1,i(k)}}}function pn(e,t,n){let i="baz",o="qux",a=null;return[i,o,a,async function(){let e=navigator.userAgent.includes("Windows")?"https://customprotocol.test/example.html":"customprotocol://test/example.html";const t=await fetch(e,{method:"POST",body:JSON.stringify({foo:i,bar:o})}),s=await t.json();n(2,a=JSON.stringify(s))},function(){i=this.value,n(0,i)},function(){o=this.value,n(1,o)}]}class hn extends J{constructor(e){super(),V(this,e,pn,dn,a,{})}}function mn(e,t,n){const i=e.slice();return i[9]=t[n],i}function fn(e){let t,n,i,o,a,s,u=e[9].label+"";function f(){return e[7](e[9])}return{c(){t=d("p"),n=p(u),i=h(),g(t,"class",o="nv noselect "+(e[0]===e[9]?"nv_selected":""))},m(e,o){c(e,t,o),r(t,n),r(t,i),a||(s=m(t,"click",f),a=!0)},p(n,i){e=n,1&i&&o!==(o="nv noselect "+(e[0]===e[9]?"nv_selected":""))&&g(t,"class",o)},d(e){e&&l(t),a=!1,s()}}}function gn(e){let t,n,o,a,s,p,f,y,b,v,w,x,k,$,C,T,O,S,E,P,z,A,W,j=e[2],L=[];for(let t=0;tDocumentation \n Github \n Source',f=h(),y=d("div"),b=d("div");for(let e=0;e{H(e,1)})),N.r||i(N.c),N=N.p}D?(x=new D(F(e)),K(x.$$.fragment),I(x.$$.fragment,1),B(x,w,null)):x=null}(!z||2&t)&&P.p(e[1])},i(e){z||(x&&I(x.$$.fragment,e),z=!0)},o(e){x&&q(x.$$.fragment,e),z=!1},d(e){e&&l(t),u(L,e),x&&H(x),A=!1,i(W)}}}function yn(e,t,n){T((()=>{ye("ctrl+b",(()=>{ke("menu_toggle")}))}));const i=[{label:"Welcome",component:Fe},{label:"Messages",component:Xe},{label:"CLI",component:Ie},{label:"Dialog",component:ot},{label:"File system",component:ut},{label:"HTTP",component:bt},{label:"HTTP Form",component:hn},{label:"Notifications",component:xt},{label:"Window",component:Dt},{label:"Shortcuts",component:Ht},{label:"Shell",component:Xt},{label:"Updater",component:tn},{label:"Clipboard",component:rn},{label:"WebRTC",component:un}];let o=i[0],a=Y([]),s="";function r(e){n(0,o=e)}T((()=>{a.subscribe((e=>{n(1,s=e.join("\n"))}))}));return[o,s,i,a,r,function(e){a.update((t=>[`[${(new Date).toLocaleTimeString()}]: `+("string"==typeof e?e:JSON.stringify(e)),...t]))},function(){Ee("https://tauri.studio/")},e=>r(e),()=>{a.update((()=>[]))}]}return new class extends J{constructor(e){super(),V(this,e,yn,gn,a,{})}}({target:document.body})}(); -//# sourceMappingURL=bundle.js.map diff --git a/examples/api/public/build/bundle.js.map b/examples/api/public/build/bundle.js.map deleted file mode 100644 index 6635790fc3cd..000000000000 --- a/examples/api/public/build/bundle.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"bundle.js","sources":["../../node_modules/svelte/internal/index.mjs","../../node_modules/svelte/store/index.mjs","../../node_modules/hotkeys-js/dist/hotkeys.esm.js","../../../../tooling/api/dist/fs-c61261aa.js","../../../../tooling/api/dist/http-cc253949.js","../../../../tooling/api/dist/tauri-6032cb22.js","../../../../tooling/api/dist/tauri-48bdc082.js","../../../../tooling/api/dist/shell-a5261760.js","../../../../tooling/api/dist/app-7fad8dcd.js","../../../../tooling/api/dist/process-27a9217f.js","../../src/components/Welcome.svelte","../../../../tooling/api/dist/cli-2d93cae7.js","../../src/components/Cli.svelte","../../../../tooling/api/dist/event-29f50a54.js","../../src/components/Communication.svelte","../../../../tooling/api/dist/dialog-f7c24807.js","../../src/components/Dialog.svelte","../../src/components/FileSystem.svelte","../../src/components/Http.svelte","../../src/components/Notifications.svelte","../../../../tooling/api/dist/window-d653c9f2.js","../../src/components/Window.svelte","../../../../tooling/api/dist/globalShortcut-4c1f1a9c.js","../../src/components/Shortcuts.svelte","../../src/components/Shell.svelte","../../../../tooling/api/dist/updater-9533d0e6.js","../../src/components/Updater.svelte","../../../../tooling/api/dist/clipboard-f9112aa8.js","../../src/components/Clipboard.svelte","../../src/components/WebRTC.svelte","../../src/components/HttpForm.svelte","../../src/App.svelte","../../src/main.js"],"sourcesContent":["function noop() { }\nconst identity = x => x;\nfunction assign(tar, src) {\n // @ts-ignore\n for (const k in src)\n tar[k] = src[k];\n return tar;\n}\nfunction is_promise(value) {\n return value && typeof value === 'object' && typeof value.then === 'function';\n}\nfunction add_location(element, file, line, column, char) {\n element.__svelte_meta = {\n loc: { file, line, column, char }\n };\n}\nfunction run(fn) {\n return fn();\n}\nfunction blank_object() {\n return Object.create(null);\n}\nfunction run_all(fns) {\n fns.forEach(run);\n}\nfunction is_function(thing) {\n return typeof thing === 'function';\n}\nfunction safe_not_equal(a, b) {\n return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}\nfunction not_equal(a, b) {\n return a != a ? b == b : a !== b;\n}\nfunction is_empty(obj) {\n return Object.keys(obj).length === 0;\n}\nfunction validate_store(store, name) {\n if (store != null && typeof store.subscribe !== 'function') {\n throw new Error(`'${name}' is not a store with a 'subscribe' method`);\n }\n}\nfunction subscribe(store, ...callbacks) {\n if (store == null) {\n return noop;\n }\n const unsub = store.subscribe(...callbacks);\n return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\nfunction get_store_value(store) {\n let value;\n subscribe(store, _ => value = _)();\n return value;\n}\nfunction component_subscribe(component, store, callback) {\n component.$$.on_destroy.push(subscribe(store, callback));\n}\nfunction create_slot(definition, ctx, $$scope, fn) {\n if (definition) {\n const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n return definition[0](slot_ctx);\n }\n}\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n return definition[1] && fn\n ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))\n : $$scope.ctx;\n}\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n if (definition[2] && fn) {\n const lets = definition[2](fn(dirty));\n if ($$scope.dirty === undefined) {\n return lets;\n }\n if (typeof lets === 'object') {\n const merged = [];\n const len = Math.max($$scope.dirty.length, lets.length);\n for (let i = 0; i < len; i += 1) {\n merged[i] = $$scope.dirty[i] | lets[i];\n }\n return merged;\n }\n return $$scope.dirty | lets;\n }\n return $$scope.dirty;\n}\nfunction update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction update_slot_spread(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_spread_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_spread_changes_fn(dirty) | get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction exclude_internal_props(props) {\n const result = {};\n for (const k in props)\n if (k[0] !== '$')\n result[k] = props[k];\n return result;\n}\nfunction compute_rest_props(props, keys) {\n const rest = {};\n keys = new Set(keys);\n for (const k in props)\n if (!keys.has(k) && k[0] !== '$')\n rest[k] = props[k];\n return rest;\n}\nfunction compute_slots(slots) {\n const result = {};\n for (const key in slots) {\n result[key] = true;\n }\n return result;\n}\nfunction once(fn) {\n let ran = false;\n return function (...args) {\n if (ran)\n return;\n ran = true;\n fn.call(this, ...args);\n };\n}\nfunction null_to_empty(value) {\n return value == null ? '' : value;\n}\nfunction set_store_value(store, ret, value = ret) {\n store.set(value);\n return ret;\n}\nconst has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);\nfunction action_destroyer(action_result) {\n return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\n\nconst is_client = typeof window !== 'undefined';\nlet now = is_client\n ? () => window.performance.now()\n : () => Date.now();\nlet raf = is_client ? cb => requestAnimationFrame(cb) : noop;\n// used internally for testing\nfunction set_now(fn) {\n now = fn;\n}\nfunction set_raf(fn) {\n raf = fn;\n}\n\nconst tasks = new Set();\nfunction run_tasks(now) {\n tasks.forEach(task => {\n if (!task.c(now)) {\n tasks.delete(task);\n task.f();\n }\n });\n if (tasks.size !== 0)\n raf(run_tasks);\n}\n/**\n * For testing purposes only!\n */\nfunction clear_loops() {\n tasks.clear();\n}\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n */\nfunction loop(callback) {\n let task;\n if (tasks.size === 0)\n raf(run_tasks);\n return {\n promise: new Promise(fulfill => {\n tasks.add(task = { c: callback, f: fulfill });\n }),\n abort() {\n tasks.delete(task);\n }\n };\n}\n\nfunction append(target, node) {\n target.appendChild(node);\n}\nfunction insert(target, node, anchor) {\n target.insertBefore(node, anchor || null);\n}\nfunction detach(node) {\n node.parentNode.removeChild(node);\n}\nfunction destroy_each(iterations, detaching) {\n for (let i = 0; i < iterations.length; i += 1) {\n if (iterations[i])\n iterations[i].d(detaching);\n }\n}\nfunction element(name) {\n return document.createElement(name);\n}\nfunction element_is(name, is) {\n return document.createElement(name, { is });\n}\nfunction object_without_properties(obj, exclude) {\n const target = {};\n for (const k in obj) {\n if (has_prop(obj, k)\n // @ts-ignore\n && exclude.indexOf(k) === -1) {\n // @ts-ignore\n target[k] = obj[k];\n }\n }\n return target;\n}\nfunction svg_element(name) {\n return document.createElementNS('http://www.w3.org/2000/svg', name);\n}\nfunction text(data) {\n return document.createTextNode(data);\n}\nfunction space() {\n return text(' ');\n}\nfunction empty() {\n return text('');\n}\nfunction listen(node, event, handler, options) {\n node.addEventListener(event, handler, options);\n return () => node.removeEventListener(event, handler, options);\n}\nfunction prevent_default(fn) {\n return function (event) {\n event.preventDefault();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_propagation(fn) {\n return function (event) {\n event.stopPropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction self(fn) {\n return function (event) {\n // @ts-ignore\n if (event.target === this)\n fn.call(this, event);\n };\n}\nfunction attr(node, attribute, value) {\n if (value == null)\n node.removeAttribute(attribute);\n else if (node.getAttribute(attribute) !== value)\n node.setAttribute(attribute, value);\n}\nfunction set_attributes(node, attributes) {\n // @ts-ignore\n const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n for (const key in attributes) {\n if (attributes[key] == null) {\n node.removeAttribute(key);\n }\n else if (key === 'style') {\n node.style.cssText = attributes[key];\n }\n else if (key === '__value') {\n node.value = node[key] = attributes[key];\n }\n else if (descriptors[key] && descriptors[key].set) {\n node[key] = attributes[key];\n }\n else {\n attr(node, key, attributes[key]);\n }\n }\n}\nfunction set_svg_attributes(node, attributes) {\n for (const key in attributes) {\n attr(node, key, attributes[key]);\n }\n}\nfunction set_custom_element_data(node, prop, value) {\n if (prop in node) {\n node[prop] = value;\n }\n else {\n attr(node, prop, value);\n }\n}\nfunction xlink_attr(node, attribute, value) {\n node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\nfunction get_binding_group_value(group, __value, checked) {\n const value = new Set();\n for (let i = 0; i < group.length; i += 1) {\n if (group[i].checked)\n value.add(group[i].__value);\n }\n if (!checked) {\n value.delete(__value);\n }\n return Array.from(value);\n}\nfunction to_number(value) {\n return value === '' ? null : +value;\n}\nfunction time_ranges_to_array(ranges) {\n const array = [];\n for (let i = 0; i < ranges.length; i += 1) {\n array.push({ start: ranges.start(i), end: ranges.end(i) });\n }\n return array;\n}\nfunction children(element) {\n return Array.from(element.childNodes);\n}\nfunction claim_element(nodes, name, attributes, svg) {\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeName === name) {\n let j = 0;\n const remove = [];\n while (j < node.attributes.length) {\n const attribute = node.attributes[j++];\n if (!attributes[attribute.name]) {\n remove.push(attribute.name);\n }\n }\n for (let k = 0; k < remove.length; k++) {\n node.removeAttribute(remove[k]);\n }\n return nodes.splice(i, 1)[0];\n }\n }\n return svg ? svg_element(name) : element(name);\n}\nfunction claim_text(nodes, data) {\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeType === 3) {\n node.data = '' + data;\n return nodes.splice(i, 1)[0];\n }\n }\n return text(data);\n}\nfunction claim_space(nodes) {\n return claim_text(nodes, ' ');\n}\nfunction set_data(text, data) {\n data = '' + data;\n if (text.wholeText !== data)\n text.data = data;\n}\nfunction set_input_value(input, value) {\n input.value = value == null ? '' : value;\n}\nfunction set_input_type(input, type) {\n try {\n input.type = type;\n }\n catch (e) {\n // do nothing\n }\n}\nfunction set_style(node, key, value, important) {\n node.style.setProperty(key, value, important ? 'important' : '');\n}\nfunction select_option(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n if (option.__value === value) {\n option.selected = true;\n return;\n }\n }\n}\nfunction select_options(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n option.selected = ~value.indexOf(option.__value);\n }\n}\nfunction select_value(select) {\n const selected_option = select.querySelector(':checked') || select.options[0];\n return selected_option && selected_option.__value;\n}\nfunction select_multiple_value(select) {\n return [].map.call(select.querySelectorAll(':checked'), option => option.__value);\n}\n// unfortunately this can't be a constant as that wouldn't be tree-shakeable\n// so we cache the result instead\nlet crossorigin;\nfunction is_crossorigin() {\n if (crossorigin === undefined) {\n crossorigin = false;\n try {\n if (typeof window !== 'undefined' && window.parent) {\n void window.parent.document;\n }\n }\n catch (error) {\n crossorigin = true;\n }\n }\n return crossorigin;\n}\nfunction add_resize_listener(node, fn) {\n const computed_style = getComputedStyle(node);\n if (computed_style.position === 'static') {\n node.style.position = 'relative';\n }\n const iframe = element('iframe');\n iframe.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ' +\n 'overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: -1;');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.tabIndex = -1;\n const crossorigin = is_crossorigin();\n let unsubscribe;\n if (crossorigin) {\n iframe.src = \"data:text/html,\";\n unsubscribe = listen(window, 'message', (event) => {\n if (event.source === iframe.contentWindow)\n fn();\n });\n }\n else {\n iframe.src = 'about:blank';\n iframe.onload = () => {\n unsubscribe = listen(iframe.contentWindow, 'resize', fn);\n };\n }\n append(node, iframe);\n return () => {\n if (crossorigin) {\n unsubscribe();\n }\n else if (unsubscribe && iframe.contentWindow) {\n unsubscribe();\n }\n detach(iframe);\n };\n}\nfunction toggle_class(element, name, toggle) {\n element.classList[toggle ? 'add' : 'remove'](name);\n}\nfunction custom_event(type, detail) {\n const e = document.createEvent('CustomEvent');\n e.initCustomEvent(type, false, false, detail);\n return e;\n}\nfunction query_selector_all(selector, parent = document.body) {\n return Array.from(parent.querySelectorAll(selector));\n}\nclass HtmlTag {\n constructor(anchor = null) {\n this.a = anchor;\n this.e = this.n = null;\n }\n m(html, target, anchor = null) {\n if (!this.e) {\n this.e = element(target.nodeName);\n this.t = target;\n this.h(html);\n }\n this.i(anchor);\n }\n h(html) {\n this.e.innerHTML = html;\n this.n = Array.from(this.e.childNodes);\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert(this.t, this.n[i], anchor);\n }\n }\n p(html) {\n this.d();\n this.h(html);\n this.i(this.a);\n }\n d() {\n this.n.forEach(detach);\n }\n}\nfunction attribute_to_object(attributes) {\n const result = {};\n for (const attribute of attributes) {\n result[attribute.name] = attribute.value;\n }\n return result;\n}\nfunction get_custom_elements_slots(element) {\n const result = {};\n element.childNodes.forEach((node) => {\n result[node.slot || 'default'] = true;\n });\n return result;\n}\n\nconst active_docs = new Set();\nlet active = 0;\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\nfunction hash(str) {\n let hash = 5381;\n let i = str.length;\n while (i--)\n hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n return hash >>> 0;\n}\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n const step = 16.666 / duration;\n let keyframes = '{\\n';\n for (let p = 0; p <= 1; p += step) {\n const t = a + (b - a) * ease(p);\n keyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n }\n const rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n const name = `__svelte_${hash(rule)}_${uid}`;\n const doc = node.ownerDocument;\n active_docs.add(doc);\n const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = doc.head.appendChild(element('style')).sheet);\n const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {});\n if (!current_rules[name]) {\n current_rules[name] = true;\n stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n }\n const animation = node.style.animation || '';\n node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;\n active += 1;\n return name;\n}\nfunction delete_rule(node, name) {\n const previous = (node.style.animation || '').split(', ');\n const next = previous.filter(name\n ? anim => anim.indexOf(name) < 0 // remove specific animation\n : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n );\n const deleted = previous.length - next.length;\n if (deleted) {\n node.style.animation = next.join(', ');\n active -= deleted;\n if (!active)\n clear_rules();\n }\n}\nfunction clear_rules() {\n raf(() => {\n if (active)\n return;\n active_docs.forEach(doc => {\n const stylesheet = doc.__svelte_stylesheet;\n let i = stylesheet.cssRules.length;\n while (i--)\n stylesheet.deleteRule(i);\n doc.__svelte_rules = {};\n });\n active_docs.clear();\n });\n}\n\nfunction create_animation(node, from, fn, params) {\n if (!from)\n return noop;\n const to = node.getBoundingClientRect();\n if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom)\n return noop;\n const { delay = 0, duration = 300, easing = identity, \n // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?\n start: start_time = now() + delay, \n // @ts-ignore todo:\n end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);\n let running = true;\n let started = false;\n let name;\n function start() {\n if (css) {\n name = create_rule(node, 0, 1, duration, delay, easing, css);\n }\n if (!delay) {\n started = true;\n }\n }\n function stop() {\n if (css)\n delete_rule(node, name);\n running = false;\n }\n loop(now => {\n if (!started && now >= start_time) {\n started = true;\n }\n if (started && now >= end) {\n tick(1, 0);\n stop();\n }\n if (!running) {\n return false;\n }\n if (started) {\n const p = now - start_time;\n const t = 0 + 1 * easing(p / duration);\n tick(t, 1 - t);\n }\n return true;\n });\n start();\n tick(0, 1);\n return stop;\n}\nfunction fix_position(node) {\n const style = getComputedStyle(node);\n if (style.position !== 'absolute' && style.position !== 'fixed') {\n const { width, height } = style;\n const a = node.getBoundingClientRect();\n node.style.position = 'absolute';\n node.style.width = width;\n node.style.height = height;\n add_transform(node, a);\n }\n}\nfunction add_transform(node, a) {\n const b = node.getBoundingClientRect();\n if (a.left !== b.left || a.top !== b.top) {\n const style = getComputedStyle(node);\n const transform = style.transform === 'none' ? '' : style.transform;\n node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n }\n}\n\nlet current_component;\nfunction set_current_component(component) {\n current_component = component;\n}\nfunction get_current_component() {\n if (!current_component)\n throw new Error('Function called outside component initialization');\n return current_component;\n}\nfunction beforeUpdate(fn) {\n get_current_component().$$.before_update.push(fn);\n}\nfunction onMount(fn) {\n get_current_component().$$.on_mount.push(fn);\n}\nfunction afterUpdate(fn) {\n get_current_component().$$.after_update.push(fn);\n}\nfunction onDestroy(fn) {\n get_current_component().$$.on_destroy.push(fn);\n}\nfunction createEventDispatcher() {\n const component = get_current_component();\n return (type, detail) => {\n const callbacks = component.$$.callbacks[type];\n if (callbacks) {\n // TODO are there situations where events could be dispatched\n // in a server (non-DOM) environment?\n const event = custom_event(type, detail);\n callbacks.slice().forEach(fn => {\n fn.call(component, event);\n });\n }\n };\n}\nfunction setContext(key, context) {\n get_current_component().$$.context.set(key, context);\n}\nfunction getContext(key) {\n return get_current_component().$$.context.get(key);\n}\nfunction hasContext(key) {\n return get_current_component().$$.context.has(key);\n}\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\nfunction bubble(component, event) {\n const callbacks = component.$$.callbacks[event.type];\n if (callbacks) {\n callbacks.slice().forEach(fn => fn(event));\n }\n}\n\nconst dirty_components = [];\nconst intros = { enabled: false };\nconst binding_callbacks = [];\nconst render_callbacks = [];\nconst flush_callbacks = [];\nconst resolved_promise = Promise.resolve();\nlet update_scheduled = false;\nfunction schedule_update() {\n if (!update_scheduled) {\n update_scheduled = true;\n resolved_promise.then(flush);\n }\n}\nfunction tick() {\n schedule_update();\n return resolved_promise;\n}\nfunction add_render_callback(fn) {\n render_callbacks.push(fn);\n}\nfunction add_flush_callback(fn) {\n flush_callbacks.push(fn);\n}\nlet flushing = false;\nconst seen_callbacks = new Set();\nfunction flush() {\n if (flushing)\n return;\n flushing = true;\n do {\n // first, call beforeUpdate functions\n // and update components\n for (let i = 0; i < dirty_components.length; i += 1) {\n const component = dirty_components[i];\n set_current_component(component);\n update(component.$$);\n }\n set_current_component(null);\n dirty_components.length = 0;\n while (binding_callbacks.length)\n binding_callbacks.pop()();\n // then, once components are updated, call\n // afterUpdate functions. This may cause\n // subsequent updates...\n for (let i = 0; i < render_callbacks.length; i += 1) {\n const callback = render_callbacks[i];\n if (!seen_callbacks.has(callback)) {\n // ...so guard against infinite loops\n seen_callbacks.add(callback);\n callback();\n }\n }\n render_callbacks.length = 0;\n } while (dirty_components.length);\n while (flush_callbacks.length) {\n flush_callbacks.pop()();\n }\n update_scheduled = false;\n flushing = false;\n seen_callbacks.clear();\n}\nfunction update($$) {\n if ($$.fragment !== null) {\n $$.update();\n run_all($$.before_update);\n const dirty = $$.dirty;\n $$.dirty = [-1];\n $$.fragment && $$.fragment.p($$.ctx, dirty);\n $$.after_update.forEach(add_render_callback);\n }\n}\n\nlet promise;\nfunction wait() {\n if (!promise) {\n promise = Promise.resolve();\n promise.then(() => {\n promise = null;\n });\n }\n return promise;\n}\nfunction dispatch(node, direction, kind) {\n node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\nconst outroing = new Set();\nlet outros;\nfunction group_outros() {\n outros = {\n r: 0,\n c: [],\n p: outros // parent group\n };\n}\nfunction check_outros() {\n if (!outros.r) {\n run_all(outros.c);\n }\n outros = outros.p;\n}\nfunction transition_in(block, local) {\n if (block && block.i) {\n outroing.delete(block);\n block.i(local);\n }\n}\nfunction transition_out(block, local, detach, callback) {\n if (block && block.o) {\n if (outroing.has(block))\n return;\n outroing.add(block);\n outros.c.push(() => {\n outroing.delete(block);\n if (callback) {\n if (detach)\n block.d(1);\n callback();\n }\n });\n block.o(local);\n }\n}\nconst null_transition = { duration: 0 };\nfunction create_in_transition(node, fn, params) {\n let config = fn(node, params);\n let running = false;\n let animation_name;\n let task;\n let uid = 0;\n function cleanup() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);\n tick(0, 1);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n if (task)\n task.abort();\n running = true;\n add_render_callback(() => dispatch(node, true, 'start'));\n task = loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(1, 0);\n dispatch(node, true, 'end');\n cleanup();\n return running = false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(t, 1 - t);\n }\n }\n return running;\n });\n }\n let started = false;\n return {\n start() {\n if (started)\n return;\n delete_rule(node);\n if (is_function(config)) {\n config = config();\n wait().then(go);\n }\n else {\n go();\n }\n },\n invalidate() {\n started = false;\n },\n end() {\n if (running) {\n cleanup();\n running = false;\n }\n }\n };\n}\nfunction create_out_transition(node, fn, params) {\n let config = fn(node, params);\n let running = true;\n let animation_name;\n const group = outros;\n group.r += 1;\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 1, 0, duration, delay, easing, css);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n add_render_callback(() => dispatch(node, false, 'start'));\n loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(0, 1);\n dispatch(node, false, 'end');\n if (!--group.r) {\n // this will result in `end()` being called,\n // so we don't need to clean up here\n run_all(group.c);\n }\n return false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(1 - t, t);\n }\n }\n return running;\n });\n }\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go();\n });\n }\n else {\n go();\n }\n return {\n end(reset) {\n if (reset && config.tick) {\n config.tick(1, 0);\n }\n if (running) {\n if (animation_name)\n delete_rule(node, animation_name);\n running = false;\n }\n }\n };\n}\nfunction create_bidirectional_transition(node, fn, params, intro) {\n let config = fn(node, params);\n let t = intro ? 0 : 1;\n let running_program = null;\n let pending_program = null;\n let animation_name = null;\n function clear_animation() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function init(program, duration) {\n const d = program.b - t;\n duration *= Math.abs(d);\n return {\n a: t,\n b: program.b,\n d,\n duration,\n start: program.start,\n end: program.start + duration,\n group: program.group\n };\n }\n function go(b) {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n const program = {\n start: now() + delay,\n b\n };\n if (!b) {\n // @ts-ignore todo: improve typings\n program.group = outros;\n outros.r += 1;\n }\n if (running_program || pending_program) {\n pending_program = program;\n }\n else {\n // if this is an intro, and there's a delay, we need to do\n // an initial tick and/or apply CSS animation immediately\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, b, duration, delay, easing, css);\n }\n if (b)\n tick(0, 1);\n running_program = init(program, duration);\n add_render_callback(() => dispatch(node, b, 'start'));\n loop(now => {\n if (pending_program && now > pending_program.start) {\n running_program = init(pending_program, duration);\n pending_program = null;\n dispatch(node, running_program.b, 'start');\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);\n }\n }\n if (running_program) {\n if (now >= running_program.end) {\n tick(t = running_program.b, 1 - t);\n dispatch(node, running_program.b, 'end');\n if (!pending_program) {\n // we're done\n if (running_program.b) {\n // intro — we can tidy up immediately\n clear_animation();\n }\n else {\n // outro — needs to be coordinated\n if (!--running_program.group.r)\n run_all(running_program.group.c);\n }\n }\n running_program = null;\n }\n else if (now >= running_program.start) {\n const p = now - running_program.start;\n t = running_program.a + running_program.d * easing(p / running_program.duration);\n tick(t, 1 - t);\n }\n }\n return !!(running_program || pending_program);\n });\n }\n }\n return {\n run(b) {\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go(b);\n });\n }\n else {\n go(b);\n }\n },\n end() {\n clear_animation();\n running_program = pending_program = null;\n }\n };\n}\n\nfunction handle_promise(promise, info) {\n const token = info.token = {};\n function update(type, index, key, value) {\n if (info.token !== token)\n return;\n info.resolved = value;\n let child_ctx = info.ctx;\n if (key !== undefined) {\n child_ctx = child_ctx.slice();\n child_ctx[key] = value;\n }\n const block = type && (info.current = type)(child_ctx);\n let needs_flush = false;\n if (info.block) {\n if (info.blocks) {\n info.blocks.forEach((block, i) => {\n if (i !== index && block) {\n group_outros();\n transition_out(block, 1, 1, () => {\n if (info.blocks[i] === block) {\n info.blocks[i] = null;\n }\n });\n check_outros();\n }\n });\n }\n else {\n info.block.d(1);\n }\n block.c();\n transition_in(block, 1);\n block.m(info.mount(), info.anchor);\n needs_flush = true;\n }\n info.block = block;\n if (info.blocks)\n info.blocks[index] = block;\n if (needs_flush) {\n flush();\n }\n }\n if (is_promise(promise)) {\n const current_component = get_current_component();\n promise.then(value => {\n set_current_component(current_component);\n update(info.then, 1, info.value, value);\n set_current_component(null);\n }, error => {\n set_current_component(current_component);\n update(info.catch, 2, info.error, error);\n set_current_component(null);\n if (!info.hasCatch) {\n throw error;\n }\n });\n // if we previously had a then/catch block, destroy it\n if (info.current !== info.pending) {\n update(info.pending, 0);\n return true;\n }\n }\n else {\n if (info.current !== info.then) {\n update(info.then, 1, info.value, promise);\n return true;\n }\n info.resolved = promise;\n }\n}\n\nconst globals = (typeof window !== 'undefined'\n ? window\n : typeof globalThis !== 'undefined'\n ? globalThis\n : global);\n\nfunction destroy_block(block, lookup) {\n block.d(1);\n lookup.delete(block.key);\n}\nfunction outro_and_destroy_block(block, lookup) {\n transition_out(block, 1, 1, () => {\n lookup.delete(block.key);\n });\n}\nfunction fix_and_destroy_block(block, lookup) {\n block.f();\n destroy_block(block, lookup);\n}\nfunction fix_and_outro_and_destroy_block(block, lookup) {\n block.f();\n outro_and_destroy_block(block, lookup);\n}\nfunction update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {\n let o = old_blocks.length;\n let n = list.length;\n let i = o;\n const old_indexes = {};\n while (i--)\n old_indexes[old_blocks[i].key] = i;\n const new_blocks = [];\n const new_lookup = new Map();\n const deltas = new Map();\n i = n;\n while (i--) {\n const child_ctx = get_context(ctx, list, i);\n const key = get_key(child_ctx);\n let block = lookup.get(key);\n if (!block) {\n block = create_each_block(key, child_ctx);\n block.c();\n }\n else if (dynamic) {\n block.p(child_ctx, dirty);\n }\n new_lookup.set(key, new_blocks[i] = block);\n if (key in old_indexes)\n deltas.set(key, Math.abs(i - old_indexes[key]));\n }\n const will_move = new Set();\n const did_move = new Set();\n function insert(block) {\n transition_in(block, 1);\n block.m(node, next);\n lookup.set(block.key, block);\n next = block.first;\n n--;\n }\n while (o && n) {\n const new_block = new_blocks[n - 1];\n const old_block = old_blocks[o - 1];\n const new_key = new_block.key;\n const old_key = old_block.key;\n if (new_block === old_block) {\n // do nothing\n next = new_block.first;\n o--;\n n--;\n }\n else if (!new_lookup.has(old_key)) {\n // remove old block\n destroy(old_block, lookup);\n o--;\n }\n else if (!lookup.has(new_key) || will_move.has(new_key)) {\n insert(new_block);\n }\n else if (did_move.has(old_key)) {\n o--;\n }\n else if (deltas.get(new_key) > deltas.get(old_key)) {\n did_move.add(new_key);\n insert(new_block);\n }\n else {\n will_move.add(old_key);\n o--;\n }\n }\n while (o--) {\n const old_block = old_blocks[o];\n if (!new_lookup.has(old_block.key))\n destroy(old_block, lookup);\n }\n while (n)\n insert(new_blocks[n - 1]);\n return new_blocks;\n}\nfunction validate_each_keys(ctx, list, get_context, get_key) {\n const keys = new Set();\n for (let i = 0; i < list.length; i++) {\n const key = get_key(get_context(ctx, list, i));\n if (keys.has(key)) {\n throw new Error('Cannot have duplicate keys in a keyed each');\n }\n keys.add(key);\n }\n}\n\nfunction get_spread_update(levels, updates) {\n const update = {};\n const to_null_out = {};\n const accounted_for = { $$scope: 1 };\n let i = levels.length;\n while (i--) {\n const o = levels[i];\n const n = updates[i];\n if (n) {\n for (const key in o) {\n if (!(key in n))\n to_null_out[key] = 1;\n }\n for (const key in n) {\n if (!accounted_for[key]) {\n update[key] = n[key];\n accounted_for[key] = 1;\n }\n }\n levels[i] = n;\n }\n else {\n for (const key in o) {\n accounted_for[key] = 1;\n }\n }\n }\n for (const key in to_null_out) {\n if (!(key in update))\n update[key] = undefined;\n }\n return update;\n}\nfunction get_spread_object(spread_props) {\n return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\n// source: https://html.spec.whatwg.org/multipage/indices.html\nconst boolean_attributes = new Set([\n 'allowfullscreen',\n 'allowpaymentrequest',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'ismap',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n]);\n\nconst invalid_attribute_name_character = /[\\s'\">/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u;\n// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n// https://infra.spec.whatwg.org/#noncharacter\nfunction spread(args, classes_to_add) {\n const attributes = Object.assign({}, ...args);\n if (classes_to_add) {\n if (attributes.class == null) {\n attributes.class = classes_to_add;\n }\n else {\n attributes.class += ' ' + classes_to_add;\n }\n }\n let str = '';\n Object.keys(attributes).forEach(name => {\n if (invalid_attribute_name_character.test(name))\n return;\n const value = attributes[name];\n if (value === true)\n str += ' ' + name;\n else if (boolean_attributes.has(name.toLowerCase())) {\n if (value)\n str += ' ' + name;\n }\n else if (value != null) {\n str += ` ${name}=\"${String(value).replace(/\"/g, '"').replace(/'/g, ''')}\"`;\n }\n });\n return str;\n}\nconst escaped = {\n '\"': '"',\n \"'\": ''',\n '&': '&',\n '<': '<',\n '>': '>'\n};\nfunction escape(html) {\n return String(html).replace(/[\"'&<>]/g, match => escaped[match]);\n}\nfunction each(items, fn) {\n let str = '';\n for (let i = 0; i < items.length; i += 1) {\n str += fn(items[i], i);\n }\n return str;\n}\nconst missing_component = {\n $$render: () => ''\n};\nfunction validate_component(component, name) {\n if (!component || !component.$$render) {\n if (name === 'svelte:component')\n name += ' this={...}';\n throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);\n }\n return component;\n}\nfunction debug(file, line, column, values) {\n console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console\n console.log(values); // eslint-disable-line no-console\n return '';\n}\nlet on_destroy;\nfunction create_ssr_component(fn) {\n function $$render(result, props, bindings, slots) {\n const parent_component = current_component;\n const $$ = {\n on_destroy,\n context: new Map(parent_component ? parent_component.$$.context : []),\n // these will be immediately discarded\n on_mount: [],\n before_update: [],\n after_update: [],\n callbacks: blank_object()\n };\n set_current_component({ $$ });\n const html = fn(result, props, bindings, slots);\n set_current_component(parent_component);\n return html;\n }\n return {\n render: (props = {}, options = {}) => {\n on_destroy = [];\n const result = { title: '', head: '', css: new Set() };\n const html = $$render(result, props, {}, options);\n run_all(on_destroy);\n return {\n html,\n css: {\n code: Array.from(result.css).map(css => css.code).join('\\n'),\n map: null // TODO\n },\n head: result.title + result.head\n };\n },\n $$render\n };\n}\nfunction add_attribute(name, value, boolean) {\n if (value == null || (boolean && !value))\n return '';\n return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `\"${value}\"`}`}`;\n}\nfunction add_classes(classes) {\n return classes ? ` class=\"${classes}\"` : '';\n}\n\nfunction bind(component, name, callback) {\n const index = component.$$.props[name];\n if (index !== undefined) {\n component.$$.bound[index] = callback;\n callback(component.$$.ctx[index]);\n }\n}\nfunction create_component(block) {\n block && block.c();\n}\nfunction claim_component(block, parent_nodes) {\n block && block.l(parent_nodes);\n}\nfunction mount_component(component, target, anchor, customElement) {\n const { fragment, on_mount, on_destroy, after_update } = component.$$;\n fragment && fragment.m(target, anchor);\n if (!customElement) {\n // onMount happens before the initial afterUpdate\n add_render_callback(() => {\n const new_on_destroy = on_mount.map(run).filter(is_function);\n if (on_destroy) {\n on_destroy.push(...new_on_destroy);\n }\n else {\n // Edge case - component was destroyed immediately,\n // most likely as a result of a binding initialising\n run_all(new_on_destroy);\n }\n component.$$.on_mount = [];\n });\n }\n after_update.forEach(add_render_callback);\n}\nfunction destroy_component(component, detaching) {\n const $$ = component.$$;\n if ($$.fragment !== null) {\n run_all($$.on_destroy);\n $$.fragment && $$.fragment.d(detaching);\n // TODO null out other refs, including component.$$ (but need to\n // preserve final state?)\n $$.on_destroy = $$.fragment = null;\n $$.ctx = [];\n }\n}\nfunction make_dirty(component, i) {\n if (component.$$.dirty[0] === -1) {\n dirty_components.push(component);\n schedule_update();\n component.$$.dirty.fill(0);\n }\n component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));\n}\nfunction init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) {\n const parent_component = current_component;\n set_current_component(component);\n const $$ = component.$$ = {\n fragment: null,\n ctx: null,\n // state\n props,\n update: noop,\n not_equal,\n bound: blank_object(),\n // lifecycle\n on_mount: [],\n on_destroy: [],\n on_disconnect: [],\n before_update: [],\n after_update: [],\n context: new Map(parent_component ? parent_component.$$.context : []),\n // everything else\n callbacks: blank_object(),\n dirty,\n skip_bound: false\n };\n let ready = false;\n $$.ctx = instance\n ? instance(component, options.props || {}, (i, ret, ...rest) => {\n const value = rest.length ? rest[0] : ret;\n if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {\n if (!$$.skip_bound && $$.bound[i])\n $$.bound[i](value);\n if (ready)\n make_dirty(component, i);\n }\n return ret;\n })\n : [];\n $$.update();\n ready = true;\n run_all($$.before_update);\n // `false` as a special case of no DOM component\n $$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n if (options.target) {\n if (options.hydrate) {\n const nodes = children(options.target);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.l(nodes);\n nodes.forEach(detach);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.c();\n }\n if (options.intro)\n transition_in(component.$$.fragment);\n mount_component(component, options.target, options.anchor, options.customElement);\n flush();\n }\n set_current_component(parent_component);\n}\nlet SvelteElement;\nif (typeof HTMLElement === 'function') {\n SvelteElement = class extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n connectedCallback() {\n const { on_mount } = this.$$;\n this.$$.on_disconnect = on_mount.map(run).filter(is_function);\n // @ts-ignore todo: improve typings\n for (const key in this.$$.slotted) {\n // @ts-ignore todo: improve typings\n this.appendChild(this.$$.slotted[key]);\n }\n }\n attributeChangedCallback(attr, _oldValue, newValue) {\n this[attr] = newValue;\n }\n disconnectedCallback() {\n run_all(this.$$.on_disconnect);\n }\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n // TODO should this delegate to addEventListener?\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n };\n}\n/**\n * Base class for Svelte components. Used when dev=false.\n */\nclass SvelteComponent {\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n}\n\nfunction dispatch_dev(type, detail) {\n document.dispatchEvent(custom_event(type, Object.assign({ version: '3.35.0' }, detail)));\n}\nfunction append_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append(target, node);\n}\nfunction insert_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert(target, node, anchor);\n}\nfunction detach_dev(node) {\n dispatch_dev('SvelteDOMRemove', { node });\n detach(node);\n}\nfunction detach_between_dev(before, after) {\n while (before.nextSibling && before.nextSibling !== after) {\n detach_dev(before.nextSibling);\n }\n}\nfunction detach_before_dev(after) {\n while (after.previousSibling) {\n detach_dev(after.previousSibling);\n }\n}\nfunction detach_after_dev(before) {\n while (before.nextSibling) {\n detach_dev(before.nextSibling);\n }\n}\nfunction listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {\n const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];\n if (has_prevent_default)\n modifiers.push('preventDefault');\n if (has_stop_propagation)\n modifiers.push('stopPropagation');\n dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });\n const dispose = listen(node, event, handler, options);\n return () => {\n dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });\n dispose();\n };\n}\nfunction attr_dev(node, attribute, value) {\n attr(node, attribute, value);\n if (value == null)\n dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });\n else\n dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });\n}\nfunction prop_dev(node, property, value) {\n node[property] = value;\n dispatch_dev('SvelteDOMSetProperty', { node, property, value });\n}\nfunction dataset_dev(node, property, value) {\n node.dataset[property] = value;\n dispatch_dev('SvelteDOMSetDataset', { node, property, value });\n}\nfunction set_data_dev(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n dispatch_dev('SvelteDOMSetData', { node: text, data });\n text.data = data;\n}\nfunction validate_each_argument(arg) {\n if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {\n let msg = '{#each} only iterates over array-like objects.';\n if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {\n msg += ' You can use a spread to convert this iterable into an array.';\n }\n throw new Error(msg);\n }\n}\nfunction validate_slots(name, slot, keys) {\n for (const slot_key of Object.keys(slot)) {\n if (!~keys.indexOf(slot_key)) {\n console.warn(`<${name}> received an unexpected slot \"${slot_key}\".`);\n }\n }\n}\n/**\n * Base class for Svelte components with some minor dev-enhancements. Used when dev=true.\n */\nclass SvelteComponentDev extends SvelteComponent {\n constructor(options) {\n if (!options || (!options.target && !options.$$inline)) {\n throw new Error(\"'target' is a required option\");\n }\n super();\n }\n $destroy() {\n super.$destroy();\n this.$destroy = () => {\n console.warn('Component was already destroyed'); // eslint-disable-line no-console\n };\n }\n $capture_state() { }\n $inject_state() { }\n}\n/**\n * Base class to create strongly typed Svelte components.\n * This only exists for typing purposes and should be used in `.d.ts` files.\n *\n * ### Example:\n *\n * You have component library on npm called `component-library`, from which\n * you export a component called `MyComponent`. For Svelte+TypeScript users,\n * you want to provide typings. Therefore you create a `index.d.ts`:\n * ```ts\n * import { SvelteComponentTyped } from \"svelte\";\n * export class MyComponent extends SvelteComponentTyped<{foo: string}> {}\n * ```\n * Typing this makes it possible for IDEs like VS Code with the Svelte extension\n * to provide intellisense and to use the component like this in a Svelte file\n * with TypeScript:\n * ```svelte\n * \n * \n * ```\n *\n * #### Why not make this part of `SvelteComponent(Dev)`?\n * Because\n * ```ts\n * class ASubclassOfSvelteComponent extends SvelteComponent<{foo: string}> {}\n * const component: typeof SvelteComponent = ASubclassOfSvelteComponent;\n * ```\n * will throw a type error, so we need to seperate the more strictly typed class.\n */\nclass SvelteComponentTyped extends SvelteComponentDev {\n constructor(options) {\n super(options);\n }\n}\nfunction loop_guard(timeout) {\n const start = Date.now();\n return () => {\n if (Date.now() - start > timeout) {\n throw new Error('Infinite loop detected');\n }\n };\n}\n\nexport { HtmlTag, SvelteComponent, SvelteComponentDev, SvelteComponentTyped, SvelteElement, action_destroyer, add_attribute, add_classes, add_flush_callback, add_location, add_render_callback, add_resize_listener, add_transform, afterUpdate, append, append_dev, assign, attr, attr_dev, attribute_to_object, beforeUpdate, bind, binding_callbacks, blank_object, bubble, check_outros, children, claim_component, claim_element, claim_space, claim_text, clear_loops, component_subscribe, compute_rest_props, compute_slots, createEventDispatcher, create_animation, create_bidirectional_transition, create_component, create_in_transition, create_out_transition, create_slot, create_ssr_component, current_component, custom_event, dataset_dev, debug, destroy_block, destroy_component, destroy_each, detach, detach_after_dev, detach_before_dev, detach_between_dev, detach_dev, dirty_components, dispatch_dev, each, element, element_is, empty, escape, escaped, exclude_internal_props, fix_and_destroy_block, fix_and_outro_and_destroy_block, fix_position, flush, getContext, get_binding_group_value, get_current_component, get_custom_elements_slots, get_slot_changes, get_slot_context, get_spread_object, get_spread_update, get_store_value, globals, group_outros, handle_promise, hasContext, has_prop, identity, init, insert, insert_dev, intros, invalid_attribute_name_character, is_client, is_crossorigin, is_empty, is_function, is_promise, listen, listen_dev, loop, loop_guard, missing_component, mount_component, noop, not_equal, now, null_to_empty, object_without_properties, onDestroy, onMount, once, outro_and_destroy_block, prevent_default, prop_dev, query_selector_all, raf, run, run_all, safe_not_equal, schedule_update, select_multiple_value, select_option, select_options, select_value, self, setContext, set_attributes, set_current_component, set_custom_element_data, set_data, set_data_dev, set_input_type, set_input_value, set_now, set_raf, set_store_value, set_style, set_svg_attributes, space, spread, stop_propagation, subscribe, svg_element, text, tick, time_ranges_to_array, to_number, toggle_class, transition_in, transition_out, update_keyed_each, update_slot, update_slot_spread, validate_component, validate_each_argument, validate_each_keys, validate_slots, validate_store, xlink_attr };\n","import { noop, safe_not_equal, subscribe, run_all, is_function } from '../internal/index.mjs';\nexport { get_store_value as get } from '../internal/index.mjs';\n\nconst subscriber_queue = [];\n/**\n * Creates a `Readable` store that allows reading by subscription.\n * @param value initial value\n * @param {StartStopNotifier}start start and stop notifications for subscriptions\n */\nfunction readable(value, start) {\n return {\n subscribe: writable(value, start).subscribe\n };\n}\n/**\n * Create a `Writable` store that allows both updating and reading by subscription.\n * @param {*=}value initial value\n * @param {StartStopNotifier=}start start and stop notifications for subscriptions\n */\nfunction writable(value, start = noop) {\n let stop;\n const subscribers = [];\n function set(new_value) {\n if (safe_not_equal(value, new_value)) {\n value = new_value;\n if (stop) { // store is ready\n const run_queue = !subscriber_queue.length;\n for (let i = 0; i < subscribers.length; i += 1) {\n const s = subscribers[i];\n s[1]();\n subscriber_queue.push(s, value);\n }\n if (run_queue) {\n for (let i = 0; i < subscriber_queue.length; i += 2) {\n subscriber_queue[i][0](subscriber_queue[i + 1]);\n }\n subscriber_queue.length = 0;\n }\n }\n }\n }\n function update(fn) {\n set(fn(value));\n }\n function subscribe(run, invalidate = noop) {\n const subscriber = [run, invalidate];\n subscribers.push(subscriber);\n if (subscribers.length === 1) {\n stop = start(set) || noop;\n }\n run(value);\n return () => {\n const index = subscribers.indexOf(subscriber);\n if (index !== -1) {\n subscribers.splice(index, 1);\n }\n if (subscribers.length === 0) {\n stop();\n stop = null;\n }\n };\n }\n return { set, update, subscribe };\n}\nfunction derived(stores, fn, initial_value) {\n const single = !Array.isArray(stores);\n const stores_array = single\n ? [stores]\n : stores;\n const auto = fn.length < 2;\n return readable(initial_value, (set) => {\n let inited = false;\n const values = [];\n let pending = 0;\n let cleanup = noop;\n const sync = () => {\n if (pending) {\n return;\n }\n cleanup();\n const result = fn(single ? values[0] : values, set);\n if (auto) {\n set(result);\n }\n else {\n cleanup = is_function(result) ? result : noop;\n }\n };\n const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {\n values[i] = value;\n pending &= ~(1 << i);\n if (inited) {\n sync();\n }\n }, () => {\n pending |= (1 << i);\n }));\n inited = true;\n sync();\n return function stop() {\n run_all(unsubscribers);\n cleanup();\n };\n });\n}\n\nexport { derived, readable, writable };\n","/*!\n * hotkeys-js v3.8.5\n * A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.\n * \n * Copyright (c) 2021 kenny wong \n * http://jaywcjlove.github.io/hotkeys\n * \n * Licensed under the MIT license.\n */\n\nvar isff = typeof navigator !== 'undefined' ? navigator.userAgent.toLowerCase().indexOf('firefox') > 0 : false; // 绑定事件\n\nfunction addEvent(object, event, method) {\n if (object.addEventListener) {\n object.addEventListener(event, method, false);\n } else if (object.attachEvent) {\n object.attachEvent(\"on\".concat(event), function () {\n method(window.event);\n });\n }\n} // 修饰键转换成对应的键码\n\n\nfunction getMods(modifier, key) {\n var mods = key.slice(0, key.length - 1);\n\n for (var i = 0; i < mods.length; i++) {\n mods[i] = modifier[mods[i].toLowerCase()];\n }\n\n return mods;\n} // 处理传的key字符串转换成数组\n\n\nfunction getKeys(key) {\n if (typeof key !== 'string') key = '';\n key = key.replace(/\\s/g, ''); // 匹配任何空白字符,包括空格、制表符、换页符等等\n\n var keys = key.split(','); // 同时设置多个快捷键,以','分割\n\n var index = keys.lastIndexOf(''); // 快捷键可能包含',',需特殊处理\n\n for (; index >= 0;) {\n keys[index - 1] += ',';\n keys.splice(index, 1);\n index = keys.lastIndexOf('');\n }\n\n return keys;\n} // 比较修饰键的数组\n\n\nfunction compareArray(a1, a2) {\n var arr1 = a1.length >= a2.length ? a1 : a2;\n var arr2 = a1.length >= a2.length ? a2 : a1;\n var isIndex = true;\n\n for (var i = 0; i < arr1.length; i++) {\n if (arr2.indexOf(arr1[i]) === -1) isIndex = false;\n }\n\n return isIndex;\n}\n\nvar _keyMap = {\n backspace: 8,\n tab: 9,\n clear: 12,\n enter: 13,\n return: 13,\n esc: 27,\n escape: 27,\n space: 32,\n left: 37,\n up: 38,\n right: 39,\n down: 40,\n del: 46,\n delete: 46,\n ins: 45,\n insert: 45,\n home: 36,\n end: 35,\n pageup: 33,\n pagedown: 34,\n capslock: 20,\n num_0: 96,\n num_1: 97,\n num_2: 98,\n num_3: 99,\n num_4: 100,\n num_5: 101,\n num_6: 102,\n num_7: 103,\n num_8: 104,\n num_9: 105,\n num_multiply: 106,\n num_add: 107,\n num_enter: 108,\n num_subtract: 109,\n num_decimal: 110,\n num_divide: 111,\n '⇪': 20,\n ',': 188,\n '.': 190,\n '/': 191,\n '`': 192,\n '-': isff ? 173 : 189,\n '=': isff ? 61 : 187,\n ';': isff ? 59 : 186,\n '\\'': 222,\n '[': 219,\n ']': 221,\n '\\\\': 220\n}; // Modifier Keys\n\nvar _modifier = {\n // shiftKey\n '⇧': 16,\n shift: 16,\n // altKey\n '⌥': 18,\n alt: 18,\n option: 18,\n // ctrlKey\n '⌃': 17,\n ctrl: 17,\n control: 17,\n // metaKey\n '⌘': 91,\n cmd: 91,\n command: 91\n};\nvar modifierMap = {\n 16: 'shiftKey',\n 18: 'altKey',\n 17: 'ctrlKey',\n 91: 'metaKey',\n shiftKey: 16,\n ctrlKey: 17,\n altKey: 18,\n metaKey: 91\n};\nvar _mods = {\n 16: false,\n 18: false,\n 17: false,\n 91: false\n};\nvar _handlers = {}; // F1~F12 special key\n\nfor (var k = 1; k < 20; k++) {\n _keyMap[\"f\".concat(k)] = 111 + k;\n}\n\nvar _downKeys = []; // 记录摁下的绑定键\n\nvar _scope = 'all'; // 默认热键范围\n\nvar elementHasBindEvent = []; // 已绑定事件的节点记录\n// 返回键码\n\nvar code = function code(x) {\n return _keyMap[x.toLowerCase()] || _modifier[x.toLowerCase()] || x.toUpperCase().charCodeAt(0);\n}; // 设置获取当前范围(默认为'所有')\n\n\nfunction setScope(scope) {\n _scope = scope || 'all';\n} // 获取当前范围\n\n\nfunction getScope() {\n return _scope || 'all';\n} // 获取摁下绑定键的键值\n\n\nfunction getPressedKeyCodes() {\n return _downKeys.slice(0);\n} // 表单控件控件判断 返回 Boolean\n// hotkey is effective only when filter return true\n\n\nfunction filter(event) {\n var target = event.target || event.srcElement;\n var tagName = target.tagName;\n var flag = true; // ignore: isContentEditable === 'true', and '\n );\n setTimeout(() => {\n const fileInput = document.getElementById(\"file-response\");\n fileInput.value = value;\n document\n .getElementById(\"file-save\")\n .addEventListener(\"click\", function () {\n writeFile(\n {\n file: pathToRead,\n contents: fileInput.value,\n },\n {\n dir: getDir(),\n }\n ).catch(onMessage);\n });\n });\n }\n } else {\n onMessage(response);\n }\n })\n .catch(onMessage);\n }\n\n function setSrc() {\n img.src = convertFileSrc(pathToRead)\n }\n\n\n
    \n \n \n \n \n\n \"file\"\n\n","\n\n
    \n \n \n
    \n \n \n\n","\n\n\n","import{i as e}from\"./tauri-48bdc082.js\";import{l as a,o as t,b as i}from\"./event-29f50a54.js\";class s{constructor(e,a){this.type=\"Logical\",this.width=e,this.height=a}}class n{constructor(e,a){this.type=\"Physical\",this.width=e,this.height=a}toLogical(e){return new s(this.width/e,this.height/e)}}class l{constructor(e,a){this.type=\"Logical\",this.x=e,this.y=a}}class r{constructor(e,a){this.type=\"Physical\",this.x=e,this.y=a}toLogical(e){return new l(this.x/e,this.y/e)}}var d;function o(){return new h(window.__TAURI__.__currentWindow.label,{skip:!0})}function c(){return window.__TAURI__.__windows.map((e=>new h(e.label,{skip:!0})))}!function(e){e[e.Critical=1]=\"Critical\",e[e.Informational=2]=\"Informational\"}(d||(d={}));const m=[\"tauri://created\",\"tauri://error\"];class u{constructor(e){this.label=e,this.listeners=Object.create(null)}async listen(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const a=this.listeners[e];a.splice(a.indexOf(t),1)})):a(e,t)}async once(e,a){return this._handleTauriEvent(e,a)?Promise.resolve((()=>{const t=this.listeners[e];t.splice(t.indexOf(a),1)})):t(e,a)}async emit(e,a){if(m.includes(e)){for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:a});return Promise.resolve()}return i(e,this.label,a)}_handleTauriEvent(e,a){return!!m.includes(e)&&(e in this.listeners?this.listeners[e].push(a):this.listeners[e]=[a],!0)}}class y extends u{async scaleFactor(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"scaleFactor\"}}}})}async innerPosition(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"innerPosition\"}}}})}async outerPosition(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"outerPosition\"}}}})}async innerSize(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"innerSize\"}}}})}async outerSize(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"outerSize\"}}}})}async isFullscreen(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"isFullscreen\"}}}})}async isMaximized(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"isMaximized\"}}}})}async isDecorated(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"isDecorated\"}}}})}async isResizable(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"isResizable\"}}}})}async isVisible(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"isVisible\"}}}})}async center(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"center\"}}}})}async requestUserAttention(a){let t=null;return a&&(t=a===d.Critical?{type:\"Critical\"}:{type:\"Informational\"}),e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"requestUserAttention\",payload:t}}}})}async setResizable(a){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setResizable\",payload:a}}}})}async setTitle(a){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setTitle\",payload:a}}}})}async maximize(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"maximize\"}}}})}async unmaximize(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"unmaximize\"}}}})}async toggleMaximize(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"toggleMaximize\"}}}})}async minimize(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"minimize\"}}}})}async unminimize(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"unminimize\"}}}})}async show(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"show\"}}}})}async hide(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"hide\"}}}})}async close(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"close\"}}}})}async setDecorations(a){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setDecorations\",payload:a}}}})}async setAlwaysOnTop(a){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setAlwaysOnTop\",payload:a}}}})}async setSize(a){if(!a||\"Logical\"!==a.type&&\"Physical\"!==a.type)throw new Error(\"the `size` argument must be either a LogicalSize or a PhysicalSize instance\");return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setSize\",payload:{type:a.type,data:{width:a.width,height:a.height}}}}}})}async setMinSize(a){if(a&&\"Logical\"!==a.type&&\"Physical\"!==a.type)throw new Error(\"the `size` argument must be either a LogicalSize or a PhysicalSize instance\");return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setMinSize\",payload:a?{type:a.type,data:{width:a.width,height:a.height}}:null}}}})}async setMaxSize(a){if(a&&\"Logical\"!==a.type&&\"Physical\"!==a.type)throw new Error(\"the `size` argument must be either a LogicalSize or a PhysicalSize instance\");return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setMaxSize\",payload:a?{type:a.type,data:{width:a.width,height:a.height}}:null}}}})}async setPosition(a){if(!a||\"Logical\"!==a.type&&\"Physical\"!==a.type)throw new Error(\"the `position` argument must be either a LogicalPosition or a PhysicalPosition instance\");return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setPosition\",payload:{type:a.type,data:{x:a.x,y:a.y}}}}}})}async setFullscreen(a){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setFullscreen\",payload:a}}}})}async setFocus(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setFocus\"}}}})}async setIcon(a){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setIcon\",payload:{icon:a}}}}})}async setSkipTaskbar(a){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"setSkipTaskbar\",payload:a}}}})}async startDragging(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{label:this.label,cmd:{type:\"startDragging\"}}}})}}class h extends y{constructor(a,t={}){super(a),t?.skip||e({__tauriModule:\"Window\",message:{cmd:\"createWebview\",data:{options:{label:a,...t}}}}).then((async()=>this.emit(\"tauri://created\"))).catch((async e=>this.emit(\"tauri://error\",e)))}static getByLabel(e){return c().some((a=>a.label===e))?new h(e,{skip:!0}):null}}const g=new h(null,{skip:!0});async function p(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{cmd:{type:\"currentMonitor\"}}}})}async function b(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{cmd:{type:\"primaryMonitor\"}}}})}async function _(){return e({__tauriModule:\"Window\",message:{cmd:\"manage\",data:{cmd:{type:\"availableMonitors\"}}}})}var w=Object.freeze({__proto__:null,WebviewWindow:h,WebviewWindowHandle:u,WindowManager:y,getCurrent:o,getAll:c,appWindow:g,LogicalSize:s,PhysicalSize:n,LogicalPosition:l,PhysicalPosition:r,get UserAttentionType(){return d},currentMonitor:p,primaryMonitor:b,availableMonitors:_});export{s as L,n as P,d as U,h as W,u as a,y as b,c,g as d,l as e,r as f,o as g,p as h,_ as i,b as p,w};\n","\n\n
    \n \n
    \n \n \n \n \n \n \n \n \n \n \n
    \n
    \n
    \n
    \n
    \n X\n \n
    \n
    \n Y\n \n
    \n
    \n\n
    \n
    \n Width\n \n
    \n
    \n Height\n \n
    \n
    \n\n
    \n
    \n Min width\n \n
    \n
    \n Min height\n \n
    \n
    \n\n
    \n
    \n Max width\n \n
    \n
    \n Max height\n \n
    \n
    \n
    \n
    \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n\n\n\n\n","import{i as r}from\"./tauri-48bdc082.js\";import{t}from\"./tauri-6032cb22.js\";async function e(e,s){return r({__tauriModule:\"GlobalShortcut\",message:{cmd:\"register\",shortcut:e,handler:t(s)}})}async function s(e,s){return r({__tauriModule:\"GlobalShortcut\",message:{cmd:\"registerAll\",shortcuts:e,handler:t(s)}})}async function u(t){return r({__tauriModule:\"GlobalShortcut\",message:{cmd:\"isRegistered\",shortcut:t}})}async function a(t){return r({__tauriModule:\"GlobalShortcut\",message:{cmd:\"unregister\",shortcut:t}})}async function o(){return r({__tauriModule:\"GlobalShortcut\",message:{cmd:\"unregisterAll\"}})}var i=Object.freeze({__proto__:null,register:e,registerAll:s,isRegistered:u,unregister:a,unregisterAll:o});export{s as a,o as b,i as g,u as i,e as r,a as u};\n","\n\n
    \n
    \n \n \n
    \n
    \n {#each $shortcuts as savedShortcut}\n
    \n {savedShortcut}\n
    \n {/each}\n {#if $shortcuts.length}\n \n {/if}\n
    \n
    \n","\n\n
    \n
    \n \n \n \n {#if child}\n \n \n {/if}\n
    \n
    \n \n \n
    \n
    \n","import{l as t,a,o as r}from\"./event-29f50a54.js\";async function e(){let r;function e(){r&&r(),r=void 0}return new Promise(((o,s)=>{t(\"tauri://update-status\",(t=>{var a;(a=t?.payload).error?(e(),s(a.error)):\"DONE\"===a.status&&(e(),o())})).then((t=>{r=t})).catch((t=>{throw e(),t})),a(\"tauri://update-install\").catch((t=>{throw e(),t}))}))}async function o(){let e;function o(){e&&e(),e=void 0}return new Promise(((s,u)=>{r(\"tauri://update-available\",(t=>{var a;a=t?.payload,o(),s({manifest:a,shouldUpdate:!0})})).catch((t=>{throw o(),t})),t(\"tauri://update-status\",(t=>{var a;(a=t?.payload).error?(o(),u(a.error)):\"UPTODATE\"===a.status&&(o(),s({shouldUpdate:!1}))})).then((t=>{e=t})).catch((t=>{throw o(),t})),a(\"tauri://update\").catch((t=>{throw o(),t}))}))}var s=Object.freeze({__proto__:null,installUpdate:e,checkUpdate:o});export{o as c,e as i,s as u};\n","\n\n
    \n \n \n
    \n","import{i as e}from\"./tauri-48bdc082.js\";async function r(r){return e({__tauriModule:\"Clipboard\",message:{cmd:\"writeText\",data:r}})}async function a(){return e({__tauriModule:\"Clipboard\",message:{cmd:\"readText\"}})}var t=Object.freeze({__proto__:null,writeText:r,readText:a});export{t as c,a as r,r as w};\n","\n\n
    \n
    \n \n \n
    \n \n
    \n","\n\n
    \n

    Not available for Linux

    \n \n
    \n","\n\n\n\n\n\n

    \n\tResult:\n

    \n
    \n{result}\n
    ","\n\n
    \n \n
    \n
    \n {#each views as view}\n

    select(view)}\n >\n {view.label}\n

    \n {/each}\n
    \n
    \n \n
    \n
    \n
    \n

    \n Tauri Console\n {\n responses.update(() => []);\n }}>clear\n

    \n {@html response}\n
    \n
    \n","import App from './App.svelte'\n\nconst app = new App({\n target: document.body\n})\n\nexport default app\n"],"names":["noop","run","fn","blank_object","Object","create","run_all","fns","forEach","is_function","thing","safe_not_equal","a","b","component_subscribe","component","store","callback","$$","on_destroy","push","callbacks","unsub","subscribe","unsubscribe","append","target","node","appendChild","insert","anchor","insertBefore","detach","parentNode","removeChild","destroy_each","iterations","detaching","i","length","d","element","name","document","createElement","text","data","createTextNode","space","listen","event","handler","options","addEventListener","removeEventListener","prevent_default","preventDefault","call","this","attr","attribute","value","removeAttribute","getAttribute","setAttribute","to_number","set_data","wholeText","set_input_value","input","set_style","key","important","style","setProperty","select_option","select","option","__value","selected","select_value","selected_option","querySelector","HtmlTag","[object Object]","e","n","html","nodeName","t","h","innerHTML","Array","from","childNodes","current_component","set_current_component","get_current_component","Error","onMount","on_mount","onDestroy","dirty_components","binding_callbacks","render_callbacks","flush_callbacks","resolved_promise","Promise","resolve","update_scheduled","add_render_callback","flushing","seen_callbacks","Set","flush","update","pop","has","add","clear","fragment","before_update","dirty","p","ctx","after_update","outroing","outros","transition_in","block","local","delete","transition_out","o","c","create_component","mount_component","customElement","m","new_on_destroy","map","filter","destroy_component","make_dirty","then","fill","init","instance","create_fragment","not_equal","props","parent_component","bound","on_disconnect","context","Map","skip_bound","ready","ret","rest","hydrate","nodes","children","l","intro","SvelteComponent","$destroy","type","index","indexOf","splice","$$props","obj","$$set","keys","subscriber_queue","writable","start","stop","subscribers","set","new_value","run_queue","s","invalidate","subscriber","isff","navigator","userAgent","toLowerCase","addEvent","object","method","attachEvent","concat","window","getMods","modifier","mods","slice","getKeys","replace","split","lastIndexOf","_keyMap","backspace","tab","enter","return","esc","escape","left","up","right","down","del","ins","home","end","pageup","pagedown","capslock","num_0","num_1","num_2","num_3","num_4","num_5","num_6","num_7","num_8","num_9","num_multiply","num_add","num_enter","num_subtract","num_decimal","num_divide","⇪",",",".","/","`","-","=",";","'","[","]","\\","_modifier","⇧","shift","⌥","alt","⌃","ctrl","control","⌘","cmd","command","modifierMap","16","18","17","91","shiftKey","ctrlKey","altKey","metaKey","_mods","_handlers","k","_downKeys","_scope","elementHasBindEvent","code","x","toUpperCase","charCodeAt","setScope","scope","getScope","eachUnbind","_ref","_ref$splitKey","splitKey","originKey","unbindKeys","len","lastKey","keyCode","record","a1","a2","arr1","arr2","isIndex","compareArray","eventHandler","modifiersMatch","y","prototype","hasOwnProperty","shortcut","returnValue","stopPropagation","cancelBubble","dispatch","asterisk","which","charCode","hotkeys","keyName","keyNum","getModifierState","keydown","keyup","_i","keyShortcut","_downKeysCurrent","sort","join","undefined","toString","isElementBind","clearModifier","_api","deleteScope","newScope","handlers","getPressedKeyCodes","isPressed","srcElement","tagName","flag","isContentEditable","readOnly","unbind","keysInfo","isArray","info","_len","arguments","args","_key","_hotkeys","noConflict","deep","Int8Array","crypto","getRandomValues","Uint8Array","Math","max","abs","defineProperty","r","Reflect","deleteProperty","configurable","async","rpc","notify","__invokeKey","__TAURI_INVOKE_KEY__","error","includes","freeze","__proto__","transformCallback","invoke","convertFileSrc","eventListeners","pid","__tauriModule","message","buffer","super","stdout","stderr","program","sidecar","onEventFn","_emit","payload","on","signal","spawn","catch","path","with","exitCode","version","tauriVersion","appName","getName","getVersion","v","getTauriVersion","exit","relaunch","Command","Child","open","onMessage","getMatches","windowLabel","eventId","id","unlisten","endpoint","body","emit","once","String","fromCharCode","apply","subarray","btoa","defaultPath","multiple","directory","filters","extensions","f","trim","res","pathToRead","isFile","match","readBinaryFile","response","blob","reader","base64","Blob","FileReader","onload","evt","dataurl","result","substr","readAsDataURL","save","Audio","Cache","Config","Data","LocalData","Desktop","Document","Download","Executable","Font","Home","Picture","Public","Runtime","Template","Video","Resource","App","Current","BaseDirectory","Dir","readTextFile","writeFile","contents","writeBinaryFile","readDir","createDir","removeDir","copyFile","source","destination","removeFile","renameFile","oldPath","newPath","getDir","getElementById","parseInt","dir","img","DirOptions","isNaN","opts","arrayBufferToBase64","setTimeout","fileInput","file","src","JSON","Text","Binary","url","status","ok","headers","client","responseType","parse","request","httpMethod","httpUrl","httpBody","getClient","startsWith","endsWith","Body","json","fetch","Client","Response","ResponseType","_sendNotification","Notification","permission","requestPermission","width","height","__TAURI__","__currentWindow","label","skip","__windows","Critical","Informational","u","listeners","_handleTauriEvent","icon","some","g","UserAttentionType","selectedWindow","getCurrent","windowMap","appWindow","urlValue","resizable","maximized","transparent","decorations","alwaysOnTop","fullscreen","minWidth","minHeight","maxWidth","maxHeight","windowTitle","setResizable","maximize","unmaximize","setDecorations","setAlwaysOnTop","setFullscreen","setSize","LogicalSize","setMinSize","setMaxSize","setPosition","LogicalPosition","setTitle","hide","show","minimize","unminimize","openDialog","setIcon","random","webview","WebviewWindow","requestUserAttention","center","WebviewWindowHandle","WindowManager","getAll","PhysicalSize","PhysicalPosition","currentMonitor","primaryMonitor","availableMonitors","shortcuts","unregister","shortcut_","unregisterShortcut","shortcuts_","registerShortcut","unregisterAllShortcuts","savedShortcut","register","registerAll","isRegistered","unregisterAll","windows","child","script","cwd","env","stdin","reduce","clause","line","kill","write","manifest","shouldUpdate","classList","checkUpdate","remove","installUpdate","writeText","readText","constraints","audio","video","stream","videoTracks","getVideoTracks","srcObject","handleSuccess","mediaDevices","getUserMedia","exact","handleError","getTracks","track","foo","bar","stringify","views","Welcome","Communication","Cli","Dialog","FileSystem","Http","HttpForm","Notifications","Window","Shortcuts","Shell","Updater","Clipboard","WebRTC","responses","view","Date","toLocaleTimeString"],"mappings":"gCAAA,SAASA,KAgBT,SAASC,EAAIC,GACT,OAAOA,IAEX,SAASC,IACL,OAAOC,OAAOC,OAAO,MAEzB,SAASC,EAAQC,GACbA,EAAIC,QAAQP,GAEhB,SAASQ,EAAYC,GACjB,MAAwB,mBAAVA,EAElB,SAASC,EAAeC,EAAGC,GACvB,OAAOD,GAAKA,EAAIC,GAAKA,EAAID,IAAMC,GAAOD,GAAkB,iBAANA,GAAgC,mBAANA,EAyBhF,SAASE,EAAoBC,EAAWC,EAAOC,GAC3CF,EAAUG,GAAGC,WAAWC,KAb5B,SAAmBJ,KAAUK,GACzB,GAAa,MAATL,EACA,OAAOhB,EAEX,MAAMsB,EAAQN,EAAMO,aAAaF,GACjC,OAAOC,EAAME,YAAc,IAAMF,EAAME,cAAgBF,EAQ1BC,CAAUP,EAAOC,IAwIlD,SAASQ,EAAOC,EAAQC,GACpBD,EAAOE,YAAYD,GAEvB,SAASE,EAAOH,EAAQC,EAAMG,GAC1BJ,EAAOK,aAAaJ,EAAMG,GAAU,MAExC,SAASE,EAAOL,GACZA,EAAKM,WAAWC,YAAYP,GAEhC,SAASQ,EAAaC,EAAYC,GAC9B,IAAK,IAAIC,EAAI,EAAGA,EAAIF,EAAWG,OAAQD,GAAK,EACpCF,EAAWE,IACXF,EAAWE,GAAGE,EAAEH,GAG5B,SAASI,EAAQC,GACb,OAAOC,SAASC,cAAcF,GAoBlC,SAASG,EAAKC,GACV,OAAOH,SAASI,eAAeD,GAEnC,SAASE,IACL,OAAOH,EAAK,KAKhB,SAASI,EAAOtB,EAAMuB,EAAOC,EAASC,GAElC,OADAzB,EAAK0B,iBAAiBH,EAAOC,EAASC,GAC/B,IAAMzB,EAAK2B,oBAAoBJ,EAAOC,EAASC,GAE1D,SAASG,EAAgBrD,GACrB,OAAO,SAAUgD,GAGb,OAFAA,EAAMM,iBAECtD,EAAGuD,KAAKC,KAAMR,IAiB7B,SAASS,EAAKhC,EAAMiC,EAAWC,GACd,MAATA,EACAlC,EAAKmC,gBAAgBF,GAChBjC,EAAKoC,aAAaH,KAAeC,GACtClC,EAAKqC,aAAaJ,EAAWC,GAkDrC,SAASI,EAAUJ,GACf,MAAiB,KAAVA,EAAe,MAAQA,EA6ClC,SAASK,EAASrB,EAAMC,GACpBA,EAAO,GAAKA,EACRD,EAAKsB,YAAcrB,IACnBD,EAAKC,KAAOA,GAEpB,SAASsB,EAAgBC,EAAOR,GAC5BQ,EAAMR,MAAiB,MAATA,EAAgB,GAAKA,EAUvC,SAASS,EAAU3C,EAAM4C,EAAKV,EAAOW,GACjC7C,EAAK8C,MAAMC,YAAYH,EAAKV,EAAOW,EAAY,YAAc,IAEjE,SAASG,EAAcC,EAAQf,GAC3B,IAAK,IAAIvB,EAAI,EAAGA,EAAIsC,EAAOxB,QAAQb,OAAQD,GAAK,EAAG,CAC/C,MAAMuC,EAASD,EAAOxB,QAAQd,GAC9B,GAAIuC,EAAOC,UAAYjB,EAEnB,YADAgB,EAAOE,UAAW,IAW9B,SAASC,EAAaJ,GAClB,MAAMK,EAAkBL,EAAOM,cAAc,aAAeN,EAAOxB,QAAQ,GAC3E,OAAO6B,GAAmBA,EAAgBH,QAqE9C,MAAMK,EACFC,YAAYtD,EAAS,MACjB4B,KAAK9C,EAAIkB,EACT4B,KAAK2B,EAAI3B,KAAK4B,EAAI,KAEtBF,EAAEG,EAAM7D,EAAQI,EAAS,MAChB4B,KAAK2B,IACN3B,KAAK2B,EAAI5C,EAAQf,EAAO8D,UACxB9B,KAAK+B,EAAI/D,EACTgC,KAAKgC,EAAEH,IAEX7B,KAAKpB,EAAER,GAEXsD,EAAEG,GACE7B,KAAK2B,EAAEM,UAAYJ,EACnB7B,KAAK4B,EAAIM,MAAMC,KAAKnC,KAAK2B,EAAES,YAE/BV,EAAEtD,GACE,IAAK,IAAIQ,EAAI,EAAGA,EAAIoB,KAAK4B,EAAE/C,OAAQD,GAAK,EACpCT,EAAO6B,KAAK+B,EAAG/B,KAAK4B,EAAEhD,GAAIR,GAGlCsD,EAAEG,GACE7B,KAAKlB,IACLkB,KAAKgC,EAAEH,GACP7B,KAAKpB,EAAEoB,KAAK9C,GAEhBwE,IACI1B,KAAK4B,EAAE9E,QAAQwB,IAoJvB,IAAI+D,EACJ,SAASC,EAAsBjF,GAC3BgF,EAAoBhF,EAExB,SAASkF,IACL,IAAKF,EACD,MAAM,IAAIG,MAAM,oDACpB,OAAOH,EAKX,SAASI,EAAQjG,GACb+F,IAAwB/E,GAAGkF,SAAShF,KAAKlB,GAK7C,SAASmG,EAAUnG,GACf+F,IAAwB/E,GAAGC,WAAWC,KAAKlB,GAmC/C,MAAMoG,EAAmB,GAEnBC,EAAoB,GACpBC,EAAmB,GACnBC,EAAkB,GAClBC,EAAmBC,QAAQC,UACjC,IAAIC,GAAmB,EAWvB,SAASC,EAAoB5G,GACzBsG,EAAiBpF,KAAKlB,GAK1B,IAAI6G,GAAW,EACf,MAAMC,EAAiB,IAAIC,IAC3B,SAASC,IACL,IAAIH,EAAJ,CAEAA,GAAW,EACX,EAAG,CAGC,IAAK,IAAIzE,EAAI,EAAGA,EAAIgE,EAAiB/D,OAAQD,GAAK,EAAG,CACjD,MAAMvB,EAAYuF,EAAiBhE,GACnC0D,EAAsBjF,GACtBoG,EAAOpG,EAAUG,IAIrB,IAFA8E,EAAsB,MACtBM,EAAiB/D,OAAS,EACnBgE,EAAkBhE,QACrBgE,EAAkBa,KAAlBb,GAIJ,IAAK,IAAIjE,EAAI,EAAGA,EAAIkE,EAAiBjE,OAAQD,GAAK,EAAG,CACjD,MAAMrB,EAAWuF,EAAiBlE,GAC7B0E,EAAeK,IAAIpG,KAEpB+F,EAAeM,IAAIrG,GACnBA,KAGRuF,EAAiBjE,OAAS,QACrB+D,EAAiB/D,QAC1B,KAAOkE,EAAgBlE,QACnBkE,EAAgBW,KAAhBX,GAEJI,GAAmB,EACnBE,GAAW,EACXC,EAAeO,SAEnB,SAASJ,EAAOjG,GACZ,GAAoB,OAAhBA,EAAGsG,SAAmB,CACtBtG,EAAGiG,SACH7G,EAAQY,EAAGuG,eACX,MAAMC,EAAQxG,EAAGwG,MACjBxG,EAAGwG,MAAQ,EAAE,GACbxG,EAAGsG,UAAYtG,EAAGsG,SAASG,EAAEzG,EAAG0G,IAAKF,GACrCxG,EAAG2G,aAAarH,QAAQsG,IAiBhC,MAAMgB,EAAW,IAAIb,IACrB,IAAIc,EAcJ,SAASC,EAAcC,EAAOC,GACtBD,GAASA,EAAM3F,IACfwF,EAASK,OAAOF,GAChBA,EAAM3F,EAAE4F,IAGhB,SAASE,EAAeH,EAAOC,EAAOlG,EAAQf,GAC1C,GAAIgH,GAASA,EAAMI,EAAG,CAClB,GAAIP,EAAST,IAAIY,GACb,OACJH,EAASR,IAAIW,GACbF,EAAOO,EAAElH,MAAK,KACV0G,EAASK,OAAOF,GACZhH,IACIe,GACAiG,EAAMzF,EAAE,GACZvB,QAGRgH,EAAMI,EAAEH,IA4kBhB,SAASK,EAAiBN,GACtBA,GAASA,EAAMK,IAKnB,SAASE,EAAgBzH,EAAWW,EAAQI,EAAQ2G,GAChD,MAAMjB,SAAEA,EAAQpB,SAAEA,EAAQjF,WAAEA,EAAU0G,aAAEA,GAAiB9G,EAAUG,GACnEsG,GAAYA,EAASkB,EAAEhH,EAAQI,GAC1B2G,GAED3B,GAAoB,KAChB,MAAM6B,EAAiBvC,EAASwC,IAAI3I,GAAK4I,OAAOpI,GAC5CU,EACAA,EAAWC,QAAQuH,GAKnBrI,EAAQqI,GAEZ5H,EAAUG,GAAGkF,SAAW,MAGhCyB,EAAarH,QAAQsG,GAEzB,SAASgC,EAAkB/H,EAAWsB,GAClC,MAAMnB,EAAKH,EAAUG,GACD,OAAhBA,EAAGsG,WACHlH,EAAQY,EAAGC,YACXD,EAAGsG,UAAYtG,EAAGsG,SAAShF,EAAEH,GAG7BnB,EAAGC,WAAaD,EAAGsG,SAAW,KAC9BtG,EAAG0G,IAAM,IAGjB,SAASmB,EAAWhI,EAAWuB,IACI,IAA3BvB,EAAUG,GAAGwG,MAAM,KACnBpB,EAAiBlF,KAAKL,GAluBrB8F,IACDA,GAAmB,EACnBH,EAAiBsC,KAAK9B,IAkuBtBnG,EAAUG,GAAGwG,MAAMuB,KAAK,IAE5BlI,EAAUG,GAAGwG,MAAOpF,EAAI,GAAM,IAAO,GAAMA,EAAI,GAEnD,SAAS4G,EAAKnI,EAAWqC,EAAS+F,EAAUC,EAAiBC,EAAWC,EAAO5B,EAAQ,EAAE,IACrF,MAAM6B,EAAmBxD,EACzBC,EAAsBjF,GACtB,MAAMG,EAAKH,EAAUG,GAAK,CACtBsG,SAAU,KACVI,IAAK,KAEL0B,MAAAA,EACAnC,OAAQnH,EACRqJ,UAAAA,EACAG,MAAOrJ,IAEPiG,SAAU,GACVjF,WAAY,GACZsI,cAAe,GACfhC,cAAe,GACfI,aAAc,GACd6B,QAAS,IAAIC,IAAIJ,EAAmBA,EAAiBrI,GAAGwI,QAAU,IAElErI,UAAWlB,IACXuH,MAAAA,EACAkC,YAAY,GAEhB,IAAIC,GAAQ,EAkBZ,GAjBA3I,EAAG0G,IAAMuB,EACHA,EAASpI,EAAWqC,EAAQkG,OAAS,IAAI,CAAChH,EAAGwH,KAAQC,KACnD,MAAMlG,EAAQkG,EAAKxH,OAASwH,EAAK,GAAKD,EAOtC,OANI5I,EAAG0G,KAAOyB,EAAUnI,EAAG0G,IAAItF,GAAIpB,EAAG0G,IAAItF,GAAKuB,MACtC3C,EAAG0I,YAAc1I,EAAGsI,MAAMlH,IAC3BpB,EAAGsI,MAAMlH,GAAGuB,GACZgG,GACAd,EAAWhI,EAAWuB,IAEvBwH,KAET,GACN5I,EAAGiG,SACH0C,GAAQ,EACRvJ,EAAQY,EAAGuG,eAEXvG,EAAGsG,WAAW4B,GAAkBA,EAAgBlI,EAAG0G,KAC/CxE,EAAQ1B,OAAQ,CAChB,GAAI0B,EAAQ4G,QAAS,CACjB,MAAMC,EA9oClB,SAAkBxH,GACd,OAAOmD,MAAMC,KAAKpD,EAAQqD,YA6oCJoE,CAAS9G,EAAQ1B,QAE/BR,EAAGsG,UAAYtG,EAAGsG,SAAS2C,EAAEF,GAC7BA,EAAMzJ,QAAQwB,QAIdd,EAAGsG,UAAYtG,EAAGsG,SAASc,IAE3BlF,EAAQgH,OACRpC,EAAcjH,EAAUG,GAAGsG,UAC/BgB,EAAgBzH,EAAWqC,EAAQ1B,OAAQ0B,EAAQtB,OAAQsB,EAAQqF,eACnEvB,IAEJlB,EAAsBuD,GAkD1B,MAAMc,EACFjF,WACI0D,EAAkBpF,KAAM,GACxBA,KAAK4G,SAAWtK,EAEpBoF,IAAImF,EAAMtJ,GACN,MAAMI,EAAaqC,KAAKxC,GAAGG,UAAUkJ,KAAU7G,KAAKxC,GAAGG,UAAUkJ,GAAQ,IAEzE,OADAlJ,EAAUD,KAAKH,GACR,KACH,MAAMuJ,EAAQnJ,EAAUoJ,QAAQxJ,IACjB,IAAXuJ,GACAnJ,EAAUqJ,OAAOF,EAAO,IAGpCpF,KAAKuF,GA//CT,IAAkBC,EAggDNlH,KAAKmH,QAhgDCD,EAggDkBD,EA//CG,IAA5BvK,OAAO0K,KAAKF,GAAKrI,UAggDhBmB,KAAKxC,GAAG0I,YAAa,EACrBlG,KAAKmH,MAAMF,GACXjH,KAAKxC,GAAG0I,YAAa,ICliDjC,MAAMmB,EAAmB,GAgBzB,SAASC,EAASnH,EAAOoH,EAAQjL,GAC7B,IAAIkL,EACJ,MAAMC,EAAc,GACpB,SAASC,EAAIC,GACT,GAAI1K,EAAekD,EAAOwH,KACtBxH,EAAQwH,EACJH,GAAM,CACN,MAAMI,GAAaP,EAAiBxI,OACpC,IAAK,IAAID,EAAI,EAAGA,EAAI6I,EAAY5I,OAAQD,GAAK,EAAG,CAC5C,MAAMiJ,EAAIJ,EAAY7I,GACtBiJ,EAAE,KACFR,EAAiB3J,KAAKmK,EAAG1H,GAE7B,GAAIyH,EAAW,CACX,IAAK,IAAIhJ,EAAI,EAAGA,EAAIyI,EAAiBxI,OAAQD,GAAK,EAC9CyI,EAAiBzI,GAAG,GAAGyI,EAAiBzI,EAAI,IAEhDyI,EAAiBxI,OAAS,IA0B1C,MAAO,CAAE6I,IAAAA,EAAKjE,OArBd,SAAgBjH,GACZkL,EAAIlL,EAAG2D,KAoBWtC,UAlBtB,SAAmBtB,EAAKuL,EAAaxL,GACjC,MAAMyL,EAAa,CAACxL,EAAKuL,GAMzB,OALAL,EAAY/J,KAAKqK,GACU,IAAvBN,EAAY5I,SACZ2I,EAAOD,EAAMG,IAAQpL,GAEzBC,EAAI4D,GACG,KACH,MAAM2G,EAAQW,EAAYV,QAAQgB,IACnB,IAAXjB,GACAW,EAAYT,OAAOF,EAAO,GAEH,IAAvBW,EAAY5I,SACZ2I,IACAA,EAAO;;;;;;;;;OChDvB,IAAIQ,EAA4B,oBAAdC,WAA4BA,UAAUC,UAAUC,cAAcpB,QAAQ,WAAa,EAErG,SAASqB,EAASC,EAAQ7I,EAAO8I,GAC3BD,EAAO1I,iBACT0I,EAAO1I,iBAAiBH,EAAO8I,GAAQ,GAC9BD,EAAOE,aAChBF,EAAOE,YAAY,KAAKC,OAAOhJ,IAAQ,WACrC8I,EAAOG,OAAOjJ,UAMpB,SAASkJ,GAAQC,EAAU9H,GAGzB,IAFA,IAAI+H,EAAO/H,EAAIgI,MAAM,EAAGhI,EAAIhC,OAAS,GAE5BD,EAAI,EAAGA,EAAIgK,EAAK/J,OAAQD,IAC/BgK,EAAKhK,GAAK+J,EAASC,EAAKhK,GAAGuJ,eAG7B,OAAOS,EAIT,SAASE,GAAQjI,GACI,iBAARA,IAAkBA,EAAM,IAOnC,IAJA,IAAIuG,GAFJvG,EAAMA,EAAIkI,QAAQ,MAAO,KAEVC,MAAM,KAEjBlC,EAAQM,EAAK6B,YAAY,IAEtBnC,GAAS,GACdM,EAAKN,EAAQ,IAAM,IACnBM,EAAKJ,OAAOF,EAAO,GACnBA,EAAQM,EAAK6B,YAAY,IAG3B,OAAO7B,EAuGT,IAvFA,IAAI8B,GAAU,CACZC,UAAW,EACXC,IAAK,EACLvF,MAAO,GACPwF,MAAO,GACPC,OAAQ,GACRC,IAAK,GACLC,OAAQ,GACRlK,MAAO,GACPmK,KAAM,GACNC,GAAI,GACJC,MAAO,GACPC,KAAM,GACNC,IAAK,GACLpF,OAAQ,GACRqF,IAAK,GACL3L,OAAQ,GACR4L,KAAM,GACNC,IAAK,GACLC,OAAQ,GACRC,SAAU,GACVC,SAAU,GACVC,MAAO,GACPC,MAAO,GACPC,MAAO,GACPC,MAAO,GACPC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,MAAO,IACPC,aAAc,IACdC,QAAS,IACTC,UAAW,IACXC,aAAc,IACdC,YAAa,IACbC,WAAY,IACZC,IAAK,GACLC,IAAK,IACLC,IAAK,IACLC,IAAK,IACLC,IAAK,IACLC,IAAKzD,EAAO,IAAM,IAClB0D,IAAK1D,EAAO,GAAK,IACjB2D,IAAK3D,EAAO,GAAK,IACjB4D,IAAM,IACNC,IAAK,IACLC,IAAK,IACLC,KAAM,KAGJC,GAAY,CAEdC,IAAK,GACLC,MAAO,GAEPC,IAAK,GACLC,IAAK,GACLjL,OAAQ,GAERkL,IAAK,GACLC,KAAM,GACNC,QAAS,GAETC,IAAK,GACLC,IAAK,GACLC,QAAS,IAEPC,GAAc,CAChBC,GAAI,WACJC,GAAI,SACJC,GAAI,UACJC,GAAI,UACJC,SAAU,GACVC,QAAS,GACTC,OAAQ,GACRC,QAAS,IAEPC,GAAQ,CACVR,IAAI,EACJC,IAAI,EACJC,IAAI,EACJC,IAAI,GAEFM,GAAY,GAEPC,GAAI,EAAGA,GAAI,GAAIA,KACtBpE,GAAQ,IAAIV,OAAO8E,KAAM,IAAMA,GAGjC,IAAIC,GAAY,GAEZC,GAAS,MAETC,GAAsB,GAGtBC,GAAO,SAAcC,GACvB,OAAOzE,GAAQyE,EAAExF,gBAAkB6D,GAAU2B,EAAExF,gBAAkBwF,EAAEC,cAAcC,WAAW,IAI9F,SAASC,GAASC,GAChBP,GAASO,GAAS,MAIpB,SAASC,KACP,OAAOR,IAAU,MAuHnB,IAAIS,GAAa,SAAoBC,GACnC,IAAIrN,EAAMqN,EAAKrN,IACXkN,EAAQG,EAAKH,MACbzF,EAAS4F,EAAK5F,OACd6F,EAAgBD,EAAKE,SACrBA,OAA6B,IAAlBD,EAA2B,IAAMA,EAC7BrF,GAAQjI,GACd/D,SAAQ,SAAUuR,GAC7B,IAAIC,EAAaD,EAAUrF,MAAMoF,GAC7BG,EAAMD,EAAWzP,OACjB2P,EAAUF,EAAWC,EAAM,GAC3BE,EAAsB,MAAZD,EAAkB,IAAMd,GAAKc,GAC3C,GAAKnB,GAAUoB,GAAf,CAEKV,IAAOA,EAAQC,MACpB,IAAIpF,EAAO2F,EAAM,EAAI7F,GAAQsD,GAAWsC,GAAc,GACtDjB,GAAUoB,GAAWpB,GAAUoB,GAASvJ,KAAI,SAAUwJ,GAIpD,QAFuBpG,GAASoG,EAAOpG,SAAWA,IAE1BoG,EAAOX,QAAUA,GApQ/C,SAAsBY,EAAIC,GAKxB,IAJA,IAAIC,EAAOF,EAAG9P,QAAU+P,EAAG/P,OAAS8P,EAAKC,EACrCE,EAAOH,EAAG9P,QAAU+P,EAAG/P,OAAS+P,EAAKD,EACrCI,GAAU,EAELnQ,EAAI,EAAGA,EAAIiQ,EAAKhQ,OAAQD,KACA,IAA3BkQ,EAAK/H,QAAQ8H,EAAKjQ,MAAYmQ,GAAU,GAG9C,OAAOA,EA2P+CC,CAAaN,EAAO9F,KAAMA,GACnE,GAGF8F,UAMb,SAASO,GAAazP,EAAOC,EAASsO,GACpC,IAAImB,EAEJ,GAAIzP,EAAQsO,QAAUA,GAA2B,QAAlBtO,EAAQsO,MAAiB,CAItD,IAAK,IAAIoB,KAFTD,EAAiBzP,EAAQmJ,KAAK/J,OAAS,EAEzBuO,GACR1Q,OAAO0S,UAAUC,eAAetP,KAAKqN,GAAO+B,MACzC/B,GAAM+B,IAAM1P,EAAQmJ,KAAK7B,SAASoI,IAAM,GAAK/B,GAAM+B,KAAoC,IAA9B1P,EAAQmJ,KAAK7B,SAASoI,MAClFD,GAAiB,IAMK,IAAxBzP,EAAQmJ,KAAK/J,QAAiBuO,GAAM,KAAQA,GAAM,KAAQA,GAAM,KAAQA,GAAM,OAAO8B,GAAuC,MAArBzP,EAAQ6P,WAC1E,IAAnC7P,EAAQ6I,OAAO9I,EAAOC,KACpBD,EAAMM,eAAgBN,EAAMM,iBAAsBN,EAAM+P,aAAc,EACtE/P,EAAMgQ,iBAAiBhQ,EAAMgQ,kBAC7BhQ,EAAMiQ,eAAcjQ,EAAMiQ,cAAe,KAOrD,SAASC,GAASlQ,GAChB,IAAImQ,EAAWtC,GAAU,KACrBxM,EAAMrB,EAAMiP,SAAWjP,EAAMoQ,OAASpQ,EAAMqQ,SAEhD,GAAKC,GAAQ3K,OAAOpF,KAAKC,KAAMR,GAA/B,CAsCA,GAnCY,KAARqB,GAAsB,MAARA,IAAaA,EAAM,KAQL,IAA5B0M,GAAUxG,QAAQlG,IAAuB,MAARA,GAAa0M,GAAU7P,KAAKmD,GAMjE,CAAC,UAAW,SAAU,WAAY,WAAW/D,SAAQ,SAAUiT,GAC7D,IAAIC,EAASrD,GAAYoD,GAErBvQ,EAAMuQ,KAA2C,IAA/BxC,GAAUxG,QAAQiJ,GACtCzC,GAAU7P,KAAKsS,IACLxQ,EAAMuQ,IAAYxC,GAAUxG,QAAQiJ,IAAW,EACzDzC,GAAUvG,OAAOuG,GAAUxG,QAAQiJ,GAAS,GACvB,YAAZD,GAAyBvQ,EAAMuQ,IAAiC,IAArBxC,GAAU1O,SAKxDW,EAAMyN,SAAWzN,EAAMwN,UAAYxN,EAAM0N,SAC7CK,GAAYA,GAAU1E,MAAM0E,GAAUxG,QAAQiJ,SAQhDnP,KAAOuM,GAAO,CAGhB,IAAK,IAAIE,KAFTF,GAAMvM,IAAO,EAECmL,GACRA,GAAUsB,KAAOzM,IAAKiP,GAAQxC,IAAK,GAGzC,IAAKqC,EAAU,OAIjB,IAAK,IAAIhO,KAAKyL,GACR1Q,OAAO0S,UAAUC,eAAetP,KAAKqN,GAAOzL,KAC9CyL,GAAMzL,GAAKnC,EAAMmN,GAAYhL,KAW7BnC,EAAMyQ,oBAAsBzQ,EAAM0N,QAAW1N,EAAMyN,UAAYzN,EAAMyQ,iBAAiB,eACzD,IAA3B1C,GAAUxG,QAAQ,KACpBwG,GAAU7P,KAAK,KAGc,IAA3B6P,GAAUxG,QAAQ,KACpBwG,GAAU7P,KAAK,IAGjB0P,GAAM,KAAM,EACZA,GAAM,KAAM,GAId,IAAIW,EAAQC,KAEZ,GAAI2B,EACF,IAAK,IAAI/Q,EAAI,EAAGA,EAAI+Q,EAAS9Q,OAAQD,IAC/B+Q,EAAS/Q,GAAGmP,QAAUA,IAAyB,YAAfvO,EAAMqH,MAAsB8I,EAAS/Q,GAAGsR,SAA0B,UAAf1Q,EAAMqH,MAAoB8I,EAAS/Q,GAAGuR,QAC3HlB,GAAazP,EAAOmQ,EAAS/Q,GAAImP,GAMvC,GAAMlN,KAAOwM,GAEb,IAAK,IAAI+C,EAAK,EAAGA,EAAK/C,GAAUxM,GAAKhC,OAAQuR,IAC3C,IAAmB,YAAf5Q,EAAMqH,MAAsBwG,GAAUxM,GAAKuP,GAAIF,SAA0B,UAAf1Q,EAAMqH,MAAoBwG,GAAUxM,GAAKuP,GAAID,QACrG9C,GAAUxM,GAAKuP,GAAIvP,IAAK,CAM1B,IALA,IAAI6N,EAASrB,GAAUxM,GAAKuP,GACxBhC,EAAWM,EAAON,SAClBiC,EAAc3B,EAAO7N,IAAImI,MAAMoF,GAC/BkC,EAAmB,GAEdpT,EAAI,EAAGA,EAAImT,EAAYxR,OAAQ3B,IACtCoT,EAAiB5S,KAAKgQ,GAAK2C,EAAYnT,KAGrCoT,EAAiBC,OAAOC,KAAK,MAAQjD,GAAUgD,OAAOC,KAAK,KAE7DvB,GAAazP,EAAOkP,EAAQX,KAYtC,SAAS+B,GAAQjP,EAAKM,EAAQmH,GAC5BiF,GAAY,GACZ,IAAInG,EAAO0B,GAAQjI,GAEf+H,EAAO,GACPmF,EAAQ,MAERhP,EAAUE,SAEVL,EAAI,EACJuR,GAAQ,EACRD,GAAU,EACV9B,EAAW,IAoBf,SAlBeqC,IAAXnI,GAA0C,mBAAXnH,IACjCmH,EAASnH,GAGoC,oBAA3CzE,OAAO0S,UAAUsB,SAAS3Q,KAAKoB,KAC7BA,EAAO4M,QAAOA,EAAQ5M,EAAO4M,OAE7B5M,EAAOpC,UAASA,EAAUoC,EAAOpC,SAEjCoC,EAAOgP,QAAOA,EAAQhP,EAAOgP,YAEVM,IAAnBtP,EAAO+O,UAAuBA,EAAU/O,EAAO+O,SAEpB,iBAApB/O,EAAOiN,WAAuBA,EAAWjN,EAAOiN,WAGvC,iBAAXjN,IAAqB4M,EAAQ5M,GAEjCvC,EAAIwI,EAAKvI,OAAQD,IAGtBgK,EAAO,IAFP/H,EAAMuG,EAAKxI,GAAGoK,MAAMoF,IAIZvP,OAAS,IAAG+J,EAAOF,GAAQsD,GAAWnL,KAG9CA,EAAc,OADdA,EAAMA,EAAIA,EAAIhC,OAAS,IACH,IAAM6O,GAAK7M,MAGlBwM,KAAYA,GAAUxM,GAAO,IAE1CwM,GAAUxM,GAAKnD,KAAK,CAClByS,MAAOA,EACPD,QAASA,EACTnC,MAAOA,EACPnF,KAAMA,EACN0G,SAAUlI,EAAKxI,GACf0J,OAAQA,EACRzH,IAAKuG,EAAKxI,GACVwP,SAAUA,SAKS,IAAZrP,IA9Db,SAAuBA,GACrB,OAAO0O,GAAoB1G,QAAQhI,IAAY,EA6DR4R,CAAc5R,IAAY0J,SAC/DgF,GAAoB/P,KAAKqB,GACzBqJ,EAASrJ,EAAS,WAAW,SAAU4C,GACrC+N,GAAS/N,MAEXyG,EAASK,OAAQ,SAAS,WACxB8E,GAAY,MAEdnF,EAASrJ,EAAS,SAAS,SAAU4C,GACnC+N,GAAS/N,GArTf,SAAuBnC,GACrB,IAAIqB,EAAMrB,EAAMiP,SAAWjP,EAAMoQ,OAASpQ,EAAMqQ,SAE5CjR,EAAI2O,GAAUxG,QAAQlG,GAe1B,GAZIjC,GAAK,GACP2O,GAAUvG,OAAOpI,EAAG,GAIlBY,EAAMqB,KAAmC,SAA5BrB,EAAMqB,IAAIsH,eACzBoF,GAAUvG,OAAO,EAAGuG,GAAU1O,QAIpB,KAARgC,GAAsB,MAARA,IAAaA,EAAM,IAEjCA,KAAOuM,GAGT,IAAK,IAAIE,KAFTF,GAAMvM,IAAO,EAECmL,GACRA,GAAUsB,KAAOzM,IAAKiP,GAAQxC,IAAK,GAgSvCsD,CAAcjP,OAKpB,IC7hB4CI,GCAAJ,GF6hBxCkP,GAAO,CACT/C,SAAUA,GACVE,SAAUA,GACV8C,YAnVF,SAAqB/C,EAAOgD,GAC1B,IAAIC,EACApS,EAIJ,IAAK,IAAIiC,KAFJkN,IAAOA,EAAQC,MAEJX,GACd,GAAI3Q,OAAO0S,UAAUC,eAAetP,KAAKsN,GAAWxM,GAGlD,IAFAmQ,EAAW3D,GAAUxM,GAEhBjC,EAAI,EAAGA,EAAIoS,EAASnS,QACnBmS,EAASpS,GAAGmP,QAAUA,EAAOiD,EAAShK,OAAOpI,EAAG,GAAQA,IAM9DoP,OAAeD,GAAOD,GAASiD,GAAY,QAmU/CE,mBAhXF,WACE,OAAO1D,GAAU1E,MAAM,IAgXvBqI,UA9VF,SAAmBzC,GAKjB,MAJuB,iBAAZA,IACTA,EAAUf,GAAKe,KAGsB,IAAhClB,GAAUxG,QAAQ0H,IA0VzBtJ,OA5WF,SAAgB3F,GACd,IAAIxB,EAASwB,EAAMxB,QAAUwB,EAAM2R,WAC/BC,EAAUpT,EAAOoT,QACjBC,GAAO,EAMX,OAJIrT,EAAOsT,oBAAkC,UAAZF,GAAmC,aAAZA,GAAsC,WAAZA,GAA0BpT,EAAOuT,YACjHF,GAAO,GAGFA,GAoWPG,OAvSF,SAAgBC,GAEd,GAAKA,GAIE,GAAIvP,MAAMwP,QAAQD,GAEvBA,EAAS3U,SAAQ,SAAU6U,GACrBA,EAAK9Q,KAAKoN,GAAW0D,WAEtB,GAAwB,iBAAbF,EAEZA,EAAS5Q,KAAKoN,GAAWwD,QACxB,GAAwB,iBAAbA,EAAuB,CACvC,IAAK,IAAIG,EAAOC,UAAUhT,OAAQiT,EAAO,IAAI5P,MAAM0P,EAAO,EAAIA,EAAO,EAAI,GAAIG,EAAO,EAAGA,EAAOH,EAAMG,IAClGD,EAAKC,EAAO,GAAKF,UAAUE,GAK7B,IAAIhE,EAAQ+D,EAAK,GACbxJ,EAASwJ,EAAK,GAEG,mBAAV/D,IACTzF,EAASyF,EACTA,EAAQ,IAGVE,GAAW,CACTpN,IAAK4Q,EACL1D,MAAOA,EACPzF,OAAQA,EACR8F,SAAU,YA9BZ1R,OAAO0K,KAAKiG,IAAWvQ,SAAQ,SAAU+D,GACvC,cAAcwM,GAAUxM,QAsS9B,IAAK,IAAI3D,MAAK2T,GACRnU,OAAO0S,UAAUC,eAAetP,KAAK8Q,GAAM3T,MAC7C4S,GAAQ5S,IAAK2T,GAAK3T,KAItB,GAAsB,oBAAXuL,OAAwB,CACjC,IAAIuJ,GAAWvJ,OAAOqH,QAEtBA,GAAQmC,WAAa,SAAUC,GAK7B,OAJIA,GAAQzJ,OAAOqH,UAAYA,KAC7BrH,OAAOqH,QAAUkC,IAGZlC,IAGTrH,OAAOqH,QAAUA,GGxjBnB,SAASnO,GAAEA,EAAEI,GAAE,GAAI,MAAMH,EAAE,WAAW,MAAMD,EAAE,IAAIwQ,UAAU,GAAG1J,OAAO2J,OAAOC,gBAAgB1Q,GAAG,MAAMI,EAAE,IAAIuQ,WAAWC,KAAKC,IAAI,GAAGD,KAAKE,IAAI9Q,EAAE,MAAM,OAAO8G,OAAO2J,OAAOC,gBAAgBtQ,GAAGA,EAAEyO,KAAK,IAAxK,GAA+K,OAAO9T,OAAOgW,eAAejK,OAAO7G,EAAE,CAACzB,MAAMwS,IAAI5Q,GAAG6Q,QAAQC,eAAepK,OAAO7G,GAAGD,IAAIgR,IAAIrL,UAAS,EAAGwL,cAAa,IAAKlR,EAAEmR,eAAehR,GAAEA,EAAEH,EAAE,IAAI,OAAO,IAAIqB,UAAU0P,EAAEhO,KAAK,MAAMzH,EAAEyE,IAAGA,IAAIgR,EAAEhR,GAAGiR,QAAQC,eAAepK,OAAO7D,MAAK,GAAIA,EAAEjD,IAAGA,IAAIgD,EAAEhD,GAAGiR,QAAQC,eAAepK,OAAOvL,MAAK,GAAIuL,OAAOuK,IAAIC,OAAOlR,EAAE,CAACmR,YAAYC,qBAAqB5V,SAASL,EAAEkW,MAAMxO,KAAKhD,OAAO,SAASA,GAAED,GAAG,OAAOsG,UAAUC,UAAUmL,SAAS,WAAW,iBAAiB1R,IAAI,WAAWA,ICApnBoR,eAAenU,GAAEA,GAAG,OAAO+T,GAAE,QAAQ/T,GDAylBlC,OAAO4W,OAAO,CAACC,UAAU,KAAKC,kBAAkB7R,GAAE8R,OAAO1R,GAAE2R,eAAe9R,KEAhqB,MAAMiG,GAAEnG,cAAc1B,KAAK2T,eAAejX,OAAOC,OAAO,MAAM+E,iBAAiBK,EAAEJ,GAAGI,KAAK/B,KAAK2T,eAAe3T,KAAK2T,eAAe5R,GAAGrE,KAAKiE,GAAG3B,KAAK2T,eAAe5R,GAAG,CAACJ,GAAGD,MAAMK,EAAEJ,GAAG,GAAGI,KAAK/B,KAAK2T,eAAe,CAAC,MAAM9L,EAAE7H,KAAK2T,eAAe5R,GAAG,IAAI,MAAMA,KAAK8F,EAAE9F,EAAEJ,IAAID,GAAGK,EAAEJ,GAAG,OAAO3B,KAAKL,iBAAiBoC,EAAEJ,GAAG3B,MAAM,MAAM2S,GAAEjR,YAAYK,GAAG/B,KAAK4T,IAAI7R,EAAEL,YAAYC,GAAG,OAAOI,GAAE,CAAC8R,cAAc,QAAQC,QAAQ,CAACrH,IAAI,aAAamH,IAAI5T,KAAK4T,IAAIG,OAAOpS,KAAKD,aAAa,OAAOK,GAAE,CAAC8R,cAAc,QAAQC,QAAQ,CAACrH,IAAI,YAAYmH,IAAI5T,KAAK4T,QAAQ,MAAMhV,WAAUiJ,GAAEnG,YAAYK,EAAEJ,EAAE,GAAGgR,GAAGqB,QAAQhU,KAAKiU,OAAO,IAAIpM,GAAE7H,KAAKkU,OAAO,IAAIrM,GAAE7H,KAAKmU,QAAQpS,EAAE/B,KAAK8R,KAAK,iBAAiBnQ,EAAE,CAACA,GAAGA,EAAE3B,KAAKN,QAAQiT,GAAG,GAAGjR,eAAeK,EAAEJ,EAAE,GAAGkG,GAAG,MAAM8K,EAAE,IAAI/T,GAAEmD,EAAEJ,EAAEkG,GAAG,OAAO8K,EAAEjT,QAAQ0U,SAAQ,EAAGzB,EAAEjR,cAAc,OAAOqR,eAAelL,EAAE8K,EAAE/T,EAAEgD,GAAG,MAAM,iBAAiBhD,GAAGlC,OAAO4W,OAAO1U,GAAGmD,GAAE,CAAC8R,cAAc,QAAQC,QAAQ,CAACrH,IAAI,UAAU0H,QAAQxB,EAAEb,KAAK,iBAAiBlT,EAAE,CAACA,GAAGA,EAAEc,QAAQkC,EAAEyS,UAAU1S,GAAEkG,MAAjLkL,EAAyLhR,IAAI,OAAOA,EAAEvC,OAAO,IAAI,QAAQQ,KAAKsU,MAAM,QAAQvS,EAAEwS,SAAS,MAAM,IAAI,aAAavU,KAAKsU,MAAM,QAAQvS,EAAEwS,SAAS,MAAM,IAAI,SAASvU,KAAKiU,OAAOK,MAAM,OAAOvS,EAAEwS,SAAS,MAAM,IAAI,SAASvU,KAAKkU,OAAOI,MAAM,OAAOvS,EAAEwS,YAAYvU,KAAKmU,QAAQnU,KAAK8R,KAAK9R,KAAKN,SAAS4F,MAAMvD,GAAG,IAAI4Q,GAAE5Q,KAAKL,gBAAgB,OAAO,IAAIuB,UAAUlB,EAAEJ,KAAK3B,KAAKwU,GAAG,QAAQ7S,GAAG,MAAMkG,EAAE,GAAG8K,EAAE,GAAG3S,KAAKiU,OAAOO,GAAG,QAAQzS,IAAI8F,EAAEnK,KAAKqE,MAAM/B,KAAKkU,OAAOM,GAAG,QAAQzS,IAAI4Q,EAAEjV,KAAKqE,MAAM/B,KAAKwU,GAAG,SAAS7S,IAAII,EAAE,CAAC2L,KAAK/L,EAAE+L,KAAK+G,OAAO9S,EAAE8S,OAAOR,OAAOpM,EAAE2I,KAAK,MAAM0D,OAAOvB,EAAEnC,KAAK,WAAWxQ,KAAK0U,QAAQC,MAAMhT,OAAOoR,eAAenR,GAAED,EAAEkG,GAAG,OAAO9F,GAAE,CAAC8R,cAAc,QAAQC,QAAQ,CAACrH,IAAI,OAAOmI,KAAKjT,EAAEkT,KAAKhN,KCAxnDkL,eAAeJ,KAAI,OAAOhR,GAAE,CAACkS,cAAc,MAAMC,QAAQ,CAACrH,IAAI,mBAAmBsG,eAAe7V,KAAI,OAAOyE,GAAE,CAACkS,cAAc,MAAMC,QAAQ,CAACrH,IAAI,gBAAgBsG,eAAehR,KAAI,OAAOJ,GAAE,CAACkS,cAAc,MAAMC,QAAQ,CAACrH,IAAI,qBCA7NsG,eAAeJ,GAAEA,EAAE,GAAG,OAAOhR,GAAE,CAACkS,cAAc,UAAUC,QAAQ,CAACrH,IAAI,OAAOqI,SAASnC,KAAKI,eAAelL,KAAI,OAAOlG,GAAE,CAACkS,cAAc,UAAUC,QAAQ,CAACrH,IAAI,yaC2B3KvI,wDACEA,mDACLA,2VAEWA,kBACAA,gCALRA,eACEA,eACLA,+JAzBhB6Q,EAAU,EACVC,EAAe,EACfC,EAAU,iBAEdC,KAAU5P,MAAK1D,QAAOqT,EAAUrT,MAChCuT,KAAa7P,MAAK8P,QAAOL,EAAUK,MACnCC,KAAkB/P,MAAK8P,QAAOJ,EAAeI,oCAGrCE,6BAIAC,OHjBiqD7Y,OAAO4W,OAAO,CAACC,UAAU,KAAKiC,QAAQ5W,GAAE6W,MAAM9C,GAAE+C,KAAK9T,KCAh8ClF,OAAO4W,OAAO,CAACC,UAAU,KAAK2B,QAAQhY,GAAEiY,WAAWxC,GAAE0C,gBAAgBtT,KCA7IrF,OAAO4W,OAAO,CAACC,UAAU,KAAK+B,KAAK3C,GAAE4C,SAAS1N,qEEA9NkL,eAAehR,KAAI,OAAOJ,GAAE,CAACkS,cAAc,MAAMC,QAAQ,CAACrH,IAAI,6nBCoBlDvI,kFAjBvCyR,yEAGTC,KAAatQ,KAAKqQ,GAAWhB,MAAMgB,ODNqFjZ,OAAO4W,OAAO,CAACC,UAAU,KAAKqC,WAAW7T,gFEArFgR,eAAehR,GAAEH,EAAEG,EAAE7E,SAASyE,GAAE,CAACkS,cAAc,QAAQC,QAAQ,CAACrH,IAAI,OAAOjN,MAAMoC,EAAEiU,YAAY9T,EAAEwS,QAAQrX,KAAK6V,eAAe7V,GAAE0E,GAAG,OAAOD,GAAE,CAACkS,cAAc,QAAQC,QAAQ,CAACrH,IAAI,WAAWqJ,QAAQlU,KAAKmR,eAAelL,GAAE9F,EAAE8F,GAAG,OAAOlG,GAAE,CAACkS,cAAc,QAAQC,QAAQ,CAACrH,IAAI,SAASjN,MAAMuC,EAAEtC,QAAQmC,GAAEiG,MAAMvC,MAAM3D,GAAGoR,SAAS7V,GAAEyE,KAAKoR,eAAenU,GAAE+C,EAAEC,GAAG,OAAOiG,GAAElG,GAAGA,IAAIC,EAAED,GAAGzE,GAAEyE,EAAEoU,IAAIpB,mBAAmB5B,eAAeJ,GAAEhR,EAAEC,GAAG,OAAOG,GAAEJ,OAAE,EAAOC,0ZC0CtdsC,kBACIA,kBAGFA,0EAxCxC8R,aADOL,YAGXlT,aACEuT,QAAiBzW,GAAO,aAAcoW,MAExChT,QACMqT,GACFA,oEAKFvC,GAAO,iBACLjU,MAAO,cACP+U,QAAS,wEAKXd,GAAO,mBACLwC,SAAU,qBACVC,MACEH,GAAI,EACJ/W,KAAM,UAGPsG,KAAKqQ,GACLhB,MAAMgB,eAITQ,GAAK,WAAY,kCDrCsfzZ,OAAO4W,OAAO,CAACC,UAAU,KAAKhU,OAAOsI,GAAEuO,KAAKxX,GAAEuX,KAAKxD,gFEAthBI,eAAepO,GAAEA,EAAE,IAAI,MAAM,iBAAiBA,GAAGjI,OAAO4W,OAAO3O,GAAGhD,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,aAAa/M,QAAQiF,KAAKoO,eAAehR,GAAE4C,EAAE,IAAI,MAAM,iBAAiBA,GAAGjI,OAAO4W,OAAO3O,GAAGhD,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,aAAa/M,QAAQiF,KZArJoO,eAAe7V,GAAE6E,EAAE4Q,EAAE,IAAI,OAAOhR,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,iBAAiBmI,KAAK7S,EAAErC,QAAQiT,KAAgrB,SAAS/Q,GAAED,GAAG,MAAMI,EAAE,SAASJ,GAAG,GAAGA,EAAE9C,OAAO,MAAM,OAAOwX,OAAOC,aAAaC,MAAM,KAAKrU,MAAMC,KAAKR,IAAI,IAAII,EAAE,GAAG,MAAM4Q,EAAEhR,EAAE9C,OAAO,IAAI,IAAI3B,EAAE,EAAEA,EAAEyV,EAAEzV,IAAI,CAAC,MAAMyV,EAAEhR,EAAE6U,SAAS,MAAMtZ,EAAE,OAAOA,EAAE,IAAI6E,GAAGsU,OAAOC,aAAaC,MAAM,KAAKrU,MAAMC,KAAKwQ,IAAI,OAAO5Q,EAAlO,CAAqO,IAAIuQ,WAAW3Q,IAAI,OAAO8U,KAAK1U,GAAiNgR,eAAelL,GAAE9F,EAAE4Q,EAAE,IAAI,OAAOhR,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,UAAUmI,KAAK7S,EAAErC,QAAQiT,4zBa0F99CzO,wBAKAA,qCAG8CA,kDAICA,6IAIXA,kBAGAA,sCAnBpCA,UAAAA,qBAKAA,UAAAA,sBAG8CA,sBAICA,yEAlGlDyR,KACPe,EAAc,KACdvR,EAAS,KACTwR,GAAW,EACXC,GAAY,8EAedlB,IACEgB,YAAAA,EACAG,QAAS1R,IAGDnG,KAAM,gBACN8X,WAAY3R,EAAO6D,MAAM,KAAK9D,KAAK6R,GAAMA,EAAEC,cAInDL,SAAAA,EACAC,UAAAA,IAECtR,eAAe2R,MACV/U,MAAMwP,QAAQuF,GAChBtB,EAAUsB,YAENC,EAAaD,EACbE,EAASD,EAAWE,MAAM,cAC9BC,GAAeH,GACZ5R,eAAegS,OAjCGvD,EAAQxW,EAC/Bga,EAGAC,EA8BUL,IAEAD,EAAW7D,SAAS,SACpB6D,EAAW7D,SAAS,UArCPU,MAwCPzB,WAAWgF,GAxCI/Z,WAyCTka,GAER9B,EAAU,mCAD2B8B,EACN,aA1C7CF,MAAWG,MAAM3D,IACnBlN,KAAM,8BAEJ2Q,MAAaG,YACVC,gBAAmBC,OACpBC,EAAUD,EAAI7Z,OAAO+Z,OACzBxa,EAASua,EAAQE,OAAOF,EAAQ/Q,QAAQ,KAAO,KAEjDyQ,EAAOS,cAAcV,IAyCT5B,EAAUsB,MAGbtC,MAAMgB,EAAUsB,QAGtBtC,MAAMgB,eAITuC,IACExB,YAAAA,EACAG,QAAS1R,IAGDnG,KAAM,gBACN8X,WAAY3R,EAAO6D,MAAM,KAAK9D,KAAK6R,GAAMA,EAAEC,gBAKlD1R,KAAKqQ,GACLhB,MAAMgB,iBAQGe,gCAKAvR,gCAG8CwR,kCAICC,wBDtGqPla,OAAO4W,OAAO,CAACC,UAAU,KAAKmC,KAAK/Q,GAAEuT,KAAKnW,KZAoG,SAASJ,GAAGA,EAAEA,EAAEwW,MAAM,GAAG,QAAQxW,EAAEA,EAAEyW,MAAM,GAAG,QAAQzW,EAAEA,EAAE0W,OAAO,GAAG,SAAS1W,EAAEA,EAAE2W,KAAK,GAAG,OAAO3W,EAAEA,EAAE4W,UAAU,GAAG,YAAY5W,EAAEA,EAAE6W,QAAQ,GAAG,UAAU7W,EAAEA,EAAE8W,SAAS,GAAG,WAAW9W,EAAEA,EAAE+W,SAAS,GAAG,WAAW/W,EAAEA,EAAEgX,WAAW,GAAG,aAAahX,EAAEA,EAAEiX,KAAK,IAAI,OAAOjX,EAAEA,EAAEkX,KAAK,IAAI,OAAOlX,EAAEA,EAAEmX,QAAQ,IAAI,UAAUnX,EAAEA,EAAEoX,OAAO,IAAI,SAASpX,EAAEA,EAAEqX,QAAQ,IAAI,UAAUrX,EAAEA,EAAEsX,SAAS,IAAI,WAAWtX,EAAEA,EAAEuX,MAAM,IAAI,QAAQvX,EAAEA,EAAEwX,SAAS,IAAI,WAAWxX,EAAEA,EAAEyX,IAAI,IAAI,MAAMzX,EAAEA,EAAE0X,QAAQ,IAAI,UAA/c,CAA0dtX,KAAIA,GAAE,KAAwmCrF,OAAO4W,OAAO,CAACC,UAAU,KAAK+F,oBAAoB,OAAOvX,IAAGwX,UAAU,OAAOxX,IAAGyX,aAA5iEzG,eAAiBhR,EAAE4Q,EAAE,IAAI,OAAOhR,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,eAAemI,KAAK7S,EAAErC,QAAQiT,MAA09D0E,eAAena,GAAEuc,UAA93D1G,eAAiBhR,EAAE4Q,EAAE,IAAI,MAAM,iBAAiBA,GAAGjW,OAAO4W,OAAOX,GAAG,iBAAiB5Q,GAAGrF,OAAO4W,OAAOvR,GAAGJ,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,YAAYmI,KAAK7S,EAAE6S,KAAK8E,SAAS3X,EAAE2X,SAASha,QAAQiT,MAA0sDgH,gBAAl8B5G,eAAiBhR,EAAE4Q,EAAE,IAAI,MAAM,iBAAiBA,GAAGjW,OAAO4W,OAAOX,GAAG,iBAAiB5Q,GAAGrF,OAAO4W,OAAOvR,GAAGJ,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,kBAAkBmI,KAAK7S,EAAE6S,KAAK8E,SAAS9X,GAAEG,EAAE2X,UAAUha,QAAQiT,MAA2wBiH,QAAQ/R,GAAEgS,UAA/qB9G,eAAiBhR,EAAE4Q,EAAE,IAAI,OAAOhR,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,YAAYmI,KAAK7S,EAAErC,QAAQiT,MAA6lBmH,UAAxlB/G,eAAiBhR,EAAE4Q,EAAE,IAAI,OAAOhR,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,YAAYmI,KAAK7S,EAAErC,QAAQiT,MAAsgBoH,SAAjgBhH,eAAiBhR,EAAE4Q,EAAEzV,EAAE,IAAI,OAAOyE,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,WAAWuN,OAAOjY,EAAEkY,YAAYtH,EAAEjT,QAAQxC,MAA6Zgd,WAAxZnH,eAAiBhR,EAAE4Q,EAAE,IAAI,OAAOhR,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,aAAamI,KAAK7S,EAAErC,QAAQiT,MAAsUwH,WAAjUpH,eAAiBhR,EAAE4Q,EAAEzV,EAAE,IAAI,OAAOyE,GAAE,CAACkS,cAAc,KAAKC,QAAQ,CAACrH,IAAI,aAAa2N,QAAQrY,EAAEsY,QAAQ1H,EAAEjT,QAAQxC,oVcqFj+DgH,KAAI,gDAAbA,KAAI,gHADdA,0BAALrF,wlBAOUqF,6FAGiCA,qBAbjBA,4CAGrBA,aAALrF,+HAAAA,sBAOUqF,UAAAA,mEAlFLoW,YACWrb,SAASsb,eAAe,OACzBpa,MAAQqa,SAASC,IAAIta,OAAS,4BAJ7Cua,aAHO/E,KAEPuB,EAAa,SAoBXyD,EAAaje,OAAO0K,KAAKmS,IAC5BpU,QAAQtE,GAAQ+Z,MAAMJ,SAAS3Z,MAC/BqE,KAAKuV,IAASA,EAAKlB,GAAIkB,sFAGlBtD,EAASD,EAAWE,MAAM,cAC1ByD,GACJJ,IAAKH,OAESnD,EACZE,GAAeH,EAAY2D,GAC3BjB,GAAQ1C,EAAY2D,IAErBvV,eAAegS,MACVH,KACED,EAAW7D,SAAS,SAAW6D,EAAW7D,SAAS,kBA3BlCU,EAAQxW,SAC7Bga,MAAWG,MAAM3D,IACrBlN,KAAM,6BAEF2Q,MAAaG,WACnBH,EAAOI,gBAAmBC,SAClBC,EAAUD,EAAI7Z,OAAO+Z,OAC3Bxa,EAASua,EAAQE,OAAOF,EAAQ/Q,QAAQ,KAAO,KAEjDyQ,EAAOS,cAAcV,GAmBbuD,KAAwBxI,WAAWgF,aAAqBG,GAEtD9B,EAAU,cADE,yBAA2B8B,GACR,0BAG3BtX,EAAQkW,OAAOC,aAAaC,MAAM,KAAMe,GAC9C3B,EACE,sGAEFoF,uBACQC,EAAY/b,SAASsb,eAAe,iBAC1CS,EAAU7a,MAAQA,EAClBlB,SACGsb,eAAe,aACf5a,iBAAiB,oBAChB8Z,WAEIwB,KAAM/D,EACNwC,SAAUsB,EAAU7a,QAGpBsa,IAAKH,OAEP3F,MAAMgB,cAKhBA,EAAU2B,MAGb3C,MAAMgB,mBAIT+E,EAAIQ,IAAMxH,GAAewD,oBAcbA,6DAKawD,4FbhGkB,SAAS3Y,GAAGA,EAAEA,EAAEoZ,KAAK,GAAG,OAAOpZ,EAAEA,EAAEqZ,KAAK,GAAG,OAAOrZ,EAAEA,EAAEsZ,OAAO,GAAG,SAAhE,CAA0E1Z,KAAIA,GAAE,KAAK,MAAMkG,GAAEnG,YAAYK,EAAEJ,GAAG3B,KAAK6G,KAAK9E,EAAE/B,KAAKuU,QAAQ5S,EAAED,YAAYK,GAAG,OAAO,IAAI8F,GAAE,OAAO9F,GAAGL,YAAYK,GAAG,OAAO,IAAI8F,GAAE,OAAO9F,GAAGL,YAAYK,GAAG,OAAO,IAAI8F,GAAE,OAAO9F,GAAGL,aAAaK,GAAG,OAAO,IAAI8F,GAAE,QAAQ9F,IAAI,MAAM4Q,GAAEjR,YAAYK,GAAG/B,KAAKsb,IAAIvZ,EAAEuZ,IAAItb,KAAKub,OAAOxZ,EAAEwZ,OAAOvb,KAAKwb,GAAGxb,KAAKub,QAAQ,KAAKvb,KAAKub,OAAO,IAAIvb,KAAKyb,QAAQ1Z,EAAE0Z,QAAQzb,KAAKZ,KAAK2C,EAAE3C,MAAM,MAAMwC,GAAEF,YAAYK,GAAG/B,KAAK+V,GAAGhU,EAAEL,aAAa,OAAOK,GAAE,CAAC8R,cAAc,OAAOC,QAAQ,CAACrH,IAAI,aAAaiP,OAAO1b,KAAK+V,MAAMrU,cAAcmG,GAAG,MAAMjG,GAAGiG,EAAE8T,cAAc9T,EAAE8T,eAAeha,GAAEwZ,KAAK,OAAOvZ,IAAIiG,EAAE8T,aAAaha,GAAEyZ,MAAMrZ,GAAE,CAAC8R,cAAc,OAAOC,QAAQ,CAACrH,IAAI,cAAciP,OAAO1b,KAAK+V,GAAGrW,QAAQmI,KAAKvC,MAAMvD,IAAI,MAAMJ,EAAE,IAAIgR,GAAE5Q,GAAG,GAAGH,EAAE,CAAC,IAAID,EAAEvC,KAAK+b,KAAKS,MAAMja,EAAEvC,MAAM,MAAM2C,GAAG,GAAGJ,EAAE6Z,GAAG,MAAMhZ,MAAM,8BAA8Bb,EAAEvC,mBAAmB2C,6JAA6J,OAAOJ,EAAE,OAAOA,KAAKD,UAAUK,EAAEJ,GAAG,OAAO3B,KAAK6b,QAAQ,CAACvT,OAAO,MAAMgT,IAAIvZ,KAAKJ,IAAID,WAAWK,EAAEJ,EAAEkG,GAAG,OAAO7H,KAAK6b,QAAQ,CAACvT,OAAO,OAAOgT,IAAIvZ,EAAEmU,KAAKvU,KAAKkG,IAAInG,UAAUK,EAAEJ,EAAEkG,GAAG,OAAO7H,KAAK6b,QAAQ,CAACvT,OAAO,MAAMgT,IAAIvZ,EAAEmU,KAAKvU,KAAKkG,IAAInG,YAAYK,EAAEJ,GAAG,OAAO3B,KAAK6b,QAAQ,CAACvT,OAAO,QAAQgT,IAAIvZ,KAAKJ,IAAID,aAAaK,EAAEJ,GAAG,OAAO3B,KAAK6b,QAAQ,CAACvT,OAAO,SAASgT,IAAIvZ,KAAKJ,KAAKoR,eAAe7V,GAAEyE,GAAG,OAAOI,GAAE,CAAC8R,cAAc,OAAOC,QAAQ,CAACrH,IAAI,eAAe/M,QAAQiC,KAAK2D,MAAMvD,GAAG,IAAIH,GAAEG,KAAK,IAAI4C,GAAE,mmBcgCh+CT,iWAAAA,wBAUzCA,sCAQAA,iGAnBgBA,iCACyBA,qBAUzCA,UAAAA,eAQAA,+DAhDV4X,EAAa,MACbC,EAAU,+CACVC,EAAW,cAEJrG,2FAGH+F,QAAeO,KAIfvc,GACJ4b,IAHQS,GAAW,IAGP,GACZzT,OALWwT,GAAc,OAKP,OAIjBE,EAASE,WAAW,MAAQF,EAASG,SAAS,MAC9CH,EAASE,WAAW,MAAQF,EAASG,SAAS,KAE/Czc,EAAQwW,KAAOkG,GAAKC,KAAKlB,KAAKS,MAAMI,IACd,KAAbA,IACTtc,EAAQwW,KAAOkG,GAAKjd,KAAK6c,IAG3BN,EAAOG,QAAQnc,GAAS4F,KAAKqQ,GAAWhB,MAAMgB,iBAKOmG,6BAUzCC,gCAQAC,sBdlDynDtf,OAAO4W,OAAO,CAACC,UAAU,KAAK0I,UAAU/e,GAAEof,MAArJvJ,eAAiBhR,EAAEJ,GAAG,OAAO,OAAOgD,KAAIA,SAAQzH,MAAKyH,GAAEkX,QAAQ,CAACP,IAAIvZ,EAAEuG,OAAO3G,GAAG2G,QAAQ,SAAS3G,KAA4Dya,KAAKvU,GAAE0U,OAAO3a,GAAE4a,SAAS7J,GAAE8J,mBAAmB,OAAO9a,4Pe4B7rDuC,0DAzBxCwY,SACHC,aAAa,sBACfzG,KAAM,mEAJCP,yEASuB,YAA5BgH,aAAaC,WACfD,aAAaE,oBACVvX,eAAegS,GACG,YAAbA,EACFoF,KAEA/G,EAAU,iBAAmB2B,MAGhC3C,MAAMgB,GAC4B,YAA5BgH,aAAaC,WACtBF,KAEA/G,EAAU,uGCvB8E,MAAM9N,GAAEnG,YAAYC,EAAEzE,GAAG8C,KAAK6G,KAAK,UAAU7G,KAAK8c,MAAMnb,EAAE3B,KAAK+c,OAAO7f,GAAmI,MAAMuJ,GAAE/E,YAAYC,EAAEzE,GAAG8C,KAAK6G,KAAK,UAAU7G,KAAK2N,EAAEhM,EAAE3B,KAAKmP,EAAEjS,GAAiH,IAAI4B,GAAE,SAAS6F,KAAI,OAAO,IAAI3C,GAAEyG,OAAOuU,UAAUC,gBAAgBC,MAAM,CAACC,MAAK,IAAK,SAASvY,KAAI,OAAO6D,OAAOuU,UAAUI,UAAUlY,KAAKvD,GAAG,IAAIK,GAAEL,EAAEub,MAAM,CAACC,MAAK,OAAQ,SAASxb,GAAGA,EAAEA,EAAE0b,SAAS,GAAG,WAAW1b,EAAEA,EAAE2b,cAAc,GAAG,gBAA5D,CAA6Exe,KAAIA,GAAE,KAAK,MAAMkG,GAAE,CAAC,kBAAkB,iBAAiB,MAAMuY,GAAE7b,YAAYC,GAAG3B,KAAKkd,MAAMvb,EAAE3B,KAAKwd,UAAU9gB,OAAOC,OAAO,MAAM+E,aAAaC,EAAEI,GAAG,OAAO/B,KAAKyd,kBAAkB9b,EAAEI,GAAGkB,QAAQC,cAAc,MAAMhG,EAAE8C,KAAKwd,UAAU7b,GAAGzE,EAAE8J,OAAO9J,EAAE6J,QAAQhF,GAAG,MAAM7E,GAAEyE,EAAEI,GAAGL,WAAWC,EAAEzE,GAAG,OAAO8C,KAAKyd,kBAAkB9b,EAAEzE,GAAG+F,QAAQC,cAAc,MAAMnB,EAAE/B,KAAKwd,UAAU7b,GAAGI,EAAEiF,OAAOjF,EAAEgF,QAAQ7J,GAAG,MAAM6E,GAAEJ,EAAEzE,GAAGwE,WAAWC,EAAEzE,GAAG,GAAG8H,GAAEqO,SAAS1R,GAAG,CAAC,IAAI,MAAMI,KAAK/B,KAAKwd,UAAU7b,IAAI,GAAGI,EAAE,CAACvC,MAAMmC,EAAEoU,IAAI,EAAExB,QAAQrX,IAAI,OAAO+F,QAAQC,UAAU,OAAOtE,GAAE+C,EAAE3B,KAAKkd,MAAMhgB,GAAGwE,kBAAkBC,EAAEzE,GAAG,QAAQ8H,GAAEqO,SAAS1R,KAAKA,KAAK3B,KAAKwd,UAAUxd,KAAKwd,UAAU7b,GAAGjE,KAAKR,GAAG8C,KAAKwd,UAAU7b,GAAG,CAACzE,IAAG,IAAK,MAAMiS,WAAUoO,GAAE7b,oBAAoB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,mBAAmBnF,sBAAsB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,qBAAqBnF,sBAAsB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,qBAAqBnF,kBAAkB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,iBAAiBnF,kBAAkB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,iBAAiBnF,qBAAqB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,oBAAoBnF,oBAAoB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,mBAAmBnF,oBAAoB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,mBAAmBnF,oBAAoB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,mBAAmBnF,kBAAkB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,iBAAiBnF,eAAe,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,cAAcnF,2BAA2BxE,GAAG,IAAI6E,EAAE,KAAK,OAAO7E,IAAI6E,EAAE7E,IAAI4B,GAAEue,SAAS,CAACxW,KAAK,YAAY,CAACA,KAAK,kBAAkBlF,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,uBAAuB0N,QAAQxS,OAAOL,mBAAmBxE,GAAG,OAAOyE,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,eAAe0N,QAAQrX,OAAOwE,eAAexE,GAAG,OAAOyE,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,WAAW0N,QAAQrX,OAAOwE,iBAAiB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,gBAAgBnF,mBAAmB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,kBAAkBnF,uBAAuB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,sBAAsBnF,iBAAiB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,gBAAgBnF,mBAAmB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,kBAAkBnF,aAAa,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,YAAYnF,aAAa,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,YAAYnF,cAAc,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,aAAanF,qBAAqBxE,GAAG,OAAOyE,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,iBAAiB0N,QAAQrX,OAAOwE,qBAAqBxE,GAAG,OAAOyE,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,iBAAiB0N,QAAQrX,OAAOwE,cAAcxE,GAAG,IAAIA,GAAG,YAAYA,EAAE2J,MAAM,aAAa3J,EAAE2J,KAAK,MAAM,IAAIrE,MAAM,+EAA+E,OAAOb,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,UAAU0N,QAAQ,CAAC1N,KAAK3J,EAAE2J,KAAKzH,KAAK,CAAC0d,MAAM5f,EAAE4f,MAAMC,OAAO7f,EAAE6f,cAAcrb,iBAAiBxE,GAAG,GAAGA,GAAG,YAAYA,EAAE2J,MAAM,aAAa3J,EAAE2J,KAAK,MAAM,IAAIrE,MAAM,+EAA+E,OAAOb,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,aAAa0N,QAAQrX,EAAE,CAAC2J,KAAK3J,EAAE2J,KAAKzH,KAAK,CAAC0d,MAAM5f,EAAE4f,MAAMC,OAAO7f,EAAE6f,SAAS,UAAUrb,iBAAiBxE,GAAG,GAAGA,GAAG,YAAYA,EAAE2J,MAAM,aAAa3J,EAAE2J,KAAK,MAAM,IAAIrE,MAAM,+EAA+E,OAAOb,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,aAAa0N,QAAQrX,EAAE,CAAC2J,KAAK3J,EAAE2J,KAAKzH,KAAK,CAAC0d,MAAM5f,EAAE4f,MAAMC,OAAO7f,EAAE6f,SAAS,UAAUrb,kBAAkBxE,GAAG,IAAIA,GAAG,YAAYA,EAAE2J,MAAM,aAAa3J,EAAE2J,KAAK,MAAM,IAAIrE,MAAM,2FAA2F,OAAOb,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,cAAc0N,QAAQ,CAAC1N,KAAK3J,EAAE2J,KAAKzH,KAAK,CAACuO,EAAEzQ,EAAEyQ,EAAEwB,EAAEjS,EAAEiS,SAASzN,oBAAoBxE,GAAG,OAAOyE,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,gBAAgB0N,QAAQrX,OAAOwE,iBAAiB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,gBAAgBnF,cAAcxE,GAAG,OAAOyE,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,UAAU0N,QAAQ,CAACmJ,KAAKxgB,QAAQwE,qBAAqBxE,GAAG,OAAOyE,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,iBAAiB0N,QAAQrX,OAAOwE,sBAAsB,OAAOC,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAAC8d,MAAMld,KAAKkd,MAAMzQ,IAAI,CAAC5F,KAAK,sBAAsB,MAAM7E,WAAUmN,GAAEzN,YAAYxE,EAAE6E,EAAE,IAAIiS,MAAM9W,GAAG6E,GAAGob,MAAMxb,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,gBAAgBrN,KAAK,CAACM,QAAQ,CAACwd,MAAMhgB,KAAK6E,OAAOuD,eAAetF,KAAKmW,KAAK,qBAAqBxB,aAAO5B,GAAS/S,KAAKmW,KAAK,gBAAgBxU,KAAKD,kBAAkBC,GAAG,OAAOiD,KAAI+Y,MAAMzgB,GAAGA,EAAEggB,QAAQvb,IAAI,IAAIK,GAAEL,EAAE,CAACwb,MAAK,IAAK,MAAM,MAAMS,GAAE,IAAI5b,GAAE,KAAK,CAACmb,MAAK,wFCsFjrNjZ,qDAARA,uEAAQA,iCAARA,qTADVxH,OAAO0K,KAAKlD,6BAAjBrF,m+CAD6BqF,k7CAAAA,4CAOMA,2CAIAA,qFAaAA,4CAIAA,2CAIAA,2CAIAA,2FAUAA,gDAIAA,yDAOAA,+CAIAA,wDAOAA,+CAIAA,yDAOAA,gDAIAA,yCAOXA,2DAIFA,qKA7E4BA,mBAGEA,mGAmBtCA,2MAkDmCA,4CAIAA,qBAIxBA,oBACAA,+CAjGpBxH,OAAO0K,KAAKlD,eAAjBrF,yIAAAA,mBAD6BqF,yBAOMA,yBAIAA,6BAaAA,2BAIAA,0BAIAA,0BAIAA,+BAUAA,YAAAA,iCAIAA,YAAAA,+BAOAA,WAAAA,8BAIAA,WAAAA,8BAOAA,WAAAA,+BAIAA,YAAAA,gCAOAA,YAAAA,gCAIAA,YAAAA,+BAOXA,YAAAA,8BAIFA,YAAAA,8IA7K5BuE,OAAOoV,kBAAoBA,OACvBC,EAAiBC,KAAab,YAC5Bc,IACHF,GAAiBG,kBAGTtI,KAEPuI,EAAW,uBACXC,GAAY,EACZC,GAAY,EACZC,GAAc,EACdC,GAAc,EACdC,GAAc,EACdC,GAAa,EACb1B,EAAQ,IACRC,EAAS,IACT0B,EAAW,IACXC,EAAY,IACZC,EAAW,KACXC,EAAY,KACZjR,EAAI,IACJwB,EAAI,IAEJ0P,EAAc,oHA0Cfb,EAAUF,GAAgBgB,aAAaX,sBACvCC,EAAYJ,EAAUF,GAAgBiB,WAAaf,EAAUF,GAAgBkB,gCAC7EhB,EAAUF,GAAgBmB,eAAeX,qBACzCN,EAAUF,GAAgBoB,eAAeX,qBACzCP,EAAUF,GAAgBqB,cAAcX,sBAExCR,EAAUF,GAAgBsB,YAAYC,GAAYvC,EAAOC,yBACzD0B,GAAYC,EAAYV,EAAUF,GAAgBwB,eAAeD,GAAYZ,EAAUC,IAAcV,EAAUF,GAAgBwB,WAAW,4BAC1IX,GAAYC,EAAYZ,EAAUF,GAAgByB,eAAeF,GAAYV,EAAUC,IAAcZ,EAAUF,GAAgByB,WAAW,4BAC1IvB,EAAUF,GAAgB0B,gBAAgBC,GAAgB9R,EAAGwB,qDAhD9DuG,GAAKwI,eAILF,EAAUF,GAAgB4B,SAASb,eAInCb,EAAUF,GAAgB6B,OAC1B5E,WAAWiD,EAAUF,GAAgB8B,KAAM,iBAI3C5B,EAAUF,GAAgB+B,WAC1B9E,WAAWiD,EAAUF,GAAgBgC,WAAY,iBAIjDC,IACEpJ,UAAU,IACTrR,KAAK0Y,EAAUF,GAAgBkC,2BAI5B9C,EAAQ3K,KAAK0N,SAASvP,WACtBwP,MAAcC,GAAcjD,OAClCc,EAAUd,GAASgD,KACnBA,EAAQ9J,KAAK,4BACXT,EAAU,yDAKNqI,EAAUF,GAAgB+B,iBAC1B7B,EAAUF,GAAgBsC,qBAAqBvC,GAAkBR,oBAC7Dpa,SAAQC,GAAW6X,WAAW7X,EAAS,aAC3C8a,EAAUF,GAAgBsC,qBAAqB,oBAgBpBtC,oCAOMK,kCAIAC,2BAGqBJ,EAAUF,GAAgBuC,oBAU/ChC,mCAIAC,kCAIAC,kCAIAC,kCAUA7Q,oCAIAwB,oCAOA2N,mCAIAC,mCAOA0B,mCAIAC,oCAOAC,oCAIAC,oCAOXC,iCAIFX,uBDlLghOxhB,OAAO4W,OAAO,CAACC,UAAU,KAAK4M,cAAcne,GAAEse,oBAAoB/C,GAAEgD,cAAcpR,GAAE4O,WAAWpZ,GAAE6b,OAAO5b,GAAEqZ,UAAUL,GAAEyB,YAAYxX,GAAE4Y,aAA3gO,MAAQ/e,YAAYC,EAAEzE,GAAG8C,KAAK6G,KAAK,WAAW7G,KAAK8c,MAAMnb,EAAE3B,KAAK+c,OAAO7f,EAAEwE,UAAUC,GAAG,OAAO,IAAIkG,GAAE7H,KAAK8c,MAAMnb,EAAE3B,KAAK+c,OAAOpb,KAA85N8d,gBAAgBhZ,GAAEia,iBAA52N,MAAQhf,YAAYC,EAAEzE,GAAG8C,KAAK6G,KAAK,WAAW7G,KAAK2N,EAAEhM,EAAE3B,KAAKmP,EAAEjS,EAAEwE,UAAUC,GAAG,OAAO,IAAI8E,GAAEzG,KAAK2N,EAAEhM,EAAE3B,KAAKmP,EAAExN,KAAqxNkc,wBAAwB,OAAO/e,IAAG6hB,eAAnjB5N,iBAAmB,OAAOpR,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAACqN,IAAI,CAAC5F,KAAK,uBAA0e+Z,eAApd7N,iBAAmB,OAAOpR,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAACqN,IAAI,CAAC5F,KAAK,uBAA2Yga,kBAArX9N,iBAAmB,OAAOpR,GAAE,CAACkS,cAAc,SAASC,QAAQ,CAACrH,IAAI,SAASrN,KAAK,CAACqN,IAAI,CAAC5F,KAAK,yZEAp8NkM,eAAepR,GAAEA,EAAEkG,GAAG,OAAO8K,GAAE,CAACkB,cAAc,iBAAiBC,QAAQ,CAACrH,IAAI,WAAW6C,SAAS3N,EAAElC,QAAQsC,GAAE8F,MAAmOkL,eAAe7V,GAAE6E,GAAG,OAAO4Q,GAAE,CAACkB,cAAc,iBAAiBC,QAAQ,CAACrH,IAAI,aAAa6C,SAASvN,KAAKgR,eAAepO,KAAI,OAAOgO,GAAE,CAACkB,cAAc,iBAAiBC,QAAQ,CAACrH,IAAI,4GCyD/jBvI,iOAAAA,mLAO6BA,kFAT3BA,0BAALrF,qCAQGqF,KAAWrF,oSAbFqF,wIAEkBA,yCAFlBA,UAAAA,wBAKPA,aAALrF,4HAAAA,OAQGqF,KAAWrF,uJAvDP8W,WACLmL,EAAYxZ,+BACdgI,EAAW,0BAcNyR,EAAWzR,SACZ0R,EAAY1R,EAClB2R,GAAmBD,GAChB1b,WACCwb,EAAUrd,QAAQyd,GAChBA,EAAW/b,QAAQ0C,GAAMA,IAAMmZ,MAEjCrL,cAAsBqL,qBAEvBrM,MAAMgB,mFApBHqL,EAAY1R,EAClB6R,GAAiBH,QACfrL,cAAsBqL,kBAErB1b,WACCwb,EAAUrd,QAAQyd,OAAmBA,EAAYF,KACjDrL,cAAsBqL,gCAEvBrM,MAAMgB,iBAgBTyL,KACG9b,WACCwb,EAAUrd,iBACVkS,mCAEDhB,MAAMgB,iBAQKrG,wBAQ4ByR,EAAWM,ID1DwiB3kB,OAAO4W,OAAO,CAACC,UAAU,KAAK+N,SAAS3f,GAAE4f,YAA7cxO,eAAiBpR,EAAEkG,GAAG,OAAO8K,GAAE,CAACkB,cAAc,iBAAiBC,QAAQ,CAACrH,IAAI,cAAcqU,UAAUnf,EAAElC,QAAQsC,GAAE8F,OAA2W2Z,aAArWzO,eAAiBhR,GAAG,OAAO4Q,GAAE,CAACkB,cAAc,iBAAiBC,QAAQ,CAACrH,IAAI,eAAe6C,SAASvN,MAAkRgf,WAAW7jB,GAAEukB,cAAc9c,8PE2D5oBT,8DACfA,oCADeA,UAAAA,mGAD7CA,iYAHcA,iFASAA,wBACAA,2CATcA,kBACAA,4EAFdA,UAAAA,MAGdA,8EAMcA,UAAAA,qBACAA,UAAAA,0EA/Dfwd,EAAUzZ,UAAUC,UAAUmL,SAAS,eAUzCsO,EATAlV,EAAMiV,EAAU,MAAQ,KACxB5P,EAAO4P,GAAW,OAAS,iBAEpB/L,KAEPiM,EAAS,qBACTC,EAAM,KACNC,EAAM,4BACNC,EAAQ,qFAcVJ,EAAQ,YACFjV,MAAc8I,GAAQ/I,MAASqF,EAAM8P,IAAWC,IAAKA,GAAO,KAAMC,IAXjEA,EAAI9Y,MAAM,KAAKgZ,SAAQF,EAAKG,SAC5BphB,EAAKV,GAAS8hB,EAAOjZ,MAAM,eAE3B8Y,GACFjhB,GAAMV,WASXuM,EAAQ8H,GAAG,SAASpV,IAClBuW,gCAAwCvW,EAAKsO,mBAAmBtO,EAAKqV,cACrEkN,EAAQ,SAEVjV,EAAQ8H,GAAG,SAASpB,GAASuC,qBAA6BvC,QAE1D1G,EAAQuH,OAAOO,GAAG,QAAQ0N,GAAQvM,sBAA8BuM,QAChExV,EAAQwH,OAAOM,GAAG,QAAQ0N,GAAQvM,sBAA8BuM,QAEhExV,EAAQgI,QACLpP,MAAKV,QACJ+c,EAAQ/c,MAET+P,MAAMgB,eAITgM,EAAMQ,OAAO7c,UAAWqQ,EAAU,0BAAyBhB,MAAMgB,eAIjEgM,EAAMS,MAAML,GAAOpN,MAAMgB,iBAMNiM,gCAI+BG,gCAK/BF,gCACAC,iGCjE0B/O,eAAepR,KAAI,IAAIgR,EAAE,SAAShR,IAAIgR,GAAGA,IAAIA,OAAE,EAAO,OAAO,IAAI1P,UAAU0B,EAAEkD,KAAK9F,GAAE,yBAAyBA,IAAI,IAAI7E,GAAGA,EAAE6E,GAAGwS,SAASnB,OAAOzR,IAAIkG,EAAE3K,EAAEkW,QAAQ,SAASlW,EAAEqe,SAAS5Z,IAAIgD,QAAQW,MAAMvD,IAAI4Q,EAAE5Q,KAAK4S,OAAO5S,IAAI,MAAMJ,IAAII,KAAK7E,GAAE,0BAA0ByX,OAAO5S,IAAI,MAAMJ,IAAII,QAAQgR,eAAepO,KAAI,IAAIhD,EAAE,SAASgD,IAAIhD,GAAGA,IAAIA,OAAE,EAAO,OAAO,IAAIsB,UAAU4E,EAAE0V,KAAK5K,GAAE,4BAA4B5Q,IAAI,IAAI7E,EAAEA,EAAE6E,GAAGwS,QAAQ5P,IAAIkD,EAAE,CAACwa,SAASnlB,EAAEolB,cAAa,OAAQ3N,OAAO5S,IAAI,MAAM4C,IAAI5C,KAAKA,GAAE,yBAAyBA,IAAI,IAAI7E,GAAGA,EAAE6E,GAAGwS,SAASnB,OAAOzO,IAAI4Y,EAAErgB,EAAEkW,QAAQ,aAAalW,EAAEqe,SAAS5W,IAAIkD,EAAE,CAACya,cAAa,QAAShd,MAAMvD,IAAIJ,EAAEI,KAAK4S,OAAO5S,IAAI,MAAM4C,IAAI5C,KAAK7E,GAAE,kBAAkByX,OAAO5S,IAAI,MAAM4C,IAAI5C,yTCwDzrBmC,kBACOA,0EA7CtD8R,aADOL,YAGXlT,aACEuT,QAAiBzW,GAAO,wBAAyBoW,MAEnDhT,QACMqT,GACFA,8EAMA/W,SAASsb,eAAe,gBAAgBgI,UAAU3e,IAAI,6BAE/C0e,EAAYD,SAAEA,SAAkBG,KACvC7M,oBAA4B2M,KAC5B3M,EAAU0M,GAENC,GACFrjB,SAASsb,eAAe,gBAAgBgI,UAAUE,OAAO,gBAErD9gB,GACNgU,EAAUhU,0BAMV1C,SAASsb,eAAe,gBAAgBgI,UAAU3e,IAAI,gBAEhD8e,KACN/M,EAAU,kDACJJ,WAEA5T,GACNgU,EAAUhU,QDhD4uBjF,OAAO4W,OAAO,CAACC,UAAU,KAAKmP,cAAc/gB,GAAE6gB,YAAY7d,gFEA9wBoO,eAAeJ,GAAEA,GAAG,OAAOhR,GAAE,CAACkS,cAAc,YAAYC,QAAQ,CAACrH,IAAI,YAAYrN,KAAKuT,KAAKI,eAAe7V,KAAI,OAAOyE,GAAE,CAACkS,cAAc,YAAYC,QAAQ,CAACrH,IAAI,qTC8BrLvI,uEAEkBA,kBAEFA,sCAJhBA,UAAAA,yEAxBLyR,KACPxW,EAAO,0FAGTwjB,GAAUxjB,GACPmG,WACCqQ,EAAU,6BAEXhB,MAAMgB,eAITiN,KACGtd,MAAMoU,IACL/D,yBAAiC+D,QAElC/E,MAAMgB,iBAQKxW,sBD9ByMzC,OAAO4W,OAAO,CAACC,UAAU,KAAKoP,UAAUhQ,GAAEiQ,SAAS1lB,8UEEjQyY,WAELkN,EAAcpa,OAAOoa,aACzBC,OAAO,EACPC,OAAO,UAyBTtgB,2BAtBuBugB,SACfD,EAAQ9jB,SAASuC,cAAc,SAC/ByhB,EAAcD,EAAOE,iBAC3BvN,EAAU,+BAAgCkN,GAC1ClN,yBAAiCsN,EAAY,GAAG/F,SAChDzU,OAAOua,OAASA,EAChBD,EAAMI,UAAYH,EAmBhBI,OADqBnb,UAAUob,aAAaC,aAAaT,UAElDlhB,aAjBUyR,MACA,gCAAfA,EAAMpU,YACFoW,EAAIyN,EAAYE,MACtBpN,oBAA4BP,EAAE0H,MAAMyG,SAASnO,EAAE2H,OAAOwG,iDAC9B,0BAAfnQ,EAAMpU,MACf2W,EAAU,yJAIZA,yBAAiCvC,EAAMpU,OAAQoU,GAS7CoQ,CAAY7hB,OAIhBgB,QACE8F,OAAOua,OAAOS,YAAY3mB,kBAAiB4mB,GACzCA,EAAMlc,4UCZXtD,gDATkBA,4BACAA,0HACaA,sCAFbA,UAAAA,qBACAA,UAAAA,eAQlBA,+HA7BIyf,EAAM,MACNC,EAAM,MACN7L,EAAS,uCAGNuD,EAAMrT,UAAUC,UAAUmL,SAAS,WAAa,2CAA6C,2CAC7F4D,QAAYqF,MAAMhB,GACvBhT,OAAQ,OACR4N,KAAMiF,KAAK0I,WACVF,IAAAA,EACAC,IAAAA,MAIIvH,QAAapF,EAAIoF,WACvBtE,EAASoD,KAAK0I,UAAUxH,gBAKPsH,gCACAC,+KC+GV1f,KAAKgZ,uGAFehZ,OAAaA,KAAO,cAAgB,uGAApCA,OAAaA,KAAO,cAAgB,iHADpDA,0BAALrF,qCAQsBqF,KAAS7G,izCAU5B6G,gCAjCsDA,8DAepDA,aAALrF,+HAAAA,iBAQsBqF,KAAS7G,kB/BsoBnCgH,EAAS,CACLsO,EAAG,EACH/N,EAAG,GACHX,EAAGI,iDAIFA,EAAOsO,GACR/V,EAAQyH,EAAOO,GAEnBP,EAASA,EAAOJ,0F+BtoBTC,yIA5HTzB,QACEqN,GAHyB,eAIvB2D,GAAO,2BAILqQ,IAEF5G,MAAO,UACP7f,UAAW0mB,KAGX7G,MAAO,WACP7f,UAAW2mB,KAGX9G,MAAO,MACP7f,UAAW4mB,KAGX/G,MAAO,SACP7f,UAAW6mB,KAGXhH,MAAO,cACP7f,UAAW8mB,KAGXjH,MAAO,OACP7f,UAAW+mB,KAGXlH,MAAO,YACP7f,UAAWgnB,KAGXnH,MAAO,gBACP7f,UAAWinB,KAGXpH,MAAO,SACP7f,UAAWknB,KAGXrH,MAAO,YACP7f,UAAWmnB,KAGXtH,MAAO,QACP7f,UAAWonB,KAGXvH,MAAO,UACP7f,UAAWqnB,KAGXxH,MAAO,YACP7f,UAAWsnB,KAGXzH,MAAO,SACP7f,UAAWunB,SAIXvjB,EAAWyiB,EAAM,GAEjBe,EAAYvd,MACZgQ,EAAW,YAENpW,EAAO4jB,OACdzjB,EAAWyjB,GAWbriB,QACEoiB,EAAUhnB,WAAU8U,QAClB2E,EAAW3E,EAAEnC,KAAK,uCAVHrQ,GACjB0kB,EAAUphB,QAAOkP,aAAcoS,MAAOC,2BAAmD,iBAAV7kB,EAAqBA,EAAQgb,KAAK0I,UAAU1jB,OAAYwS,iBAIvI+C,GAAK,6BA4B4ExU,EAAO4jB,QAcpFD,EAAUphB,0BC/IN,kEAAQ,CAClBzF,OAAQiB,SAASiX"} \ No newline at end of file diff --git a/examples/api/public/favicon.png b/examples/api/public/favicon.png deleted file mode 100644 index bf8075d14770..000000000000 Binary files a/examples/api/public/favicon.png and /dev/null differ diff --git a/examples/api/public/global.css b/examples/api/public/global.css index 0be50a57095a..3645dd44467e 100644 --- a/examples/api/public/global.css +++ b/examples/api/public/global.css @@ -185,4 +185,8 @@ main { box-shadow: rgba(0, 0, 0, 0.06) 0px 0px 10px; border-left: 6px solid #ff0000; background: #f0f4f5; -} \ No newline at end of file +} + +#file-response { + height: 400px; +} diff --git a/examples/api/public/index.html b/examples/api/public/index.html deleted file mode 100644 index cce959e63de4..000000000000 --- a/examples/api/public/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - Svelte app - - - - - - - - - diff --git a/examples/api/rollup.config.js b/examples/api/rollup.config.js deleted file mode 100644 index 09dd36d75eea..000000000000 --- a/examples/api/rollup.config.js +++ /dev/null @@ -1,77 +0,0 @@ -import svelte from 'rollup-plugin-svelte' -import resolve from '@rollup/plugin-node-resolve' -import commonjs from '@rollup/plugin-commonjs' -import livereload from 'rollup-plugin-livereload' -import { terser } from 'rollup-plugin-terser' - -const production = !process.env.ROLLUP_WATCH - -export default { - input: 'src/main.js', - output: { - sourcemap: true, - format: 'iife', - name: 'app', - file: 'public/build/bundle.js' - }, - plugins: [ - svelte({ - compilerOptions: { - // enable run-time checks when not in production - dev: !production - }, - emitCss: false - }), - - // If you have external dependencies installed from - // npm, you'll most likely need these plugins. In - // some cases you'll need additional configuration - - // consult the documentation for details: - // https://github.com/rollup/plugins/tree/master/packages/commonjs - resolve({ - browser: true, - dedupe: ['svelte'] - }), - commonjs(), - - // In dev mode, call `npm run start` once - // the bundle has been generated - !production && serve(), - - // Watch the `public` directory and refresh the - // browser on changes when not in production - !production && livereload('public'), - - // If we're building for production (npm run build - // instead of npm run dev), minify - production && terser() - ], - watch: { - clearScreen: false - } -} - -function serve() { - let server - - function toExit() { - if (server) server.kill(0) - } - - return { - writeBundle() { - if (server) return - server = require('child_process').spawn( - 'npm', - ['run', 'start', '--', '--dev'], - { - stdio: ['ignore', 'inherit', 'inherit'], - shell: true - } - ) - - process.on('SIGTERM', toExit) - process.on('exit', toExit) - } - } -} diff --git a/examples/api/src-tauri/.gitignore b/examples/api/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/api/src-tauri/.gitignore +++ b/examples/api/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/api/src-tauri/Cargo.lock b/examples/api/src-tauri/Cargo.lock index ca683361fb2d..1eb10b4a25dc 100644 --- a/examples/api/src-tauri/Cargo.lock +++ b/examples/api/src-tauri/Cargo.lock @@ -14,6 +14,41 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -23,11 +58,20 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" [[package]] name = "api" @@ -53,9 +97,59 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" -version = "0.7.1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "ashpd" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7915e26e0786f91768d23de32afafa4ee5e2ea76be21c0ecd8e14441543c1655" +dependencies = [ + "enumflags2", + "futures", + "rand 0.8.4", + "serde", + "serde_repr", + "zbus", +] + +[[package]] +name = "async-broadcast" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90622698a1218e0b2fb846c97b5f19a0831f6baddee73d9454156365ccfa473b" +dependencies = [ + "easy-parallel", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" +checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell", + "slab", +] [[package]] name = "async-io" @@ -76,35 +170,72 @@ dependencies = [ "winapi", ] +[[package]] +name = "async-lock" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-recursion" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d78656ba01f1b93024b7c3a0467f1608e4be67d725749fdcd7d2c7678fd7a2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-task" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d306121baf53310a3fd342d88dc0824f6bbeace68347593658525565abee8" + +[[package]] +name = "async-trait" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atk" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a83b21d2aa75e464db56225e1bda2dd5993311ba1095acaa8fa03d1ae67026ba" +checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" dependencies = [ "atk-sys", - "bitflags 1.3.2", + "bitflags", "glib", "libc", ] [[package]] name = "atk-sys" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea" +checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" dependencies = [ - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] name = "attohttpc" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8bda305457262b339322106c776e3fd21df860018e566eb6a5b1aa4b6ae02d" +checksum = "e69e13a99a7e6e070bb114f7ff381e58c7ccc188630121fc4c2fe4bcf24cd072" dependencies = [ "flate2", "http", @@ -131,9 +262,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" @@ -150,12 +281,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bitflags" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" - [[package]] name = "bitflags" version = "1.3.2" @@ -175,14 +300,14 @@ dependencies = [ [[package]] name = "blake3" -version = "1.0.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcd555c66291d5f836dbb6883b48660ece810fe25a31f3bdfb911945dff2691f" +checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" dependencies = [ "arrayref", - "arrayvec 0.7.1", + "arrayvec 0.7.2", "cc", - "cfg-if 1.0.0", + "cfg-if", "constant_time_eq", "digest", "rayon", @@ -194,20 +319,29 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + [[package]] name = "bstr" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "memchr", ] [[package]] name = "bumpalo" -version = "3.7.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "byteorder" @@ -217,9 +351,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "bzip2" @@ -244,17 +378,17 @@ dependencies = [ [[package]] name = "cache-padded" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" +checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "cairo-rs" -version = "0.14.3" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f859ade407c19810ae920b4fafab92189ed312adad490d08fb16b5f49f1e2207" +checksum = "b869e97a87170f96762f9f178eae8c461147e722ba21dd8814105bf5716bf14a" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cairo-sys-rs", "glib", "libc", @@ -263,20 +397,31 @@ dependencies = [ [[package]] name = "cairo-sys-rs" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" dependencies = [ - "glib-sys 0.14.0", + "glib-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", +] + +[[package]] +name = "cargo_toml" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e270ef0cd868745878982f7ce470aa898d0d4bb248af67f0cf66f54617913ef" +dependencies = [ + "serde", + "serde_derive", + "toml", ] [[package]] name = "cc" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" dependencies = [ "jobserver", ] @@ -301,10 +446,13 @@ dependencies = [ ] [[package]] -name = "cfg-if" -version = "0.1.10" +name = "cfg-expr" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" +dependencies = [ + "smallvec", +] [[package]] name = "cfg-if" @@ -331,36 +479,28 @@ dependencies = [ "winapi", ] +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + [[package]] name = "clap" -version = "3.0.0-beta.2" +version = "3.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" +checksum = "b63edc3f163b3c71ec8aa23f9bd6070f77edbf3d1d198b164afa90ff00e4ec62" dependencies = [ "atty", - "bitflags 1.3.2", - "clap_derive", + "bitflags", "indexmap", - "lazy_static", "os_str_bytes", "strsim 0.10.0", "termcolor", "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "clap_derive" -version = "3.0.0-beta.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", ] [[package]] @@ -369,11 +509,11 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" dependencies = [ - "bitflags 1.3.2", + "bitflags", "block", "cocoa-foundation", - "core-foundation 0.9.1", - "core-graphics 0.22.2", + "core-foundation", + "core-graphics", "foreign-types", "libc", "objc", @@ -385,46 +525,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" dependencies = [ - "bitflags 1.3.2", + "bitflags", "block", - "core-foundation 0.9.1", + "core-foundation", "core-graphics-types", "foreign-types", "libc", "objc", ] -[[package]] -name = "com" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a30a2b2a013da986dc5cc3eda3d19c0d59d53f835be1b2356eb8d00f000c793" -dependencies = [ - "com_macros", -] - -[[package]] -name = "com_macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7606b05842fea68ddcc89e8053b8860ebcb2a0ba8d6abfe3a148e5d5a8d3f0c1" -dependencies = [ - "com_macros_support", - "proc-macro2", - "syn 1.0.75", -] - -[[package]] -name = "com_macros_support" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e9a6d20f4ac8830e309a455d7e9416e65c6af5a97c88c55fbb4c2012e107da" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", -] - [[package]] name = "concurrent-queue" version = "1.2.2" @@ -448,56 +557,28 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "core-foundation-sys 0.8.2", + "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - -[[package]] -name = "core-foundation-sys" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" - -[[package]] -name = "core-graphics" -version = "0.19.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.7.0", - "foreign-types", - "libc", -] +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "core-graphics" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.1", + "bitflags", + "core-foundation", "core-graphics-types", "foreign-types", "libc", @@ -509,41 +590,37 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.1", + "bitflags", + "core-foundation", "foreign-types", "libc", ] [[package]] -name = "core-video-sys" -version = "0.1.4" +name = "cpufeatures" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", "libc", - "objc", ] [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -553,18 +630,18 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", "lazy_static", "memoffset", @@ -573,14 +650,23 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "lazy_static", ] +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + [[package]] name = "cssparser" version = "0.27.2" @@ -589,13 +675,13 @@ checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" dependencies = [ "cssparser-macros", "dtoa-short", - "itoa", + "itoa 0.4.8", "matches", "phf 0.8.0", "proc-macro2", - "quote 1.0.9", + "quote", "smallvec", - "syn 1.0.75", + "syn", ] [[package]] @@ -604,18 +690,53 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" dependencies = [ - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", +] + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", ] +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + [[package]] name = "darling" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + +[[package]] +name = "darling" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +dependencies = [ + "darling_core 0.13.1", + "darling_macro 0.13.1", ] [[package]] @@ -627,9 +748,23 @@ dependencies = [ "fnv", "ident_case", "proc-macro2", - "quote 1.0.9", + "quote", "strsim 0.9.3", - "syn 1.0.75", + "syn", +] + +[[package]] +name = "darling_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn", ] [[package]] @@ -638,9 +773,20 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" dependencies = [ - "darling_core", - "quote 1.0.9", - "syn 1.0.75", + "darling_core 0.10.2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +dependencies = [ + "darling_core 0.13.1", + "quote", + "syn", ] [[package]] @@ -670,30 +816,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "derive_more" -version = "0.99.16" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", "proc-macro2", - "quote 1.0.9", - "rustc_version", - "syn 1.0.75", + "quote", + "rustc_version 0.4.0", + "syn", ] [[package]] name = "digest" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" dependencies = [ + "block-buffer", + "crypto-common", "generic-array", + "subtle", ] [[package]] @@ -713,7 +862,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "dirs-sys-next", ] @@ -749,6 +898,12 @@ dependencies = [ "dtoa", ] +[[package]] +name = "easy-parallel" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6907e25393cdcc1f4f3f513d9aac1e840eb1cc341a0fccb01171f7d14d10b946" + [[package]] name = "either" version = "1.6.1" @@ -757,15 +912,15 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "embed_plist" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53dd2e43a7d32952a6054141ee0d75183958620e84e5eab045de362dff13dc99" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" [[package]] name = "enumflags2" -version = "0.6.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +checksum = "a25c90b056b3f84111cf183cbeddef0d3a0bbe9a674f057e1a1533c315f24def" dependencies = [ "enumflags2_derive", "serde", @@ -773,20 +928,26 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.6.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +checksum = "144ec79496cbab6f84fa125dc67be9264aef22eb8a28da8454d9c33f15108da4" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] +[[package]] +name = "event-listener" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" + [[package]] name = "fastrand" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ "instant", ] @@ -798,7 +959,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" dependencies = [ "memoffset", - "rustc_version", + "rustc_version 0.3.3", ] [[package]] @@ -807,7 +968,7 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall 0.2.10", "winapi", @@ -815,11 +976,11 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crc32fast", "libc", "miniz_oxide 0.4.4", @@ -858,9 +1019,9 @@ dependencies = [ [[package]] name = "futf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" dependencies = [ "mac", "new_debug_unreachable", @@ -868,9 +1029,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -883,9 +1044,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -893,15 +1054,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -910,9 +1071,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-lite" @@ -931,36 +1092,33 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ - "autocfg", "futures-channel", "futures-core", "futures-io", @@ -970,8 +1128,6 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -986,11 +1142,11 @@ dependencies = [ [[package]] name = "gdk" -version = "0.14.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "679e22651cd15888e7acd01767950edca2ee9fcd6421fbf5b3c3b420d4e88bb0" +checksum = "614258e81ec35ed8770e64a0838f3a47f95b398bc51e724d3b3fa09c1ee0f8d5" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cairo-rs", "gdk-pixbuf", "gdk-sys", @@ -1002,10 +1158,11 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.14.0" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f" +checksum = "73aa2f5de1b45710da90a55863276667dc3a3264aaf6a2aeace62bb015244d49" dependencies = [ + "bitflags", "gdk-pixbuf-sys", "gio", "glib", @@ -1014,32 +1171,45 @@ dependencies = [ [[package]] name = "gdk-pixbuf-sys" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590" +checksum = "413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171" dependencies = [ - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] name = "gdk-sys" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e" +checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", "pango-sys", "pkg-config", - "system-deps 3.2.0", + "system-deps 6.0.1", +] + +[[package]] +name = "gdkx11-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178" +dependencies = [ + "gdk-sys", + "glib-sys 0.15.5", + "libc", + "system-deps 6.0.1", + "x11", ] [[package]] @@ -1057,9 +1227,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -1071,33 +1241,43 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.10.2+wasi-snapshot-preview1", ] +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gio" -version = "0.14.3" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a7057cd21d64bfa7ac027b344a7f50f677fb3308693df0e8c70fb55d29f0d" +checksum = "59105fa464928adf56b159c8d980cc11fbfbe414befb904caac5163d383049bf" dependencies = [ - "bitflags 1.3.2", + "bitflags", "futures-channel", "futures-core", "futures-io", - "gio-sys 0.14.0", + "gio-sys 0.15.5", "glib", "libc", "once_cell", @@ -1106,84 +1286,91 @@ dependencies = [ [[package]] name = "gio-sys" -version = "0.10.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e24fb752f8f5d2cf6bbc2c606fd2bc989c81c5e2fe321ab974d54f8b6344eac" +checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" dependencies = [ - "glib-sys 0.10.1", - "gobject-sys 0.10.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", "libc", - "system-deps 1.3.2", + "system-deps 3.2.0", "winapi", ] [[package]] name = "gio-sys" -version = "0.14.0" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" +checksum = "4f0bc4cfc9ebcdd05cc5057bc51b99c32f8f9bf246274f6a556ffd27279f8fe3" dependencies = [ - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", "winapi", ] [[package]] name = "glib" -version = "0.14.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fb802e3798d75b415bea8f016eed88d50106ce82f1274e80f31d80cfd4b056" +checksum = "41dcfbdb6cc6c02aee163339465d8a40d6f3f64c3a43f729a4195f0e153338b7" dependencies = [ - "bitflags 1.3.2", + "bitflags", "futures-channel", "futures-core", "futures-executor", "futures-task", "glib-macros", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", "once_cell", "smallvec", + "thiserror", ] [[package]] name = "glib-macros" -version = "0.14.1" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" +checksum = "e58b262ff65ef771003873cea8c10e0fe854f1c508d48d62a4111a1ff163f7d1" dependencies = [ "anyhow", - "heck", - "proc-macro-crate 1.0.0", + "heck 0.4.0", + "proc-macro-crate 1.1.0", "proc-macro-error", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "glib-sys" -version = "0.10.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1" +checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" dependencies = [ "libc", - "system-deps 1.3.2", + "system-deps 3.2.0", ] [[package]] name = "glib-sys" -version = "0.14.0" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" +checksum = "fa1d4e1a63d8574541e5b92931e4e669ddc87ffa85d58e84e631dba13ad2e10c" dependencies = [ "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + [[package]] name = "globset" version = "0.4.8" @@ -1199,34 +1386,34 @@ dependencies = [ [[package]] name = "gobject-sys" -version = "0.10.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c" +checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" dependencies = [ - "glib-sys 0.10.1", + "glib-sys 0.14.0", "libc", - "system-deps 1.3.2", + "system-deps 3.2.0", ] [[package]] name = "gobject-sys" -version = "0.14.0" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" +checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a" dependencies = [ - "glib-sys 0.14.0", + "glib-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] name = "gtk" -version = "0.14.1" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6603bb79ded6ac6f3bac203794383afa8b1d6a8656d34a93a88f0b22826cd46c" +checksum = "c7978eaec05bea63947c801d29a21372f2ed39aec0bf56bf7725d3599094675e" dependencies = [ "atk", - "bitflags 1.3.2", + "bitflags", "cairo-rs", "field-offset", "futures-channel", @@ -1244,35 +1431,34 @@ dependencies = [ [[package]] name = "gtk-sys" -version = "0.14.0" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e" +checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" dependencies = [ "atk-sys", "cairo-sys-rs", "gdk-pixbuf-sys", "gdk-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", "pango-sys", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] name = "gtk3-macros" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79" +checksum = "8c891188af69e77a1e8a0b1746fbd03b9b396e7d34d518c5331b15950259f541" dependencies = [ "anyhow", - "heck", - "proc-macro-crate 1.0.0", + "proc-macro-crate 1.1.0", "proc-macro-error", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] @@ -1290,6 +1476,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1299,6 +1491,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "html5ever" version = "0.25.1" @@ -1309,19 +1507,19 @@ dependencies = [ "mac", "markup5ever", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "http" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.1", ] [[package]] @@ -1377,9 +1575,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ "autocfg", "hashbrown", @@ -1405,18 +1603,18 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "itertools" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] @@ -1427,23 +1625,33 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "javascriptcore-rs" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca9c7d1445bba2889672fbadc16c3d5007bfdcf0a15a18a3a50fe9fab2c7427" +checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c" dependencies = [ + "bitflags", "glib", "javascriptcore-rs-sys", ] [[package]] name = "javascriptcore-rs-sys" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f46ada8a08dcd75a10afae872fbfb51275df4a8ae0d46b8cc7c708f08dd2998" +checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c" dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", + "system-deps 5.0.0", ] [[package]] @@ -1463,13 +1671,24 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json-patch" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" +dependencies = [ + "serde", + "serde_json", + "treediff", +] + [[package]] name = "kuchiki" version = "0.8.1" @@ -1488,17 +1707,40 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "libappindicator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b29fab3280d59f3d06725f75da9ef9a1b001b2c748b1abfebd1c966c61d7de" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bdcb8c5cfc11febe2ff3f18386d6cb7d29f464cbaf6b286985c3f1a501d74f" +dependencies = [ + "gtk-sys", + "pkg-config", +] + [[package]] name = "libc" -version = "0.2.100" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" dependencies = [ "scopeguard", ] @@ -1509,20 +1751,22 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "loom" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2111607c723d7857e0d8299d5ce7a0bf4b844d3e44f8de136b13da513eaf8fc4" +checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "generator", "scoped-tls", "serde", "serde_json", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1567,16 +1811,19 @@ dependencies = [ ] [[package]] -name = "matches" -version = "0.1.9" +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] [[package]] -name = "maybe-uninit" -version = "2.0.0" +name = "matches" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" @@ -1586,18 +1833,18 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] [[package]] name = "minisign-verify" -version = "0.1.8" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0507fe8e3c68cd62961cf9f87f6c2b21d884d3515a7150a4a3fa9d014e5c12" +checksum = "95ccf091884470c4b3a80ad6daadbb2e7736611d631cbf0c9e603bb7dbcfdfd9" [[package]] name = "miniz_oxide" @@ -1636,23 +1883,13 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nb-connect" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1bb540dc6ef51cfe1916ec038ce7a620daf3a111e2502d745197cd53d6bca15" -dependencies = [ - "libc", - "socket2", -] - [[package]] name = "ndk" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" dependencies = [ - "bitflags 1.3.2", + "bitflags", "jni-sys", "ndk-sys", "num_enum", @@ -1679,18 +1916,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" dependencies = [ - "darling", + "darling 0.10.2", "proc-macro-crate 0.1.5", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "ndk-sys" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" [[package]] name = "new_debug_unreachable" @@ -1700,15 +1937,15 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" [[package]] name = "nix" -version = "0.17.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cc", - "cfg-if 0.1.10", + "cfg-if", "libc", - "void", + "memoffset", ] [[package]] @@ -1719,9 +1956,9 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "notify-rust" -version = "4.5.2" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2ca742cd7268b60c35828d318357f0b1bb9b82088e157ccf3013eb3ce70247" +checksum = "367e1355a950d3e758e414f3ca1b3981a57a2aa1fa3338eb0059f5b230b6ffa4" dependencies = [ "mac-notification-sys", "serde", @@ -1763,9 +2000,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -1773,24 +2010,23 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" +checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" dependencies = [ - "derivative", "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" +checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" dependencies = [ - "proc-macro-crate 1.0.0", + "proc-macro-crate 1.1.0", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] @@ -1800,6 +2036,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ "malloc_buf", + "objc_exception", ] [[package]] @@ -1813,6 +2050,15 @@ dependencies = [ "objc_id", ] +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + [[package]] name = "objc_id" version = "0.1.1" @@ -1824,15 +2070,21 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "opaque-debug" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "open" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46b233de7d83bc167fe43ae2dda3b5b84e80e09cceba581e4decb958a4896bf" +checksum = "176ee4b630d174d2da8241336763bb459281dddc0f4d87f72c3b1efc9a6109b7" dependencies = [ "pathdiff", "winapi", @@ -1840,12 +2092,12 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.36" +version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ - "bitflags 1.3.2", - "cfg-if 1.0.0", + "bitflags", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -1854,15 +2106,15 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.66" +version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ "autocfg", "cc", @@ -1871,11 +2123,21 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-stream" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44630c059eacfd6e08bdaa51b1db2ce33119caa4ddc1235e923109aa5f25ccb1" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "os_info" -version = "3.0.7" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac91020bfed8cc3f8aa450d4c3b5fa1d3373fc091c8a92009f3b27749d5a227" +checksum = "023df84d545ef479cf67fd2f4459a613585c9db4852c2fad12ab70587859d340" dependencies = [ "log", "serde", @@ -1884,9 +2146,9 @@ dependencies = [ [[package]] name = "os_pipe" -version = "0.9.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb233f06c2307e1f5ce2ecad9f8121cffbbee2c95428f44ea85222e460d0d213" +checksum = "0e3492ebca331b895fe23ed427dce2013d9b2e00c45964f12040b0db38b8ab27" dependencies = [ "libc", "winapi", @@ -1894,17 +2156,20 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "2.4.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] [[package]] name = "pango" -version = "0.14.3" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc88307d9797976ea62722ff2ec5de3fae279c6e20100ed3f49ca1a4bf3f96" +checksum = "79211eff430c29cc38c69e0ab54bc78fa1568121ca9737707eee7f92a8417a94" dependencies = [ - "bitflags 1.3.2", + "bitflags", "glib", "libc", "once_cell", @@ -1913,14 +2178,14 @@ dependencies = [ [[package]] name = "pango-sys" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe" +checksum = "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2" dependencies = [ - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] @@ -1931,9 +2196,9 @@ checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", @@ -1942,11 +2207,11 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "instant", "libc", "redox_syscall 0.2.10", @@ -1956,9 +2221,9 @@ dependencies = [ [[package]] name = "pathdiff" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877630b3de15c0b64cc52f659345724fbf6bdad9bd9566699fc53688f3c34a34" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "percent-encoding" @@ -1988,9 +2253,9 @@ dependencies = [ [[package]] name = "phf" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fc3db1018c4b59d7d582a739436478b6035138b6aecbce989fc91c3e98409f" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ "phf_macros 0.10.0", "phf_shared 0.10.0", @@ -2037,8 +2302,8 @@ dependencies = [ "phf_shared 0.8.0", "proc-macro-hack", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] @@ -2051,8 +2316,8 @@ dependencies = [ "phf_shared 0.10.0", "proc-macro-hack", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] @@ -2075,9 +2340,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -2087,9 +2352,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] name = "png" @@ -2097,7 +2362,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" dependencies = [ - "bitflags 1.3.2", + "bitflags", "deflate 0.7.20", "inflate", "num-iter", @@ -2109,7 +2374,7 @@ version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" dependencies = [ - "bitflags 1.3.2", + "bitflags", "crc32fast", "deflate 0.8.6", "miniz_oxide 0.3.7", @@ -2117,22 +2382,40 @@ dependencies = [ [[package]] name = "polling" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25" +checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "log", "wepoll-ffi", "winapi", ] +[[package]] +name = "pollster" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7" + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "precomputed-hash" @@ -2151,9 +2434,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" dependencies = [ "thiserror", "toml", @@ -2167,8 +2450,8 @@ checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", "version_check", ] @@ -2179,7 +2462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", - "quote 1.0.9", + "quote", "version_check", ] @@ -2189,32 +2472,20 @@ version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ - "unicode-xid 0.2.2", + "unicode-xid", ] [[package]] name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.9" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -2280,7 +2551,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.4", ] [[package]] @@ -2312,11 +2583,11 @@ dependencies = [ [[package]] name = "raw-window-handle" -version = "0.3.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +checksum = "fba75eee94a9d5273a68c9e1e105d9cffe1ef700532325788389e5a83e2522b7" dependencies = [ - "libc", + "cty", ] [[package]] @@ -2356,7 +2627,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] @@ -2376,7 +2647,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.4", "redox_syscall 0.2.10", ] @@ -2391,6 +2662,15 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.25" @@ -2408,24 +2688,42 @@ dependencies = [ [[package]] name = "rfd" -version = "0.4.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cede43618603a102f37bb58244534a33de7daa6a3b77f00277675eef5f8174fe" +checksum = "2aaf1d71ccd44689f7c2c72da1117fd8db71f72a76fe9b5c5dbb17ab903007e0" dependencies = [ + "ashpd", "block", "dispatch", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "gtk-sys", "js-sys", "lazy_static", + "log", "objc", "objc-foundation", "objc_id", + "pollster", "raw-window-handle", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "windows 0.30.0", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", "winapi", ] @@ -2450,17 +2748,26 @@ dependencies = [ "semver 0.11.0", ] +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.5", +] + [[package]] name = "rustversion" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "same-file" @@ -2495,24 +2802,24 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "security-framework" -version = "2.3.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.1", - "core-foundation-sys 0.8.2", + "bitflags", + "core-foundation", + "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "2.3.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" dependencies = [ - "core-foundation-sys 0.8.2", + "core-foundation-sys", "libc", ] @@ -2522,7 +2829,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cssparser", "derive_more", "fxhash", @@ -2547,9 +2854,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" [[package]] name = "semver-parser" @@ -2562,31 +2869,31 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.129" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.129" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" dependencies = [ - "itoa", + "itoa 1.0.1", "ryu", "serde", ] @@ -2598,25 +2905,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "serde_urlencoded" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "dtoa", - "itoa", + "form_urlencoded", + "itoa 1.0.1", + "ryu", "serde", - "url", ] [[package]] -name = "servo_arc" -version = "0.1.1" +name = "serde_with" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1e6ec4d8950e5b1e894eac0d360742f3b1407a6078a604a731c4b3f49cefbc" +dependencies = [ + "rustversion", + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" +dependencies = [ + "darling 0.13.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" dependencies = [ @@ -2624,11 +2976,46 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sha1" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + [[package]] name = "shared_child" -version = "0.3.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6be9f7d5565b1483af3e72975e2dee33879b3b86bd48c0929fccf6585d79e65a" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" dependencies = [ "libc", "winapi", @@ -2636,47 +3023,52 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" [[package]] name = "slab" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "smallvec" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "socket2" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", "winapi", ] [[package]] -name = "soup-sys" -version = "0.10.0" +name = "soup2-sys" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7adf08565630bbb71f955f11f8a68464817ded2703a3549747c235b58a13e" +checksum = "9f056675eda9a7417163e5f742bb119e8e1d385edd2ada8f7031a7230a3ec10a" dependencies = [ - "bitflags 1.3.2", - "gio-sys 0.10.1", - "glib-sys 0.10.1", - "gobject-sys 0.10.0", + "bitflags", + "gio-sys 0.14.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", "libc", - "pkg-config", - "system-deps 1.3.2", + "system-deps 5.0.0", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -2700,13 +3092,14 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_cache" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a" +checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" dependencies = [ "lazy_static", "new_debug_unreachable", - "phf_shared 0.8.0", + "parking_lot", + "phf_shared 0.10.0", "precomputed-hash", "serde", ] @@ -2720,7 +3113,7 @@ dependencies = [ "phf_generator 0.8.0", "phf_shared 0.8.0", "proc-macro2", - "quote 1.0.9", + "quote", ] [[package]] @@ -2735,18 +3128,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "strum" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca6e4730f517e041e547ffe23d29daab8de6b73af4b6ae2a002108169f5e7da" - -[[package]] -name = "strum" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b" - [[package]] name = "strum" version = "0.21.0" @@ -2754,127 +3135,134 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" [[package]] -name = "strum_macros" -version = "0.8.0" +name = "strum" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3384590878eb0cab3b128e844412e2d010821e7e091211b9d87324173ada7db8" +checksum = "f7ac893c7d471c8a21f31cfe213ec4f6d9afeed25537c772e08ef3f005f8729e" dependencies = [ - "quote 0.3.15", - "syn 0.11.11", + "strum_macros 0.22.0", ] [[package]] name = "strum_macros" -version = "0.18.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "strum_macros" -version = "0.21.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +checksum = "339f799d8b549e3744c7ac7feb216383e4005d94bdb22561b3ab8f3b808ae9fb" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] -name = "syn" -version = "0.11.11" +name = "subtle" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid 0.0.4", -] +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.75" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", - "quote 1.0.9", - "unicode-xid 0.2.2", + "quote", + "unicode-xid", ] [[package]] -name = "synom" -version = "0.11.3" +name = "sys-info" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" dependencies = [ - "unicode-xid 0.0.4", + "cc", + "libc", ] [[package]] name = "system-deps" -version = "1.3.2" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b" +checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" dependencies = [ - "heck", + "anyhow", + "cfg-expr 0.8.1", + "heck 0.3.3", + "itertools", "pkg-config", - "strum 0.18.0", - "strum_macros 0.18.0", + "strum 0.21.0", + "strum_macros 0.21.1", "thiserror", "toml", - "version-compare 0.0.10", + "version-compare 0.0.11", ] [[package]] name = "system-deps" -version = "3.2.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" dependencies = [ - "anyhow", - "cfg-expr", - "heck", - "itertools", + "cfg-expr 0.9.1", + "heck 0.3.3", "pkg-config", - "strum 0.21.0", - "strum_macros 0.21.1", - "thiserror", "toml", "version-compare 0.0.11", ] +[[package]] +name = "system-deps" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad3a97fdef3daf935d929b3e97e5a6a680cd4622e40c2941ca0875d6566416f8" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.4.0", + "pkg-config", + "toml", + "version-compare 0.1.0", +] + [[package]] name = "tao" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa57de7c282b68f8906278543a724ed8f5a2568f069dd0cc05fc10d1f07036b" +checksum = "53d2bba60298cbc0ff0651fe5a0bdfb73438b91231f700dcc8d539548237cae7" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cairo-rs", "cc", "cocoa", - "core-foundation 0.9.1", - "core-graphics 0.22.2", - "core-video-sys", + "core-foundation", + "core-graphics", "crossbeam-channel", "dispatch", "gdk", "gdk-pixbuf", "gdk-sys", + "gdkx11-sys", "gio", "glib", - "glib-sys 0.14.0", + "glib-sys 0.15.5", "gtk", "instant", "lazy_static", + "libappindicator", "libc", "log", "ndk", @@ -2885,17 +3273,30 @@ dependencies = [ "raw-window-handle", "scopeguard", "serde", - "tauri-libappindicator", + "tao-core-video-sys", "unicode-segmentation", - "winapi", + "windows 0.30.0", + "windows_macros", "x11-dl", ] +[[package]] +name = "tao-core-video-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271450eb289cb4d8d0720c6ce70c72c8c858c93dd61fc625881616752e6b98f6" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "objc", +] + [[package]] name = "tar" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" dependencies = [ "filetime", "libc", @@ -2918,6 +3319,7 @@ dependencies = [ "futures", "futures-lite", "glib", + "glob", "gtk", "http", "ignore", @@ -2930,11 +3332,13 @@ dependencies = [ "percent-encoding", "rand 0.8.4", "raw-window-handle", + "regex", "rfd", - "semver 1.0.4", + "semver 1.0.5", "serde", "serde_json", "serde_repr", + "serialize-to-javascript", "shared_child", "state", "tar", @@ -2955,9 +3359,9 @@ name = "tauri-build" version = "1.0.0-beta.4" dependencies = [ "anyhow", - "proc-macro2", - "quote 1.0.9", + "cargo_toml", "serde_json", + "tauri-codegen", "tauri-utils", "winres", ] @@ -2966,50 +3370,31 @@ dependencies = [ name = "tauri-codegen" version = "1.0.0-beta.4" dependencies = [ + "base64", "blake3", - "kuchiki", "proc-macro2", - "quote 1.0.9", + "quote", "regex", "serde", "serde_json", + "sha2", "tauri-utils", "thiserror", + "uuid", "walkdir", "zstd", ] -[[package]] -name = "tauri-libappindicator" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af6057bf1b03141122da159ad4136d8a474240db59d81af1840d7fce3b819ef2" -dependencies = [ - "glib", - "gtk", - "gtk-sys", - "log", - "tauri-libappindicator-sys", -] - -[[package]] -name = "tauri-libappindicator-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c40a817171cf25d69dd31e3fa9360fd4367e54948e30f3356962f0b1d9f23dad" -dependencies = [ - "gtk-sys", - "pkg-config", -] - [[package]] name = "tauri-macros" version = "1.0.0-beta.5" dependencies = [ + "heck 0.4.0", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", "tauri-codegen", + "tauri-utils", ] [[package]] @@ -3025,7 +3410,8 @@ dependencies = [ "tauri-utils", "thiserror", "uuid", - "winapi", + "webview2-com", + "windows 0.30.0", ] [[package]] @@ -3039,7 +3425,8 @@ dependencies = [ "tauri-runtime", "tauri-utils", "uuid", - "winapi", + "webview2-com", + "windows 0.30.0", "wry", ] @@ -3047,27 +3434,37 @@ dependencies = [ name = "tauri-utils" version = "1.0.0-beta.3" dependencies = [ + "aes-gcm", + "ctor", + "glob", + "heck 0.4.0", "html5ever", + "json-patch", "kuchiki", - "phf 0.10.0", + "once_cell", + "phf 0.10.1", "proc-macro2", - "quote 1.0.9", + "quote", + "ring", "serde", "serde_json", + "serde_with", + "serialize-to-javascript", "thiserror", "url", + "walkdir", "zstd", ] [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", + "fastrand", "libc", - "rand 0.8.4", "redox_syscall 0.2.10", "remove_dir_all", "winapi", @@ -3095,12 +3492,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.12.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" -dependencies = [ - "unicode-width", -] +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" [[package]] name = "thin-slice" @@ -3110,29 +3504,29 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "thread_local" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" dependencies = [ "once_cell", ] @@ -3149,9 +3543,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -3164,11 +3558,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.10.1" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92036be488bb6594459f2e03b60e42df6f937fe6ca5c5ffdcb539c6b84dc40f5" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" dependencies = [ - "autocfg", "bytes", "memchr", "num_cpus", @@ -3184,11 +3577,82 @@ dependencies = [ "serde", ] +[[package]] +name = "tracing" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d8d93354fe2a8e50d5953f5ae2e47a3fc2ef03292e7ea46e3cc38f549525fb9" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8276d9a4a3a558d7b7ad5303ad50b53d58264641b82914b7ada36bd762e7a716" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +dependencies = [ + "lazy_static", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74786ce43333fcf51efe947aed9718fbe46d5c7328ec3f1029e818083966d9aa" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "treediff" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" +dependencies = [ + "serde_json", +] + [[package]] name = "typenum" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "ucd-trie" @@ -3198,9 +3662,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "unicode-bidi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-normalization" @@ -3213,27 +3677,31 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] -name = "unicode-width" -version = "0.1.8" +name = "unicode-xid" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] -name = "unicode-xid" -version = "0.0.4" +name = "universal-hash" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "untrusted" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" @@ -3260,26 +3728,20 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.4", ] [[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vec_map" -version = "0.8.2" +name = "valuable" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] -name = "version-compare" -version = "0.0.10" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version-compare" @@ -3288,16 +3750,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" [[package]] -name = "version_check" -version = "0.9.3" +name = "version-compare" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" [[package]] -name = "void" -version = "1.0.2" +name = "version_check" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" @@ -3330,36 +3792,36 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" dependencies = [ "bumpalo", "lazy_static", "log", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.26" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" +checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -3367,38 +3829,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" dependencies = [ - "quote 1.0.9", + "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" [[package]] name = "web-sys" -version = "0.3.53" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" dependencies = [ "js-sys", "wasm-bindgen", @@ -3406,19 +3868,19 @@ dependencies = [ [[package]] name = "webkit2gtk" -version = "0.14.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e47b7f870883fc21612d2a51b74262f7f2cc5371f1621370817292a35300a9" +checksum = "2cbd39499e917de9dad36eb11c09f665eb984d432638ae7971feed98eb96df88" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cairo-rs", "gdk", "gdk-sys", "gio", - "gio-sys 0.14.0", + "gio-sys 0.15.5", "glib", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "gtk", "gtk-sys", "javascriptcore-rs", @@ -3429,48 +3891,62 @@ dependencies = [ [[package]] name = "webkit2gtk-sys" -version = "0.14.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66ccc9f0cb4de7c3b92376a5bf64e7ddffb33852f092721731a039ec38dda98" +checksum = "ddcce6f1e0fc7715d651dba29875741509f5fc12f4e2976907272a74405f2b01" dependencies = [ "atk-sys", - "bitflags 1.3.2", + "bitflags", "cairo-sys-rs", "gdk-pixbuf-sys", "gdk-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "gtk-sys", "javascriptcore-rs-sys", "libc", "pango-sys", "pkg-config", - "soup-sys", - "system-deps 3.2.0", + "soup2-sys", + "system-deps 5.0.0", ] [[package]] -name = "webview2" -version = "0.1.1" +name = "webview2-com" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fab1ccfdabb098b047293c8d496c1914d1c654b68fdaa3bb77cfa47c4bca2c7" +checksum = "1975ce3573344c099935fe3903f1708dac69efe8539f1efee3ae54d8f9315fbb" dependencies = [ - "com", - "once_cell", - "webview2-sys", - "widestring", - "winapi", + "webview2-com-macros", + "webview2-com-sys", + "windows 0.30.0", + "windows_macros", ] [[package]] -name = "webview2-sys" -version = "0.1.0" +name = "webview2-com-macros" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5288cef1e0cbcf7a0b961e6271e33589b8989c80b2e11078504e989b5346ff" +checksum = "1515c6c82fcee93f6edaacc72c8e233dbe4ff3ca569dce1901dfc36c404a3e99" dependencies = [ - "com", - "winapi", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "webview2-com-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a746838a94b7391f707209a246e3436d81d1e71832126a65a897d3ee5511040" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows 0.30.0", + "windows-bindgen", ] [[package]] @@ -3482,17 +3958,11 @@ dependencies = [ "cc", ] -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - [[package]] name = "wildmatch" -version = "1.1.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" +checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" [[package]] name = "winapi" @@ -3526,44 +3996,156 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "winres" -version = "0.1.11" +name = "windows" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4fb510bbfe5b8992ff15f77a2e6fe6cf062878f0eda00c0f44963a807ca5dc" +checksum = "a9f39345ae0c8ab072c0ac7fe8a8b411636aa34f89be19ddd0d9226544f13944" dependencies = [ - "toml", + "windows_i686_gnu 0.24.0", + "windows_i686_msvc 0.24.0", + "windows_x86_64_gnu 0.24.0", + "windows_x86_64_msvc 0.24.0", ] [[package]] -name = "winrt" -version = "0.4.0" +name = "windows" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30cba82e22b083dc5a422c2ee77e20dc7927271a0dc981360c57c1453cb48d" +checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0" dependencies = [ - "winapi", + "windows_aarch64_msvc", + "windows_i686_gnu 0.30.0", + "windows_i686_msvc 0.30.0", + "windows_x86_64_gnu 0.30.0", + "windows_x86_64_msvc 0.30.0", +] + +[[package]] +name = "windows-bindgen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "944c545fcae9dd66488308f8b69aa3ba34f53714416ecfcdcbbfa4b6821e27c6" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca" + +[[package]] +name = "windows_gen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30dff4d91d22520628bb94b66f2bb313cb16a09a515a32320a84a1b449bc94c0" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_i686_gnu" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0866510a3eca9aed73a077490bbbf03e5eaac4e1fd70849d89539e5830501fd" + +[[package]] +name = "windows_i686_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8" + +[[package]] +name = "windows_i686_msvc" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf0ffed56b7e9369a29078d2ab3aaeceea48eb58999d2cff3aa2494a275b95c6" + +[[package]] +name = "windows_i686_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6" + +[[package]] +name = "windows_macros" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ae44ab917e9005fe710d99d52d227ca0164b10a09be90649142cc3fab825d3" +dependencies = [ + "syn", + "windows_gen", + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_quote" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71f02c51a77e6248c1206aaa920802c32d50a05205e229b118d7f3afd3036667" + +[[package]] +name = "windows_reader" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e44e6df0da993cda589c5ac852272fbb2a0ead67a031a017dd3eac11528a2d72" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384a173630588044205a2993b6864a2f56e5a8c1e7668c07b93ec18cf4888dc4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd8f062d8ca5446358159d79a90be12c543b3a965c847c8f3eedf14b321d399" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1" + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", ] [[package]] name = "winrt-notification" -version = "0.2.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57790eb281688a4682dab44df2a1ba8b78373233bd71cb291c3e75fecb1a01c4" +checksum = "007a0353840b23e0c6dc73e5b962ff58ed7f6bc9ceff3ce7fe6fbad8d496edf4" dependencies = [ - "strum 0.8.0", - "strum_macros 0.8.0", - "winapi", - "winrt", + "strum 0.22.0", + "windows 0.24.0", "xml-rs", ] [[package]] name = "wry" -version = "0.12.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9549393a3917b5303277abb0267f8eecf9fd629b25f1c04e5284aa58b61915" +checksum = "194b2750d8fe10fef189af5e2ca09e56cb8c5458a365d2b32842b024351f58c9" dependencies = [ "cocoa", - "core-graphics 0.22.2", + "core-graphics", "gdk", "gio", "glib", @@ -3576,25 +4158,35 @@ dependencies = [ "once_cell", "serde", "serde_json", + "sys-info", "tao", "thiserror", "url", "webkit2gtk", "webkit2gtk-sys", - "webview2", - "webview2-sys", - "winapi", + "webview2-com", + "windows 0.30.0", + "windows_macros", +] + +[[package]] +name = "x11" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd0565fa8bfba8c5efe02725b14dff114c866724eff2cfd44d76cea74bcd87a" +dependencies = [ + "libc", + "pkg-config", ] [[package]] name = "x11-dl" -version = "2.18.5" +version = "2.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" dependencies = [ "lazy_static", "libc", - "maybe-uninit", "pkg-config", ] @@ -3609,46 +4201,69 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.6.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621" -dependencies = [ - "bitflags 0.9.1", -] +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" [[package]] name = "zbus" -version = "1.9.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2326acc379a3ac4e34b794089f5bdb17086bf29a5fdf619b7b4cc772dc2e9dad" +checksum = "7bb86f3d4592e26a48b2719742aec94f8ae6238ebde20d98183ee185d1275e9a" dependencies = [ + "async-broadcast", + "async-channel", + "async-executor", "async-io", + "async-lock", + "async-recursion", + "async-task", + "async-trait", "byteorder", "derivative", "enumflags2", - "fastrand", - "futures", - "nb-connect", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "lazy_static", "nix", "once_cell", - "polling", - "scoped-tls", + "ordered-stream", + "rand 0.8.4", "serde", "serde_repr", + "sha1", + "static_assertions", + "winapi", "zbus_macros", + "zbus_names", "zvariant", ] [[package]] name = "zbus_macros" -version = "1.9.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a482c56029e48681b89b92b5db3c446db0915e8dd1052c0328a574eda38d5f93" +checksum = "36823cc10fddc3c6b19f048903262dacaf8274170e9a255784bdd8b4570a8040" dependencies = [ - "proc-macro-crate 0.1.5", + "proc-macro-crate 1.1.0", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "regex", + "syn", +] + +[[package]] +name = "zbus_names" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45dfcdcf87b71dad505d30cc27b1b7b88a64b6d1c435648f48f9dbc1fdc4b7e1" +dependencies = [ + "serde", + "static_assertions", + "zvariant", ] [[package]] @@ -3667,18 +4282,18 @@ dependencies = [ [[package]] name = "zstd" -version = "0.9.0+zstd.1.5.0" +version = "0.10.0+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07749a5dc2cb6b36661290245e350f15ec3bbb304e493db54a1d354480522ccd" +checksum = "3b1365becbe415f3f0fcd024e2f7b45bacfb5bdd055f0dc113571394114e7bdd" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "4.1.1+zstd.1.5.0" +version = "4.1.4+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91c90f2c593b003603e5e0493c837088df4469da25aafff8bce42ba48caf079" +checksum = "2f7cd17c9af1a4d6c24beb1cc54b17e2ef7b593dc92f19e9d9acad8b182bbaee" dependencies = [ "libc", "zstd-sys", @@ -3686,9 +4301,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "1.6.1+zstd.1.5.0" +version = "1.6.3+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615120c7a2431d16cf1cf979e7fc31ba7a5b5e5707b29c8a99e5dbf8a8392a33" +checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8" dependencies = [ "cc", "libc", @@ -3696,12 +4311,13 @@ dependencies = [ [[package]] name = "zvariant" -version = "2.8.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4b785b8b32b0f8433b4474e6bb4ea77b37c1960e84d7598e01dd199b2b23ef" +checksum = "49ea5dc38b2058fae6a5b79009388143dadce1e91c26a67f984a0fc0381c8033" dependencies = [ "byteorder", "enumflags2", + "libc", "serde", "static_assertions", "zvariant_derive", @@ -3709,12 +4325,12 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "2.8.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42af4ee88fb928781391216c34be77ec7cdb3546042b2947ce38d86aa5f37dd" +checksum = "8c2cecc5a61c2a053f7f653a24cd15b3b0195d7f7ddb5042c837fb32e161fb7a" dependencies = [ - "proc-macro-crate 1.0.0", + "proc-macro-crate 1.1.0", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] diff --git a/examples/api/src-tauri/Cargo.toml b/examples/api/src-tauri/Cargo.toml index 49e24b6b6ef1..221b474246c7 100644 --- a/examples/api/src-tauri/Cargo.toml +++ b/examples/api/src-tauri/Cargo.toml @@ -2,17 +2,26 @@ name = "api" version = "0.1.0" description = "An example Tauri Application showcasing the api" -edition = "2018" +edition = "2021" +rust-version = "1.57" license = "Apache-2.0 OR MIT" [build-dependencies] -tauri-build = { path = "../../../core/tauri-build" } +tauri-build = { path = "../../../core/tauri-build", features = ["isolation"] } [dependencies] serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } -tauri = { path = "../../../core/tauri", features = ["api-all", "cli", "system-tray", "updater"] } +tauri = { path = "../../../core/tauri", features = ["api-all", "cli", "isolation", "macos-private-api", "system-tray", "updater"] } [features] default = [ "custom-protocol" ] custom-protocol = [ "tauri/custom-protocol" ] + +# default to small, optimized release binaries +[profile.release] +panic = "abort" +codegen-units = 1 +lto = true +incremental = false +opt-level = "s" diff --git a/examples/api/src-tauri/locales/pt-BR.wxl b/examples/api/src-tauri/locales/pt-BR.wxl new file mode 100644 index 000000000000..8f58c07435de --- /dev/null +++ b/examples/api/src-tauri/locales/pt-BR.wxl @@ -0,0 +1,6 @@ + + Executar Tauri API + Uma versão mais recente de Tauri API está instalada. + Adiciona o caminho do executável de Tauri API para a variável de ambiente PATH. Isso permite Tauri API ser executado pela linha de comando. + Instala Tauri API. + diff --git a/examples/api/src-tauri/src/cmd.rs b/examples/api/src-tauri/src/cmd.rs index 8cad4d1dc63f..525246f3283b 100644 --- a/examples/api/src-tauri/src/cmd.rs +++ b/examples/api/src-tauri/src/cmd.rs @@ -6,6 +6,7 @@ use serde::Deserialize; use tauri::command; #[derive(Debug, Deserialize)] +#[allow(dead_code)] pub struct RequestBody { id: i32, name: String, diff --git a/examples/api/src-tauri/src/main.rs b/examples/api/src-tauri/src/main.rs index 64c570467d44..8da65e657182 100644 --- a/examples/api/src-tauri/src/main.rs +++ b/examples/api/src-tauri/src/main.rs @@ -12,15 +12,15 @@ mod menu; #[cfg(target_os = "linux")] use std::path::PathBuf; +use std::sync::atomic::{AtomicBool, Ordering}; use serde::{Deserialize, Serialize}; use tauri::{ - api::dialog::ask, async_runtime, http::ResponseBuilder, CustomMenuItem, Event, - GlobalShortcutManager, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowBuilder, - WindowUrl, + api::dialog::ask, http::ResponseBuilder, CustomMenuItem, GlobalShortcutManager, Manager, + RunEvent, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowBuilder, WindowUrl, }; -#[derive(Serialize)] +#[derive(Clone, Serialize)] struct Reply { data: String, } @@ -43,8 +43,27 @@ async fn menu_toggle(window: tauri::Window) { } fn main() { + let tray_menu1 = SystemTrayMenu::new() + .add_item(CustomMenuItem::new("toggle", "Toggle")) + .add_item(CustomMenuItem::new("new", "New window")) + .add_item(CustomMenuItem::new("icon_1", "Tray Icon 1")) + .add_item(CustomMenuItem::new("icon_2", "Tray Icon 2")) + .add_item(CustomMenuItem::new("switch_menu", "Switch Menu")) + .add_item(CustomMenuItem::new("exit_app", "Quit")); + let tray_menu2 = SystemTrayMenu::new() + .add_item(CustomMenuItem::new("toggle", "Toggle")) + .add_item(CustomMenuItem::new("new", "New window")) + .add_item(CustomMenuItem::new("switch_menu", "Switch Menu")) + .add_item(CustomMenuItem::new("exit_app", "Quit")); + let is_menu1 = AtomicBool::new(true); + #[allow(unused_mut)] let mut app = tauri::Builder::default() + .setup(|app| { + #[cfg(debug_assertions)] + app.get_window("main").unwrap().open_devtools(); + Ok(()) + }) .on_page_load(|window, _| { let window_ = window.clone(); window.listen("js-event", move |event| { @@ -80,17 +99,8 @@ fn main() { .on_menu_event(|event| { println!("{:?}", event.menu_item_id()); }) - .system_tray( - SystemTray::new().with_menu( - SystemTrayMenu::new() - .add_item(CustomMenuItem::new("toggle", "Toggle")) - .add_item(CustomMenuItem::new("new", "New window")) - .add_item(CustomMenuItem::new("icon_1", "Tray Icon 1")) - .add_item(CustomMenuItem::new("icon_2", "Tray Icon 2")) - .add_item(CustomMenuItem::new("exit_app", "Quit")), - ), - ) - .on_system_tray_event(|app, event| match event { + .system_tray(SystemTray::new().with_menu(tray_menu1.clone())) + .on_system_tray_event(move |app, event| match event { SystemTrayEvent::LeftClick { position: _, size: _, @@ -118,15 +128,17 @@ fn main() { }; item_handle.set_title(new_title).unwrap(); } - "new" => app - .create_window( - "new", - WindowUrl::App("index.html".into()), - |window_builder, webview_attributes| { - (window_builder.title("Tauri"), webview_attributes) - }, - ) - .unwrap(), + "new" => { + app + .create_window( + "new", + WindowUrl::App("index.html".into()), + |window_builder, webview_attributes| { + (window_builder.title("Tauri"), webview_attributes) + }, + ) + .unwrap(); + } #[cfg(target_os = "macos")] "icon_1" => { app.tray_handle().set_icon_as_template(true).unwrap(); @@ -177,6 +189,18 @@ fn main() { include_bytes!("../../../.icons/icon.ico").to_vec(), )) .unwrap(), + "switch_menu" => { + let flag = is_menu1.load(Ordering::Relaxed); + app + .tray_handle() + .set_menu(if flag { + tray_menu2.clone() + } else { + tray_menu1.clone() + }) + .unwrap(); + is_menu1.store(!flag, Ordering::Relaxed); + } _ => {} } } @@ -195,48 +219,43 @@ fn main() { app.run(|app_handle, e| match e { // Application is ready (triggered only once) - Event::Ready => { + RunEvent::Ready => { let app_handle = app_handle.clone(); - // launch a new thread so it doesnt block any channel - async_runtime::spawn(async move { - let app_handle = app_handle.clone(); - app_handle - .global_shortcut_manager() - .register("CmdOrCtrl+1", move || { - let app_handle = app_handle.clone(); - let window = app_handle.get_window("main").unwrap(); - window.set_title("New title!").unwrap(); - }) - .unwrap(); - }); + app_handle + .global_shortcut_manager() + .register("CmdOrCtrl+1", move || { + let app_handle = app_handle.clone(); + let window = app_handle.get_window("main").unwrap(); + window.set_title("New title!").unwrap(); + }) + .unwrap(); } // Triggered when a window is trying to close - Event::CloseRequested { label, api, .. } => { + RunEvent::CloseRequested { label, api, .. } => { let app_handle = app_handle.clone(); let window = app_handle.get_window(&label).unwrap(); // use the exposed close api, and prevent the event loop to close api.prevent_close(); // ask the user if he wants to quit - // we need to run this on another thread because this is the event loop callback handler - // and the dialog API needs to communicate with the event loop. - std::thread::spawn(move || { - ask( - Some(&window), - "Tauri API", - "Are you sure that you want to close this window?", - move |answer| { - if answer { + ask( + Some(&window), + "Tauri API", + "Are you sure that you want to close this window?", + move |answer| { + if answer { + // .close() cannot be called on the main thread + std::thread::spawn(move || { app_handle.get_window(&label).unwrap().close().unwrap(); - } - }, - ); - }); + }); + } + }, + ); } // Keep the event loop running even if all windows are closed // This allow us to catch system tray events when there is no window - Event::ExitRequested { api, .. } => { + RunEvent::ExitRequested { api, .. } => { api.prevent_exit(); } _ => {} diff --git a/examples/api/src-tauri/src/menu.rs b/examples/api/src-tauri/src/menu.rs index a6cc9a62afbb..026f3b7a470c 100644 --- a/examples/api/src-tauri/src/menu.rs +++ b/examples/api/src-tauri/src/menu.rs @@ -17,7 +17,7 @@ pub fn get_menu() -> Menu { } // create a submenu - let my_sub_menu = Menu::new().add_item(disable_item); + let my_sub_menu = Menu::with_items([disable_item.into()]); let my_app_menu = Menu::new() .add_native_item(MenuItem::Copy) diff --git a/examples/api/src-tauri/tauri.conf.json b/examples/api/src-tauri/tauri.conf.json index 6e7f66d1b4cc..612a21735763 100644 --- a/examples/api/src-tauri/tauri.conf.json +++ b/examples/api/src-tauri/tauri.conf.json @@ -1,15 +1,22 @@ { "build": { - "distDir": "../public", - "devPath": "../public", + "distDir": "../dist", + "devPath": "http://localhost:5000", "beforeDevCommand": "yarn dev", "beforeBuildCommand": "yarn build" }, "package": { "productName": "Tauri API", - "version": "0.1.0" + "version": "../package.json" }, "tauri": { + "pattern": { + "use": "isolation", + "options": { + "dir": "../isolation-dist/" + } + }, + "macOSPrivateApi": true, "cli": { "description": "Tauri API example", "args": [ @@ -55,7 +62,17 @@ "../../.icons/128x128@2x.png", "../../.icons/icon.icns", "../../.icons/icon.ico" - ] + ], + "windows": { + "wix": { + "language": { + "en-US": {}, + "pt-BR": { + "localePath": "locales/pt-BR.wxl" + } + } + } + } }, "updater": { "active": true, @@ -66,7 +83,29 @@ ] }, "allowlist": { - "all": true + "all": true, + "fs": { + "scope": ["$APP/db", "$DOWNLOAD/**", "$RESOURCE/**"] + }, + "shell": { + "scope": [ + { + "name": "sh", + "cmd": "sh" + }, + { + "name": "cmd", + "cmd": "cmd" + } + ] + }, + "protocol": { + "asset": true, + "assetScope": ["$RESOURCE/**", "$APP/**"] + }, + "http": { + "scope": ["https://jsonplaceholder.typicode.com/todos/*"] + } }, "windows": [ { @@ -75,7 +114,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: asset: customprotocol: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'" + "csp": "default-src 'self' customprotocol: img-src: 'self'; style-src 'unsafe-inline' 'self' https://fonts.googleapis.com; img-src 'self' asset: https://asset.localhost blob: data:; font-src https://fonts.gstatic.com" }, "systemTray": { "iconPath": "../../.icons/tray_icon_with_transparency.png", diff --git a/examples/api/src/App.svelte b/examples/api/src/App.svelte index 2685e46b9772..cf966d5aaeec 100644 --- a/examples/api/src/App.svelte +++ b/examples/api/src/App.svelte @@ -90,32 +90,35 @@ let selected = views[0]; let responses = writable([]); - let response = '' function select(view) { selected = view; } function onMessage(value) { - responses.update(r => [`[${new Date().toLocaleTimeString()}]` + ': ' + (typeof value === "string" ? value : JSON.stringify(value)), ...r]) + responses.update(r => [{ text: `[${new Date().toLocaleTimeString()}]` + ': ' + (typeof value === "string" ? value : JSON.stringify(value)) }, ...r]) + } + + // this function is renders HTML without sanitizing it so it's insecure + // we only use it with our own input data + function insecureRenderHtml(html) { + responses.update(r => [{ html }, ...r]) + } + + function clear() { + responses.update(() => []); } function onLogoClick() { open("https://tauri.studio/"); } - - onMount(() => { - responses.subscribe(r => { - response = r.join('\n') - }) - })
    -
    + + diff --git a/examples/api/src/components/Dialog.svelte b/examples/api/src/components/Dialog.svelte index 0d3fad0fca1e..ed065df9a789 100644 --- a/examples/api/src/components/Dialog.svelte +++ b/examples/api/src/components/Dialog.svelte @@ -3,6 +3,7 @@ import { readBinaryFile } from "@tauri-apps/api/fs"; export let onMessage; + export let insecureRenderHtml; let defaultPath = null; let filter = null; let multiple = false; @@ -22,6 +23,7 @@ function openDialog() { open({ + title: 'My wonderful open dialog', defaultPath, filters: filter ? [ @@ -51,7 +53,7 @@ new Uint8Array(response), function (base64) { var src = "data:image/png;base64," + base64; - onMessage(''); + insecureRenderHtml(''); } ); } else { @@ -69,6 +71,7 @@ function saveDialog() { save({ + title: 'My wonderful save dialog', defaultPath, filters: filter ? [ diff --git a/examples/api/src/components/FileSystem.svelte b/examples/api/src/components/FileSystem.svelte index 67b2196182f3..e128249ab065 100644 --- a/examples/api/src/components/FileSystem.svelte +++ b/examples/api/src/components/FileSystem.svelte @@ -3,6 +3,7 @@ import { convertFileSrc } from "@tauri-apps/api/tauri"; export let onMessage; + export let insecureRenderHtml; let pathToRead = ""; let img; @@ -42,12 +43,12 @@ if (pathToRead.includes(".png") || pathToRead.includes(".jpg")) { arrayBufferToBase64(new Uint8Array(response), function (base64) { const src = "data:image/png;base64," + base64; - onMessage(''); + insecureRenderHtml(''); }); } else { const value = String.fromCharCode.apply(null, response); - onMessage( - '' + insecureRenderHtml( + '' ); setTimeout(() => { const fileInput = document.getElementById("file-response"); diff --git a/examples/api/src/components/Http.svelte b/examples/api/src/components/Http.svelte index 9f1e2603f50a..2dc92169aca6 100644 --- a/examples/api/src/components/Http.svelte +++ b/examples/api/src/components/Http.svelte @@ -7,7 +7,10 @@ export let onMessage; async function makeHttpRequest() { - const client = await getClient(); + const client = await getClient().catch(e => { + onMessage(e) + throw e + }); let method = httpMethod || "GET"; let url = httpUrl || ""; @@ -47,8 +50,15 @@ id="request-body" placeholder="Request body" rows="5" - style="width:100%;margin-right:10px;font-size:12px" bind:value={httpBody} /> + + diff --git a/examples/api/src/components/Notifications.svelte b/examples/api/src/components/Notifications.svelte index a8311a4e5fcf..698b5904ea2a 100644 --- a/examples/api/src/components/Notifications.svelte +++ b/examples/api/src/components/Notifications.svelte @@ -1,12 +1,15 @@ - diff --git a/examples/api/src/components/Shell.svelte b/examples/api/src/components/Shell.svelte index fe1481c09f93..5d289874d4ab 100644 --- a/examples/api/src/components/Shell.svelte +++ b/examples/api/src/components/Shell.svelte @@ -63,6 +63,12 @@
    - +
    + + diff --git a/examples/api/src/components/WebRTC.svelte b/examples/api/src/components/WebRTC.svelte index 26b7c5c2e00d..5e8d178e975e 100644 --- a/examples/api/src/components/WebRTC.svelte +++ b/examples/api/src/components/WebRTC.svelte @@ -47,5 +47,7 @@

    Not available for Linux

    - +
    diff --git a/examples/api/src/components/Window.svelte b/examples/api/src/components/Window.svelte index c691ea1a6eb4..3a06dbedf43d 100644 --- a/examples/api/src/components/Window.svelte +++ b/examples/api/src/components/Window.svelte @@ -1,10 +1,9 @@
    @@ -171,11 +216,61 @@
    -
    +
    +
    +
    +
    Inner Size
    + Width: {innerSize.width} + Height: {innerSize.height} +
    +
    +
    Outer Size
    + Width: {outerSize.width} + Height: {outerSize.height} +
    +
    +
    +
    +
    Inner Logical Size
    + Width: {innerSize.toLogical(scaleFactor).width} + Height: {innerSize.toLogical(scaleFactor).height} +
    +
    +
    Outer Logical Size
    + Width: {outerSize.toLogical(scaleFactor).width} + Height: {outerSize.toLogical(scaleFactor).height} +
    +
    +
    +
    +
    Inner Position
    + x: {innerPosition.x} + y: {innerPosition.y} +
    +
    +
    Outer Position
    + x: {outerPosition.x} + y: {outerPosition.y} +
    +
    +
    +
    +
    Inner Logical Position
    + x: {innerPosition.toLogical(scaleFactor).x} + y: {innerPosition.toLogical(scaleFactor).y} +
    +
    +
    Outer Logical Position
    + x: {outerPosition.toLogical(scaleFactor).x} + y: {outerPosition.toLogical(scaleFactor).y} +
    +
    +
    +
    -
    +
    @@ -183,6 +278,10 @@ diff --git a/examples/api/vite.config.js b/examples/api/vite.config.js new file mode 100644 index 000000000000..8258931bd87d --- /dev/null +++ b/examples/api/vite.config.js @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()], + build: { + rollupOptions: { + output: { + entryFileNames: `assets/[name].js`, + chunkFileNames: `assets/[name].js`, + assetFileNames: `assets/[name].[ext]` + } + } + }, + server: { + fs: { + allow: ['.', '../../tooling/api/dist'] + } + } +}) diff --git a/examples/api/yarn.lock b/examples/api/yarn.lock index df48d6fa5cd1..912261b42fe7 100644 --- a/examples/api/yarn.lock +++ b/examples/api/yarn.lock @@ -2,240 +2,152 @@ # yarn lockfile v1 -"@babel/code-frame@^7.10.4": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" - integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== +"@rollup/pluginutils@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec" + integrity sha512-clDjivHqWGXi7u+0d2r2sBi4Ie6VLEAzWMIkvJLnDmxoOhBYOTfzGbOQBA32THHm11/LiJbd01tJUpJsbshSWQ== dependencies: - "@babel/highlight" "^7.12.13" - -"@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== - -"@babel/highlight@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" - integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@polka/url@^1.0.0-next.9": - version "1.0.0-next.11" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" - integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== - -"@rollup/plugin-commonjs@17.1.0": - version "17.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz#757ec88737dffa8aa913eb392fade2e45aef2a2d" - integrity sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew== - dependencies: - "@rollup/pluginutils" "^3.1.0" - commondir "^1.0.1" estree-walker "^2.0.1" - glob "^7.1.6" - is-reference "^1.2.1" - magic-string "^0.25.7" - resolve "^1.17.0" - -"@rollup/plugin-node-resolve@11.2.0": - version "11.2.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.0.tgz#a5ab88c35bb7622d115f44984dee305112b6f714" - integrity sha512-qHjNIKYt5pCcn+5RUBQxK8krhRvf1HnyVgUCcFFcweDS7fhkOLZeYh0mhHK6Ery8/bb9tvN/ubPzmfF0qjDCTA== - dependencies: - "@rollup/pluginutils" "^3.1.0" - "@types/resolve" "1.17.1" - builtin-modules "^3.1.0" - deepmerge "^4.2.2" - is-module "^1.0.0" - resolve "^1.19.0" - -"@rollup/pluginutils@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" - integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== - dependencies: - "@types/estree" "0.0.39" - estree-walker "^1.0.1" picomatch "^2.2.2" -"@tauri-apps/api@link:../../tooling/api/dist": - version "0.0.0" - -"@types/estree@*": - version "0.0.46" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe" - integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg== - -"@types/estree@0.0.39": - version "0.0.39" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" - integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== - -"@types/node@*": - version "14.14.27" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.27.tgz#c7127f8da0498993e13b1a42faf1303d3110d2f2" - integrity sha512-Ecfmo4YDQPwuqTCl1yBxLV5ihKfRlkBmzUEDcfIRvDxOTGQEeikr317Ln7Gcv0tjA8dVgKI3rniqW2G1OyKDng== - -"@types/resolve@1.17.1": - version "1.17.1" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" - integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== - dependencies: - "@types/node" "*" - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -builtin-modules@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" - integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chokidar@^3.3.0: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== +"@sveltejs/vite-plugin-svelte@^1.0.0-next.11": + version "1.0.0-next.30" + resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.30.tgz#a6cd181bb406d590c1fa8d480c55950d567689f9" + integrity sha512-YQqdMxjL1VgSFk4/+IY3yLwuRRapPafPiZTiaGEq1psbJYSNYUWx9F1zMm32GMsnogg3zn99mGJOqe3ld3HZSg== dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" + "@rollup/pluginutils" "^4.1.1" + debug "^4.3.2" + kleur "^4.1.4" + magic-string "^0.25.7" + require-relative "^0.8.7" + svelte-hmr "^0.14.7" + +"@tauri-apps/api@../../tooling/api/dist": + version "1.0.0-beta.8" + dependencies: + type-fest "2.8.0" + +debug@^4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +esbuild-android-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44" + integrity sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg== + +esbuild-darwin-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz#8e9169c16baf444eacec60d09b24d11b255a8e72" + integrity sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ== + +esbuild-darwin-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz#1b07f893b632114f805e188ddfca41b2b778229a" + integrity sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ== + +esbuild-freebsd-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz#0b8b7eca1690c8ec94c75680c38c07269c1f4a85" + integrity sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA== + +esbuild-freebsd-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz#2e1a6c696bfdcd20a99578b76350b41db1934e52" + integrity sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ== + +esbuild-linux-32@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz#6fd39f36fc66dd45b6b5f515728c7bbebc342a69" + integrity sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g== + +esbuild-linux-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz#9cb8e4bcd7574e67946e4ee5f1f1e12386bb6dd3" + integrity sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA== + +esbuild-linux-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz#3891aa3704ec579a1b92d2a586122e5b6a2bfba1" + integrity sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA== + +esbuild-linux-arm@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz#8a00e99e6a0c6c9a6b7f334841364d8a2b4aecfe" + integrity sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA== + +esbuild-linux-mips64le@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz#36b07cc47c3d21e48db3bb1f4d9ef8f46aead4f7" + integrity sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg== + +esbuild-linux-ppc64le@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz#f7e6bba40b9a11eb9dcae5b01550ea04670edad2" + integrity sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ== + +esbuild-netbsd-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz#a2fedc549c2b629d580a732d840712b08d440038" + integrity sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w== + +esbuild-openbsd-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz#b22c0e5806d3a1fbf0325872037f885306b05cd7" + integrity sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g== + +esbuild-sunos-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz#d0b6454a88375ee8d3964daeff55c85c91c7cef4" + integrity sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw== + +esbuild-windows-32@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz#c96d0b9bbb52f3303322582ef8e4847c5ad375a7" + integrity sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw== + +esbuild-windows-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz#1f79cb9b1e1bb02fb25cd414cb90d4ea2892c294" + integrity sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ== + +esbuild-windows-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz#482173070810df22a752c686509c370c3be3b3c3" + integrity sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA== + +esbuild@^0.13.2: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.15.tgz#db56a88166ee373f87dbb2d8798ff449e0450cdf" + integrity sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw== optionalDependencies: - fsevents "~2.3.1" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -console-clear@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/console-clear/-/console-clear-1.1.1.tgz#995e20cbfbf14dd792b672cde387bd128d674bf7" - integrity sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ== - -deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -estree-walker@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" - integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== - -estree-walker@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" - integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + esbuild-android-arm64 "0.13.15" + esbuild-darwin-64 "0.13.15" + esbuild-darwin-arm64 "0.13.15" + esbuild-freebsd-64 "0.13.15" + esbuild-freebsd-arm64 "0.13.15" + esbuild-linux-32 "0.13.15" + esbuild-linux-64 "0.13.15" + esbuild-linux-arm "0.13.15" + esbuild-linux-arm64 "0.13.15" + esbuild-linux-mips64le "0.13.15" + esbuild-linux-ppc64le "0.13.15" + esbuild-netbsd-64 "0.13.15" + esbuild-openbsd-64 "0.13.15" + esbuild-sunos-64 "0.13.15" + esbuild-windows-32 "0.13.15" + esbuild-windows-64 "0.13.15" + esbuild-windows-arm64 "0.13.15" estree-walker@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.1: +fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -245,40 +157,6 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -get-port@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" - integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= - -glob-parent@~5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -291,26 +169,6 @@ hotkeys-js@^3.8.5: resolved "https://registry.yarnpkg.com/hotkeys-js/-/hotkeys-js-3.8.5.tgz#a66030c48b75ceb2f3fc48fd39e7a0b3473a4b19" integrity sha512-beJJ2Y4J6XkSlXlLPOG29BRKxZx3bV0gVi3eUpYdjrecN1i25iqndM/+X1eIDPSeG0XdqSv7Ksek43j5tQrmPQ== -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - is-core-module@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" @@ -318,73 +176,10 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-reference@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" - integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== - dependencies: - "@types/estree" "*" - -jest-worker@^26.2.1: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -kleur@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -livereload-js@^3.1.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-3.3.1.tgz#61f887468086762e61fb2987412cf9d1dda99202" - integrity sha512-CBu1gTEfzVhlOK1WASKAAJ9Qx1fHECTq0SUB67sfxwQssopTyvzqTlgl+c0h9pZ6V+Fzd2rc510ppuNusg9teQ== - -livereload@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/livereload/-/livereload-0.9.1.tgz#65125dabdf2db4fd3f1169e953fe56e3bcc6f477" - integrity sha512-9g7sua11kkyZNo2hLRCG3LuZZwqexoyEyecSlV8cAsfAVVCZqLzVir6XDqmH0r+Vzgnd5LrdHDMyjtFnJQLAYw== - dependencies: - chokidar "^3.3.0" - livereload-js "^3.1.0" - opts ">= 1.2.0" - ws "^6.2.1" - -local-access@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/local-access/-/local-access-1.1.0.tgz#e007c76ba2ca83d5877ba1a125fc8dfe23ba4798" - integrity sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw== +kleur@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d" + integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA== magic-string@^0.25.7: version "0.25.7" @@ -393,80 +188,46 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.4" -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -mime@^2.3.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.0.tgz#2b4af934401779806ee98026bb42e8c1ae1876b1" - integrity sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag== - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -mri@^1.1.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.6.tgz#49952e1044db21dbf90f6cd92bc9c9a777d415a6" - integrity sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -"opts@>= 1.2.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/opts/-/opts-2.0.2.tgz#a17e189fbbfee171da559edd8a42423bc5993ce1" - integrity sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +nanoid@^3.1.30: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== path-parse@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2: +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== +postcss@^8.3.8: + version "8.4.4" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.4.tgz#d53d4ec6a75fd62557a66bb41978bf47ff0c2869" + integrity sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q== dependencies: - safe-buffer "^5.1.0" - -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== - dependencies: - picomatch "^2.2.1" + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^1.0.1" require-relative@^0.8.7: version "0.8.7" resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" integrity sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4= -resolve@^1.17.0, resolve@^1.19.0: +resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -474,168 +235,46 @@ resolve@^1.17.0, resolve@^1.19.0: is-core-module "^2.2.0" path-parse "^1.0.6" -rollup-plugin-livereload@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.0.tgz#d3928d74e8cf2ae4286c5dd46b770fd3f3b82313" - integrity sha512-oC/8NqumGYuphkqrfszOHUUIwzKsaHBICw6QRwT5uD07gvePTS+HW+GFwu6f9K8W02CUuTvtIM9AWJrbj4wE1A== - dependencies: - livereload "^0.9.1" - -rollup-plugin-svelte@7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz#d45f2b92b1014be4eb46b55aa033fb9a9c65f04d" - integrity sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg== - dependencies: - require-relative "^0.8.7" - rollup-pluginutils "^2.8.2" - -rollup-plugin-terser@7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" - integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== - dependencies: - "@babel/code-frame" "^7.10.4" - jest-worker "^26.2.1" - serialize-javascript "^4.0.0" - terser "^5.0.0" - -rollup-pluginutils@^2.8.2: - version "2.8.2" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" - integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== - dependencies: - estree-walker "^0.6.1" - -rollup@2.40.0: - version "2.40.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.40.0.tgz#efc218eaede7ab590954df50f96195188999c304" - integrity sha512-WiOGAPbXoHu+TOz6hyYUxIksOwsY/21TRWoO593jgYt8mvYafYqQl+axaA8y1z2HFazNUUrsMSjahV2A6/2R9A== +rollup@^2.57.0: + version "2.60.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.60.2.tgz#3f45ace36a9b10b4297181831ea0719922513463" + integrity sha512-1Bgjpq61sPjgoZzuiDSGvbI1tD91giZABgjCQBKM5aYLnzjq52GoDuWVwT/cm/MCxCMPU8gqQvkj8doQ5C8Oqw== optionalDependencies: - fsevents "~2.3.1" - -sade@^1.6.0: - version "1.7.4" - resolved "https://registry.yarnpkg.com/sade/-/sade-1.7.4.tgz#ea681e0c65d248d2095c90578c03ca0bb1b54691" - integrity sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA== - dependencies: - mri "^1.1.0" - -safe-buffer@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -semiver@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semiver/-/semiver-1.1.0.tgz#9c97fb02c21c7ce4fcf1b73e2c7a24324bdddd5f" - integrity sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg== - -serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" + fsevents "~2.3.2" -sirv-cli@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/sirv-cli/-/sirv-cli-1.0.11.tgz#a3f4bed53b7c09306ed7f16ebea6e1e7be676c74" - integrity sha512-L8NILoRSBd38VcfFcERYCaVCnWPBLo9G6u/a37UJ8Ysv4DfjizMbFBcM+SswNnndJienhR6qy8KFuAEaeL4g8Q== - dependencies: - console-clear "^1.1.0" - get-port "^3.2.0" - kleur "^3.0.0" - local-access "^1.0.1" - sade "^1.6.0" - semiver "^1.0.0" - sirv "^1.0.11" - tinydate "^1.0.0" - -sirv@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.11.tgz#81c19a29202048507d6ec0d8ba8910fda52eb5a4" - integrity sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg== - dependencies: - "@polka/url" "^1.0.0-next.9" - mime "^2.3.1" - totalist "^1.0.0" - -source-map-support@~0.5.19: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +source-map-js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" + integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== sourcemap-codec@^1.4.4: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" +svelte-hmr@^0.14.7: + version "0.14.7" + resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.7.tgz#7fa8261c7b225d9409f0a86f3b9ea5c3ca6f6607" + integrity sha512-pDrzgcWSoMaK6AJkBWkmgIsecW0GChxYZSZieIYfCP0v2oPyx2CYU/zm7TBIcjLVUPP714WxmViE9Thht4etog== svelte@3.35.0: version "3.35.0" resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.35.0.tgz#e0d0ba60c4852181c2b4fd851194be6fda493e65" integrity sha512-gknlZkR2sXheu/X+B7dDImwANVvK1R0QGQLd8CNIfxxGPeXBmePnxfzb6fWwTQRsYQG7lYkZXvpXJvxvpsoB7g== -terser@^5.0.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.6.0.tgz#138cdf21c5e3100b1b3ddfddf720962f88badcd2" - integrity sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.19" - -tinydate@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/tinydate/-/tinydate-1.3.0.tgz#e6ca8e5a22b51bb4ea1c3a2a4fd1352dbd4c57fb" - integrity sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -totalist@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" - integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -ws@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== +type-fest@2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.8.0.tgz#39d7c9f9c508df8d6ce1cf5a966b0e6568dcc50d" + integrity sha512-O+V9pAshf9C6loGaH0idwsmugI2LxVNR7DtS40gVo2EXZVYFgz9OuNtOhgHLdHdapOEWNdvz9Ob/eeuaWwwlxA== + +vite@^2.6.4: + version "2.6.14" + resolved "https://registry.yarnpkg.com/vite/-/vite-2.6.14.tgz#35c09a15e4df823410819a2a239ab11efb186271" + integrity sha512-2HA9xGyi+EhY2MXo0+A2dRsqsAG3eFNEVIo12olkWhOmc8LfiM+eMdrXf+Ruje9gdXgvSqjLI9freec1RUM5EA== dependencies: - async-limiter "~1.0.0" + esbuild "^0.13.2" + postcss "^8.3.8" + resolve "^1.20.0" + rollup "^2.57.0" + optionalDependencies: + fsevents "~2.3.2" diff --git a/examples/commands/README.md b/examples/commands/README.md new file mode 100644 index 000000000000..671b450a0f6d --- /dev/null +++ b/examples/commands/README.md @@ -0,0 +1,5 @@ +# Commands Example + +A simple Tauri Application showcasing the command API. + +To execute run the following on the root directory of the repository: `cargo run --example commands`. diff --git a/examples/commands/package.json b/examples/commands/package.json index 5c7a0e03847e..b609dca33a0a 100644 --- a/examples/commands/package.json +++ b/examples/commands/package.json @@ -2,6 +2,6 @@ "name": "state", "version": "1.0.0", "scripts": { - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "node ../../tooling/cli/node/tauri.js" } -} +} \ No newline at end of file diff --git a/examples/commands/src-tauri/.gitignore b/examples/commands/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/commands/src-tauri/.gitignore +++ b/examples/commands/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/commands/src-tauri/Cargo.toml b/examples/commands/src-tauri/Cargo.toml index c09815f30856..9e6fb29722e2 100644 --- a/examples/commands/src-tauri/Cargo.toml +++ b/examples/commands/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "commands" version = "0.1.0" description = "A simple Tauri Application showcasing the commands API" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } @@ -10,7 +11,7 @@ tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } [dependencies] serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } -tauri = { path = "../../../core/tauri", features = ["api-all"] } +tauri = { path = "../../../core/tauri", features = [] } [features] default = [ "custom-protocol" ] diff --git a/examples/commands/src-tauri/src/commands.rs b/examples/commands/src-tauri/src/commands.rs index 4640dfb0b023..b9c4c1055825 100644 --- a/examples/commands/src-tauri/src/commands.rs +++ b/examples/commands/src-tauri/src/commands.rs @@ -22,6 +22,6 @@ pub fn simple_command(argument: String) { } #[command] -pub fn stateful_command(argument: Option, state: State) { +pub fn stateful_command(argument: Option, state: State<'_, super::MyState>) { println!("{:?} {:?}", argument, state.inner()); } diff --git a/examples/commands/src-tauri/src/main.rs b/examples/commands/src-tauri/src/main.rs index 899d3b55c761..cb142666b1e2 100644 --- a/examples/commands/src-tauri/src/main.rs +++ b/examples/commands/src-tauri/src/main.rs @@ -16,7 +16,9 @@ use tauri::{command, State, Window}; #[derive(Debug)] pub struct MyState { + #[allow(dead_code)] value: u64, + #[allow(dead_code)] label: String, } @@ -132,7 +134,7 @@ struct Person<'a> { } #[command] -fn command_arguments_struct(Person { name, age }: Person) { +fn command_arguments_struct(Person { name, age }: Person<'_>) { println!("received person struct with name: {} | age: {}", name, age) } @@ -140,7 +142,7 @@ fn command_arguments_struct(Person { name, age }: Person) { struct InlinePerson<'a>(&'a str, u8); #[command] -fn command_arguments_tuple_struct(InlinePerson(name, age): InlinePerson) { +fn command_arguments_tuple_struct(InlinePerson(name, age): InlinePerson<'_>) { println!("received person tuple with name: {} | age: {}", name, age) } diff --git a/examples/commands/src-tauri/tauri.conf.json b/examples/commands/src-tauri/tauri.conf.json index 64a16926c0e0..e4af12b6718c 100644 --- a/examples/commands/src-tauri/tauri.conf.json +++ b/examples/commands/src-tauri/tauri.conf.json @@ -36,7 +36,7 @@ } }, "allowlist": { - "all": true + "all": false }, "windows": [ { @@ -48,7 +48,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" + "csp": "default-src 'self'" }, "updater": { "active": false diff --git a/examples/helloworld/README.md b/examples/helloworld/README.md new file mode 100644 index 000000000000..e3a8ff23fd01 --- /dev/null +++ b/examples/helloworld/README.md @@ -0,0 +1,3 @@ +# Hello Wolrd Example + +To execute run the following on the root directory of the repository: `cargo example --helloworld`. diff --git a/examples/helloworld/package.json b/examples/helloworld/package.json index 03c879d0ee21..090a0da96824 100644 --- a/examples/helloworld/package.json +++ b/examples/helloworld/package.json @@ -2,6 +2,6 @@ "name": "hello-world", "version": "1.0.0", "scripts": { - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "node ../../tooling/cli/node/tauri.js" } -} +} \ No newline at end of file diff --git a/examples/helloworld/src-tauri/.gitignore b/examples/helloworld/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/helloworld/src-tauri/.gitignore +++ b/examples/helloworld/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/helloworld/src-tauri/Cargo.toml b/examples/helloworld/src-tauri/Cargo.toml index 2f005750e1fa..d611b4d87d62 100644 --- a/examples/helloworld/src-tauri/Cargo.toml +++ b/examples/helloworld/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "helloworld" version = "0.1.0" description = "A very simple Tauri Appplication" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } diff --git a/examples/helloworld/src-tauri/tauri.conf.json b/examples/helloworld/src-tauri/tauri.conf.json index 81233fa46146..b59986109c58 100644 --- a/examples/helloworld/src-tauri/tauri.conf.json +++ b/examples/helloworld/src-tauri/tauri.conf.json @@ -47,10 +47,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" - }, - "updater": { - "active": false + "csp": "default-src 'self'" } } } diff --git a/examples/isolation/dist/index.html b/examples/isolation/dist/index.html new file mode 100644 index 000000000000..523b0edde7bc --- /dev/null +++ b/examples/isolation/dist/index.html @@ -0,0 +1,84 @@ + + + + + + + Hello Tauri! + + + + + +
    +

    Hello, Tauri!

    +
    +
    + +
    +
    + + + + + + diff --git a/examples/isolation/dist/linked.js b/examples/isolation/dist/linked.js new file mode 100644 index 000000000000..7f65231311a7 --- /dev/null +++ b/examples/isolation/dist/linked.js @@ -0,0 +1 @@ +console.log("linked", window.__TAURI_PATTERN__); diff --git a/examples/isolation/isolation-dist/index.html b/examples/isolation/isolation-dist/index.html new file mode 100644 index 000000000000..1a12b0bc4607 --- /dev/null +++ b/examples/isolation/isolation-dist/index.html @@ -0,0 +1,10 @@ + + + + + Isolation Secure Script + + + + + diff --git a/examples/isolation/isolation-dist/index.js b/examples/isolation/isolation-dist/index.js new file mode 100644 index 000000000000..2acb850a594a --- /dev/null +++ b/examples/isolation/isolation-dist/index.js @@ -0,0 +1,4 @@ +window.__TAURI_ISOLATION_HOOK__= (payload) => { + console.log('hook', payload) + return payload +} diff --git a/examples/isolation/package.json b/examples/isolation/package.json new file mode 100644 index 000000000000..fdb28735c975 --- /dev/null +++ b/examples/isolation/package.json @@ -0,0 +1,10 @@ +{ + "name": "isolation", + "license": "Apache-2.0 OR MIT", + "scripts": { + "tauri": "node ../../tooling/cli/node/tauri.js" + }, + "dependencies": { + "@tauri-apps/api": "../../tooling/api/dist" + } +} \ No newline at end of file diff --git a/examples/isolation/src-tauri/.gitignore b/examples/isolation/src-tauri/.gitignore new file mode 100644 index 000000000000..1320e8c0a93d --- /dev/null +++ b/examples/isolation/src-tauri/.gitignore @@ -0,0 +1,5 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +WixTools +.cargo diff --git a/examples/isolation/src-tauri/.license_template b/examples/isolation/src-tauri/.license_template new file mode 120000 index 000000000000..860f082565b3 --- /dev/null +++ b/examples/isolation/src-tauri/.license_template @@ -0,0 +1 @@ +../../../.license_template \ No newline at end of file diff --git a/examples/isolation/src-tauri/Cargo.lock b/examples/isolation/src-tauri/Cargo.lock new file mode 100644 index 000000000000..81bd3a6972a8 --- /dev/null +++ b/examples/isolation/src-tauri/Cargo.lock @@ -0,0 +1,3448 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" + +[[package]] +name = "app" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "tauri", + "tauri-build", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "atk" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a83b21d2aa75e464db56225e1bda2dd5993311ba1095acaa8fa03d1ae67026ba" +dependencies = [ + "atk-sys", + "bitflags", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea" +dependencies = [ + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake3" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "526c210b4520e416420759af363083471656e819a75e831b8d2c9d5a584f2413" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if 1.0.0", + "constant_time_eq", + "digest", + "rayon", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + +[[package]] +name = "bumpalo" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cairo-rs" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b5725979db0c586d98abad2193cdb612dd40ef95cd26bd99851bf93b3cb482" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b448b876970834fda82ba3aeaccadbd760206b75388fc5c1b02f1e343b697570" +dependencies = [ + "glib-sys 0.14.0", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "cargo_toml" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67110a7844b75a4dda12f4dca5a731c961750d6c8fa3cb6a41ab67411be05d3a" +dependencies = [ + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfb" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca453e8624711b2f0f4eb47076a318feda166252a827ee25d067b43de83dcba0" +dependencies = [ + "byteorder", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edae0b9625d1fce32f7d64b71784d9b1bf8469ec1a9c417e44aaf16a9cbd7571" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cocoa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation 0.9.2", + "core-graphics 0.22.3", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation 0.9.2", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "const-sha1" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +dependencies = [ + "core-foundation-sys 0.8.3", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +dependencies = [ + "bitflags", + "core-foundation 0.7.0", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation 0.9.2", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation 0.9.2", + "foreign-types", + "libc", +] + +[[package]] +name = "core-video-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +dependencies = [ + "cfg-if 0.1.10", + "core-foundation-sys 0.7.0", + "core-graphics 0.19.2", + "libc", + "objc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + +[[package]] +name = "darling" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +dependencies = [ + "darling_core 0.13.1", + "darling_macro 0.13.1", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.9.3", + "syn", +] + +[[package]] +name = "darling_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core 0.10.2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +dependencies = [ + "darling_core 0.13.1", + "quote", + "syn", +] + +[[package]] +name = "data-url" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193" +dependencies = [ + "matches", +] + +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dtoa-short" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +dependencies = [ + "dtoa", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "embed_plist" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53dd2e43a7d32952a6054141ee0d75183958620e84e5eab045de362dff13dc99" + +[[package]] +name = "fastrand" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +dependencies = [ + "instant", +] + +[[package]] +name = "field-offset" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +dependencies = [ + "memoffset", + "rustc_version 0.3.3", +] + +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "winapi", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" + +[[package]] +name = "futures-executor" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" + +[[package]] +name = "futures-task" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" + +[[package]] +name = "futures-util" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d749dcfc00d8de0d7c3a289e04a04293eb5ba3d8a4e64d64911d481fa9933b" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590" +dependencies = [ + "gio-sys 0.14.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gdk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys 0.14.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "pango-sys", + "pkg-config", + "system-deps 3.2.0", +] + +[[package]] +name = "generator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "winapi", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gio" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711c3632b3ebd095578a9c091418d10fed492da9443f58ebc8f45efbeb215cb0" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys 0.14.0", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e24fb752f8f5d2cf6bbc2c606fd2bc989c81c5e2fe321ab974d54f8b6344eac" +dependencies = [ + "glib-sys 0.10.1", + "gobject-sys 0.10.0", + "libc", + "system-deps 1.3.2", + "winapi", +] + +[[package]] +name = "gio-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" +dependencies = [ + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 3.2.0", + "winapi", +] + +[[package]] +name = "glib" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c515f1e62bf151ef6635f528d05b02c11506de986e43b34a5c920ef0b3796a4" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "once_cell", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1" +dependencies = [ + "libc", + "system-deps 1.3.2", +] + +[[package]] +name = "glib-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" +dependencies = [ + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "globset" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "gobject-sys" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c" +dependencies = [ + "glib-sys 0.10.1", + "libc", + "system-deps 1.3.2", +] + +[[package]] +name = "gobject-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" +dependencies = [ + "glib-sys 0.14.0", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gtk" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb51122dd3317e9327ec1e4faa151d1fa0d95664cd8fb8dcfacf4d4d29ac70c" +dependencies = [ + "atk", + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys 0.14.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "pango-sys", + "system-deps 3.2.0", +] + +[[package]] +name = "gtk3-macros" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "html5ever" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "http" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +dependencies = [ + "bytes", + "fnv", + "itoa 0.4.8", +] + +[[package]] +name = "http-range" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee9694f83d9b7c09682fdb32213682939507884e5bcf227be9aff5d644b90dc" + +[[package]] +name = "ico" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" +dependencies = [ + "byteorder", + "png 0.11.0", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "infer" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92b41dab759f9e8427c03f519c344a14655490b8db548dac1e57a75b3258391" +dependencies = [ + "cfb", +] + +[[package]] +name = "inflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" +dependencies = [ + "adler32", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "javascriptcore-rs" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e207780c1d1cd3c36056695e44010a19dd481574a2106cd2540edda4128a9794" +dependencies = [ + "bitflags", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2adf2de824b178d76c6017da59f4e7e95de49a766b584c59d47821a6c3dce9e2" +dependencies = [ + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kuchiki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +dependencies = [ + "cssparser", + "html5ever", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.112" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "loom" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" +dependencies = [ + "cfg-if 1.0.0", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +dependencies = [ + "log", + "phf 0.8.0", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "ndk" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-glue" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk", + "ndk-macro", + "ndk-sys", +] + +[[package]] +name = "ndk-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +dependencies = [ + "darling 0.10.2", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "085fe377a4b2805c0fbc09484415ec261174614b7f080b0e0d520456ac421a67" +dependencies = [ + "derivative", + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5249369707a1e07b39f78d98c8f34e00aca7dcb053812fdbb5ad7be82c1bba38" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "pango" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546fd59801e5ca735af82839007edd226fe7d3bb06433ec48072be4439c28581" +dependencies = [ + "bitflags", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe" +dependencies = [ + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.4", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "png" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" +dependencies = [ + "bitflags", + "deflate 0.7.20", + "inflate", + "num-iter", +] + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.8.6", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76" +dependencies = [ + "libc", + "raw-window-handle 0.4.2", +] + +[[package]] +name = "raw-window-handle" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba75eee94a9d5273a68c9e1e105d9cffe1ef700532325788389e5a83e2522b7" +dependencies = [ + "cty", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.3", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.4", +] + +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +dependencies = [ + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_with" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6056b4cb69b6e43e3a0f055def223380baecc99da683884f205bf347f7c4b3" +dependencies = [ + "rustversion", + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" +dependencies = [ + "darling 0.13.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.0" +source = "git+https://github.com/chippers/serialize-to-javascript#38d5026f371bfba4f5197ed143a6667a09375fbd" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.0" +source = "git+https://github.com/chippers/serialize-to-javascript#38d5026f371bfba4f5197ed143a6667a09375fbd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +dependencies = [ + "block-buffer", + "cfg-if 1.0.0", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "siphasher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" + +[[package]] +name = "soup-sys" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7adf08565630bbb71f955f11f8a68464817ded2703a3549747c235b58a13e" +dependencies = [ + "bitflags", + "gio-sys 0.10.1", + "glib-sys 0.10.1", + "gobject-sys 0.10.0", + "libc", + "pkg-config", + "system-deps 1.3.2", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923f0f39b6267d37d23ce71ae7235602134b250ace715dd2c90421998ddac0c6" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.8.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b" + +[[package]] +name = "strum" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" + +[[package]] +name = "strum_macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "system-deps" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b" +dependencies = [ + "heck", + "pkg-config", + "strum 0.18.0", + "strum_macros 0.18.0", + "thiserror", + "toml", + "version-compare 0.0.10", +] + +[[package]] +name = "system-deps" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" +dependencies = [ + "anyhow", + "cfg-expr 0.8.1", + "heck", + "itertools", + "pkg-config", + "strum 0.21.0", + "strum_macros 0.21.1", + "thiserror", + "toml", + "version-compare 0.0.11", +] + +[[package]] +name = "system-deps" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" +dependencies = [ + "cfg-expr 0.9.0", + "heck", + "pkg-config", + "toml", + "version-compare 0.0.11", +] + +[[package]] +name = "tao" +version = "0.5.2" +source = "git+https://github.com/tauri-apps/tao?rev=2294e312b7c0d422968be3b1406eaa4fe83bc96d#2294e312b7c0d422968be3b1406eaa4fe83bc96d" +dependencies = [ + "bitflags", + "cairo-rs", + "cc", + "cocoa", + "core-foundation 0.9.2", + "core-graphics 0.22.3", + "core-video-sys", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "glib-sys 0.14.0", + "gtk", + "instant", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-glue", + "ndk-sys", + "objc", + "parking_lot", + "raw-window-handle 0.3.4", + "scopeguard", + "serde", + "unicode-segmentation", + "webview2-com-sys", + "windows", + "x11-dl", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tauri" +version = "1.0.0-beta.8" +dependencies = [ + "bincode", + "cfg_aliases", + "data-url", + "dirs-next", + "either", + "embed_plist", + "flate2", + "futures", + "futures-lite", + "glib", + "glob", + "gtk", + "http", + "ignore", + "once_cell", + "percent-encoding", + "rand 0.8.4", + "raw-window-handle 0.3.4", + "regex", + "semver 1.0.4", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "state", + "tar", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "tempfile", + "thiserror", + "tokio", + "url", + "uuid", + "zip", +] + +[[package]] +name = "tauri-build" +version = "1.0.0-beta.4" +dependencies = [ + "anyhow", + "cargo_toml", + "serde_json", + "tauri-codegen", + "tauri-utils", + "winres", +] + +[[package]] +name = "tauri-codegen" +version = "1.0.0-beta.4" +dependencies = [ + "base64", + "blake3", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "sha2", + "tauri-utils", + "thiserror", + "uuid", + "walkdir", + "zstd", +] + +[[package]] +name = "tauri-macros" +version = "1.0.0-beta.5" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", + "tauri-codegen", +] + +[[package]] +name = "tauri-runtime" +version = "0.2.1" +dependencies = [ + "gtk", + "http", + "http-range", + "infer", + "serde", + "serde_json", + "tauri-utils", + "thiserror", + "uuid", + "webview2-com-sys", +] + +[[package]] +name = "tauri-runtime-wry" +version = "0.2.1" +dependencies = [ + "gtk", + "ico", + "infer", + "png 0.16.8", + "tauri-runtime", + "tauri-utils", + "uuid", + "webview2-com", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "1.0.0-beta.3" +dependencies = [ + "aes-gcm", + "base64", + "heck", + "html5ever", + "kuchiki", + "once_cell", + "phf 0.10.1", + "proc-macro2", + "quote", + "ring", + "serde", + "serde_json", + "serde_with", + "serialize-to-javascript", + "sha2", + "thiserror", + "url", + "zstd", +] + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand 0.8.4", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tendril" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" +dependencies = [ + "bytes", + "memchr", + "num_cpus", + "pin-project-lite", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245da694cc7fc4729f3f418b304cb57789f1bed2a78c575407ab8a23f53cb4d3" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "version-compare" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1" + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" + +[[package]] +name = "web-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webkit2gtk" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5725e8ede878b7c00419066868085b83fb7d01eea904c1a0bd0159ad3ce0ba3" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys 0.14.0", + "glib", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b34314407e381b88a72610d0f4eeff1552cbf8ee5420dbe84749fa26aa11b4e3" +dependencies = [ + "atk-sys", + "bitflags", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys 0.14.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pango-sys", + "pkg-config", + "soup-sys", + "system-deps 5.0.0", +] + +[[package]] +name = "webview2-com" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2294dee38668da0d71019097dddc6cef525fde7aa4784243dd83f0752e08aa5" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", +] + +[[package]] +name = "webview2-com-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eba35fdbb8fbc8de7e7479532a356dbbf2754d8a6e9c9fbfa430896cbb1ca89" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "webview2-com-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14690dcb8b57c5238c4502cfc321f858fa1306edd4109e8e1d7ddee0c29b06a5" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef84dd25f4c69a271b1bba394532bf400523b43169de21dfc715e8f8e491053d" +dependencies = [ + "const-sha1", + "windows_gen", + "windows_macros", +] + +[[package]] +name = "windows_gen" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac7bb21b8ff5e801232b72a6ff554b4cc0cef9ed9238188c3ca78fe3968a7e5d" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_macros" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5566b8c51118769e4a9094a688bf1233a3f36aacbfc78f3b15817fe0b6e0442f" +dependencies = [ + "syn", + "windows_gen", + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_quote" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4af8236a9493c38855f95cdd11b38b342512a5df4ee7473cffa828b5ebb0e39c" + +[[package]] +name = "windows_reader" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8d5cf83fb08083438c5c46723e6206b2970da57ce314f80b57724439aaacab" + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", +] + +[[package]] +name = "wry" +version = "0.12.2" +dependencies = [ + "cocoa", + "core-graphics 0.22.3", + "gdk", + "gio", + "glib", + "gtk", + "http", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "tao", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", +] + +[[package]] +name = "x11-dl" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +dependencies = [ + "lazy_static", + "libc", + "pkg-config", +] + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "bzip2", + "crc32fast", + "flate2", + "thiserror", + "time", +] + +[[package]] +name = "zstd" +version = "0.9.0+zstd.1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07749a5dc2cb6b36661290245e350f15ec3bbb304e493db54a1d354480522ccd" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "4.1.1+zstd.1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91c90f2c593b003603e5e0493c837088df4469da25aafff8bce42ba48caf079" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.6.1+zstd.1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "615120c7a2431d16cf1cf979e7fc31ba7a5b5e5707b29c8a99e5dbf8a8392a33" +dependencies = [ + "cc", + "libc", +] diff --git a/examples/isolation/src-tauri/Cargo.toml b/examples/isolation/src-tauri/Cargo.toml new file mode 100644 index 000000000000..4ae9cea0d5ce --- /dev/null +++ b/examples/isolation/src-tauri/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "app" +version = "0.1.0" +description = "An example Tauri Application showcasing the isolation pattern" +edition = "2021" +license = "Apache-2.0 OR MIT" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +tauri-build = { path = "../../../core/tauri-build", features = [ "isolation" ] } + +[dependencies] +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +tauri = { path = "../../../core/tauri", features = [ "isolation" ] } + +[features] +default = [ "custom-protocol", "isolation" ] +isolation = [ "tauri/isolation", "tauri-build/isolation" ] +custom-protocol = [ "tauri/custom-protocol" ] diff --git a/examples/isolation/src-tauri/LICENSE_APACHE-2.0 b/examples/isolation/src-tauri/LICENSE_APACHE-2.0 new file mode 120000 index 000000000000..5ee573597fa5 --- /dev/null +++ b/examples/isolation/src-tauri/LICENSE_APACHE-2.0 @@ -0,0 +1 @@ +../../../LICENSE_APACHE-2.0 \ No newline at end of file diff --git a/examples/isolation/src-tauri/LICENSE_MIT b/examples/isolation/src-tauri/LICENSE_MIT new file mode 120000 index 000000000000..71b6663417bc --- /dev/null +++ b/examples/isolation/src-tauri/LICENSE_MIT @@ -0,0 +1 @@ +../../../LICENSE_MIT \ No newline at end of file diff --git a/examples/isolation/src-tauri/build.rs b/examples/isolation/src-tauri/build.rs new file mode 100644 index 000000000000..68540db55877 --- /dev/null +++ b/examples/isolation/src-tauri/build.rs @@ -0,0 +1,13 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use tauri_build::{try_build, Attributes, WindowsAttributes}; + +fn main() { + try_build( + Attributes::new() + .windows_attributes(WindowsAttributes::new().window_icon_path("../../.icons/icon.ico")), + ) + .expect("could not build tauri application"); +} diff --git a/examples/isolation/src-tauri/src/main.rs b/examples/isolation/src-tauri/src/main.rs new file mode 100644 index 000000000000..317c015b16a4 --- /dev/null +++ b/examples/isolation/src-tauri/src/main.rs @@ -0,0 +1,30 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] + +use std::time::Instant; + +#[tauri::command] +fn ping() { + dbg!(format!("ping: {:?}", Instant::now())); +} + +#[cfg(not(feature = "isolation"))] +fn main() { + compile_error!("Feature `isolation` is required to run this example"); +} + +#[cfg(feature = "isolation")] +fn main() { + tauri::Builder::default() + .invoke_handler(tauri::generate_handler![ping]) + .run(tauri::generate_context!( + "../../examples/isolation/src-tauri/tauri.conf.json" + )) + .expect("error while running tauri application"); +} diff --git a/examples/isolation/src-tauri/tauri.conf.json b/examples/isolation/src-tauri/tauri.conf.json new file mode 100644 index 000000000000..3a14c8eea2b9 --- /dev/null +++ b/examples/isolation/src-tauri/tauri.conf.json @@ -0,0 +1,71 @@ +{ + "package": { + "productName": "isolation", + "version": "0.1.0" + }, + "build": { + "distDir": "../dist", + "devPath": "../dist", + "beforeDevCommand": "", + "beforeBuildCommand": "", + "withGlobalTauri": true + }, + "tauri": { + "pattern": { + "use": "isolation", + "options": { + "dir": "../isolation-dist" + } + }, + "bundle": { + "active": true, + "targets": "all", + "identifier": "com.tauri.isolation", + "icon": [ + "../../.icons/32x32.png", + "../../.icons/128x128.png", + "../../.icons/128x128@2x.png", + "../../.icons/icon.icns", + "../../.icons/icon.ico" + ], + "resources": [], + "externalBin": [], + "copyright": "", + "category": "DeveloperTool", + "shortDescription": "", + "longDescription": "", + "deb": { + "depends": [], + "useBootstrapper": false + }, + "macOS": { + "frameworks": [], + "minimumSystemVersion": "", + "useBootstrapper": false, + "exceptionDomain": "", + "signingIdentity": null, + "entitlements": null + }, + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "" + } + }, + "updater": { + "active": false + }, + "windows": [ + { + "title": "Isolation", + "width": 800, + "height": 600, + "resizable": true, + "fullscreen": false + } + ], + "security": { + "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'" + } + } +} diff --git a/examples/isolation/yarn.lock b/examples/isolation/yarn.lock new file mode 100644 index 000000000000..39b685a5ac09 --- /dev/null +++ b/examples/isolation/yarn.lock @@ -0,0 +1,13 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@tauri-apps/api@../../tooling/api/dist": + version "1.0.0-beta.8" + dependencies: + type-fest "2.5.1" + +type-fest@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.5.1.tgz#17ba4f36a6abfabf0a92005d045dca77564607b0" + integrity sha512-JDcsxbLR6Z6OcL7TnGAAAGQrY4g7Q4EEALMT4Kp6FQuIc0JLQvOF3l7ejFvx8o5GmLlfMseTWUL++sYFP+o8kw== diff --git a/examples/multiwindow/README.md b/examples/multiwindow/README.md new file mode 100644 index 000000000000..ee52a1226ea9 --- /dev/null +++ b/examples/multiwindow/README.md @@ -0,0 +1,5 @@ +# Multi-Window Example + +An example Tauri Multi-Window Application. + +To execute run the following on the root directory of the repository: `cargo run --example multiwindow`. diff --git a/examples/multiwindow/index.html b/examples/multiwindow/index.html index 65f1c3c0dc15..c87cb492b3e7 100644 --- a/examples/multiwindow/index.html +++ b/examples/multiwindow/index.html @@ -1,74 +1,84 @@ - -
    -
    -
    - - var container = document.getElementById('container') + +
    +
    +
    - function createWindowMessageBtn(label) { - var tauriWindow = WebviewWindow.getByLabel(label) - var button = document.createElement('button') - button.innerHTML = 'Send message to ' + label - button.addEventListener('click', function () { - tauriWindow.emit('clicked', 'message from ' + windowLabel) - }) - container.appendChild(button) - } + - - + createWindowMessageBtn(label) + } + + + + \ No newline at end of file diff --git a/examples/multiwindow/package.json b/examples/multiwindow/package.json index 67de63845b2e..0cda486d9e2d 100644 --- a/examples/multiwindow/package.json +++ b/examples/multiwindow/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "node ../../tooling/cli/node/tauri.js" }, "private": true -} +} \ No newline at end of file diff --git a/examples/multiwindow/src-tauri/.gitignore b/examples/multiwindow/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/multiwindow/src-tauri/.gitignore +++ b/examples/multiwindow/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/multiwindow/src-tauri/Cargo.toml b/examples/multiwindow/src-tauri/Cargo.toml index d797d9c9e756..0ef261e55a4e 100644 --- a/examples/multiwindow/src-tauri/Cargo.toml +++ b/examples/multiwindow/src-tauri/Cargo.toml @@ -2,14 +2,15 @@ name = "multiwindow" version = "0.1.0" description = "An example Tauri Multi-Window Application" -edition = "2018" +edition = "2021" +rust-version = "1.57" license = "Apache-2.0 OR MIT" [build-dependencies] tauri-build = { path = "../../../core/tauri-build" } [dependencies] -tauri = { path = "../../../core/tauri", features = ["api-all"] } +tauri = { path = "../../../core/tauri", features = ["window-create"] } [features] default = [ "custom-protocol" ] diff --git a/examples/multiwindow/src-tauri/tauri.conf.json b/examples/multiwindow/src-tauri/tauri.conf.json index 9ea12140348a..3910c3c1ac1c 100644 --- a/examples/multiwindow/src-tauri/tauri.conf.json +++ b/examples/multiwindow/src-tauri/tauri.conf.json @@ -22,7 +22,9 @@ "category": "DeveloperTool" }, "allowlist": { - "all": true + "window": { + "create": true + } }, "windows": [ { @@ -39,7 +41,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" + "csp": "default-src 'self'" }, "updater": { "active": false diff --git a/examples/navigation/README.md b/examples/navigation/README.md new file mode 100644 index 000000000000..a931ed19acd0 --- /dev/null +++ b/examples/navigation/README.md @@ -0,0 +1,5 @@ +# Naviagtion Example + +A very simple Tauri Appplication with frontend navigation. + +To execute run the following on the root directory of the repository: `cargo run --example navigation`. diff --git a/examples/navigation/package.json b/examples/navigation/package.json index baab4dca692d..089cf71dcebe 100644 --- a/examples/navigation/package.json +++ b/examples/navigation/package.json @@ -2,6 +2,6 @@ "name": "navigation", "version": "1.0.0", "scripts": { - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "node ../../tooling/cli/node/tauri.js" } -} +} \ No newline at end of file diff --git a/examples/navigation/public/index.js b/examples/navigation/public/index.js index 5cd17d3b4ded..858552292f5e 100644 --- a/examples/navigation/public/index.js +++ b/examples/navigation/public/index.js @@ -12,7 +12,7 @@ document.querySelector('#go').addEventListener('click', () => { }) document.querySelector('#open-window').addEventListener('click', () => { - new WebviewWindow(Math.random().toString(), { + new WebviewWindow(Math.random().toString().replace('.', ''), { url: routeSelect.value }) }) diff --git a/examples/navigation/public/nested/index.html b/examples/navigation/public/nested/index.html index a0fb4b027912..d3332a6fe266 100644 --- a/examples/navigation/public/nested/index.html +++ b/examples/navigation/public/nested/index.html @@ -9,7 +9,11 @@

    - + + diff --git a/examples/navigation/public/nested/secondary.html b/examples/navigation/public/nested/secondary.html index 889026b73927..88cb5470ffc5 100644 --- a/examples/navigation/public/nested/secondary.html +++ b/examples/navigation/public/nested/secondary.html @@ -9,7 +9,11 @@

    - + + diff --git a/examples/navigation/public/secondary.html b/examples/navigation/public/secondary.html index 889026b73927..421ed3cb13b4 100644 --- a/examples/navigation/public/secondary.html +++ b/examples/navigation/public/secondary.html @@ -1,15 +1,21 @@ - - - - - Tauri - - -

    - - - + + + + + Tauri + + + +

    + + + + + diff --git a/examples/navigation/src-tauri/.gitignore b/examples/navigation/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/navigation/src-tauri/.gitignore +++ b/examples/navigation/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/navigation/src-tauri/Cargo.toml b/examples/navigation/src-tauri/Cargo.toml index 8d3b98c74eb4..c052aacb7a51 100644 --- a/examples/navigation/src-tauri/Cargo.toml +++ b/examples/navigation/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "navigation" version = "0.1.0" description = "A very simple Tauri Appplication with navigation" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } @@ -10,7 +11,7 @@ tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } [dependencies] serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } -tauri = { path = "../../../core/tauri", features = ["api-all"] } +tauri = { path = "../../../core/tauri", features = ["window-create"] } [features] default = [ "custom-protocol" ] diff --git a/examples/navigation/src-tauri/tauri.conf.json b/examples/navigation/src-tauri/tauri.conf.json index e2050dd484d7..bcd49593c707 100644 --- a/examples/navigation/src-tauri/tauri.conf.json +++ b/examples/navigation/src-tauri/tauri.conf.json @@ -36,7 +36,9 @@ } }, "allowlist": { - "all": true + "window": { + "create": true + } }, "windows": [ { @@ -48,7 +50,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" + "csp": "default-src 'self'" }, "updater": { "active": false diff --git a/examples/resources/README.md b/examples/resources/README.md index 6b13f28fbe58..13e0bd1b99ea 100644 --- a/examples/resources/README.md +++ b/examples/resources/README.md @@ -1,3 +1,5 @@ # Resource example This example demonstrates the Tauri bundle resources functionality. The example adds `src-tauri/assets/index.js` as a resource (defined on `tauri.conf.json > tauri > bundle > resources`) and executes it using `Node.js`, locating the JavaScript file using the `tauri::api::path::resolve_path` API. + +To execute run the following on the root directory of the repository: `cargo run --example resources`. diff --git a/examples/resources/index.html b/examples/resources/index.html index 1ab8c4f4e47a..04ae01ffe33a 100644 --- a/examples/resources/index.html +++ b/examples/resources/index.html @@ -13,7 +13,7 @@ const div = document.querySelector('div') window.__TAURI__.event.listen('message', (event) => { const p = document.createElement('p') - p.innerHTML = event.payload + p.innerText = event.payload div.appendChild(p) }) diff --git a/examples/resources/package.json b/examples/resources/package.json index 47da863d476f..4d9bc441495f 100644 --- a/examples/resources/package.json +++ b/examples/resources/package.json @@ -2,6 +2,6 @@ "name": "resources", "version": "1.0.0", "scripts": { - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "node ../../tooling/cli/node/tauri.js" } -} +} \ No newline at end of file diff --git a/examples/resources/src-tauri/.gitignore b/examples/resources/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/resources/src-tauri/.gitignore +++ b/examples/resources/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/resources/src-tauri/Cargo.lock b/examples/resources/src-tauri/Cargo.lock new file mode 100644 index 000000000000..d5dbc18433c9 --- /dev/null +++ b/examples/resources/src-tauri/Cargo.lock @@ -0,0 +1,3347 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "atk" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" +dependencies = [ + "atk-sys", + "bitflags", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake3" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.1", + "rayon", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cairo-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b869e97a87170f96762f9f178eae8c461147e722ba21dd8814105bf5716bf14a" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +dependencies = [ + "glib-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "cargo_toml" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363c7cfaa15f101415c4ac9e68706ca4a2277773932828b33f96e59d28c68e62" +dependencies = [ + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfb" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca453e8624711b2f0f4eb47076a318feda166252a827ee25d067b43de83dcba0" +dependencies = [ + "byteorder", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cocoa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + +[[package]] +name = "darling" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +dependencies = [ + "darling_core 0.13.1", + "darling_macro 0.13.1", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.9.3", + "syn", +] + +[[package]] +name = "darling_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core 0.10.2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +dependencies = [ + "darling_core 0.13.1", + "quote", + "syn", +] + +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", + "generic-array", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dtoa-short" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +dependencies = [ + "dtoa", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "field-offset" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +dependencies = [ + "memoffset", + "rustc_version 0.3.3", +] + +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614258e81ec35ed8770e64a0838f3a47f95b398bc51e724d3b3fa09c1ee0f8d5" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73aa2f5de1b45710da90a55863276667dc3a3264aaf6a2aeace62bb015244d49" +dependencies = [ + "bitflags", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171" +dependencies = [ + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "gdk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "pango-sys", + "pkg-config", + "system-deps 6.0.1", +] + +[[package]] +name = "gdkx11-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178" +dependencies = [ + "gdk-sys", + "glib-sys 0.15.5", + "libc", + "system-deps 6.0.1", + "x11", +] + +[[package]] +name = "generator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "winapi", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gio" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59105fa464928adf56b159c8d980cc11fbfbe414befb904caac5163d383049bf" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys 0.15.5", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" +dependencies = [ + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 3.2.0", + "winapi", +] + +[[package]] +name = "gio-sys" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f0bc4cfc9ebcdd05cc5057bc51b99c32f8f9bf246274f6a556ffd27279f8fe3" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", + "winapi", +] + +[[package]] +name = "glib" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dcfbdb6cc6c02aee163339465d8a40d6f3f64c3a43f729a4195f0e153338b7" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e58b262ff65ef771003873cea8c10e0fe854f1c508d48d62a4111a1ff163f7d1" +dependencies = [ + "anyhow", + "heck 0.4.0", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" +dependencies = [ + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "glib-sys" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1d4e1a63d8574541e5b92931e4e669ddc87ffa85d58e84e631dba13ad2e10c" +dependencies = [ + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "globset" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "gobject-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" +dependencies = [ + "glib-sys 0.14.0", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gobject-sys" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a" +dependencies = [ + "glib-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "gtk" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7978eaec05bea63947c801d29a21372f2ed39aec0bf56bf7725d3599094675e" +dependencies = [ + "atk", + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "pango-sys", + "system-deps 6.0.1", +] + +[[package]] +name = "gtk3-macros" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c891188af69e77a1e8a0b1746fbd03b9b396e7d34d518c5331b15950259f541" +dependencies = [ + "anyhow", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "html5ever" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.1", +] + +[[package]] +name = "http-range" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee9694f83d9b7c09682fdb32213682939507884e5bcf227be9aff5d644b90dc" + +[[package]] +name = "ico" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" +dependencies = [ + "byteorder", + "png 0.11.0", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "infer" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92b41dab759f9e8427c03f519c344a14655490b8db548dac1e57a75b3258391" +dependencies = [ + "cfb", +] + +[[package]] +name = "inflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" +dependencies = [ + "adler32", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "javascriptcore-rs" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c" +dependencies = [ + "bitflags", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "json-patch" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" +dependencies = [ + "serde", + "serde_json", + "treediff", +] + +[[package]] +name = "kuchiki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +dependencies = [ + "cssparser", + "html5ever", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" + +[[package]] +name = "lock_api" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "loom" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +dependencies = [ + "log", + "phf 0.8.0", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "ndk" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-glue" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk", + "ndk-macro", + "ndk-sys", +] + +[[package]] +name = "ndk-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +dependencies = [ + "darling 0.10.2", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "os_pipe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3492ebca331b895fe23ed427dce2013d9b2e00c45964f12040b0db38b8ab27" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "pango" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79211eff430c29cc38c69e0ab54bc78fa1568121ca9737707eee7f92a8417a94" +dependencies = [ + "bitflags", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.4", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "png" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" +dependencies = [ + "bitflags", + "deflate 0.7.20", + "inflate", + "num-iter", +] + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.8.6", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba75eee94a9d5273a68c9e1e105d9cffe1ef700532325788389e5a83e2522b7" +dependencies = [ + "cty", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.4", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "resources" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "tauri", + "tauri-build", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.5", +] + +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +dependencies = [ + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_with" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1e6ec4d8950e5b1e894eac0d360742f3b1407a6078a604a731c4b3f49cefbc" +dependencies = [ + "rustversion", + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" +dependencies = [ + "darling 0.13.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9186a81e763ca2a5e13ba76d843534620bffe0cf1e76e1a2f2d231ba1db79b82" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3ff83d7962f690dbe675ca0fd516c097194723b6bda8c7c500d35f0b02902e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared_child" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "siphasher" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "soup2-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f056675eda9a7417163e5f742bb119e8e1d385edd2ada8f7031a7230a3ec10a" +dependencies = [ + "bitflags", + "gio-sys 0.14.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" + +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "sys-info" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "system-deps" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" +dependencies = [ + "anyhow", + "cfg-expr 0.8.1", + "heck 0.3.3", + "itertools", + "pkg-config", + "strum", + "strum_macros", + "thiserror", + "toml", + "version-compare 0.0.11", +] + +[[package]] +name = "system-deps" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.3.3", + "pkg-config", + "toml", + "version-compare 0.0.11", +] + +[[package]] +name = "system-deps" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad3a97fdef3daf935d929b3e97e5a6a680cd4622e40c2941ca0875d6566416f8" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.4.0", + "pkg-config", + "toml", + "version-compare 0.1.0", +] + +[[package]] +name = "tao" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d2bba60298cbc0ff0651fe5a0bdfb73438b91231f700dcc8d539548237cae7" +dependencies = [ + "bitflags", + "cairo-rs", + "cc", + "cocoa", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys 0.15.5", + "gtk", + "instant", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-glue", + "ndk-sys", + "objc", + "parking_lot", + "raw-window-handle", + "scopeguard", + "serde", + "tao-core-video-sys", + "unicode-segmentation", + "windows", + "windows_macros", + "x11-dl", +] + +[[package]] +name = "tao-core-video-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271450eb289cb4d8d0720c6ce70c72c8c858c93dd61fc625881616752e6b98f6" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "objc", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tauri" +version = "1.0.0-beta.8" +dependencies = [ + "bincode", + "cfg_aliases", + "dirs-next", + "either", + "embed_plist", + "flate2", + "futures", + "futures-lite", + "glib", + "glob", + "gtk", + "http", + "ignore", + "once_cell", + "os_pipe", + "percent-encoding", + "rand 0.8.4", + "raw-window-handle", + "regex", + "semver 1.0.5", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "shared_child", + "state", + "tar", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "tempfile", + "thiserror", + "tokio", + "url", + "uuid", + "zip", +] + +[[package]] +name = "tauri-build" +version = "1.0.0-beta.4" +dependencies = [ + "anyhow", + "cargo_toml", + "quote", + "serde_json", + "tauri-codegen", + "tauri-utils", + "winres", +] + +[[package]] +name = "tauri-codegen" +version = "1.0.0-beta.4" +dependencies = [ + "base64", + "blake3", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "sha2", + "tauri-utils", + "thiserror", + "uuid", + "walkdir", + "zstd", +] + +[[package]] +name = "tauri-macros" +version = "1.0.0-beta.5" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-runtime" +version = "0.2.1" +dependencies = [ + "gtk", + "http", + "http-range", + "infer", + "serde", + "serde_json", + "tauri-utils", + "thiserror", + "uuid", + "webview2-com", + "windows", +] + +[[package]] +name = "tauri-runtime-wry" +version = "0.2.1" +dependencies = [ + "gtk", + "ico", + "infer", + "png 0.16.8", + "tauri-runtime", + "tauri-utils", + "uuid", + "webview2-com", + "windows", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "1.0.0-beta.3" +dependencies = [ + "ctor", + "glob", + "heck 0.4.0", + "html5ever", + "json-patch", + "kuchiki", + "phf 0.10.1", + "proc-macro2", + "quote", + "serde", + "serde_json", + "serde_with", + "serialize-to-javascript", + "thiserror", + "url", + "walkdir", + "zstd", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tendril" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" +dependencies = [ + "bytes", + "memchr", + "num_cpus", + "pin-project-lite", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d8d93354fe2a8e50d5953f5ae2e47a3fc2ef03292e7ea46e3cc38f549525fb9" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8276d9a4a3a558d7b7ad5303ad50b53d58264641b82914b7ada36bd762e7a716" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +dependencies = [ + "lazy_static", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74786ce43333fcf51efe947aed9718fbe46d5c7328ec3f1029e818083966d9aa" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "treediff" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" +dependencies = [ + "serde_json", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version-compare" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "webkit2gtk" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cbd39499e917de9dad36eb11c09f665eb984d432638ae7971feed98eb96df88" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys 0.15.5", + "glib", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddcce6f1e0fc7715d651dba29875741509f5fc12f4e2976907272a74405f2b01" +dependencies = [ + "atk-sys", + "bitflags", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pango-sys", + "pkg-config", + "soup2-sys", + "system-deps 5.0.0", +] + +[[package]] +name = "webview2-com" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1975ce3573344c099935fe3903f1708dac69efe8539f1efee3ae54d8f9315fbb" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows_macros", +] + +[[package]] +name = "webview2-com-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515c6c82fcee93f6edaacc72c8e233dbe4ff3ca569dce1901dfc36c404a3e99" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "webview2-com-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a746838a94b7391f707209a246e3436d81d1e71832126a65a897d3ee5511040" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows", + "windows-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-bindgen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "944c545fcae9dd66488308f8b69aa3ba34f53714416ecfcdcbbfa4b6821e27c6" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca" + +[[package]] +name = "windows_gen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30dff4d91d22520628bb94b66f2bb313cb16a09a515a32320a84a1b449bc94c0" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_i686_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8" + +[[package]] +name = "windows_i686_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6" + +[[package]] +name = "windows_macros" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ae44ab917e9005fe710d99d52d227ca0164b10a09be90649142cc3fab825d3" +dependencies = [ + "syn", + "windows_gen", + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_quote" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71f02c51a77e6248c1206aaa920802c32d50a05205e229b118d7f3afd3036667" + +[[package]] +name = "windows_reader" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e44e6df0da993cda589c5ac852272fbb2a0ead67a031a017dd3eac11528a2d72" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1" + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", +] + +[[package]] +name = "wry" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194b2750d8fe10fef189af5e2ca09e56cb8c5458a365d2b32842b024351f58c9" +dependencies = [ + "cocoa", + "core-graphics", + "gdk", + "gio", + "glib", + "gtk", + "http", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sys-info", + "tao", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows_macros", +] + +[[package]] +name = "x11" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd0565fa8bfba8c5efe02725b14dff114c866724eff2cfd44d76cea74bcd87a" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +dependencies = [ + "lazy_static", + "libc", + "pkg-config", +] + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "bzip2", + "crc32fast", + "flate2", + "thiserror", + "time", +] + +[[package]] +name = "zstd" +version = "0.10.0+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b1365becbe415f3f0fcd024e2f7b45bacfb5bdd055f0dc113571394114e7bdd" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "4.1.4+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f7cd17c9af1a4d6c24beb1cc54b17e2ef7b593dc92f19e9d9acad8b182bbaee" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.6.3+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8" +dependencies = [ + "cc", + "libc", +] diff --git a/examples/resources/src-tauri/Cargo.toml b/examples/resources/src-tauri/Cargo.toml index d2bbd4129981..c193cbed4f23 100644 --- a/examples/resources/src-tauri/Cargo.toml +++ b/examples/resources/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "resources" version = "0.1.0" description = "A Tauri application that uses Node.js with app resources" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } diff --git a/examples/resources/src-tauri/src/main.rs b/examples/resources/src-tauri/src/main.rs index 5840d0fde92b..16dc142c30fd 100644 --- a/examples/resources/src-tauri/src/main.rs +++ b/examples/resources/src-tauri/src/main.rs @@ -7,32 +7,22 @@ windows_subsystem = "windows" )] -#[cfg(not(any(feature = "api-all", feature = "shell-all", feature = "shell-execute")))] -fn main() { - eprintln!("Not supported without `api-all`, `shell-all` or `shell-execute`") -} - -#[cfg(any(feature = "api-all", feature = "shell-all", feature = "shell-execute"))] fn main() { use tauri::{ - api::{ - path::{resolve_path, BaseDirectory}, - process::{Command, CommandEvent}, - }, + api::process::{Command, CommandEvent}, Manager, }; - let context = tauri::generate_context!("../../examples/resources/src-tauri/tauri.conf.json"); - let script_path = resolve_path( - context.config(), - context.package_info(), - "assets/index.js", - Some(BaseDirectory::Resource), - ) - .unwrap(); + tauri::Builder::default() .setup(move |app| { let window = app.get_window("main").unwrap(); - let script_path = script_path.to_string_lossy().to_string(); + let script_path = app + .path_resolver() + .resource_dir() + .unwrap() + .join("assets/index.js") + .to_string_lossy() + .to_string(); tauri::async_runtime::spawn(async move { let (mut rx, _child) = Command::new("node") .args(&[script_path]) @@ -51,6 +41,6 @@ fn main() { Ok(()) }) - .run(context) + .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/examples/resources/src-tauri/tauri.conf.json b/examples/resources/src-tauri/tauri.conf.json index 879b67e3715d..d2a7c35c81df 100644 --- a/examples/resources/src-tauri/tauri.conf.json +++ b/examples/resources/src-tauri/tauri.conf.json @@ -51,7 +51,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" + "csp": "default-src 'self'" }, "updater": { "active": false diff --git a/examples/sidecar/README.md b/examples/sidecar/README.md index 7ecc9ecdb07a..4bf47bf5584f 100644 --- a/examples/sidecar/README.md +++ b/examples/sidecar/README.md @@ -1,3 +1,43 @@ # Sidecar example This example demonstrates how to use the Tauri sidecar feature. It uses [pkg](https://github.com/vercel/pkg) to compile a Node.js application and bundle it on the Tauri application. + +## Running the example + +- Compile Tauri +go to root of the Tauri repo and run: +Linux / Mac: +``` +# choose to install node cli (1) +bash .scripts/setup.sh +``` + +Windows: +``` +./.scripts/setup.ps1 +``` + +- Install dependencies (Run inside of this folder `examples/sidecar/`) +```bash +# with yarn +$ yarn +# with npm +$ npm install + +$ yarn tauri +$ yarn package +``` + +- Run the app in development mode (Run inside of this folder `examples/sidecar/`) +```bash +# with yarn +$ yarn tauri dev +# with npm +$ npm run tauri dev +``` + +- Build an run the release app (Run inside of this folder `examples/sidecar/`) +```bash +$ yarn tauri build +$ ./src-tauri/target/release/app +``` diff --git a/examples/sidecar/index.html b/examples/sidecar/index.html index 1ab8c4f4e47a..04ae01ffe33a 100644 --- a/examples/sidecar/index.html +++ b/examples/sidecar/index.html @@ -13,7 +13,7 @@ const div = document.querySelector('div') window.__TAURI__.event.listen('message', (event) => { const p = document.createElement('p') - p.innerHTML = event.payload + p.innerText = event.payload div.appendChild(p) }) diff --git a/examples/sidecar/package.json b/examples/sidecar/package.json index e74398ca6fad..b40a204049a0 100644 --- a/examples/sidecar/package.json +++ b/examples/sidecar/package.json @@ -8,11 +8,11 @@ ] }, "scripts": { - "tauri": "node ../../tooling/cli.js/bin/tauri", + "tauri": "node ../../tooling/cli/node/tauri.js", "package": "pkg package.json --output src-tauri/binaries/app && node scripts/move-binary.js" }, "devDependencies": { "execa": "5.1.1", "pkg": "5.2.1" } -} +} \ No newline at end of file diff --git a/examples/sidecar/src-tauri/.gitignore b/examples/sidecar/src-tauri/.gitignore index d0b75524c84d..3bbdbf4b4dc3 100644 --- a/examples/sidecar/src-tauri/.gitignore +++ b/examples/sidecar/src-tauri/.gitignore @@ -3,9 +3,3 @@ /target/ binaries/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/sidecar/src-tauri/Cargo.lock b/examples/sidecar/src-tauri/Cargo.lock new file mode 100644 index 000000000000..d665125a4026 --- /dev/null +++ b/examples/sidecar/src-tauri/Cargo.lock @@ -0,0 +1,3347 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "atk" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" +dependencies = [ + "atk-sys", + "bitflags", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake3" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.1", + "rayon", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cairo-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b869e97a87170f96762f9f178eae8c461147e722ba21dd8814105bf5716bf14a" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +dependencies = [ + "glib-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "cargo_toml" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363c7cfaa15f101415c4ac9e68706ca4a2277773932828b33f96e59d28c68e62" +dependencies = [ + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfb" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca453e8624711b2f0f4eb47076a318feda166252a827ee25d067b43de83dcba0" +dependencies = [ + "byteorder", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cocoa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + +[[package]] +name = "darling" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +dependencies = [ + "darling_core 0.13.1", + "darling_macro 0.13.1", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.9.3", + "syn", +] + +[[package]] +name = "darling_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core 0.10.2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +dependencies = [ + "darling_core 0.13.1", + "quote", + "syn", +] + +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", + "generic-array", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dtoa-short" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +dependencies = [ + "dtoa", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "field-offset" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +dependencies = [ + "memoffset", + "rustc_version 0.3.3", +] + +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614258e81ec35ed8770e64a0838f3a47f95b398bc51e724d3b3fa09c1ee0f8d5" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73aa2f5de1b45710da90a55863276667dc3a3264aaf6a2aeace62bb015244d49" +dependencies = [ + "bitflags", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171" +dependencies = [ + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "gdk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "pango-sys", + "pkg-config", + "system-deps 6.0.1", +] + +[[package]] +name = "gdkx11-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178" +dependencies = [ + "gdk-sys", + "glib-sys 0.15.5", + "libc", + "system-deps 6.0.1", + "x11", +] + +[[package]] +name = "generator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "winapi", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gio" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59105fa464928adf56b159c8d980cc11fbfbe414befb904caac5163d383049bf" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys 0.15.5", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" +dependencies = [ + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 3.2.0", + "winapi", +] + +[[package]] +name = "gio-sys" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f0bc4cfc9ebcdd05cc5057bc51b99c32f8f9bf246274f6a556ffd27279f8fe3" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", + "winapi", +] + +[[package]] +name = "glib" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dcfbdb6cc6c02aee163339465d8a40d6f3f64c3a43f729a4195f0e153338b7" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e58b262ff65ef771003873cea8c10e0fe854f1c508d48d62a4111a1ff163f7d1" +dependencies = [ + "anyhow", + "heck 0.4.0", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" +dependencies = [ + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "glib-sys" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1d4e1a63d8574541e5b92931e4e669ddc87ffa85d58e84e631dba13ad2e10c" +dependencies = [ + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "globset" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "gobject-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" +dependencies = [ + "glib-sys 0.14.0", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gobject-sys" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a" +dependencies = [ + "glib-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "gtk" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7978eaec05bea63947c801d29a21372f2ed39aec0bf56bf7725d3599094675e" +dependencies = [ + "atk", + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "pango-sys", + "system-deps 6.0.1", +] + +[[package]] +name = "gtk3-macros" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c891188af69e77a1e8a0b1746fbd03b9b396e7d34d518c5331b15950259f541" +dependencies = [ + "anyhow", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "html5ever" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.1", +] + +[[package]] +name = "http-range" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee9694f83d9b7c09682fdb32213682939507884e5bcf227be9aff5d644b90dc" + +[[package]] +name = "ico" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" +dependencies = [ + "byteorder", + "png 0.11.0", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "infer" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92b41dab759f9e8427c03f519c344a14655490b8db548dac1e57a75b3258391" +dependencies = [ + "cfb", +] + +[[package]] +name = "inflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" +dependencies = [ + "adler32", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "javascriptcore-rs" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c" +dependencies = [ + "bitflags", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "json-patch" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" +dependencies = [ + "serde", + "serde_json", + "treediff", +] + +[[package]] +name = "kuchiki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +dependencies = [ + "cssparser", + "html5ever", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" + +[[package]] +name = "lock_api" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "loom" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +dependencies = [ + "log", + "phf 0.8.0", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "ndk" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-glue" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk", + "ndk-macro", + "ndk-sys", +] + +[[package]] +name = "ndk-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +dependencies = [ + "darling 0.10.2", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "os_pipe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3492ebca331b895fe23ed427dce2013d9b2e00c45964f12040b0db38b8ab27" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "pango" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79211eff430c29cc38c69e0ab54bc78fa1568121ca9737707eee7f92a8417a94" +dependencies = [ + "bitflags", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", +] + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.4", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "png" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" +dependencies = [ + "bitflags", + "deflate 0.7.20", + "inflate", + "num-iter", +] + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.8.6", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba75eee94a9d5273a68c9e1e105d9cffe1ef700532325788389e5a83e2522b7" +dependencies = [ + "cty", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.4", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.5", +] + +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +dependencies = [ + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_with" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1e6ec4d8950e5b1e894eac0d360742f3b1407a6078a604a731c4b3f49cefbc" +dependencies = [ + "rustversion", + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" +dependencies = [ + "darling 0.13.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9186a81e763ca2a5e13ba76d843534620bffe0cf1e76e1a2f2d231ba1db79b82" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3ff83d7962f690dbe675ca0fd516c097194723b6bda8c7c500d35f0b02902e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared_child" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "sidecar" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "tauri", + "tauri-build", +] + +[[package]] +name = "siphasher" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "soup2-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f056675eda9a7417163e5f742bb119e8e1d385edd2ada8f7031a7230a3ec10a" +dependencies = [ + "bitflags", + "gio-sys 0.14.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" + +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "sys-info" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "system-deps" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" +dependencies = [ + "anyhow", + "cfg-expr 0.8.1", + "heck 0.3.3", + "itertools", + "pkg-config", + "strum", + "strum_macros", + "thiserror", + "toml", + "version-compare 0.0.11", +] + +[[package]] +name = "system-deps" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.3.3", + "pkg-config", + "toml", + "version-compare 0.0.11", +] + +[[package]] +name = "system-deps" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad3a97fdef3daf935d929b3e97e5a6a680cd4622e40c2941ca0875d6566416f8" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.4.0", + "pkg-config", + "toml", + "version-compare 0.1.0", +] + +[[package]] +name = "tao" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d2bba60298cbc0ff0651fe5a0bdfb73438b91231f700dcc8d539548237cae7" +dependencies = [ + "bitflags", + "cairo-rs", + "cc", + "cocoa", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys 0.15.5", + "gtk", + "instant", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-glue", + "ndk-sys", + "objc", + "parking_lot", + "raw-window-handle", + "scopeguard", + "serde", + "tao-core-video-sys", + "unicode-segmentation", + "windows", + "windows_macros", + "x11-dl", +] + +[[package]] +name = "tao-core-video-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271450eb289cb4d8d0720c6ce70c72c8c858c93dd61fc625881616752e6b98f6" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "objc", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tauri" +version = "1.0.0-beta.8" +dependencies = [ + "bincode", + "cfg_aliases", + "dirs-next", + "either", + "embed_plist", + "flate2", + "futures", + "futures-lite", + "glib", + "glob", + "gtk", + "http", + "ignore", + "once_cell", + "os_pipe", + "percent-encoding", + "rand 0.8.4", + "raw-window-handle", + "regex", + "semver 1.0.5", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "shared_child", + "state", + "tar", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "tempfile", + "thiserror", + "tokio", + "url", + "uuid", + "zip", +] + +[[package]] +name = "tauri-build" +version = "1.0.0-beta.4" +dependencies = [ + "anyhow", + "cargo_toml", + "quote", + "serde_json", + "tauri-codegen", + "tauri-utils", + "winres", +] + +[[package]] +name = "tauri-codegen" +version = "1.0.0-beta.4" +dependencies = [ + "base64", + "blake3", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "sha2", + "tauri-utils", + "thiserror", + "uuid", + "walkdir", + "zstd", +] + +[[package]] +name = "tauri-macros" +version = "1.0.0-beta.5" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-runtime" +version = "0.2.1" +dependencies = [ + "gtk", + "http", + "http-range", + "infer", + "serde", + "serde_json", + "tauri-utils", + "thiserror", + "uuid", + "webview2-com", + "windows", +] + +[[package]] +name = "tauri-runtime-wry" +version = "0.2.1" +dependencies = [ + "gtk", + "ico", + "infer", + "png 0.16.8", + "tauri-runtime", + "tauri-utils", + "uuid", + "webview2-com", + "windows", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "1.0.0-beta.3" +dependencies = [ + "ctor", + "glob", + "heck 0.4.0", + "html5ever", + "json-patch", + "kuchiki", + "phf 0.10.1", + "proc-macro2", + "quote", + "serde", + "serde_json", + "serde_with", + "serialize-to-javascript", + "thiserror", + "url", + "walkdir", + "zstd", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tendril" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" +dependencies = [ + "bytes", + "memchr", + "num_cpus", + "pin-project-lite", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d8d93354fe2a8e50d5953f5ae2e47a3fc2ef03292e7ea46e3cc38f549525fb9" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8276d9a4a3a558d7b7ad5303ad50b53d58264641b82914b7ada36bd762e7a716" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +dependencies = [ + "lazy_static", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74786ce43333fcf51efe947aed9718fbe46d5c7328ec3f1029e818083966d9aa" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "treediff" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" +dependencies = [ + "serde_json", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version-compare" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "webkit2gtk" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cbd39499e917de9dad36eb11c09f665eb984d432638ae7971feed98eb96df88" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys 0.15.5", + "glib", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddcce6f1e0fc7715d651dba29875741509f5fc12f4e2976907272a74405f2b01" +dependencies = [ + "atk-sys", + "bitflags", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pango-sys", + "pkg-config", + "soup2-sys", + "system-deps 5.0.0", +] + +[[package]] +name = "webview2-com" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1975ce3573344c099935fe3903f1708dac69efe8539f1efee3ae54d8f9315fbb" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows_macros", +] + +[[package]] +name = "webview2-com-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515c6c82fcee93f6edaacc72c8e233dbe4ff3ca569dce1901dfc36c404a3e99" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "webview2-com-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a746838a94b7391f707209a246e3436d81d1e71832126a65a897d3ee5511040" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows", + "windows-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-bindgen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "944c545fcae9dd66488308f8b69aa3ba34f53714416ecfcdcbbfa4b6821e27c6" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca" + +[[package]] +name = "windows_gen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30dff4d91d22520628bb94b66f2bb313cb16a09a515a32320a84a1b449bc94c0" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_i686_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8" + +[[package]] +name = "windows_i686_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6" + +[[package]] +name = "windows_macros" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ae44ab917e9005fe710d99d52d227ca0164b10a09be90649142cc3fab825d3" +dependencies = [ + "syn", + "windows_gen", + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_quote" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71f02c51a77e6248c1206aaa920802c32d50a05205e229b118d7f3afd3036667" + +[[package]] +name = "windows_reader" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e44e6df0da993cda589c5ac852272fbb2a0ead67a031a017dd3eac11528a2d72" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1" + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", +] + +[[package]] +name = "wry" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194b2750d8fe10fef189af5e2ca09e56cb8c5458a365d2b32842b024351f58c9" +dependencies = [ + "cocoa", + "core-graphics", + "gdk", + "gio", + "glib", + "gtk", + "http", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sys-info", + "tao", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows_macros", +] + +[[package]] +name = "x11" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd0565fa8bfba8c5efe02725b14dff114c866724eff2cfd44d76cea74bcd87a" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +dependencies = [ + "lazy_static", + "libc", + "pkg-config", +] + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "bzip2", + "crc32fast", + "flate2", + "thiserror", + "time", +] + +[[package]] +name = "zstd" +version = "0.10.0+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b1365becbe415f3f0fcd024e2f7b45bacfb5bdd055f0dc113571394114e7bdd" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "4.1.4+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f7cd17c9af1a4d6c24beb1cc54b17e2ef7b593dc92f19e9d9acad8b182bbaee" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.6.3+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8" +dependencies = [ + "cc", + "libc", +] diff --git a/examples/sidecar/src-tauri/Cargo.toml b/examples/sidecar/src-tauri/Cargo.toml index e2bc34f86dbc..74b02b3ccf6e 100644 --- a/examples/sidecar/src-tauri/Cargo.toml +++ b/examples/sidecar/src-tauri/Cargo.toml @@ -2,10 +2,11 @@ name = "sidecar" version = "0.1.0" description = "A Tauri application with a sidecar binary" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] -tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } +tauri-build = { path = "../../../core/tauri-build", features = ["codegen"] } [dependencies] serde_json = "1.0" diff --git a/examples/sidecar/src-tauri/src/main.rs b/examples/sidecar/src-tauri/src/main.rs index 44d63ed68c26..5bd3afadd700 100644 --- a/examples/sidecar/src-tauri/src/main.rs +++ b/examples/sidecar/src-tauri/src/main.rs @@ -39,8 +39,6 @@ fn main() { Ok(()) }) - .run(tauri::generate_context!( - "../../examples/sidecar/src-tauri/tauri.conf.json" - )) + .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/examples/sidecar/src-tauri/tauri.conf.json b/examples/sidecar/src-tauri/tauri.conf.json index 64b8e22fc464..07070202ebfe 100644 --- a/examples/sidecar/src-tauri/tauri.conf.json +++ b/examples/sidecar/src-tauri/tauri.conf.json @@ -51,7 +51,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" + "csp": "default-src 'self'" }, "updater": { "active": false diff --git a/examples/sidecar/yarn.lock b/examples/sidecar/yarn.lock index 008ef00025a8..c420541e41c9 100644 --- a/examples/sidecar/yarn.lock +++ b/examples/sidecar/yarn.lock @@ -605,9 +605,11 @@ node-abi@^2.7.0: semver "^5.4.1" node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" noop-logger@^0.1.1: version "0.1.1" @@ -882,9 +884,9 @@ simple-concat@^1.0.0: integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== simple-get@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" - integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + version "3.1.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55" + integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== dependencies: decompress-response "^4.2.0" once "^1.3.1" @@ -1018,6 +1020,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + tslib@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" @@ -1047,6 +1054,19 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-pm-runs@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" diff --git a/examples/splashscreen/package.json b/examples/splashscreen/package.json index 6257427876a1..17e0df4ce830 100644 --- a/examples/splashscreen/package.json +++ b/examples/splashscreen/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "node ../../tooling/cli/node/tauri.js" }, "private": true -} +} \ No newline at end of file diff --git a/examples/splashscreen/src-tauri/.gitignore b/examples/splashscreen/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/splashscreen/src-tauri/.gitignore +++ b/examples/splashscreen/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/splashscreen/src-tauri/Cargo.toml b/examples/splashscreen/src-tauri/Cargo.toml index e5f58e073f06..9df6df4f93ae 100644 --- a/examples/splashscreen/src-tauri/Cargo.toml +++ b/examples/splashscreen/src-tauri/Cargo.toml @@ -2,14 +2,15 @@ name = "splashscreen" version = "0.1.0" description = "An example Tauri Application with a splashscreen" -edition = "2018" +edition = "2021" +rust-version = "1.57" license = "Apache-2.0 OR MIT" [build-dependencies] tauri-build = { path = "../../../core/tauri-build" } [dependencies] -tauri = { path = "../../../core/tauri", features = ["api-all"] } +tauri = { path = "../../../core/tauri", features = [] } [features] default = [ "custom-protocol" ] diff --git a/examples/splashscreen/src-tauri/src/main.rs b/examples/splashscreen/src-tauri/src/main.rs index fd3350ecade1..382f088ad548 100644 --- a/examples/splashscreen/src-tauri/src/main.rs +++ b/examples/splashscreen/src-tauri/src/main.rs @@ -22,7 +22,7 @@ mod rust { .setup(|app| { let splashscreen_window = app.get_window("splashscreen").unwrap(); let main_window = app.get_window("main").unwrap(); - // we perform the initialization code on a new task so the app doesn't freeze + // we perform the initialization code on a new task so the app doesn't crash tauri::async_runtime::spawn(async move { println!("Initializing..."); sleep(Duration::from_secs(2)); diff --git a/examples/splashscreen/src-tauri/tauri.conf.json b/examples/splashscreen/src-tauri/tauri.conf.json index f7cd9dc7fa3d..8a79e28ac69a 100644 --- a/examples/splashscreen/src-tauri/tauri.conf.json +++ b/examples/splashscreen/src-tauri/tauri.conf.json @@ -22,7 +22,7 @@ "category": "DeveloperTool" }, "allowlist": { - "all": true + "all": false }, "windows": [ { @@ -42,7 +42,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'" + "csp": "default-src 'self'" }, "updater": { "active": false diff --git a/examples/state/README.md b/examples/state/README.md new file mode 100644 index 000000000000..f6a401e4017a --- /dev/null +++ b/examples/state/README.md @@ -0,0 +1,5 @@ +# State example + +A simple Tauri Appplication showcase the application State usage. + +To execute run the following on the root directory of the repository: `cargo run --example state` diff --git a/examples/state/index.html b/examples/state/index.html index be4f4c483f1e..a5f18f2df095 100644 --- a/examples/state/index.html +++ b/examples/state/index.html @@ -31,7 +31,7 @@

    Database

    const responseContainer = document.querySelector('#response') function updateResponse(response) { - responseContainer.innerHTML = + responseContainer.innerText = typeof response === 'string' ? response : JSON.stringify(response) } diff --git a/examples/state/package.json b/examples/state/package.json index 03c879d0ee21..f4e2f37e079e 100644 --- a/examples/state/package.json +++ b/examples/state/package.json @@ -2,6 +2,6 @@ "name": "hello-world", "version": "1.0.0", "scripts": { - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "ncargo tauri" } } diff --git a/examples/state/src-tauri/.gitignore b/examples/state/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/state/src-tauri/.gitignore +++ b/examples/state/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/state/src-tauri/Cargo.toml b/examples/state/src-tauri/Cargo.toml index 546a2b107a82..410906e04956 100644 --- a/examples/state/src-tauri/Cargo.toml +++ b/examples/state/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "state" version = "0.1.0" description = "A simple Tauri Appplication showcase the state functionality" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } @@ -10,7 +11,7 @@ tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } [dependencies] serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } -tauri = { path = "../../../core/tauri", features = ["api-all"] } +tauri = { path = "../../../core/tauri", features = [] } [features] default = [ "custom-protocol" ] diff --git a/examples/state/src-tauri/src/main.rs b/examples/state/src-tauri/src/main.rs index ed86a4b6ce33..459f9e5dd99a 100644 --- a/examples/state/src-tauri/src/main.rs +++ b/examples/state/src-tauri/src/main.rs @@ -32,18 +32,18 @@ impl Client { struct Connection(Mutex>); #[tauri::command] -fn connect(connection: State) { +fn connect(connection: State<'_, Connection>) { *connection.0.lock().unwrap() = Some(Client {}); } #[tauri::command] -fn disconnect(connection: State) { +fn disconnect(connection: State<'_, Connection>) { // drop the connection *connection.0.lock().unwrap() = None; } #[tauri::command] -fn connection_send(connection: State) { +fn connection_send(connection: State<'_, Connection>) { connection .0 .lock() @@ -54,17 +54,17 @@ fn connection_send(connection: State) { } #[tauri::command] -fn increment_counter(counter: State) -> usize { +fn increment_counter(counter: State<'_, Counter>) -> usize { counter.0.fetch_add(1, Ordering::Relaxed) + 1 } #[tauri::command] -fn db_insert(key: String, value: String, db: State) { +fn db_insert(key: String, value: String, db: State<'_, Database>) { db.0.lock().unwrap().insert(key, value); } #[tauri::command] -fn db_read(key: String, db: State) -> Option { +fn db_read(key: String, db: State<'_, Database>) -> Option { db.0.lock().unwrap().get(&key).cloned() } diff --git a/examples/state/src-tauri/tauri.conf.json b/examples/state/src-tauri/tauri.conf.json index 64a16926c0e0..e4af12b6718c 100644 --- a/examples/state/src-tauri/tauri.conf.json +++ b/examples/state/src-tauri/tauri.conf.json @@ -36,7 +36,7 @@ } }, "allowlist": { - "all": true + "all": false }, "windows": [ { @@ -48,7 +48,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" + "csp": "default-src 'self'" }, "updater": { "active": false diff --git a/examples/streaming/README.md b/examples/streaming/README.md new file mode 100644 index 000000000000..4a1cf4f1b4f5 --- /dev/null +++ b/examples/streaming/README.md @@ -0,0 +1,5 @@ +# Streaming example + +A simple Tauri Appplication showcase the streaming functionality. + +To execute run the following on the root directory of the repository: `cargo run --example streaming`. diff --git a/examples/streaming/index.html b/examples/streaming/index.html index 6ed6bb68d89f..bf802564f114 100644 --- a/examples/streaming/index.html +++ b/examples/streaming/index.html @@ -4,11 +4,16 @@ + diff --git a/examples/streaming/package.json b/examples/streaming/package.json index 390bf1567041..1c04c4e4986a 100644 --- a/examples/streaming/package.json +++ b/examples/streaming/package.json @@ -2,6 +2,6 @@ "name": "streaming", "version": "1.0.0", "scripts": { - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "node ../../tooling/cli/node/tauri.js" } -} +} \ No newline at end of file diff --git a/examples/streaming/src-tauri/.gitignore b/examples/streaming/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/streaming/src-tauri/.gitignore +++ b/examples/streaming/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/streaming/src-tauri/Cargo.lock b/examples/streaming/src-tauri/Cargo.lock deleted file mode 100644 index cfd41540588d..000000000000 --- a/examples/streaming/src-tauri/Cargo.lock +++ /dev/null @@ -1,3165 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" - -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - -[[package]] -name = "arrayvec" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" - -[[package]] -name = "atk" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a83b21d2aa75e464db56225e1bda2dd5993311ba1095acaa8fa03d1ae67026ba" -dependencies = [ - "atk-sys", - "bitflags", - "glib", - "libc", -] - -[[package]] -name = "atk-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea" -dependencies = [ - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "libc", - "system-deps 3.2.0", -] - -[[package]] -name = "attohttpc" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8bda305457262b339322106c776e3fd21df860018e566eb6a5b1aa4b6ae02d" -dependencies = [ - "flate2", - "http", - "log", - "native-tls", - "openssl", - "serde", - "serde_json", - "serde_urlencoded", - "url", - "wildmatch", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "blake3" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcd555c66291d5f836dbb6883b48660ece810fe25a31f3bdfb911945dff2691f" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if 1.0.0", - "constant_time_eq", - "digest", - "rayon", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "bstr" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" -dependencies = [ - "memchr", -] - -[[package]] -name = "bumpalo" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" - -[[package]] -name = "bzip2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "cairo-rs" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a408c13bbc04c3337b94194c1a4d04067097439b79dbc1dcbceba299d828b9ea" -dependencies = [ - "bitflags", - "cairo-sys-rs", - "glib", - "libc", - "thiserror", -] - -[[package]] -name = "cairo-sys-rs" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80" -dependencies = [ - "glib-sys 0.14.0", - "libc", - "system-deps 3.2.0", -] - -[[package]] -name = "cc" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfb" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca453e8624711b2f0f4eb47076a318feda166252a827ee25d067b43de83dcba0" -dependencies = [ - "byteorder", - "uuid", -] - -[[package]] -name = "cfg-expr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" -dependencies = [ - "smallvec", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - -[[package]] -name = "cocoa" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" -dependencies = [ - "bitflags", - "block", - "cocoa-foundation", - "core-foundation 0.9.1", - "core-graphics 0.22.2", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" -dependencies = [ - "bitflags", - "block", - "core-foundation 0.9.1", - "core-graphics-types", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "com" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a30a2b2a013da986dc5cc3eda3d19c0d59d53f835be1b2356eb8d00f000c793" -dependencies = [ - "com_macros", -] - -[[package]] -name = "com_macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7606b05842fea68ddcc89e8053b8860ebcb2a0ba8d6abfe3a148e5d5a8d3f0c1" -dependencies = [ - "com_macros_support", - "proc-macro2", - "syn", -] - -[[package]] -name = "com_macros_support" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e9a6d20f4ac8830e309a455d7e9416e65c6af5a97c88c55fbb4c2012e107da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" -dependencies = [ - "core-foundation-sys 0.8.2", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - -[[package]] -name = "core-foundation-sys" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" - -[[package]] -name = "core-graphics" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" -dependencies = [ - "bitflags", - "core-foundation 0.7.0", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86" -dependencies = [ - "bitflags", - "core-foundation 0.9.1", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" -dependencies = [ - "bitflags", - "core-foundation 0.9.1", - "foreign-types", - "libc", -] - -[[package]] -name = "core-video-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" -dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", - "libc", - "objc", -] - -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if 1.0.0", - "lazy_static", -] - -[[package]] -name = "cssparser" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" -dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa", - "matches", - "phf 0.8.0", - "proc-macro2", - "quote", - "smallvec", - "syn", -] - -[[package]] -name = "cssparser-macros" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "deflate" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" -dependencies = [ - "adler32", - "byteorder", -] - -[[package]] -name = "deflate" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" -dependencies = [ - "adler32", - "byteorder", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "derive_more" -version = "0.99.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - -[[package]] -name = "dtoa-short" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" -dependencies = [ - "dtoa", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "embed_plist" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53dd2e43a7d32952a6054141ee0d75183958620e84e5eab045de362dff13dc99" - -[[package]] -name = "fastrand" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" -dependencies = [ - "instant", -] - -[[package]] -name = "field-offset" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" -dependencies = [ - "memoffset", - "rustc_version", -] - -[[package]] -name = "filetime" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall", - "winapi", -] - -[[package]] -name = "flate2" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "miniz_oxide 0.4.4", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "futf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" -dependencies = [ - "mac", - "new_debug_unreachable", -] - -[[package]] -name = "futures" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" - -[[package]] -name = "futures-executor" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" - -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-macro" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" -dependencies = [ - "autocfg", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" - -[[package]] -name = "futures-task" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" - -[[package]] -name = "futures-util" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" -dependencies = [ - "autocfg", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "gdk" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "679e22651cd15888e7acd01767950edca2ee9fcd6421fbf5b3c3b420d4e88bb0" -dependencies = [ - "bitflags", - "cairo-rs", - "gdk-pixbuf", - "gdk-sys", - "gio", - "glib", - "libc", - "pango", -] - -[[package]] -name = "gdk-pixbuf" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f" -dependencies = [ - "gdk-pixbuf-sys", - "gio", - "glib", - "libc", -] - -[[package]] -name = "gdk-pixbuf-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590" -dependencies = [ - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "libc", - "system-deps 3.2.0", -] - -[[package]] -name = "gdk-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e" -dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "libc", - "pango-sys", - "pkg-config", - "system-deps 3.2.0", -] - -[[package]] -name = "generator" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "winapi", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "gio" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86c6823b39d46d22cac2466de261f28d7f049ebc18f7b35296a42c7ed8a88325" -dependencies = [ - "bitflags", - "futures-channel", - "futures-core", - "futures-io", - "gio-sys 0.14.0", - "glib", - "libc", - "once_cell", - "thiserror", -] - -[[package]] -name = "gio-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e24fb752f8f5d2cf6bbc2c606fd2bc989c81c5e2fe321ab974d54f8b6344eac" -dependencies = [ - "glib-sys 0.10.1", - "gobject-sys 0.10.0", - "libc", - "system-deps 1.3.2", - "winapi", -] - -[[package]] -name = "gio-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" -dependencies = [ - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "libc", - "system-deps 3.2.0", - "winapi", -] - -[[package]] -name = "glib" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbecad7a3a898ee749d491ce2ae0decb0bce9e736f9747bc49159b1cea5d37f4" -dependencies = [ - "bitflags", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "glib-macros", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "libc", - "once_cell", - "smallvec", -] - -[[package]] -name = "glib-macros" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" -dependencies = [ - "anyhow", - "heck", - "proc-macro-crate 1.0.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "glib-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1" -dependencies = [ - "libc", - "system-deps 1.3.2", -] - -[[package]] -name = "glib-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" -dependencies = [ - "libc", - "system-deps 3.2.0", -] - -[[package]] -name = "globset" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" -dependencies = [ - "aho-corasick", - "bstr", - "fnv", - "log", - "regex", -] - -[[package]] -name = "gobject-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c" -dependencies = [ - "glib-sys 0.10.1", - "libc", - "system-deps 1.3.2", -] - -[[package]] -name = "gobject-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" -dependencies = [ - "glib-sys 0.14.0", - "libc", - "system-deps 3.2.0", -] - -[[package]] -name = "gtk" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ae864e5eab8bc8b6b8544ed259eb02dd61b25323b20e777a77aa289c05fd0c" -dependencies = [ - "atk", - "bitflags", - "cairo-rs", - "field-offset", - "futures-channel", - "gdk", - "gdk-pixbuf", - "gio", - "glib", - "gtk-sys", - "gtk3-macros", - "libc", - "once_cell", - "pango", - "pkg-config", -] - -[[package]] -name = "gtk-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e" -dependencies = [ - "atk-sys", - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "libc", - "pango-sys", - "system-deps 3.2.0", -] - -[[package]] -name = "gtk3-macros" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79" -dependencies = [ - "anyhow", - "heck", - "proc-macro-crate 1.0.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "html5ever" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" -dependencies = [ - "log", - "mac", - "markup5ever", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "http" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-range" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee9694f83d9b7c09682fdb32213682939507884e5bcf227be9aff5d644b90dc" - -[[package]] -name = "ico" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" -dependencies = [ - "byteorder", - "png 0.11.0", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "ignore" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" -dependencies = [ - "crossbeam-utils", - "globset", - "lazy_static", - "log", - "memchr", - "regex", - "same-file", - "thread_local", - "walkdir", - "winapi-util", -] - -[[package]] -name = "infer" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92b41dab759f9e8427c03f519c344a14655490b8db548dac1e57a75b3258391" -dependencies = [ - "cfb", -] - -[[package]] -name = "inflate" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" -dependencies = [ - "adler32", -] - -[[package]] -name = "instant" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "itertools" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "javascriptcore-rs" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca9c7d1445bba2889672fbadc16c3d5007bfdcf0a15a18a3a50fe9fab2c7427" -dependencies = [ - "glib", - "javascriptcore-rs-sys", -] - -[[package]] -name = "javascriptcore-rs-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f46ada8a08dcd75a10afae872fbfb51275df4a8ae0d46b8cc7c708f08dd2998" -dependencies = [ - "libc", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[package]] -name = "jobserver" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "kuchiki" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" -dependencies = [ - "cssparser", - "html5ever", - "matches", - "selectors", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" - -[[package]] -name = "lock_api" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "loom" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2111607c723d7857e0d8299d5ce7a0bf4b844d3e44f8de136b13da513eaf8fc4" -dependencies = [ - "cfg-if 1.0.0", - "generator", - "scoped-tls", - "serde", - "serde_json", -] - -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "markup5ever" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" -dependencies = [ - "log", - "phf 0.8.0", - "phf_codegen", - "string_cache", - "string_cache_codegen", - "tendril", -] - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "memoffset" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" -dependencies = [ - "autocfg", -] - -[[package]] -name = "miniz_oxide" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" -dependencies = [ - "adler32", -] - -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg", -] - -[[package]] -name = "native-tls" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ndk" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" -dependencies = [ - "bitflags", - "jni-sys", - "ndk-sys", - "num_enum", - "thiserror", -] - -[[package]] -name = "ndk-glue" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420" -dependencies = [ - "lazy_static", - "libc", - "log", - "ndk", - "ndk-macro", - "ndk-sys", -] - -[[package]] -name = "ndk-macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" -dependencies = [ - "darling", - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ndk-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d" - -[[package]] -name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" -dependencies = [ - "derivative", - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" -dependencies = [ - "proc-macro-crate 1.0.0", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - -[[package]] -name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[package]] -name = "openssl" -version = "0.10.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" - -[[package]] -name = "openssl-sys" -version = "0.9.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "pango" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415823a4fb9f1789785cd6e2d2413816f2ecff92380382969aaca9c400e13a19" -dependencies = [ - "bitflags", - "glib", - "libc", - "once_cell", - "pango-sys", -] - -[[package]] -name = "pango-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe" -dependencies = [ - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "libc", - "system-deps 3.2.0", -] - -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - -[[package]] -name = "parking_lot" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_macros 0.8.0", - "phf_shared 0.8.0", - "proc-macro-hack", -] - -[[package]] -name = "phf" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fc3db1018c4b59d7d582a739436478b6035138b6aecbce989fc91c3e98409f" -dependencies = [ - "phf_macros 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", -] - -[[package]] -name = "phf_codegen" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", -] - -[[package]] -name = "phf_generator" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" -dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.4", -] - -[[package]] -name = "phf_macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_macros" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" - -[[package]] -name = "png" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" -dependencies = [ - "bitflags", - "deflate 0.7.20", - "inflate", - "num-iter", -] - -[[package]] -name = "png" -version = "0.16.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" -dependencies = [ - "bitflags", - "crc32fast", - "deflate 0.8.6", - "miniz_oxide 0.3.7", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro-crate" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" -dependencies = [ - "thiserror", - "toml", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - -[[package]] -name = "proc-macro2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg", -] - -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", - "rand_hc 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "raw-window-handle" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" -dependencies = [ - "libc", -] - -[[package]] -name = "rayon" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" -dependencies = [ - "getrandom 0.2.3", - "redox_syscall", -] - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "rfd" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cede43618603a102f37bb58244534a33de7daa6a3b77f00277675eef5f8174fe" -dependencies = [ - "block", - "dispatch", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "gtk-sys", - "js-sys", - "lazy_static", - "objc", - "objc-foundation", - "objc_id", - "raw-window-handle", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winapi", -] - -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "rustversion" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - -[[package]] -name = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "security-framework" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" -dependencies = [ - "bitflags", - "core-foundation 0.9.1", - "core-foundation-sys 0.8.2", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" -dependencies = [ - "core-foundation-sys 0.8.2", - "libc", -] - -[[package]] -name = "selectors" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" -dependencies = [ - "bitflags", - "cssparser", - "derive_more", - "fxhash", - "log", - "matches", - "phf 0.8.0", - "phf_codegen", - "precomputed-hash", - "servo_arc", - "smallvec", - "thin-slice", -] - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - -[[package]] -name = "serde" -version = "1.0.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_urlencoded" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" -dependencies = [ - "dtoa", - "itoa", - "serde", - "url", -] - -[[package]] -name = "servo_arc" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" -dependencies = [ - "nodrop", - "stable_deref_trait", -] - -[[package]] -name = "siphasher" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" - -[[package]] -name = "slab" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" - -[[package]] -name = "smallvec" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" - -[[package]] -name = "soup-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7adf08565630bbb71f955f11f8a68464817ded2703a3549747c235b58a13e" -dependencies = [ - "bitflags", - "gio-sys 0.10.1", - "glib-sys 0.10.1", - "gobject-sys 0.10.0", - "libc", - "pkg-config", - "system-deps 1.3.2", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "state" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5" -dependencies = [ - "loom", -] - -[[package]] -name = "streaming" -version = "0.1.0" -dependencies = [ - "serde", - "serde_json", - "tauri", - "tauri-build", -] - -[[package]] -name = "string_cache" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a" -dependencies = [ - "lazy_static", - "new_debug_unreachable", - "phf_shared 0.8.0", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", - "proc-macro2", - "quote", -] - -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - -[[package]] -name = "strum" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b" - -[[package]] -name = "strum" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" - -[[package]] -name = "strum_macros" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "strum_macros" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "1.0.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "system-deps" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b" -dependencies = [ - "heck", - "pkg-config", - "strum 0.18.0", - "strum_macros 0.18.0", - "thiserror", - "toml", - "version-compare 0.0.10", -] - -[[package]] -name = "system-deps" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" -dependencies = [ - "anyhow", - "cfg-expr", - "heck", - "itertools", - "pkg-config", - "strum 0.21.0", - "strum_macros 0.21.1", - "thiserror", - "toml", - "version-compare 0.0.11", -] - -[[package]] -name = "tao" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa57de7c282b68f8906278543a724ed8f5a2568f069dd0cc05fc10d1f07036b" -dependencies = [ - "bitflags", - "cairo-rs", - "cc", - "cocoa", - "core-foundation 0.9.1", - "core-graphics 0.22.2", - "core-video-sys", - "crossbeam-channel", - "dispatch", - "gdk", - "gdk-pixbuf", - "gdk-sys", - "gio", - "glib", - "glib-sys 0.14.0", - "gtk", - "instant", - "lazy_static", - "libc", - "log", - "ndk", - "ndk-glue", - "ndk-sys", - "objc", - "parking_lot", - "raw-window-handle", - "scopeguard", - "serde", - "unicode-segmentation", - "winapi", - "x11-dl", -] - -[[package]] -name = "tar" -version = "0.4.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "tauri" -version = "1.0.0-beta.7" -dependencies = [ - "attohttpc", - "bincode", - "cfg_aliases", - "dirs-next", - "either", - "embed_plist", - "flate2", - "futures", - "futures-lite", - "glib", - "gtk", - "http", - "http-range", - "ignore", - "once_cell", - "percent-encoding", - "rand 0.8.4", - "raw-window-handle", - "rfd", - "semver 1.0.4", - "serde", - "serde_json", - "serde_repr", - "state", - "tar", - "tauri-macros", - "tauri-runtime", - "tauri-runtime-wry", - "tauri-utils", - "tempfile", - "thiserror", - "tokio", - "url", - "uuid", - "zip", -] - -[[package]] -name = "tauri-build" -version = "1.0.0-beta.4" -dependencies = [ - "anyhow", - "proc-macro2", - "quote", - "serde_json", - "tauri-codegen", - "tauri-utils", - "winres", -] - -[[package]] -name = "tauri-codegen" -version = "1.0.0-beta.4" -dependencies = [ - "blake3", - "kuchiki", - "proc-macro2", - "quote", - "regex", - "serde", - "serde_json", - "tauri-utils", - "thiserror", - "walkdir", - "zstd", -] - -[[package]] -name = "tauri-macros" -version = "1.0.0-beta.5" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "tauri-codegen", -] - -[[package]] -name = "tauri-runtime" -version = "0.2.0" -dependencies = [ - "gtk", - "http", - "infer", - "serde", - "serde_json", - "tauri-utils", - "thiserror", - "uuid", - "winapi", -] - -[[package]] -name = "tauri-runtime-wry" -version = "0.2.0" -dependencies = [ - "gtk", - "ico", - "infer", - "png 0.16.8", - "tauri-runtime", - "tauri-utils", - "uuid", - "winapi", - "wry", -] - -[[package]] -name = "tauri-utils" -version = "1.0.0-beta.3" -dependencies = [ - "html5ever", - "kuchiki", - "phf 0.10.0", - "proc-macro2", - "quote", - "serde", - "serde_json", - "thiserror", - "url", - "zstd", -] - -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "rand 0.8.4", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "tendril" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" -dependencies = [ - "futf", - "mac", - "utf-8", -] - -[[package]] -name = "thin-slice" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" - -[[package]] -name = "thiserror" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" -dependencies = [ - "once_cell", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "tinyvec" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b" -dependencies = [ - "autocfg", - "bytes", - "memchr", - "num_cpus", - "pin-project-lite", -] - -[[package]] -name = "toml" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" -dependencies = [ - "serde", -] - -[[package]] -name = "typenum" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "unicode-bidi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version-compare" -version = "0.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1" - -[[package]] -name = "version-compare" -version = "0.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasm-bindgen" -version = "0.2.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" - -[[package]] -name = "web-sys" -version = "0.3.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webkit2gtk" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e47b7f870883fc21612d2a51b74262f7f2cc5371f1621370817292a35300a9" -dependencies = [ - "bitflags", - "cairo-rs", - "gdk", - "gdk-sys", - "gio", - "gio-sys 0.14.0", - "glib", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "gtk", - "gtk-sys", - "javascriptcore-rs", - "libc", - "once_cell", - "webkit2gtk-sys", -] - -[[package]] -name = "webkit2gtk-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66ccc9f0cb4de7c3b92376a5bf64e7ddffb33852f092721731a039ec38dda98" -dependencies = [ - "atk-sys", - "bitflags", - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", - "gtk-sys", - "javascriptcore-rs-sys", - "libc", - "pango-sys", - "pkg-config", - "soup-sys", - "system-deps 3.2.0", -] - -[[package]] -name = "webview2" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fab1ccfdabb098b047293c8d496c1914d1c654b68fdaa3bb77cfa47c4bca2c7" -dependencies = [ - "com", - "once_cell", - "webview2-sys", - "widestring", - "winapi", -] - -[[package]] -name = "webview2-sys" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5288cef1e0cbcf7a0b961e6271e33589b8989c80b2e11078504e989b5346ff" -dependencies = [ - "com", - "winapi", -] - -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - -[[package]] -name = "wildmatch" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "winres" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4fb510bbfe5b8992ff15f77a2e6fe6cf062878f0eda00c0f44963a807ca5dc" -dependencies = [ - "toml", -] - -[[package]] -name = "wry" -version = "0.12.1" -source = "git+https://github.com/tauri-apps/wry?branch=feat/refactor-protocol#f1bd52826e3270898d4225f5020d4de9b450d7de" -dependencies = [ - "cocoa", - "core-graphics 0.22.2", - "gdk", - "gio", - "glib", - "gtk", - "http", - "libc", - "log", - "objc", - "objc_id", - "once_cell", - "serde", - "serde_json", - "tao", - "thiserror", - "url", - "webkit2gtk", - "webkit2gtk-sys", - "webview2", - "webview2-sys", - "winapi", -] - -[[package]] -name = "x11-dl" -version = "2.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" -dependencies = [ - "lazy_static", - "libc", - "maybe-uninit", - "pkg-config", -] - -[[package]] -name = "xattr" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" -dependencies = [ - "libc", -] - -[[package]] -name = "zip" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" -dependencies = [ - "byteorder", - "bzip2", - "crc32fast", - "flate2", - "thiserror", - "time", -] - -[[package]] -name = "zstd" -version = "0.9.0+zstd.1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07749a5dc2cb6b36661290245e350f15ec3bbb304e493db54a1d354480522ccd" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "4.1.1+zstd.1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91c90f2c593b003603e5e0493c837088df4469da25aafff8bce42ba48caf079" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "1.6.1+zstd.1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615120c7a2431d16cf1cf979e7fc31ba7a5b5e5707b29c8a99e5dbf8a8392a33" -dependencies = [ - "cc", - "libc", -] diff --git a/examples/streaming/src-tauri/Cargo.toml b/examples/streaming/src-tauri/Cargo.toml index 10fcf2ef2c01..e16469f5e61c 100644 --- a/examples/streaming/src-tauri/Cargo.toml +++ b/examples/streaming/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "streaming" version = "0.1.0" description = "A very simple Tauri Appplication" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } diff --git a/examples/streaming/src-tauri/src/main.rs b/examples/streaming/src-tauri/src/main.rs index 7f79143bde4d..57d860169d61 100644 --- a/examples/streaming/src-tauri/src/main.rs +++ b/examples/streaming/src-tauri/src/main.rs @@ -9,6 +9,7 @@ fn main() { use std::{ + cmp::min, io::{Read, Seek, SeekFrom}, path::PathBuf, process::{Command, Stdio}, @@ -74,7 +75,7 @@ fn main() { if range.length > file_size / 3 { // max size sent (400ko / request) // as it's local file system we can afford to read more often - real_length = 1024 * 400; + real_length = min(file_size - range.start, 1024 * 400); } // last byte we are reading, the length of the range include the last byte diff --git a/examples/streaming/src-tauri/tauri.conf.json b/examples/streaming/src-tauri/tauri.conf.json index d4a6f4a124e2..4137b946c1a1 100644 --- a/examples/streaming/src-tauri/tauri.conf.json +++ b/examples/streaming/src-tauri/tauri.conf.json @@ -47,7 +47,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: stream: 'unsafe-eval' 'unsafe-inline' 'self'" + "csp": "default-src 'self'" }, "updater": { "active": false diff --git a/examples/tauri-dynamic-lib/README.md b/examples/tauri-dynamic-lib/README.md new file mode 100644 index 000000000000..e04d5db4fea6 --- /dev/null +++ b/examples/tauri-dynamic-lib/README.md @@ -0,0 +1,36 @@ +# Readme + +This is an example of compiling tauri as a dynamic shared library and running it from another app. + + * src-tauri is an example of a library containing code to launch a tauri webview window. + * src-app1 is a small example of calling tauri from a dynamic shared library through FFI. + +Note that bundling of resources via tauri.conf.json may not work in some cases due to the nature of the build. +So you have to be aware of copying any files needed to the correct paths for html / js etc. + +## Rust libraries + +Typically there are 3 types of libraries rust can generate + + * rlib - rust static libraries + * dylib - rust shared libraries + * cdylib - dynamic shared libraries that can be used to interop with other languages. + +Typically cdylib libraries are used for interop with C / C++ Projects but this can also include other languages. +The src-tauri example uses the cdylib crate type + +## Building / Running + +``` bash +# First build the library +cd src-tauri +cargo build +cd .. + +# Next build the app +cd src-app1 +cargo build + +# Next run the app +cargo run +``` diff --git a/examples/tauri-dynamic-lib/src-app1/.gitignore b/examples/tauri-dynamic-lib/src-app1/.gitignore new file mode 100644 index 000000000000..270a92d275ed --- /dev/null +++ b/examples/tauri-dynamic-lib/src-app1/.gitignore @@ -0,0 +1,10 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +WixTools + +# These are backup files generated by rustfmt +**/*.rs.bk + +config.json +bundle.json diff --git a/tooling/cli.rs/.license_template b/examples/tauri-dynamic-lib/src-app1/.license_template similarity index 100% rename from tooling/cli.rs/.license_template rename to examples/tauri-dynamic-lib/src-app1/.license_template diff --git a/examples/tauri-dynamic-lib/src-app1/Cargo.lock b/examples/tauri-dynamic-lib/src-app1/Cargo.lock new file mode 100644 index 000000000000..53a8b2e5fb54 --- /dev/null +++ b/examples/tauri-dynamic-lib/src-app1/Cargo.lock @@ -0,0 +1,48 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "app1" +version = "0.1.0" +dependencies = [ + "libloading", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "libloading" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/examples/tauri-dynamic-lib/src-app1/Cargo.toml b/examples/tauri-dynamic-lib/src-app1/Cargo.toml new file mode 100644 index 000000000000..c547b6bfbea9 --- /dev/null +++ b/examples/tauri-dynamic-lib/src-app1/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "app1" +version = "0.1.0" +description = "A simple app that makes a dll call" +edition = "2021" +rust-version = "1.56" + +[workspace] + +[dependencies] +libloading = "0.7.2" diff --git a/examples/tauri-dynamic-lib/src-app1/src/main.rs b/examples/tauri-dynamic-lib/src-app1/src/main.rs new file mode 100644 index 000000000000..edd74437c30c --- /dev/null +++ b/examples/tauri-dynamic-lib/src-app1/src/main.rs @@ -0,0 +1,22 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +// This is an example of an application that loads and runs a dll +// Typically this could be c++, we use rust here just for convenience +// See https://michael-f-bryan.github.io/rust-ffi-guide/dynamic_loading.html + +use libloading::{Library, library_filename, Symbol}; +type LibFunctionType1 = fn(); + +fn main() { + let library_path = library_filename("../src-tauri/target/debug/tauri_app"); + println!("Loading run_tauri() from {:?}", library_path); + + unsafe { + let lib = Library::new(library_path).unwrap(); + let run_tauri: Symbol = lib.get(b"run_tauri").unwrap(); + println!("Launching webview"); + run_tauri() + } +} diff --git a/examples/tauri-dynamic-lib/src-tauri/.gitignore b/examples/tauri-dynamic-lib/src-tauri/.gitignore new file mode 100644 index 000000000000..270a92d275ed --- /dev/null +++ b/examples/tauri-dynamic-lib/src-tauri/.gitignore @@ -0,0 +1,10 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +WixTools + +# These are backup files generated by rustfmt +**/*.rs.bk + +config.json +bundle.json diff --git a/examples/tauri-dynamic-lib/src-tauri/.license_template b/examples/tauri-dynamic-lib/src-tauri/.license_template new file mode 100644 index 000000000000..9601f8a1b49f --- /dev/null +++ b/examples/tauri-dynamic-lib/src-tauri/.license_template @@ -0,0 +1,3 @@ +// Copyright {20\d{2}(-20\d{2})?} Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT \ No newline at end of file diff --git a/examples/tauri-dynamic-lib/src-tauri/Cargo.lock b/examples/tauri-dynamic-lib/src-tauri/Cargo.lock new file mode 100644 index 000000000000..331828049c0d --- /dev/null +++ b/examples/tauri-dynamic-lib/src-tauri/Cargo.lock @@ -0,0 +1,3303 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "atk" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a83b21d2aa75e464db56225e1bda2dd5993311ba1095acaa8fa03d1ae67026ba" +dependencies = [ + "atk-sys", + "bitflags", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "attohttpc" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e69e13a99a7e6e070bb114f7ff381e58c7ccc188630121fc4c2fe4bcf24cd072" +dependencies = [ + "flate2", + "http", + "log", + "native-tls", + "openssl", + "serde", + "serde_json", + "serde_urlencoded", + "url", + "wildmatch", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake3" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "526c210b4520e416420759af363083471656e819a75e831b8d2c9d5a584f2413" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if 1.0.0", + "constant_time_eq", + "digest", + "rayon", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + +[[package]] +name = "bumpalo" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cairo-rs" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b5725979db0c586d98abad2193cdb612dd40ef95cd26bd99851bf93b3cb482" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b448b876970834fda82ba3aeaccadbd760206b75388fc5c1b02f1e343b697570" +dependencies = [ + "glib-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfb" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca453e8624711b2f0f4eb47076a318feda166252a827ee25d067b43de83dcba0" +dependencies = [ + "byteorder", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edae0b9625d1fce32f7d64b71784d9b1bf8469ec1a9c417e44aaf16a9cbd7571" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cocoa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation 0.9.2", + "core-graphics 0.22.3", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation 0.9.2", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +dependencies = [ + "core-foundation-sys 0.8.3", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +dependencies = [ + "bitflags", + "core-foundation 0.7.0", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation 0.9.2", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation 0.9.2", + "foreign-types", + "libc", +] + +[[package]] +name = "core-video-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +dependencies = [ + "cfg-if 0.1.10", + "core-foundation-sys 0.7.0", + "core-graphics 0.19.2", + "libc", + "objc", +] + +[[package]] +name = "crc32fast" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dtoa-short" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +dependencies = [ + "dtoa", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "embed_plist" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53dd2e43a7d32952a6054141ee0d75183958620e84e5eab045de362dff13dc99" + +[[package]] +name = "fastrand" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +dependencies = [ + "instant", +] + +[[package]] +name = "field-offset" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +dependencies = [ + "memoffset", + "rustc_version 0.3.3", +] + +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "winapi", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" + +[[package]] +name = "futures-executor" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" + +[[package]] +name = "futures-task" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" + +[[package]] +name = "futures-util" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d749dcfc00d8de0d7c3a289e04a04293eb5ba3d8a4e64d64911d481fa9933b" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gdk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps 3.2.0", +] + +[[package]] +name = "gdkx11-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cefbc8ac7be19c9b51f54fbd7cef48b70495a4cb23a812e2137e75b484b29d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps 3.2.0", + "x11", +] + +[[package]] +name = "generator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "winapi", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gio" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711c3632b3ebd095578a9c091418d10fed492da9443f58ebc8f45efbeb215cb0" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", + "winapi", +] + +[[package]] +name = "glib" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c515f1e62bf151ef6635f528d05b02c11506de986e43b34a5c920ef0b3796a4" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" +dependencies = [ + "anyhow", + "heck 0.3.3", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" +dependencies = [ + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "globset" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "gobject-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" +dependencies = [ + "glib-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "gtk" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb51122dd3317e9327ec1e4faa151d1fa0d95664cd8fb8dcfacf4d4d29ac70c" +dependencies = [ + "atk", + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps 3.2.0", +] + +[[package]] +name = "gtk3-macros" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79" +dependencies = [ + "anyhow", + "heck 0.3.3", + "proc-macro-crate 1.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "html5ever" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.1", +] + +[[package]] +name = "http-range" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee9694f83d9b7c09682fdb32213682939507884e5bcf227be9aff5d644b90dc" + +[[package]] +name = "ico" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" +dependencies = [ + "byteorder", + "png 0.11.0", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "infer" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92b41dab759f9e8427c03f519c344a14655490b8db548dac1e57a75b3258391" +dependencies = [ + "cfb", +] + +[[package]] +name = "inflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" +dependencies = [ + "adler32", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "javascriptcore-rs" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e207780c1d1cd3c36056695e44010a19dd481574a2106cd2540edda4128a9794" +dependencies = [ + "bitflags", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2adf2de824b178d76c6017da59f4e7e95de49a766b584c59d47821a6c3dce9e2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kuchiki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +dependencies = [ + "cssparser", + "html5ever", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.112" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "loom" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" +dependencies = [ + "cfg-if 1.0.0", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +dependencies = [ + "log", + "phf 0.8.0", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "native-tls" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-glue" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk", + "ndk-macro", + "ndk-sys", +] + +[[package]] +name = "ndk-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +dependencies = [ + "darling", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "openssl" +version = "0.10.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +dependencies = [ + "bitflags", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-probe" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" + +[[package]] +name = "openssl-sys" +version = "0.9.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "pango" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546fd59801e5ca735af82839007edd226fe7d3bb06433ec48072be4439c28581" +dependencies = [ + "bitflags", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 3.2.0", +] + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.4", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "png" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" +dependencies = [ + "bitflags", + "deflate 0.7.20", + "inflate", + "num-iter", +] + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.8.6", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba75eee94a9d5273a68c9e1e105d9cffe1ef700532325788389e5a83e2522b7" +dependencies = [ + "cty", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.3", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rfd" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0c25b610bf37d9874ff224ab2791ff2272bedeb5638a2dca8b18e1270ed69b" +dependencies = [ + "block", + "dispatch", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "lazy_static", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.4", +] + +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "security-framework" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +dependencies = [ + "bitflags", + "core-foundation 0.9.2", + "core-foundation-sys 0.8.3", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +dependencies = [ + "core-foundation-sys 0.8.3", + "libc", +] + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" +dependencies = [ + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +dependencies = [ + "form_urlencoded", + "itoa 0.4.8", + "ryu", + "serde", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "siphasher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" + +[[package]] +name = "soup2-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f056675eda9a7417163e5f742bb119e8e1d385edd2ada8f7031a7230a3ec10a" +dependencies = [ + "bitflags", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923f0f39b6267d37d23ce71ae7235602134b250ace715dd2c90421998ddac0c6" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.8.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "strum" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" + +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "system-deps" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" +dependencies = [ + "anyhow", + "cfg-expr 0.8.1", + "heck 0.3.3", + "itertools", + "pkg-config", + "strum", + "strum_macros", + "thiserror", + "toml", + "version-compare", +] + +[[package]] +name = "system-deps" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" +dependencies = [ + "cfg-expr 0.9.0", + "heck 0.3.3", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.5.2" +source = "git+https://github.com/tauri-apps/tao?branch=next#f8866a084afe18983c91c67401d8759697578a9c" +dependencies = [ + "bitflags", + "cairo-rs", + "cc", + "cocoa", + "core-foundation 0.9.2", + "core-graphics 0.22.3", + "core-video-sys", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys", + "gtk", + "instant", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-glue", + "ndk-sys", + "objc", + "parking_lot", + "raw-window-handle", + "scopeguard", + "serde", + "unicode-segmentation", + "windows", + "windows_macros", + "x11-dl", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tauri" +version = "1.0.0-beta.8" +dependencies = [ + "attohttpc", + "bincode", + "cfg_aliases", + "dirs-next", + "either", + "embed_plist", + "flate2", + "futures", + "futures-lite", + "glib", + "gtk", + "http", + "ignore", + "once_cell", + "percent-encoding", + "rand 0.8.4", + "raw-window-handle", + "rfd", + "semver 1.0.4", + "serde", + "serde_json", + "serde_repr", + "state", + "tar", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "tempfile", + "thiserror", + "tokio", + "url", + "uuid", + "zip", +] + +[[package]] +name = "tauri-build" +version = "1.0.0-beta.4" +dependencies = [ + "anyhow", + "quote", + "serde_json", + "tauri-codegen", + "tauri-utils", + "winres", +] + +[[package]] +name = "tauri-codegen" +version = "1.0.0-beta.4" +dependencies = [ + "blake3", + "kuchiki", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "tauri-utils", + "thiserror", + "walkdir", + "zstd", +] + +[[package]] +name = "tauri-macros" +version = "1.0.0-beta.5" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "tauri-codegen", +] + +[[package]] +name = "tauri-runtime" +version = "0.2.1" +dependencies = [ + "gtk", + "http", + "http-range", + "infer", + "serde", + "serde_json", + "tauri-utils", + "thiserror", + "uuid", + "webview2-com", + "windows", +] + +[[package]] +name = "tauri-runtime-wry" +version = "0.2.1" +dependencies = [ + "gtk", + "ico", + "infer", + "png 0.16.8", + "tauri-runtime", + "tauri-utils", + "uuid", + "webview2-com", + "windows", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "1.0.0-beta.3" +dependencies = [ + "heck 0.4.0", + "html5ever", + "kuchiki", + "phf 0.10.1", + "proc-macro2", + "quote", + "serde", + "serde_json", + "thiserror", + "url", + "zstd", +] + +[[package]] +name = "tauri_app" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "tauri", + "tauri-build", +] + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand 0.8.4", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tendril" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" +dependencies = [ + "bytes", + "memchr", + "num_cpus", + "pin-project-lite", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d81bfa81424cc98cb034b837c985b7a290f592e5b4322f353f94a0ab0f9f594" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" + +[[package]] +name = "web-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webkit2gtk" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07654baccd8874fc7c99cc33c27052fb02804276102dff0f78f981669316e0e9" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854a0cbf3570541bf13df70aac23826da7cd88f27a722b7b2043f32637373113" +dependencies = [ + "atk-sys", + "bitflags", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pango-sys", + "pkg-config", + "soup2-sys", + "system-deps 5.0.0", +] + +[[package]] +name = "webview2-com" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0f21eed16a0078ef52de94d15d6e3a22f9998cf45bdabaf9ef4a235ae235ac" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows_macros", +] + +[[package]] +name = "webview2-com-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515c6c82fcee93f6edaacc72c8e233dbe4ff3ca569dce1901dfc36c404a3e99" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "webview2-com-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56fe9356e3729233bed63e7c002c0f5064f5d2148f169ce77eec8932a98c4c0" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows", + "windows-bindgen", +] + +[[package]] +name = "wildmatch" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac7fef12f4b59cd0a29339406cc9203ab44e440ddff6b3f5a41455349fa9cf3" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-bindgen" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01138bf46333583966ea4b86fd4f61a9b524c0f5f88bc3c18768d6b66cb6c4e" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d027175d00b01e0cbeb97d6ab6ebe03b12330a35786cbaca5252b1c4bf5d9b" + +[[package]] +name = "windows_gen" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e59eb69ef41a029911bb604a850f70ec1f58c8587511bc10ed84a3465931df0b" +dependencies = [ + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_i686_gnu" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8793f59f7b8e8b01eda1a652b2697d87b93097198ae85f823b969ca5b89bba58" + +[[package]] +name = "windows_i686_msvc" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8602f6c418b67024be2996c512f5f995de3ba417f4c75af68401ab8756796ae4" + +[[package]] +name = "windows_macros" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f6443f71f760ce91f4cc7fc81ee78f680dccb8ec110c52a92ec857a7def39a3" +dependencies = [ + "syn", + "windows_gen", + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_quote" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd83f20d7c391dc3b115a7e8a0851b71d0a9c356be2791571e858063b5f823c" + +[[package]] +name = "windows_reader" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87b34c04457bad3c5436ffe1ed262c908228bb634e3bda34f4ce2c252495787" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d615f419543e0bd7d2b3323af0d86ff19cbc4f816e6453f36a2c2ce889c354" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d95421d9ed3672c280884da53201a5c46b7b2765ca6faf34b0d71cf34a3561" + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", +] + +[[package]] +name = "wry" +version = "0.12.2" +source = "git+https://github.com/tauri-apps/wry?rev=3284f8d442978269f7654edbdfc9bc51022eaa40#3284f8d442978269f7654edbdfc9bc51022eaa40" +dependencies = [ + "cocoa", + "core-graphics 0.22.3", + "gdk", + "gio", + "glib", + "gtk", + "http", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "tao", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows_macros", +] + +[[package]] +name = "x11" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd0565fa8bfba8c5efe02725b14dff114c866724eff2cfd44d76cea74bcd87a" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +dependencies = [ + "lazy_static", + "libc", + "pkg-config", +] + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "bzip2", + "crc32fast", + "flate2", + "thiserror", + "time", +] + +[[package]] +name = "zstd" +version = "0.9.1+zstd.1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "538b8347df9257b7fbce37677ef7535c00a3c7bf1f81023cc328ed7fe4b41de8" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "4.1.2+zstd.1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb4cfe2f6e6d35c5d27ecd9d256c4b6f7933c4895654917460ec56c29336cc1" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.6.2+zstd.1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2daf2f248d9ea44454bfcb2516534e8b8ad2fc91bf818a1885495fc42bc8ac9f" +dependencies = [ + "cc", + "libc", +] diff --git a/examples/tauri-dynamic-lib/src-tauri/Cargo.toml b/examples/tauri-dynamic-lib/src-tauri/Cargo.toml new file mode 100644 index 000000000000..37c78b723f16 --- /dev/null +++ b/examples/tauri-dynamic-lib/src-tauri/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "tauri_app" +version = "0.1.0" +description = "A very simple Dll Library that runs tauri and launches a webview window" +edition = "2021" +rust-version = "1.56" + +[workspace] + +[lib] +crate-type = ["cdylib"] + +[build-dependencies] +tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } + +[dependencies] +serde_json = "1.0" +serde = { version = "1.0", features = [ "derive" ] } +tauri = { path = "../../../core/tauri", features = [] } + +[features] +default = [ "custom-protocol" ] +custom-protocol = [ "tauri/custom-protocol" ] diff --git a/examples/tauri-dynamic-lib/src-tauri/build.rs b/examples/tauri-dynamic-lib/src-tauri/build.rs new file mode 100644 index 000000000000..2ad1cb4e66a1 --- /dev/null +++ b/examples/tauri-dynamic-lib/src-tauri/build.rs @@ -0,0 +1,14 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use tauri_build::{try_build, Attributes, WindowsAttributes}; + +fn main() { + if let Err(error) = try_build( + Attributes::new() + .windows_attributes(WindowsAttributes::new().window_icon_path("../../.icons/icon.ico")), + ) { + panic!("error found during tauri-build: {}", error); + } +} diff --git a/examples/tauri-dynamic-lib/src-tauri/src/index.html b/examples/tauri-dynamic-lib/src-tauri/src/index.html new file mode 100644 index 000000000000..7035e7f7b5c7 --- /dev/null +++ b/examples/tauri-dynamic-lib/src-tauri/src/index.html @@ -0,0 +1,12 @@ + + + + + + + Welcome to Tauri! + + +

    Welcome to Tauri!

    + + diff --git a/examples/tauri-dynamic-lib/src-tauri/src/lib.rs b/examples/tauri-dynamic-lib/src-tauri/src/lib.rs new file mode 100644 index 000000000000..ab2d29475544 --- /dev/null +++ b/examples/tauri-dynamic-lib/src-tauri/src/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +// This is an example of a taui app built into a dll +// Calling lib_test1 within the dll will launch the webview + +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] + +#[no_mangle] +pub extern fn run_tauri() { + tauri::Builder::default() + .run(tauri::generate_context!( + "./tauri.conf.json" + )) + .expect("error while running tauri application"); +} diff --git a/examples/tauri-dynamic-lib/src-tauri/tauri.conf.json b/examples/tauri-dynamic-lib/src-tauri/tauri.conf.json new file mode 100644 index 000000000000..89ec0a687e0a --- /dev/null +++ b/examples/tauri-dynamic-lib/src-tauri/tauri.conf.json @@ -0,0 +1,56 @@ +{ + "build": { + "distDir": ["src/index.html"], + "devPath": ["src/index.html"], + "beforeDevCommand": "", + "beforeBuildCommand": "" + }, + "tauri": { + "bundle": { + "active": true, + "targets": "all", + "identifier": "com.tauri.dev", + "icon": [ + "../../.icons/32x32.png", + "../../.icons/128x128.png", + "../../.icons/128x128@2x.png", + "../../.icons/icon.icns", + "../../.icons/icon.ico" + ], + "resources": [], + "externalBin": [], + "copyright": "", + "category": "DeveloperTool", + "shortDescription": "", + "longDescription": "", + "deb": { + "depends": [], + "useBootstrapper": false + }, + "macOS": { + "frameworks": [], + "minimumSystemVersion": "", + "useBootstrapper": false, + "exceptionDomain": "" + } + }, + "allowlist": { + "all": false + }, + "windows": [ + { + "title": "Welcome to Tauri!", + "width": 800, + "height": 600, + "resizable": true, + "fullscreen": false + } + ], + "security": { + "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" + }, + "updater": { + "active": false + } + } +} diff --git a/examples/updater/README.md b/examples/updater/README.md new file mode 100644 index 000000000000..1eb77687d7e5 --- /dev/null +++ b/examples/updater/README.md @@ -0,0 +1,29 @@ +# Updater Example + +This example showcases the App Updater feature. + +## Running the example + +- Compile Tauri +go to root of the Tauri repo and run: +Linux / Mac: +``` +# choose to install node cli (1) +bash .scripts/setup.sh +``` + +Windows: +``` +./.scripts/setup.ps1 +``` + +- Run the app in development mode (Run inside of this folder `examples/updater/`) +```bash +$ cargo tauri dev +``` + +- Build an run the release app (Run inside of this folder `examples/updater/`) +```bash +$ cargo tauri build +$ ./src-tauri/target/release/app +``` diff --git a/examples/updater/package.json b/examples/updater/package.json index b8f24273df30..0e217e0863fe 100644 --- a/examples/updater/package.json +++ b/examples/updater/package.json @@ -2,6 +2,6 @@ "name": "updater", "version": "1.0.0", "scripts": { - "tauri": "node ../../tooling/cli.js/bin/tauri" + "tauri": "node ../../tooling/cli/node/tauri.js" } -} +} \ No newline at end of file diff --git a/examples/updater/src-tauri/.gitignore b/examples/updater/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/examples/updater/src-tauri/.gitignore +++ b/examples/updater/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/examples/updater/src-tauri/Cargo.lock b/examples/updater/src-tauri/Cargo.lock index 0b0bfa19bbea..166961a37f6b 100644 --- a/examples/updater/src-tauri/Cargo.lock +++ b/examples/updater/src-tauri/Cargo.lock @@ -23,11 +23,20 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" [[package]] name = "arrayref" @@ -37,64 +46,39 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "arrayvec" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" - -[[package]] -name = "async-io" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" -dependencies = [ - "concurrent-queue", - "futures-lite", - "libc", - "log", - "once_cell", - "parking", - "polling", - "slab", - "socket2", - "waker-fn", - "winapi", -] +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "atk" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a83b21d2aa75e464db56225e1bda2dd5993311ba1095acaa8fa03d1ae67026ba" +checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" dependencies = [ "atk-sys", - "bitflags 1.3.2", + "bitflags", "glib", "libc", ] [[package]] name = "atk-sys" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea" +checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" dependencies = [ - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] name = "attohttpc" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8bda305457262b339322106c776e3fd21df860018e566eb6a5b1aa4b6ae02d" +checksum = "e69e13a99a7e6e070bb114f7ff381e58c7ccc188630121fc4c2fe4bcf24cd072" dependencies = [ "flate2", "http", @@ -110,9 +94,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" @@ -129,41 +113,24 @@ dependencies = [ "serde", ] -[[package]] -name = "bitflags" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" - [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - [[package]] name = "blake3" -version = "1.0.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcd555c66291d5f836dbb6883b48660ece810fe25a31f3bdfb911945dff2691f" +checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" dependencies = [ "arrayref", - "arrayvec 0.7.1", + "arrayvec", "cc", - "cfg-if 1.0.0", + "cfg-if", "constant_time_eq", - "digest", + "digest 0.10.1", "rayon", ] @@ -173,20 +140,38 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + [[package]] name = "bstr" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "memchr", ] [[package]] name = "bumpalo" -version = "3.7.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "byteorder" @@ -196,9 +181,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "bzip2" @@ -221,19 +206,13 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "cache-padded" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" - [[package]] name = "cairo-rs" -version = "0.14.3" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f859ade407c19810ae920b4fafab92189ed312adad490d08fb16b5f49f1e2207" +checksum = "b869e97a87170f96762f9f178eae8c461147e722ba21dd8814105bf5716bf14a" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cairo-sys-rs", "glib", "libc", @@ -242,20 +221,31 @@ dependencies = [ [[package]] name = "cairo-sys-rs" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" dependencies = [ - "glib-sys 0.14.0", + "glib-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", +] + +[[package]] +name = "cargo_toml" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363c7cfaa15f101415c4ac9e68706ca4a2277773932828b33f96e59d28c68e62" +dependencies = [ + "serde", + "serde_derive", + "toml", ] [[package]] name = "cc" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" dependencies = [ "jobserver", ] @@ -280,10 +270,13 @@ dependencies = [ ] [[package]] -name = "cfg-if" -version = "0.1.10" +name = "cfg-expr" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" +dependencies = [ + "smallvec", +] [[package]] name = "cfg-if" @@ -297,30 +290,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", -] - [[package]] name = "cocoa" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" dependencies = [ - "bitflags 1.3.2", + "bitflags", "block", "cocoa-foundation", - "core-foundation 0.9.1", - "core-graphics 0.22.2", + "core-foundation", + "core-graphics", "foreign-types", "libc", "objc", @@ -332,55 +312,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" dependencies = [ - "bitflags 1.3.2", + "bitflags", "block", - "core-foundation 0.9.1", + "core-foundation", "core-graphics-types", "foreign-types", "libc", "objc", ] -[[package]] -name = "com" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a30a2b2a013da986dc5cc3eda3d19c0d59d53f835be1b2356eb8d00f000c793" -dependencies = [ - "com_macros", -] - -[[package]] -name = "com_macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7606b05842fea68ddcc89e8053b8860ebcb2a0ba8d6abfe3a148e5d5a8d3f0c1" -dependencies = [ - "com_macros_support", - "proc-macro2", - "syn 1.0.75", -] - -[[package]] -name = "com_macros_support" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e9a6d20f4ac8830e309a455d7e9416e65c6af5a97c88c55fbb4c2012e107da" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", -] - -[[package]] -name = "concurrent-queue" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" -dependencies = [ - "cache-padded", -] - [[package]] name = "constant_time_eq" version = "0.1.5" @@ -395,56 +335,28 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "core-foundation-sys 0.8.2", + "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - -[[package]] -name = "core-foundation-sys" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" - -[[package]] -name = "core-graphics" -version = "0.19.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.7.0", - "foreign-types", - "libc", -] +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "core-graphics" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.1", + "bitflags", + "core-foundation", "core-graphics-types", "foreign-types", "libc", @@ -456,41 +368,37 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.1", + "bitflags", + "core-foundation", "foreign-types", "libc", ] [[package]] -name = "core-video-sys" -version = "0.1.4" +name = "cpufeatures" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", "libc", - "objc", ] [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -500,18 +408,18 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", "lazy_static", "memoffset", @@ -520,14 +428,23 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "lazy_static", ] +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + [[package]] name = "cssparser" version = "0.27.2" @@ -536,13 +453,13 @@ checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" dependencies = [ "cssparser-macros", "dtoa-short", - "itoa", + "itoa 0.4.8", "matches", "phf 0.8.0", "proc-macro2", - "quote 1.0.9", + "quote", "smallvec", - "syn 1.0.75", + "syn", ] [[package]] @@ -551,18 +468,44 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" dependencies = [ - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", +] + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", ] +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + [[package]] name = "darling" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + +[[package]] +name = "darling" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +dependencies = [ + "darling_core 0.13.1", + "darling_macro 0.13.1", ] [[package]] @@ -574,9 +517,23 @@ dependencies = [ "fnv", "ident_case", "proc-macro2", - "quote 1.0.9", - "strsim", - "syn 1.0.75", + "quote", + "strsim 0.9.3", + "syn", +] + +[[package]] +name = "darling_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn", ] [[package]] @@ -585,9 +542,20 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" dependencies = [ - "darling_core", - "quote 1.0.9", - "syn 1.0.75", + "darling_core 0.10.2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +dependencies = [ + "darling_core 0.13.1", + "quote", + "syn", ] [[package]] @@ -610,28 +578,17 @@ dependencies = [ "byteorder", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", -] - [[package]] name = "derive_more" -version = "0.99.16" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", "proc-macro2", - "quote 1.0.9", - "rustc_version", - "syn 1.0.75", + "quote", + "rustc_version 0.4.0", + "syn", ] [[package]] @@ -644,14 +601,15 @@ dependencies = [ ] [[package]] -name = "dirs" -version = "1.0.5" +name = "digest" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" dependencies = [ - "libc", - "redox_users 0.3.5", - "winapi", + "block-buffer 0.10.2", + "crypto-common", + "generic-array", + "subtle", ] [[package]] @@ -660,7 +618,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "dirs-sys-next", ] @@ -671,7 +629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", - "redox_users 0.4.0", + "redox_users", "winapi", ] @@ -704,36 +662,15 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "embed_plist" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53dd2e43a7d32952a6054141ee0d75183958620e84e5eab045de362dff13dc99" - -[[package]] -name = "enumflags2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" -dependencies = [ - "enumflags2_derive", - "serde", -] - -[[package]] -name = "enumflags2_derive" -version = "0.6.4" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", -] +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" [[package]] name = "fastrand" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ "instant", ] @@ -745,7 +682,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" dependencies = [ "memoffset", - "rustc_version", + "rustc_version 0.3.3", ] [[package]] @@ -754,19 +691,19 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", - "redox_syscall 0.2.10", + "redox_syscall", "winapi", ] [[package]] name = "flate2" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crc32fast", "libc", "miniz_oxide 0.4.4", @@ -805,9 +742,9 @@ dependencies = [ [[package]] name = "futf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" dependencies = [ "mac", "new_debug_unreachable", @@ -815,9 +752,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -830,9 +767,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -840,15 +777,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -857,9 +794,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-lite" @@ -878,36 +815,33 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.16" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ - "autocfg", "futures-channel", "futures-core", "futures-io", @@ -917,8 +851,6 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -933,11 +865,11 @@ dependencies = [ [[package]] name = "gdk" -version = "0.14.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "679e22651cd15888e7acd01767950edca2ee9fcd6421fbf5b3c3b420d4e88bb0" +checksum = "614258e81ec35ed8770e64a0838f3a47f95b398bc51e724d3b3fa09c1ee0f8d5" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cairo-rs", "gdk-pixbuf", "gdk-sys", @@ -949,10 +881,11 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.14.0" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f" +checksum = "73aa2f5de1b45710da90a55863276667dc3a3264aaf6a2aeace62bb015244d49" dependencies = [ + "bitflags", "gdk-pixbuf-sys", "gio", "glib", @@ -961,32 +894,45 @@ dependencies = [ [[package]] name = "gdk-pixbuf-sys" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590" +checksum = "413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171" dependencies = [ - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] name = "gdk-sys" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e" +checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", "pango-sys", "pkg-config", - "system-deps 3.2.0", + "system-deps 6.0.1", +] + +[[package]] +name = "gdkx11-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178" +dependencies = [ + "gdk-sys", + "glib-sys 0.15.5", + "libc", + "system-deps 6.0.1", + "x11", ] [[package]] @@ -1004,9 +950,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -1018,52 +964,39 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] name = "gio" -version = "0.14.3" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a7057cd21d64bfa7ac027b344a7f50f677fb3308693df0e8c70fb55d29f0d" +checksum = "59105fa464928adf56b159c8d980cc11fbfbe414befb904caac5163d383049bf" dependencies = [ - "bitflags 1.3.2", + "bitflags", "futures-channel", "futures-core", "futures-io", - "gio-sys 0.14.0", + "gio-sys 0.15.5", "glib", "libc", "once_cell", "thiserror", ] -[[package]] -name = "gio-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e24fb752f8f5d2cf6bbc2c606fd2bc989c81c5e2fe321ab974d54f8b6344eac" -dependencies = [ - "glib-sys 0.10.1", - "gobject-sys 0.10.0", - "libc", - "system-deps 1.3.2", - "winapi", -] - [[package]] name = "gio-sys" version = "0.14.0" @@ -1077,60 +1010,80 @@ dependencies = [ "winapi", ] +[[package]] +name = "gio-sys" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f0bc4cfc9ebcdd05cc5057bc51b99c32f8f9bf246274f6a556ffd27279f8fe3" +dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", + "libc", + "system-deps 6.0.1", + "winapi", +] + [[package]] name = "glib" -version = "0.14.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fb802e3798d75b415bea8f016eed88d50106ce82f1274e80f31d80cfd4b056" +checksum = "41dcfbdb6cc6c02aee163339465d8a40d6f3f64c3a43f729a4195f0e153338b7" dependencies = [ - "bitflags 1.3.2", + "bitflags", "futures-channel", "futures-core", "futures-executor", "futures-task", "glib-macros", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", "once_cell", "smallvec", + "thiserror", ] [[package]] name = "glib-macros" -version = "0.14.1" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" +checksum = "e58b262ff65ef771003873cea8c10e0fe854f1c508d48d62a4111a1ff163f7d1" dependencies = [ "anyhow", - "heck", - "proc-macro-crate 1.0.0", + "heck 0.4.0", + "proc-macro-crate 1.1.0", "proc-macro-error", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "glib-sys" -version = "0.10.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1" +checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" dependencies = [ "libc", - "system-deps 1.3.2", + "system-deps 3.2.0", ] [[package]] name = "glib-sys" -version = "0.14.0" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" +checksum = "fa1d4e1a63d8574541e5b92931e4e669ddc87ffa85d58e84e631dba13ad2e10c" dependencies = [ "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + [[package]] name = "globset" version = "0.4.8" @@ -1146,34 +1099,34 @@ dependencies = [ [[package]] name = "gobject-sys" -version = "0.10.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c" +checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" dependencies = [ - "glib-sys 0.10.1", + "glib-sys 0.14.0", "libc", - "system-deps 1.3.2", + "system-deps 3.2.0", ] [[package]] name = "gobject-sys" -version = "0.14.0" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" +checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a" dependencies = [ - "glib-sys 0.14.0", + "glib-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] name = "gtk" -version = "0.14.1" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6603bb79ded6ac6f3bac203794383afa8b1d6a8656d34a93a88f0b22826cd46c" +checksum = "c7978eaec05bea63947c801d29a21372f2ed39aec0bf56bf7725d3599094675e" dependencies = [ "atk", - "bitflags 1.3.2", + "bitflags", "cairo-rs", "field-offset", "futures-channel", @@ -1191,35 +1144,34 @@ dependencies = [ [[package]] name = "gtk-sys" -version = "0.14.0" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e" +checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" dependencies = [ "atk-sys", "cairo-sys-rs", "gdk-pixbuf-sys", "gdk-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", "pango-sys", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] name = "gtk3-macros" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79" +checksum = "8c891188af69e77a1e8a0b1746fbd03b9b396e7d34d518c5331b15950259f541" dependencies = [ "anyhow", - "heck", - "proc-macro-crate 1.0.0", + "proc-macro-crate 1.1.0", "proc-macro-error", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] @@ -1231,6 +1183,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1250,19 +1208,19 @@ dependencies = [ "mac", "markup5ever", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "http" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.1", ] [[package]] @@ -1336,18 +1294,18 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "itertools" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] @@ -1358,23 +1316,33 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "javascriptcore-rs" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca9c7d1445bba2889672fbadc16c3d5007bfdcf0a15a18a3a50fe9fab2c7427" +checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c" dependencies = [ + "bitflags", "glib", "javascriptcore-rs-sys", ] [[package]] name = "javascriptcore-rs-sys" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f46ada8a08dcd75a10afae872fbfb51275df4a8ae0d46b8cc7c708f08dd2998" +checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c" dependencies = [ + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", + "system-deps 5.0.0", ] [[package]] @@ -1394,13 +1362,24 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json-patch" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" +dependencies = [ + "serde", + "serde_json", + "treediff", +] + [[package]] name = "kuchiki" version = "0.8.1" @@ -1421,15 +1400,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.100" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" dependencies = [ "scopeguard", ] @@ -1440,20 +1419,22 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "loom" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2111607c723d7857e0d8299d5ce7a0bf4b844d3e44f8de136b13da513eaf8fc4" +checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "generator", "scoped-tls", "serde", "serde_json", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1462,18 +1443,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -[[package]] -name = "mac-notification-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb6b71a9a89cd38b395d994214297447e8e63b1ba5708a9a2b0b1048ceda76" -dependencies = [ - "cc", - "chrono", - "dirs", - "objc-foundation", -] - [[package]] name = "malloc_buf" version = "0.0.6" @@ -1498,16 +1467,19 @@ dependencies = [ ] [[package]] -name = "matches" -version = "0.1.9" +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] [[package]] -name = "maybe-uninit" -version = "2.0.0" +name = "matches" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" @@ -1517,18 +1489,18 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] [[package]] name = "minisign-verify" -version = "0.1.8" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0507fe8e3c68cd62961cf9f87f6c2b21d884d3515a7150a4a3fa9d014e5c12" +checksum = "95ccf091884470c4b3a80ad6daadbb2e7736611d631cbf0c9e603bb7dbcfdfd9" [[package]] name = "miniz_oxide" @@ -1567,23 +1539,13 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nb-connect" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1bb540dc6ef51cfe1916ec038ce7a620daf3a111e2502d745197cd53d6bca15" -dependencies = [ - "libc", - "socket2", -] - [[package]] name = "ndk" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c" dependencies = [ - "bitflags 1.3.2", + "bitflags", "jni-sys", "ndk-sys", "num_enum", @@ -1610,18 +1572,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" dependencies = [ - "darling", + "darling 0.10.2", "proc-macro-crate 0.1.5", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "ndk-sys" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" [[package]] name = "new_debug_unreachable" @@ -1629,39 +1591,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" -[[package]] -name = "nix" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" -dependencies = [ - "bitflags 1.3.2", - "cc", - "cfg-if 0.1.10", - "libc", - "void", -] - [[package]] name = "nodrop" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -[[package]] -name = "notify-rust" -version = "4.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2ca742cd7268b60c35828d318357f0b1bb9b82088e157ccf3013eb3ce70247" -dependencies = [ - "mac-notification-sys", - "serde", - "winrt-notification", - "zbus", - "zvariant", - "zvariant_derive", -] - [[package]] name = "num-integer" version = "0.1.44" @@ -1694,9 +1629,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -1704,24 +1639,23 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" +checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" dependencies = [ - "derivative", "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" +checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" dependencies = [ - "proc-macro-crate 1.0.0", + "proc-macro-crate 1.1.0", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] @@ -1731,6 +1665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ "malloc_buf", + "objc_exception", ] [[package]] @@ -1744,6 +1679,15 @@ dependencies = [ "objc_id", ] +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + [[package]] name = "objc_id" version = "0.1.1" @@ -1755,28 +1699,24 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] -name = "open" -version = "2.0.1" +name = "opaque-debug" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46b233de7d83bc167fe43ae2dda3b5b84e80e09cceba581e4decb958a4896bf" -dependencies = [ - "pathdiff", - "winapi", -] +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.36" +version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ - "bitflags 1.3.2", - "cfg-if 1.0.0", + "bitflags", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -1785,15 +1725,15 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.66" +version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ "autocfg", "cc", @@ -1802,34 +1742,13 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "os_info" -version = "3.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac91020bfed8cc3f8aa450d4c3b5fa1d3373fc091c8a92009f3b27749d5a227" -dependencies = [ - "log", - "serde", - "winapi", -] - -[[package]] -name = "os_pipe" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb233f06c2307e1f5ce2ecad9f8121cffbbee2c95428f44ea85222e460d0d213" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "pango" -version = "0.14.3" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc88307d9797976ea62722ff2ec5de3fae279c6e20100ed3f49ca1a4bf3f96" +checksum = "79211eff430c29cc38c69e0ab54bc78fa1568121ca9737707eee7f92a8417a94" dependencies = [ - "bitflags 1.3.2", + "bitflags", "glib", "libc", "once_cell", @@ -1838,14 +1757,14 @@ dependencies = [ [[package]] name = "pango-sys" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe" +checksum = "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2" dependencies = [ - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "libc", - "system-deps 3.2.0", + "system-deps 6.0.1", ] [[package]] @@ -1856,9 +1775,9 @@ checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", @@ -1867,24 +1786,18 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "instant", "libc", - "redox_syscall 0.2.10", + "redox_syscall", "smallvec", "winapi", ] -[[package]] -name = "pathdiff" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877630b3de15c0b64cc52f659345724fbf6bdad9bd9566699fc53688f3c34a34" - [[package]] name = "percent-encoding" version = "2.1.0" @@ -1913,9 +1826,9 @@ dependencies = [ [[package]] name = "phf" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fc3db1018c4b59d7d582a739436478b6035138b6aecbce989fc91c3e98409f" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ "phf_macros 0.10.0", "phf_shared 0.10.0", @@ -1962,8 +1875,8 @@ dependencies = [ "phf_shared 0.8.0", "proc-macro-hack", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] @@ -1976,8 +1889,8 @@ dependencies = [ "phf_shared 0.10.0", "proc-macro-hack", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] @@ -2000,9 +1913,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -2012,9 +1925,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] name = "png" @@ -2022,7 +1935,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" dependencies = [ - "bitflags 1.3.2", + "bitflags", "deflate 0.7.20", "inflate", "num-iter", @@ -2034,30 +1947,17 @@ version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" dependencies = [ - "bitflags 1.3.2", + "bitflags", "crc32fast", "deflate 0.8.6", "miniz_oxide 0.3.7", ] -[[package]] -name = "polling" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "log", - "wepoll-ffi", - "winapi", -] - [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "precomputed-hash" @@ -2076,9 +1976,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" dependencies = [ "thiserror", "toml", @@ -2092,8 +1992,8 @@ checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", "version_check", ] @@ -2104,7 +2004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", - "quote 1.0.9", + "quote", "version_check", ] @@ -2114,32 +2014,20 @@ version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ - "unicode-xid 0.2.2", + "unicode-xid", ] [[package]] name = "quote" -version = "0.3.15" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -2205,7 +2093,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.4", ] [[package]] @@ -2237,11 +2125,11 @@ dependencies = [ [[package]] name = "raw-window-handle" -version = "0.3.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +checksum = "fba75eee94a9d5273a68c9e1e105d9cffe1ef700532325788389e5a83e2522b7" dependencies = [ - "libc", + "cty", ] [[package]] @@ -2269,30 +2157,13 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_users" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" -dependencies = [ - "getrandom 0.1.16", - "redox_syscall 0.1.57", - "rust-argon2", + "bitflags", ] [[package]] @@ -2301,8 +2172,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ - "getrandom 0.2.3", - "redox_syscall 0.2.10", + "getrandom 0.2.4", + "redox_syscall", ] [[package]] @@ -2316,6 +2187,15 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.25" @@ -2333,14 +2213,14 @@ dependencies = [ [[package]] name = "rfd" -version = "0.4.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cede43618603a102f37bb58244534a33de7daa6a3b77f00277675eef5f8174fe" +checksum = "d4e3a2a1461f8ef8023ff00ce76f877c112cf1ffd601d95ba01a41e820af1f3d" dependencies = [ "block", "dispatch", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "gtk-sys", "js-sys", "lazy_static", @@ -2351,41 +2231,38 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winapi", + "windows", ] [[package]] -name = "rust-argon2" -version = "0.8.3" +name = "rustc_version" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" dependencies = [ - "base64", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", + "semver 0.11.0", ] [[package]] name = "rustc_version" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 0.11.0", + "semver 1.0.5", ] [[package]] name = "rustversion" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "same-file" @@ -2420,24 +2297,24 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "security-framework" -version = "2.3.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.1", - "core-foundation-sys 0.8.2", + "bitflags", + "core-foundation", + "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "2.3.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" dependencies = [ - "core-foundation-sys 0.8.2", + "core-foundation-sys", "libc", ] @@ -2447,7 +2324,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cssparser", "derive_more", "fxhash", @@ -2472,9 +2349,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" [[package]] name = "semver-parser" @@ -2487,31 +2364,31 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.129" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.129" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" dependencies = [ - "itoa", + "itoa 1.0.1", "ryu", "serde", ] @@ -2523,83 +2400,129 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "serde_urlencoded" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "dtoa", - "itoa", + "form_urlencoded", + "itoa 1.0.1", + "ryu", "serde", - "url", ] [[package]] -name = "servo_arc" -version = "0.1.1" +name = "serde_with" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +checksum = "ec1e6ec4d8950e5b1e894eac0d360742f3b1407a6078a604a731c4b3f49cefbc" dependencies = [ - "nodrop", - "stable_deref_trait", + "rustversion", + "serde", + "serde_with_macros", ] [[package]] -name = "shared_child" -version = "0.3.5" +name = "serde_with_macros" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6be9f7d5565b1483af3e72975e2dee33879b3b86bd48c0929fccf6585d79e65a" +checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" dependencies = [ - "libc", - "winapi", + "darling 0.13.1", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "siphasher" -version = "0.3.6" +name = "serialize-to-javascript" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" +checksum = "9186a81e763ca2a5e13ba76d843534620bffe0cf1e76e1a2f2d231ba1db79b82" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] [[package]] -name = "slab" -version = "0.4.4" +name = "serialize-to-javascript-impl" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" +checksum = "4e3ff83d7962f690dbe675ca0fd516c097194723b6bda8c7c500d35f0b02902e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "smallvec" -version = "1.6.1" +name = "servo_arc" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] [[package]] -name = "socket2" -version = "0.4.1" +name = "sha2" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "libc", - "winapi", + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", ] [[package]] -name = "soup-sys" -version = "0.10.0" +name = "sharded-slab" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7adf08565630bbb71f955f11f8a68464817ded2703a3549747c235b58a13e" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ - "bitflags 1.3.2", - "gio-sys 0.10.1", - "glib-sys 0.10.1", - "gobject-sys 0.10.0", + "lazy_static", +] + +[[package]] +name = "siphasher" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "soup2-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f056675eda9a7417163e5f742bb119e8e1d385edd2ada8f7031a7230a3ec10a" +dependencies = [ + "bitflags", + "gio-sys 0.14.0", + "glib-sys 0.14.0", + "gobject-sys 0.14.0", "libc", - "pkg-config", - "system-deps 1.3.2", + "system-deps 5.0.0", ] [[package]] @@ -2617,21 +2540,16 @@ dependencies = [ "loom", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "string_cache" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a" +checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" dependencies = [ "lazy_static", "new_debug_unreachable", - "phf_shared 0.8.0", + "parking_lot", + "phf_shared 0.10.0", "precomputed-hash", "serde", ] @@ -2645,7 +2563,7 @@ dependencies = [ "phf_generator 0.8.0", "phf_shared 0.8.0", "proc-macro2", - "quote 1.0.9", + "quote", ] [[package]] @@ -2655,16 +2573,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" [[package]] -name = "strum" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca6e4730f517e041e547ffe23d29daab8de6b73af4b6ae2a002108169f5e7da" - -[[package]] -name = "strum" -version = "0.18.0" +name = "strsim" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" @@ -2672,125 +2584,110 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" -[[package]] -name = "strum_macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3384590878eb0cab3b128e844412e2d010821e7e091211b9d87324173ada7db8" -dependencies = [ - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "strum_macros" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" -dependencies = [ - "heck", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", -] - [[package]] name = "strum_macros" version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] -name = "syn" -version = "0.11.11" +name = "subtle" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid 0.0.4", -] +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.75" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", - "quote 1.0.9", - "unicode-xid 0.2.2", + "quote", + "unicode-xid", ] [[package]] -name = "synom" -version = "0.11.3" +name = "sys-info" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" dependencies = [ - "unicode-xid 0.0.4", + "cc", + "libc", ] [[package]] name = "system-deps" -version = "1.3.2" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b" +checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" dependencies = [ - "heck", + "anyhow", + "cfg-expr 0.8.1", + "heck 0.3.3", + "itertools", "pkg-config", - "strum 0.18.0", - "strum_macros 0.18.0", + "strum", + "strum_macros", "thiserror", "toml", - "version-compare 0.0.10", + "version-compare 0.0.11", ] [[package]] name = "system-deps" -version = "3.2.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" dependencies = [ - "anyhow", - "cfg-expr", - "heck", - "itertools", + "cfg-expr 0.9.1", + "heck 0.3.3", "pkg-config", - "strum 0.21.0", - "strum_macros 0.21.1", - "thiserror", "toml", "version-compare 0.0.11", ] +[[package]] +name = "system-deps" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad3a97fdef3daf935d929b3e97e5a6a680cd4622e40c2941ca0875d6566416f8" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.4.0", + "pkg-config", + "toml", + "version-compare 0.1.0", +] + [[package]] name = "tao" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa57de7c282b68f8906278543a724ed8f5a2568f069dd0cc05fc10d1f07036b" +checksum = "53d2bba60298cbc0ff0651fe5a0bdfb73438b91231f700dcc8d539548237cae7" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cairo-rs", "cc", "cocoa", - "core-foundation 0.9.1", - "core-graphics 0.22.2", - "core-video-sys", + "core-foundation", + "core-graphics", "crossbeam-channel", "dispatch", "gdk", "gdk-pixbuf", "gdk-sys", + "gdkx11-sys", "gio", "glib", - "glib-sys 0.14.0", + "glib-sys 0.15.5", "gtk", "instant", "lazy_static", @@ -2804,16 +2701,30 @@ dependencies = [ "raw-window-handle", "scopeguard", "serde", + "tao-core-video-sys", "unicode-segmentation", - "winapi", + "windows", + "windows_macros", "x11-dl", ] +[[package]] +name = "tao-core-video-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271450eb289cb4d8d0720c6ce70c72c8c858c93dd61fc625881616752e6b98f6" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "objc", +] + [[package]] name = "tar" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" dependencies = [ "filetime", "libc", @@ -2835,24 +2746,21 @@ dependencies = [ "futures", "futures-lite", "glib", + "glob", "gtk", "http", "ignore", "minisign-verify", - "notify-rust", "once_cell", - "open", - "os_info", - "os_pipe", "percent-encoding", "rand 0.8.4", "raw-window-handle", "rfd", - "semver 1.0.4", + "semver 1.0.5", "serde", "serde_json", "serde_repr", - "shared_child", + "serialize-to-javascript", "state", "tar", "tauri-macros", @@ -2872,8 +2780,8 @@ name = "tauri-build" version = "1.0.0-beta.4" dependencies = [ "anyhow", - "proc-macro2", - "quote 1.0.9", + "cargo_toml", + "quote", "serde_json", "tauri-codegen", "tauri-utils", @@ -2884,15 +2792,16 @@ dependencies = [ name = "tauri-codegen" version = "1.0.0-beta.4" dependencies = [ + "base64", "blake3", - "kuchiki", "proc-macro2", - "quote 1.0.9", - "regex", + "quote", "serde", "serde_json", + "sha2", "tauri-utils", "thiserror", + "uuid", "walkdir", "zstd", ] @@ -2901,10 +2810,12 @@ dependencies = [ name = "tauri-macros" version = "1.0.0-beta.5" dependencies = [ + "heck 0.3.3", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", "tauri-codegen", + "tauri-utils", ] [[package]] @@ -2920,7 +2831,8 @@ dependencies = [ "tauri-utils", "thiserror", "uuid", - "winapi", + "webview2-com", + "windows", ] [[package]] @@ -2934,7 +2846,8 @@ dependencies = [ "tauri-runtime", "tauri-utils", "uuid", - "winapi", + "webview2-com", + "windows", "wry", ] @@ -2942,28 +2855,35 @@ dependencies = [ name = "tauri-utils" version = "1.0.0-beta.3" dependencies = [ + "ctor", + "glob", + "heck 0.4.0", "html5ever", + "json-patch", "kuchiki", - "phf 0.10.0", + "phf 0.10.1", "proc-macro2", - "quote 1.0.9", + "quote", "serde", "serde_json", + "serde_with", + "serialize-to-javascript", "thiserror", "url", + "walkdir", "zstd", ] [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", + "fastrand", "libc", - "rand 0.8.4", - "redox_syscall 0.2.10", + "redox_syscall", "remove_dir_all", "winapi", ] @@ -2987,29 +2907,29 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", ] [[package]] name = "thread_local" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" dependencies = [ "once_cell", ] @@ -3026,9 +2946,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -3041,11 +2961,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.10.1" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92036be488bb6594459f2e03b60e42df6f937fe6ca5c5ffdcb539c6b84dc40f5" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" dependencies = [ - "autocfg", "bytes", "memchr", "num_cpus", @@ -3061,11 +2980,82 @@ dependencies = [ "serde", ] +[[package]] +name = "tracing" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d8d93354fe2a8e50d5953f5ae2e47a3fc2ef03292e7ea46e3cc38f549525fb9" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8276d9a4a3a558d7b7ad5303ad50b53d58264641b82914b7ada36bd762e7a716" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +dependencies = [ + "lazy_static", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74786ce43333fcf51efe947aed9718fbe46d5c7328ec3f1029e818083966d9aa" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "treediff" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" +dependencies = [ + "serde_json", +] + [[package]] name = "typenum" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "ucd-trie" @@ -3075,9 +3065,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "unicode-bidi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-normalization" @@ -3090,15 +3080,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-xid" @@ -3141,20 +3125,20 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.4", ] [[package]] -name = "vcpkg" -version = "0.2.15" +name = "valuable" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] -name = "version-compare" -version = "0.0.10" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version-compare" @@ -3163,16 +3147,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" [[package]] -name = "version_check" -version = "0.9.3" +name = "version-compare" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" [[package]] -name = "void" -version = "1.0.2" +name = "version_check" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" @@ -3205,36 +3189,36 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" dependencies = [ "bumpalo", "lazy_static", "log", "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.26" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" +checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -3242,38 +3226,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" dependencies = [ - "quote 1.0.9", + "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" dependencies = [ "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "quote", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" [[package]] name = "web-sys" -version = "0.3.53" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" dependencies = [ "js-sys", "wasm-bindgen", @@ -3281,19 +3265,19 @@ dependencies = [ [[package]] name = "webkit2gtk" -version = "0.14.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e47b7f870883fc21612d2a51b74262f7f2cc5371f1621370817292a35300a9" +checksum = "2cbd39499e917de9dad36eb11c09f665eb984d432638ae7971feed98eb96df88" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cairo-rs", "gdk", "gdk-sys", "gio", - "gio-sys 0.14.0", + "gio-sys 0.15.5", "glib", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "gtk", "gtk-sys", "javascriptcore-rs", @@ -3304,70 +3288,69 @@ dependencies = [ [[package]] name = "webkit2gtk-sys" -version = "0.14.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66ccc9f0cb4de7c3b92376a5bf64e7ddffb33852f092721731a039ec38dda98" +checksum = "ddcce6f1e0fc7715d651dba29875741509f5fc12f4e2976907272a74405f2b01" dependencies = [ "atk-sys", - "bitflags 1.3.2", + "bitflags", "cairo-sys-rs", "gdk-pixbuf-sys", "gdk-sys", - "gio-sys 0.14.0", - "glib-sys 0.14.0", - "gobject-sys 0.14.0", + "gio-sys 0.15.5", + "glib-sys 0.15.5", + "gobject-sys 0.15.5", "gtk-sys", "javascriptcore-rs-sys", "libc", "pango-sys", "pkg-config", - "soup-sys", - "system-deps 3.2.0", + "soup2-sys", + "system-deps 5.0.0", ] [[package]] -name = "webview2" -version = "0.1.1" +name = "webview2-com" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fab1ccfdabb098b047293c8d496c1914d1c654b68fdaa3bb77cfa47c4bca2c7" +checksum = "1975ce3573344c099935fe3903f1708dac69efe8539f1efee3ae54d8f9315fbb" dependencies = [ - "com", - "once_cell", - "webview2-sys", - "widestring", - "winapi", + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows_macros", ] [[package]] -name = "webview2-sys" -version = "0.1.0" +name = "webview2-com-macros" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5288cef1e0cbcf7a0b961e6271e33589b8989c80b2e11078504e989b5346ff" +checksum = "1515c6c82fcee93f6edaacc72c8e233dbe4ff3ca569dce1901dfc36c404a3e99" dependencies = [ - "com", - "winapi", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "wepoll-ffi" -version = "0.1.2" +name = "webview2-com-sys" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +checksum = "9a746838a94b7391f707209a246e3436d81d1e71832126a65a897d3ee5511040" dependencies = [ - "cc", + "regex", + "serde", + "serde_json", + "thiserror", + "windows", + "windows-bindgen", ] -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - [[package]] name = "wildmatch" -version = "1.1.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" +checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" [[package]] name = "winapi" @@ -3401,44 +3384,109 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "winres" -version = "0.1.11" +name = "windows" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4fb510bbfe5b8992ff15f77a2e6fe6cf062878f0eda00c0f44963a807ca5dc" +checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0" dependencies = [ - "toml", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", ] [[package]] -name = "winrt" -version = "0.4.0" +name = "windows-bindgen" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30cba82e22b083dc5a422c2ee77e20dc7927271a0dc981360c57c1453cb48d" +checksum = "944c545fcae9dd66488308f8b69aa3ba34f53714416ecfcdcbbfa4b6821e27c6" dependencies = [ - "winapi", + "windows_quote", + "windows_reader", ] [[package]] -name = "winrt-notification" -version = "0.2.4" +name = "windows_aarch64_msvc" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57790eb281688a4682dab44df2a1ba8b78373233bd71cb291c3e75fecb1a01c4" +checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca" + +[[package]] +name = "windows_gen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30dff4d91d22520628bb94b66f2bb313cb16a09a515a32320a84a1b449bc94c0" dependencies = [ - "strum 0.8.0", - "strum_macros 0.8.0", - "winapi", - "winrt", - "xml-rs", + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_i686_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8" + +[[package]] +name = "windows_i686_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6" + +[[package]] +name = "windows_macros" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ae44ab917e9005fe710d99d52d227ca0164b10a09be90649142cc3fab825d3" +dependencies = [ + "syn", + "windows_gen", + "windows_quote", + "windows_reader", +] + +[[package]] +name = "windows_quote" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71f02c51a77e6248c1206aaa920802c32d50a05205e229b118d7f3afd3036667" + +[[package]] +name = "windows_reader" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e44e6df0da993cda589c5ac852272fbb2a0ead67a031a017dd3eac11528a2d72" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1" + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", ] [[package]] name = "wry" -version = "0.12.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9549393a3917b5303277abb0267f8eecf9fd629b25f1c04e5284aa58b61915" +checksum = "194b2750d8fe10fef189af5e2ca09e56cb8c5458a365d2b32842b024351f58c9" dependencies = [ "cocoa", - "core-graphics 0.22.2", + "core-graphics", "gdk", "gio", "glib", @@ -3451,79 +3499,45 @@ dependencies = [ "once_cell", "serde", "serde_json", + "sys-info", "tao", "thiserror", "url", "webkit2gtk", "webkit2gtk-sys", - "webview2", - "webview2-sys", - "winapi", + "webview2-com", + "windows", + "windows_macros", ] [[package]] -name = "x11-dl" -version = "2.18.5" +name = "x11" +version = "2.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +checksum = "6dd0565fa8bfba8c5efe02725b14dff114c866724eff2cfd44d76cea74bcd87a" dependencies = [ - "lazy_static", "libc", - "maybe-uninit", "pkg-config", ] [[package]] -name = "xattr" -version = "0.2.2" +name = "x11-dl" +version = "2.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" dependencies = [ + "lazy_static", "libc", + "pkg-config", ] [[package]] -name = "xml-rs" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621" -dependencies = [ - "bitflags 0.9.1", -] - -[[package]] -name = "zbus" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2326acc379a3ac4e34b794089f5bdb17086bf29a5fdf619b7b4cc772dc2e9dad" -dependencies = [ - "async-io", - "byteorder", - "derivative", - "enumflags2", - "fastrand", - "futures", - "nb-connect", - "nix", - "once_cell", - "polling", - "scoped-tls", - "serde", - "serde_repr", - "zbus_macros", - "zvariant", -] - -[[package]] -name = "zbus_macros" -version = "1.9.1" +name = "xattr" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a482c56029e48681b89b92b5db3c446db0915e8dd1052c0328a574eda38d5f93" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" dependencies = [ - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", + "libc", ] [[package]] @@ -3542,18 +3556,18 @@ dependencies = [ [[package]] name = "zstd" -version = "0.9.0+zstd.1.5.0" +version = "0.10.0+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07749a5dc2cb6b36661290245e350f15ec3bbb304e493db54a1d354480522ccd" +checksum = "3b1365becbe415f3f0fcd024e2f7b45bacfb5bdd055f0dc113571394114e7bdd" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "4.1.1+zstd.1.5.0" +version = "4.1.4+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91c90f2c593b003603e5e0493c837088df4469da25aafff8bce42ba48caf079" +checksum = "2f7cd17c9af1a4d6c24beb1cc54b17e2ef7b593dc92f19e9d9acad8b182bbaee" dependencies = [ "libc", "zstd-sys", @@ -3561,35 +3575,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "1.6.1+zstd.1.5.0" +version = "1.6.3+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615120c7a2431d16cf1cf979e7fc31ba7a5b5e5707b29c8a99e5dbf8a8392a33" +checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8" dependencies = [ "cc", "libc", ] - -[[package]] -name = "zvariant" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4b785b8b32b0f8433b4474e6bb4ea77b37c1960e84d7598e01dd199b2b23ef" -dependencies = [ - "byteorder", - "enumflags2", - "serde", - "static_assertions", - "zvariant_derive", -] - -[[package]] -name = "zvariant_derive" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42af4ee88fb928781391216c34be77ec7cdb3546042b2947ce38d86aa5f37dd" -dependencies = [ - "proc-macro-crate 1.0.0", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.75", -] diff --git a/examples/updater/src-tauri/Cargo.toml b/examples/updater/src-tauri/Cargo.toml index 5d1464be911b..af8118e8de9d 100644 --- a/examples/updater/src-tauri/Cargo.toml +++ b/examples/updater/src-tauri/Cargo.toml @@ -2,16 +2,17 @@ name = "updater-example" version = "0.1.0" description = "A very simple Tauri Appplication" -edition = "2018" +edition = "2021" +rust-version = "1.57" license = "Apache-2.0 OR MIT" [build-dependencies] -tauri-build = { path = "../../../core/tauri-build", features = [ "codegen" ] } +tauri-build = { path = "../../../core/tauri-build", features = ["codegen"] } [dependencies] serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } -tauri = { path = "../../../core/tauri", features = ["api-all", "updater"] } +tauri = { path = "../../../core/tauri", features = ["updater"] } [features] default = [ "custom-protocol" ] @@ -20,3 +21,11 @@ custom-protocol = [ "tauri/custom-protocol" ] [[bin]] name = "updater-example" path = "src/main.rs" + +# default to small, optimized release binaries +[profile.release] +panic = "abort" +codegen-units = 1 +lto = true +incremental = false +opt-level = "s" diff --git a/examples/updater/src-tauri/tauri.conf.json b/examples/updater/src-tauri/tauri.conf.json index aa1efdf640cd..2d9c7a3b38eb 100644 --- a/examples/updater/src-tauri/tauri.conf.json +++ b/examples/updater/src-tauri/tauri.conf.json @@ -45,7 +45,7 @@ } }, "allowlist": { - "all": true + "all": false }, "windows": [ { @@ -57,7 +57,7 @@ } ], "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'" + "csp": "default-src 'self'" }, "updater": { "active": true, diff --git a/maskfile.md b/maskfile.md deleted file mode 100644 index 774505fd759e..000000000000 --- a/maskfile.md +++ /dev/null @@ -1,197 +0,0 @@ -# Shorthand Commands - - - -## prepare - -> Setup all stuff needed for running the smoke tests - -```sh -git clone --recursive git@github.com:tauri-apps/smoke-tests.git \ -|| (cd smoke-tests && git pull origin dev; cd ..) # always prepare up-to-date smoke tests in case it's already available - -cargo build --lib -cargo install --locked trunk --force # used by rust/yew - -. .scripts/setup.sh -``` - -```powershell -# Setup Environment to execute in the tauri directory. -$CWD = [Environment]::CurrentDirectory -Push-Location $MyInvocation.MyCommand.Path -[Environment]::CurrentDirectory = $PWD -# send git stderr to powershell stdout -$env:GIT_REDIRECT_STDERR = '2>&1' - -# if the smoke-tests path doesn't exist. -if (-Not (Test-Path $CWD\smoke-tests -PathType Any)) { - Start-Job -ScriptBlock { - # Setup Environment to execute in the tauri directory. - $CWD = [Environment]::CurrentDirectory - Push-Location $MyInvocation.MyCommand.Path - [Environment]::CurrentDirectory = $PWD - - #clone the smoke-tests repo into the smoke-tests folder - git clone --recursive https://github.com/tauri-apps/smoke-tests.git $CWD\smoke-tests - } | Receive-Job -AutoRemoveJob -Wait -} - -# Enter the smoke-tests folder and pull the latest data from origin/dev -cd smoke-tests; git pull origin dev; cd .. - -# build and install everything Rust related. -cargo build --lib -cargo install --locked trunk --force - -. .scripts/setup.ps1 -``` - -## run - -![tauri-mask-run-smoke-test](https://user-images.githubusercontent.com/4953069/75866011-00ed8600-5e37-11ea-9106-3cb104a05f80.gif) - -### run smoke-test (name) - -> Run specific smoketest in dev mode - -```sh -shopt -s globstar - -cd smoke-tests/**/$name 2>/dev/null \ -|| cd smoke-tests/**/$name/$name # workaround for rust/yew/todomvc/todomvc - -case "$PWD" in -*/node/*) - yarn && yarn tauri:dev -;; -*/rust/*) - cargo web deploy - [ $name = `basename $(dirname $PWD)` ] && cd .. - - yarn add tauri@link:../../../tooling/cli.js - yarn && yarn tauri dev -;; -*) - echo unknown project $(dirname $name)/$name -;; -esac -``` - -```powershell -param( - [string] $smoke_test_name -) - -# Setup Environment to execute in the tauri directory. -$CWD = [Environment]::CurrentDirectory -Push-Location $MyInvocation.MyCommand.Path -[Environment]::CurrentDirectory = $PWD - -# get the example paths. -$smoke_test_path = Get-ChildItem smoke-tests\*\*\$env:name - -# if the example path is null get the todomvc path. -if ($smoke_test_path -eq $null) { - $smoke_test_path = Get-ChildItem smoke-tests\*\*\*\$env:name\$env:name -} - -# if the example path is still null get the helloworld example path. -if ($smoke_test_path -eq $null) { - $smoke_test_path = Get-ChildItem smoke-tests\tauri\*\$env:name -} - -# switch on the parent folder name. -switch ($smoke_test_path.parent) { - # if node, run yarn. - {"vanillajs" -Or "react" -Or "svelte" -Or "vue"} { - cd $smoke_test_path.FullName; yarn; yarn tauri:dev - } - # if rust, run cargo web deploy - "yew" { - cd $smoke_test_path.FullName; cargo web deploy - } - # if tauri run the helloworld example from the tauri folder. - "tauri" { - cd $CWD/tauri; cargo run --example helloworld - } - # transpiled are not supported yet. - "transpiled" { - Write-Output("Example not supported yet") - } -} -``` - -## list - -### list smoke-tests - -> List all available smoke tests - -```sh -find smoke-tests/*/*/* -maxdepth 0 -type d -not -path '*.git*' \ --exec sh -c 'echo $(basename $(dirname {}))/$(basename {})' \; -``` - -```powershell -# Setup Environment to execute in the tauri directory. -$CWD = [Environment]::CurrentDirectory -Push-Location $MyInvocation.MyCommand.Path -[Environment]::CurrentDirectory = $PWD - -# initialize the smoke-tests list. -$smoke_tests = @() - -# get the helloworld smoke tests -$smoke_tests += Get-ChildItem smoke-tests/*/* -Filter helloworld -# get the rest of the smoke-tests. -$smoke_tests += Get-ChildItem smoke-tests/*/* -Directory -Exclude ('src*', 'public', 'test*', 'source', 'lib', 'web', 'dist', 'node_*') - -# print out the smoke tests. -foreach($e in $smoke_tests) { - Write-Output("$($e.Name): $($e.Parent)/$($e.Name)") -} -``` - -## clean - -> Remove installed dependencies and reset smoke tests in case something gone wrong - -```sh -cargo clean - -shopt -s globstar -rm -r **/node_modules - -cd smoke-tests -git checkout -- . # discard all unstaged changes -git clean -dfX # remove all untracked files & directories -``` - -```powershell -# Setup Environment to execute in the tauri directory. -$CWD = [Environment]::CurrentDirectory -Push-Location $MyInvocation.MyCommand.Path -[Environment]::CurrentDirectory = $PWD - -# clean up any artifacts. -cargo clean - -# find any node_module folders. -$node_paths = Get-ChildItem -Path smoke-tests\ -Filter node_modules -Recurse -ErrorAction SilentlyContinue -Force - -if (-Not $node_paths -eq $null) { -# delete all of the node_module folders. - foreach ($path in $node_paths) { - $path.Delete() - } - # enter the smoke-tests folder and remove any changes. - cd $CWD/smoke-tests; git checkout -- .; git clean -dfX -} - - -``` diff --git a/package.json b/package.json index 9817cff6d0e7..d38234c31fd4 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/tauri-apps/tauri.git", - "directory": "tooling/cli.js" + "url": "https://github.com/tauri-apps/tauri.git" }, "scripts": { "format": "prettier --write --end-of-line=auto \"./**/*.{cjs,js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore", @@ -18,6 +17,9 @@ "devDependencies": { "covector": "^0.5.3", "husky": "^6.0.0", - "prettier": "^2.2.1" + "prettier": "^2.5.1" + }, + "dependencies": { + "typescript": "^4.5.4" } } diff --git a/renovate.json b/renovate.json index d8de87609d42..ebd1563c7d58 100644 --- a/renovate.json +++ b/renovate.json @@ -1,20 +1,31 @@ { - "extends": ["config:base"], + "extends": [ + "config:base" + ], "schedule": "after 3am on Wednesday", "ignorePaths": [], - "labels": ["chore"], - "enabledManagers": ["cargo", "npm"], + "labels": [ + "chore" + ], + "enabledManagers": [ + "cargo", + "npm" + ], "cargo": { "enabled": true }, "packageRules": [ { - "packagePatterns": ["*"], + "packagePatterns": [ + "*" + ], "enabled": false }, { "enabled": true, - "paths": ["core/tauri/**"], + "paths": [ + "core/tauri/**" + ], "groupName": "Tauri Core", "groupSlug": "allTauriCore", "commitMessagePrefix": "chore(deps)", @@ -25,7 +36,9 @@ }, { "enabled": true, - "paths": ["core/tauri-build/**"], + "paths": [ + "core/tauri-build/**" + ], "groupName": "Tauri Build", "groupSlug": "allTauriBuild", "commitMessagePrefix": "chore(deps)", @@ -36,7 +49,9 @@ }, { "enabled": true, - "paths": ["core/tauri-codegen/**"], + "paths": [ + "core/tauri-codegen/**" + ], "groupName": "Tauri Codegen", "groupSlug": "allTauriCodegen", "commitMessagePrefix": "chore(deps)", @@ -47,7 +62,9 @@ }, { "enabled": true, - "paths": ["core/tauri-macros/**"], + "paths": [ + "core/tauri-macros/**" + ], "groupName": "Tauri Macros", "groupSlug": "allTauriMacros", "commitMessagePrefix": "chore(deps)", @@ -58,7 +75,9 @@ }, { "enabled": true, - "paths": ["core/tauri-utils/**"], + "paths": [ + "core/tauri-utils/**" + ], "groupName": "Tauri Utils", "groupSlug": "allTauriUtils", "commitMessagePrefix": "chore(deps)", @@ -69,7 +88,9 @@ }, { "enabled": true, - "paths": ["tooling/cli.rs/**"], + "paths": [ + "tooling/cli/**" + ], "groupName": "Tauri CLI", "groupSlug": "allTauriCLI", "commitMessagePrefix": "chore(deps)", @@ -80,7 +101,9 @@ }, { "enabled": true, - "paths": ["tooling/bundler/**"], + "paths": [ + "tooling/bundler/**" + ], "groupName": "Tauri Bundler", "groupSlug": "allTauriBundler", "commitMessagePrefix": "chore(deps)", @@ -91,7 +114,9 @@ }, { "enabled": true, - "paths": ["tooling/cli.js/**"], + "paths": [ + "tooling/cli/node" + ], "groupName": "Tauri JS CLI", "groupSlug": "allTauriJSCLI", "commitMessagePrefix": "chore(deps)", @@ -102,7 +127,9 @@ }, { "enabled": true, - "paths": ["tooling/api/**"], + "paths": [ + "tooling/api/**" + ], "groupName": "Tauri API Definitions", "groupSlug": "allTauriAPIDefinitions", "commitMessagePrefix": "chore(deps)", @@ -113,7 +140,9 @@ }, { "enabled": true, - "paths": ["tooling/create-tauri-app/**"], + "paths": [ + "tooling/create-tauri-app/**" + ], "groupName": "create-tauri-app", "groupSlug": "allCTA", "commitMessagePrefix": "chore(deps)", @@ -123,4 +152,4 @@ "rebaseConflictedPrs": false } ] -} +} \ No newline at end of file diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index b7921ae87bcb..000000000000 --- a/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.54.0 diff --git a/rustfmt.toml b/rustfmt.toml index 49c6abc12218..b0094a0655d8 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -6,7 +6,7 @@ use_small_heuristics = "Default" reorder_imports = true reorder_modules = true remove_nested_parens = true -edition = "2018" +edition = "2021" merge_derives = true use_try_shorthand = false use_field_init_shorthand = false diff --git a/tooling/api/.gitignore b/tooling/api/.gitignore index 0169607dd76e..e77e5b1c3571 100644 --- a/tooling/api/.gitignore +++ b/tooling/api/.gitignore @@ -62,3 +62,6 @@ typings/ debug.log package-lock.json .vscode/settings.json + +# Documentation output +docs \ No newline at end of file diff --git a/tooling/api/package.json b/tooling/api/package.json index e704e635976a..e02623ca2cd7 100644 --- a/tooling/api/package.json +++ b/tooling/api/package.json @@ -18,7 +18,8 @@ "lint-fix": "eslint --fix --ext ts \"./src/**/*.ts\"", "lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn", "format": "prettier --write --end-of-line=auto \"./**/*.{cjs,js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore", - "format:check": "prettier --check --end-of-line=auto \"./**/*.{cjs,js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore" + "format:check": "prettier --check --end-of-line=auto \"./**/*.{cjs,js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore", + "generate-docs": "typedoc src --githubPages false --readme none --entryDocument index.md --hideInPageTOC true --out docs --json docs/js-api.json --pretty false" }, "repository": { "type": "git", @@ -41,34 +42,35 @@ "yarn": ">= 1.19.1" }, "devDependencies": { - "@babel/core": "7.15.0", - "@babel/preset-env": "7.15.0", - "@babel/preset-typescript": "7.15.0", + "@babel/core": "7.17.2", + "@babel/preset-env": "7.16.11", + "@babel/preset-typescript": "7.16.7", "@rollup/plugin-babel": "5.3.0", - "@rollup/plugin-commonjs": "20.0.0", - "@rollup/plugin-node-resolve": "13.0.4", - "@rollup/plugin-sucrase": "4.0.0", - "@rollup/plugin-typescript": "8.2.5", - "@typescript-eslint/eslint-plugin": "4.29.1", - "@typescript-eslint/parser": "4.29.1", - "eslint": "7.32.0", + "@rollup/plugin-commonjs": "21.0.1", + "@rollup/plugin-node-resolve": "13.1.3", + "@rollup/plugin-sucrase": "4.0.2", + "@rollup/plugin-typescript": "8.3.0", + "@typescript-eslint/eslint-plugin": "5.11.0", + "@typescript-eslint/parser": "5.11.0", + "eslint": "8.8.0", "eslint-config-prettier": "8.3.0", - "eslint-config-standard-with-typescript": "20.0.0", - "eslint-plugin-import": "2.24.0", + "eslint-config-standard-with-typescript": "21.0.1", + "eslint-plugin-import": "2.25.4", "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "5.1.0", + "eslint-plugin-promise": "6.0.0", "eslint-plugin-security": "1.4.0", - "fs-extra": "10.0.0", "lockfile-lint": "4.6.2", - "prettier": "2.3.2", + "prettier": "2.5.1", "regenerator-runtime": "0.13.9", "rimraf": "3.0.2", - "rollup": "2.56.2", + "rollup": "2.67.1", "rollup-plugin-terser": "7.0.2", "tslib": "2.3.1", - "type-fest": "2.0.0", - "typedoc": "0.21.5", - "typedoc-plugin-markdown": "3.10.4", - "typescript": "4.3.5" + "typedoc": "0.22.11", + "typedoc-plugin-markdown": "3.11.13", + "typescript": "4.5.5" + }, + "dependencies": { + "type-fest": "2.11.2" } } diff --git a/tooling/api/scripts/after-build.cjs b/tooling/api/scripts/after-build.cjs index 78bbe5afea0f..383bd15ad11d 100644 --- a/tooling/api/scripts/after-build.cjs +++ b/tooling/api/scripts/after-build.cjs @@ -3,7 +3,6 @@ // SPDX-License-Identifier: MIT const { readFileSync, readdirSync, writeFileSync, copyFileSync } = require('fs') -const { copySync } = require('fs-extra') // append our api modules to `exports` in `package.json` then write it to `./dist` const pkg = JSON.parse(readFileSync('package.json', 'utf8')) @@ -42,6 +41,3 @@ const files = [ ...dir.filter((f) => f.endsWith('.md')) ] files.forEach((f) => copyFileSync(f, `dist/${f}`)) - -// copy typescript src files to `./dist` -copySync('src', 'dist') diff --git a/tooling/api/src/bundle.ts b/tooling/api/src/bundle.ts index cb0390c84253..f19285144cb4 100644 --- a/tooling/api/src/bundle.ts +++ b/tooling/api/src/bundle.ts @@ -2,8 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -/** @ignore */ /** */ - import 'regenerator-runtime/runtime' import * as app from './app' import * as cli from './cli' @@ -21,6 +19,8 @@ import * as tauri from './tauri' import * as updater from './updater' import * as window from './window' import * as os from './os' + +/** @ignore */ const invoke = tauri.invoke export { diff --git a/tooling/api/src/dialog.ts b/tooling/api/src/dialog.ts index 36c5845a9bb0..554934096905 100644 --- a/tooling/api/src/dialog.ts +++ b/tooling/api/src/dialog.ts @@ -43,9 +43,11 @@ interface DialogFilter { /** Options for the open dialog. */ interface OpenDialogOptions { + /** The title of the dialog window. */ + title?: string /** The filters of the dialog. */ filters?: DialogFilter[] - /** Initial directory or file path. It must exist. */ + /** Initial directory or file path. */ defaultPath?: string /** Whether the dialog allows multiple selection or not. */ multiple?: boolean @@ -55,6 +57,8 @@ interface OpenDialogOptions { /** Options for the save dialog. */ interface SaveDialogOptions { + /** The title of the dialog window. */ + title?: string /** The filters of the dialog. */ filters?: DialogFilter[] /** @@ -77,7 +81,7 @@ async function open( Object.freeze(options) } - return invokeTauriCommand({ + return invokeTauriCommand({ __tauriModule: 'Dialog', message: { cmd: 'openDialog', @@ -96,7 +100,7 @@ async function save(options: SaveDialogOptions = {}): Promise { Object.freeze(options) } - return invokeTauriCommand({ + return invokeTauriCommand({ __tauriModule: 'Dialog', message: { cmd: 'saveDialog', @@ -105,6 +109,61 @@ async function save(options: SaveDialogOptions = {}): Promise { }) } +/** + * Shows a message dialog with an `Ok` button. + * + * @param {string} message The message to show. + * + * @return {Promise} A promise indicating the success or failure of the operation. + */ +async function message(message: string): Promise { + return invokeTauriCommand({ + __tauriModule: 'Dialog', + message: { + cmd: 'messageDialog', + message + } + }) +} + +/** + * Shows a question dialog with `Yes` and `No` buttons. + * + * @param {string} message The message to show. + * @param {string|undefined} title The dialog's title. Defaults to the application name. + * + * @return {Promise} A promise resolving to a boolean indicating whether `Yes` was clicked or not. + */ +async function ask(message: string, title?: string): Promise { + return invokeTauriCommand({ + __tauriModule: 'Dialog', + message: { + cmd: 'askDialog', + title, + message + } + }) +} + +/** + * Shows a question dialog with `Ok` and `Cancel` buttons. + * + * @param {string} message The message to show. + * @param {string|undefined} title The dialog's title. Defaults to the application name. + * + * @return {Promise} A promise resolving to a boolean indicating whether `Ok` was clicked or not. + */ +async function confirm(message: string, title?: string): Promise { + return invokeTauriCommand({ + __tauriModule: 'Dialog', + message: { + cmd: 'confirmDialog', + title, + message + } + }) +} + export type { DialogFilter, OpenDialogOptions, SaveDialogOptions } -export { open, save } +export { open, save, message, ask, confirm } diff --git a/tooling/api/src/event.ts b/tooling/api/src/event.ts index da614db27668..dd108f8171f6 100644 --- a/tooling/api/src/event.ts +++ b/tooling/api/src/event.ts @@ -9,109 +9,51 @@ * @module */ -import { invokeTauriCommand } from './helpers/tauri' -import { emit as emitEvent } from './helpers/event' -import { transformCallback } from './tauri' -import { LiteralUnion } from 'type-fest' - -interface Event { - /** Event name */ - event: string - /** Event identifier used to unlisten */ - id: number - /** Event payload */ - payload: T -} - -type EventName = LiteralUnion< - | 'tauri://update' - | 'tauri://update-available' - | 'tauri://update-install' - | 'tauri://update-status' - | 'tauri://resize' - | 'tauri://move' - | 'tauri://close-requested' - | 'tauri://destroyed' - | 'tauri://focus' - | 'tauri://blur' - | 'tauri://scale-change' - | 'tauri://menu' - | 'tauri://file-drop' - | 'tauri://file-drop-hover' - | 'tauri://file-drop-cancelled', - string -> - -type EventCallback = (event: Event) => void - -type UnlistenFn = () => void - -/** - * Unregister the event listener associated with the given id. - * - * @ignore - * @param eventId Event identifier - * @returns - */ -async function _unlisten(eventId: number): Promise { - return invokeTauriCommand({ - __tauriModule: 'Event', - message: { - cmd: 'unlisten', - eventId - } - }) -} +import * as eventApi from './helpers/event' +import type { + EventName, + EventCallback, + UnlistenFn, + Event +} from './helpers/event' /** * Listen to an event from the backend. * - * @param event Event name - * @param handler Event handler callback + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. + * @param handler Event handler callback. * @return A promise resolving to a function to unlisten to the event. */ async function listen( event: EventName, handler: EventCallback ): Promise { - return invokeTauriCommand({ - __tauriModule: 'Event', - message: { - cmd: 'listen', - event, - handler: transformCallback(handler) - } - }).then((eventId) => { - return async () => _unlisten(eventId) - }) + return eventApi.listen(event, null, handler) } /** * Listen to an one-off event from the backend. * - * @param event Event name - * @param handler Event handler callback + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. + * @param handler Event handler callback. * @returns A promise resolving to a function to unlisten to the event. */ async function once( event: EventName, handler: EventCallback ): Promise { - return listen(event, (eventData) => { - handler(eventData) - _unlisten(eventData.id).catch(() => {}) - }) + return eventApi.once(event, null, handler) } /** * Emits an event to the backend. * - * @param event Event name + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. * @param [payload] Event payload * @returns */ -async function emit(event: string, payload?: string): Promise { - return emitEvent(event, undefined, payload) +async function emit(event: string, payload?: unknown): Promise { + return eventApi.emit(event, undefined, payload) } export type { Event, EventName, EventCallback, UnlistenFn } diff --git a/tooling/api/src/fs.ts b/tooling/api/src/fs.ts index 3c7acc990e9a..836ed8889425 100644 --- a/tooling/api/src/fs.ts +++ b/tooling/api/src/fs.ts @@ -14,10 +14,8 @@ * "allowlist": { * "fs": { * "all": true, // enable all FS APIs - * "readTextFile": true, - * "readBinaryFile": true, + * "readFile": true, * "writeFile": true, - * "writeBinaryFile": true, * "readDir": true, * "copyFile": true, * "createDir": true, @@ -54,7 +52,7 @@ export enum BaseDirectory { Video, Resource, App, - Current + Log } interface FsOptions { @@ -66,14 +64,20 @@ interface FsDirOptions { recursive?: boolean } +/** Options object used to write a UTF-8 string to a file. */ interface FsTextFileOption { + /** Path to the file to write. */ path: string + /** The UTF-8 string to write to the file. */ contents: string } +/** Options object used to write a binary data to a file. */ interface FsBinaryFileOption { + /** Path to the file to write. */ path: string - contents: ArrayBuffer + /** The byte array contents. */ + contents: Iterable | ArrayLike } interface FileEntry { @@ -88,7 +92,7 @@ interface FileEntry { } /** - * Reads a file as UTF-8 encoded string. + * Reads a file as an UTF-8 encoded string. * * @param filePath Path to the file. * @param options Configuration object. @@ -98,14 +102,14 @@ async function readTextFile( filePath: string, options: FsOptions = {} ): Promise { - return invokeTauriCommand({ + return invokeTauriCommand({ __tauriModule: 'Fs', message: { - cmd: 'readTextFile', + cmd: 'readFile', path: filePath, options } - }) + }).then((data) => new TextDecoder().decode(new Uint8Array(data))) } /** @@ -118,19 +122,21 @@ async function readTextFile( async function readBinaryFile( filePath: string, options: FsOptions = {} -): Promise { - return invokeTauriCommand({ +): Promise { + const arr = await invokeTauriCommand({ __tauriModule: 'Fs', message: { - cmd: 'readBinaryFile', + cmd: 'readFile', path: filePath, options } }) + + return Uint8Array.from(arr) } /** - * Writes a text file. + * Writes a UTF-8 text file. * * @param file File configuration object. * @param options Configuration object. @@ -152,50 +158,14 @@ async function writeFile( message: { cmd: 'writeFile', path: file.path, - contents: file.contents, + contents: Array.from(new TextEncoder().encode(file.contents)), options } }) } -/** @ignore */ -const CHUNK_SIZE = 65536 - /** - * Convert an Uint8Array to ascii string. - * - * @ignore - * @param arr - * @returns An ASCII string. - */ -function uint8ArrayToString(arr: Uint8Array): string { - if (arr.length < CHUNK_SIZE) { - return String.fromCharCode.apply(null, Array.from(arr)) - } - - let result = '' - const arrLen = arr.length - for (let i = 0; i < arrLen; i++) { - const chunk = arr.subarray(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE) - result += String.fromCharCode.apply(null, Array.from(chunk)) - } - return result -} - -/** - * Convert an ArrayBuffer to base64 encoded string. - * - * @ignore - * @param buffer - * @returns A base64 encoded string. - */ -function arrayBufferToBase64(buffer: ArrayBuffer): string { - const str = uint8ArrayToString(new Uint8Array(buffer)) - return btoa(str) -} - -/** - * Writes a binary file. + * Writes a byte array content to a file. * * @param file Write configuration object. * @param options Configuration object. @@ -215,9 +185,9 @@ async function writeBinaryFile( return invokeTauriCommand({ __tauriModule: 'Fs', message: { - cmd: 'writeBinaryFile', + cmd: 'writeFile', path: file.path, - contents: arrayBufferToBase64(file.contents), + contents: Array.from(file.contents), options } }) diff --git a/tooling/api/src/helpers/event.ts b/tooling/api/src/helpers/event.ts index 20f69f10fa83..95d569510ef4 100644 --- a/tooling/api/src/helpers/event.ts +++ b/tooling/api/src/helpers/event.ts @@ -2,23 +2,73 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -/** @ignore */ - import { WindowLabel } from '../window' import { invokeTauriCommand } from './tauri' +import { transformCallback } from '../tauri' +import { LiteralUnion } from 'type-fest' + +export interface Event { + /** Event name */ + event: EventName + /** The label of the window that emitted this event. */ + windowLabel: string + /** Event identifier used to unlisten */ + id: number + /** Event payload */ + payload: T +} + +export type EventName = LiteralUnion< + | 'tauri://update' + | 'tauri://update-available' + | 'tauri://update-install' + | 'tauri://update-status' + | 'tauri://resize' + | 'tauri://move' + | 'tauri://close-requested' + | 'tauri://focus' + | 'tauri://blur' + | 'tauri://scale-change' + | 'tauri://menu' + | 'tauri://file-drop' + | 'tauri://file-drop-hover' + | 'tauri://file-drop-cancelled', + string +> + +export type EventCallback = (event: Event) => void + +export type UnlistenFn = () => void + +/** + * Unregister the event listener associated with the given id. + * + * @ignore + * @param eventId Event identifier + * @returns + */ +async function _unlisten(eventId: number): Promise { + return invokeTauriCommand({ + __tauriModule: 'Event', + message: { + cmd: 'unlisten', + eventId + } + }) +} /** * Emits an event to the backend. * - * @param event Event name + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. * @param [windowLabel] The label of the window to which the event is sent, if null/undefined the event will be sent to all windows * @param [payload] Event payload * @returns */ async function emit( event: string, - windowLabel: WindowLabel, - payload?: string + windowLabel?: WindowLabel, + payload?: unknown ): Promise { await invokeTauriCommand({ __tauriModule: 'Event', @@ -26,9 +76,52 @@ async function emit( cmd: 'emit', event, windowLabel, - payload + payload: typeof payload === 'string' ? payload : JSON.stringify(payload) } }) } -export { emit } +/** + * Listen to an event from the backend. + * + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. + * @param handler Event handler callback. + * @return A promise resolving to a function to unlisten to the event. + */ +async function listen( + event: EventName, + windowLabel: string | null, + handler: EventCallback +): Promise { + return invokeTauriCommand({ + __tauriModule: 'Event', + message: { + cmd: 'listen', + event, + windowLabel, + handler: transformCallback(handler) + } + }).then((eventId) => { + return async () => _unlisten(eventId) + }) +} + +/** + * Listen to an one-off event from the backend. + * + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. + * @param handler Event handler callback. + * @returns A promise resolving to a function to unlisten to the event. + */ +async function once( + event: EventName, + windowLabel: string | null, + handler: EventCallback +): Promise { + return listen(event, windowLabel, (eventData) => { + handler(eventData) + _unlisten(eventData.id).catch(() => {}) + }) +} + +export { emit, listen, once } diff --git a/tooling/api/src/http.ts b/tooling/api/src/http.ts index 0475bf99b68f..d381b6885d09 100644 --- a/tooling/api/src/http.ts +++ b/tooling/api/src/http.ts @@ -37,7 +37,7 @@ enum ResponseType { Binary = 3 } -type Part = 'string' | number[] +type Part = string | Uint8Array /** The body object to be used on POST and PUT requests. */ class Body { @@ -58,7 +58,14 @@ class Body { * @return The body object ready to be used on the POST and PUT requests. */ static form(data: Record): Body { - return new Body('Form', data) + const form: Record = {} + for (const key in data) { + // eslint-disable-next-line security/detect-object-injection + const v = data[key] + // eslint-disable-next-line security/detect-object-injection + form[key] = typeof v === 'string' ? v : Array.from(v) + } + return new Body('Form', form) } /** @@ -90,8 +97,9 @@ class Body { * * @return The body object ready to be used on the POST and PUT requests. */ - static bytes(bytes: number[]): Body { - return new Body('Bytes', bytes) + static bytes(bytes: Uint8Array): Body { + // stringifying Uint8Array doesn't return an array of numbers, so we create one here + return new Body('Bytes', Array.from(bytes)) } } @@ -128,6 +136,7 @@ interface IResponse { url: string status: number headers: Record + rawHeaders: Record data: T } @@ -141,6 +150,8 @@ class Response { ok: boolean /** The response headers. */ headers: Record + /** The response raw headers. */ + rawHeaders: Record /** The response data. */ data: T @@ -150,6 +161,7 @@ class Response { this.status = response.status this.ok = this.status >= 200 && this.status < 300 this.headers = response.headers + this.rawHeaders = response.rawHeaders this.data = response.data } } @@ -203,7 +215,10 @@ class Client { // @ts-expect-error response.data = JSON.parse(response.data as string) } catch (e) { - if (response.ok) { + if (response.ok && (response.data as unknown as string) === '') { + // @ts-expect-error + response.data = {} + } else if (response.ok) { throw Error( `Failed to parse response \`${response.data}\` as JSON: ${e}; try setting the \`responseType\` option to \`ResponseType.Text\` or \`ResponseType.Binary\` if the API does not return a JSON response.` @@ -322,7 +337,7 @@ async function getClient(options?: ClientOptions): Promise { }).then((id) => new Client(id)) } -/** @ignore */ +/** @internal */ let defaultClient: Client | null = null /** diff --git a/tooling/api/src/index.ts b/tooling/api/src/index.ts index eef47f284a83..04d610d4755d 100644 --- a/tooling/api/src/index.ts +++ b/tooling/api/src/index.ts @@ -10,7 +10,7 @@ * ```typescript * import { app, dialog, event, fs, globalShortcut } from '@tauri-apps/api' * ``` - * @packageDocumentation + * @module */ export * from './bundle' diff --git a/tooling/api/src/os.ts b/tooling/api/src/os.ts index 7fede4f7ef1f..b17d9896bfb7 100644 --- a/tooling/api/src/os.ts +++ b/tooling/api/src/os.ts @@ -5,7 +5,7 @@ /** * Provides operating system-related utility methods and properties. * - * This package is also accessible with `window.__TAURI__.fs` when `tauri.conf.json > build > withGlobalTauri` is set to true. + * This package is also accessible with `window.__TAURI__.os` when `tauri.conf.json > build > withGlobalTauri` is set to true. * * The APIs must be allowlisted on `tauri.conf.json`: * ```json @@ -23,6 +23,7 @@ * @module */ +import { LiteralUnion } from 'type-fest' import { isWindows } from './helpers/os-check' import { invokeTauriCommand } from './helpers/tauri' @@ -35,9 +36,23 @@ const EOL = isWindows() ? '\r\n' : '\n' /** * Returns a string identifying the operating system platform. - * The value is set at compile time. Possible values are `'aix'`, `'darwin'`, `'freebsd'`, `'linux'`, `'openbsd'`, `'sunos'`, and `'win32'`. + * The value is set at compile time. Possible values are `'linux'`, `'darwin'`, `'ios'`, `'freebsd'`, `'dragonfly'`, `'netbsd'`, `'openbsd'`, `'solaris'`, `'android'`, `'win32'` */ -async function platform(): Promise { +async function platform(): Promise< + LiteralUnion< + | 'linux' + | 'darwin' + | 'ios' + | 'freebsd' + | 'dragonfly' + | 'netbsd' + | 'openbsd' + | 'solaris' + | 'android' + | 'win32', + string + > +> { return invokeTauriCommand({ __tauriModule: 'Os', message: { @@ -61,11 +76,13 @@ async function version(): Promise { /** * Returns `'Linux'` on Linux, `'Darwin'` on macOS, and `'Windows_NT'` on Windows. */ -async function type(): Promise { +async function type(): Promise< + LiteralUnion<'Linux' | 'Darwin' | 'Windows_NT', string> +> { return invokeTauriCommand({ __tauriModule: 'Os', message: { - cmd: 'type' + cmd: 'osType' } }) } @@ -73,7 +90,22 @@ async function type(): Promise { /** * Returns the operating system CPU architecture for which the tauri app was compiled. Possible values are `'x86'`, `'x86_64'`, `'arm'`, `'aarch64'`, `'mips'`, `'mips64'`, `'powerpc'`, `'powerpc64'`, `'riscv64'`, `'s390x'`, `'sparc64'` */ -async function arch(): Promise { +async function arch(): Promise< + LiteralUnion< + | 'x86' + | 'x86_64' + | 'arm' + | 'aarch64' + | 'mips' + | 'mips64' + | 'powerpc' + | 'powerpc64' + | 'riscv64' + | 's390x' + | 'sparc64', + string + > +> { return invokeTauriCommand({ __tauriModule: 'Os', message: { diff --git a/tooling/api/src/path.ts b/tooling/api/src/path.ts index 16cb897d57ca..1c0ec7386a86 100644 --- a/tooling/api/src/path.ts +++ b/tooling/api/src/path.ts @@ -47,9 +47,9 @@ async function appDir(): Promise { /** * Returns the path to the user's audio directory. * - * ## Platform-specific + * #### Platform-specific * - * - **Linux:** Resolves to `$XDG_MUSIC_DIR`. + * - **Linux:** Resolves to [`xdg-user-dirs`](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/)' `XDG_MUSIC_DIR`. * - **macOS:** Resolves to `$HOME/Music`. * - **Windows:** Resolves to `{FOLDERID_Music}`. * @@ -69,7 +69,7 @@ async function audioDir(): Promise { /** * Returns the path to the user's cache directory. * - * ## Platform-specific + * #### Platform-specific * * - **Linux:** Resolves to `$XDG_CACHE_HOME` or `$HOME/.cache`. * - **macOS:** Resolves to `$HOME/Library/Caches`. @@ -91,7 +91,7 @@ async function cacheDir(): Promise { /** * Returns the path to the user's config directory. * - * ## Platform-specific + * #### Platform-specific * * - **Linux:** Resolves to `$XDG_CONFIG_HOME` or `$HOME/.config`. * - **macOS:** Resolves to `$HOME/Library/Application Support`. @@ -113,7 +113,7 @@ async function configDir(): Promise { /** * Returns the path to the user's data directory. * - * ## Platform-specific + * #### Platform-specific * * - **Linux:** Resolves to `$XDG_DATA_HOME` or `$HOME/.local/share`. * - **macOS:** Resolves to `$HOME/Library/Application Support`. @@ -135,9 +135,9 @@ async function dataDir(): Promise { /** * Returns the path to the user's desktop directory. * - * ## Platform-specific + * #### Platform-specific * - * - **Linux:** Resolves to `$XDG_DESKTOP_DIR`. + * - **Linux:** Resolves to [`xdg-user-dirs`](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/)' `XDG_DESKTOP_DIR`. * - **macOS:** Resolves to `$HOME/Library/Desktop`. * - **Windows:** Resolves to `{FOLDERID_Desktop}`. @@ -157,9 +157,9 @@ async function desktopDir(): Promise { /** * Returns the path to the user's document directory. * - * ## Platform-specific + * #### Platform-specific * - * - **Linux:** Resolves to `$XDG_DOCUMENTS_DIR`. + * - **Linux:** Resolves to [`xdg-user-dirs`](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/)' `XDG_DOCUMENTS_DIR`. * - **macOS:** Resolves to `$HOME/Documents`. * - **Windows:** Resolves to `{FOLDERID_Documents}`. * @@ -179,9 +179,9 @@ async function documentDir(): Promise { /** * Returns the path to the user's download directory. * - * ## Platform-specific + * #### Platform-specific * - * - **Linux**: Resolves to `$XDG_DOWNLOAD_DIR`. + * - **Linux**: Resolves to [`xdg-user-dirs`](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/)' `XDG_DOWNLOAD_DIR`. * - **macOS**: Resolves to `$HOME/Downloads`. * - **Windows**: Resolves to `{FOLDERID_Downloads}`. * @@ -201,7 +201,7 @@ async function downloadDir(): Promise { /** * Returns the path to the user's executable directory. * - * ## Platform-specific + * #### Platform-specific * * - **Linux:** Resolves to `$XDG_BIN_HOME/../bin` or `$XDG_DATA_HOME/../bin` or `$HOME/.local/bin`. * - **macOS:** Not supported. @@ -223,7 +223,7 @@ async function executableDir(): Promise { /** * Returns the path to the user's font directory. * - * ## Platform-specific + * #### Platform-specific * * - **Linux:** Resolves to `$XDG_DATA_HOME/fonts` or `$HOME/.local/share/fonts`. * - **macOS:** Resolves to `$HOME/Library/Fonts`. @@ -245,7 +245,7 @@ async function fontDir(): Promise { /** * Returns the path to the user's home directory. * - * ## Platform-specific + * #### Platform-specific * * - **Linux:** Resolves to `$HOME`. * - **macOS:** Resolves to `$HOME`. @@ -267,7 +267,7 @@ async function homeDir(): Promise { /** * Returns the path to the user's local data directory. * - * ## Platform-specific + * #### Platform-specific * * - **Linux:** Resolves to `$XDG_DATA_HOME` or `$HOME/.local/share`. * - **macOS:** Resolves to `$HOME/Library/Application Support`. @@ -289,9 +289,9 @@ async function localDataDir(): Promise { /** * Returns the path to the user's picture directory. * - * ## Platform-specific + * #### Platform-specific * - * - **Linux:** Resolves to `$XDG_PICTURES_DIR`. + * - **Linux:** Resolves to [`xdg-user-dirs`](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/)' `XDG_PICTURES_DIR`. * - **macOS:** Resolves to `$HOME/Pictures`. * - **Windows:** Resolves to `{FOLDERID_Pictures}`. * @@ -311,9 +311,9 @@ async function pictureDir(): Promise { /** * Returns the path to the user's public directory. * - * ## Platform-specific + * #### Platform-specific * - * - **Linux:** Resolves to `$XDG_PUBLICSHARE_DIR`. + * - **Linux:** Resolves to [`xdg-user-dirs`](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/)' `XDG_PUBLICSHARE_DIR`. * - **macOS:** Resolves to `$HOME/Public`. * - **Windows:** Resolves to `{FOLDERID_Public}`. * @@ -349,7 +349,7 @@ async function resourceDir(): Promise { /** * Returns the path to the user's runtime directory. * - * ## Platform-specific + * #### Platform-specific * * - **Linux:** Resolves to `$XDG_RUNTIME_DIR`. * - **macOS:** Not supported. @@ -371,9 +371,9 @@ async function runtimeDir(): Promise { /** * Returns the path to the user's template directory. * - * ## Platform-specific + * #### Platform-specific * - * - **Linux:** Resolves to `$XDG_TEMPLATES_DIR`. + * - **Linux:** Resolves to [`xdg-user-dirs`](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/)' `XDG_TEMPLATES_DIR`. * - **macOS:** Not supported. * - **Windows:** Resolves to `{FOLDERID_Templates}`. * @@ -393,9 +393,9 @@ async function templateDir(): Promise { /** * Returns the path to the user's video directory. * - * ## Platform-specific + * #### Platform-specific * - * - **Linux:** Resolves to `$XDG_VIDEOS_DIR`. + * - **Linux:** Resolves to [`xdg-user-dirs`](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/)' `XDG_VIDEOS_DIR`. * - **macOS:** Resolves to `$HOME/Movies`. * - **Windows:** Resolves to `{FOLDERID_Videos}`. * @@ -413,17 +413,23 @@ async function videoDir(): Promise { } /** - * Returns the path to the current working directory. + * Returns the path to the suggested log directory. + * + * ### Platform-specific + * + * - **Linux:** Resolves to `${configDir}/${bundleIdentifier}`. + * - **macOS:** Resolves to `${homeDir}//Library/Logs/{bundleIdentifier}` + * - **Windows:** Resolves to `${configDir}/${bundleIdentifier}`. * * @returns */ -async function currentDir(): Promise { +async function logDir(): Promise { return invokeTauriCommand({ __tauriModule: 'Path', message: { cmd: 'resolvePath', path: '', - directory: BaseDirectory.Current + directory: BaseDirectory.Log } }) } @@ -556,7 +562,7 @@ export { runtimeDir, templateDir, videoDir, - currentDir, + logDir, BaseDirectory, sep, delimiter, diff --git a/tooling/api/src/shell.ts b/tooling/api/src/shell.ts index 1042825ee0ac..272bcb87e2bd 100644 --- a/tooling/api/src/shell.ts +++ b/tooling/api/src/shell.ts @@ -56,8 +56,7 @@ interface ChildProcess { * Spawns a process. * * @ignore - * @param program The name of the program to execute e.g. 'mkdir' or 'node'. - * @param sidecar Whether the program is a sidecar or a system program. + * @param program The name of the scoped command. * @param onEvent Event handler. * @param args Program arguments. * @param options Configuration for the process spawn. @@ -66,7 +65,7 @@ interface ChildProcess { async function execute( onEvent: (event: CommandEvent) => void, program: string, - args?: string | string[], + args: string | string[] = [], options?: InternalSpawnOptions ): Promise { if (typeof args === 'object') { @@ -78,14 +77,14 @@ async function execute( message: { cmd: 'execute', program, - args: typeof args === 'string' ? [args] : args, + args, options, onEventFn: transformCallback(onEvent) } }) } -class EventEmitter { +class EventEmitter { /** @ignore */ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment private eventListeners: { @@ -123,7 +122,7 @@ class EventEmitter { * @return The `this` instance for chained calls. */ on(event: E, handler: (arg: any) => void): EventEmitter { - this.addEventListener(event as any, handler) + this.addEventListener(event, handler) return this } } @@ -150,13 +149,14 @@ class Child { * * @return A promise indicating the success or failure of the operation. */ - async write(data: string | number[]): Promise { + async write(data: string | Uint8Array): Promise { return invokeTauriCommand({ __tauriModule: 'Shell', message: { cmd: 'stdinWrite', pid: this.pid, - buffer: data + // correctly serialize Uint8Arrays + buffer: typeof data === 'string' ? data : Array.from(data) } }) } @@ -294,10 +294,10 @@ class Command extends EventEmitter<'close' | 'error'> { this.on('error', reject) const stdout: string[] = [] const stderr: string[] = [] - this.stdout.on('data', (line) => { + this.stdout.on('data', (line: string) => { stdout.push(line) }) - this.stderr.on('data', (line) => { + this.stderr.on('data', (line: string) => { stderr.push(line) }) this.on('close', (payload: TerminatedPayload) => { @@ -341,6 +341,10 @@ type CommandEvent = /** * Opens a path or URL with the system's default app, * or the one specified with `openWith`. + * + * The `openWith` value must be one of `firefox`, `google chrome`, `chromium` `safari`, + * `open`, `start`, `xdg-open`, `gio`, gnome-open`, `kde-open` or `wslview`. + * * @example * ```typescript * // opens the given URL on the default browser: diff --git a/tooling/api/src/tauri.ts b/tooling/api/src/tauri.ts index 149cfbae6c36..fd8deac52bc2 100644 --- a/tooling/api/src/tauri.ts +++ b/tooling/api/src/tauri.ts @@ -13,23 +13,16 @@ declare global { // eslint-disable-next-line @typescript-eslint/no-unused-vars interface Window { - rpc: { - notify: (command: string, args?: { [key: string]: unknown }) => void + __TAURI_IPC__: (message: any) => void + ipc: { + postMessage: (args: string) => void } } } -// the `__TAURI_INVOKE_KEY__` variable is injected at runtime by Tauri -// eslint-disable-next-line @typescript-eslint/naming-convention -declare let __TAURI_INVOKE_KEY__: number - /** @ignore */ -function uid(): string { - const length = new Int8Array(1) - window.crypto.getRandomValues(length) - const array = new Uint8Array(Math.max(16, Math.abs(length[0]))) - window.crypto.getRandomValues(array) - return array.join('') +function uid(): number { + return window.crypto.getRandomValues(new Uint32Array(1))[0] } /** @@ -41,13 +34,14 @@ function uid(): string { function transformCallback( callback?: (response: any) => void, once = false -): string { +): number { const identifier = uid() + const prop = `_${identifier}` - Object.defineProperty(window, identifier, { + Object.defineProperty(window, prop, { value: (result: any) => { if (once) { - Reflect.deleteProperty(window, identifier) + Reflect.deleteProperty(window, prop) } return callback?.(result) @@ -73,7 +67,7 @@ interface InvokeArgs { */ async function invoke(cmd: string, args: InvokeArgs = {}): Promise { return new Promise((resolve, reject) => { - const callback = transformCallback((e) => { + const callback = transformCallback((e: T) => { resolve(e) Reflect.deleteProperty(window, error) }, true) @@ -82,8 +76,8 @@ async function invoke(cmd: string, args: InvokeArgs = {}): Promise { Reflect.deleteProperty(window, callback) }, true) - window.rpc.notify(cmd, { - __invokeKey: __TAURI_INVOKE_KEY__, + window.__TAURI_IPC__({ + cmd, callback, error, ...args @@ -93,11 +87,15 @@ async function invoke(cmd: string, args: InvokeArgs = {}): Promise { /** * Convert a device file path to an URL that can be loaded by the webview. - * Note that `asset:` must be allowed on the `csp` value configured on `tauri.conf.json`. + * Note that `asset:` and `https://asset.localhost` must be allowed on the `csp` value configured on `tauri.conf.json > tauri > security`. + * Example CSP value: `"csp": "default-src 'self'; img-src 'self' asset: https://asset.localhost"`. + * + * Additionally, the `asset` must be allowlisted under `tauri.conf.json > tauri > allowlist > protocol`, + * and its access scope must be defined on the `assetScope` array on the same `protocol` object. * - * @param filePath the file path. On Windows, the drive name must be omitted, i.e. using `/Users/user/file.png` instead of `C:/Users/user/file.png`. + * @param filePath the file path. * - * @return the URL that can be used as source on the webview + * @return the URL that can be used as source on the webview. */ function convertFileSrc(filePath: string): string { return navigator.userAgent.includes('Windows') diff --git a/tooling/api/src/window.ts b/tooling/api/src/window.ts index b51c38d1afab..e8bcd5107118 100644 --- a/tooling/api/src/window.ts +++ b/tooling/api/src/window.ts @@ -50,9 +50,7 @@ * * #### 'tauri://close-requested' * Emitted when the user requests the window to be closed. - * - * #### 'tauri://destroyed' - * Emitted after the window is closed. + * If a listener is registered for this event, Tauri won't close the window so you must call `appWindow.close()` manually. * * #### 'tauri://focus' * Emitted when the window gains focus. @@ -85,8 +83,8 @@ */ import { invokeTauriCommand } from './helpers/tauri' -import { EventName, EventCallback, UnlistenFn, listen, once } from './event' -import { emit } from './helpers/event' +import type { EventName, EventCallback, UnlistenFn } from './event' +import { emit, listen, once } from './helpers/event' /** Allows you to retrieve information about a given monitor. */ interface Monitor { @@ -166,7 +164,7 @@ interface WindowDef { /** @ignore */ declare global { interface Window { - __TAURI__: { + __TAURI_METADATA__: { __windows: WindowDef[] __currentWindow: WindowDef } @@ -176,13 +174,13 @@ declare global { /** Attention type to request on a window. */ enum UserAttentionType { /** - * ## Platform-specific + * #### Platform-specific * - **macOS:** Bounces the dock icon until the application is in focus. * - **Windows:** Flashes both the window and the taskbar button until the application is in focus. */ Critical = 1, /** - * ## Platform-specific + * #### Platform-specific * - **macOS:** Bounces the dock icon once. * - **Windows:** Flashes the taskbar button until the application is in focus. */ @@ -195,7 +193,7 @@ enum UserAttentionType { * @return The current WebviewWindow. */ function getCurrent(): WebviewWindow { - return new WebviewWindow(window.__TAURI__.__currentWindow.label, { + return new WebviewWindow(window.__TAURI_METADATA__.__currentWindow.label, { // @ts-expect-error skip: true }) @@ -207,7 +205,7 @@ function getCurrent(): WebviewWindow { * @return The list of WebviewWindow. */ function getAll(): WebviewWindow[] { - return window.__TAURI__.__windows.map( + return window.__TAURI_METADATA__.__windows.map( (w) => new WebviewWindow(w.label, { // @ts-expect-error @@ -220,7 +218,7 @@ function getAll(): WebviewWindow[] { // events that are emitted right here instead of by the created webview const localTauriEvents = ['tauri://created', 'tauri://error'] /** @ignore */ -export type WindowLabel = string | null | undefined +export type WindowLabel = string /** * A webview window handle allows emitting and listening to events from the backend that are tied to the window. */ @@ -239,7 +237,7 @@ class WebviewWindowHandle { /** * Listen to an event emitted by the backend that is tied to the webview window. * - * @param event Event name. + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. * @param handler Event handler. * @returns A promise resolving to a function to unlisten to the event. */ @@ -254,13 +252,13 @@ class WebviewWindowHandle { listeners.splice(listeners.indexOf(handler), 1) }) } - return listen(event, handler) + return listen(event, this.label, handler) } /** * Listen to an one-off event emitted by the backend that is tied to the webview window. * - * @param event Event name. + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. * @param handler Event handler. * @returns A promise resolving to a function to unlisten to the event. */ @@ -272,20 +270,20 @@ class WebviewWindowHandle { listeners.splice(listeners.indexOf(handler), 1) }) } - return once(event, handler) + return once(event, this.label, handler) } /** * Emits an event to the backend, tied to the webview window. * - * @param event Event name. + * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. * @param payload Event payload. */ - async emit(event: string, payload?: string): Promise { + async emit(event: string, payload?: unknown): Promise { if (localTauriEvents.includes(event)) { // eslint-disable-next-line for (const handler of this.listeners[event] || []) { - handler({ event, id: -1, payload }) + handler({ event, id: -1, windowLabel: this.label, payload }) } return Promise.resolve() } @@ -330,7 +328,7 @@ class WindowManager extends WebviewWindowHandle { /** The position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop. */ async innerPosition(): Promise { - return invokeTauriCommand({ + return invokeTauriCommand<{ x: number; y: number }>({ __tauriModule: 'Window', message: { cmd: 'manage', @@ -341,12 +339,12 @@ class WindowManager extends WebviewWindowHandle { } } } - }) + }).then(({ x, y }) => new PhysicalPosition(x, y)) } /** The position of the top-left hand corner of the window relative to the top-left hand corner of the desktop. */ async outerPosition(): Promise { - return invokeTauriCommand({ + return invokeTauriCommand<{ x: number; y: number }>({ __tauriModule: 'Window', message: { cmd: 'manage', @@ -357,7 +355,7 @@ class WindowManager extends WebviewWindowHandle { } } } - }) + }).then(({ x, y }) => new PhysicalPosition(x, y)) } /** @@ -365,7 +363,7 @@ class WindowManager extends WebviewWindowHandle { * The client area is the content of the window, excluding the title bar and borders. */ async innerSize(): Promise { - return invokeTauriCommand({ + return invokeTauriCommand<{ width: number; height: number }>({ __tauriModule: 'Window', message: { cmd: 'manage', @@ -376,7 +374,7 @@ class WindowManager extends WebviewWindowHandle { } } } - }) + }).then(({ width, height }) => new PhysicalSize(width, height)) } /** @@ -384,7 +382,7 @@ class WindowManager extends WebviewWindowHandle { * These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead. */ async outerSize(): Promise { - return invokeTauriCommand({ + return invokeTauriCommand<{ width: number; height: number }>({ __tauriModule: 'Window', message: { cmd: 'manage', @@ -395,7 +393,7 @@ class WindowManager extends WebviewWindowHandle { } } } - }) + }).then(({ width, height }) => new PhysicalSize(width, height)) } /** Gets the window's current fullscreen state. */ @@ -509,9 +507,10 @@ class WindowManager extends WebviewWindowHandle { * Providing `null` will unset the request for user attention. Unsetting the request for * user attention might not be done automatically by the WM when the window receives input. * - * ## Platform-specific + * #### Platform-specific * * - **macOS:** `null` has no effect. + * - **Linux:** Urgency levels have the same effect. * * @param resizable * @returns A promise indicating the success or failure of the operation. @@ -791,14 +790,14 @@ class WindowManager extends WebviewWindowHandle { } /** - * Resizes the window. + * Resizes the window with a new inner size. * @example * ```typescript * import { appWindow, LogicalSize } from '@tauri-apps/api/window' * await appWindow.setSize(new LogicalSize(600, 500)) * ``` * - * @param size The logical or physical size. + * @param size The logical or physical inner size. * @returns A promise indicating the success or failure of the operation. */ async setSize(size: LogicalSize | PhysicalSize): Promise { @@ -829,18 +828,18 @@ class WindowManager extends WebviewWindowHandle { } /** - * Sets the window min size. If the `size` argument is not provided, the min size is unset. + * Sets the window minimum inner size. If the `size` argument is not provided, the constraint is unset. * @example * ```typescript * import { appWindow, PhysicalSize } from '@tauri-apps/api/window' * await appWindow.setMinSize(new PhysicalSize(600, 500)) * ``` * - * @param size The logical or physical size. + * @param size The logical or physical inner size, or `null` to unset the constraint. * @returns A promise indicating the success or failure of the operation. */ async setMinSize( - size: LogicalSize | PhysicalSize | undefined + size: LogicalSize | PhysicalSize | null | undefined ): Promise { if (size && size.type !== 'Logical' && size.type !== 'Physical') { throw new Error( @@ -871,18 +870,18 @@ class WindowManager extends WebviewWindowHandle { } /** - * Sets the window max size. If the `size` argument is undefined, the max size is unset. + * Sets the window maximum inner size. If the `size` argument is undefined, the constraint is unset. * @example * ```typescript * import { appWindow, LogicalSize } from '@tauri-apps/api/window' * await appWindow.setMaxSize(new LogicalSize(600, 500)) * ``` * - * @param size The logical or physical size. + * @param size The logical or physical inner size, or `null` to unset the constraint. * @returns A promise indicating the success or failure of the operation. */ async setMaxSize( - size: LogicalSize | PhysicalSize | undefined + size: LogicalSize | PhysicalSize | null | undefined ): Promise { if (size && size.type !== 'Logical' && size.type !== 'Physical') { throw new Error( @@ -913,7 +912,7 @@ class WindowManager extends WebviewWindowHandle { } /** - * Sets the window position. + * Sets the window outer position. * @example * ```typescript * import { appWindow, LogicalPosition } from '@tauri-apps/api/window' @@ -1003,7 +1002,7 @@ class WindowManager extends WebviewWindowHandle { * @param icon Icon bytes or path to the icon file. * @returns A promise indicating the success or failure of the operation. */ - async setIcon(icon: string | number[]): Promise { + async setIcon(icon: string | Uint8Array): Promise { return invokeTauriCommand({ __tauriModule: 'Window', message: { @@ -1013,7 +1012,8 @@ class WindowManager extends WebviewWindowHandle { cmd: { type: 'setIcon', payload: { - icon + // correctly serialize Uint8Arrays + icon: typeof icon === 'string' ? icon : Array.from(icon) } } } @@ -1092,6 +1092,11 @@ class WindowManager extends WebviewWindowHandle { * ``` */ class WebviewWindow extends WindowManager { + /** + * Creates a new WebviewWindow. + * * @param label The webview window label. It must be alphanumeric. + * @returns The WebviewWindow instance to communicate with the webview. + */ constructor(label: WindowLabel, options: WindowOptions = {}) { super(label) // @ts-expect-error @@ -1109,7 +1114,7 @@ class WebviewWindow extends WindowManager { } }) .then(async () => this.emit('tauri://created')) - .catch(async (e) => this.emit('tauri://error', e)) + .catch(async (e: string) => this.emit('tauri://error', e)) } } @@ -1129,15 +1134,22 @@ class WebviewWindow extends WindowManager { } /** The WebviewWindow for the current window. */ -const appWindow = new WebviewWindow(null, { - // @ts-expect-error - skip: true -}) +const appWindow = new WebviewWindow( + window.__TAURI_METADATA__.__currentWindow.label, + { + // @ts-expect-error + skip: true + } +) /** Configuration for the window to create. */ interface WindowOptions { /** - * Remote URL or local file path to open, e.g. `https://github.com/tauri-apps` or `path/to/page.html`. + * Remote URL or local file path to open. + * + * - URL such as `https://github.com/tauri-apps` is opened directly on a Tauri window. + * - data: URL such as `data:text/html,...` is only supported with the `window-data-url` Cargo feature for the `tauri` dependency. + * - local file path or route such as `/path/to/page.html` or `/users` is appended to the application URL (the devServer URL on development, or `tauri://localhost/` and `https://tauri.localhost/` on production). */ url?: string /** Show window in the center of the screen.. */ @@ -1166,7 +1178,11 @@ interface WindowOptions { fullscreen?: boolean /** Whether the window will be initially hidden or focused. */ focus?: boolean - /** Whether the window is transparent or not. */ + /** + * Whether the window is transparent or not. + * Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri.conf.json > tauri > macosPrivateApi`. + * WARNING: Using private APIs on `macOS` prevents your application from being accepted for the `App Store`. + */ transparent?: boolean /** Whether the window should be maximized upon creation or not. */ maximized?: boolean @@ -1178,6 +1194,12 @@ interface WindowOptions { alwaysOnTop?: boolean /** Whether or not the window icon should be added to the taskbar. */ skipTaskbar?: boolean + /** + * Whether the file drop is enabled or not on the webview. By default it is enabled. + * + * Disabling it is required to use drag and drop on the frontend on Windows. + */ + fileDropEnabled?: boolean } /** diff --git a/tooling/api/yarn.lock b/tooling/api/yarn.lock index 98a5d3ce968f..19e9a24c13cd 100644 --- a/tooling/api/yarn.lock +++ b/tooling/api/yarn.lock @@ -2,12 +2,12 @@ # yarn lockfile v1 -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== +"@ampproject/remapping@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.0.tgz#72becdf17ee44b2d1ac5651fb12f1952c336fe23" + integrity sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g== dependencies: - "@babel/highlight" "^7.10.4" + "@jridgewell/trace-mapping" "^0.3.0" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13": version "7.12.13" @@ -16,53 +16,48 @@ dependencies: "@babel/highlight" "^7.12.13" -"@babel/code-frame@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== +"@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== dependencies: - "@babel/highlight" "^7.14.5" + "@babel/highlight" "^7.16.7" "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.4": version "7.14.4" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.4.tgz#45720fe0cecf3fd42019e1d12cc3d27fadc98d58" integrity sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ== -"@babel/compat-data@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.5.tgz#8ef4c18e58e801c5c95d3c1c0f2874a2680fadea" - integrity sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w== - -"@babel/compat-data@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" - integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw== - -"@babel/compat-data@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" - integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== - -"@babel/core@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.0.tgz#749e57c68778b73ad8082775561f67f5196aafa8" - integrity sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.0" - "@babel/helper-compilation-targets" "^7.15.0" - "@babel/helper-module-transforms" "^7.15.0" - "@babel/helpers" "^7.14.8" - "@babel/parser" "^7.15.0" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" +"@babel/compat-data@^7.16.4": + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" + integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== + +"@babel/compat-data@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" + integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== + +"@babel/core@7.17.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.2.tgz#2c77fc430e95139d816d39b113b31bf40fb22337" + integrity sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw== + dependencies: + "@ampproject/remapping" "^2.0.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.0" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helpers" "^7.17.2" + "@babel/parser" "^7.17.0" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.1.2" semver "^6.3.0" - source-map "^0.5.0" "@babel/generator@^7.14.2": version "7.14.3" @@ -73,21 +68,30 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" - integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== +"@babel/generator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.7.tgz#b42bf46a3079fa65e1544135f32e7958f048adbb" + integrity sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.16.7" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15" - integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ== +"@babel/generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" + integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== dependencies: - "@babel/types" "^7.15.0" + "@babel/types" "^7.16.8" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/generator@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" + integrity sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw== + dependencies: + "@babel/types" "^7.17.0" jsesc "^2.5.1" source-map "^0.5.0" @@ -98,20 +102,20 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-annotate-as-pure@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" - integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA== +"@babel/helper-annotate-as-pure@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" + integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.16.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz#b939b43f8c37765443a19ae74ad8b15978e0a191" - integrity sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" + integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/helper-explode-assignable-expression" "^7.16.7" + "@babel/types" "^7.16.7" "@babel/helper-compilation-targets@^7.13.0": version "7.14.4" @@ -123,49 +127,41 @@ browserslist "^4.16.6" semver "^6.3.0" -"@babel/helper-compilation-targets@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" - integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== - dependencies: - "@babel/compat-data" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.16.6" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818" - integrity sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A== +"@babel/helper-compilation-targets@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== dependencies: - "@babel/compat-data" "^7.15.0" - "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.16.6" + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.14.5": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz#f114469b6c06f8b5c59c6c4e74621f5085362542" - integrity sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-member-expression-to-functions" "^7.14.5" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - -"@babel/helper-create-class-features-plugin@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz#c9a137a4d137b2d0e2c649acf536d7ba1a76c0f7" - integrity sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-member-expression-to-functions" "^7.15.0" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/helper-replace-supers" "^7.15.0" - "@babel/helper-split-export-declaration" "^7.14.5" +"@babel/helper-create-class-features-plugin@^7.16.10": + version "7.17.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21" + integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + +"@babel/helper-create-class-features-plugin@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz#9c5b34b53a01f2097daf10678d65135c1b9f84ba" + integrity sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" "@babel/helper-create-regexp-features-plugin@^7.12.13": version "7.14.3" @@ -175,18 +171,18 @@ "@babel/helper-annotate-as-pure" "^7.12.13" regexpu-core "^4.7.1" -"@babel/helper-create-regexp-features-plugin@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz#c7d5ac5e9cf621c26057722fb7a8a4c5889358c4" - integrity sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A== +"@babel/helper-create-regexp-features-plugin@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48" + integrity sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g== dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.16.7" regexpu-core "^4.7.1" -"@babel/helper-define-polyfill-provider@^0.2.2": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" - integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew== +"@babel/helper-define-polyfill-provider@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz#c5b10cf4b324ff840140bb07e05b8564af2ae971" + integrity sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg== dependencies: "@babel/helper-compilation-targets" "^7.13.0" "@babel/helper-module-imports" "^7.12.13" @@ -197,12 +193,19 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-explode-assignable-expression@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz#8aa72e708205c7bb643e45c73b4386cdf2a1f645" - integrity sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ== +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.16.7" + +"@babel/helper-explode-assignable-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" + integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== + dependencies: + "@babel/types" "^7.16.7" "@babel/helper-function-name@^7.14.2": version "7.14.2" @@ -213,14 +216,14 @@ "@babel/template" "^7.12.13" "@babel/types" "^7.14.2" -"@babel/helper-function-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" - integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== dependencies: - "@babel/helper-get-function-arity" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" "@babel/helper-get-function-arity@^7.12.13": version "7.12.13" @@ -229,33 +232,26 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-get-function-arity@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" - integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.16.7" -"@babel/helper-hoist-variables@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" - integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.16.7" -"@babel/helper-member-expression-to-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.5.tgz#d5c70e4ad13b402c95156c7a53568f504e2fb7b8" - integrity sha512-UxUeEYPrqH1Q/k0yRku1JE7dyfyehNwT6SVkMHvYvPDv4+uu627VXBckVj891BO8ruKBkiDoGnZf4qPDD8abDQ== +"@babel/helper-member-expression-to-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" + integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q== dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-member-expression-to-functions@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b" - integrity sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg== - dependencies: - "@babel/types" "^7.15.0" + "@babel/types" "^7.16.7" "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13": version "7.13.12" @@ -264,47 +260,33 @@ dependencies: "@babel/types" "^7.13.12" -"@babel/helper-module-imports@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" - integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== +"@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.16.7" -"@babel/helper-module-transforms@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz#7de42f10d789b423eb902ebd24031ca77cb1e10e" - integrity sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA== - dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - "@babel/helper-simple-access" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-module-transforms@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08" - integrity sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg== - dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-replace-supers" "^7.15.0" - "@babel/helper-simple-access" "^7.14.8" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.9" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" - -"@babel/helper-optimise-call-expression@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" - integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA== +"@babel/helper-module-transforms@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" + integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== dependencies: - "@babel/types" "^7.14.5" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-optimise-call-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" + integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== + dependencies: + "@babel/types" "^7.16.7" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.13.0" @@ -316,55 +298,44 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== -"@babel/helper-remap-async-to-generator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz#51439c913612958f54a987a4ffc9ee587a2045d6" - integrity sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-wrap-function" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-replace-supers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94" - integrity sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.14.5" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" +"@babel/helper-plugin-utils@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== -"@babel/helper-replace-supers@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz#ace07708f5bf746bf2e6ba99572cce79b5d4e7f4" - integrity sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA== +"@babel/helper-remap-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" + integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.15.0" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-wrap-function" "^7.16.8" + "@babel/types" "^7.16.8" -"@babel/helper-simple-access@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4" - integrity sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw== +"@babel/helper-replace-supers@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" + integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== dependencies: - "@babel/types" "^7.14.5" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" -"@babel/helper-simple-access@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz#82e1fec0644a7e775c74d305f212c39f8fe73924" - integrity sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg== +"@babel/helper-simple-access@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" + integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== dependencies: - "@babel/types" "^7.14.8" + "@babel/types" "^7.16.7" -"@babel/helper-skip-transparent-expression-wrappers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz#96f486ac050ca9f44b009fbe5b7d394cab3a0ee4" - integrity sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ== +"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" + integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.16.0" "@babel/helper-split-export-declaration@^7.12.13": version "7.12.13" @@ -373,58 +344,58 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-split-export-declaration@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" - integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.16.7" "@babel/helper-validator-identifier@^7.14.0": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== -"@babel/helper-validator-identifier@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" - integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== +"@babel/helper-validator-identifier@^7.15.7": + version "7.15.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" + integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== -"@babel/helper-validator-identifier@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" - integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== "@babel/helper-validator-option@^7.12.17": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== -"@babel/helper-validator-option@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" - integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== -"@babel/helper-wrap-function@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz#5919d115bf0fe328b8a5d63bcb610f51601f2bff" - integrity sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ== +"@babel/helper-wrap-function@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" + integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== dependencies: - "@babel/helper-function-name" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/helper-function-name" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.8" + "@babel/types" "^7.16.8" -"@babel/helpers@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.8.tgz#839f88f463025886cff7f85a35297007e2da1b77" - integrity sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw== +"@babel/helpers@^7.17.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" + integrity sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ== dependencies: - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.8" - "@babel/types" "^7.14.8" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": +"@babel/highlight@^7.12.13": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== @@ -433,12 +404,12 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== +"@babel/highlight@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b" + integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw== dependencies: - "@babel/helper-validator-identifier" "^7.14.5" + "@babel/helper-validator-identifier" "^7.16.7" chalk "^2.0.0" js-tokens "^4.0.0" @@ -447,152 +418,164 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.4.tgz#a5c560d6db6cd8e6ed342368dea8039232cbab18" integrity sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA== -"@babel/parser@^7.14.5": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.6.tgz#d85cc68ca3cac84eae384c06f032921f5227f4b2" - integrity sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ== +"@babel/parser@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.7.tgz#d372dda9c89fcec340a82630a9f533f2fe15877e" + integrity sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA== -"@babel/parser@^7.15.0": - version "7.15.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.2.tgz#08d4ffcf90d211bf77e7cc7154c6f02d468d2b1d" - integrity sha512-bMJXql1Ss8lFnvr11TZDH4ArtwlAS5NG9qBmdiFW2UHHm6MVoR+GDc5XE2b9K938cyjc9O6/+vjjcffLDtfuDg== +"@babel/parser@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" + integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e" - integrity sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ== +"@babel/parser@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" + integrity sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" + integrity sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" - "@babel/plugin-proposal-optional-chaining" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-async-generator-functions@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz#7028dc4fa21dc199bbacf98b39bab1267d0eaf9a" - integrity sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" + integrity sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + +"@babel/plugin-proposal-async-generator-functions@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" + integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz#40d1ee140c5b1e31a350f4f5eed945096559b42e" - integrity sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg== +"@babel/plugin-proposal-class-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" + integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz#158e9e10d449c3849ef3ecde94a03d9f1841b681" - integrity sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg== +"@babel/plugin-proposal-class-static-block@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz#712357570b612106ef5426d13dc433ce0f200c2a" + integrity sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-proposal-dynamic-import@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz#0c6617df461c0c1f8fff3b47cd59772360101d2c" - integrity sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g== +"@babel/plugin-proposal-dynamic-import@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" + integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-export-namespace-from@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz#dbad244310ce6ccd083072167d8cea83a52faf76" - integrity sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA== +"@babel/plugin-proposal-export-namespace-from@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" + integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz#38de60db362e83a3d8c944ac858ddf9f0c2239eb" - integrity sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ== +"@babel/plugin-proposal-json-strings@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" + integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz#6e6229c2a99b02ab2915f82571e0cc646a40c738" - integrity sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw== +"@babel/plugin-proposal-logical-assignment-operators@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" + integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz#ee38589ce00e2cc59b299ec3ea406fcd3a0fdaf6" - integrity sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" + integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz#83631bf33d9a51df184c2102a069ac0c58c05f18" - integrity sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg== +"@babel/plugin-proposal-numeric-separator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" + integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363" - integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g== +"@babel/plugin-proposal-object-rest-spread@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz#94593ef1ddf37021a25bdcb5754c4a8d534b01d8" + integrity sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA== dependencies: - "@babel/compat-data" "^7.14.7" - "@babel/helper-compilation-targets" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/compat-data" "^7.16.4" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.14.5" + "@babel/plugin-transform-parameters" "^7.16.7" -"@babel/plugin-proposal-optional-catch-binding@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz#939dd6eddeff3a67fdf7b3f044b5347262598c3c" - integrity sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ== +"@babel/plugin-proposal-optional-catch-binding@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" + integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz#fa83651e60a360e3f13797eef00b8d519695b603" - integrity sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ== +"@babel/plugin-proposal-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" + integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz#37446495996b2945f30f5be5b60d5e2aa4f5792d" - integrity sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g== +"@babel/plugin-proposal-private-methods@^7.16.11": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" + integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.16.10" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz#9f65a4d0493a940b4c01f8aa9d3f1894a587f636" - integrity sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q== +"@babel/plugin-proposal-private-property-in-object@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" + integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz#0f95ee0e757a5d647f378daa0eca7e93faa8bbe8" - integrity sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q== +"@babel/plugin-proposal-unicode-property-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" + integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.12.13" @@ -700,77 +683,78 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" - integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== +"@babel/plugin-syntax-typescript@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" + integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-arrow-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz#f7187d9588a768dd080bf4c9ffe117ea62f7862a" - integrity sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A== +"@babel/plugin-transform-arrow-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" + integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-async-to-generator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz#72c789084d8f2094acb945633943ef8443d39e67" - integrity sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA== +"@babel/plugin-transform-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" + integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.14.5" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" -"@babel/plugin-transform-block-scoped-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz#e48641d999d4bc157a67ef336aeb54bc44fd3ad4" - integrity sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ== +"@babel/plugin-transform-block-scoped-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" + integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-block-scoping@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz#8cc63e61e50f42e078e6f09be775a75f23ef9939" - integrity sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw== +"@babel/plugin-transform-block-scoping@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" + integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-classes@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz#2a391ffb1e5292710b00f2e2c210e1435e7d449f" - integrity sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A== +"@babel/plugin-transform-classes@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" + integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz#1b9d78987420d11223d41195461cc43b974b204f" - integrity sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg== +"@babel/plugin-transform-computed-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" + integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-destructuring@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576" - integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw== +"@babel/plugin-transform-destructuring@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23" + integrity sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-dotall-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz#2f6bf76e46bdf8043b4e7e16cf24532629ba0c7a" - integrity sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw== +"@babel/plugin-transform-dotall-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" + integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.12.13" @@ -780,223 +764,225 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-duplicate-keys@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz#365a4844881bdf1501e3a9f0270e7f0f91177954" - integrity sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A== +"@babel/plugin-transform-duplicate-keys@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" + integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-exponentiation-operator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz#5154b8dd6a3dfe6d90923d61724bd3deeb90b493" - integrity sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA== +"@babel/plugin-transform-exponentiation-operator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" + integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-for-of@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz#dae384613de8f77c196a8869cbf602a44f7fc0eb" - integrity sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA== +"@babel/plugin-transform-for-of@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" + integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-function-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz#e81c65ecb900746d7f31802f6bed1f52d915d6f2" - integrity sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ== +"@babel/plugin-transform-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" + integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== dependencies: - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz#41d06c7ff5d4d09e3cf4587bd3ecf3930c730f78" - integrity sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A== +"@babel/plugin-transform-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" + integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-member-expression-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz#b39cd5212a2bf235a617d320ec2b48bcc091b8a7" - integrity sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q== +"@babel/plugin-transform-member-expression-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" + integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-modules-amd@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz#4fd9ce7e3411cb8b83848480b7041d83004858f7" - integrity sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g== +"@babel/plugin-transform-modules-amd@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" + integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== dependencies: - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz#3305896e5835f953b5cdb363acd9e8c2219a5281" - integrity sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig== +"@babel/plugin-transform-modules-commonjs@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" + integrity sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA== dependencies: - "@babel/helper-module-transforms" "^7.15.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-simple-access" "^7.14.8" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz#c75342ef8b30dcde4295d3401aae24e65638ed29" - integrity sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA== +"@babel/plugin-transform-modules-systemjs@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7" + integrity sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw== dependencies: - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.5" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz#fb662dfee697cce274a7cda525190a79096aa6e0" - integrity sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA== +"@babel/plugin-transform-modules-umd@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" + integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== dependencies: - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-named-capturing-groups-regex@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz#c68f5c5d12d2ebaba3762e57c2c4f6347a46e7b2" - integrity sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" + integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" + "@babel/helper-create-regexp-features-plugin" "^7.16.7" -"@babel/plugin-transform-new-target@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz#31bdae8b925dc84076ebfcd2a9940143aed7dbf8" - integrity sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ== +"@babel/plugin-transform-new-target@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" + integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-object-super@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz#d0b5faeac9e98597a161a9cf78c527ed934cdc45" - integrity sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg== +"@babel/plugin-transform-object-super@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" + integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" -"@babel/plugin-transform-parameters@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz#49662e86a1f3ddccac6363a7dfb1ff0a158afeb3" - integrity sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA== +"@babel/plugin-transform-parameters@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" + integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-property-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz#0ddbaa1f83db3606f1cdf4846fa1dfb473458b34" - integrity sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw== +"@babel/plugin-transform-property-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" + integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-regenerator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz#9676fd5707ed28f522727c5b3c0aa8544440b04f" - integrity sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg== +"@babel/plugin-transform-regenerator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb" + integrity sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz#c44589b661cfdbef8d4300dcc7469dffa92f8304" - integrity sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-shorthand-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz#97f13855f1409338d8cadcbaca670ad79e091a58" - integrity sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-spread@^7.14.6": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz#6bd40e57fe7de94aa904851963b5616652f73144" - integrity sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" - -"@babel/plugin-transform-sticky-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz#5b617542675e8b7761294381f3c28c633f40aeb9" - integrity sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-template-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz#a5f2bc233937d8453885dc736bdd8d9ffabf3d93" - integrity sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-typeof-symbol@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz#39af2739e989a2bd291bf6b53f16981423d457d4" - integrity sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-typescript@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.0.tgz#553f230b9d5385018716586fc48db10dd228eb7e" - integrity sha512-WIIEazmngMEEHDaPTx0IZY48SaAmjVWe3TRSX7cmJXn0bEv9midFzAjxiruOWYIVf5iQ10vFx7ASDpgEO08L5w== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.15.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-typescript" "^7.14.5" - -"@babel/plugin-transform-unicode-escapes@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz#9d4bd2a681e3c5d7acf4f57fa9e51175d91d0c6b" - integrity sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-unicode-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz#4cd09b6c8425dd81255c7ceb3fb1836e7414382e" - integrity sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/preset-env@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.0.tgz#e2165bf16594c9c05e52517a194bf6187d6fe464" - integrity sha512-FhEpCNFCcWW3iZLg0L2NPE9UerdtsCR6ZcsGHUX6Om6kbCQeL5QZDqFDmeNHC6/fy6UH3jEge7K4qG5uC9In0Q== - dependencies: - "@babel/compat-data" "^7.15.0" - "@babel/helper-compilation-targets" "^7.15.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-async-generator-functions" "^7.14.9" - "@babel/plugin-proposal-class-properties" "^7.14.5" - "@babel/plugin-proposal-class-static-block" "^7.14.5" - "@babel/plugin-proposal-dynamic-import" "^7.14.5" - "@babel/plugin-proposal-export-namespace-from" "^7.14.5" - "@babel/plugin-proposal-json-strings" "^7.14.5" - "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" - "@babel/plugin-proposal-numeric-separator" "^7.14.5" - "@babel/plugin-proposal-object-rest-spread" "^7.14.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" - "@babel/plugin-proposal-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-private-methods" "^7.14.5" - "@babel/plugin-proposal-private-property-in-object" "^7.14.5" - "@babel/plugin-proposal-unicode-property-regex" "^7.14.5" +"@babel/plugin-transform-reserved-words@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" + integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-shorthand-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" + integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-spread@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" + integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + +"@babel/plugin-transform-sticky-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" + integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-template-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" + integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typeof-symbol@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" + integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typescript@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.7.tgz#33f8c2c890fbfdc4ef82446e9abb8de8211a3ff3" + integrity sha512-Hzx1lvBtOCWuCEwMmYOfpQpO7joFeXLgoPuzZZBtTxXqSqUGUubvFGZv2ygo1tB5Bp9q6PXV3H0E/kf7KM0RLA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-typescript" "^7.16.7" + +"@babel/plugin-transform-unicode-escapes@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" + integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" + integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/preset-env@7.16.11": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" + integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g== + dependencies: + "@babel/compat-data" "^7.16.8" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-async-generator-functions" "^7.16.8" + "@babel/plugin-proposal-class-properties" "^7.16.7" + "@babel/plugin-proposal-class-static-block" "^7.16.7" + "@babel/plugin-proposal-dynamic-import" "^7.16.7" + "@babel/plugin-proposal-export-namespace-from" "^7.16.7" + "@babel/plugin-proposal-json-strings" "^7.16.7" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.7" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" + "@babel/plugin-proposal-numeric-separator" "^7.16.7" + "@babel/plugin-proposal-object-rest-spread" "^7.16.7" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-private-methods" "^7.16.11" + "@babel/plugin-proposal-private-property-in-object" "^7.16.7" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.7" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" @@ -1011,50 +997,50 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.14.5" - "@babel/plugin-transform-async-to-generator" "^7.14.5" - "@babel/plugin-transform-block-scoped-functions" "^7.14.5" - "@babel/plugin-transform-block-scoping" "^7.14.5" - "@babel/plugin-transform-classes" "^7.14.9" - "@babel/plugin-transform-computed-properties" "^7.14.5" - "@babel/plugin-transform-destructuring" "^7.14.7" - "@babel/plugin-transform-dotall-regex" "^7.14.5" - "@babel/plugin-transform-duplicate-keys" "^7.14.5" - "@babel/plugin-transform-exponentiation-operator" "^7.14.5" - "@babel/plugin-transform-for-of" "^7.14.5" - "@babel/plugin-transform-function-name" "^7.14.5" - "@babel/plugin-transform-literals" "^7.14.5" - "@babel/plugin-transform-member-expression-literals" "^7.14.5" - "@babel/plugin-transform-modules-amd" "^7.14.5" - "@babel/plugin-transform-modules-commonjs" "^7.15.0" - "@babel/plugin-transform-modules-systemjs" "^7.14.5" - "@babel/plugin-transform-modules-umd" "^7.14.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.9" - "@babel/plugin-transform-new-target" "^7.14.5" - "@babel/plugin-transform-object-super" "^7.14.5" - "@babel/plugin-transform-parameters" "^7.14.5" - "@babel/plugin-transform-property-literals" "^7.14.5" - "@babel/plugin-transform-regenerator" "^7.14.5" - "@babel/plugin-transform-reserved-words" "^7.14.5" - "@babel/plugin-transform-shorthand-properties" "^7.14.5" - "@babel/plugin-transform-spread" "^7.14.6" - "@babel/plugin-transform-sticky-regex" "^7.14.5" - "@babel/plugin-transform-template-literals" "^7.14.5" - "@babel/plugin-transform-typeof-symbol" "^7.14.5" - "@babel/plugin-transform-unicode-escapes" "^7.14.5" - "@babel/plugin-transform-unicode-regex" "^7.14.5" - "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.15.0" - babel-plugin-polyfill-corejs2 "^0.2.2" - babel-plugin-polyfill-corejs3 "^0.2.2" - babel-plugin-polyfill-regenerator "^0.2.2" - core-js-compat "^3.16.0" + "@babel/plugin-transform-arrow-functions" "^7.16.7" + "@babel/plugin-transform-async-to-generator" "^7.16.8" + "@babel/plugin-transform-block-scoped-functions" "^7.16.7" + "@babel/plugin-transform-block-scoping" "^7.16.7" + "@babel/plugin-transform-classes" "^7.16.7" + "@babel/plugin-transform-computed-properties" "^7.16.7" + "@babel/plugin-transform-destructuring" "^7.16.7" + "@babel/plugin-transform-dotall-regex" "^7.16.7" + "@babel/plugin-transform-duplicate-keys" "^7.16.7" + "@babel/plugin-transform-exponentiation-operator" "^7.16.7" + "@babel/plugin-transform-for-of" "^7.16.7" + "@babel/plugin-transform-function-name" "^7.16.7" + "@babel/plugin-transform-literals" "^7.16.7" + "@babel/plugin-transform-member-expression-literals" "^7.16.7" + "@babel/plugin-transform-modules-amd" "^7.16.7" + "@babel/plugin-transform-modules-commonjs" "^7.16.8" + "@babel/plugin-transform-modules-systemjs" "^7.16.7" + "@babel/plugin-transform-modules-umd" "^7.16.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.8" + "@babel/plugin-transform-new-target" "^7.16.7" + "@babel/plugin-transform-object-super" "^7.16.7" + "@babel/plugin-transform-parameters" "^7.16.7" + "@babel/plugin-transform-property-literals" "^7.16.7" + "@babel/plugin-transform-regenerator" "^7.16.7" + "@babel/plugin-transform-reserved-words" "^7.16.7" + "@babel/plugin-transform-shorthand-properties" "^7.16.7" + "@babel/plugin-transform-spread" "^7.16.7" + "@babel/plugin-transform-sticky-regex" "^7.16.7" + "@babel/plugin-transform-template-literals" "^7.16.7" + "@babel/plugin-transform-typeof-symbol" "^7.16.7" + "@babel/plugin-transform-unicode-escapes" "^7.16.7" + "@babel/plugin-transform-unicode-regex" "^7.16.7" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.16.8" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" + core-js-compat "^3.20.2" semver "^6.3.0" -"@babel/preset-modules@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" - integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" @@ -1062,14 +1048,14 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-typescript@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz#e8fca638a1a0f64f14e1119f7fe4500277840945" - integrity sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow== +"@babel/preset-typescript@7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" + integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-transform-typescript" "^7.15.0" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-transform-typescript" "^7.16.7" "@babel/runtime@^7.8.4": version "7.14.0" @@ -1087,14 +1073,14 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/template@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" - integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== +"@babel/template@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" "@babel/traverse@^7.13.0": version "7.14.2" @@ -1110,33 +1096,51 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.5.tgz#c111b0f58afab4fea3d3385a406f692748c59870" - integrity sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" +"@babel/traverse@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.7.tgz#dac01236a72c2560073658dd1a285fe4e0865d76" + integrity sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.8.tgz#bab2f2b09a5fe8a8d9cad22cbfe3ba1d126fef9c" + integrity sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.8" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.16.8" + "@babel/types" "^7.16.8" debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.14.8", "@babel/traverse@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98" - integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.0" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.15.0" - "@babel/types" "^7.15.0" +"@babel/traverse@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" + integrity sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.0" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.0" + "@babel/types" "^7.17.0" debug "^4.1.0" globals "^11.1.0" @@ -1148,50 +1152,84 @@ "@babel/helper-validator-identifier" "^7.14.0" to-fast-properties "^2.0.0" -"@babel/types@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff" - integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg== +"@babel/types@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" + integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg== dependencies: - "@babel/helper-validator-identifier" "^7.14.5" + "@babel/helper-validator-identifier" "^7.15.7" to-fast-properties "^2.0.0" -"@babel/types@^7.14.8", "@babel/types@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" - integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ== +"@babel/types@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.7.tgz#4ed19d51f840ed4bd5645be6ce40775fecf03159" + integrity sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg== dependencies: - "@babel/helper-validator-identifier" "^7.14.9" + "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== +"@babel/types@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" + integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@babel/types@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@eslint/eslintrc@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.5.tgz#33f1b838dbf1f923bfa517e008362b78ddbbf318" + integrity sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" + debug "^4.3.2" + espree "^9.2.0" globals "^13.9.0" ignore "^4.0.6" import-fresh "^3.2.1" - js-yaml "^3.13.1" + js-yaml "^4.1.0" minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== +"@humanwhocodes/config-array@^0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914" + integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== dependencies: - "@humanwhocodes/object-schema" "^1.2.0" + "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz#b876e3feefb9c8d3aa84014da28b5e52a0640d72" + integrity sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.10" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz#baf57b4e2a690d4f38560171f91783656b7f8186" + integrity sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" "@nodelib/fs.scandir@2.1.4": version "2.1.4" @@ -1222,10 +1260,10 @@ "@babel/helper-module-imports" "^7.10.4" "@rollup/pluginutils" "^3.1.0" -"@rollup/plugin-commonjs@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-20.0.0.tgz#3246872dcbcb18a54aaa6277a8c7d7f1b155b745" - integrity sha512-5K0g5W2Ol8hAcTHqcTBHiA7M58tfmYi1o9KxeJuuRNpGaTa5iLjcyemBitCBcKXaHamOBBEH2dGom6v6Unmqjg== +"@rollup/plugin-commonjs@21.0.1": + version "21.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz#1e57c81ae1518e4df0954d681c642e7d94588fee" + integrity sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg== dependencies: "@rollup/pluginutils" "^3.1.0" commondir "^1.0.1" @@ -1235,10 +1273,10 @@ magic-string "^0.25.7" resolve "^1.17.0" -"@rollup/plugin-node-resolve@13.0.4": - version "13.0.4" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz#b10222f4145a019740acb7738402130d848660c0" - integrity sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w== +"@rollup/plugin-node-resolve@13.1.3": + version "13.1.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz#2ed277fb3ad98745424c1d2ba152484508a92d79" + integrity sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ== dependencies: "@rollup/pluginutils" "^3.1.0" "@types/resolve" "1.17.1" @@ -1247,18 +1285,18 @@ is-module "^1.0.0" resolve "^1.19.0" -"@rollup/plugin-sucrase@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-sucrase/-/plugin-sucrase-4.0.0.tgz#8b803438611dcb5f05bf148f6190b436dd9fd45a" - integrity sha512-+GQMrkkA1WaEIwpW0PWnDTC8ZoP/DUDQd6ipsAh63Dq65y2rhe1r8YQ/SIQvqd+09t35wRDkY7Xd7O2yQGEOCQ== +"@rollup/plugin-sucrase@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-sucrase/-/plugin-sucrase-4.0.2.tgz#e29226a69b3c55bdfe12d1cf12a9d9e8bba8b0cf" + integrity sha512-QQ5c1wfJQHCiVRaeSZPBVXG9tXeP5+FdHsnwbkyCTINSeHgCYXiVeMFqodgw6r/lG4v6ECGkcQ1SStvE+DHt5w== dependencies: "@rollup/pluginutils" "^4.1.1" sucrase "^3.20.0" -"@rollup/plugin-typescript@8.2.5": - version "8.2.5" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.2.5.tgz#e0319761b2b5105615e5a0c371ae05bc2984b7de" - integrity sha512-QL/LvDol/PAGB2O0S7/+q2HpSUNodpw7z6nGn9BfoVCPOZ0r4EALrojFU29Bkoi2Hr2jgTocTejJ5GGWZfOxbQ== +"@rollup/plugin-typescript@8.3.0": + version "8.3.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz#bc1077fa5897b980fc27e376c4e377882c63e68b" + integrity sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA== dependencies: "@rollup/pluginutils" "^3.1.0" resolve "^1.17.0" @@ -1290,10 +1328,10 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/json-schema@^7.0.7": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== +"@types/json-schema@^7.0.9": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== "@types/json5@^0.0.29": version "0.0.29" @@ -1317,40 +1355,30 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.1.tgz#808d206e2278e809292b5de752a91105da85860b" - integrity sha512-AHqIU+SqZZgBEiWOrtN94ldR3ZUABV5dUG94j8Nms9rQnHFc8fvDOue/58K4CFz6r8OtDDc35Pw9NQPWo0Ayrw== +"@typescript-eslint/eslint-plugin@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.11.0.tgz#3b866371d8d75c70f9b81535e7f7d3aa26527c7a" + integrity sha512-HJh33bgzXe6jGRocOj4FmefD7hRY4itgjzOrSs3JPrTNXsX7j5+nQPciAUj/1nZtwo2kAc3C75jZO+T23gzSGw== dependencies: - "@typescript-eslint/experimental-utils" "4.29.1" - "@typescript-eslint/scope-manager" "4.29.1" - debug "^4.3.1" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/type-utils" "5.11.0" + "@typescript-eslint/utils" "5.11.0" + debug "^4.3.2" functional-red-black-tree "^1.0.1" - regexpp "^3.1.0" + ignore "^5.1.8" + regexpp "^3.2.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.1.tgz#0af2b17b0296b60c6b207f11062119fa9c5a8994" - integrity sha512-kl6QG6qpzZthfd2bzPNSJB2YcZpNOrP6r9jueXupcZHnL74WiuSjaft7WSu17J9+ae9zTlk0KJMXPUj0daBxMw== +"@typescript-eslint/parser@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.11.0.tgz#b4fcaf65513f9b34bdcbffdda055724a5efb7e04" + integrity sha512-x0DCjetHZYBRovJdr3U0zG9OOdNXUaFLJ82ehr1AlkArljJuwEsgnud+Q7umlGDFLFrs8tU8ybQDFocp/eX8mQ== dependencies: - "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.29.1" - "@typescript-eslint/types" "4.29.1" - "@typescript-eslint/typescript-estree" "4.29.1" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/parser@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.1.tgz#17dfbb45c9032ffa0fe15881d20fbc2a4bdeb02d" - integrity sha512-3fL5iN20hzX3Q4OkG7QEPFjZV2qsVGiDhEwwh+EkmE/w7oteiOvUNzmpu5eSwGJX/anCryONltJ3WDmAzAoCMg== - dependencies: - "@typescript-eslint/scope-manager" "4.29.1" - "@typescript-eslint/types" "4.29.1" - "@typescript-eslint/typescript-estree" "4.29.1" - debug "^4.3.1" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/typescript-estree" "5.11.0" + debug "^4.3.2" "@typescript-eslint/parser@^4.0.0": version "4.25.0" @@ -1370,23 +1398,32 @@ "@typescript-eslint/types" "4.25.0" "@typescript-eslint/visitor-keys" "4.25.0" -"@typescript-eslint/scope-manager@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.1.tgz#f25da25bc6512812efa2ce5ebd36619d68e61358" - integrity sha512-Hzv/uZOa9zrD/W5mftZa54Jd5Fed3tL6b4HeaOpwVSabJK8CJ+2MkDasnX/XK4rqP5ZTWngK1ZDeCi6EnxPQ7A== +"@typescript-eslint/scope-manager@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.11.0.tgz#f5aef83ff253f457ecbee5f46f762298f0101e4b" + integrity sha512-z+K4LlahDFVMww20t/0zcA7gq/NgOawaLuxgqGRVKS0PiZlCTIUtX0EJbC0BK1JtR4CelmkPK67zuCgpdlF4EA== dependencies: - "@typescript-eslint/types" "4.29.1" - "@typescript-eslint/visitor-keys" "4.29.1" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/visitor-keys" "5.11.0" + +"@typescript-eslint/type-utils@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.11.0.tgz#58be0ba73d1f6ef8983d79f7f0bc2209b253fefe" + integrity sha512-wDqdsYO6ofLaD4DsGZ0jGwxp4HrzD2YKulpEZXmgN3xo4BHJwf7kq49JTRpV0Gx6bxkSUmc9s0EIK1xPbFFpIA== + dependencies: + "@typescript-eslint/utils" "5.11.0" + debug "^4.3.2" + tsutils "^3.21.0" "@typescript-eslint/types@4.25.0": version "4.25.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.25.0.tgz#0e444a5c5e3c22d7ffa5e16e0e60510b3de5af87" integrity sha512-+CNINNvl00OkW6wEsi32wU5MhHti2J25TJsJJqgQmJu3B3dYDBcmOxcE5w9cgoM13TrdE/5ND2HoEnBohasxRQ== -"@typescript-eslint/types@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.1.tgz#94cce6cf7cc83451df03339cda99d326be2feaf5" - integrity sha512-Jj2yu78IRfw4nlaLtKjVaGaxh/6FhofmQ/j8v3NXmAiKafbIqtAPnKYrf0sbGjKdj0hS316J8WhnGnErbJ4RCA== +"@typescript-eslint/types@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.11.0.tgz#ba345818a2540fdf2755c804dc2158517ab61188" + integrity sha512-cxgBFGSRCoBEhvSVLkKw39+kMzUKHlJGVwwMbPcTZX3qEhuXhrjwaZXWMxVfxDgyMm+b5Q5b29Llo2yow8Y7xQ== "@typescript-eslint/typescript-estree@4.25.0": version "4.25.0" @@ -1401,19 +1438,31 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.1.tgz#7b32a25ff8e51f2671ccc6b26cdbee3b1e6c5e7f" - integrity sha512-lIkkrR9E4lwZkzPiRDNq0xdC3f2iVCUjw/7WPJ4S2Sl6C3nRWkeE1YXCQ0+KsiaQRbpY16jNaokdWnm9aUIsfw== +"@typescript-eslint/typescript-estree@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.11.0.tgz#53f9e09b88368191e52020af77c312a4777ffa43" + integrity sha512-yVH9hKIv3ZN3lw8m/Jy5I4oXO4ZBMqijcXCdA4mY8ull6TPTAoQnKKrcZ0HDXg7Bsl0Unwwx7jcXMuNZc0m4lg== dependencies: - "@typescript-eslint/types" "4.29.1" - "@typescript-eslint/visitor-keys" "4.29.1" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/visitor-keys" "5.11.0" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" +"@typescript-eslint/utils@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.11.0.tgz#d91548ef180d74c95d417950336d9260fdbe1dc5" + integrity sha512-g2I480tFE1iYRDyMhxPAtLQ9HAn0jjBtipgTCZmd9I9s11OV8CTsG+YfFciuNDcHqm4csbAgC2aVZCHzLxMSUw== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/typescript-estree" "5.11.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + "@typescript-eslint/visitor-keys@4.25.0": version "4.25.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.25.0.tgz#863e7ed23da4287c5b469b13223255d0fde6aaa7" @@ -1422,13 +1471,13 @@ "@typescript-eslint/types" "4.25.0" eslint-visitor-keys "^2.0.0" -"@typescript-eslint/visitor-keys@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.1.tgz#0615be8b55721f5e854f3ee99f1a714f2d093e5d" - integrity sha512-zLqtjMoXvgdZY/PG6gqA73V8BjqPs4af1v2kiiETBObp+uC6gRYnJLmJHxC0QyUrrHDLJPIWNYxoBV3wbcRlag== +"@typescript-eslint/visitor-keys@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.11.0.tgz#888542381f1a2ac745b06d110c83c0b261487ebb" + integrity sha512-E8w/vJReMGuloGxJDkpPlGwhxocxOpSVgSvjiLO5IxZPmxZF30weOeJYyPSEACwM+X4NziYS9q+WkN/2DHYQwA== dependencies: - "@typescript-eslint/types" "4.29.1" - eslint-visitor-keys "^2.0.0" + "@typescript-eslint/types" "5.11.0" + eslint-visitor-keys "^3.0.0" "@yarnpkg/lockfile@^1.1.0": version "1.1.0" @@ -1440,10 +1489,15 @@ acorn-jsx@^5.3.1: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== -acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.6.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== + +acorn@^8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" @@ -1455,25 +1509,10 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" - integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.0, ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^3.2.1: version "3.2.1" @@ -1494,42 +1533,35 @@ any-promise@^1.0.0: resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -array-includes@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" - integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== +array-includes@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" + integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" + es-abstract "^1.19.1" get-intrinsic "^1.1.1" - is-string "^1.0.5" + is-string "^1.0.7" array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.flat@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" - integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== +array.prototype.flat@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" + integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + es-abstract "^1.19.0" babel-plugin-dynamic-import-node@^2.3.3: version "2.3.3" @@ -1538,29 +1570,29 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-polyfill-corejs2@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" - integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd" + integrity sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA== dependencies: "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.2.2" + "@babel/helper-define-polyfill-provider" "^0.3.0" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5" - integrity sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A== +babel-plugin-polyfill-corejs3@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.0.tgz#f81371be3fe499d39e074e272a1ef86533f3d268" + integrity sha512-Hcrgnmkf+4JTj73GbK3bBhlVPiLL47owUAnoJIf69Hakl3q+KfodbDXiZWGMM7iqCZTxCG3Z2VRfPNYES4rXqQ== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.2" - core-js-compat "^3.9.1" + "@babel/helper-define-polyfill-provider" "^0.3.0" + core-js-compat "^3.20.0" -babel-plugin-polyfill-regenerator@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" - integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== +babel-plugin-polyfill-regenerator@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz#9ebbcd7186e1a33e21c5e20cae4e7983949533be" + integrity sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.2" + "@babel/helper-define-polyfill-provider" "^0.3.0" balanced-match@^1.0.0: version "1.0.2" @@ -1593,16 +1625,27 @@ browserslist@^4.16.6: escalade "^3.1.1" node-releases "^1.1.71" -browserslist@^4.16.7: - version "4.16.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.7.tgz#108b0d1ef33c4af1b587c54f390e7041178e4335" - integrity sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA== +browserslist@^4.17.5: + version "4.18.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f" + integrity sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ== dependencies: - caniuse-lite "^1.0.30001248" - colorette "^1.2.2" - electron-to-chromium "^1.3.793" + caniuse-lite "^1.0.30001280" + electron-to-chromium "^1.3.896" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +browserslist@^4.19.1: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" escalade "^3.1.1" - node-releases "^1.1.73" + node-releases "^2.0.1" + picocolors "^1.0.0" buffer-from@^1.0.0: version "1.1.1" @@ -1632,10 +1675,15 @@ caniuse-lite@^1.0.30001219: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71" integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ== -caniuse-lite@^1.0.30001248: - version "1.0.30001249" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz#90a330057f8ff75bfe97a94d047d5e14fabb2ee8" - integrity sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw== +caniuse-lite@^1.0.30001280: + version "1.0.30001281" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001281.tgz#fe92459012197185263c1e5362e10df51ddad8c2" + integrity sha512-1ktfDV2+4LYxOGeAZygMyvhiPBJKV1gsqPmfGGwRbwYOzDWbsQHgBFo+2lpRTMO2gWjPWJrCMLWa2fnSVnxn0A== + +caniuse-lite@^1.0.30001286: + version "1.0.30001298" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001298.tgz#0e690039f62e91c3ea581673d716890512e7ec52" + integrity sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ== chalk@^2.0.0: version "2.4.2" @@ -1719,20 +1767,12 @@ convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" -core-js-compat@^3.16.0: - version "3.16.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.16.1.tgz#c44b7caa2dcb94b673a98f27eee1c8312f55bc2d" - integrity sha512-NHXQXvRbd4nxp9TEmooTJLUf94ySUG6+DSsscBpTftN1lQLQ4LjnWvc7AoIo4UjDsFF3hB8Uh5LLCRRdaiT5MQ== +core-js-compat@^3.20.0, core-js-compat@^3.20.2: + version "3.20.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.2.tgz#d1ff6936c7330959b46b2e08b122a8b14e26140b" + integrity sha512-qZEzVQ+5Qh6cROaTPFLNS4lkvQ6mBzE3R6A6EEpssj7Zr2egMHgsy4XapdifqJDGC9CBiNv7s+ejI96rLNQFdg== dependencies: - browserslist "^4.16.7" - semver "7.0.0" - -core-js-compat@^3.9.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.13.1.tgz#05444caa8f153be0c67db03cf8adb8ec0964e58e" - integrity sha512-mdrcxc0WznfRd8ZicEZh1qVeJ2mu6bwQFh8YVUK48friy/FOwFV5EJj9/dlh+nMQ74YusdVfBFDuomKgUspxWQ== - dependencies: - browserslist "^4.16.6" + browserslist "^4.19.1" semver "7.0.0" cosmiconfig@^6.0.0: @@ -1769,13 +1809,20 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: +debug@^4.1.0, debug@^4.1.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" +debug@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + deep-is@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -1819,23 +1866,21 @@ electron-to-chromium@^1.3.723: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz#7223215acbbd3a5284962ebcb6df85d88b95f200" integrity sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q== -electron-to-chromium@^1.3.793: - version "1.3.799" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.799.tgz#6e9911b25e7ecd5aa1e54dcb68f82a3e02d00f09" - integrity sha512-V2rbYWdGvSqrg+95KjkVuSi41bGfrhrOzjl1tSi2VLnm0mRe3FsSvhiqidSiSll9WiMhrQAhpDcW/wcqK3c+Yw== +electron-to-chromium@^1.3.896: + version "1.3.900" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.900.tgz#5be2c5818a2a012c511b4b43e87b6ab7a296d4f5" + integrity sha512-SuXbQD8D4EjsaBaJJxySHbC+zq8JrFfxtb4GIr4E9n1BcROyMcRrJCYQNpJ9N+Wjf5mFp7Wp0OHykd14JNEzzQ== + +electron-to-chromium@^1.4.17: + version "1.4.41" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.41.tgz#0b2e126796e7fafb9fd71e29304468b9d0af5d65" + integrity sha512-VQEXEJc+8rJIva85H8EPtB5Ux9g8TzkNGBanqphM9ZWMZ34elueKJ+5g+BPhz3Lk8gkujfQRcIZ+fpA0btUIuw== emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -1843,22 +1888,26 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: - version "1.18.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" - integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== +es-abstract@^1.19.0, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" has "^1.0.3" has-symbols "^1.0.2" - is-callable "^1.2.3" + internal-slot "^1.0.3" + is-callable "^1.2.4" is-negative-zero "^2.0.1" - is-regex "^1.1.3" - is-string "^1.0.6" - object-inspect "^1.10.3" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" object-keys "^1.1.1" object.assign "^4.1.2" string.prototype.trimend "^1.0.4" @@ -1894,10 +1943,10 @@ eslint-config-prettier@8.3.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== -eslint-config-standard-with-typescript@20.0.0: - version "20.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-20.0.0.tgz#0c550eca0a216cbf8da9013eb6e311acd3102d87" - integrity sha512-IoySf3r0a2+P3Z6GMjv8p1HuOQ6GWQbMpdt9G8uEbkGpnNWAGBXpgaiutbZHbaQAvG5pkVtYepCfHUxYbVDLCA== +eslint-config-standard-with-typescript@21.0.1: + version "21.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-21.0.1.tgz#f4c8bb883d8dfd634005239a54c3c222746e3c64" + integrity sha512-FeiMHljEJ346Y0I/HpAymNKdrgKEpHpcg/D93FvPHWfCzbT4QyUJba/0FwntZeGLXfUiWDSeKmdJD597d9wwiw== dependencies: "@typescript-eslint/parser" "^4.0.0" eslint-config-standard "^16.0.0" @@ -1907,21 +1956,21 @@ eslint-config-standard@^16.0.0: resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516" integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg== -eslint-import-resolver-node@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.5.tgz#939bbb0f74e179e757ca87f7a4a890dabed18ac4" - integrity sha512-XMoPKjSpXbkeJ7ZZ9icLnJMTY5Mc1kZbCakHquaFsXPpyWOwK0TK6CODO+0ca54UoM9LKOxyUNnoVZRl8TeaAg== +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== dependencies: debug "^3.2.7" resolve "^1.20.0" -eslint-module-utils@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" - integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== +eslint-module-utils@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz#1d0aa455dcf41052339b63cada8ab5fd57577129" + integrity sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg== dependencies: debug "^3.2.7" - pkg-dir "^2.0.0" + find-up "^2.1.0" eslint-plugin-es@^3.0.0: version "3.0.1" @@ -1931,26 +1980,24 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.0.tgz#697ffd263e24da5e84e03b282f5fb62251777177" - integrity sha512-Kc6xqT9hiYi2cgybOc0I2vC9OgAYga5o/rAFinam/yF/t5uBqxQbauNPMC6fgb640T/89P0gFoO27FOilJ/Cqg== +eslint-plugin-import@2.25.4: + version "2.25.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1" + integrity sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA== dependencies: - array-includes "^3.1.3" - array.prototype.flat "^1.2.4" + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" debug "^2.6.9" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.5" - eslint-module-utils "^2.6.2" - find-up "^2.0.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.2" has "^1.0.3" - is-core-module "^2.4.0" + is-core-module "^2.8.0" + is-glob "^4.0.3" minimatch "^3.0.4" - object.values "^1.1.3" - pkg-up "^2.0.0" - read-pkg-up "^3.0.0" + object.values "^1.1.5" resolve "^1.20.0" - tsconfig-paths "^3.9.0" + tsconfig-paths "^3.12.0" eslint-plugin-node@11.1.0: version "11.1.0" @@ -1964,10 +2011,10 @@ eslint-plugin-node@11.1.0: resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-promise@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz#fb2188fb734e4557993733b41aa1a688f46c6f24" - integrity sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng== +eslint-plugin-promise@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.0.0.tgz#017652c07c9816413a41e11c30adc42c3d55ff18" + integrity sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw== eslint-plugin-security@1.4.0: version "1.4.0" @@ -1984,7 +2031,15 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.0.0, eslint-utils@^2.1.0: +eslint-scope@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153" + integrity sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== @@ -1998,7 +2053,7 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: +eslint-visitor-keys@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== @@ -2008,65 +2063,79 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint@7.32.0: - version "7.32.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== +eslint-visitor-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186" + integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== + +eslint-visitor-keys@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz#eee4acea891814cda67a7d8812d9647dd0179af2" + integrity sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA== + +eslint-visitor-keys@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1" + integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ== + +eslint@8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.8.0.tgz#9762b49abad0cb4952539ffdb0a046392e571a2d" + integrity sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ== dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" + "@eslint/eslintrc" "^1.0.5" + "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" + eslint-scope "^7.1.0" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.2.0" + espree "^9.3.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" + glob-parent "^6.0.1" globals "^13.6.0" - ignore "^4.0.6" + ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" + regexpp "^3.2.0" + strip-ansi "^6.0.1" strip-json-comments "^3.1.0" - table "^6.0.9" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.2.0.tgz#c50814e01611c2d0f8bd4daa83c369eabba80dbc" + integrity sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg== dependencies: - acorn "^7.4.0" + acorn "^8.6.0" acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" + eslint-visitor-keys "^3.1.0" -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +espree@^9.3.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.0.tgz#c1240d79183b72aaee6ccfa5a90bc9111df085a8" + integrity sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ== + dependencies: + acorn "^8.7.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.1.0" esquery@^1.4.0: version "1.4.0" @@ -2155,7 +2224,7 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -find-up@^2.0.0, find-up@^2.1.0: +find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= @@ -2175,15 +2244,6 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== -fs-extra@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" - integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -2214,7 +2274,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== @@ -2223,13 +2283,28 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" -glob-parent@^5.1.0, glob-parent@^5.1.2: +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +glob-parent@^5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + glob@7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -2242,7 +2317,7 @@ glob@7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3, glob@^7.1.6, glob@^7.1.7: +glob@^7.1.3, glob@^7.1.6: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -2254,6 +2329,18 @@ glob@^7.1.3, glob@^7.1.6, glob@^7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -2266,7 +2353,7 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" -globby@^11.0.1, globby@^11.0.3: +globby@^11.0.1: version "11.0.3" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== @@ -2278,10 +2365,17 @@ globby@^11.0.1, globby@^11.0.3: merge2 "^1.3.0" slash "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== +globby@^11.0.4: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" handlebars@^4.7.7: version "4.7.7" @@ -2315,6 +2409,13 @@ has-symbols@^1.0.1, has-symbols@^1.0.2: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -2322,21 +2423,21 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1, ignore@^5.1.4: +ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -2363,6 +2464,15 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -2380,18 +2490,30 @@ is-boolean-object@^1.1.0: dependencies: call-bind "^1.0.2" -is-callable@^1.1.4, is-callable@^1.2.3: +is-callable@^1.1.4: version "1.2.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== -is-core-module@^2.2.0, is-core-module@^2.4.0: +is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-core-module@^2.2.0: version "2.4.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== dependencies: has "^1.0.3" +is-core-module@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== + dependencies: + has "^1.0.3" + is-date-object@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" @@ -2414,6 +2536,13 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" @@ -2441,19 +2570,31 @@ is-reference@^1.2.1: dependencies: "@types/estree" "*" -is-regex@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" - integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" - has-symbols "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== -is-string@^1.0.5, is-string@^1.0.6: +is-string@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== +is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" @@ -2461,6 +2602,13 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" +is-weakref@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" + integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== + dependencies: + call-bind "^1.0.0" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2480,13 +2628,12 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: - argparse "^1.0.7" - esprima "^4.0.0" + argparse "^2.0.1" jsesc@^2.5.1: version "2.5.2" @@ -2498,11 +2645,6 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -2513,11 +2655,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -2537,14 +2674,10 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" +jsonc-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== levn@^0.4.1: version "0.4.1" @@ -2559,16 +2692,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -2596,11 +2719,6 @@ lockfile-lint@4.6.2: lockfile-lint-api "^5.1.7" yargs "^16.0.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -2611,18 +2729,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -2642,10 +2748,10 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.4" -marked@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.2.tgz#59579e17b02443312caa1509994d5a0b18ae38e1" - integrity sha512-ueJhIvklJJw04qxQbGIAu63EXwwOCYc7yKMBjgagTM4rjC5QtWyqSNgW7jCosV1/Km/1TUfs5qEpAqcGG0Mo5g== +marked@^4.0.10: + version "4.0.12" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.12.tgz#2262a4e6fd1afd2f13557726238b69a48b982f7d" + integrity sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ== merge-stream@^2.0.0: version "2.0.0" @@ -2665,7 +2771,7 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.2.3" -minimatch@^3.0.0, minimatch@^3.0.4: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -2721,20 +2827,10 @@ node-releases@^1.1.71: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== -node-releases@^1.1.73: - version "1.1.73" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" - integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== object-assign@^4.0.1: version "4.1.1" @@ -2746,10 +2842,10 @@ object-hash@^2.0.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== -object-inspect@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" - integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -2766,14 +2862,14 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.values@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" - integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== +object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.2" + es-abstract "^1.19.1" once@^1.3.0: version "1.4.0" @@ -2782,13 +2878,6 @@ once@^1.3.0: dependencies: wrappy "1" -onigasm@^2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/onigasm/-/onigasm-2.2.5.tgz#cc4d2a79a0fa0b64caec1f4c7ea367585a676892" - integrity sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA== - dependencies: - lru-cache "^5.1.1" - optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -2827,14 +2916,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - parse-json@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -2865,28 +2946,21 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3: version "2.3.0" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -2894,34 +2968,15 @@ pirates@^4.0.1: dependencies: node-modules-regexp "^1.0.0" -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" - integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== - -progress@^2.0.0, progress@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +prettier@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== punycode@^2.1.0: version "2.1.1" @@ -2940,23 +2995,6 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -2986,11 +3024,16 @@ regenerator-transform@^0.14.2: dependencies: "@babel/runtime" "^7.8.4" -regexpp@^3.0.0, regexpp@^3.1.0: +regexpp@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + regexpu-core@^4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" @@ -3020,17 +3063,12 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0: +resolve@^1.10.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -3065,10 +3103,10 @@ rollup-plugin-terser@7.0.2: serialize-javascript "^4.0.0" terser "^5.0.0" -rollup@2.56.2: - version "2.56.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.56.2.tgz#a045ff3f6af53ee009b5f5016ca3da0329e5470f" - integrity sha512-s8H00ZsRi29M2/lGdm1u8DJpJ9ML8SUOpVVBd33XNeEeL3NVaTiUcSBHzBdF3eAyR0l7VSpsuoVUGrRHq7aPwQ== +rollup@2.67.1: + version "2.67.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.67.1.tgz#4402665706fa00f321d446ce45f880e02cf54f01" + integrity sha512-1Sbcs4OuW+aD+hhqpIRl+RqooIpF6uQcfzU/QSI7vGkwADY6cM4iLsBGRM2CGLXDTDN5y/yShohFmnKegSPWzg== optionalDependencies: fsevents "~2.3.2" @@ -3096,11 +3134,6 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"semver@2 || 3 || 4 || 5": - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" @@ -3111,7 +3144,7 @@ semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: +semver@^7.3.2, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -3137,28 +3170,29 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shiki@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.3.tgz#7bf7bcf3ed50ca525ec89cc09254abce4264d5ca" - integrity sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA== +shiki@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.0.tgz#85f21ecfa95b377ff64db6c71442c22c220e9540" + integrity sha512-iczxaIYeBFHTFrQPb9DVy2SKgYxC4Wo7Iucm7C17cCh2Ge/refnvHscUOxM85u57MfLoNOtjoEFUWt9gBexblA== dependencies: - onigasm "^2.2.5" - vscode-textmate "^5.2.0" + jsonc-parser "^3.0.0" + vscode-oniguruma "^1.6.1" + vscode-textmate "5.2.0" + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - source-map-support@~0.5.19: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" @@ -3187,37 +3221,6 @@ sourcemap-codec@^1.4.4: resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" - integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" @@ -3250,6 +3253,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -3286,18 +3296,6 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -table@^6.0.9: - version "6.7.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" - integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== - dependencies: - ajv "^8.0.1" - lodash.clonedeep "^4.5.0" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - terser@^5.0.0: version "5.7.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" @@ -3343,10 +3341,10 @@ ts-interface-checker@^0.1.9: resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== -tsconfig-paths@^3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" - integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== +tsconfig-paths@^3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b" + integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.1" @@ -3377,46 +3375,38 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-fest@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.0.0.tgz#e9daf5615e89f6d430f34117f88f4ee2cd5a2725" - integrity sha512-BoEUnckjP9oiudy3KxlGdudtBAdJQ74Wp7dYwVPkUzBn+cVHOsBXh2zD2jLyqgbuJ1KMNriczZCI7lTBA94dFg== +type-fest@2.11.2: + version "2.11.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.11.2.tgz#5534a919858bc517492cd3a53a673835a76d2e71" + integrity sha512-reW2Y2Mpn0QNA/5fvtm5doROLwDPu2zOm5RtY7xQQS05Q7xgC8MOZ3yPNaP9m/s/sNjjFQtHo7VCNqYW2iI+Ig== type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -typedoc-default-themes@^0.12.10: - version "0.12.10" - resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843" - integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA== - -typedoc-plugin-markdown@3.10.4: - version "3.10.4" - resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.10.4.tgz#4e0e9c584a1e421beafa4c3666896615f069da6b" - integrity sha512-if9w7S9fXLg73AYi/EoRSEhTOZlg3I8mIP8YEmvzSE33VrNXC9/hA0nVcLEwFVJeQY7ay6z67I6kW0KIv7LjeA== +typedoc-plugin-markdown@3.11.13: + version "3.11.13" + resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.11.13.tgz#d0c937d60bd58b117fa6600a99b9278bcc251fae" + integrity sha512-9Y7eWWmUF5i8LMfetPlOP+kTn5L3Q71fm/AUHZhxWYoAiugbybQujhjQk4h09uY2WghPP2BldOivtTxnOwj85A== dependencies: handlebars "^4.7.7" -typedoc@0.21.5: - version "0.21.5" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.5.tgz#45643618ede5c3d75e2040b964d05fcffed7ca58" - integrity sha512-uRDRmYheE5Iju9Zz0X50pTASTpBorIHFt02F5Y8Dt4eBt55h3mwk1CBSY2+EfwBxY16N4Xm7f8KXhnfFZ0AmBw== +typedoc@0.22.11: + version "0.22.11" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.11.tgz#a3d7f4577eef9fc82dd2e8f4e2915e69f884c250" + integrity sha512-pVr3hh6dkS3lPPaZz1fNpvcrqLdtEvXmXayN55czlamSgvEjh+57GUqfhAI1Xsuu/hNHUT1KNSx8LH2wBP/7SA== dependencies: - glob "^7.1.7" - handlebars "^4.7.7" + glob "^7.2.0" lunr "^2.3.9" - marked "^2.1.1" - minimatch "^3.0.0" - progress "^2.0.3" - shiki "^0.9.3" - typedoc-default-themes "^0.12.10" + marked "^4.0.10" + minimatch "^3.0.4" + shiki "^0.10.0" -typescript@4.3.5: - version "4.3.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== +typescript@4.5.5: + version "4.5.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" + integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== uglify-js@^3.1.4: version "3.13.8" @@ -3456,11 +3446,6 @@ unicode-property-aliases-ecmascript@^1.0.4: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -3473,18 +3458,15 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" +vscode-oniguruma@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.1.tgz#2bf4dfcfe3dd2e56eb549a3068c8ee39e6c30ce5" + integrity sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ== -vscode-textmate@^5.2.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.4.0.tgz#4b25ffc1f14ac3a90faf9a388c67a01d24257cd7" - integrity sha512-c0Q4zYZkcLizeYJ3hNyaVUM2AA8KDhNCA3JvXY8CeZSJuBdAy3bAvSbv46RClC4P3dSO9BdwhnKEx2zOo6vP/w== +vscode-textmate@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" + integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== which-boxed-primitive@^1.0.2: version "1.0.2" @@ -3533,11 +3515,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" diff --git a/tooling/bench/Cargo.lock b/tooling/bench/Cargo.lock index 218ab331b0ab..2da8f23c3d3b 100644 --- a/tooling/bench/Cargo.lock +++ b/tooling/bench/Cargo.lock @@ -4,21 +4,15 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.40" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cfg-if" @@ -27,129 +21,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chrono" -version = "0.4.19" +name = "fastrand" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", + "instant", ] [[package]] -name = "getrandom" -version = "0.2.3" +name = "instant" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", - "libc", - "wasi", ] [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "libc" -version = "0.2.94" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] -name = "num-integer" -version = "0.1.44" +name = "num_threads" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15" dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", + "libc", ] -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -dependencies = [ - "rand_core", -] - [[package]] name = "redox_syscall" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags", ] @@ -165,24 +97,24 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "serde" -version = "1.0.126" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -191,9 +123,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" dependencies = [ "itoa", "ryu", @@ -202,9 +134,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.72" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -216,21 +148,21 @@ name = "tauri_bench" version = "0.1.0" dependencies = [ "anyhow", - "chrono", "serde", "serde_json", "tempfile", + "time", ] [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", + "fastrand", "libc", - "rand", "redox_syscall", "remove_dir_all", "winapi", @@ -238,13 +170,13 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d" dependencies = [ + "itoa", "libc", - "wasi", - "winapi", + "num_threads", ] [[package]] @@ -253,12 +185,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "winapi" version = "0.3.9" diff --git a/tooling/bench/Cargo.toml b/tooling/bench/Cargo.toml index 3563b75b7d24..a81f8f65a755 100644 --- a/tooling/bench/Cargo.toml +++ b/tooling/bench/Cargo.toml @@ -4,14 +4,15 @@ workspace = {} name = "tauri_bench" version = "0.1.0" authors = [ "Tauri Programme within The Commons Conservancy" ] -edition = "2018" +edition = "2021" +rust-version = "1.57" license = "Apache-2.0 OR MIT" description = "Cross-platform WebView rendering library" repository = "https://github.com/tauri-apps/wry" [dependencies] anyhow = "1.0.40" -chrono = "0.4.19" +time = { version = "0.3", features = ["formatting"] } tempfile = "3.2.0" serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } diff --git a/tooling/bench/src/run_benchmark.rs b/tooling/bench/src/run_benchmark.rs index e746b507ea6a..8319e008b5e0 100644 --- a/tooling/bench/src/run_benchmark.rs +++ b/tooling/bench/src/run_benchmark.rs @@ -264,8 +264,11 @@ fn main() -> Result<()> { env::set_current_dir(&utils::bench_root_path())?; + let format = + time::format_description::parse("[year]-[month]-[day]T[hour]:[minute]:[second]Z").unwrap(); + let now = time::OffsetDateTime::now_utc(); let mut new_data = utils::BenchResult { - created_at: chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true), + created_at: format!("{}", now.format(&format).unwrap()), sha1: utils::run_collect(&["git", "rev-parse", "HEAD"]) .0 .trim() diff --git a/tooling/bench/src/utils.rs b/tooling/bench/src/utils.rs index f537e3b41443..66ee7d550c3d 100644 --- a/tooling/bench/src/utils.rs +++ b/tooling/bench/src/utils.rs @@ -41,7 +41,7 @@ pub fn get_target() -> &'static str { #[cfg(target_os = "linux")] return "x86_64-unknown-linux-gnu"; #[cfg(target_os = "windows")] - return unimplemented!(); + unimplemented!(); } pub fn target_dir() -> PathBuf { diff --git a/tooling/bench/tests/cpu_intensive/public/site.js b/tooling/bench/tests/cpu_intensive/public/site.js index c42953cd00b0..11ae51702fb9 100644 --- a/tooling/bench/tests/cpu_intensive/public/site.js +++ b/tooling/bench/tests/cpu_intensive/public/site.js @@ -17,7 +17,7 @@ const onMessage = (message) => { if (message.data.status === 'done') { // tell tauri that we are done - window.__TAURI__.invoke('app_completed_successfully'); + window.__TAURI__.invoke('app_completed_successfully') } status.innerHTML = `${prefix} Found ${message.data.count} prime numbers in ${message.data.time}ms` diff --git a/tooling/bench/tests/cpu_intensive/src-tauri/.gitignore b/tooling/bench/tests/cpu_intensive/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/tooling/bench/tests/cpu_intensive/src-tauri/.gitignore +++ b/tooling/bench/tests/cpu_intensive/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/tooling/bench/tests/cpu_intensive/src-tauri/Cargo.toml b/tooling/bench/tests/cpu_intensive/src-tauri/Cargo.toml index 6e22858ee53e..9e0e991b0441 100644 --- a/tooling/bench/tests/cpu_intensive/src-tauri/Cargo.toml +++ b/tooling/bench/tests/cpu_intensive/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "bench_cpu_intensive" version = "0.1.0" description = "A very simple Tauri Appplication" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../../../core/tauri-build", features = [ "codegen" ] } diff --git a/tooling/bench/tests/files_transfer/public/index.html b/tooling/bench/tests/files_transfer/public/index.html index d57fa334368f..a48e3fffd957 100644 --- a/tooling/bench/tests/files_transfer/public/index.html +++ b/tooling/bench/tests/files_transfer/public/index.html @@ -25,11 +25,11 @@

    Welcome to Tauri!

    }) .then((_data) => { // success - window.__TAURI__.invoke('app_should_close', {exitCode: 0}); + window.__TAURI__.invoke('app_should_close', { exitCode: 0 }) }) .catch((_error) => { // error - window.__TAURI__.invoke('app_should_close', {exitCode: 1}); + window.__TAURI__.invoke('app_should_close', { exitCode: 1 }) }) }) diff --git a/tooling/bench/tests/files_transfer/src-tauri/.gitignore b/tooling/bench/tests/files_transfer/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/tooling/bench/tests/files_transfer/src-tauri/.gitignore +++ b/tooling/bench/tests/files_transfer/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/tooling/bench/tests/files_transfer/src-tauri/Cargo.toml b/tooling/bench/tests/files_transfer/src-tauri/Cargo.toml index 036d6a13a407..d146c4228d14 100644 --- a/tooling/bench/tests/files_transfer/src-tauri/Cargo.toml +++ b/tooling/bench/tests/files_transfer/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "bench_files_transfer" version = "0.1.0" description = "A very simple Tauri Appplication" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../../../core/tauri-build", features = [ "codegen" ] } @@ -10,7 +11,7 @@ tauri-build = { path = "../../../../../core/tauri-build", features = [ "codegen" [dependencies] serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } -tauri = { path = "../../../../../core/tauri", features = ["fs-read-binary-file"] } +tauri = { path = "../../../../../core/tauri", features = ["fs-read-file"] } [features] default = [ "custom-protocol" ] diff --git a/tooling/bench/tests/files_transfer/src-tauri/tauri.conf.json b/tooling/bench/tests/files_transfer/src-tauri/tauri.conf.json index 86dc14269b76..a7cd23dc22e5 100644 --- a/tooling/bench/tests/files_transfer/src-tauri/tauri.conf.json +++ b/tooling/bench/tests/files_transfer/src-tauri/tauri.conf.json @@ -38,7 +38,7 @@ "allowlist": { "all": false, "fs": { - "readBinaryFile": true + "readFile": true } }, "windows": [ diff --git a/tooling/bench/tests/helloworld/public/index.html b/tooling/bench/tests/helloworld/public/index.html index b9f700c66dc0..fa54376c888b 100644 --- a/tooling/bench/tests/helloworld/public/index.html +++ b/tooling/bench/tests/helloworld/public/index.html @@ -10,8 +10,9 @@

    Welcome to Tauri!

    diff --git a/tooling/bench/tests/helloworld/src-tauri/.gitignore b/tooling/bench/tests/helloworld/src-tauri/.gitignore index 270a92d275ed..c1237045915f 100644 --- a/tooling/bench/tests/helloworld/src-tauri/.gitignore +++ b/tooling/bench/tests/helloworld/src-tauri/.gitignore @@ -2,9 +2,3 @@ # will have compiled files and executables /target/ WixTools - -# These are backup files generated by rustfmt -**/*.rs.bk - -config.json -bundle.json diff --git a/tooling/bench/tests/helloworld/src-tauri/Cargo.toml b/tooling/bench/tests/helloworld/src-tauri/Cargo.toml index 9f9ca36ebca1..4fcff3628b0f 100644 --- a/tooling/bench/tests/helloworld/src-tauri/Cargo.toml +++ b/tooling/bench/tests/helloworld/src-tauri/Cargo.toml @@ -2,7 +2,8 @@ name = "bench_helloworld" version = "0.1.0" description = "A very simple Tauri Appplication" -edition = "2018" +edition = "2021" +rust-version = "1.57" [build-dependencies] tauri-build = { path = "../../../../../core/tauri-build", features = [ "codegen" ] } diff --git a/tooling/bundler/Cargo.toml b/tooling/bundler/Cargo.toml index 91ec0eebc913..6ef4df3d1a91 100644 --- a/tooling/bundler/Cargo.toml +++ b/tooling/bundler/Cargo.toml @@ -12,7 +12,8 @@ license = "Apache-2.0 OR MIT" keywords = [ "bundle", "cargo", "tauri" ] repository = "https://github.com/tauri-apps/tauri" description = "Wrap rust executables in OS-specific app bundles for Tauri" -edition = "2018" +edition = "2021" +rust-version = "1.57" exclude = [ ".license_template", "CHANGELOG.md", @@ -21,10 +22,10 @@ exclude = [ ] [dependencies] -ar = "0.8.0" -glob = "0.3.0" +tauri-utils = { version = "1.0.0-beta.3", path = "../../core/tauri-utils", features = [ "resources" ] } +ar = "0.9.0" icns = "0.3" -image = "0.23.14" +image = "0.24.0" libflate = "1.1" md5 = "0.7.0" anyhow = "1.0" @@ -36,25 +37,29 @@ tar = "0.4" termcolor = "1.1.2" toml = "0.5.8" walkdir = "2" -handlebars = { version = "4.1" } +handlebars = { version = "4.2" } zip = { version = "0.5" } -tempfile = "3.2.0" -regex = "1" +tempfile = "3.3.0" +os_pipe = "1" [target."cfg(target_os = \"windows\")".dependencies] -attohttpc = "0.17" +attohttpc = "0.18" uuid = { version = "0.8", features = [ "v4", "v5" ] } bitness = "0.4" -winreg = "0.9" -sha2 = "0.9" +winreg = "0.10" +sha2 = "0.10" hex = "0.4" +glob = "0.3" [target."cfg(target_os = \"macos\")".dependencies] -chrono = "0.4" +time = { version = "0.3", features = ["formatting"] } dirs-next = "2.0" +[target."cfg(any(target_os = \"macos\", target_os = \"windows\"))".dependencies] +regex = "1" + [target."cfg(target_os = \"linux\")".dependencies] -heck = "0.3" +heck = "0.4" [lib] name = "tauri_bundler" diff --git a/tooling/bundler/README.md b/tooling/bundler/README.md index a0a9cf624877..871920659abe 100644 --- a/tooling/bundler/README.md +++ b/tooling/bundler/README.md @@ -4,7 +4,7 @@ Wrap Rust executables in OS-specific app bundles. ## About -This is a fork of the awesome [cargo-bundle](https://github.com/burtonageo/cargo-bundle), turned into a library used by the [Tauri CLI](../cli.rs). +This is a fork of the awesome [cargo-bundle](https://github.com/burtonageo/cargo-bundle), turned into a library used by the [Tauri CLI](../cli). ## Configuration @@ -76,6 +76,7 @@ These settings are used only when bundling `app` and `dmg` packages. * `license`: Path to the license file for the DMG bundle. * `exception_domain`: The exception domain to use on the macOS .app bundle. Allows communication to the outside world e.g. a web server you're shipping. * `use_bootstrapper`: Enables the bootstrapper script, which allows access to the environment variables. +* `provider_short_name`: If your Apple ID is connected to multiple teams, you have to specify the provider short name of the team you want to use to notarize your app. See [Customizing the notarization workflow](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow) and search for `--list-providers` for more information how to obtain your provider short name. ### Example `tauri.conf.json`: diff --git a/tooling/bundler/rustfmt.toml b/tooling/bundler/rustfmt.toml deleted file mode 100644 index 136f5f330967..000000000000 --- a/tooling/bundler/rustfmt.toml +++ /dev/null @@ -1,14 +0,0 @@ -max_width = 100 -hard_tabs = false -tab_spaces = 2 -newline_style = "Auto" -use_small_heuristics = "Default" -reorder_imports = true -reorder_modules = true -remove_nested_parens = true -edition = "2018" -merge_derives = true -use_try_shorthand = false -use_field_init_shorthand = false -force_explicit_abi = true -imports_granularity = "Crate" diff --git a/tooling/bundler/src/bundle.rs b/tooling/bundler/src/bundle.rs index 8edf446fe445..ee04920b7566 100644 --- a/tooling/bundler/src/bundle.rs +++ b/tooling/bundler/src/bundle.rs @@ -22,7 +22,7 @@ pub use self::{ Settings, SettingsBuilder, UpdaterSettings, }, }; -pub use settings::{WindowsSettings, WixSettings}; +pub use settings::{WindowsSettings, WixLanguage, WixLanguageConfig, WixSettings}; use common::{print_finished, print_info}; diff --git a/tooling/bundler/src/bundle/category.rs b/tooling/bundler/src/bundle/category.rs index 3b817cf5f68c..563b9cb7b10f 100644 --- a/tooling/bundler/src/bundle/category.rs +++ b/tooling/bundler/src/bundle/category.rs @@ -73,8 +73,8 @@ impl FromStr for AppCategory { .1 .to_string(); } - input = input.replace(" ", ""); - input = input.replace("-", ""); + input = input.replace(' ', ""); + input = input.replace('-', ""); // Find best match: let mut best_confidence = 0.0; diff --git a/tooling/bundler/src/bundle/common.rs b/tooling/bundler/src/bundle/common.rs index aa32663493b3..11bc5d15d60d 100644 --- a/tooling/bundler/src/bundle/common.rs +++ b/tooling/bundler/src/bundle/common.rs @@ -2,13 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::Settings; +use crate::{CommandExt, Settings}; use std::{ ffi::OsStr, fs::{self, File}, io::{self, BufWriter, Write}, - path::{Component, Path, PathBuf}, - process::{Command, Stdio}, + path::Path, + process::Command, }; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; @@ -133,23 +133,6 @@ pub fn copy_dir(from: &Path, to: &Path) -> crate::Result<()> { Ok(()) } -/// Given a path (absolute or relative) to a resource file, returns the -/// relative path from the bundle resources directory where that resource -/// should be stored. -pub fn resource_relpath(path: &Path) -> PathBuf { - let mut dest = PathBuf::new(); - for component in path.components() { - match component { - Component::Prefix(_) => {} - Component::RootDir => dest.push("_root_"), - Component::CurDir => {} - Component::ParentDir => dest.push("_up_"), - Component::Normal(string) => dest.push(string), - } - } - dest -} - /// Prints a message to stderr, in the same format that `cargo` uses, /// indicating that we are creating a bundle with the given filename. pub fn print_bundling(filename: &str) -> crate::Result<()> { @@ -213,16 +196,10 @@ pub fn print_info(message: &str) -> crate::Result<()> { } pub fn execute_with_verbosity(cmd: &mut Command, settings: &Settings) -> crate::Result<()> { - let stdio_config = if settings.is_verbose() { - Stdio::inherit - } else { - Stdio::null - }; - let status = cmd - .stdout(stdio_config()) - .stderr(stdio_config()) - .status() - .expect("failed to spawn command"); + if settings.is_verbose() { + cmd.pipe()?; + } + let status = cmd.status().expect("failed to spawn command"); if status.success() { Ok(()) @@ -233,8 +210,9 @@ pub fn execute_with_verbosity(cmd: &mut Command, settings: &Settings) -> crate:: #[cfg(test)] mod tests { - use super::{create_file, is_retina, resource_relpath}; + use super::{create_file, is_retina}; use std::{io::Write, path::PathBuf}; + use tauri_utils::resources::resource_relpath; #[test] fn create_file_with_parent_dirs() { diff --git a/tooling/bundler/src/bundle/linux/debian.rs b/tooling/bundler/src/bundle/linux/debian.rs index 520357e29fb7..07a59323afa8 100644 --- a/tooling/bundler/src/bundle/linux/debian.rs +++ b/tooling/bundler/src/bundle/linux/debian.rs @@ -26,8 +26,8 @@ use super::super::common; use crate::Settings; use anyhow::Context; -use heck::KebabCase; -use image::{self, png::PngDecoder, GenericImageView, ImageDecoder}; +use heck::ToKebabCase; +use image::{self, codecs::png::PngDecoder, GenericImageView, ImageDecoder}; use libflate::gzip; use std::process::{Command, Stdio}; use walkdir::WalkDir; @@ -250,28 +250,22 @@ fn generate_control_file( let dest_path = control_dir.join("control"); let mut file = common::create_file(&dest_path)?; writeln!( - &mut file, + file, "Package: {}", settings.product_name().to_kebab_case().to_ascii_lowercase() )?; - writeln!(&mut file, "Version: {}", settings.version_string())?; - writeln!(&mut file, "Architecture: {}", arch)?; + writeln!(file, "Version: {}", settings.version_string())?; + writeln!(file, "Architecture: {}", arch)?; // Installed-Size must be divided by 1024, see https://www.debian.org/doc/debian-policy/ch-controlfields.html#installed-size - writeln!( - &mut file, - "Installed-Size: {}", - total_dir_size(data_dir)? / 1024 - )?; - let authors = settings - .authors_comma_separated() - .unwrap_or_else(String::new); - writeln!(&mut file, "Maintainer: {}", authors)?; + writeln!(file, "Installed-Size: {}", total_dir_size(data_dir)? / 1024)?; + let authors = settings.authors_comma_separated().unwrap_or_default(); + writeln!(file, "Maintainer: {}", authors)?; if !settings.homepage_url().is_empty() { - writeln!(&mut file, "Homepage: {}", settings.homepage_url())?; + writeln!(file, "Homepage: {}", settings.homepage_url())?; } let dependencies = settings.deb().depends.as_ref().cloned().unwrap_or_default(); if !dependencies.is_empty() { - writeln!(&mut file, "Depends: {}", dependencies.join(", "))?; + writeln!(file, "Depends: {}", dependencies.join(", "))?; } let mut short_description = settings.short_description().trim(); if short_description.is_empty() { @@ -281,13 +275,13 @@ fn generate_control_file( if long_description.is_empty() { long_description = "(none)"; } - writeln!(&mut file, "Description: {}", short_description)?; + writeln!(file, "Description: {}", short_description)?; for line in long_description.lines() { let line = line.trim(); if line.is_empty() { - writeln!(&mut file, " .")?; + writeln!(file, " .")?; } else { - writeln!(&mut file, " {}", line)?; + writeln!(file, " {}", line)?; } } file.flush()?; diff --git a/tooling/bundler/src/bundle/linux/mod.rs b/tooling/bundler/src/bundle/linux/mod.rs index a0530dd3b119..bff5285a9c55 100644 --- a/tooling/bundler/src/bundle/linux/mod.rs +++ b/tooling/bundler/src/bundle/linux/mod.rs @@ -1,3 +1,7 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + pub mod appimage; pub mod debian; pub mod rpm; diff --git a/tooling/bundler/src/bundle/linux/templates/appimage b/tooling/bundler/src/bundle/linux/templates/appimage index 6c6d9c4c6170..d5cd734cad5e 100644 --- a/tooling/bundler/src/bundle/linux/templates/appimage +++ b/tooling/bundler/src/bundle/linux/templates/appimage @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright 2019-2021 Tauri Programme within The Commons Conservancy # SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: MIT @@ -12,6 +12,11 @@ cp -r ../appimage_deb/data/usr "{{app_name}}.AppDir" cd "{{app_name}}.AppDir" +# Copy WebKit files. +find /usr/lib* -name WebKitNetworkProcess -exec mkdir -p "$(dirname '{}')" \; -exec cp --parents '{}' "." \; || true +find /usr/lib* -name WebKitWebProcess -exec mkdir -p "$(dirname '{}')" \; -exec cp --parents '{}' "." \; || true +find /usr/lib* -name libwebkit2gtkinjectedbundle.so -exec mkdir -p "$(dirname '{}')" \; -exec cp --parents '{}' "." \; || true + wget -q -4 -O AppRun https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-x86_64 || wget -q -4 -O AppRun https://github.com/AppImage/AppImageKit/releases/download/12/AppRun-aarch64 chmod +x AppRun @@ -22,10 +27,10 @@ ln -s "usr/share/applications/{{app_name}}.desktop" "{{app_name}}.desktop" cd .. -wget -q -4 -O linuxdeploy-plugin-gtk.sh "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh" +wget -q -4 -O linuxdeploy-plugin-gtk.sh "https://raw.githubusercontent.com/tauri-apps/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh" wget -q -4 -O linuxdeploy-x86_64.AppImage https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage chmod +x linuxdeploy-plugin-gtk.sh chmod +x linuxdeploy-x86_64.AppImage -OUTPUT="{{appimage_filename}}" ./linuxdeploy-x86_64.AppImage --appdir "{{app_name}}.AppDir" --plugin gtk --output appimage +OUTPUT="{{appimage_filename}}" ./linuxdeploy-x86_64.AppImage --appimage-extract-and-run --appdir "{{app_name}}.AppDir" --plugin gtk --output appimage diff --git a/tooling/bundler/src/bundle/macos/app.rs b/tooling/bundler/src/bundle/macos/app.rs index 7c2394729876..d0488493630c 100644 --- a/tooling/bundler/src/bundle/macos/app.rs +++ b/tooling/bundler/src/bundle/macos/app.rs @@ -180,7 +180,11 @@ fn create_info_plist( bundle_icon_file: Option, settings: &Settings, ) -> crate::Result<()> { - let build_number = chrono::Utc::now().format("%Y%m%d.%H%M%S"); + let format = time::format_description::parse("[year][month][day].[hour][minute][second]") + .map_err(|e| time::error::Error::from(e))?; + let build_number = time::OffsetDateTime::now_utc() + .format(&format) + .map_err(|e| time::error::Error::from(e))?; let bundle_plist_path = bundle_dir.join("Info.plist"); let file = &mut common::create_file(&bundle_plist_path)?; diff --git a/tooling/bundler/src/bundle/macos/icon.rs b/tooling/bundler/src/bundle/macos/icon.rs index 1c8b9c6e0057..5814f92261f8 100644 --- a/tooling/bundler/src/bundle/macos/icon.rs +++ b/tooling/bundler/src/bundle/macos/icon.rs @@ -109,5 +109,5 @@ fn make_icns_image(img: image::DynamicImage) -> io::Result { return Err(io::Error::new(io::ErrorKind::InvalidData, msg)); } }; - icns::Image::from_data(pixel_format, img.width(), img.height(), img.to_bytes()) + icns::Image::from_data(pixel_format, img.width(), img.height(), img.into_bytes()) } diff --git a/tooling/bundler/src/bundle/macos/ios.rs b/tooling/bundler/src/bundle/macos/ios.rs index 8a0850bc2acf..348c7badaca6 100644 --- a/tooling/bundler/src/bundle/macos/ios.rs +++ b/tooling/bundler/src/bundle/macos/ios.rs @@ -15,7 +15,7 @@ use crate::{bundle::common, Settings}; use anyhow::Context; -use image::{self, png::PngDecoder, GenericImageView, ImageDecoder}; +use image::{self, codecs::png::PngDecoder, GenericImageView, ImageDecoder}; use std::{ collections::BTreeSet, @@ -45,7 +45,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { for src in settings.resource_files() { let src = src?; - let dest = bundle_dir.join(common::resource_relpath(&src)); + let dest = bundle_dir.join(tauri_utils::resources::resource_relpath(&src)); common::copy_file(&src, &dest) .with_context(|| format!("Failed to copy resource file {:?}", src))?; } diff --git a/tooling/bundler/src/bundle/macos/mod.rs b/tooling/bundler/src/bundle/macos/mod.rs index ce7d8b5c4bba..8f2c9fd7c11d 100644 --- a/tooling/bundler/src/bundle/macos/mod.rs +++ b/tooling/bundler/src/bundle/macos/mod.rs @@ -1,3 +1,7 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + pub mod app; pub mod dmg; pub mod icon; diff --git a/tooling/bundler/src/bundle/macos/sign.rs b/tooling/bundler/src/bundle/macos/sign.rs index 2fee8fb449e3..876e6ab34825 100644 --- a/tooling/bundler/src/bundle/macos/sign.rs +++ b/tooling/bundler/src/bundle/macos/sign.rs @@ -1,3 +1,7 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + use std::{ fs::File, io::prelude::*, @@ -254,7 +258,7 @@ pub fn notarize( sign(zip_path.clone(), identity, &settings, false)?; }; - let notarize_args = vec![ + let mut notarize_args = vec![ "altool", "--notarize-app", "-f", @@ -264,6 +268,12 @@ pub fn notarize( "--primary-bundle-id", identifier, ]; + + if let Some(provider_short_name) = &settings.macos().provider_short_name { + notarize_args.push("--asc-provider"); + notarize_args.push(provider_short_name); + } + common::print_info("notarizing app")?; let output = Command::new("xcrun") .args(notarize_args) diff --git a/tooling/bundler/src/bundle/path_utils.rs b/tooling/bundler/src/bundle/path_utils.rs index f945c2a2043a..f8e0414ec33b 100644 --- a/tooling/bundler/src/bundle/path_utils.rs +++ b/tooling/bundler/src/bundle/path_utils.rs @@ -8,7 +8,7 @@ use std::{ }; /// Directory options. -#[derive(Clone)] +#[derive(Default, Clone)] pub struct DirOpts { pub depth: u64, } @@ -51,12 +51,6 @@ impl Default for Options { } } -impl Default for DirOpts { - fn default() -> DirOpts { - DirOpts { depth: 0 } - } -} - impl Default for FileOpts { fn default() -> FileOpts { FileOpts { @@ -166,14 +160,14 @@ where "Path is not a directory".to_owned(), )); } - let dir_name; - if let Some(val) = from.components().last() { - dir_name = val.as_os_str(); + + let dir_name = if let Some(val) = from.components().last() { + val.as_os_str() } else { return Err(crate::Error::PathUtilError( "Invalid Folder form".to_owned(), )); - } + }; let mut to: PathBuf = to.as_ref().to_path_buf(); if !options.content_only && (!options.copy_files || to.exists()) { to.push(dir_name); diff --git a/tooling/bundler/src/bundle/platform.rs b/tooling/bundler/src/bundle/platform.rs index 2127de3c9dad..b15610d5e8aa 100644 --- a/tooling/bundler/src/bundle/platform.rs +++ b/tooling/bundler/src/bundle/platform.rs @@ -1,15 +1,31 @@ -use std::{io::Cursor, process::Command}; +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT -#[derive(Debug, serde::Deserialize)] -struct TargetSpec { - #[serde(rename = "llvm-target")] - llvm_target: String, -} +use std::process::Command; // Copyright 2019-2021 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT +#[derive(Debug, PartialEq, Eq)] +struct RustCfg { + target_arch: Option, +} + +fn parse_rust_cfg(cfg: String) -> RustCfg { + let target_line = "target_arch=\""; + let mut target_arch = None; + for line in cfg.split('\n') { + if line.starts_with(target_line) { + let len = target_line.len(); + let arch = line.chars().skip(len).take(line.len() - len - 1).collect(); + target_arch.replace(arch); + } + } + RustCfg { target_arch } +} + /// Try to determine the current target triple. /// /// Returns a target triple (e.g. `x86_64-unknown-linux-gnu` or `i686-pc-windows-msvc`) or an @@ -20,18 +36,12 @@ struct TargetSpec { /// * Errors: /// * Unexpected system config pub fn target_triple() -> Result { - let output = Command::new("rustc") - .args(&["-Z", "unstable-options", "--print", "target-spec-json"]) - .env("RUSTC_BOOTSTRAP", "1") - .output()?; + let output = Command::new("rustc").args(&["--print", "cfg"]).output()?; + let arch = if output.status.success() { - let target_spec: TargetSpec = serde_json::from_reader(Cursor::new(output.stdout))?; - target_spec - .llvm_target - .split('-') - .next() - .unwrap() - .to_string() + parse_rust_cfg(String::from_utf8_lossy(&output.stdout).into_owned()) + .target_arch + .expect("could not find `target_arch` when running `rustc --print cfg`.") } else { super::common::print_info(&format!( "failed to determine target arch using rustc, error: `{}`. The fallback is the architecture of the machine that compiled this crate.", @@ -86,3 +96,34 @@ pub fn target_triple() -> Result { Ok(format!("{}-{}", arch, os)) } + +#[cfg(test)] +mod tests { + use super::RustCfg; + + #[test] + fn parse_rust_cfg() { + assert_eq!( + super::parse_rust_cfg("target_arch".into()), + RustCfg { target_arch: None } + ); + + assert_eq!( + super::parse_rust_cfg( + r#"debug_assertions +target_arch="aarch64" +target_endian="little" +target_env="" +target_family="unix" +target_os="macos" +target_pointer_width="64" +target_vendor="apple" +unix"# + .into() + ), + RustCfg { + target_arch: Some("aarch64".into()) + } + ); + } +} diff --git a/tooling/bundler/src/bundle/settings.rs b/tooling/bundler/src/bundle/settings.rs index c28e530d487f..62306472e3bf 100644 --- a/tooling/bundler/src/bundle/settings.rs +++ b/tooling/bundler/src/bundle/settings.rs @@ -4,6 +4,7 @@ use super::category::AppCategory; use crate::bundle::{common, platform::target_triple}; +use tauri_utils::resources::{external_binaries, ResourcePaths}; use std::{ collections::HashMap, @@ -113,8 +114,8 @@ pub struct UpdaterSettings { pub active: bool, /// The updater endpoints. pub endpoints: Option>, - /// Optional pubkey. - pub pubkey: Option, + /// Signature public key. + pub pubkey: String, /// Display built-in dialog or use event system if disabled. pub dialog: bool, } @@ -168,17 +169,36 @@ pub struct MacOsSettings { pub exception_domain: Option, /// Code signing identity. pub signing_identity: Option, + /// Provider short name for notarization. + pub provider_short_name: Option, /// Path to the entitlements.plist file. pub entitlements: Option, /// Path to the Info.plist file for the bundle. pub info_plist_path: Option, } +/// Configuration for a target language for the WiX build. +#[derive(Debug, Clone, Default)] +pub struct WixLanguageConfig { + /// The path to a locale (`.wxl`) file. See https://wixtoolset.org/documentation/manual/v3/howtos/ui_and_localization/build_a_localized_version.html. + pub locale_path: Option, +} + +/// The languages to build using WiX. +#[derive(Debug, Clone)] +pub struct WixLanguage(pub Vec<(String, WixLanguageConfig)>); + +impl Default for WixLanguage { + fn default() -> Self { + Self(vec![("en-US".into(), Default::default())]) + } +} + /// Settings specific to the WiX implementation. #[derive(Clone, Debug, Default)] pub struct WixSettings { - /// The app language. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables. - pub language: String, + /// The app languages to build. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables. + pub language: WixLanguage, /// By default, the bundler uses an internal template. /// This option allows you to define your own wix file. pub template: Option, @@ -225,6 +245,8 @@ pub struct WindowsSettings { pub wix: Option, /// The path to the application icon. Defaults to `./icons/icon.ico`. pub icon_path: PathBuf, + /// Path to the webview fixed runtime to use. + pub webview_fixed_runtime_path: Option, } impl Default for WindowsSettings { @@ -235,6 +257,7 @@ impl Default for WindowsSettings { timestamp_url: None, wix: None, icon_path: PathBuf::from("icons/icon.ico"), + webview_fixed_runtime_path: None, } } } @@ -265,12 +288,18 @@ pub struct BundleSettings { pub bin: Option>, /// External binaries to add to the bundle. /// - /// Note that each binary name will have the target platform's target triple appended, - /// so if you're bundling the `sqlite3` app, the bundler will look for e.g. - /// `sqlite3-x86_64-unknown-linux-gnu` on linux, + /// Note that each binary name should have the target platform's target triple appended, + /// as well as `.exe` for Windows. + /// For example, if you're bundling a sidecar called `sqlite3`, the bundler expects + /// a binary named `sqlite3-x86_64-unknown-linux-gnu` on linux, /// and `sqlite3-x86_64-pc-windows-gnu.exe` on windows. /// - /// The possible target triples can be seen by running `$ rustup target list`. + /// Run `tauri build --help` for more info on targets. + /// + /// If you are building a universal binary for MacOS, the bundler expects + /// your external binary to also be universal, and named after the target triple, + /// e.g. `sqlite3-universal-apple-darwin`. See + /// https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary pub external_bin: Option>, /// Debian-specific settings. pub deb: DebianSettings, @@ -305,6 +334,7 @@ impl BundleBinary { } /// Sets the src path of the binary. + #[must_use] pub fn set_src_path(mut self, src_path: Option) -> Self { self.src_path = src_path; self @@ -376,6 +406,7 @@ impl SettingsBuilder { } /// Sets the project output directory. It's used as current working directory. + #[must_use] pub fn project_out_directory>(mut self, path: P) -> Self { self .project_out_directory @@ -384,36 +415,42 @@ impl SettingsBuilder { } /// Enables verbose output. + #[must_use] pub fn verbose(mut self) -> Self { self.verbose = true; self } /// Sets the package types to create. + #[must_use] pub fn package_types(mut self, package_types: Vec) -> Self { self.package_types = Some(package_types); self } /// Sets the package settings. + #[must_use] pub fn package_settings(mut self, settings: PackageSettings) -> Self { self.package_settings.replace(settings); self } /// Sets the bundle settings. + #[must_use] pub fn bundle_settings(mut self, settings: BundleSettings) -> Self { self.bundle_settings = settings; self } /// Sets the binaries to bundle. + #[must_use] pub fn binaries(mut self, binaries: Vec) -> Self { self.binaries = binaries; self } /// Sets the target triple. + #[must_use] pub fn target(mut self, target: String) -> Self { self.target.replace(target); self @@ -430,7 +467,6 @@ impl SettingsBuilder { } else { target_triple()? }; - let bundle_settings = parse_external_bin(&target, self.bundle_settings)?; Ok(Settings { package: self.package_settings.expect("package settings is required"), @@ -440,7 +476,14 @@ impl SettingsBuilder { .project_out_directory .expect("out directory is required"), binaries: self.binaries, - bundle_settings, + bundle_settings: BundleSettings { + external_bin: self + .bundle_settings + .external_bin + .as_ref() + .map(|bins| external_binaries(bins, &target)), + ..self.bundle_settings + }, target, }) } @@ -462,6 +505,8 @@ impl Settings { "arm" } else if self.target.starts_with("aarch64") { "aarch64" + } else if self.target.starts_with("universal") { + "universal" } else { panic!("Unexpected target triple {}", self.target) } @@ -585,7 +630,9 @@ impl Settings { let dest = path.join( src .file_name() - .expect("failed to extract external binary filename"), + .expect("failed to extract external binary filename") + .to_string_lossy() + .replace(&format!("-{}", self.target), ""), ); common::copy_file(&src, &dest)?; } @@ -596,7 +643,7 @@ impl Settings { pub fn copy_resources(&self, path: &Path) -> crate::Result<()> { for src in self.resource_files() { let src = src?; - let dest = path.join(common::resource_relpath(&src)); + let dest = path.join(tauri_utils::resources::resource_relpath(&src)); common::copy_file(&src, &dest)?; } Ok(()) @@ -676,144 +723,4 @@ impl Settings { None => false, } } - - /// Is pubkey provided? - pub fn is_updater_pubkey(&self) -> bool { - match &self.bundle_settings.updater { - Some(val) => val.pubkey.is_some(), - None => false, - } - } - - /// Get pubkey (mainly for testing) - #[cfg(test)] - pub fn updater_pubkey(&self) -> Option<&str> { - self - .bundle_settings - .updater - .as_ref() - .expect("Updater is not defined") - .pubkey - .as_deref() - } -} - -/// Parses the external binaries to bundle, adding the target triple suffix to each of them. -fn parse_external_bin( - target_triple: &str, - bundle_settings: BundleSettings, -) -> crate::Result { - let mut win_paths = Vec::new(); - let external_bin = match bundle_settings.external_bin { - Some(paths) => { - for curr_path in paths.iter() { - win_paths.push(format!( - "{}-{}{}", - curr_path, - target_triple, - if cfg!(windows) { ".exe" } else { "" } - )); - } - Some(win_paths) - } - None => Some(vec![]), - }; - - Ok(BundleSettings { - external_bin, - ..bundle_settings - }) -} - -/// A helper to iterate through resources. -pub struct ResourcePaths<'a> { - /// the patterns to iterate. - pattern_iter: std::slice::Iter<'a, String>, - /// the glob iterator if the path from the current iteration is a glob pattern. - glob_iter: Option, - /// the walkdir iterator if the path from the current iteration is a directory. - walk_iter: Option, - /// whether the resource paths allows directories or not. - allow_walk: bool, - /// the pattern of the current iteration. - current_pattern: Option, - /// whether the current pattern is valid or not. - current_pattern_is_valid: bool, -} - -impl<'a> ResourcePaths<'a> { - /// Creates a new ResourcePaths from a slice of patterns to iterate - fn new(patterns: &'a [String], allow_walk: bool) -> ResourcePaths<'a> { - ResourcePaths { - pattern_iter: patterns.iter(), - glob_iter: None, - walk_iter: None, - allow_walk, - current_pattern: None, - current_pattern_is_valid: false, - } - } -} - -impl<'a> Iterator for ResourcePaths<'a> { - type Item = crate::Result; - - fn next(&mut self) -> Option> { - loop { - if let Some(ref mut walk_entries) = self.walk_iter { - if let Some(entry) = walk_entries.next() { - let entry = match entry { - Ok(entry) => entry, - Err(error) => return Some(Err(crate::Error::from(error))), - }; - let path = entry.path(); - if path.is_dir() { - continue; - } - self.current_pattern_is_valid = true; - return Some(Ok(path.to_path_buf())); - } - } - self.walk_iter = None; - if let Some(ref mut glob_paths) = self.glob_iter { - if let Some(glob_result) = glob_paths.next() { - let path = match glob_result { - Ok(path) => path, - Err(error) => return Some(Err(crate::Error::from(error))), - }; - if path.is_dir() { - if self.allow_walk { - let walk = walkdir::WalkDir::new(path); - self.walk_iter = Some(walk.into_iter()); - continue; - } else { - let msg = format!("{:?} is a directory", path); - return Some(Err(crate::Error::GenericError(msg))); - } - } - self.current_pattern_is_valid = true; - return Some(Ok(path)); - } else if let Some(current_path) = &self.current_pattern { - if !self.current_pattern_is_valid { - return Some(Err(crate::Error::GenericError(format!( - "Path matching '{}' not found", - current_path - )))); - } - } - } - self.glob_iter = None; - if let Some(pattern) = self.pattern_iter.next() { - self.current_pattern = Some(pattern.to_string()); - self.current_pattern_is_valid = false; - let glob = match glob::glob(pattern) { - Ok(glob) => glob, - Err(error) => return Some(Err(crate::Error::from(error))), - }; - self.glob_iter = Some(glob); - continue; - } - return None; - } - } } diff --git a/tooling/bundler/src/bundle/windows/mod.rs b/tooling/bundler/src/bundle/windows/mod.rs index e05336d0a2a8..b9cf2ab9936d 100644 --- a/tooling/bundler/src/bundle/windows/mod.rs +++ b/tooling/bundler/src/bundle/windows/mod.rs @@ -1,2 +1,6 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + pub mod msi; pub mod sign; diff --git a/tooling/bundler/src/bundle/windows/msi.rs b/tooling/bundler/src/bundle/windows/msi.rs index c0a7c2641f77..96a302b0c43c 100644 --- a/tooling/bundler/src/bundle/windows/msi.rs +++ b/tooling/bundler/src/bundle/windows/msi.rs @@ -17,7 +17,5 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { wix::get_and_extract_wix(&wix_path)?; } - let msi_path = wix::build_wix_app_installer(settings, &wix_path)?; - - Ok(vec![msi_path]) + wix::build_wix_app_installer(settings, &wix_path) } diff --git a/tooling/bundler/src/bundle/windows/msi/default-locale-strings.xml b/tooling/bundler/src/bundle/windows/msi/default-locale-strings.xml new file mode 100644 index 000000000000..e994c6bfa336 --- /dev/null +++ b/tooling/bundler/src/bundle/windows/msi/default-locale-strings.xml @@ -0,0 +1,6 @@ +__language__ +__codepage__ +Launch __productName__ +A newer version of __productName__ is already installed. +Add the install location of the __productName__ executable to the PATH system environment variable. This allows the __productName__ executable to be called from any location. +Installs __productName__. \ No newline at end of file diff --git a/tooling/bundler/src/bundle/windows/msi/wix.rs b/tooling/bundler/src/bundle/windows/msi/wix.rs index 68edf8a4fc2d..5aa094e0bec9 100644 --- a/tooling/bundler/src/bundle/windows/msi/wix.rs +++ b/tooling/bundler/src/bundle/windows/msi/wix.rs @@ -18,7 +18,7 @@ use zip::ZipArchive; use std::{ collections::{BTreeMap, HashMap}, - fs::{create_dir_all, remove_dir_all, rename, write, File}, + fs::{create_dir_all, read_to_string, remove_dir_all, rename, write, File}, io::{Cursor, Read, Write}, path::{Path, PathBuf}, process::{Command, Stdio}, @@ -132,10 +132,11 @@ impl ResourceDirectory { format!("{}{}", files, directories) } else { format!( - r#"{contents}"#, - id = format!("I{}", Uuid::new_v4().to_simple()), + r#"{files}{directories}"#, + id = Uuid::new_v4().to_simple(), name = self.name, - contents = format!("{}{}", files, directories) + files = files, + directories = directories, ) }; @@ -189,8 +190,8 @@ fn download_and_verify(url: &str, hash: &str) -> crate::Result> { } } -/// The installer directory of the app. -fn app_installer_dir(settings: &Settings) -> crate::Result { +/// The app installer output path. +fn app_installer_output_path(settings: &Settings, language: &str) -> crate::Result { let arch = match settings.binary_arch() { "x86" => "x86", "x86_64" => "x64", @@ -203,10 +204,11 @@ fn app_installer_dir(settings: &Settings) -> crate::Result { }; let package_base_name = format!( - "{}_{}_{}", + "{}_{}_{}_{}", settings.main_binary_name().replace(".exe", ""), settings.version_string(), - arch + arch, + language, ); Ok( @@ -330,6 +332,8 @@ fn run_light( let mut args: Vec = vec![ "-ext".to_string(), "WixUIExtension".to_string(), + "-ext".to_string(), + "WixUtilExtension".to_string(), "-o".to_string(), output_path.display().to_string(), ]; @@ -364,7 +368,7 @@ fn run_light( pub fn build_wix_app_installer( settings: &Settings, wix_toolset_path: &Path, -) -> crate::Result { +) -> crate::Result> { let arch = match settings.binary_arch() { "x86_64" => "x64", "x86" => "x86", @@ -385,27 +389,35 @@ pub fn build_wix_app_installer( .find(|bin| bin.main()) .ok_or_else(|| anyhow::anyhow!("Failed to get main binary"))?; let app_exe_source = settings.binary_path(main_binary); + let try_sign = |file_path: &PathBuf| -> crate::Result<()> { + if let Some(certificate_thumbprint) = &settings.windows().certificate_thumbprint { + common::print_info(&format!("signing {}", file_path.display()))?; + sign( + &file_path, + &SignParams { + digest_algorithm: settings + .windows() + .digest_algorithm + .as_ref() + .map(|algorithm| algorithm.to_string()) + .unwrap_or_else(|| "sha256".to_string()), + certificate_thumbprint: certificate_thumbprint.to_string(), + timestamp_url: settings + .windows() + .timestamp_url + .as_ref() + .map(|url| url.to_string()), + }, + )?; + } + Ok(()) + }; - if let Some(certificate_thumbprint) = &settings.windows().certificate_thumbprint { - common::print_info("signing app")?; - sign( - &app_exe_source, - &SignParams { - digest_algorithm: settings - .windows() - .digest_algorithm - .as_ref() - .map(|algorithm| algorithm.to_string()) - .unwrap_or_else(|| "sha256".to_string()), - certificate_thumbprint: certificate_thumbprint.to_string(), - timestamp_url: settings - .windows() - .timestamp_url - .as_ref() - .map(|url| url.to_string()), - }, - )?; - } + common::print_info("trying to sign app")?; + try_sign(&app_exe_source)?; + + // ensure that `target/{release, debug}/wix` folder exists + std::fs::create_dir_all(settings.project_out_directory().join("wix"))?; let output_path = settings.project_out_directory().join("wix").join(arch); @@ -419,14 +431,14 @@ pub fn build_wix_app_installer( if license.ends_with(".rtf") { data.insert("license", to_json(license)); } else { - let license_contents = std::fs::read_to_string(&license)?; + let license_contents = read_to_string(&license)?; let license_rtf = format!( r#"{{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{{\fonttbl{{\f0\fnil\fcharset0 Calibri;}}}} {{\*\generator Riched20 10.0.18362}}\viewkind4\uc1 \pard\sa200\sl276\slmult1\f0\fs22\lang9 {}\par }} "#, - license_contents.replace("\n", "\\par ") + license_contents.replace('\n', "\\par ") ); let rtf_output_path = settings .project_out_directory() @@ -438,30 +450,19 @@ pub fn build_wix_app_installer( } } - let (language, language_metadata) = if let Some(wix) = &settings.windows().wix { - let metadata = language_map.get(&wix.language).unwrap_or_else(|| { - panic!( - "Language {} not found. It must be one of {}", - wix.language, - language_map - .keys() - .cloned() - .collect::>() - .join(", ") - ) - }); - (wix.language.clone(), metadata) - } else { - common::print_info("Wix settings not found. Using `en-US` as language.")?; - ("en-US".into(), language_map.get("en-US").unwrap()) - }; - data.insert("language_id", to_json(language_metadata.lang_id)); - data.insert("ascii_codepage", to_json(language_metadata.ascii_code)); + let configured_languages = settings + .windows() + .wix + .as_ref() + .map(|w| w.language.clone()) + .unwrap_or_default(); data.insert("product_name", to_json(settings.product_name())); data.insert("version", to_json(settings.version_string())); - let manufacturer = settings.bundle_identifier().to_string(); - data.insert("manufacturer", to_json(manufacturer.as_str())); + let bundle_id = settings.bundle_identifier(); + let manufacturer = bundle_id.split('.').nth(1).unwrap_or(bundle_id); + data.insert("bundle_id", to_json(bundle_id)); + data.insert("manufacturer", to_json(manufacturer)); let upgrade_code = Uuid::new_v5( &Uuid::NAMESPACE_DNS, format!("{}.app.x64", &settings.main_binary_name()).as_bytes(), @@ -511,7 +512,7 @@ pub fn build_wix_app_installer( let mut fragment_paths = Vec::new(); let mut handlebars = Handlebars::new(); let mut has_custom_template = false; - let mut install_webview = true; + let mut install_webview = settings.windows().webview_fixed_runtime_path.is_none(); let mut enable_elevated_update_task = false; if let Some(wix) = &settings.windows().wix { @@ -521,11 +522,13 @@ pub fn build_wix_app_installer( data.insert("feature_refs", to_json(&wix.feature_refs)); data.insert("merge_refs", to_json(&wix.merge_refs)); fragment_paths = wix.fragment_paths.clone(); - install_webview = !wix.skip_webview_install; + if wix.skip_webview_install { + install_webview = false; + } enable_elevated_update_task = wix.enable_elevated_update_task; if let Some(temp_path) = &wix.template { - let template = std::fs::read_to_string(temp_path)?; + let template = read_to_string(temp_path)?; handlebars .register_template_string("main.wxs", &template) .map_err(|e| e.to_string()) @@ -538,8 +541,7 @@ pub fn build_wix_app_installer( .file_name() .unwrap() .to_string_lossy() - .into_owned() - .to_string(); + .into_owned(); data.insert( "banner_path", to_json(copy_icon(settings, &filename, banner_path)?), @@ -551,8 +553,7 @@ pub fn build_wix_app_installer( .file_name() .unwrap() .to_string_lossy() - .into_owned() - .to_string(); + .into_owned(); data.insert( "dialog_image_path", to_json(copy_icon(settings, &filename, dialog_image_path)?), @@ -598,7 +599,7 @@ pub fn build_wix_app_installer( .expect("Failed to setup Update Task Installer handlebars"); let temp_ps1_path = output_path.join("install-task.ps1"); let install_script_content = skip_uac_task_installer.render("install-task.ps1", &data)?; - write(&temp_ps1_path, install_script_content.clone())?; + write(&temp_ps1_path, install_script_content)?; // Create the Powershell script to uninstall the task let mut skip_uac_task_uninstaller = Handlebars::new(); @@ -609,7 +610,7 @@ pub fn build_wix_app_installer( .expect("Failed to setup Update Task Uninstaller handlebars"); let temp_ps1_path = output_path.join("uninstall-task.ps1"); let install_script_content = skip_uac_task_uninstaller.render("uninstall-task.ps1", &data)?; - write(&temp_ps1_path, install_script_content.clone())?; + write(&temp_ps1_path, install_script_content)?; data.insert("enable_elevated_update_task", to_json(true)); } @@ -628,26 +629,90 @@ pub fn build_wix_app_installer( run_candle(settings, wix_toolset_path, &output_path, wxs)?; } - let arguments = vec![ - format!("-cultures:{}", language.to_lowercase()), - "*.wixobj".into(), - ]; - let msi_output_path = output_path.join("output.msi"); - let msi_path = app_installer_dir(settings)?; - create_dir_all(msi_path.parent().unwrap())?; - - common::print_info(format!("running light to produce {}", msi_path.display()).as_str())?; - - run_light( - wix_toolset_path, - &output_path, - arguments, - &msi_output_path, - settings, - )?; - rename(&msi_output_path, &msi_path)?; + let mut output_paths = Vec::new(); + + for (language, language_config) in configured_languages.0 { + let language_metadata = language_map.get(&language).unwrap_or_else(|| { + panic!( + "Language {} not found. It must be one of {}", + language, + language_map + .keys() + .cloned() + .collect::>() + .join(", ") + ) + }); + + let locale_contents = match language_config.locale_path { + Some(p) => read_to_string(p)?, + None => format!( + r#""#, + language.to_lowercase(), + ), + }; + + let locale_strings = include_str!("./default-locale-strings.xml") + .replace("__language__", &language_metadata.lang_id.to_string()) + .replace("__codepage__", &language_metadata.ascii_code.to_string()) + .replace("__productName__", settings.product_name()); + + let mut unset_locale_strings = String::new(); + let prefix_len = "{value}').unwrap() - prefix_len) + .collect::(); + if !locale_contents.contains(&id) { + unset_locale_strings.push_str(locale_string); + } + } + + let locale_contents = locale_contents.replace( + "", + &format!("{}", unset_locale_strings), + ); + let locale_path = output_path.join("locale.wxl"); + { + let mut fileout = File::create(&locale_path).expect("Failed to create locale file"); + fileout.write_all(locale_contents.as_bytes())?; + } + + let arguments = vec![ + format!( + "-cultures:{}", + if language == "en-US" { + language.to_lowercase() + } else { + format!("{};en-US", language.to_lowercase()) + } + ), + "-loc".into(), + locale_path.display().to_string(), + "*.wixobj".into(), + ]; + let msi_output_path = output_path.join("output.msi"); + let msi_path = app_installer_output_path(settings, &language)?; + create_dir_all(msi_path.parent().unwrap())?; + + common::print_info(format!("running light to produce {}", msi_path.display()).as_str())?; + + run_light( + wix_toolset_path, + &output_path, + arguments, + &msi_output_path, + settings, + )?; + rename(&msi_output_path, &msi_path)?; + try_sign(&msi_path)?; + output_paths.push(msi_path); + } - Ok(msi_path) + Ok(output_paths) } /// Generates the data required for the external binaries and extra binaries bundling. diff --git a/tooling/bundler/src/bundle/windows/sign.rs b/tooling/bundler/src/bundle/windows/sign.rs index 5b7071635de7..e8567d491fe8 100644 --- a/tooling/bundler/src/bundle/windows/sign.rs +++ b/tooling/bundler/src/bundle/windows/sign.rs @@ -1,3 +1,7 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + use std::{ path::{Path, PathBuf}, process::Command, diff --git a/tooling/bundler/src/bundle/windows/templates/main.wxs b/tooling/bundler/src/bundle/windows/templates/main.wxs index bc4fd24cbece..c9b5c7357d34 100644 --- a/tooling/bundler/src/bundle/windows/templates/main.wxs +++ b/tooling/bundler/src/bundle/windows/templates/main.wxs @@ -13,20 +13,19 @@ Id="*" Name="{{{product_name}}}" UpgradeCode="{{{upgrade_code}}}" - Language="{{language_id}}" - Codepage="{{ascii_codepage}}" + Language="!(loc.TauriLanguage)" Manufacturer="{{{manufacturer}}}" Version="{{{version}}}"> + SummaryCodepage="!(loc.TauriCodepage)"/> - @@ -46,7 +45,20 @@ + + + + + + + + + + + + WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed + {{#unless license}} @@ -71,7 +83,7 @@ - + @@ -83,6 +95,11 @@ + + + + + @@ -114,9 +131,9 @@ - @@ -131,16 +148,16 @@ Target="[!Path]" Icon="ProductIcon" WorkingDirectory="INSTALLDIR"> - + - + {{#each merge_modules as |msm| ~}} - + @@ -151,13 +168,15 @@ + + {{#each resource_file_ids as |resource_file_id| ~}} {{/each~}} @@ -180,7 +199,7 @@ @@ -211,7 +230,8 @@ {{#if install_webview}} - + + diff --git a/tooling/bundler/src/error.rs b/tooling/bundler/src/error.rs index f751179a0b74..7fed9989c457 100644 --- a/tooling/bundler/src/error.rs +++ b/tooling/bundler/src/error.rs @@ -9,15 +9,12 @@ use thiserror::Error as DeriveError; #[derive(Debug, DeriveError)] #[non_exhaustive] pub enum Error { + /// Error running tauri_utils API. + #[error("{0}")] + Resource(#[from] tauri_utils::Error), /// Bundler error. #[error("{0}")] BundlerError(#[from] anyhow::Error), - /// Failed to use glob pattern. - #[error("`{0}`")] - GlobError(#[from] glob::GlobError), - /// Invalid glob pattern. - #[error("`{0}`")] - GlobPatternError(#[from] glob::PatternError), /// I/O error. #[error("`{0}`")] IoError(#[from] io::Error), @@ -50,12 +47,21 @@ pub enum Error { #[error("`{0}`")] JsonError(#[from] serde_json::error::Error), /// Regex error. + #[cfg(any(target_os = "macos", windows))] #[error("`{0}`")] RegexError(#[from] regex::Error), /// Failed to perform HTTP request. #[cfg(windows)] #[error("`{0}`")] HttpError(#[from] attohttpc::Error), + /// Invalid glob pattern. + #[cfg(windows)] + #[error("{0}")] + GlobPattern(#[from] glob::PatternError), + /// Failed to use glob pattern. + #[cfg(windows)] + #[error("`{0}`")] + Glob(#[from] glob::GlobError), /// Failed to validate downloaded file hash. #[error("hash mismatch of downloaded file")] HashError, @@ -95,6 +101,10 @@ pub enum Error { /// Failed to sign application. #[error("failed to sign app: {0}")] Sign(String), + /// time error. + #[cfg(target_os = "macos")] + #[error("`{0}`")] + TimeError(#[from] time::error::Error), } /// Convenient type alias of Result type. diff --git a/tooling/bundler/src/lib.rs b/tooling/bundler/src/lib.rs index 238db717feba..424b1ba63075 100644 --- a/tooling/bundler/src/lib.rs +++ b/tooling/bundler/src/lib.rs @@ -15,6 +15,18 @@ //! - Windows //! - MSI using WiX +pub(crate) trait CommandExt { + fn pipe(&mut self) -> Result<&mut Self>; +} + +impl CommandExt for std::process::Command { + fn pipe(&mut self) -> Result<&mut Self> { + self.stdout(os_pipe::dup_stdout()?); + self.stderr(os_pipe::dup_stderr()?); + Ok(self) + } +} + /// The bundle API. pub mod bundle; mod error; diff --git a/tooling/cli.js/.eslintrc.cjs b/tooling/cli.js/.eslintrc.cjs deleted file mode 100644 index 24b1e39d28f1..000000000000 --- a/tooling/cli.js/.eslintrc.cjs +++ /dev/null @@ -1,55 +0,0 @@ -module.exports = { - root: true, - - env: { - node: true, - jest: true - }, - - parser: '@typescript-eslint/parser', - - extends: [ - 'standard-with-typescript', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - 'plugin:lodash-template/recommended', - // TODO: make this work with typescript - // 'plugin:node/recommended' - 'prettier' - ], - - plugins: ['@typescript-eslint', 'node', 'security'], - - parserOptions: { - tsconfigRootDir: __dirname, - project: './tsconfig.json' - }, - - globals: { - __statics: true, - process: true - }, - - // add your custom rules here - rules: { - // allow console.log during development only - 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', - // allow debugger during development only - 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', - 'no-process-exit': 'off', - 'security/detect-non-literal-fs-filename': 'warn', - 'security/detect-unsafe-regex': 'error', - 'security/detect-buffer-noassert': 'error', - 'security/detect-child-process': 'warn', - 'security/detect-disable-mustache-escape': 'error', - 'security/detect-eval-with-expression': 'error', - 'security/detect-no-csrf-before-method-override': 'error', - 'security/detect-non-literal-regexp': 'error', - 'security/detect-non-literal-require': 'warn', - 'security/detect-object-injection': 'warn', - 'security/detect-possible-timing-attacks': 'error', - 'security/detect-pseudoRandomBytes': 'error', - 'space-before-function-paren': 'off', - '@typescript-eslint/default-param-last': 'off', - '@typescript-eslint/strict-boolean-expressions': 0 - } -} diff --git a/tooling/cli.js/.gitignore b/tooling/cli.js/.gitignore deleted file mode 100644 index 057f1bd96cd9..000000000000 --- a/tooling/cli.js/.gitignore +++ /dev/null @@ -1,71 +0,0 @@ -# Build output -/dist -target/ - -# Downloaded binaries -bin/tauri-cli -bin/tauri-cli.exe -bin/rustup-init.sh -bin/rustup-init.exe - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Typescript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - -/.vs -.DS_Store -.Thumbs.db -*.sublime* -.idea/ -debug.log -package-lock.json -.vscode/settings.json diff --git a/tooling/cli.js/.npmignore b/tooling/cli.js/.npmignore deleted file mode 100644 index e057bfa2b280..000000000000 --- a/tooling/cli.js/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -test -node_modules -.git -.github -.idea -SECURITY.md -build diff --git a/tooling/cli.js/.prettierrc.cjs b/tooling/cli.js/.prettierrc.cjs deleted file mode 100644 index 2be2f932702c..000000000000 --- a/tooling/cli.js/.prettierrc.cjs +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - singleQuote: true, - semi: false, - trailingComma: 'none' -} diff --git a/tooling/cli.js/CHANGELOG.md b/tooling/cli.js/CHANGELOG.md deleted file mode 100644 index 3cc22a4ce467..000000000000 --- a/tooling/cli.js/CHANGELOG.md +++ /dev/null @@ -1,310 +0,0 @@ -# Changelog - -## \[1.0.0-beta.10] - -- Update cli.yml to pass clap ArgSettings::MultipleValues assertion. - - Bumped due to a bump in cli.rs. - - [0391ac3d](https://www.github.com/tauri-apps/tauri/commit/0391ac3dc96d9c74c34a957e4cb70da88a0a85b7) fix: Update cli.yml to pass clap ArgSettings::MultipleValues assertion. ([#2506](https://www.github.com/tauri-apps/tauri/pull/2506)) ([#2507](https://www.github.com/tauri-apps/tauri/pull/2507)) on 2021-08-22 - -## \[1.0.0-beta.9] - -- The CLI is now an ES module and requires at least Node.js v12.20. Fixed previous releases by using Rollup instead of Webpack. - - [8d1fe0ea](https://www.github.com/tauri-apps/tauri/commit/8d1fe0ea056f4ef0ab0a90c89c6391f3e3185bc7) feat(cli.js): readd ESM distribution ([#2468](https://www.github.com/tauri-apps/tauri/pull/2468)) on 2021-08-17 - -## \[1.0.0-beta.8] - -- Reverts ESM distribution. - - [01ad2925](https://www.github.com/tauri-apps/tauri/commit/01ad29257ca0a0d5b56d93dab4f68f4521aa30a6) fix(cli.js): revert ESM distribution ([#2457](https://www.github.com/tauri-apps/tauri/pull/2457)) on 2021-08-16 - -## \[1.0.0-beta.7] - -- Force Cargo manifest update when running the `deps update` command and fix the version that is written to the file. - - [c544cea8](https://www.github.com/tauri-apps/tauri/commit/c544cea8c971a4f133dc48b4700b86684bcec5f8) fix(cli.js): force version update on Cargo manifest ([#2419](https://www.github.com/tauri-apps/tauri/pull/2419)) on 2021-08-13 -- The CLI is now a ES module and requires at least Node.js v12.20. - - [5f6e135f](https://www.github.com/tauri-apps/tauri/commit/5f6e135f23b370e008fc5e1849be0fcb78fc87e2) refactor(cli.js): package as ES module, closes [#2256](https://www.github.com/tauri-apps/tauri/pull/2256) ([#2392](https://www.github.com/tauri-apps/tauri/pull/2392)) on 2021-08-11 -- Adds support to HTTPS proxy set with the `HTTPS_PROXY` environment variable. - - [9c4032ba](https://www.github.com/tauri-apps/tauri/commit/9c4032ba10d800bccc307f7afcc8e00f282b041e) fix(cli.js): usage with HTTPS_PROXY, closes [#2237](https://www.github.com/tauri-apps/tauri/pull/2237) ([#2381](https://www.github.com/tauri-apps/tauri/pull/2381)) on 2021-08-10 -- Adjust check for `dev` mode and switch CTA test to a script runner. The script gives us more control and better output into any failures. - - [c410e034](https://www.github.com/tauri-apps/tauri/commit/c410e034f74d0624c8465b1f30bb7af58eb98b34) convert jest tests to child_process run script ([#2308](https://www.github.com/tauri-apps/tauri/pull/2308)) on 2021-08-08 - -## \[1.0.0-beta.6] - -- Run powershell commands with `-NoProfile` flag - - [3e6f3416](https://www.github.com/tauri-apps/tauri/commit/3e6f34160deab4f774d90aba28122e5b6b6f9db2) fix(cli.rs): run powershell kill command without profile ([#2130](https://www.github.com/tauri-apps/tauri/pull/2130)) on 2021-06-30 -- Throw error on `cli.rs` download failure instead of silent exit. - - [fd033464](https://www.github.com/tauri-apps/tauri/commit/fd0334645b415b8be574d44256194f601227cb40) fix: tauri init may failed with no error message. (fix [#2079](https://www.github.com/tauri-apps/tauri/pull/2079)) ([#2117](https://www.github.com/tauri-apps/tauri/pull/2117)) on 2021-06-30 - -## \[1.0.0-beta.5] - -- Improve error message when the product name is invalid. - - Bumped due to a bump in cli.rs. - - [1a41e9f0](https://www.github.com/tauri-apps/tauri/commit/1a41e9f040cfa18b6cc1380dfe21251d56e3f973) feat(cli.rs): improve error message on app rename, closes [#2101](https://www.github.com/tauri-apps/tauri/pull/2101) ([#2114](https://www.github.com/tauri-apps/tauri/pull/2114)) on 2021-06-28 - -## \[1.0.0-beta.4] - -- Properly detect target platform's architecture. - - Bumped due to a bump in cli.rs. - - [628a53eb](https://www.github.com/tauri-apps/tauri/commit/628a53eb6176f811d22d7730f08a99e5c370dbf4) fix(cli): properly detect target architecture, closes [#2040](https://www.github.com/tauri-apps/tauri/pull/2040) ([#2102](https://www.github.com/tauri-apps/tauri/pull/2102)) on 2021-06-28 -- Fixes `build` command when the `target` arg is set. - - Bumped due to a bump in cli.rs. - - [8e238701](https://www.github.com/tauri-apps/tauri/commit/8e2387018940e9e1421948d74a82156661ce2e4b) fix(cli.rs): fix out dir detection when target arg is set, closes [#2040](https://www.github.com/tauri-apps/tauri/pull/2040) ([#2098](https://www.github.com/tauri-apps/tauri/pull/2098)) on 2021-06-27 - -## \[1.0.0-beta.3] - -- Allow empty argument when running `cli.rs`. - - [8be35ced](https://www.github.com/tauri-apps/tauri/commit/8be35ced78658de732360e3b20d7d70108c9b32d) fix(cli.rs): `tauri.conf.json > tauri > bundle > targets` being ignored ([#1945](https://www.github.com/tauri-apps/tauri/pull/1945)) on 2021-06-04 - -## \[1.0.0-beta.2] - -- Packages are checked with `!=` instead of `semver` for beta releases. - - [66b6136](https://www.github.com/tauri-apps/tauri/commit/66b6136e06053e839b936ab17051d61748fa4f4e) Disable version check with semver for now ([#1810](https://www.github.com/tauri-apps/tauri/pull/1810)) on 2021-05-13 - -## \[1.0.0-beta.1] - -- Add `'self'` to default CSP because otherwise no joy on macOS. - - Bumped due to a bump in cli.rs. - - [12268e6](https://www.github.com/tauri-apps/tauri/commit/12268e6e69dc9a7034652f50316d3545cac687c7) fix(csp): add 'self' ([#1794](https://www.github.com/tauri-apps/tauri/pull/1794)) on 2021-05-12 -- Fix a typo that would result in bundle arg being ignored. - - Bumped due to a bump in cli.rs. - - [71f6a5e](https://www.github.com/tauri-apps/tauri/commit/71f6a5ed442a43bf1008043c95a1a90effdd2f81) fix(cli.rs/build): fix typo getting bundle arg ([#1783](https://www.github.com/tauri-apps/tauri/pull/1783)) on 2021-05-12 - -## \[1.0.0-beta.0] - -- Fixes `UnhandledPromiseRejectionWarning` when the Rust CLI call fails. - - [8845487](https://www.github.com/tauri-apps/tauri/commit/8845487f9d2791a47b5368d08c152f65abe98835) fix(cli.js): handle cli.rs promise rejection ([#1689](https://www.github.com/tauri-apps/tauri/pull/1689)) on 2021-05-03 - -- Download `rustup` script on runtime instead of shipping it. - - [862e33a](https://www.github.com/tauri-apps/tauri/commit/862e33a0f652cca1fa313f3749a0445e811b2e3b) refactor(cli.js): download rustup binary ([#1711](https://www.github.com/tauri-apps/tauri/pull/1711)) on 2021-05-05 - -- Adds `pnpm` support. - - [908b703](https://www.github.com/tauri-apps/tauri/commit/908b703246ca9ed1959e8aac0c3df898b72d1e59) feat(cli.js): package managers interface, add pnpm support ([#1743](https://www.github.com/tauri-apps/tauri/pull/1743)) on 2021-05-09 - -- Updates to `tauri icon` - -- detect if icon is NOT transparent via metadata - -- detect again on pixel level - -- remove pngquant as a waste of space - -- make optipng default - -- relax optipng settings - -- [82a580e](https://www.github.com/tauri-apps/tauri/commit/82a580ec4585e96ea31fe0f36f3238e34d46e599) feat(tauricon): fix transparency ([#1678](https://www.github.com/tauri-apps/tauri/pull/1678)) on 2021-05-03 - -## \[1.0.0-beta-rc.4] - -- Fixes the Message `command` name value on plugin invoke handler. - - Bumped due to a bump in cli.rs. - - [422dd5e](https://www.github.com/tauri-apps/tauri/commit/422dd5e2a0a03bb1556915c78f110bfab092c874) fix(core): command name on plugin invoke handler ([#1577](https://www.github.com/tauri-apps/tauri/pull/1577)) on 2021-04-21 - - [f575aaa](https://www.github.com/tauri-apps/tauri/commit/f575aaad71f23d44b2f89cf9ee5d84817dc3bb7a) fix: change files not referencing core packages ([#1619](https://www.github.com/tauri-apps/tauri/pull/1619)) on 2021-04-25 -- The package info APIs now checks the `package` object on `tauri.conf.json`. - - Bumped due to a bump in cli.rs. - - [8fd1baf](https://www.github.com/tauri-apps/tauri/commit/8fd1baf69b14bb81d7be9d31605ed7f02058b392) fix(core): pull package info from tauri.conf.json if set ([#1581](https://www.github.com/tauri-apps/tauri/pull/1581)) on 2021-04-22 - - [f575aaa](https://www.github.com/tauri-apps/tauri/commit/f575aaad71f23d44b2f89cf9ee5d84817dc3bb7a) fix: change files not referencing core packages ([#1619](https://www.github.com/tauri-apps/tauri/pull/1619)) on 2021-04-25 - -## \[1.0.0-beta-rc.3] - -- Remove Rust CLI download file if the download fails or the prpocess is killed. - - [8a32d0e](https://www.github.com/tauri-apps/tauri/commit/8a32d0ec39ea87383e286516ab3ee5ab7cdefc8e) fix(cli.js): remove cli file if the download fails or process is killed ([#1592](https://www.github.com/tauri-apps/tauri/pull/1592)) on 2021-04-22 -- The `tauri deps` command now properly detects `beta-rc` crate updates. - - [07eb6ce](https://www.github.com/tauri-apps/tauri/commit/07eb6cec8b60420e034b56c80f5fdca4a5aeb3e3) fix(cli.js): use `cargo search` on crate latest version detection ([#1563](https://www.github.com/tauri-apps/tauri/pull/1563)) on 2021-04-21 -- Update minimum Node.js version to v12.13.0 - - [1f089fb](https://www.github.com/tauri-apps/tauri/commit/1f089fb4f964c673dcab5784bdf1da2833487a7c) chore: update minimum nodejs version to 12.13.0 ([#1562](https://www.github.com/tauri-apps/tauri/pull/1562)) on 2021-04-21 -- The `tauri icon` command now accepts the icon path as the first positional argument instead of `--icon PATH`. - - [1e0b41e](https://www.github.com/tauri-apps/tauri/commit/1e0b41e155355aee82983a2cb3040fd4dd84572e) refactor(cli.js): `tauri icon` with positional arg for icon path ([#1600](https://www.github.com/tauri-apps/tauri/pull/1600)) on 2021-04-23 -- Do not prompt to install dependencies on `tauri init` when the `--ci` argument is passed. - - [941585c](https://www.github.com/tauri-apps/tauri/commit/941585c0c54710df552d8437f7252d67783558e7) fix(cli.js): skip installing deps when `--ci` is passed on `tauri init` ([#1603](https://www.github.com/tauri-apps/tauri/pull/1603)) on 2021-04-23 - -## \[1.0.0-beta-rc.2] - -- Add missing camelcase rename for config - - Bumped due to a bump in cli.rs. - - [bdf7072](https://www.github.com/tauri-apps/tauri/commit/bdf707285e3d307ab083009c274ccb56d5053ff2) fix(cli.rs/info): add missing camelCase rename ([#1505](https://www.github.com/tauri-apps/tauri/pull/1505)) on 2021-04-14 -- Fix `tauri info` -- Properly detect `yarn` and `npm` versions on windows. -- Fix a panic caused by a wrong field name in `metadata.json` -- Bumped due to a bump in cli.rs. -- [71666e9](https://www.github.com/tauri-apps/tauri/commit/71666e9f9cfb5499a727b3f95182e89073f67d7b) fix(cli.rs): fix panic & use `cmd` to run `yarn`&`npm` on windows ([#1511](https://www.github.com/tauri-apps/tauri/pull/1511)) on 2021-04-17 -- Sync `metadata.json` via script to update version reference to cli.js, tauri (core) and tauri-build. - - Bumped due to a bump in cli.rs. - - [1f64927](https://www.github.com/tauri-apps/tauri/commit/1f64927362ef20761d7cd3591281519eb292aa33) chore: sync cli.rs metadata.json file versions ([#1534](https://www.github.com/tauri-apps/tauri/pull/1534)) on 2021-04-19 - -## \[1.0.0-beta-rc.1] - -- Missing the `files` property in the package.json which mean that the `dist` directory was not published and used. - - Bumped due to a bump in cli.rs. - - [b2569a7](https://www.github.com/tauri-apps/tauri/commit/b2569a729a3caa88bdba62abc31f0665e1323aaa) fix(js-api): dist ([#1498](https://www.github.com/tauri-apps/tauri/pull/1498)) on 2021-04-15 - -## \[1.0.0-beta-rc.0] - -- Fixed missing 'App' variant & string promise instead of void promise. - - [44fc65c](https://www.github.com/tauri-apps/tauri/commit/44fc65c723f638f2a1b2ecafb79b32d509ed2f35) Fixing TS API typings ([#1451](https://www.github.com/tauri-apps/tauri/pull/1451)) on 2021-04-11 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- Update all code files to have our license header. - - [bf82136](https://www.github.com/tauri-apps/tauri/commit/bf8213646689175f8a158b956911f3a43e360690) feat(license): SPDX Headers ([#1449](https://www.github.com/tauri-apps/tauri/pull/1449)) on 2021-04-11 - - [a6def70](https://www.github.com/tauri-apps/tauri/commit/a6def7066eec19c889b0f14cc1e475bf209a332e) Refactor(tauri): move tauri-api and tauri-updater to tauri ([#1455](https://www.github.com/tauri-apps/tauri/pull/1455)) on 2021-04-11 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- JS CLI now downloads prebuilt Rust CLI. - - [df305b2](https://www.github.com/tauri-apps/tauri/commit/df305b234bfe487f429949df90e522c1b0ce85c9) feat(cli/tauri.js): download prebuilt cli ([#1452](https://www.github.com/tauri-apps/tauri/pull/1452)) on 2021-04-13 -- The `info` command was rewritten in Rust. - - [c3e06ee](https://www.github.com/tauri-apps/tauri/commit/c3e06ee9e88b3631da6eeb17d61ddd41cd5c6fe9) refactor(cli): rewrite info in Rust ([#1389](https://www.github.com/tauri-apps/tauri/pull/1389)) on 2021-03-25 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- The `init` command was rewritten in Rust. - - [f72b93b](https://www.github.com/tauri-apps/tauri/commit/f72b93b676ba8c48fd9273c187de3dbbc410fa0f) refactor(cli): rewrite init command in Rust ([#1382](https://www.github.com/tauri-apps/tauri/pull/1382)) on 2021-03-24 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- Removed the `no-server` mode, the `inliner`, the `dev` server proxy and the `loadAsset` API. - - [84d7cda](https://www.github.com/tauri-apps/tauri/commit/84d7cdae632eeb02a66f8d1d7577adfa65917a34) refactor(core): remove `no-server` and its APIs ([#1215](https://www.github.com/tauri-apps/tauri/pull/1215)) on 2021-02-11 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- Revert `tauri create` deletion and shift remaining pieces that weren't deleted to `create-tauri-app`. - - [4ec20a4](https://www.github.com/tauri-apps/tauri/commit/4ec20a4a28823614186365c5a90512d77170cff2) feat: shift tauri create \[not wired up] ([#1330](https://www.github.com/tauri-apps/tauri/pull/1330)) on 2021-03-07 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- The Tauri API interface is now shipped with the `@tauri-apps/api` package instead of the deprecated `tauri` package. - To use the new API package, delete the old `tauri` from your `package.json` and install the new package: - `$ yarn remove tauri && yarn add @tauri-apps/api` or `$ npm uninstall tauri && npm install @tauri-apps/api`. - And change all `import { someApi } from 'tauri/api` to `import { someApi } from '@tauri-apps/api'`. - - [3e8abe3](https://www.github.com/tauri-apps/tauri/commit/3e8abe376407bb0ca8893602590ed9edf7aa71a1) feat(cli) rewrite the core CLI in Rust ([#851](https://www.github.com/tauri-apps/tauri/pull/851)) on 2021-01-30 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- The Tauri Node.js CLI package is now `@tauri-apps/cli`. - - [3e8abe3](https://www.github.com/tauri-apps/tauri/commit/3e8abe376407bb0ca8893602590ed9edf7aa71a1) feat(cli) rewrite the core CLI in Rust ([#851](https://www.github.com/tauri-apps/tauri/pull/851)) on 2021-01-30 - - [e02c941](https://www.github.com/tauri-apps/tauri/commit/e02c9419cb8c66f4e43ed598d2fc74d4b19384ec) refactor(tauri): support for building without environmental variables ([#850](https://www.github.com/tauri-apps/tauri/pull/850)) on 2021-02-09 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- All the arguments passed after `tauri dev --` are now propagated to the binary. - - [4e9d31c](https://www.github.com/tauri-apps/tauri/commit/4e9d31c70ba13f1cabe830c6519a1b5f4789fd7b) feat(cli): propagate args passed after `dev --`, closes [#1406](https://www.github.com/tauri-apps/tauri/pull/1406) ([#1407](https://www.github.com/tauri-apps/tauri/pull/1407)) on 2021-03-30 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 -- Eliminate the dead code in cli.js. Also removed some unused dependencies and updated the publish config that we are not publishing the Typescript files (since this is now primarily a CLI). - - [c718bd2](https://www.github.com/tauri-apps/tauri/commit/c718bd2382a289666cd665bb356a39193c06deb6) chore: tauri.js dead code elim ([#1422](https://www.github.com/tauri-apps/tauri/pull/1422)) on 2021-04-01 - - [aea6145](https://www.github.com/tauri-apps/tauri/commit/aea614587bddab930d552512b54e18624fbf573e) refactor(repo): add /tooling folder ([#1457](https://www.github.com/tauri-apps/tauri/pull/1457)) on 2021-04-12 - -## \[0.14.1] - -- Fixed a TypeScript issue where it didn't allow you to put the "recursive" option in the directory functions. - - [2fd1067](https://www.github.com/tauri-apps/tauri/commit/2fd1067a4c7ef86dda074867b6a6702527962829) Fix: add recursive option to directory APIs ([#1141](https://www.github.com/tauri-apps/tauri/pull/1141)) on 2021-01-12 - -## \[0.14.0] - -- Update the tauri template to properly set the app icon id on Windows so the webview can load the executable icon. - To use it on old projects, update your `src-tauri/src/build.rs` file, replacing `res.set_icon("icons/icon.ico");` with `res.set_icon_with_id("icons/icon.ico", "32512");`. - \- [f887320](https://www.github.com/tauri-apps/tauri/commit/f887320df35e44b56e437355ee0ff05507a83173) fix(template) default windows icon id should be 32512, fixes [#1099](https://www.github.com/tauri-apps/tauri/pull/1099) ([#1107](https://www.github.com/tauri-apps/tauri/pull/1107)) on 2020-12-05 -- Fixes `tauri deps` command usage when `npm` is not installed. - - [8da495f](https://www.github.com/tauri-apps/tauri/commit/8da495f78c34780b76d0b1201f622edcbba00229) fix(tauri.js) `deps` cmd usage when `npm` is not installed, closes [#1037](https://www.github.com/tauri-apps/tauri/pull/1037) ([#1053](https://www.github.com/tauri-apps/tauri/pull/1053)) on 2020-12-05 -- Match writeBinaryFile command name between js and rust - - [486bd92](https://www.github.com/tauri-apps/tauri/commit/486bd920f899905bec0f690092aa1e3cac2c78f3) Fix: writeBinaryFile to call the correct command (fix [#1133](https://www.github.com/tauri-apps/tauri/pull/1133)) ([#1136](https://www.github.com/tauri-apps/tauri/pull/1136)) on 2021-01-06 - -## \[0.13.0] - -- Fixes `Reflect.deleteProperty` on promisified API calls failing with `Unable to delete property` by making it configurable. - - [c8b167a](https://www.github.com/tauri-apps/tauri/commit/c8b167adb3561db182bc8f6e4d8753ce1ae3f450) fix(tauri.js) promisified API fails on Reflect.deleteProperty, fix [#1038](https://www.github.com/tauri-apps/tauri/pull/1038) ([#1056](https://www.github.com/tauri-apps/tauri/pull/1056)) on 2020-10-17 - - [72996be](https://www.github.com/tauri-apps/tauri/commit/72996be1bd3eb878c4cf30bfec79058071c26d7a) apply version updates ([#1024](https://www.github.com/tauri-apps/tauri/pull/1024)) on 2020-10-21 -- Adds a path resolution API (e.g. getting the download directory or resolving a path to the home directory). - - [771e401](https://www.github.com/tauri-apps/tauri/commit/771e4019b8cfd1973015ffa632c9d6c6b82c5657) feat: Port path api to js ([#1006](https://www.github.com/tauri-apps/tauri/pull/1006)) on 2020-09-24 - - [72996be](https://www.github.com/tauri-apps/tauri/commit/72996be1bd3eb878c4cf30bfec79058071c26d7a) apply version updates ([#1024](https://www.github.com/tauri-apps/tauri/pull/1024)) on 2020-10-21 - -## \[0.12.0] - -- Break out TauriBuildConfig interface from TauriConfig build property - - [43a8c4d](https://www.github.com/tauri-apps/tauri/commit/43a8c4d2bcc2461232e2ddfdf2506d3b4d68471d) fix [#920](https://www.github.com/tauri-apps/tauri/pull/920): Create recipes ([#930](https://www.github.com/tauri-apps/tauri/pull/930)) on 2020-08-17 -- Create recipes. A recipe: - - Updates the TauriBuildConfig during the init process - - Specifies npm dev and production dependencies to be installed - - Runs extra installation scripts - - [43a8c4d](https://www.github.com/tauri-apps/tauri/commit/43a8c4d2bcc2461232e2ddfdf2506d3b4d68471d) fix [#920](https://www.github.com/tauri-apps/tauri/pull/920): Create recipes ([#930](https://www.github.com/tauri-apps/tauri/pull/930)) on 2020-08-17 -- Create React JS and React TS recipes - - [43a8c4d](https://www.github.com/tauri-apps/tauri/commit/43a8c4d2bcc2461232e2ddfdf2506d3b4d68471d) fix [#920](https://www.github.com/tauri-apps/tauri/pull/920): Create recipes ([#930](https://www.github.com/tauri-apps/tauri/pull/930)) on 2020-08-17 -- Add new top level command `create`, which accepts a recipe as a CLI, or runs interactively, prompting for a recipe out of a menu of choices defined by `api/recipes/index` - - [43a8c4d](https://www.github.com/tauri-apps/tauri/commit/43a8c4d2bcc2461232e2ddfdf2506d3b4d68471d) fix [#920](https://www.github.com/tauri-apps/tauri/pull/920): Create recipes ([#930](https://www.github.com/tauri-apps/tauri/pull/930)) on 2020-08-17 -- Refactor `init` command so that it is just an alias for `create` with no recipe - - [43a8c4d](https://www.github.com/tauri-apps/tauri/commit/43a8c4d2bcc2461232e2ddfdf2506d3b4d68471d) fix [#920](https://www.github.com/tauri-apps/tauri/pull/920): Create recipes ([#930](https://www.github.com/tauri-apps/tauri/pull/930)) on 2020-08-17 -- Bump all deps as noted in #975, #976, #977, #978, and #979. - - [06dd75b](https://www.github.com/tauri-apps/tauri/commit/06dd75b68a15d388808c51ae2bf50554ae761d9d) chore: bump all js/rust deps ([#983](https://www.github.com/tauri-apps/tauri/pull/983)) on 2020-08-20 -- Make interactive prompt not ask for app name supplied as cli arg - - [59e0de7](https://www.github.com/tauri-apps/tauri/commit/59e0de765046a240d6c9ff3ddcd7a98e8f765512) Fix cli no prompt for app-name cli arg ([#980](https://www.github.com/tauri-apps/tauri/pull/980)) on 2020-08-19 -- Change `String` to `string` type for `open` and `save` methods - - [0a5bac1](https://www.github.com/tauri-apps/tauri/commit/0a5bac1dd641792a64f79ec90e2a357f18280776) fix(tauri.js): fix typings for open and save dialogs ([#926](https://www.github.com/tauri-apps/tauri/pull/926)) on 2020-08-08 -- Format all code with prettier. This technically should only affect code styles, but noting for posterity. - - [6a21965](https://www.github.com/tauri-apps/tauri/commit/6a21965ff302940bcbdefa16490249ec7d0c1f2e) chore: add prettier for js formatting ([#937](https://www.github.com/tauri-apps/tauri/pull/937)) on 2020-08-18 -- Set correct promise resolve type which returns from `readBinaryFile` - - [f98d4b9](https://www.github.com/tauri-apps/tauri/commit/f98d4b9076b51a7fc9eca12b4bed2cd3b466c6bc) fix(tauri.js): fix return type for `readBinaryFile` api method ([#927](https://www.github.com/tauri-apps/tauri/pull/927)) on 2020-08-08 -- Add types to JSDoc annotations - - [f98d4b9](https://www.github.com/tauri-apps/tauri/commit/f98d4b9076b51a7fc9eca12b4bed2cd3b466c6bc) fix(tauri.js): fix return type for `readBinaryFile` api method ([#927](https://www.github.com/tauri-apps/tauri/pull/927)) on 2020-08-08 - -## \[0.11.1] - -- Fix command line arguments -W (window title) and -P (dev server uri) to work as intended. - - [e1fd626](https://www.github.com/tauri-apps/tauri/commit/e1fd626453bf6310b18e48472aa831c367212290) Fix typos referring to CLI args in init command ([#921](https://www.github.com/tauri-apps/tauri/pull/921)) on 2020-08-03 - -## \[0.11.0] - -- Fixes the Webview initialization on Windows. - - [4abd12c](https://www.github.com/tauri-apps/tauri/commit/4abd12c2a42b5ace8527114ab64da38f4486754f) fix(tauri) webview initialization on windows, fixes [#879](https://www.github.com/tauri-apps/tauri/pull/879) ([#885](https://www.github.com/tauri-apps/tauri/pull/885)) on 2020-07-23 - -## \[0.10.0] - -- Fixes the `writeFile` and `writeBinaryFile` usage. - - [cbd14c3](https://www.github.com/tauri-apps/tauri/commit/cbd14c307753449d2d8a9cd4d4b29d30af6a7097) fix(tauri.js) `writeFile` and `writeBinaryFile` API ([#857](https://www.github.com/tauri-apps/tauri/pull/857)) on 2020-07-19 -- The notification's `body` is now optional, closes #793. - - [dac1db3](https://www.github.com/tauri-apps/tauri/commit/dac1db39831ecbcf23c630351d5753af01ccd500) fix(tauri) notification body optional, requestPermission() regression, closes [#793](https://www.github.com/tauri-apps/tauri/pull/793) ([#844](https://www.github.com/tauri-apps/tauri/pull/844)) on 2020-07-16 -- Fixes a memory leak on the `promisified` helper usage. - - [42a8bb0](https://www.github.com/tauri-apps/tauri/commit/42a8bb0e096548f2f9d6da2ba3699260e6cda18e) fix(api) `promisified` not cleaning up transformed callbacks, fixes [#852](https://www.github.com/tauri-apps/tauri/pull/852) ([#853](https://www.github.com/tauri-apps/tauri/pull/853)) on 2020-07-18 -- Prevent running the `dev` pipeline when running with administrator privileges. - - [1780057](https://www.github.com/tauri-apps/tauri/commit/17800571fe417b5250aa1bd7052340a1c93918a8) fix(tauri.js) exit dev when running as admin, fixes [#781](https://www.github.com/tauri-apps/tauri/pull/781) ([#839](https://www.github.com/tauri-apps/tauri/pull/839)) on 2020-07-15 -- Print outdated dependencies information on `tauri info`. - - [f0ce94f](https://www.github.com/tauri-apps/tauri/commit/f0ce94fc8e38642f2ba479311370dc1ca54799c7) feat(tauri.js) print outdated deps information on `tauri info` ([#841](https://www.github.com/tauri-apps/tauri/pull/841)) on 2020-07-15 -- Convert the `--app-name` value to kebab case. - - [da99f63](https://www.github.com/tauri-apps/tauri/commit/da99f632f0c8a6b3b7fc5dfecaffb04b74537f0f) fix(tauri.js) app name as kebab case ([#856](https://www.github.com/tauri-apps/tauri/pull/856)) on 2020-07-19 -- Do not require a `package.json` file on the app root. - - [45d3de6](https://www.github.com/tauri-apps/tauri/commit/45d3de6d97f060659e72e0cc0dc56d4f33f4a2f9) fix(tauri.js) do not require a package.json ([#855](https://www.github.com/tauri-apps/tauri/pull/855)) on 2020-07-19 -- Adds a dependency manager command to the Node.js CLI (`tauri deps`). The manager is able to install and update Rust and the Tauri ecosystem dependencies (npm package, crates, cargo subcommands). - Usage: `tauri deps install` and `tauri deps update`. - [77282c1](https://www.github.com/tauri-apps/tauri/commit/77282c1e513227fe379f916cd21249b44faa8756) feat(tauri.js) add dependency manager command ([#829](https://www.github.com/tauri-apps/tauri/pull/829)) on 2020-07-15 -- Run the dependency manager's install script after `tauri init` succeeds. - - [0591f1f](https://www.github.com/tauri-apps/tauri/commit/0591f1f945420ec4bc53919d05a8f8de014b3823) feat(tauri.js) run `deps install` after `tauri init` ([#842](https://www.github.com/tauri-apps/tauri/pull/842)) on 2020-07-15 -- Move types exported in the `tauri` js api into the modules that use them. For - example, `Event` is now available from `tauri/api/event` instead of - `tauri/api/types/event`. - [660a2d8](https://www.github.com/tauri-apps/tauri/commit/660a2d87d6acf0abf6be70c01e6402cb5aba96c7) feat(tauri.js) move exported api types into api modules (fix [#807](https://www.github.com/tauri-apps/tauri/pull/807)) ([#809](https://www.github.com/tauri-apps/tauri/pull/809)) on 2020-07-12 - -## \[0.9.1] - -- Fixes Edge blank screen on Windows when running tauri dev (Tauri crashing window due to Edge reloading app because of missing Content-Type header). - - Bumped due to a bump in tauri-api. - - [fedee83](https://www.github.com/tauri-apps/tauri/commit/fedee835e36daa4363b91aabd43143e8033c9a5c) fix(tauri.js) windows Edge blank screen on tauri dev ([#808](https://www.github.com/tauri-apps/tauri/pull/808)) on 2020-07-11 -- Improve the tauri info output on Windows, including the Microsoft Edge version. - - [0d6235e](https://www.github.com/tauri-apps/tauri/commit/0d6235e427c0f8241d1068bdd1e34903eb9298f9) feat(tauri.js) add microsoft edge version to the info output ([#810](https://www.github.com/tauri-apps/tauri/pull/810)) on 2020-07-12 - -## \[0.9.0] - -- Fixes a race condition on the beforeDevCommand usage (starting Tauri before the devServer is ready). - - [a26cffc](https://www.github.com/tauri-apps/tauri/commit/a26cffc575bee224a6beb5b7b0565d5583c0131f) fix(tauri.js) beforeDevCommand race condition ([#801](https://www.github.com/tauri-apps/tauri/pull/801)) on 2020-07-10 -- Revert a nullish coalescing operator that changed embedded server/inliner behavior. - - [e7b4951](https://www.github.com/tauri-apps/tauri/commit/e7b495133fe9f4e9f576bb9805bec98b967783eb) fix(tauri.js) revert nullish coalesce addition ([#799](https://www.github.com/tauri-apps/tauri/pull/799)) on 2020-07-10 -- Fixes tauri init not generating tauri.conf.json on the Vue CLI Plugin. - - [f208a68](https://www.github.com/tauri-apps/tauri/commit/f208a68e40c804daf41d54539d3a5951679e8a64) fix(tauri.js) do not swallow init errors, fix conf inject ([#802](https://www.github.com/tauri-apps/tauri/pull/802)) on 2020-07-10 -- tauri init now prompt for default values such as window title, app name, dist dir and dev path. You can use --ci to skip the prompts. - - [ee8724b](https://www.github.com/tauri-apps/tauri/commit/ee8724b90a63f281292c6eb174773b905ba52e32) feat(tauri.js/init): prompt for default values (fix [#422](https://www.github.com/tauri-apps/tauri/pull/422)/[#162](https://www.github.com/tauri-apps/tauri/pull/162)) ([#472](https://www.github.com/tauri-apps/tauri/pull/472)) on 2020-07-10 - -## \[0.8.4] - -- Bump lodash to 4.17.19 - -## \[0.8.3] - -- Fixes the wrong cli value on the template that's used by tauri init. - Also fixes the template test. -- Fixes the tauri icon usage with the --icon flag. Previously, only the -i flag worked. - -## \[0.8.2] - -- Adds tauri.conf.json schema validation to the CLI. - -## \[0.8.1] - -- Transpile the TS API to ES5. - Expose CJS as .js and ESM as .mjs. -- Fixes the assets embedding into the binary. - -## \[0.8.0] - -- Create UMD, ESM and CJS artifacts for the JavaScript API entry point from TS source using rollup. -- Renaming `window.tauri` to `window.__TAURI__`, closing #435. - The **Tauri** object now follows the TypeScript API structure (e.g. `window.tauri.readTextFile` is now `window.__TAURI__.fs.readTextFile`). - If you want to keep the `window.tauri` object for a while, you can add a [mapping object](https://gist.github.com/lucasfernog/8f7b29cadd91d92ee2cf816a20c2ef01) to your code. diff --git a/tooling/cli.js/LICENSE_APACHE-2.0 b/tooling/cli.js/LICENSE_APACHE-2.0 deleted file mode 100644 index f433b1a53f5b..000000000000 --- a/tooling/cli.js/LICENSE_APACHE-2.0 +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/tooling/cli.js/LICENSE_MIT b/tooling/cli.js/LICENSE_MIT deleted file mode 100644 index b08530d59433..000000000000 --- a/tooling/cli.js/LICENSE_MIT +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 - Present Tauri Apps Contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/tooling/cli.js/README.md b/tooling/cli.js/README.md deleted file mode 100644 index efe0db0e0d81..000000000000 --- a/tooling/cli.js/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# @tauri-apps/cli - - -[![status](https://img.shields.io/badge/Status-Beta-green.svg)](https://github.com/tauri-apps/tauri) -[![Chat Server](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/SpmNs4S) -[![devto](https://img.shields.io/badge/blog-dev.to-black.svg)](https://dev.to/tauri) - -![](https://img.shields.io/github/workflow/status/tauri-apps/tauri/test%20library?label=test%20library -) -[![devto](https://img.shields.io/badge/documentation-site-purple.svg)](https://tauri.studio) - -[![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) -[![support](https://img.shields.io/badge/sponsor-Opencollective-blue.svg)](https://opencollective.com/tauri) - -| Component | Version | -| --------- | ------------------------------------------- | -| @tauri-apps/cli | ![](https://img.shields.io/npm/v/@tauri-apps/cli.svg) | - -## About Tauri -Tauri is a polyglot and generic system that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. In fact, developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily. - -Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the system's webview. They do not ship a runtime, since the final binary is compiled from rust. This makes the reversing of Tauri apps not a trivial task. -## This module -Written in Typescript and packaged such that it can be used with `npm`, `pnpm`, and `yarn`, this library provides a node.js runner for common tasks when using Tauri, like `yarn tauri dev`. For the most part it is a wrapper around [cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli.rs). - -To 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. - - -## Installation - -The preferred method is to install this module locally as a development dependency: -``` -$ npm install --save-dev @tauri-apps/cli -$ yarn add --dev @tauri-apps/cli -``` - -## Semver -**tauri** is following [Semantic Versioning 2.0](https://semver.org/). -## Licenses -Code: (c) 2019 - 2021 - The Tauri Programme within The Commons Conservancy. - -MIT or MIT/Apache 2.0 where applicable. - -Logo: CC-BY-NC-ND -- Original Tauri Logo Designs by [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum) diff --git a/tooling/cli.js/app-icon.png b/tooling/cli.js/app-icon.png deleted file mode 100644 index f71d543ce36d..000000000000 Binary files a/tooling/cli.js/app-icon.png and /dev/null differ diff --git a/tooling/cli.js/architecture.md b/tooling/cli.js/architecture.md deleted file mode 100644 index 3f3749cc2a43..000000000000 --- a/tooling/cli.js/architecture.md +++ /dev/null @@ -1,11 +0,0 @@ -# Contributing - -See the main document in the `.github` folder for general instructions. This document includes information regarding specific architecture choices. - -# Development and Publishing - -This package is primarily a CLI. This means that the output should not contain any Typescript, and only use the `bin` directory with `.js` (or files runnable directly in pure node) or the `dist` directory which includes processed Typescript files. Running `npm publish --dry-run` will give you a list of files and the package structure that are included when it is published. This may be helpful for understanding path requirements. - -The `scripts` folder is included for use in dependency manager to install rustup. - -Webpack is our current bundler of choice. It is not bundling the `node_modules` so our `package.json` dependency array needs to include anything required within the repository. diff --git a/tooling/cli.js/babel.config.cjs b/tooling/cli.js/babel.config.cjs deleted file mode 100644 index 42ad110a3d3d..000000000000 --- a/tooling/cli.js/babel.config.cjs +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - presets: [ - [ - '@babel/preset-env', - { - targets: { - node: 'current' - }, - modules: false - } - ], - '@babel/preset-typescript' - ] -} diff --git a/tooling/cli.js/bin/tauri-deps.js b/tooling/cli.js/bin/tauri-deps.js deleted file mode 100644 index 987407627da2..000000000000 --- a/tooling/cli.js/bin/tauri-deps.js +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { - installDependencies, - updateDependencies -} from '../dist/api/dependency-manager.js' - -async function run() { - const choice = process.argv[2] - if (choice === 'install') { - await installDependencies() - } else if (choice === 'update') { - await updateDependencies() - } else { - console.log(` - Description - Tauri dependency management script - Usage - $ tauri deps [install|update] - `) - } -} - -run() diff --git a/tooling/cli.js/bin/tauri-icon.js b/tooling/cli.js/bin/tauri-icon.js deleted file mode 100644 index 137df7d37ce9..000000000000 --- a/tooling/cli.js/bin/tauri-icon.js +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import parseArgs from 'minimist' -import tauricon from '../dist/api/tauricon.js' - -/** - * @type {object} - * @property {boolean} h - * @property {boolean} help - * @property {string|boolean} f - * @property {string|boolean} force - * @property {boolean} l - * @property {boolean} log - * @property {boolean} c - * @property {boolean} config - * @property {boolean} s - * @property {boolean} source - * @property {boolean} t - * @property {boolean} target - */ -const argv = parseArgs(process.argv.slice(2), { - alias: { - h: 'help', - l: 'log', - c: 'config', - t: 'target' - }, - boolean: ['h', 'l'] -}) - -if (argv.help) { - console.log(` - Description - Create all the icons you need for your Tauri app. - The icon path is the source icon (png, 1240x1240 with transparency). - - Usage - $ tauri icon [ICON-PATH] - - Options - --help, -h Displays this message - --log, l Logging [boolean] - --target, t Target folder (default: 'src-tauri/icons') - --compression, c Compression type [optipng|zopfli] - --ci Runs the script in CI mode - `) - process.exit(0) -} - -tauricon - .make(argv._[0], argv.t, argv.c || 'optipng') - .then(() => { - // TODO: use logger module for prettier output - console.log('app:tauri (tauricon) Completed') - }) - .catch((e) => { - // TODO: use logger module for prettier output - console.error('app:tauri (icon)', e) - }) diff --git a/tooling/cli.js/bin/tauri.js b/tooling/cli.js/bin/tauri.js deleted file mode 100755 index 5cc8f1e3951b..000000000000 --- a/tooling/cli.js/bin/tauri.js +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env node -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import chalk from 'chalk' -import updateNotifier from 'update-notifier' -import { createRequire } from 'module' -const require = createRequire(import.meta.url) -const pkg = require('../package.json') - -const cmds = ['icon', 'deps'] -const rustCliCmds = ['dev', 'build', 'init', 'info', 'sign'] - -const cmd = process.argv[2] -/** - * @description This is the bootstrapper that in turn calls subsequent - * Tauri Commands - * - * @param {string|array} command - */ -const tauri = async function (command) { - // notifying updates. - if (!process.argv.some((arg) => arg === '--no-update-notifier')) { - updateNotifier({ - pkg, - updateCheckInterval: 0 - }).notify() - } - - if (typeof command === 'object') { - // technically we just care about an array - command = command[0] - } - - const help = - !command || command === '-h' || command === '--help' || command === 'help' - if (help) { - console.log(` - ${chalk.cyan(` - :oooodddoooo; ;oddl, ,ol, ,oc, ,ldoooooooc, ,oc, - ';;;cxOx:;;;' ;xOxxko' :kx: lkd, :xkl;;;;:okx: lkd, - 'dOo' 'oOd;:xkc :kx: lkd, :xx: ;xkc lkd, - 'dOo' ckx: lkx; :kx: lkd, :xx: :xkc lkd, - 'dOo' ;xkl ,dko' :kx: lkd, :xx:.....xko, lkd, - 'dOo' 'oOd, :xkc :kx: lkd, :xx:,;cokko' lkd, - 'dOo' ckk: lkx; :kx: lkd, :xx: ckkc lkd, - 'dOo' ;xOl lko; :xkl;,....;oOd, :xx: :xkl' lkd, - 'okl' 'kd' 'xx' 'dxxxddddxxo' :dd; ;dxc 'xo'`)} - -${chalk.yellow('Description')} -This is the Tauri CLI -${chalk.yellow('Usage')} -$ tauri ${[...rustCliCmds, ...cmds].join('|')} -${chalk.yellow('Options')} ---help, -h Displays this message ---version, -v Displays the Tauri CLI version - `) - - process.exit(0) - // eslint-disable-next-line no-unreachable - return false // do this for node consumers and tests - } else if (command === '-v' || command === '--version') { - console.log(`${pkg.version}`) - return false // do this for node consumers and tests - } else if (cmds.includes(command)) { - if (process.argv && process.env.NODE_ENV !== 'test') { - process.argv.splice(2, 1) - } - console.log(`[tauri]: running ${command}`) - await import(`./tauri-${command}.js`) - } else { - const { runOnRustCli } = await import('../dist/helpers/rust-cli.js') - if (process.argv && process.env.NODE_ENV !== 'test') { - process.argv.splice(0, 3) - } - ;( - await runOnRustCli( - command, - (process.argv || []).filter((v) => v !== '--no-update-notifier') - ) - ).promise - .then(() => { - if (command === 'init' && !process.argv.some((arg) => arg === '--ci')) { - return import('../dist/api/dependency-manager.js').then( - ({ installDependencies }) => installDependencies() - ) - } - }) - .catch(() => process.exit(1)) - } -} - -export default tauri - -// on test we use the module.exports -if (process.env.NODE_ENV !== 'test') { - tauri(cmd).catch((e) => { - throw e - }) -} diff --git a/tooling/cli.js/jest.config.js b/tooling/cli.js/jest.config.js deleted file mode 100644 index 1315cf6a9a08..000000000000 --- a/tooling/cli.js/jest.config.js +++ /dev/null @@ -1,50 +0,0 @@ -export default { - globals: { - __DEV__: true - }, - setupFilesAfterEnv: ['/test/jest/jest.setup.js'], - // noStackTrace: true, - // bail: true, - // cache: false, - // verbose: true, - // watch: true, - - // TODO: coverage does not work with esm - // collectCoverage: true, - // coverageDirectory: '/test/jest/coverage', - // collectCoverageFrom: [ - // '/bin/**/*.js', - // '/helpers/**/*.js', - // '/api/**/*.js' - // ], - // coverageReporters: ['json-summary', 'text', 'lcov'], - // coverageThreshold: { - // global: { - // branches: 50, - // functions: 50, - // lines: 50, - // statements: 50 - // } - // }, - testMatch: [ - '/test/jest/__tests__/**/*.spec.js', - '/test/jest/__tests__/**/*.test.js' - ], - moduleFileExtensions: ['ts', 'js', 'json'], - moduleNameMapper: { - '^~/(.*)$': '/$1', - '^dist/(.*)$': '/dist/$1', - '^bin/(.*)$': '/bin/$1', - '^helpers/(.*)$': '/src/helpers/$1', - '^api/(.*)$': '/src/api/$1', - '^templates/(.*)$': '/src/templates/$1', - '^test/(.*)$': '/test/$1', - '../../package.json': '/package.json', - 'node:(.*)$': '$1' - }, - transform: { - '\\.toml$': 'jest-transform-toml', - '\\.(js|ts)$': 'babel-jest' - }, - extensionsToTreatAsEsm: ['.ts'] -} diff --git a/tooling/cli.js/package.json b/tooling/cli.js/package.json deleted file mode 100644 index 21fffd5355c0..000000000000 --- a/tooling/cli.js/package.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "name": "@tauri-apps/cli", - "version": "1.0.0-beta.10", - "description": "Command line interface for building Tauri apps", - "type": "module", - "bin": { - "tauri": "./bin/tauri.js" - }, - "files": [ - "bin", - "dist", - "scripts" - ], - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/tauri" - }, - "scripts": { - "build": "rimraf ./dist && rollup -c --silent", - "build-release": "rimraf ./dist && cross-env NODE_ENV=production rollup -c", - "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --forceExit --no-cache --testPathIgnorePatterns=\"(build|dev)\"", - "pretest": "yarn build", - "prepublishOnly": "yarn build-release", - "test:local": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --forceExit", - "lint": "eslint --ext ts \"./src/**/*.ts\"", - "lint-fix": "eslint --fix --ext ts \"./src/**/*.ts\"", - "lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn", - "format": "prettier --write --end-of-line=auto \"./**/*.{cjs,js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore", - "format:check": "prettier --check --end-of-line=auto \"./**/*.{cjs,js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/tauri-apps/tauri.git" - }, - "contributors": [ - "Tauri Team (https://tauri.studio)" - ], - "license": "Apache-2.0 OR MIT", - "bugs": { - "url": "https://github.com/tauri-apps/tauri/issues" - }, - "homepage": "https://github.com/tauri-apps/tauri#readme", - "publishConfig": { - "access": "public" - }, - "engines": { - "node": ">= 12.20.0", - "npm": ">= 6.6.0", - "yarn": ">= 1.19.1" - }, - "dependencies": { - "@tauri-apps/toml": "2.2.4", - "chalk": "4.1.2", - "cross-env": "7.0.3", - "cross-spawn": "7.0.3", - "fs-extra": "10.0.0", - "global-agent": "3.0.0", - "got": "11.8.2", - "imagemin": "8.0.1", - "imagemin-optipng": "8.0.0", - "imagemin-zopfli": "7.0.0", - "inquirer": "8.1.2", - "is-png": "3.0.0", - "minimist": "1.2.5", - "ms": "2.1.3", - "png2icons": "2.0.1", - "read-chunk": "3.2.0", - "semver": "7.3.5", - "sharp": "0.28.3", - "update-notifier": "5.1.0" - }, - "devDependencies": { - "@babel/core": "7.15.0", - "@babel/preset-env": "7.15.0", - "@babel/preset-typescript": "7.15.0", - "@jest/globals": "27.0.6", - "@rollup/plugin-babel": "5.3.0", - "@rollup/plugin-commonjs": "20.0.0", - "@rollup/plugin-node-resolve": "13.0.4", - "@rollup/plugin-replace": "^3.0.0", - "@rollup/plugin-typescript": "8.2.5", - "@types/cross-spawn": "6.0.2", - "@types/fs-extra": "9.0.12", - "@types/global-agent": "2.1.1", - "@types/imagemin": "7.0.1", - "@types/imagemin-optipng": "5.2.1", - "@types/inquirer": "7.3.3", - "@types/ms": "0.7.31", - "@types/semver": "7.3.8", - "@types/sharp": "0.28.5", - "@typescript-eslint/eslint-plugin": "4.29.1", - "@typescript-eslint/parser": "4.29.1", - "babel-jest": "27.0.6", - "eslint": "7.32.0", - "eslint-config-prettier": "8.3.0", - "eslint-config-standard-with-typescript": "20.0.0", - "eslint-plugin-import": "2.24.0", - "eslint-plugin-lodash-template": "0.19.0", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "5.1.0", - "eslint-plugin-security": "1.4.0", - "is-running": "2.1.0", - "jest": "27.0.6", - "jest-transform-toml": "1.0.0", - "lockfile-lint": "4.6.2", - "prettier": "2.3.2", - "promise": "8.1.0", - "rimraf": "3.0.2", - "rollup": "2.56.2", - "rollup-plugin-terser": "7.0.2", - "tslib": "2.3.1", - "typescript": "4.3.5" - }, - "resolutions": { - "**/trim-newlines": "4.0.2" - } -} diff --git a/tooling/cli.js/rollup.config.js b/tooling/cli.js/rollup.config.js deleted file mode 100644 index 6166562b3c8e..000000000000 --- a/tooling/cli.js/rollup.config.js +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -// rollup.config.js -import { readFileSync } from 'fs' -import { terser } from 'rollup-plugin-terser' -import resolve from '@rollup/plugin-node-resolve' -import commonjs from '@rollup/plugin-commonjs' -import babel from '@rollup/plugin-babel' -import typescript from '@rollup/plugin-typescript' -import pkg from './package.json' -import replace from '@rollup/plugin-replace' -import TOML from '@tauri-apps/toml' - -const cliManifestContents = readFileSync('../cli.rs/Cargo.toml').toString() -const cliManifest = TOML.parse(cliManifestContents) - -export default { - input: { - 'api/cli': './src/api/cli.ts', - 'api/tauricon': './src/api/tauricon.ts', - 'api/dependency-manager': './src/api/dependency-manager/index.ts', - 'helpers/spawn': './src/helpers/spawn.ts', - 'helpers/rust-cli': './src/helpers/rust-cli.ts', - 'helpers/download-binary': './src/helpers/download-binary.ts' - }, - treeshake: true, - perf: true, - output: { - dir: 'dist/', - entryFileNames: '[name].js', - format: 'esm', - exports: 'named', - globals: {} - }, - plugins: [ - replace({ - __RUST_CLI_VERSION__: JSON.stringify(cliManifest.package.version), - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) - }), - commonjs({}), - resolve({ - // pass custom options to the resolve plugin - customResolveOptions: { - moduleDirectories: ['node_modules'] - } - }), - typescript({ - tsconfig: './tsconfig.json' - }), - babel({ - configFile: false, - presets: [['@babel/preset-env'], ['@babel/preset-typescript']] - }), - terser() - ], - external: [ - ...Object.keys(pkg.dependencies || {}), - ...Object.keys(pkg.peerDependencies || {}) - ] -} diff --git a/tooling/cli.js/src/api/cli.ts b/tooling/cli.js/src/api/cli.ts deleted file mode 100644 index 8717df62135f..000000000000 --- a/tooling/cli.js/src/api/cli.ts +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { runOnRustCli } from '../helpers/rust-cli' - -interface Args { - [key: string]: string | Object -} - -interface Cmd { - pid: number - promise: Promise -} - -function toKebabCase(value: string): string { - return value - .replace(/([a-z])([A-Z])/g, '$1-$2') - .replace(/\s+/g, '-') - .toLowerCase() -} - -async function runCliCommand(command: string, args?: Args): Promise { - const argsArray = [] - for (const [argName, argValue] of Object.entries(args ?? {})) { - if (argValue === false) { - continue - } - argsArray.push(`--${toKebabCase(argName)}`) - if (argValue === true) { - continue - } - argsArray.push( - typeof argValue === 'string' ? argValue : JSON.stringify(argValue) - ) - } - return await runOnRustCli(command, argsArray) -} - -export const init = async (args?: Args): Promise => - await runCliCommand('init', args) -export const dev = async (args?: Args): Promise => - await runCliCommand('dev', args) -export const build = async (args?: Args): Promise => - await runCliCommand('build', args) diff --git a/tooling/cli.js/src/api/dependency-manager/cargo-crates.ts b/tooling/cli.js/src/api/dependency-manager/cargo-crates.ts deleted file mode 100644 index 79ce1d010b8b..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/cargo-crates.ts +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { spawnSync } from './../../helpers/spawn' -import { - CargoManifest, - CargoManifestDependency, - CargoLock -} from './../../types/cargo' -import { ManagementType, Result } from './types' -import { getCrateLatestVersion, semverLt } from './util' -import logger from '../../helpers/logger' -import { resolve as appResolve, tauriDir } from '../../helpers/app-paths' -import { readFileSync, writeFileSync, existsSync } from 'fs' -import inquirer from 'inquirer' -import { createRequire } from 'module' - -const require = createRequire(import.meta.url) -// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires -const toml = require('@tauri-apps/toml') -const log = logger('dependency:crates') - -const dependencies = ['tauri'] - -function readToml(tomlPath: string): T | null { - if (existsSync(tomlPath)) { - const manifest = readFileSync(tomlPath).toString() - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call - return toml.parse(manifest) as T - } - return null -} - -function dependencyDefinition( - dependency: string | CargoManifestDependency, - version: string -): string | CargoManifestDependency { - if (typeof dependency === 'string') { - return version - } - return { ...dependency, version } -} - -async function manageDependencies( - managementType: ManagementType -): Promise { - const installedDeps = [] - const updatedDeps = [] - const result: Result = new Map() - - const manifest = readToml(appResolve.tauri('Cargo.toml')) - - if (manifest === null) { - log('Cargo.toml not found. Skipping crates check...') - return result - } - - const lockPath = appResolve.tauri('Cargo.lock') - if (!existsSync(lockPath)) { - spawnSync('cargo', ['generate-lockfile'], tauriDir) - } - const lock = readToml(lockPath) - - for (const dependency of dependencies) { - const lockPackages = lock - ? lock.package.filter((pkg) => pkg.name === dependency) - : [] - // eslint-disable-next-line security/detect-object-injection - const manifestDep = manifest.dependencies[dependency] - const currentVersion = - lockPackages.length === 1 - ? lockPackages[0].version - : typeof manifestDep === 'string' - ? manifestDep - : manifestDep?.version - if (currentVersion === undefined) { - log(`Installing ${dependency}...`) - const latestVersion = getCrateLatestVersion(dependency) - if (latestVersion !== null) { - // eslint-disable-next-line security/detect-object-injection - manifest.dependencies[dependency] = dependencyDefinition( - // eslint-disable-next-line security/detect-object-injection - manifest.dependencies[dependency], - latestVersion - ) - } - installedDeps.push(dependency) - } else if (managementType === ManagementType.Update) { - const latestVersion = getCrateLatestVersion(dependency) - if (latestVersion !== null) { - if (semverLt(currentVersion, latestVersion)) { - const inquired = (await inquirer.prompt([ - { - type: 'confirm', - name: 'answer', - message: `[CRATES] "${dependency}" latest version is ${latestVersion}. Do you want to update?`, - default: false - } - ])) as { answer: boolean } - if (inquired.answer) { - log(`Updating ${dependency}...`) - // eslint-disable-next-line security/detect-object-injection - manifest.dependencies[dependency] = dependencyDefinition( - // eslint-disable-next-line security/detect-object-injection - manifest.dependencies[dependency], - latestVersion - ) - updatedDeps.push(dependency) - } - } else { - // force update the manifest to the show the latest version even if the lockfile is up to date - // eslint-disable-next-line security/detect-object-injection - manifest.dependencies[dependency] = dependencyDefinition( - // eslint-disable-next-line security/detect-object-injection - manifest.dependencies[dependency], - latestVersion - ) - updatedDeps.push(dependency) - log(`"${dependency}" is up to date`) - } - } - } else { - log(`"${dependency}" is already installed`) - } - } - - if (installedDeps.length || updatedDeps.length) { - writeFileSync( - appResolve.tauri('Cargo.toml'), - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call - toml.stringify(manifest as any) - ) - } - if (updatedDeps.length) { - if (!existsSync(appResolve.tauri('Cargo.lock'))) { - spawnSync('cargo', ['generate-lockfile'], tauriDir) - } - spawnSync( - 'cargo', - [ - 'update', - '--aggressive', - ...updatedDeps.reduce( - (initialValue, dep) => [...initialValue, '-p', dep], - [] - ) - ], - tauriDir - ) - } - - result.set(ManagementType.Install, installedDeps) - result.set(ManagementType.Update, updatedDeps) - - return result -} - -async function install(): Promise { - return await manageDependencies(ManagementType.Install) -} - -async function update(): Promise { - return await manageDependencies(ManagementType.Update) -} - -export { install, update } diff --git a/tooling/cli.js/src/api/dependency-manager/index.ts b/tooling/cli.js/src/api/dependency-manager/index.ts deleted file mode 100644 index 7339c6e70bcd..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import logger from '../../helpers/logger' -import * as rust from './rust' -import * as cargoCrates from './cargo-crates' -import * as npmPackages from './npm-packages' - -const log = logger('dependency:manager') - -export async function installDependencies(): Promise { - log('Installing missing dependencies...') - await rust.install() - await cargoCrates.install() - await npmPackages.install() -} - -export async function updateDependencies(): Promise { - log('Updating dependencies...') - await rust.update() - await cargoCrates.update() - await npmPackages.update() -} diff --git a/tooling/cli.js/src/api/dependency-manager/managers/index.ts b/tooling/cli.js/src/api/dependency-manager/managers/index.ts deleted file mode 100644 index 318431a107d8..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/managers/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './yarn-manager' -export * from './npm-manager' -export * from './pnpm-manager' -export * from './types' diff --git a/tooling/cli.js/src/api/dependency-manager/managers/npm-manager.ts b/tooling/cli.js/src/api/dependency-manager/managers/npm-manager.ts deleted file mode 100644 index 0b5de13e3a63..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/managers/npm-manager.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { IManager } from './types' -import { sync as crossSpawnSync } from 'cross-spawn' -import { spawnSync } from '../../../helpers/spawn' -import { appDir } from '../../../helpers/app-paths' - -export class NpmManager implements IManager { - type = 'npm' - - installPackage(packageName: string): void { - spawnSync('npm', ['install', packageName], appDir) - } - - installDevPackage(packageName: string): void { - spawnSync('npm', ['install', packageName, '--save-dev'], appDir) - } - - updatePackage(packageName: string): void { - spawnSync('npm', ['install', `${packageName}@latest`], appDir) - } - - getPackageVersion(packageName: string): string | null { - const child = crossSpawnSync( - 'npm', - ['list', packageName, 'version', '--depth', '0'], - { - cwd: appDir - } - ) - - const output = String(child.output[1]) - // eslint-disable-next-line security/detect-non-literal-regexp - const matches = new RegExp(packageName + '@(\\S+)', 'g').exec(output) - - if (matches?.[1]) { - return matches[1] - } else { - return null - } - } - - getLatestVersion(packageName: string): string { - const child = crossSpawnSync('npm', ['show', packageName, 'version'], { - cwd: appDir - }) - - return String(child.output[1]).replace('\n', '') - } -} diff --git a/tooling/cli.js/src/api/dependency-manager/managers/pnpm-manager.ts b/tooling/cli.js/src/api/dependency-manager/managers/pnpm-manager.ts deleted file mode 100644 index f8353ce07f9a..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/managers/pnpm-manager.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { IManager } from './types' -import { sync as crossSpawnSync } from 'cross-spawn' -import { spawnSync } from '../../../helpers/spawn' -import { appDir } from '../../../helpers/app-paths' - -export class PnpmManager implements IManager { - type = 'pnpm' - - installPackage(packageName: string): void { - spawnSync('pnpm', ['add', packageName], appDir) - } - - installDevPackage(packageName: string): void { - spawnSync('pnpm', ['add', packageName, '--save-dev'], appDir) - } - - updatePackage(packageName: string): void { - spawnSync('pnpm', ['add', `${packageName}@latest`], appDir) - } - - getPackageVersion(packageName: string): string | null { - const child = crossSpawnSync( - 'pnpm', - ['list', packageName, 'version', '--depth', '0'], - { - cwd: appDir - } - ) - - const output = String(child.output[1]) - // eslint-disable-next-line security/detect-non-literal-regexp - const matches = new RegExp(packageName + ' (\\S+)', 'g').exec(output) - - if (matches?.[1]) { - return matches[1] - } else { - return null - } - } - - getLatestVersion(packageName: string): string { - const child = crossSpawnSync('pnpm', ['info', packageName, 'version'], { - cwd: appDir - }) - - return String(child.output[1]).replace('\n', '') - } -} diff --git a/tooling/cli.js/src/api/dependency-manager/managers/types.ts b/tooling/cli.js/src/api/dependency-manager/managers/types.ts deleted file mode 100644 index 19289baf3bfb..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/managers/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface IManager { - type: string - installPackage: (packageName: string) => void - installDevPackage: (packageName: string) => void - updatePackage: (packageName: string) => void - getPackageVersion: (packageName: string) => string | null - getLatestVersion: (packageName: string) => string -} diff --git a/tooling/cli.js/src/api/dependency-manager/managers/yarn-manager.ts b/tooling/cli.js/src/api/dependency-manager/managers/yarn-manager.ts deleted file mode 100644 index 8ef91280532c..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/managers/yarn-manager.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { IManager } from './types' -import { sync as crossSpawnSync } from 'cross-spawn' -import { spawnSync } from '../../../helpers/spawn' -import { appDir } from '../../../helpers/app-paths' - -export class YarnManager implements IManager { - type = 'yarn' - - installPackage(packageName: string): void { - spawnSync('yarn', ['add', packageName], appDir) - } - - installDevPackage(packageName: string): void { - spawnSync('yarn', ['add', packageName, '--dev'], appDir) - } - - updatePackage(packageName: string): void { - spawnSync('yarn', ['upgrade', packageName, '--latest'], appDir) - } - - getPackageVersion(packageName: string): string | null { - const child = crossSpawnSync( - 'yarn', - ['list', '--pattern', packageName, '--depth', '0'], - { cwd: appDir } - ) - - const output = String(child.output[1]) - // eslint-disable-next-line security/detect-non-literal-regexp - const matches = new RegExp(packageName + '@(\\S+)', 'g').exec(output) - if (matches?.[1]) { - return matches[1] - } else { - return null - } - } - - getLatestVersion(packageName: string): string { - const child = crossSpawnSync( - 'yarn', - ['info', packageName, 'version', '--json'], - { cwd: appDir } - ) - const output = String(child.output[1]) - const packageJson = JSON.parse(output) as { data: string } - return packageJson.data - } -} diff --git a/tooling/cli.js/src/api/dependency-manager/npm-packages.ts b/tooling/cli.js/src/api/dependency-manager/npm-packages.ts deleted file mode 100644 index 88e20d2a546e..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/npm-packages.ts +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { Answer, ManagementType, Result } from './types' -import { - getNpmLatestVersion, - getNpmPackageVersion, - installNpmPackage, - installNpmDevPackage, - updateNpmPackage, - semverLt, - getManager -} from './util' -import logger from '../../helpers/logger' -import { resolve } from '../../helpers/app-paths' -import inquirer from 'inquirer' -import { existsSync } from 'fs' -import { sync as crossSpawnSync } from 'cross-spawn' - -const log = logger('dependency:npm-packages') - -async function manageDependencies( - managementType: ManagementType, - dependencies: string[] -): Promise { - const installedDeps = [] - const updatedDeps = [] - - const npmChild = crossSpawnSync('npm', ['--version']) - const yarnChild = crossSpawnSync('yarn', ['--version']) - const pnpmChild = crossSpawnSync('pnpm', ['--version']) - if ( - (npmChild.status ?? npmChild.error) && - (yarnChild.status ?? yarnChild.error) && - (pnpmChild.status ?? pnpmChild.error) - ) { - throw new Error( - 'must have installed one of the following package managers `npm`, `yarn`, `pnpm` to manage dependenices' - ) - } - - if (existsSync(resolve.app('package.json'))) { - for (const dependency of dependencies) { - const currentVersion = getNpmPackageVersion(dependency) - const packageManager = getManager().type.toUpperCase() - - if (currentVersion === null) { - log(`Installing ${dependency}...`) - if ( - managementType === ManagementType.Install || - managementType === ManagementType.InstallDev - ) { - const prefix = - managementType === ManagementType.InstallDev - ? ' as dev-dependency' - : '' - - const inquired = await inquirer.prompt([ - { - type: 'confirm', - name: 'answer', - message: `[${packageManager}]: "Do you want to install ${dependency}${prefix}?"`, - default: false - } - ]) - - if (inquired.answer) { - if (managementType === ManagementType.Install) { - installNpmPackage(dependency) - } else if (managementType === ManagementType.InstallDev) { - installNpmDevPackage(dependency) - } - installedDeps.push(dependency) - } - } - } else if (managementType === ManagementType.Update) { - const latestVersion = getNpmLatestVersion(dependency) - - if (semverLt(currentVersion, latestVersion)) { - const inquired = await inquirer.prompt([ - { - type: 'confirm', - name: 'answer', - message: `[${packageManager}]: "${dependency}" latest version is ${latestVersion}. Do you want to update?`, - default: false - } - ]) - - if (inquired.answer) { - log(`Updating ${dependency}...`) - updateNpmPackage(dependency) - updatedDeps.push(dependency) - } - } else { - log(`"${dependency}" is up to date`) - } - } else { - log(`"${dependency}" is already installed`) - } - } - } - - const result: Result = new Map() - result.set(ManagementType.Install, installedDeps) - result.set(ManagementType.Update, updatedDeps) - - return result -} - -const dependencies = ['@tauri-apps/api', '@tauri-apps/cli'] - -async function install(): Promise { - return await manageDependencies(ManagementType.Install, dependencies) -} - -async function installThese(dependencies: string[]): Promise { - return await manageDependencies(ManagementType.Install, dependencies) -} - -async function installTheseDev(dependencies: string[]): Promise { - return await manageDependencies(ManagementType.InstallDev, dependencies) -} - -async function update(): Promise { - return await manageDependencies(ManagementType.Update, dependencies) -} - -export { install, installThese, installTheseDev, update } diff --git a/tooling/cli.js/src/api/dependency-manager/rust.ts b/tooling/cli.js/src/api/dependency-manager/rust.ts deleted file mode 100644 index eabd6b7a695f..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/rust.ts +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { ManagementType } from './types' -import { spawnSync } from '../../helpers/spawn' -import getScriptVersion from '../../helpers/get-script-version' -import { downloadRustup } from '../../helpers/download-binary' -import logger from '../../helpers/logger' -import { createWriteStream, unlinkSync, existsSync } from 'fs' -import { dirname, resolve } from 'path' -import { platform } from 'os' -import https from 'https' -import { fileURLToPath } from 'url' - -const currentDirName = dirname(fileURLToPath(import.meta.url)) -const log = logger('dependency:rust') - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -async function download(url: string, dest: string): Promise { - const file = createWriteStream(dest) - return await new Promise((resolve, reject) => { - https - .get(url, (response) => { - response.pipe(file) - file.on('finish', function () { - file.close() - resolve() - }) - }) - .on('error', function (err) { - unlinkSync(dest) - reject(err.message) - }) - }) -} - -async function installRustup(): Promise { - const assetName = - platform() === 'win32' ? 'rustup-init.exe' : 'rustup-init.sh' - const rustupPath = resolve(currentDirName, `../../bin/${assetName}`) - if (!existsSync(rustupPath)) { - await downloadRustup() - } - if (platform() === 'win32') { - return spawnSync('powershell', ['-NoProfile', rustupPath], process.cwd()) - } - return spawnSync('/bin/sh', [rustupPath], process.cwd()) -} - -async function manageDependencies( - managementType: ManagementType -): Promise { - if (getScriptVersion('rustup') === null) { - log('Installing rustup...') - await installRustup() - } - - if (managementType === ManagementType.Update) { - spawnSync('rustup', ['update'], process.cwd()) - } -} - -async function install(): Promise { - return await manageDependencies(ManagementType.Install) -} - -async function update(): Promise { - return await manageDependencies(ManagementType.Update) -} - -export { install, update } diff --git a/tooling/cli.js/src/api/dependency-manager/types.ts b/tooling/cli.js/src/api/dependency-manager/types.ts deleted file mode 100644 index 07f6e8bb4063..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -export enum ManagementType { - Install, - InstallDev, - Update -} - -export type Result = Map - -export interface Answer { - answer: boolean -} diff --git a/tooling/cli.js/src/api/dependency-manager/util.ts b/tooling/cli.js/src/api/dependency-manager/util.ts deleted file mode 100644 index 94ad57092538..000000000000 --- a/tooling/cli.js/src/api/dependency-manager/util.ts +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { sync as crossSpawnSync } from 'cross-spawn' -import { resolve as appResolve } from '../../helpers/app-paths' -import { existsSync } from 'fs' -// import semver from 'semver' -import { IManager, NpmManager, YarnManager, PnpmManager } from './managers' - -const getManager = (): IManager => { - if (existsSync(appResolve.app('yarn.lock'))) { - return new YarnManager() - } else if (existsSync(appResolve.app('pnpm-lock.yaml'))) { - return new PnpmManager() - } else { - return new NpmManager() - } -} - -function getCrateLatestVersion(crateName: string): string | null { - const child = crossSpawnSync('cargo', ['search', crateName, '--limit', '1']) - const output = String(child.output[1]) - // eslint-disable-next-line security/detect-non-literal-regexp - const matches = new RegExp(crateName + ' = "(\\S+)"', 'g').exec(output) - if (matches?.[1]) { - return matches[1] - } else { - return null - } -} - -function getNpmLatestVersion(packageName: string): string { - return getManager().getLatestVersion(packageName) -} - -function getNpmPackageVersion(packageName: string): string | null { - return getManager().getPackageVersion(packageName) -} - -function installNpmPackage(packageName: string): void { - return getManager().installPackage(packageName) -} - -function installNpmDevPackage(packageName: string): void { - return getManager().installDevPackage(packageName) -} - -function updateNpmPackage(packageName: string): void { - return getManager().updatePackage(packageName) -} - -function padVersion(version: string): string { - let count = (version.match(/\./g) ?? []).length - while (count < 2) { - count++ - version += '.0' - } - return version -} - -function semverLt(first: string, second: string): boolean { - return first !== second - // TODO: When version 1.0.0 is released this code should work again - // return semver.lt(padVersion(first), padVersion(second)) -} - -export { - getManager, - getCrateLatestVersion, - getNpmLatestVersion, - getNpmPackageVersion, - installNpmPackage, - installNpmDevPackage, - updateNpmPackage, - padVersion, - semverLt -} diff --git a/tooling/cli.js/src/api/tauricon.ts b/tooling/cli.js/src/api/tauricon.ts deleted file mode 100644 index 56dd1fdd18c2..000000000000 --- a/tooling/cli.js/src/api/tauricon.ts +++ /dev/null @@ -1,524 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -'use strict' - -/* eslint-disable @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call */ - -/** - * This is a module that takes an original image and resizes - * it to common icon sizes and will put them in a folder. - * It will retain transparency and can make special file - * types. You can control the settings. - * - * @module tauricon - * @exports tauricon - * @author Daniel Thompson-Yvetot - * @license MIT - */ - -import * as fsExtra from 'fs-extra' -import imagemin, { Plugin } from 'imagemin' -import optipng from 'imagemin-optipng' -import zopfli from 'imagemin-zopfli' -import isPng from 'is-png' -import path from 'path' -import * as png2icons from 'png2icons' -import readChunk from 'read-chunk' -import sharp from 'sharp' -import { appDir, tauriDir } from '../helpers/app-paths' -import logger from '../helpers/logger' -import * as settings from '../helpers/tauricon.config' -import chalk from 'chalk' -import { createRequire } from 'module' - -// @ts-expect-error -const { access, ensureDir, ensureFileSync, writeFileSync } = fsExtra.default - -const require = createRequire(import.meta.url) -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { version } = require('../../package.json') - -const log = logger('app:spawn') -const warn = logger('app:spawn', chalk.red) - -let image: boolean | sharp.Sharp = false -let spinnerInterval: NodeJS.Timeout | null = null - -const exists = async function (file: string | Buffer): Promise { - try { - await access(file) - return true - } catch (err) { - return false - } -} - -/** - * This is the first call that attempts to memoize the sharp(src). - * If the source image cannot be found or if it is not a png, it - * is a failsafe that will exit or throw. - * - * @param {string} src - a folder to target - * @exits {error} if not a png, if not an image - */ -const checkSrc = async (src: string): Promise => { - if (image !== false) { - return image - } else { - const srcExists = await exists(src) - if (!srcExists) { - image = false - if (spinnerInterval) clearInterval(spinnerInterval) - warn('[ERROR] Source image for tauricon not found') - process.exit(1) - } else { - const buffer = await readChunk(src, 0, 8) - if (isPng(buffer)) { - image = sharp(src) - const meta = await image.metadata() - if (!meta.hasAlpha || meta.channels !== 4) { - if (spinnerInterval) clearInterval(spinnerInterval) - warn('[ERROR] Source png for tauricon is not transparent') - process.exit(1) - } - - // just because PNG is sneaky, lets look at the - // individual pixels for something weird - const stats = await image.stats() - if (stats.isOpaque) { - if (spinnerInterval) clearInterval(spinnerInterval) - warn( - '[ERROR] Source png for tauricon could not be detected as transparent' - ) - process.exit(1) - } - - return image - } else { - image = false - if (spinnerInterval) clearInterval(spinnerInterval) - warn('[ERROR] Source image for tauricon is not a png') - process.exit(1) - } - } - } -} - -/** - * Sort the folders in the current job for unique folders. - * - * @param {object} options - a subset of the settings - * @returns {array} folders - */ -// TODO: proper type of options and folders -const uniqueFolders = (options: { [index: string]: any }): any[] => { - let folders = [] - for (const type in options) { - const option = options[String(type)] - if (option.folder) { - folders.push(option.folder) - } - } - // TODO: is compare argument required? - // eslint-disable-next-line @typescript-eslint/require-array-sort-compare - folders = folders.sort().filter((x, i, a) => !i || x !== a[i - 1]) - return folders -} - -/** - * Turn a hex color (like #212342) into r,g,b values - * - * @param {string} hex - hex colour - * @returns {array} r,g,b - */ -const hexToRgb = ( - hex: string -): { r: number; g: number; b: number } | undefined => { - // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i - hex = hex.replace( - shorthandRegex, - function (m: string, r: string, g: string, b: string) { - return r + r + g + g + b + b - } - ) - - const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) - return result - ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16) - } - : undefined -} - -/** - * validate image and directory - */ -const validate = async ( - src: string, - target: string -): Promise => { - if (target !== undefined) { - await ensureDir(target) - } - const res = await checkSrc(src) - return res -} - -// TODO: should take end param? -/** - * Log progress in the command line - * - * @param {boolean} end - */ -const progress = (msg: string): void => { - process.stdout.write(` ${msg} \r`) -} - -/** - * Create a spinner on the command line - * - * @example - * - * const spinnerInterval = spinner() - * // later - * clearInterval(spinnerInterval) - */ -const spinner = (): NodeJS.Timeout | null => { - if ('CI' in process.env || process.argv.some((arg) => arg === '--ci')) { - return null - } - return setInterval(() => { - process.stdout.write('/ \r') - setTimeout(() => { - process.stdout.write('- \r') - setTimeout(() => { - process.stdout.write('\\ \r') - setTimeout(() => { - process.stdout.write('| \r') - }, 100) - }, 100) - }, 100) - }, 500) -} - -const tauricon = { - validate: async function (src: string, target: string) { - await validate(src, target) - return typeof image === 'object' - }, - version: function () { - return version - }, - make: async function ( - src: string | undefined, - target: string = path.resolve(tauriDir, 'icons'), - strategy: string, - // TODO: proper type for options - options: { [index: string]: any } - ) { - if (!src) { - src = path.resolve(appDir, 'app-icon.png') - } - spinnerInterval = spinner() - options = options || settings.options.tauri - progress(`Building Tauri icns and ico from "${src}"`) - await this.validate(src, target) - await this.icns(src, target, options, strategy) - progress('Building Tauri png icons') - await this.build(src, target, options) - if (strategy) { - progress(`Minifying assets with ${strategy}`) - await this.minify(target, options, strategy, 'batch') - } else { - log('no minify strategy') - } - progress('Tauricon Finished') - if (spinnerInterval) clearInterval(spinnerInterval) - return true - }, - - /** - * Creates a set of images according to the subset of options it knows about. - * - * @param {string} src - image location - * @param {string} target - where to drop the images - * @param {object} options - js object that defines path and sizes - */ - build: async function ( - src: string, - target: string, - // TODO: proper type for options - options: { [index: string]: any } - ) { - await this.validate(src, target) - const sharpSrc = sharp(src) // creates the image object - const buildify2 = async function ( - pvar: [string, number, number] - ): Promise { - try { - const pngImage = sharpSrc.resize(pvar[1], pvar[1]) - if (pvar[2]) { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const rgb = hexToRgb(options.background_color) || { - r: undefined, - g: undefined, - b: undefined - } - pngImage.flatten({ - background: { r: rgb.r, g: rgb.g, b: rgb.b, alpha: 1 } - }) - } - pngImage.png() - await pngImage.toFile(pvar[0]) - } catch (err) { - warn(err) - } - } - - let output - const folders = uniqueFolders(options) - // eslint-disable-next-line @typescript-eslint/no-for-in-array - for (const n in folders) { - const folder = folders[Number(n)] - // make the folders first - // TODO: should this be ensureDirSync? - // eslint-disable-next-line @typescript-eslint/no-floating-promises - ensureDir(`${target}${path.sep}${folder}`) - } - for (const optionKey in options) { - const option = options[String(optionKey)] - // chain up the transforms - for (const sizeKey in option.sizes) { - const size = option.sizes[String(sizeKey)] - if (!option.splash) { - const dest = `${target}/${option.folder}` - if (option.infix === true) { - output = `${dest}${path.sep}${option.prefix}${size}x${size}${option.suffix}` - } else { - output = `${dest}${path.sep}${option.prefix}${option.suffix}` - } - const pvar: [string, number, number] = [ - output, - size, - option.background - ] - await buildify2(pvar) - } - } - } - }, - /** - * Creates a set of splash images (COMING SOON!!!) - * - * @param {string} src - icon location - * @param {string} splashSrc - splashscreen location - * @param {string} target - where to drop the images - * @param {object} options - js object that defines path and sizes - */ - splash: async function ( - src: string, - splashSrc: string, - target: string, - // TODO: proper type for options - options: { [index: string]: any } - ) { - let output - let block = false - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const rgb = hexToRgb(options.background_color) || { - r: undefined, - g: undefined, - b: undefined - } - - // three options - // options: splashscreen_type [generate | overlay | pure] - // - generate (icon + background color) DEFAULT - // - overlay (icon + splashscreen) - // - pure (only splashscreen) - - let sharpSrc - if (splashSrc === src) { - // prevent overlay or pure - block = true - } - if (block || options.splashscreen_type === 'generate') { - await this.validate(src, target) - if (!image) { - process.exit(1) - } - sharpSrc = sharp(src) - sharpSrc - .extend({ - top: 726, - bottom: 726, - left: 726, - right: 726, - background: { - r: rgb.r, - g: rgb.g, - b: rgb.b, - alpha: 1 - } - }) - .flatten({ background: { r: rgb.r, g: rgb.g, b: rgb.b, alpha: 1 } }) - } else if (options.splashscreen_type === 'overlay') { - sharpSrc = sharp(splashSrc) - .flatten({ background: { r: rgb.r, g: rgb.g, b: rgb.b, alpha: 1 } }) - .composite([ - { - input: src - // blend: 'multiply' <= future work, maybe just a gag - } - ]) - } else if (options.splashscreen_type === 'pure') { - sharpSrc = sharp(splashSrc).flatten({ - background: { r: rgb.r, g: rgb.g, b: rgb.b, alpha: 1 } - }) - } else { - throw new Error( - `unknown options.splashscreen_type: ${options.splashscreen_type}` - ) - } - const data = await sharpSrc.toBuffer() - - for (const optionKey in options) { - const option = options[String(optionKey)] - for (const sizeKey in option.sizes) { - const size = option.sizes[String(sizeKey)] - if (option.splash) { - const dest = `${target}${path.sep}${option.folder}` - await ensureDir(dest) - - if (option.infix === true) { - output = `${dest}${path.sep}${option.prefix}${size}x${size}${option.suffix}` - } else { - output = `${dest}${path.sep}${option.prefix}${option.suffix}` - } - const pvar = [output, size] - let sharpData = sharp(data) - sharpData = sharpData.resize(pvar[1][0], pvar[1][1]) - await sharpData.toFile(pvar[0]) - } - } - } - }, - - /** - * Minifies a set of images - * - * @param {string} target - image location - * @param {object} options - where to drop the images - * @param {string} strategy - which minify strategy to use - * @param {string} mode - singlefile or batch - */ - minify: async function ( - target: string, - // TODO: proper type for options - options: { [index: string]: any }, - strategy: string, - mode: string - ) { - let cmd: Plugin - const minify = settings.options.minify - if (!minify.available.find((x) => x === strategy)) { - strategy = minify.type - } - switch (strategy) { - case 'optipng': - cmd = optipng(minify.optipngOptions) - break - case 'zopfli': - cmd = zopfli(minify.zopfliOptions) - break - default: - throw new Error('unknown strategy' + strategy) - } - - const minifier = async (pvar: string[], cmd: Plugin): Promise => { - await imagemin([pvar[0]], { - destination: pvar[1], - plugins: [cmd] - }).catch((err) => { - warn(err) - }) - } - - switch (mode) { - case 'singlefile': - await minifier([target, path.dirname(target)], cmd) - break - case 'batch': - // eslint-disable-next-line no-case-declarations - const folders = uniqueFolders(options) - // eslint-disable-next-line @typescript-eslint/no-for-in-array - for (const n in folders) { - const folder = folders[Number(n)] - log('batch minify:' + String(folder)) - await minifier( - [ - `${target}${path.sep}${folder}${path.sep}*.png`, - `${target}${path.sep}${folder}` - ], - cmd - ) - } - break - default: - warn('[ERROR] Minify mode must be one of [ singlefile | batch]') - process.exit(1) - } - return 'minified' - }, - - /** - * Creates special icns and ico filetypes - * - * @param {string} src - image location - * @param {string} target - where to drop the images - * @param {object} options - * @param {string} strategy - */ - icns: async function ( - src: string, - target: string, - // TODO: proper type for options - options: { [index: string]: any }, - strategy: string - ) { - try { - if (!image) { - process.exit(1) - } - await this.validate(src, target) - - const sharpSrc = sharp(src) - const buf = await sharpSrc.toBuffer() - - const out = png2icons.createICNS(buf, png2icons.BICUBIC, 0) - if (out === null) { - throw new Error('Failed to create icon.icns') - } - ensureFileSync(path.join(target, '/icon.icns')) - writeFileSync(path.join(target, '/icon.icns'), out) - - const out2 = png2icons.createICO(buf, png2icons.BICUBIC, 0, true) - if (out2 === null) { - throw new Error('Failed to create icon.ico') - } - ensureFileSync(path.join(target, '/icon.ico')) - writeFileSync(path.join(target, '/icon.ico'), out2) - } catch (err) { - console.error(err) - throw err - } - } -} - -export default tauricon diff --git a/tooling/cli.js/src/helpers/app-paths.ts b/tooling/cli.js/src/helpers/app-paths.ts deleted file mode 100644 index d08d66132ec7..000000000000 --- a/tooling/cli.js/src/helpers/app-paths.ts +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { existsSync } from 'fs' -import { join, normalize, resolve, sep, isAbsolute } from 'path' -import logger from './logger' -import chalk from 'chalk' - -const warn = logger('tauri', chalk.red) - -function resolvePath(basePath: string, dir: string): string { - return dir && isAbsolute(dir) ? dir : resolve(basePath, dir) -} - -const getAppDir = (): string => { - let dir = process.env.__TAURI_TEST_APP_DIR ?? process.cwd() - let count = 0 - - // only go up three folders max - while (dir.length > 0 && !dir.endsWith(sep) && count <= 2) { - if (existsSync(join(dir, 'src-tauri', 'tauri.conf.json'))) { - return dir - } - count++ - dir = normalize(join(dir, '..')) - } - - warn("Couldn't recognize the current folder as a part of a Tauri project") - process.exit(1) -} - -const appDir = getAppDir() -const tauriDir = resolve(appDir, 'src-tauri') - -const resolveDir = { - app: (dir: string) => resolvePath(appDir, dir), - tauri: (dir: string) => resolvePath(tauriDir, dir) -} - -export { appDir, tauriDir, resolveDir as resolve } diff --git a/tooling/cli.js/src/helpers/download-binary.ts b/tooling/cli.js/src/helpers/download-binary.ts deleted file mode 100644 index 428c152045d6..000000000000 --- a/tooling/cli.js/src/helpers/download-binary.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { promisify } from 'util' -import stream from 'stream' -import fs from 'fs' -import path from 'path' -import { bootstrap } from 'global-agent' -import { fileURLToPath } from 'url' -import { createRequire } from 'module' - -// eslint-disable-next-line -declare let __RUST_CLI_VERSION__: string - -const currentDirName = path.dirname(fileURLToPath(import.meta.url)) - -const require = createRequire(import.meta.url) -/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires */ -const got = require('got') -/* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires */ - -// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -const pipeline = promisify(stream.pipeline) - -const downloads: { [url: string]: boolean } = {} - -async function downloadBinaryRelease( - tag: string, - asset: string, - outPath: string -): Promise { - const url = `https://github.com/tauri-apps/binary-releases/releases/download/${tag}/${asset}` - - const removeDownloadedCliIfNeeded = (): void => { - try { - if (!(url in downloads)) { - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.unlinkSync(outPath) - } - } finally { - process.exit() - } - } - - // on exit, we remove the `tauri-cli` file if the download didn't complete - process.on('exit', removeDownloadedCliIfNeeded) - process.on('SIGINT', removeDownloadedCliIfNeeded) - process.on('SIGTERM', removeDownloadedCliIfNeeded) - process.on('SIGHUP', removeDownloadedCliIfNeeded) - process.on('SIGBREAK', removeDownloadedCliIfNeeded) - - bootstrap({ - environmentVariableNamespace: '' - }) - - // TODO: Check hash of download - // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, security/detect-non-literal-fs-filename - await pipeline(got.stream(url), fs.createWriteStream(outPath)).catch( - (e: unknown) => { - try { - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.unlinkSync(outPath) - } catch {} - throw e - } - ) - // eslint-disable-next-line security/detect-object-injection - downloads[url] = true - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.chmodSync(outPath, 0o700) - console.log('Download Complete') -} - -async function downloadCli(): Promise { - let platform: string = process.platform - if (platform === 'win32') { - platform = 'windows' - } else if (platform === 'linux') { - platform = 'linux' - } else if (platform === 'darwin') { - platform = 'macos' - } else { - throw Error('Unsupported platform') - } - const extension = platform === 'windows' ? '.exe' : '' - const outPath = path.join(currentDirName, `../../bin/tauri-cli${extension}`) - console.log('Downloading Rust CLI...') - await downloadBinaryRelease( - `tauri-cli-v${__RUST_CLI_VERSION__}`, - `tauri-cli_${platform}${extension}`, - outPath - ) -} - -async function downloadRustup(): Promise { - const assetName = - process.platform === 'win32' ? 'rustup-init.exe' : 'rustup-init.sh' - console.log('Downloading Rustup...') - return await downloadBinaryRelease( - 'rustup', - assetName, - path.join(currentDirName, `../../bin/${assetName}`) - ) -} - -export { downloadCli, downloadRustup } diff --git a/tooling/cli.js/src/helpers/get-script-version.ts b/tooling/cli.js/src/helpers/get-script-version.ts deleted file mode 100644 index 85db818a9001..000000000000 --- a/tooling/cli.js/src/helpers/get-script-version.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { sync as spawn } from 'cross-spawn' - -export default function getVersion( - command: string, - args: string[] = [] -): string | null { - try { - const child = spawn(command, [...args, '--version']) - if (child.status === 0) { - const output = String(child.output[1]) - return output.replace(/\n/g, '') - } - return null - } catch (err) { - return null - } -} diff --git a/tooling/cli.js/src/helpers/logger.ts b/tooling/cli.js/src/helpers/logger.ts deleted file mode 100644 index 0df64b51774e..000000000000 --- a/tooling/cli.js/src/helpers/logger.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import chalk from 'chalk' -import ms from 'ms' - -let prevTime: number - -export default (banner: string, color: chalk.Chalk = chalk.green) => { - return (msg?: string) => { - const curr = +new Date() - const diff = curr - (prevTime || curr) - - prevTime = curr - - if (msg) { - console.log( - // TODO: proper typings for color and banner - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-call - ` ${color(String(banner))} ${msg} ${chalk.green(`+${ms(diff)}`)}` - ) - } else { - console.log() - } - } -} diff --git a/tooling/cli.js/src/helpers/non-webpack-require.ts b/tooling/cli.js/src/helpers/non-webpack-require.ts deleted file mode 100644 index bf698cb51f92..000000000000 --- a/tooling/cli.js/src/helpers/non-webpack-require.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -// this function has been moved to a module so we can mock it -export default (path: string): any => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return __non_webpack_require__(path) -} diff --git a/tooling/cli.js/src/helpers/rust-cli.ts b/tooling/cli.js/src/helpers/rust-cli.ts deleted file mode 100644 index 362e2a2fef5d..000000000000 --- a/tooling/cli.js/src/helpers/rust-cli.ts +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { existsSync } from 'fs' -import { resolve, join, dirname } from 'path' -import { spawnSync, spawn } from './spawn' -import { downloadCli } from './download-binary' -import { fileURLToPath } from 'url' - -// eslint-disable-next-line -declare let __RUST_CLI_VERSION__: string - -const currentDirName = dirname(fileURLToPath(import.meta.url)) - -export async function runOnRustCli( - command: string, - args: string[] -): Promise<{ pid: number; promise: Promise }> { - const targetPath = resolve(currentDirName, '../..') - const targetCliPath = join( - targetPath, - 'bin/tauri-cli' + (process.platform === 'win32' ? '.exe' : '') - ) - - let resolveCb: () => void - let rejectCb: () => void - let pid: number - const promise = new Promise((resolve, reject) => { - resolveCb = resolve - rejectCb = () => reject(new Error()) - }) - const onClose = (code: number, pid: number): void => { - if (code === 0) { - resolveCb() - } else { - rejectCb() - } - } - - if (existsSync(targetCliPath)) { - pid = spawn( - targetCliPath, - ['tauri', command, ...args], - process.cwd(), - onClose - ) - } else if (process.env.NODE_ENV === 'production') { - await downloadCli() - pid = spawn( - targetCliPath, - ['tauri', command, ...args], - process.cwd(), - onClose - ) - } else { - if (existsSync(resolve(targetPath, 'test'))) { - // running local CLI since test directory exists - const cliPath = resolve(targetPath, '../cli.rs') - spawnSync('cargo', ['build', '--release'], cliPath) - const localCliPath = resolve( - targetPath, - '../cli.rs/target/release/cargo-tauri' - ) - pid = spawn( - localCliPath, - ['tauri', command, ...args], - process.cwd(), - onClose - ) - } else { - spawnSync( - 'cargo', - [ - 'install', - '--root', - targetPath, - 'tauri-cli', - '--version', - __RUST_CLI_VERSION__ - ], - process.cwd() - ) - pid = spawn( - targetCliPath, - ['tauri', command, ...args], - process.cwd(), - onClose - ) - } - } - - return { pid, promise } -} diff --git a/tooling/cli.js/src/helpers/spawn.ts b/tooling/cli.js/src/helpers/spawn.ts deleted file mode 100644 index 5758587a41d7..000000000000 --- a/tooling/cli.js/src/helpers/spawn.ts +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import crossSpawn from 'cross-spawn' -import logger from './logger' -import chalk from 'chalk' - -const log = logger('app:spawn') -const warn = logger('app:spawn', chalk.red) - -/* - Returns pid, takes onClose - */ -export const spawn = ( - cmd: string, - params: string[], - cwd: string, - onClose?: (code: number, pid: number) => void -): number => { - log(`Running "${cmd} ${params.join(' ')}"`) - log() - - // TODO: move to execa? - const runner = crossSpawn(cmd, params, { - stdio: 'inherit', - cwd, - env: process.env - }) - - runner.on('close', (code) => { - log() - if (code) { - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - log(`Command "${cmd}" failed with exit code: ${code}`) - } - - // eslint-disable-next-line @typescript-eslint/prefer-optional-chain - onClose && onClose(code ?? 0, runner.pid ?? 0) - }) - - return runner.pid ?? 0 -} - -/* - Returns nothing, takes onFail - */ -export const spawnSync = ( - cmd: string, - params: string[], - cwd: string, - onFail?: () => void -): void => { - log(`[sync] Running "${cmd} ${params.join(' ')}"`) - log() - - const runner = crossSpawn.sync(cmd, params, { - stdio: 'inherit', - cwd - }) - - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - if (runner.status || runner.error) { - warn() - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - warn(`⚠️ Command "${cmd}" failed with exit code: ${runner.status}`) - if (runner.status === null) { - warn(`⚠️ Please globally install "${cmd}"`) - } - // eslint-disable-next-line @typescript-eslint/prefer-optional-chain - onFail && onFail() - process.exit(1) - } -} diff --git a/tooling/cli.js/src/helpers/tauricon.config.ts b/tooling/cli.js/src/helpers/tauricon.config.ts deleted file mode 100644 index 5bd0fa23baf9..000000000000 --- a/tooling/cli.js/src/helpers/tauricon.config.ts +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -export const options = { - // folder determines in which path to drop the generated file - // prefix is the first part of the generated file's name - // infix adds e.g. '44x44' based on the size in sizes to the generated file's name - // suffix adds a file-ending to the generated file's name - // sizes determines the pixel width and height to use - background_color: '#000074', - theme_color: '#02aa9b', - sharp: 'kernel: sharp.kernel.lanczos3', // one of [nearest|cubic|lanczos2|lanczos3] - minify: { - batch: false, - overwrite: true, - available: ['optipng', 'zopfli'], - type: 'optipng', - optipngOptions: { - optimizationLevel: 4, - paletteReduction: true - }, - zopfliOptions: { - transparent: true, - more: true - } - }, - splash_type: 'generate', - tauri: { - linux: { - folder: '.', - prefix: '', - infix: true, - suffix: '.png', - sizes: [32, 128] - }, - linux_2x: { - folder: '.', - prefix: '128x128@2x', - infix: false, - suffix: '.png', - sizes: [256] - }, - defaults: { - folder: '.', - prefix: 'icon', - infix: false, - suffix: '.png', - sizes: [512] - }, - appx_logo: { - folder: '.', - prefix: 'StoreLogo', - infix: false, - suffix: '.png', - sizes: [50] - }, - appx_square: { - folder: '.', - prefix: 'Square', - infix: true, - suffix: 'Logo.png', - sizes: [30, 44, 71, 89, 107, 142, 150, 284, 310] - } - // todo: look at capacitor and cordova for insight into what icons - // we need for those distribution targets - } -} diff --git a/tooling/cli.js/src/types/cargo.ts b/tooling/cli.js/src/types/cargo.ts deleted file mode 100644 index 5f9e7e3514dc..000000000000 --- a/tooling/cli.js/src/types/cargo.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -export interface CargoManifest { - dependencies: { [k: string]: string | CargoManifestDependency } - package: { version: string; name: string; 'default-run': string } - bin: Array<{ - name: string - path: string - }> -} - -export interface CargoManifestDependency { - version?: string - path?: string - features?: string[] -} - -export interface CargoLock { - package: [CargoLockPackage] -} - -export interface CargoLockPackage { - name: string - version: string -} diff --git a/tooling/cli.js/src/types/modules.d.ts b/tooling/cli.js/src/types/modules.d.ts deleted file mode 100644 index 242d7dc6438b..000000000000 --- a/tooling/cli.js/src/types/modules.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -declare module 'imagemin-zopfli' - -// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars -declare const __non_webpack_require__: Function diff --git a/tooling/cli.js/test/jest/__tests__/build.spec.js b/tooling/cli.js/test/jest/__tests__/build.spec.js deleted file mode 100644 index 5b8aa49a82d5..000000000000 --- a/tooling/cli.js/test/jest/__tests__/build.spec.js +++ /dev/null @@ -1,87 +0,0 @@ -import path from 'path' -import * as fixtureSetup from '../fixtures/app-test-setup.js' -import { spawn } from 'helpers/spawn' - -const appDir = path.join(fixtureSetup.fixtureDir, 'app') -const distDir = path.join(appDir, 'dist') - -function runBuildTest(args) { - fixtureSetup.initJest('app') - console.log(2) - return new Promise(async (resolve, reject) => { - try { - let success = false - const { server, responses } = fixtureSetup.startServer(() => { - success = true - try { - process.kill(appPid) - } catch {} - // wait for the app process to be killed - setTimeout(resolve, 2000) - }) - process.chdir(appDir) - const { build } = await import('dist/api/cli') - const { promise } = await build(args) - await promise - - const artifactFolder = args.debug ? 'debug' : 'release' - const artifactPath = path.resolve( - appDir, - `src-tauri/target/${artifactFolder}/app` - ) - - const appPid = spawn( - process.platform === 'win32' - ? `${artifactPath}.exe` - : artifactPath.replace( - `${artifactFolder}/app`, - `${artifactFolder}/./app` - ), - [], - null - ) - - setTimeout(() => { - if (!success) { - server.close(() => { - try { - process.kill(appPid) - } catch {} - const failedCommands = Object.keys(responses) - .filter((k) => responses[k] === null) - .join(', ') - reject("App didn't reply to " + failedCommands) - }) - } - }, 15000) - } catch (error) { - reject(error) - } - }) -} - -describe('Tauri Build', () => { - const build = { - devPath: distDir, - distDir: distDir, - withGlobalTauri: true - } - - it.each` - mode | flag - ${'custom-protocol'} | ${'debug'} - ${'custom-protocol'} | ${'release'} - `('works with the $mode $flag mode', ({ mode, flag }) => { - return runBuildTest({ - debug: flag === 'debug', - config: { - build, - tauri: { - allowlist: { - all: true - } - } - } - }) - }) -}) diff --git a/tooling/cli.js/test/jest/__tests__/dev.spec.js b/tooling/cli.js/test/jest/__tests__/dev.spec.js deleted file mode 100644 index af45bf5cd2e8..000000000000 --- a/tooling/cli.js/test/jest/__tests__/dev.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -import path from 'path' -import isRunning from 'is-running' -import http from 'http' -import { statSync, createReadStream } from 'fs' -import * as fixtureSetup from '../fixtures/app-test-setup.js' -const distDir = path.resolve(fixtureSetup.fixtureDir, 'app', 'dist') - -function startDevServer() { - const app = http.createServer((req, res) => { - if (req.method === 'GET') { - if (req.url === '/') { - const indexPath = path.join(distDir, 'index.html') - const stat = statSync(indexPath) - res.writeHead(200, { - 'Content-Type': 'text/html', - 'Content-Length': stat.size - }) - createReadStream(indexPath).pipe(res) - } - } - }) - - const port = 7001 - - const server = app.listen(port) - return { - server, - url: `http://localhost:${port}` - } -} - -function runDevTest(tauriConfig) { - fixtureSetup.initJest('app') - return new Promise(async (resolve, reject) => { - try { - process.chdir(path.join(fixtureSetup.fixtureDir, 'app')) - const { dev } = await import('dist/api/cli') - const { promise, pid } = await dev({ config: tauriConfig }) - - let success = false - const checkIntervalId = setInterval(async () => { - if (!isRunning(pid) && !success) { - const failedCommands = Object.keys(responses) - .filter((k) => responses[k] === null) - .join(', ') - server.close(() => reject("App didn't reply to " + failedCommands)) - } - }, 2000) - - const { server, responses } = fixtureSetup.startServer(async () => { - success = true - clearInterval(checkIntervalId) - // wait for the app process to be killed - setTimeout(async () => { - try { - process.kill(pid) - } catch {} - resolve() - }, 2000) - }) - await promise - } catch (error) { - reject(error) - } - }) -} - -describe('Tauri Dev', () => { - const build = { - distDir: distDir, - withGlobalTauri: true - } - - const devServer = startDevServer() - - it.each` - url - ${devServer.url} - ${distDir} - `('works with dev pointing to $url', ({ url }) => { - const runningDevServer = url.startsWith('http') - const promise = runDevTest({ - build: { - ...build, - devPath: url - } - }) - - promise.then(() => { - if (runningDevServer) { - devServer.server.close() - } - }) - - return promise - }) -}) diff --git a/tooling/cli.js/test/jest/__tests__/tauri.spec.js b/tooling/cli.js/test/jest/__tests__/tauri.spec.js deleted file mode 100644 index ba23af21a3f1..000000000000 --- a/tooling/cli.js/test/jest/__tests__/tauri.spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import { jest } from '@jest/globals' -import tauri from 'bin/tauri' -import { createRequire } from 'module' -const require = createRequire(import.meta.url) - -const { version } = require('../../../package.json') - -describe('[CLI] cli.js', () => { - it('displays a help message', async () => { - jest.spyOn(console, 'log') - jest.spyOn(process, 'exit').mockImplementation(() => true) - tauri('help') - console.log(process.exit.mock.calls[0][0]) - expect(process.exit.mock.calls[0][0]).toBe(0) - expect(!!console.log.mock.calls[0][0]).toBe(true) - tauri('--help') - expect(!!console.log.mock.calls[2][0]).toBe(true) - tauri('-h') - expect(!!console.log.mock.calls[3][0]).toBe(true) - tauri(['help']) - expect(!!console.log.mock.calls[4][0]).toBe(true) - jest.clearAllMocks() - }) - - it('gets you help', async () => { - jest.spyOn(console, 'log') - const tests = ['--help', '-h'] - for (const test of tests) { - tauri([test]) - expect(!!console.log.mock.calls[0][0]).toBe(true) - jest.clearAllMocks() - } - }) - it('gets you version', async () => { - jest.spyOn(console, 'log') - const tests = ['--version', '-v'] - for (const test of tests) { - tauri([test]) - expect(console.log.mock.calls[0][0]).toBe(version) - jest.clearAllMocks() - } - }) -}) diff --git a/tooling/cli.js/test/jest/__tests__/tauricon.spec.js b/tooling/cli.js/test/jest/__tests__/tauricon.spec.js deleted file mode 100644 index 8cee5bf62ec7..000000000000 --- a/tooling/cli.js/test/jest/__tests__/tauricon.spec.js +++ /dev/null @@ -1,54 +0,0 @@ -import * as appTestSetup from '../fixtures/app-test-setup.js' -appTestSetup.initJest('app') - -describe('[CLI] tauri-icon internals', () => { - it('tells you the version', async () => { - const tauricon = (await import('api/tauricon')).default - const version = tauricon.version() - expect(!!version).toBe(true) - }) -}) - -describe('[CLI] tauri-icon builder', () => { - it('will still use default compression if missing compression chosen', async () => { - const tauricon = (await import('api/tauricon')).default - const valid = await tauricon.make( - 'test/jest/fixtures/tauri-logo.png', - 'test/jest/tmp/missing', - 'missing' - ) - expect(valid).toBe(true) - }) - - it('will not validate a non-file', async () => { - try { - const tauricon = (await import('api/tauricon')).default - await tauricon.make( - 'test/jest/fixtures/tauri-foo-not-found.png', - 'test/jest/tmp/optipng', - 'optipng' - ) - } catch (e) { - expect(e.message).toBe('Input file is missing') - } - }) - - it('makes a set of icons with optipng', async () => { - const tauricon = (await import('api/tauricon')).default - const valid = await tauricon.make( - 'test/jest/fixtures/tauri-logo.png', - 'test/jest/tmp/optipng', - 'optipng' - ) - expect(valid).toBe(true) - }) - - /* - TURNED OFF BECAUSE IT TAKES FOREVER - it('makes a set of icons with zopfli', async () => { - jest.setTimeout(120000) - const valid = await tauricon.make('test/jest/fixtures/tauri-logo.png', 'test/jest/tmp/zopfli', 'zopfli') - expect(valid).toBe(true) - }) - */ -}) diff --git a/tooling/cli.js/test/jest/__tests__/template.spec.js b/tooling/cli.js/test/jest/__tests__/template.spec.js deleted file mode 100644 index c05d87c1ddfb..000000000000 --- a/tooling/cli.js/test/jest/__tests__/template.spec.js +++ /dev/null @@ -1,37 +0,0 @@ -import * as fixtureSetup from '../fixtures/app-test-setup.js' -import { resolve, dirname } from 'path' -import { writeFileSync, readFileSync } from 'fs' -import { init, build } from 'dist/api/cli' -import { fileURLToPath } from 'url' - -const currentDirName = dirname(fileURLToPath(import.meta.url)) - -describe('[CLI] cli.js template', () => { - it('init a project and builds it', async () => { - const cwd = process.cwd() - const fixturePath = resolve(currentDirName, '../fixtures/empty') - const tauriFixturePath = resolve(fixturePath, 'src-tauri') - - fixtureSetup.initJest('empty') - - process.chdir(fixturePath) - - const { promise } = await init({ - directory: process.cwd(), - force: true, - tauriPath: resolve(currentDirName, '../../../../..'), - ci: true - }) - await promise - - process.chdir(tauriFixturePath) - - const manifestPath = resolve(tauriFixturePath, 'Cargo.toml') - const manifestFile = readFileSync(manifestPath).toString() - writeFileSync(manifestPath, `workspace = { }\n${manifestFile}`) - - const { promise: buildPromise } = await build() - await buildPromise - process.chdir(cwd) - }) -}) diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/.gitignore b/tooling/cli.js/test/jest/fixtures/app/src-tauri/.gitignore deleted file mode 100644 index 088ba6ba7d34..000000000000 --- a/tooling/cli.js/test/jest/fixtures/app/src-tauri/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - -# These are backup files generated by rustfmt -**/*.rs.bk diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/Cargo.toml b/tooling/cli.js/test/jest/fixtures/app/src-tauri/Cargo.toml deleted file mode 100644 index 12f4a0afed25..000000000000 --- a/tooling/cli.js/test/jest/fixtures/app/src-tauri/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -workspace = { } - -[package] -name = "app" -version = "0.1.0" -description = "A Tauri App" -authors = [ "Tauri Programme within The Commons Conservancy" ] -license = "" -repository = "" -edition = "2018" - -[package.metadata.bundle] -identifier = "com.tauri.dev" -icon = [ - "icons/32x32.png", - "icons/128x128.png", - "icons/128x128@2x.png", - "icons/icon.icns", - "icons/icon.ico" -] - -[build-dependencies] -tauri-build = { path = "../../../../../../../core/tauri-build" } - -[dependencies] -serde_json = "1.0.66" -serde = "1.0" -serde_derive = "1.0" -tauri = { path = "../../../../../../../core/tauri", features = ["api-all"] } - -[features] -default = [ "custom-protocol" ] -custom-protocol = [ "tauri/custom-protocol" ] diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/icon.icns b/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/icon.icns deleted file mode 100644 index 43c73bda9674..000000000000 Binary files a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/icon.icns and /dev/null differ diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/rustfmt.toml b/tooling/cli.js/test/jest/fixtures/app/src-tauri/rustfmt.toml deleted file mode 100644 index 136f5f330967..000000000000 --- a/tooling/cli.js/test/jest/fixtures/app/src-tauri/rustfmt.toml +++ /dev/null @@ -1,14 +0,0 @@ -max_width = 100 -hard_tabs = false -tab_spaces = 2 -newline_style = "Auto" -use_small_heuristics = "Default" -reorder_imports = true -reorder_modules = true -remove_nested_parens = true -edition = "2018" -merge_derives = true -use_try_shorthand = false -use_field_init_shorthand = false -force_explicit_abi = true -imports_granularity = "Crate" diff --git a/tooling/cli.js/test/jest/fixtures/no-alpha.png b/tooling/cli.js/test/jest/fixtures/no-alpha.png deleted file mode 100644 index 99089dce58d7..000000000000 Binary files a/tooling/cli.js/test/jest/fixtures/no-alpha.png and /dev/null differ diff --git a/tooling/cli.js/test/jest/fixtures/notAMeme.jpg b/tooling/cli.js/test/jest/fixtures/notAMeme.jpg deleted file mode 100644 index 73eef8efa382..000000000000 Binary files a/tooling/cli.js/test/jest/fixtures/notAMeme.jpg and /dev/null differ diff --git a/tooling/cli.js/test/jest/fixtures/tauri-logo.png b/tooling/cli.js/test/jest/fixtures/tauri-logo.png deleted file mode 100644 index ef2a894550b7..000000000000 Binary files a/tooling/cli.js/test/jest/fixtures/tauri-logo.png and /dev/null differ diff --git a/tooling/cli.js/test/jest/jest.setup.js b/tooling/cli.js/test/jest/jest.setup.js deleted file mode 100644 index c2ccf0585051..000000000000 --- a/tooling/cli.js/test/jest/jest.setup.js +++ /dev/null @@ -1,7 +0,0 @@ -import { jest } from '@jest/globals' - -jest.setTimeout(1200000) - -setTimeout(() => { - // do nothing -}, 1) diff --git a/tooling/cli.js/tsconfig.json b/tooling/cli.js/tsconfig.json deleted file mode 100644 index 23b2dd444451..000000000000 --- a/tooling/cli.js/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "outDir": "./dist/", - "strict": true, - "module": "es2020", - "target": "es5", - "allowJs": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "moduleResolution": "node", - "baseUrl": ".", - "paths": { - "types": ["src/types"] - } - }, - "include": ["src", "api-src"] -} diff --git a/tooling/cli.js/yarn.lock b/tooling/cli.js/yarn.lock deleted file mode 100644 index 3c61c54ede88..000000000000 --- a/tooling/cli.js/yarn.lock +++ /dev/null @@ -1,7480 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.5.tgz#8ef4c18e58e801c5c95d3c1c0f2874a2680fadea" - integrity sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w== - -"@babel/compat-data@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" - integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw== - -"@babel/compat-data@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" - integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== - -"@babel/core@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.0.tgz#749e57c68778b73ad8082775561f67f5196aafa8" - integrity sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.0" - "@babel/helper-compilation-targets" "^7.15.0" - "@babel/helper-module-transforms" "^7.15.0" - "@babel/helpers" "^7.14.8" - "@babel/parser" "^7.15.0" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.1.2" - semver "^6.3.0" - source-map "^0.5.0" - -"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab" - integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.5" - "@babel/helper-compilation-targets" "^7.14.5" - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helpers" "^7.14.6" - "@babel/parser" "^7.14.6" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.1.2" - semver "^6.3.0" - source-map "^0.5.0" - -"@babel/generator@^7.14.5", "@babel/generator@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" - integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== - dependencies: - "@babel/types" "^7.14.5" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/generator@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.8.tgz#bf86fd6af96cf3b74395a8ca409515f89423e070" - integrity sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg== - dependencies: - "@babel/types" "^7.14.8" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/generator@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15" - integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ== - dependencies: - "@babel/types" "^7.15.0" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" - integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz#b939b43f8c37765443a19ae74ad8b15978e0a191" - integrity sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" - integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== - dependencies: - "@babel/compat-data" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.16.6" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818" - integrity sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A== - dependencies: - "@babel/compat-data" "^7.15.0" - "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.16.6" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.14.5": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz#f114469b6c06f8b5c59c6c4e74621f5085362542" - integrity sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-member-expression-to-functions" "^7.14.5" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - -"@babel/helper-create-class-features-plugin@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz#c9a137a4d137b2d0e2c649acf536d7ba1a76c0f7" - integrity sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-member-expression-to-functions" "^7.15.0" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/helper-replace-supers" "^7.15.0" - "@babel/helper-split-export-declaration" "^7.14.5" - -"@babel/helper-create-regexp-features-plugin@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz#c7d5ac5e9cf621c26057722fb7a8a4c5889358c4" - integrity sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - regexpu-core "^4.7.1" - -"@babel/helper-define-polyfill-provider@^0.2.2": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" - integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew== - dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - -"@babel/helper-explode-assignable-expression@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz#8aa72e708205c7bb643e45c73b4386cdf2a1f645" - integrity sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-function-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" - integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== - dependencies: - "@babel/helper-get-function-arity" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-get-function-arity@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" - integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-hoist-variables@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" - integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-member-expression-to-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.5.tgz#d5c70e4ad13b402c95156c7a53568f504e2fb7b8" - integrity sha512-UxUeEYPrqH1Q/k0yRku1JE7dyfyehNwT6SVkMHvYvPDv4+uu627VXBckVj891BO8ruKBkiDoGnZf4qPDD8abDQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-member-expression-to-functions@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b" - integrity sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg== - dependencies: - "@babel/types" "^7.15.0" - -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" - integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-module-transforms@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz#7de42f10d789b423eb902ebd24031ca77cb1e10e" - integrity sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA== - dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - "@babel/helper-simple-access" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-module-transforms@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08" - integrity sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg== - dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-replace-supers" "^7.15.0" - "@babel/helper-simple-access" "^7.14.8" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.9" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" - -"@babel/helper-optimise-call-expression@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" - integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" - integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== - -"@babel/helper-remap-async-to-generator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz#51439c913612958f54a987a4ffc9ee587a2045d6" - integrity sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-wrap-function" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-replace-supers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94" - integrity sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.14.5" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-replace-supers@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz#ace07708f5bf746bf2e6ba99572cce79b5d4e7f4" - integrity sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.15.0" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/traverse" "^7.15.0" - "@babel/types" "^7.15.0" - -"@babel/helper-simple-access@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4" - integrity sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-simple-access@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz#82e1fec0644a7e775c74d305f212c39f8fe73924" - integrity sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg== - dependencies: - "@babel/types" "^7.14.8" - -"@babel/helper-skip-transparent-expression-wrappers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz#96f486ac050ca9f44b009fbe5b7d394cab3a0ee4" - integrity sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-split-export-declaration@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" - integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-validator-identifier@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" - integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== - -"@babel/helper-validator-identifier@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz#32be33a756f29e278a0d644fa08a2c9e0f88a34c" - integrity sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow== - -"@babel/helper-validator-identifier@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" - integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== - -"@babel/helper-validator-option@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" - integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== - -"@babel/helper-wrap-function@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz#5919d115bf0fe328b8a5d63bcb610f51601f2bff" - integrity sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ== - dependencies: - "@babel/helper-function-name" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helpers@^7.14.6": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.6.tgz#5b58306b95f1b47e2a0199434fa8658fa6c21635" - integrity sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA== - dependencies: - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helpers@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.8.tgz#839f88f463025886cff7f85a35297007e2da1b77" - integrity sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw== - dependencies: - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.8" - "@babel/types" "^7.14.8" - -"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.7.2": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.6.tgz#d85cc68ca3cac84eae384c06f032921f5227f4b2" - integrity sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ== - -"@babel/parser@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.8.tgz#66fd41666b2d7b840bd5ace7f7416d5ac60208d4" - integrity sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA== - -"@babel/parser@^7.15.0": - version "7.15.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.2.tgz#08d4ffcf90d211bf77e7cc7154c6f02d468d2b1d" - integrity sha512-bMJXql1Ss8lFnvr11TZDH4ArtwlAS5NG9qBmdiFW2UHHm6MVoR+GDc5XE2b9K938cyjc9O6/+vjjcffLDtfuDg== - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e" - integrity sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" - "@babel/plugin-proposal-optional-chaining" "^7.14.5" - -"@babel/plugin-proposal-async-generator-functions@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz#7028dc4fa21dc199bbacf98b39bab1267d0eaf9a" - integrity sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.14.5" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz#40d1ee140c5b1e31a350f4f5eed945096559b42e" - integrity sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-proposal-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz#158e9e10d449c3849ef3ecde94a03d9f1841b681" - integrity sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-dynamic-import@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz#0c6617df461c0c1f8fff3b47cd59772360101d2c" - integrity sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz#dbad244310ce6ccd083072167d8cea83a52faf76" - integrity sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz#38de60db362e83a3d8c944ac858ddf9f0c2239eb" - integrity sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz#6e6229c2a99b02ab2915f82571e0cc646a40c738" - integrity sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz#ee38589ce00e2cc59b299ec3ea406fcd3a0fdaf6" - integrity sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz#83631bf33d9a51df184c2102a069ac0c58c05f18" - integrity sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363" - integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g== - dependencies: - "@babel/compat-data" "^7.14.7" - "@babel/helper-compilation-targets" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.14.5" - -"@babel/plugin-proposal-optional-catch-binding@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz#939dd6eddeff3a67fdf7b3f044b5347262598c3c" - integrity sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz#fa83651e60a360e3f13797eef00b8d519695b603" - integrity sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz#37446495996b2945f30f5be5b60d5e2aa4f5792d" - integrity sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-proposal-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz#9f65a4d0493a940b4c01f8aa9d3f1894a587f636" - integrity sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.14.5", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz#0f95ee0e757a5d647f378daa0eca7e93faa8bbe8" - integrity sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.14.5", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" - integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-arrow-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz#f7187d9588a768dd080bf4c9ffe117ea62f7862a" - integrity sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-async-to-generator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz#72c789084d8f2094acb945633943ef8443d39e67" - integrity sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA== - dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.14.5" - -"@babel/plugin-transform-block-scoped-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz#e48641d999d4bc157a67ef336aeb54bc44fd3ad4" - integrity sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-block-scoping@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz#8cc63e61e50f42e078e6f09be775a75f23ef9939" - integrity sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-classes@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz#2a391ffb1e5292710b00f2e2c210e1435e7d449f" - integrity sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz#1b9d78987420d11223d41195461cc43b974b204f" - integrity sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-destructuring@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576" - integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-dotall-regex@^7.14.5", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz#2f6bf76e46bdf8043b4e7e16cf24532629ba0c7a" - integrity sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-duplicate-keys@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz#365a4844881bdf1501e3a9f0270e7f0f91177954" - integrity sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-exponentiation-operator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz#5154b8dd6a3dfe6d90923d61724bd3deeb90b493" - integrity sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-for-of@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz#dae384613de8f77c196a8869cbf602a44f7fc0eb" - integrity sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-function-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz#e81c65ecb900746d7f31802f6bed1f52d915d6f2" - integrity sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ== - dependencies: - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz#41d06c7ff5d4d09e3cf4587bd3ecf3930c730f78" - integrity sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-member-expression-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz#b39cd5212a2bf235a617d320ec2b48bcc091b8a7" - integrity sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-modules-amd@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz#4fd9ce7e3411cb8b83848480b7041d83004858f7" - integrity sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g== - dependencies: - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-commonjs@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz#3305896e5835f953b5cdb363acd9e8c2219a5281" - integrity sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig== - dependencies: - "@babel/helper-module-transforms" "^7.15.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-simple-access" "^7.14.8" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-systemjs@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz#c75342ef8b30dcde4295d3401aae24e65638ed29" - integrity sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA== - dependencies: - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.5" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-umd@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz#fb662dfee697cce274a7cda525190a79096aa6e0" - integrity sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA== - dependencies: - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz#c68f5c5d12d2ebaba3762e57c2c4f6347a46e7b2" - integrity sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" - -"@babel/plugin-transform-new-target@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz#31bdae8b925dc84076ebfcd2a9940143aed7dbf8" - integrity sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-object-super@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz#d0b5faeac9e98597a161a9cf78c527ed934cdc45" - integrity sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - -"@babel/plugin-transform-parameters@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz#49662e86a1f3ddccac6363a7dfb1ff0a158afeb3" - integrity sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-property-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz#0ddbaa1f83db3606f1cdf4846fa1dfb473458b34" - integrity sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-regenerator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz#9676fd5707ed28f522727c5b3c0aa8544440b04f" - integrity sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg== - dependencies: - regenerator-transform "^0.14.2" - -"@babel/plugin-transform-reserved-words@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz#c44589b661cfdbef8d4300dcc7469dffa92f8304" - integrity sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-shorthand-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz#97f13855f1409338d8cadcbaca670ad79e091a58" - integrity sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-spread@^7.14.6": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz#6bd40e57fe7de94aa904851963b5616652f73144" - integrity sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" - -"@babel/plugin-transform-sticky-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz#5b617542675e8b7761294381f3c28c633f40aeb9" - integrity sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-template-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz#a5f2bc233937d8453885dc736bdd8d9ffabf3d93" - integrity sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-typeof-symbol@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz#39af2739e989a2bd291bf6b53f16981423d457d4" - integrity sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-typescript@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.0.tgz#553f230b9d5385018716586fc48db10dd228eb7e" - integrity sha512-WIIEazmngMEEHDaPTx0IZY48SaAmjVWe3TRSX7cmJXn0bEv9midFzAjxiruOWYIVf5iQ10vFx7ASDpgEO08L5w== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.15.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-typescript" "^7.14.5" - -"@babel/plugin-transform-unicode-escapes@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz#9d4bd2a681e3c5d7acf4f57fa9e51175d91d0c6b" - integrity sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-transform-unicode-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz#4cd09b6c8425dd81255c7ceb3fb1836e7414382e" - integrity sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/preset-env@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.0.tgz#e2165bf16594c9c05e52517a194bf6187d6fe464" - integrity sha512-FhEpCNFCcWW3iZLg0L2NPE9UerdtsCR6ZcsGHUX6Om6kbCQeL5QZDqFDmeNHC6/fy6UH3jEge7K4qG5uC9In0Q== - dependencies: - "@babel/compat-data" "^7.15.0" - "@babel/helper-compilation-targets" "^7.15.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-async-generator-functions" "^7.14.9" - "@babel/plugin-proposal-class-properties" "^7.14.5" - "@babel/plugin-proposal-class-static-block" "^7.14.5" - "@babel/plugin-proposal-dynamic-import" "^7.14.5" - "@babel/plugin-proposal-export-namespace-from" "^7.14.5" - "@babel/plugin-proposal-json-strings" "^7.14.5" - "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" - "@babel/plugin-proposal-numeric-separator" "^7.14.5" - "@babel/plugin-proposal-object-rest-spread" "^7.14.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" - "@babel/plugin-proposal-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-private-methods" "^7.14.5" - "@babel/plugin-proposal-private-property-in-object" "^7.14.5" - "@babel/plugin-proposal-unicode-property-regex" "^7.14.5" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.14.5" - "@babel/plugin-transform-async-to-generator" "^7.14.5" - "@babel/plugin-transform-block-scoped-functions" "^7.14.5" - "@babel/plugin-transform-block-scoping" "^7.14.5" - "@babel/plugin-transform-classes" "^7.14.9" - "@babel/plugin-transform-computed-properties" "^7.14.5" - "@babel/plugin-transform-destructuring" "^7.14.7" - "@babel/plugin-transform-dotall-regex" "^7.14.5" - "@babel/plugin-transform-duplicate-keys" "^7.14.5" - "@babel/plugin-transform-exponentiation-operator" "^7.14.5" - "@babel/plugin-transform-for-of" "^7.14.5" - "@babel/plugin-transform-function-name" "^7.14.5" - "@babel/plugin-transform-literals" "^7.14.5" - "@babel/plugin-transform-member-expression-literals" "^7.14.5" - "@babel/plugin-transform-modules-amd" "^7.14.5" - "@babel/plugin-transform-modules-commonjs" "^7.15.0" - "@babel/plugin-transform-modules-systemjs" "^7.14.5" - "@babel/plugin-transform-modules-umd" "^7.14.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.9" - "@babel/plugin-transform-new-target" "^7.14.5" - "@babel/plugin-transform-object-super" "^7.14.5" - "@babel/plugin-transform-parameters" "^7.14.5" - "@babel/plugin-transform-property-literals" "^7.14.5" - "@babel/plugin-transform-regenerator" "^7.14.5" - "@babel/plugin-transform-reserved-words" "^7.14.5" - "@babel/plugin-transform-shorthand-properties" "^7.14.5" - "@babel/plugin-transform-spread" "^7.14.6" - "@babel/plugin-transform-sticky-regex" "^7.14.5" - "@babel/plugin-transform-template-literals" "^7.14.5" - "@babel/plugin-transform-typeof-symbol" "^7.14.5" - "@babel/plugin-transform-unicode-escapes" "^7.14.5" - "@babel/plugin-transform-unicode-regex" "^7.14.5" - "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.15.0" - babel-plugin-polyfill-corejs2 "^0.2.2" - babel-plugin-polyfill-corejs3 "^0.2.2" - babel-plugin-polyfill-regenerator "^0.2.2" - core-js-compat "^3.16.0" - semver "^6.3.0" - -"@babel/preset-modules@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" - integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/preset-typescript@7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz#e8fca638a1a0f64f14e1119f7fe4500277840945" - integrity sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-transform-typescript" "^7.15.0" - -"@babel/runtime@^7.8.4": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" - integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.14.5", "@babel/template@^7.3.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" - integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.5.tgz#c111b0f58afab4fea3d3385a406f692748c59870" - integrity sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.8.tgz#c0253f02677c5de1a8ff9df6b0aacbec7da1a8ce" - integrity sha512-kexHhzCljJcFNn1KYAQ6A5wxMRzq9ebYpEDV4+WdNyr3i7O44tanbDOR/xjiG2F3sllan+LgwK+7OMk0EmydHg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.8" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.14.8" - "@babel/types" "^7.14.8" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98" - integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.0" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.15.0" - "@babel/types" "^7.15.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.14.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff" - integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - to-fast-properties "^2.0.0" - -"@babel/types@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.8.tgz#38109de8fcadc06415fbd9b74df0065d4d41c728" - integrity sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q== - dependencies: - "@babel/helper-validator-identifier" "^7.14.8" - to-fast-properties "^2.0.0" - -"@babel/types@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" - integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ== - dependencies: - "@babel/helper-validator-identifier" "^7.14.9" - to-fast-properties "^2.0.0" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== - dependencies: - "@humanwhocodes/object-schema" "^1.2.0" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.6.tgz#3eb72ea80897495c3d73dd97aab7f26770e2260f" - integrity sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg== - dependencies: - "@jest/types" "^27.0.6" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^27.0.6" - jest-util "^27.0.6" - slash "^3.0.0" - -"@jest/core@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.6.tgz#c5f642727a0b3bf0f37c4b46c675372d0978d4a1" - integrity sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow== - dependencies: - "@jest/console" "^27.0.6" - "@jest/reporters" "^27.0.6" - "@jest/test-result" "^27.0.6" - "@jest/transform" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-changed-files "^27.0.6" - jest-config "^27.0.6" - jest-haste-map "^27.0.6" - jest-message-util "^27.0.6" - jest-regex-util "^27.0.6" - jest-resolve "^27.0.6" - jest-resolve-dependencies "^27.0.6" - jest-runner "^27.0.6" - jest-runtime "^27.0.6" - jest-snapshot "^27.0.6" - jest-util "^27.0.6" - jest-validate "^27.0.6" - jest-watcher "^27.0.6" - micromatch "^4.0.4" - p-each-series "^2.1.0" - rimraf "^3.0.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.6.tgz#ee293fe996db01d7d663b8108fa0e1ff436219d2" - integrity sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg== - dependencies: - "@jest/fake-timers" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/node" "*" - jest-mock "^27.0.6" - -"@jest/fake-timers@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.6.tgz#cbad52f3fe6abe30e7acb8cd5fa3466b9588e3df" - integrity sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ== - dependencies: - "@jest/types" "^27.0.6" - "@sinonjs/fake-timers" "^7.0.2" - "@types/node" "*" - jest-message-util "^27.0.6" - jest-mock "^27.0.6" - jest-util "^27.0.6" - -"@jest/globals@27.0.6", "@jest/globals@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.6.tgz#48e3903f99a4650673d8657334d13c9caf0e8f82" - integrity sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw== - dependencies: - "@jest/environment" "^27.0.6" - "@jest/types" "^27.0.6" - expect "^27.0.6" - -"@jest/reporters@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.6.tgz#91e7f2d98c002ad5df94d5b5167c1eb0b9fd5b00" - integrity sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.0.6" - "@jest/test-result" "^27.0.6" - "@jest/transform" "^27.0.6" - "@jest/types" "^27.0.6" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.4" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^4.0.3" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - jest-haste-map "^27.0.6" - jest-resolve "^27.0.6" - jest-util "^27.0.6" - jest-worker "^27.0.6" - slash "^3.0.0" - source-map "^0.6.0" - string-length "^4.0.1" - terminal-link "^2.0.0" - v8-to-istanbul "^8.0.0" - -"@jest/source-map@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.6.tgz#be9e9b93565d49b0548b86e232092491fb60551f" - integrity sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.2.4" - source-map "^0.6.0" - -"@jest/test-result@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.6.tgz#3fa42015a14e4fdede6acd042ce98c7f36627051" - integrity sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w== - dependencies: - "@jest/console" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz#80a913ed7a1130545b1cd777ff2735dd3af5d34b" - integrity sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA== - dependencies: - "@jest/test-result" "^27.0.6" - graceful-fs "^4.2.4" - jest-haste-map "^27.0.6" - jest-runtime "^27.0.6" - -"@jest/transform@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.6.tgz#189ad7107413208f7600f4719f81dd2f7278cc95" - integrity sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^27.0.6" - babel-plugin-istanbul "^6.0.0" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^27.0.6" - jest-regex-util "^27.0.6" - jest-util "^27.0.6" - micromatch "^4.0.4" - pirates "^4.0.1" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/types@^27.0.6": - version "27.0.6" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.6.tgz#9a992bc517e0c49f035938b8549719c2de40706b" - integrity sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2" - integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@rollup/plugin-babel@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz#9cb1c5146ddd6a4968ad96f209c50c62f92f9879" - integrity sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@rollup/pluginutils" "^3.1.0" - -"@rollup/plugin-commonjs@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-20.0.0.tgz#3246872dcbcb18a54aaa6277a8c7d7f1b155b745" - integrity sha512-5K0g5W2Ol8hAcTHqcTBHiA7M58tfmYi1o9KxeJuuRNpGaTa5iLjcyemBitCBcKXaHamOBBEH2dGom6v6Unmqjg== - dependencies: - "@rollup/pluginutils" "^3.1.0" - commondir "^1.0.1" - estree-walker "^2.0.1" - glob "^7.1.6" - is-reference "^1.2.1" - magic-string "^0.25.7" - resolve "^1.17.0" - -"@rollup/plugin-node-resolve@13.0.4": - version "13.0.4" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz#b10222f4145a019740acb7738402130d848660c0" - integrity sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w== - dependencies: - "@rollup/pluginutils" "^3.1.0" - "@types/resolve" "1.17.1" - builtin-modules "^3.1.0" - deepmerge "^4.2.2" - is-module "^1.0.0" - resolve "^1.19.0" - -"@rollup/plugin-replace@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-3.0.0.tgz#3a4c9665d4e7a4ce2c360cf021232784892f3fac" - integrity sha512-3c7JCbMuYXM4PbPWT4+m/4Y6U60SgsnDT/cCyAyUKwFHg7pTSfsSQzIpETha3a3ig6OdOKzZz87D9ZXIK3qsDg== - dependencies: - "@rollup/pluginutils" "^3.1.0" - magic-string "^0.25.7" - -"@rollup/plugin-typescript@8.2.5": - version "8.2.5" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.2.5.tgz#e0319761b2b5105615e5a0c371ae05bc2984b7de" - integrity sha512-QL/LvDol/PAGB2O0S7/+q2HpSUNodpw7z6nGn9BfoVCPOZ0r4EALrojFU29Bkoi2Hr2jgTocTejJ5GGWZfOxbQ== - dependencies: - "@rollup/pluginutils" "^3.1.0" - resolve "^1.17.0" - -"@rollup/pluginutils@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" - integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== - dependencies: - "@types/estree" "0.0.39" - estree-walker "^1.0.1" - picomatch "^2.2.2" - -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - -"@sindresorhus/is@^0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" - integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== - -"@sindresorhus/is@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5" - integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g== - -"@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^7.0.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" - integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - -"@szmarczak/http-timer@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" - integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== - dependencies: - defer-to-connect "^2.0.0" - -"@tauri-apps/toml@2.2.4": - version "2.2.4" - resolved "https://registry.yarnpkg.com/@tauri-apps/toml/-/toml-2.2.4.tgz#2b4f637aded7fc3a7302724605682c8fa3ac7505" - integrity sha512-NJV/pdgJObDlDWi5+MTHZ2qyNvdL0dlHqQ72nzQYXWbW1LHMPXgCJYl0pLqL1XxxLtxtInYbtVCGVAcwhGxdkw== - -"@tokenizer/token@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" - integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.1.14" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" - integrity sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8" - integrity sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be" - integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" - integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== - dependencies: - "@babel/types" "^7.3.0" - -"@types/cacheable-request@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" - integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "*" - "@types/node" "*" - "@types/responselike" "*" - -"@types/cross-spawn@6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.2.tgz#168309de311cd30a2b8ae720de6475c2fbf33ac7" - integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw== - dependencies: - "@types/node" "*" - -"@types/estree@*": - version "0.0.48" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74" - integrity sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew== - -"@types/estree@0.0.39": - version "0.0.39" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" - integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== - -"@types/fs-extra@9.0.12": - version "9.0.12" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.12.tgz#9b8f27973df8a7a3920e8461517ebf8a7d4fdfaf" - integrity sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw== - dependencies: - "@types/node" "*" - -"@types/global-agent@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@types/global-agent/-/global-agent-2.1.1.tgz#3f93185e48a3a36e377a52a8301320cd162a831b" - integrity sha512-sVox8Phk1UKgP6LQPAdeRxfww6vHKt7Bf59dXzYLsQBUEMEn8S10a+ESp/yO0i4fJ3WS4+CIuz42hgJcuA+3mA== - -"@types/graceful-fs@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== - dependencies: - "@types/node" "*" - -"@types/http-cache-semantics@*": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" - integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== - -"@types/imagemin-optipng@5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@types/imagemin-optipng/-/imagemin-optipng-5.2.1.tgz#6ef033f3b15d281009de4e0bd2cadf6cbd2e741a" - integrity sha512-XCM/3q+HUL7v4zOqMI+dJ5dTxT+MUukY9KU49DSnYb/4yWtSMHJyADP+WHSMVzTR63J2ZvfUOzSilzBNEQW78g== - dependencies: - "@types/imagemin" "*" - -"@types/imagemin@*": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@types/imagemin/-/imagemin-7.0.0.tgz#cb99d719190ebe421015213733d656fac1f8af2e" - integrity sha512-BiNd5FazD5ZmJUYD9txsbrttL0P0welrb9yAPn6ykKK3kWufwFsxYqw5KdggfZQDjiNYwsBrX+Fwei0Xsw4oAw== - dependencies: - "@types/node" "*" - -"@types/imagemin@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@types/imagemin/-/imagemin-7.0.1.tgz#11ca1e65ccb3871a8469d9b23033b95d3838eda0" - integrity sha512-xEn5+M3lDBtI3JxLy6eU3ksoVurygnlG7OYhTqJfGGP4PcvYnfn+IABCmMve7ziM/SneHDm5xgJFKC8hCYPicw== - dependencies: - "@types/node" "*" - -"@types/inquirer@7.3.3": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-7.3.3.tgz#92e6676efb67fa6925c69a2ee638f67a822952ac" - integrity sha512-HhxyLejTHMfohAuhRun4csWigAMjXTmRyiJTU1Y/I1xmggikFMkOUoMQRlFm+zQcPEGHSs3io/0FAmNZf8EymQ== - dependencies: - "@types/through" "*" - rxjs "^6.4.0" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" - integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/json-schema@^7.0.7": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@types/keyv@*": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" - integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== - dependencies: - "@types/node" "*" - -"@types/ms@0.7.31": - version "0.7.31" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/node@*": - version "15.12.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d" - integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/prettier@^2.1.5": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.0.tgz#2e8332cc7363f887d32ec5496b207d26ba8052bb" - integrity sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw== - -"@types/resolve@1.17.1": - version "1.17.1" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" - integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== - dependencies: - "@types/node" "*" - -"@types/responselike@*", "@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== - dependencies: - "@types/node" "*" - -"@types/semver@7.3.8": - version "7.3.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.8.tgz#508a27995498d7586dcecd77c25e289bfaf90c59" - integrity sha512-D/2EJvAlCEtYFEYmmlGwbGXuK886HzyCc3nZX/tkFTQdEU8jZDAgiv08P162yB17y4ZXZoq7yFAnW4GDBb9Now== - -"@types/sharp@0.28.5": - version "0.28.5" - resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.28.5.tgz#2095c304e24c310945d6ece7a9fd44b34272c93f" - integrity sha512-+RYU1NdKeDtTMau6HBbcVUCWjMiDydW4nRIGnOviwRxZxjJy0LqRdx0+YdxBKHcSlUWIYhD1XtiGQsUtInsjBQ== - dependencies: - "@types/node" "*" - -"@types/stack-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" - integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== - -"@types/through@*": - version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895" - integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg== - dependencies: - "@types/node" "*" - -"@types/yargs-parser@*": - version "20.2.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" - integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== - -"@types/yargs@^16.0.0": - version "16.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.3.tgz#4b6d35bb8e680510a7dc2308518a80ee1ef27e01" - integrity sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.1.tgz#808d206e2278e809292b5de752a91105da85860b" - integrity sha512-AHqIU+SqZZgBEiWOrtN94ldR3ZUABV5dUG94j8Nms9rQnHFc8fvDOue/58K4CFz6r8OtDDc35Pw9NQPWo0Ayrw== - dependencies: - "@typescript-eslint/experimental-utils" "4.29.1" - "@typescript-eslint/scope-manager" "4.29.1" - debug "^4.3.1" - functional-red-black-tree "^1.0.1" - regexpp "^3.1.0" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/experimental-utils@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.1.tgz#0af2b17b0296b60c6b207f11062119fa9c5a8994" - integrity sha512-kl6QG6qpzZthfd2bzPNSJB2YcZpNOrP6r9jueXupcZHnL74WiuSjaft7WSu17J9+ae9zTlk0KJMXPUj0daBxMw== - dependencies: - "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.29.1" - "@typescript-eslint/types" "4.29.1" - "@typescript-eslint/typescript-estree" "4.29.1" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/parser@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.1.tgz#17dfbb45c9032ffa0fe15881d20fbc2a4bdeb02d" - integrity sha512-3fL5iN20hzX3Q4OkG7QEPFjZV2qsVGiDhEwwh+EkmE/w7oteiOvUNzmpu5eSwGJX/anCryONltJ3WDmAzAoCMg== - dependencies: - "@typescript-eslint/scope-manager" "4.29.1" - "@typescript-eslint/types" "4.29.1" - "@typescript-eslint/typescript-estree" "4.29.1" - debug "^4.3.1" - -"@typescript-eslint/parser@^4.0.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.27.0.tgz#85447e573364bce4c46c7f64abaa4985aadf5a94" - integrity sha512-XpbxL+M+gClmJcJ5kHnUpBGmlGdgNvy6cehgR6ufyxkEJMGP25tZKCaKyC0W/JVpuhU3VU1RBn7SYUPKSMqQvQ== - dependencies: - "@typescript-eslint/scope-manager" "4.27.0" - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/typescript-estree" "4.27.0" - debug "^4.3.1" - -"@typescript-eslint/scope-manager@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.27.0.tgz#b0b1de2b35aaf7f532e89c8e81d0fa298cae327d" - integrity sha512-DY73jK6SEH6UDdzc6maF19AHQJBFVRf6fgAXHPXCGEmpqD4vYgPEzqpFz1lf/daSbOcMpPPj9tyXXDPW2XReAw== - dependencies: - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/visitor-keys" "4.27.0" - -"@typescript-eslint/scope-manager@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.1.tgz#f25da25bc6512812efa2ce5ebd36619d68e61358" - integrity sha512-Hzv/uZOa9zrD/W5mftZa54Jd5Fed3tL6b4HeaOpwVSabJK8CJ+2MkDasnX/XK4rqP5ZTWngK1ZDeCi6EnxPQ7A== - dependencies: - "@typescript-eslint/types" "4.29.1" - "@typescript-eslint/visitor-keys" "4.29.1" - -"@typescript-eslint/types@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.27.0.tgz#712b408519ed699baff69086bc59cd2fc13df8d8" - integrity sha512-I4ps3SCPFCKclRcvnsVA/7sWzh7naaM/b4pBO2hVxnM3wrU51Lveybdw5WoIktU/V4KfXrTt94V9b065b/0+wA== - -"@typescript-eslint/types@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.1.tgz#94cce6cf7cc83451df03339cda99d326be2feaf5" - integrity sha512-Jj2yu78IRfw4nlaLtKjVaGaxh/6FhofmQ/j8v3NXmAiKafbIqtAPnKYrf0sbGjKdj0hS316J8WhnGnErbJ4RCA== - -"@typescript-eslint/typescript-estree@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.27.0.tgz#189a7b9f1d0717d5cccdcc17247692dedf7a09da" - integrity sha512-KH03GUsUj41sRLLEy2JHstnezgpS5VNhrJouRdmh6yNdQ+yl8w5LrSwBkExM+jWwCJa7Ct2c8yl8NdtNRyQO6g== - dependencies: - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/visitor-keys" "4.27.0" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/typescript-estree@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.1.tgz#7b32a25ff8e51f2671ccc6b26cdbee3b1e6c5e7f" - integrity sha512-lIkkrR9E4lwZkzPiRDNq0xdC3f2iVCUjw/7WPJ4S2Sl6C3nRWkeE1YXCQ0+KsiaQRbpY16jNaokdWnm9aUIsfw== - dependencies: - "@typescript-eslint/types" "4.29.1" - "@typescript-eslint/visitor-keys" "4.29.1" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/visitor-keys@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.27.0.tgz#f56138b993ec822793e7ebcfac6ffdce0a60cb81" - integrity sha512-es0GRYNZp0ieckZ938cEANfEhsfHrzuLrePukLKtY3/KPXcq1Xd555Mno9/GOgXhKzn0QfkDLVgqWO3dGY80bg== - dependencies: - "@typescript-eslint/types" "4.27.0" - eslint-visitor-keys "^2.0.0" - -"@typescript-eslint/visitor-keys@4.29.1": - version "4.29.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.1.tgz#0615be8b55721f5e854f3ee99f1a714f2d093e5d" - integrity sha512-zLqtjMoXvgdZY/PG6gqA73V8BjqPs4af1v2kiiETBObp+uC6gRYnJLmJHxC0QyUrrHDLJPIWNYxoBV3wbcRlag== - dependencies: - "@typescript-eslint/types" "4.29.1" - eslint-visitor-keys "^2.0.0" - -"@yarnpkg/lockfile@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" - integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== - -abab@^2.0.3, abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - -acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== - -acorn-walk@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - -acorn@^7.1.1, acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.2.4: - version "8.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.0.tgz#af53266e698d7cffa416714b503066a82221be60" - integrity sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.1: - version "8.6.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.0.tgz#60cc45d9c46a477d80d92c48076d972c342e5720" - integrity sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-align@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" - integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== - dependencies: - string-width "^3.0.0" - -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -anymatch@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -arch@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" - integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== - -archive-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" - integrity sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA= - dependencies: - file-type "^4.2.0" - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - -array-includes@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" - integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - get-intrinsic "^1.1.1" - is-string "^1.0.5" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-union@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975" - integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw== - -array.prototype.flat@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" - integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - -asap@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -babel-jest@27.0.6, babel-jest@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.6.tgz#e99c6e0577da2655118e3608b68761a5a69bd0d8" - integrity sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA== - dependencies: - "@jest/transform" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^27.0.6" - chalk "^4.0.0" - graceful-fs "^4.2.4" - slash "^3.0.0" - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-istanbul@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" - integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^4.0.0" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz#f7c6b3d764af21cb4a2a1ab6870117dbde15b456" - integrity sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.0.0" - "@types/babel__traverse" "^7.0.6" - -babel-plugin-polyfill-corejs2@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" - integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== - dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.2.2" - semver "^6.1.1" - -babel-plugin-polyfill-corejs3@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5" - integrity sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.2" - core-js-compat "^3.9.1" - -babel-plugin-polyfill-regenerator@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" - integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.2" - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - -babel-preset-jest@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz#909ef08e9f24a4679768be2f60a3df0856843f9d" - integrity sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw== - dependencies: - babel-plugin-jest-hoist "^27.0.6" - babel-preset-current-node-syntax "^1.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bin-build@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bin-build/-/bin-build-3.0.0.tgz#c5780a25a8a9f966d8244217e6c1f5082a143861" - integrity sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA== - dependencies: - decompress "^4.0.0" - download "^6.2.2" - execa "^0.7.0" - p-map-series "^1.0.0" - tempfile "^2.0.0" - -bin-check@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bin-check/-/bin-check-4.1.0.tgz#fc495970bdc88bb1d5a35fc17e65c4a149fc4a49" - integrity sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA== - dependencies: - execa "^0.7.0" - executable "^4.1.0" - -bin-version-check@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-4.0.0.tgz#7d819c62496991f80d893e6e02a3032361608f71" - integrity sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ== - dependencies: - bin-version "^3.0.0" - semver "^5.6.0" - semver-truncate "^1.1.2" - -bin-version@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-3.1.0.tgz#5b09eb280752b1bd28f0c9db3f96f2f43b6c0839" - integrity sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ== - dependencies: - execa "^1.0.0" - find-versions "^3.0.0" - -bin-wrapper@^4.0.0, bin-wrapper@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bin-wrapper/-/bin-wrapper-4.1.0.tgz#99348f2cf85031e3ef7efce7e5300aeaae960605" - integrity sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q== - dependencies: - bin-check "^4.1.0" - bin-version-check "^4.0.0" - download "^7.1.0" - import-lazy "^3.1.0" - os-filter-obj "^2.0.0" - pify "^4.0.1" - -bl@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" - integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - -bl@^4.0.3, bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -boolean@^3.0.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.1.2.tgz#e30f210a26b02458482a8cc353ab06f262a780c2" - integrity sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw== - -boxen@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.0.1.tgz#657528bdd3f59a772b8279b831f27ec2c744664b" - integrity sha512-49VBlw+PrWEF51aCmy7QIteYPIFZxSpvqBdP/2itCPPlJ49kj9zg/XPRFrdkne2W+CfwXUls8exMvu1RysZpKA== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.0" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browserslist@^4.16.6: - version "4.16.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" - integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== - dependencies: - caniuse-lite "^1.0.30001219" - colorette "^1.2.2" - electron-to-chromium "^1.3.723" - escalade "^3.1.1" - node-releases "^1.1.71" - -browserslist@^4.16.7: - version "4.16.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.7.tgz#108b0d1ef33c4af1b587c54f390e7041178e4335" - integrity sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA== - dependencies: - caniuse-lite "^1.0.30001248" - colorette "^1.2.2" - electron-to-chromium "^1.3.793" - escalade "^3.1.1" - node-releases "^1.1.73" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-crc32@~0.2.3: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer@^5.2.1, buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -builtin-modules@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" - integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== - -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== - -cacheable-request@^2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" - integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= - dependencies: - clone-response "1.0.2" - get-stream "3.0.0" - http-cache-semantics "3.8.1" - keyv "3.0.0" - lowercase-keys "1.0.0" - normalize-url "2.0.1" - responselike "1.0.2" - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -cacheable-request@^7.0.1: - version "7.0.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - -caniuse-lite@^1.0.30001219: - version "1.0.30001237" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001237.tgz#4b7783661515b8e7151fc6376cfd97f0e427b9e5" - integrity sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw== - -caniuse-lite@^1.0.30001248: - version "1.0.30001249" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz#90a330057f8ff75bfe97a94d047d5e14fabb2ee8" - integrity sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw== - -caw@^2.0.0, caw@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" - integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== - dependencies: - get-proxy "^2.0.0" - isurl "^1.0.0-alpha5" - tunnel-agent "^0.6.0" - url-to-options "^1.0.1" - -chalk@4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -ci-info@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" - integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== - -cjs-module-lexer@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz#2fd46d9906a126965aa541345c499aaa18e8cd73" - integrity sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw== - -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-spinners@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" - integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-response@1.0.2, clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.5.4: - version "1.5.5" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" - integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" - integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.4" - -colorette@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" - integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@^2.20.0, commander@^2.8.1: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -config-chain@^1.1.11: - version "1.1.13" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" - integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - -configstore@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" - integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== - dependencies: - dot-prop "^5.2.0" - graceful-fs "^4.1.2" - make-dir "^3.0.0" - unique-string "^2.0.0" - write-file-atomic "^3.0.0" - xdg-basedir "^4.0.0" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -console-stream@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/console-stream/-/console-stream-0.1.1.tgz#a095fe07b20465955f2fafd28b5d72bccd949d44" - integrity sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ= - -content-disposition@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -core-js-compat@^3.16.0: - version "3.16.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.16.1.tgz#c44b7caa2dcb94b673a98f27eee1c8312f55bc2d" - integrity sha512-NHXQXvRbd4nxp9TEmooTJLUf94ySUG6+DSsscBpTftN1lQLQ4LjnWvc7AoIo4UjDsFF3hB8Uh5LLCRRdaiT5MQ== - dependencies: - browserslist "^4.16.7" - semver "7.0.0" - -core-js-compat@^3.9.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.14.0.tgz#b574dabf29184681d5b16357bd33d104df3d29a5" - integrity sha512-R4NS2eupxtiJU+VwgkF9WTpnSfZW4pogwKHd8bclWU2sp93Pr5S1uYJI84cMOubJRou7bcfL0vmwtLslWN5p3A== - dependencies: - browserslist "^4.16.6" - semver "7.0.0" - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - -cross-env@7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" - integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== - dependencies: - cross-spawn "^7.0.1" - -cross-spawn@7.0.3, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= - dependencies: - array-find-index "^1.0.1" - -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -decompress-response@^3.2.0, decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - -decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" - integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== - dependencies: - file-type "^5.2.0" - is-stream "^1.1.0" - tar-stream "^1.5.2" - -decompress-tarbz2@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" - integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== - dependencies: - decompress-tar "^4.1.0" - file-type "^6.1.0" - is-stream "^1.1.0" - seek-bzip "^1.0.5" - unbzip2-stream "^1.0.9" - -decompress-targz@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" - integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== - dependencies: - decompress-tar "^4.1.1" - file-type "^5.2.0" - is-stream "^1.1.0" - -decompress-unzip@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" - integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= - dependencies: - file-type "^3.8.0" - get-stream "^2.2.0" - pify "^2.3.0" - yauzl "^2.4.2" - -decompress@^4.0.0, decompress@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" - integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== - dependencies: - decompress-tar "^4.0.0" - decompress-tarbz2 "^4.0.0" - decompress-targz "^4.0.0" - decompress-unzip "^4.0.1" - graceful-fs "^4.1.10" - make-dir "^1.0.0" - pify "^2.3.0" - strip-dirs "^2.0.0" - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= - dependencies: - clone "^1.0.2" - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - -defer-to-connect@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -diff-sequences@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723" - integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== - dependencies: - webidl-conversions "^5.0.0" - -dot-prop@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -download@^6.2.2: - version "6.2.5" - resolved "https://registry.yarnpkg.com/download/-/download-6.2.5.tgz#acd6a542e4cd0bb42ca70cfc98c9e43b07039714" - integrity sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA== - dependencies: - caw "^2.0.0" - content-disposition "^0.5.2" - decompress "^4.0.0" - ext-name "^5.0.0" - file-type "5.2.0" - filenamify "^2.0.0" - get-stream "^3.0.0" - got "^7.0.0" - make-dir "^1.0.0" - p-event "^1.0.0" - pify "^3.0.0" - -download@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/download/-/download-7.1.0.tgz#9059aa9d70b503ee76a132897be6dec8e5587233" - integrity sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ== - dependencies: - archive-type "^4.0.0" - caw "^2.0.1" - content-disposition "^0.5.2" - decompress "^4.2.0" - ext-name "^5.0.0" - file-type "^8.1.0" - filenamify "^2.0.0" - get-stream "^3.0.0" - got "^8.3.1" - make-dir "^1.2.0" - p-event "^2.1.0" - pify "^3.0.0" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -electron-to-chromium@^1.3.723: - version "1.3.752" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz#0728587f1b9b970ec9ffad932496429aef750d09" - integrity sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A== - -electron-to-chromium@^1.3.793: - version "1.3.802" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.802.tgz#0afa989321de3e904ac653ee79e0d642883731a1" - integrity sha512-dXB0SGSypfm3iEDxrb5n/IVKeX4uuTnFHdve7v+yKJqNpEP0D4mjFJ8e1znmSR+OOVlVC+kDO6f2kAkTFXvJBg== - -emittery@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" - integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: - version "1.18.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" - integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.2" - is-callable "^1.2.3" - is-negative-zero "^2.0.1" - is-regex "^1.1.3" - is-string "^1.0.6" - object-inspect "^1.10.3" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-error@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-goat@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" - integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-config-prettier@8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" - integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== - -eslint-config-standard-with-typescript@20.0.0: - version "20.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-20.0.0.tgz#0c550eca0a216cbf8da9013eb6e311acd3102d87" - integrity sha512-IoySf3r0a2+P3Z6GMjv8p1HuOQ6GWQbMpdt9G8uEbkGpnNWAGBXpgaiutbZHbaQAvG5pkVtYepCfHUxYbVDLCA== - dependencies: - "@typescript-eslint/parser" "^4.0.0" - eslint-config-standard "^16.0.0" - -eslint-config-standard@^16.0.0: - version "16.0.3" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516" - integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg== - -eslint-import-resolver-node@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.5.tgz#939bbb0f74e179e757ca87f7a4a890dabed18ac4" - integrity sha512-XMoPKjSpXbkeJ7ZZ9icLnJMTY5Mc1kZbCakHquaFsXPpyWOwK0TK6CODO+0ca54UoM9LKOxyUNnoVZRl8TeaAg== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-module-utils@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" - integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== - dependencies: - debug "^3.2.7" - pkg-dir "^2.0.0" - -eslint-plugin-es@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-import@2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.0.tgz#697ffd263e24da5e84e03b282f5fb62251777177" - integrity sha512-Kc6xqT9hiYi2cgybOc0I2vC9OgAYga5o/rAFinam/yF/t5uBqxQbauNPMC6fgb640T/89P0gFoO27FOilJ/Cqg== - dependencies: - array-includes "^3.1.3" - array.prototype.flat "^1.2.4" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.5" - eslint-module-utils "^2.6.2" - find-up "^2.0.0" - has "^1.0.3" - is-core-module "^2.4.0" - minimatch "^3.0.4" - object.values "^1.1.3" - pkg-up "^2.0.0" - read-pkg-up "^3.0.0" - resolve "^1.20.0" - tsconfig-paths "^3.9.0" - -eslint-plugin-lodash-template@0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-lodash-template/-/eslint-plugin-lodash-template-0.19.0.tgz#4b2aafec4fc2a23bbbc08325fbcb946371479666" - integrity sha512-OWcxGOkJ87lflnFDeKAhYErN1F6SQ7qLisko4n/mK3iQPT747ft2EYlI+SSt2aYGSp8fhvidsrnR7hlK9TRi0w== - dependencies: - esquery "^1.0.1" - parse5 "^6.0.0" - -eslint-plugin-node@11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" - integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== - dependencies: - eslint-plugin-es "^3.0.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - -eslint-plugin-promise@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz#fb2188fb734e4557993733b41aa1a688f46c6f24" - integrity sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng== - -eslint-plugin-security@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-security/-/eslint-plugin-security-1.4.0.tgz#d4f314484a80b1b613b8c8886e84f52efe1526c2" - integrity sha512-xlS7P2PLMXeqfhyf3NpqbvbnW04kN8M9NtmhpR3XGyOvt/vNKS7XPXT5EDbwKW9vCjWH4PpfQvgD/+JgN0VJKA== - dependencies: - safe-regex "^1.1.0" - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^2.0.0, eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint@7.32.0: - version "7.32.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.9" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - -esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1, esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -estree-walker@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" - integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== - -estree-walker@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -exec-buffer@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/exec-buffer/-/exec-buffer-3.2.0.tgz#b1686dbd904c7cf982e652c1f5a79b1e5573082b" - integrity sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA== - dependencies: - execa "^0.7.0" - p-finally "^1.0.0" - pify "^3.0.0" - rimraf "^2.5.4" - tempfile "^2.0.0" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -executable@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" - integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== - dependencies: - pify "^2.2.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= - -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - -expect@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.6.tgz#a4d74fbe27222c718fff68ef49d78e26a8fd4c05" - integrity sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw== - dependencies: - "@jest/types" "^27.0.6" - ansi-styles "^5.0.0" - jest-get-type "^27.0.6" - jest-matcher-utils "^27.0.6" - jest-message-util "^27.0.6" - jest-regex-util "^27.0.6" - -ext-list@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" - integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== - dependencies: - mime-db "^1.28.0" - -ext-name@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" - integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== - dependencies: - ext-list "^2.0.0" - sort-keys-length "^1.0.0" - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.1.1: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" - merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" - -fast-glob@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fastq@^1.6.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" - integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== - dependencies: - reusify "^1.0.4" - -fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== - dependencies: - bser "2.1.1" - -fd-slicer@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" - integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= - dependencies: - pend "~1.2.0" - -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -file-type@5.2.0, file-type@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" - integrity sha1-LdvqfHP/42No365J3DOMBYwritY= - -file-type@^16.5.3: - version "16.5.3" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.3.tgz#474b7e88c74724046abb505e9b8ed4db30c4fc06" - integrity sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A== - dependencies: - readable-web-to-node-stream "^3.0.0" - strtok3 "^6.2.4" - token-types "^4.1.1" - -file-type@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" - integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= - -file-type@^4.2.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" - integrity sha1-G2AOX8ofvcboDApwxxyNul95BsU= - -file-type@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" - integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== - -file-type@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" - integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== - -filename-reserved-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" - integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= - -filenamify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" - integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA== - dependencies: - filename-reserved-regex "^2.0.0" - strip-outer "^1.0.0" - trim-repeated "^1.0.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-versions@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" - integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== - dependencies: - semver-regex "^2.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" - integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== - -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -from2@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" - integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^2.3.2, fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-proxy@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" - integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== - dependencies: - npm-conf "^1.1.0" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= - -get-stream@3.0.0, get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - -get-stream@^4.0.0, get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= - -glob-parent@^5.1.0, glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-agent@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6" - integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q== - dependencies: - boolean "^3.0.1" - es6-error "^4.1.1" - matcher "^3.0.0" - roarr "^2.15.3" - semver "^7.3.2" - serialize-error "^7.0.1" - -global-dirs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" - integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== - dependencies: - ini "2.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.6.0, globals@^13.9.0: - version "13.9.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" - integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b" - integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ== - dependencies: - define-properties "^1.1.3" - -globby@^11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -globby@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-12.0.0.tgz#b8bbb8e9d48f8a3c9abf5624030f1f9e1cfbe3ed" - integrity sha512-3mOIUduqSMHm6gNjIw9E641TZ93NB8lFVt+6MKIw6vUaIS5aSsw/6cl0gT86z1IoKlaL90BiOQlA593GUMlzEA== - dependencies: - array-union "^3.0.1" - dir-glob "^3.0.1" - fast-glob "^3.2.7" - ignore "^5.1.8" - merge2 "^1.4.1" - slash "^4.0.0" - -got@11.8.2: - version "11.8.2" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" - integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.1" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - -got@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" - integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== - dependencies: - decompress-response "^3.2.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-plain-obj "^1.1.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - isurl "^1.0.0-alpha5" - lowercase-keys "^1.0.0" - p-cancelable "^0.3.0" - p-timeout "^1.1.1" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - url-parse-lax "^1.0.0" - url-to-options "^1.0.1" - -got@^8.3.1: - version "8.3.2" - resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" - integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== - dependencies: - "@sindresorhus/is" "^0.7.0" - cacheable-request "^2.1.1" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - into-stream "^3.1.0" - is-retry-allowed "^1.1.0" - isurl "^1.0.0-alpha5" - lowercase-keys "^1.0.0" - mimic-response "^1.0.0" - p-cancelable "^0.4.0" - p-timeout "^2.0.1" - pify "^3.0.0" - safe-buffer "^5.1.1" - timed-out "^4.0.1" - url-parse-lax "^3.0.0" - url-to-options "^1.0.1" - -got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== - -graceful-fs@^4.2.8: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbol-support-x@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" - integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-to-string-tag-x@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" - integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== - dependencies: - has-symbol-support-x "^1.4.1" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-yarn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" - integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== - dependencies: - whatwg-encoding "^1.0.5" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-cache-semantics@3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" - integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== - -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.13, ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -imagemin-optipng@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/imagemin-optipng/-/imagemin-optipng-8.0.0.tgz#b88e5cf6da25cc8479e07cdf38c3ae0479df7ef2" - integrity sha512-CUGfhfwqlPjAC0rm8Fy+R2DJDBGjzy2SkfyT09L8rasnF9jSoHFqJ1xxSZWK6HVPZBMhGPMxCTL70OgTHlLF5A== - dependencies: - exec-buffer "^3.0.0" - is-png "^2.0.0" - optipng-bin "^7.0.0" - -imagemin-zopfli@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/imagemin-zopfli/-/imagemin-zopfli-7.0.0.tgz#a44daa3bb80e2620cd1dc883d823b20b4d3788d6" - integrity sha512-nmffj58rVb0O3AlCZLBBVKGyZ5MYPZZfKxUhvA7bwPGougHl/F7EUKSse9jkgXjdvtJYG2ojJeh5N67mYgBM9g== - dependencies: - exec-buffer "^3.0.0" - is-png "^2.0.0" - zopflipng-bin "^6.0.0" - -imagemin@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/imagemin/-/imagemin-8.0.1.tgz#8b29ecb78197d8f0eac6a782f2e6b38fb3780d9e" - integrity sha512-Q/QaPi+5HuwbZNtQRqUVk6hKacI6z9iWiCSQBisAv7uBynZwO7t1svkryKl7+iSQbkU/6t9DWnHz04cFs2WY7w== - dependencies: - file-type "^16.5.3" - globby "^12.0.0" - graceful-fs "^4.2.8" - junk "^3.1.0" - p-pipe "^4.0.0" - replace-ext "^2.0.0" - slash "^3.0.0" - -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -import-lazy@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-3.1.0.tgz#891279202c8a2280fdbd6674dbd8da1a1dfc67cc" - integrity sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ== - -import-local@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" - integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= - dependencies: - repeating "^2.0.0" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - -ini@^1.3.4, ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -inquirer@8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.1.2.tgz#65b204d2cd7fb63400edd925dfe428bafd422e3d" - integrity sha512-DHLKJwLPNgkfwNmsuEUKSejJFbkv0FMO9SMiQbjI3n5NQuCrSIBqP66ggqyz2a6t2qEolKrMjhQ3+W/xXgUQ+Q== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.3.0" - run-async "^2.4.0" - rxjs "^7.2.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - -into-stream@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" - integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= - dependencies: - from2 "^2.1.1" - p-is-promise "^1.1.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-bigint@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" - integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== - -is-boolean-object@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" - integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== - dependencies: - call-bind "^1.0.2" - -is-callable@^1.1.4, is-callable@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" - integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-ci@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" - integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== - dependencies: - ci-info "^3.1.1" - -is-core-module@^2.2.0, is-core-module@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" - integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" - integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-installed-globally@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" - integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== - dependencies: - global-dirs "^3.0.0" - is-path-inside "^3.0.2" - -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= - -is-natural-number@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" - integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-npm@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" - integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== - -is-number-object@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" - integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== - -is-path-inside@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-png@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-png/-/is-png-3.0.0.tgz#7bf5db7f32527d10c90594a751c15f74d46c8f5e" - integrity sha512-waa2qEuqgLjjYT14KOUQqAEIRRIv7ttkzPVctY/qv+IAKnzXf+JAPKQas50RgO0ECPDUG/iB1zQmwpyB9kkZtQ== - -is-png@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d" - integrity sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g== - -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - -is-reference@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" - integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== - dependencies: - "@types/estree" "*" - -is-regex@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" - integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== - dependencies: - call-bind "^1.0.2" - has-symbols "^1.0.2" - -is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - -is-running@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-running/-/is-running-2.1.0.tgz#30a73ff5cc3854e4fc25490809e9f5abf8de09e0" - integrity sha1-MKc/9cw4VOT8JUkICen1q/jeCeA= - -is-stream@^1.0.0, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - -is-string@^1.0.5, is-string@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" - integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-yarn-global@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" - integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -istanbul-lib-coverage@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" - integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== - -istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== - dependencies: - "@babel/core" "^7.7.5" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" - semver "^6.3.0" - -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" - integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" - integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -isurl@^1.0.0-alpha5: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" - integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== - dependencies: - has-to-string-tag-x "^1.2.0" - is-object "^1.0.1" - -jest-changed-files@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.6.tgz#bed6183fcdea8a285482e3b50a9a7712d49a7a8b" - integrity sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA== - dependencies: - "@jest/types" "^27.0.6" - execa "^5.0.0" - throat "^6.0.1" - -jest-circus@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.6.tgz#dd4df17c4697db6a2c232aaad4e9cec666926668" - integrity sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q== - dependencies: - "@jest/environment" "^27.0.6" - "@jest/test-result" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - expect "^27.0.6" - is-generator-fn "^2.0.0" - jest-each "^27.0.6" - jest-matcher-utils "^27.0.6" - jest-message-util "^27.0.6" - jest-runtime "^27.0.6" - jest-snapshot "^27.0.6" - jest-util "^27.0.6" - pretty-format "^27.0.6" - slash "^3.0.0" - stack-utils "^2.0.3" - throat "^6.0.1" - -jest-cli@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.6.tgz#d021e5f4d86d6a212450d4c7b86cb219f1e6864f" - integrity sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg== - dependencies: - "@jest/core" "^27.0.6" - "@jest/test-result" "^27.0.6" - "@jest/types" "^27.0.6" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.4" - import-local "^3.0.2" - jest-config "^27.0.6" - jest-util "^27.0.6" - jest-validate "^27.0.6" - prompts "^2.0.1" - yargs "^16.0.3" - -jest-config@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.6.tgz#119fb10f149ba63d9c50621baa4f1f179500277f" - integrity sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w== - dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^27.0.6" - "@jest/types" "^27.0.6" - babel-jest "^27.0.6" - chalk "^4.0.0" - deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.4" - is-ci "^3.0.0" - jest-circus "^27.0.6" - jest-environment-jsdom "^27.0.6" - jest-environment-node "^27.0.6" - jest-get-type "^27.0.6" - jest-jasmine2 "^27.0.6" - jest-regex-util "^27.0.6" - jest-resolve "^27.0.6" - jest-runner "^27.0.6" - jest-util "^27.0.6" - jest-validate "^27.0.6" - micromatch "^4.0.4" - pretty-format "^27.0.6" - -jest-diff@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.6.tgz#4a7a19ee6f04ad70e0e3388f35829394a44c7b5e" - integrity sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg== - dependencies: - chalk "^4.0.0" - diff-sequences "^27.0.6" - jest-get-type "^27.0.6" - pretty-format "^27.0.6" - -jest-docblock@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.6.tgz#cc78266acf7fe693ca462cbbda0ea4e639e4e5f3" - integrity sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA== - dependencies: - detect-newline "^3.0.0" - -jest-each@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.6.tgz#cee117071b04060158dc8d9a66dc50ad40ef453b" - integrity sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA== - dependencies: - "@jest/types" "^27.0.6" - chalk "^4.0.0" - jest-get-type "^27.0.6" - jest-util "^27.0.6" - pretty-format "^27.0.6" - -jest-environment-jsdom@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz#f66426c4c9950807d0a9f209c590ce544f73291f" - integrity sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw== - dependencies: - "@jest/environment" "^27.0.6" - "@jest/fake-timers" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/node" "*" - jest-mock "^27.0.6" - jest-util "^27.0.6" - jsdom "^16.6.0" - -jest-environment-node@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.6.tgz#a6699b7ceb52e8d68138b9808b0c404e505f3e07" - integrity sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w== - dependencies: - "@jest/environment" "^27.0.6" - "@jest/fake-timers" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/node" "*" - jest-mock "^27.0.6" - jest-util "^27.0.6" - -jest-get-type@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe" - integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg== - -jest-haste-map@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.6.tgz#4683a4e68f6ecaa74231679dca237279562c8dc7" - integrity sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w== - dependencies: - "@jest/types" "^27.0.6" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^27.0.6" - jest-serializer "^27.0.6" - jest-util "^27.0.6" - jest-worker "^27.0.6" - micromatch "^4.0.4" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.3.2" - -jest-jasmine2@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz#fd509a9ed3d92bd6edb68a779f4738b100655b37" - integrity sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA== - dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^27.0.6" - "@jest/source-map" "^27.0.6" - "@jest/test-result" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^27.0.6" - is-generator-fn "^2.0.0" - jest-each "^27.0.6" - jest-matcher-utils "^27.0.6" - jest-message-util "^27.0.6" - jest-runtime "^27.0.6" - jest-snapshot "^27.0.6" - jest-util "^27.0.6" - pretty-format "^27.0.6" - throat "^6.0.1" - -jest-leak-detector@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz#545854275f85450d4ef4b8fe305ca2a26450450f" - integrity sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ== - dependencies: - jest-get-type "^27.0.6" - pretty-format "^27.0.6" - -jest-matcher-utils@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz#2a8da1e86c620b39459f4352eaa255f0d43e39a9" - integrity sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA== - dependencies: - chalk "^4.0.0" - jest-diff "^27.0.6" - jest-get-type "^27.0.6" - pretty-format "^27.0.6" - -jest-message-util@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.6.tgz#158bcdf4785706492d164a39abca6a14da5ab8b5" - integrity sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.0.6" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.4" - micromatch "^4.0.4" - pretty-format "^27.0.6" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.6.tgz#0efdd40851398307ba16778728f6d34d583e3467" - integrity sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw== - dependencies: - "@jest/types" "^27.0.6" - "@types/node" "*" - -jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== - -jest-regex-util@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5" - integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== - -jest-resolve-dependencies@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz#3e619e0ef391c3ecfcf6ef4056207a3d2be3269f" - integrity sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA== - dependencies: - "@jest/types" "^27.0.6" - jest-regex-util "^27.0.6" - jest-snapshot "^27.0.6" - -jest-resolve@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.6.tgz#e90f436dd4f8fbf53f58a91c42344864f8e55bff" - integrity sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA== - dependencies: - "@jest/types" "^27.0.6" - chalk "^4.0.0" - escalade "^3.1.1" - graceful-fs "^4.2.4" - jest-pnp-resolver "^1.2.2" - jest-util "^27.0.6" - jest-validate "^27.0.6" - resolve "^1.20.0" - slash "^3.0.0" - -jest-runner@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.6.tgz#1325f45055539222bbc7256a6976e993ad2f9520" - integrity sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ== - dependencies: - "@jest/console" "^27.0.6" - "@jest/environment" "^27.0.6" - "@jest/test-result" "^27.0.6" - "@jest/transform" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-docblock "^27.0.6" - jest-environment-jsdom "^27.0.6" - jest-environment-node "^27.0.6" - jest-haste-map "^27.0.6" - jest-leak-detector "^27.0.6" - jest-message-util "^27.0.6" - jest-resolve "^27.0.6" - jest-runtime "^27.0.6" - jest-util "^27.0.6" - jest-worker "^27.0.6" - source-map-support "^0.5.6" - throat "^6.0.1" - -jest-runtime@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.6.tgz#45877cfcd386afdd4f317def551fc369794c27c9" - integrity sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q== - dependencies: - "@jest/console" "^27.0.6" - "@jest/environment" "^27.0.6" - "@jest/fake-timers" "^27.0.6" - "@jest/globals" "^27.0.6" - "@jest/source-map" "^27.0.6" - "@jest/test-result" "^27.0.6" - "@jest/transform" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.4" - jest-haste-map "^27.0.6" - jest-message-util "^27.0.6" - jest-mock "^27.0.6" - jest-regex-util "^27.0.6" - jest-resolve "^27.0.6" - jest-snapshot "^27.0.6" - jest-util "^27.0.6" - jest-validate "^27.0.6" - slash "^3.0.0" - strip-bom "^4.0.0" - yargs "^16.0.3" - -jest-serializer@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.6.tgz#93a6c74e0132b81a2d54623251c46c498bb5bec1" - integrity sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.4" - -jest-snapshot@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.6.tgz#f4e6b208bd2e92e888344d78f0f650bcff05a4bf" - integrity sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A== - dependencies: - "@babel/core" "^7.7.2" - "@babel/generator" "^7.7.2" - "@babel/parser" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.0.0" - "@jest/transform" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^27.0.6" - graceful-fs "^4.2.4" - jest-diff "^27.0.6" - jest-get-type "^27.0.6" - jest-haste-map "^27.0.6" - jest-matcher-utils "^27.0.6" - jest-message-util "^27.0.6" - jest-resolve "^27.0.6" - jest-util "^27.0.6" - natural-compare "^1.4.0" - pretty-format "^27.0.6" - semver "^7.3.2" - -jest-transform-toml@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jest-transform-toml/-/jest-transform-toml-1.0.0.tgz#0a255066d4e59620ec3c3cc5a555321bb05f153d" - integrity sha1-CiVQZtTlliDsPDzFpVUyG7BfFT0= - dependencies: - toml-loader "^1.0.0" - -jest-util@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.6.tgz#e8e04eec159de2f4d5f57f795df9cdc091e50297" - integrity sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ== - dependencies: - "@jest/types" "^27.0.6" - "@types/node" "*" - chalk "^4.0.0" - graceful-fs "^4.2.4" - is-ci "^3.0.0" - picomatch "^2.2.3" - -jest-validate@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.6.tgz#930a527c7a951927df269f43b2dc23262457e2a6" - integrity sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA== - dependencies: - "@jest/types" "^27.0.6" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^27.0.6" - leven "^3.1.0" - pretty-format "^27.0.6" - -jest-watcher@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.6.tgz#89526f7f9edf1eac4e4be989bcb6dec6b8878d9c" - integrity sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ== - dependencies: - "@jest/test-result" "^27.0.6" - "@jest/types" "^27.0.6" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - jest-util "^27.0.6" - string-length "^4.0.1" - -jest-worker@^26.2.1: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - -jest-worker@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed" - integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.6.tgz#10517b2a628f0409087fbf473db44777d7a04505" - integrity sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA== - dependencies: - "@jest/core" "^27.0.6" - import-local "^3.0.2" - jest-cli "^27.0.6" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsdom@^16.6.0: - version "16.6.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.6.0.tgz#f79b3786682065492a3da6a60a4695da983805ac" - integrity sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.5" - xml-name-validator "^3.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -json5@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" - integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== - dependencies: - minimist "^1.2.5" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -junk@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" - integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== - -keyv@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" - integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== - dependencies: - json-buffer "3.0.0" - -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - -keyv@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" - integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== - dependencies: - json-buffer "3.0.1" - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -latest-version@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" - integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== - dependencies: - package-json "^6.3.0" - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lockfile-lint-api@^5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/lockfile-lint-api/-/lockfile-lint-api-5.1.7.tgz#052f615ab85ac3ad69f8c90b03eb3b64dbd6ebd9" - integrity sha512-o10D4DiLUFXl/8UqYBsuNnye3DcNtAuIm6+vCsnSwHONIQqR6etWUA0v94lMhh5tIDqPOV08Gc8Ds+A3bMqW4g== - dependencies: - "@yarnpkg/lockfile" "^1.1.0" - debug "^4.1.1" - object-hash "^2.0.1" - -lockfile-lint@4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lockfile-lint/-/lockfile-lint-4.6.2.tgz#ca4a896f702ea22b04d4084246ce0ecfb2b4ff74" - integrity sha512-TvWN2Yfc/dvSy1GKdpy0wJ6GCvq/9Qj457D+QQtP+eYvsX4zNp3vaaB2LS1d+TK1lO/7I0VQ0qqRCRCOzSj2wQ== - dependencies: - cosmiconfig "^6.0.0" - debug "^4.1.1" - lockfile-lint-api "^5.1.7" - yargs "^16.0.0" - -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= - -lodash@^4.17.21, lodash@^4.7.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -logalot@^2.0.0, logalot@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/logalot/-/logalot-2.1.0.tgz#5f8e8c90d304edf12530951a5554abb8c5e3f552" - integrity sha1-X46MkNME7fElMJUaVVSruMXj9VI= - dependencies: - figures "^1.3.5" - squeak "^1.0.0" - -longest@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= - -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lowercase-keys@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" - integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= - -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lpad-align@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/lpad-align/-/lpad-align-1.1.2.tgz#21f600ac1c3095c3c6e497ee67271ee08481fe9e" - integrity sha1-IfYArBwwlcPG5JfuZyce4ISB/p4= - dependencies: - get-stdin "^4.0.1" - indent-string "^2.1.0" - longest "^1.0.0" - meow "^3.3.0" - -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -magic-string@^0.25.7: - version "0.25.7" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" - integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== - dependencies: - sourcemap-codec "^1.4.4" - -make-dir@^1.0.0, make-dir@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= - dependencies: - tmpl "1.0.x" - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= - -matcher@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca" - integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng== - dependencies: - escape-string-regexp "^4.0.0" - -meow@^3.3.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -mime-db@1.48.0, mime-db@^1.28.0: - version "1.48.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" - integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== - -mime-types@^2.1.12: - version "2.1.31" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" - integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== - dependencies: - mime-db "1.48.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@1.2.5, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-abi@^2.21.0: - version "2.30.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.0.tgz#8be53bf3e7945a34eea10e0fc9a5982776cf550b" - integrity sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg== - dependencies: - semver "^5.4.1" - -node-addon-api@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - -node-releases@^1.1.71: - version "1.1.73" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" - integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== - -node-releases@^1.1.73: - version "1.1.74" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.74.tgz#e5866488080ebaa70a93b91144ccde06f3c3463e" - integrity sha512-caJBVempXZPepZoZAPCWRTNxYQ+xtG/KAi4ozTA5A+nJ7IU+kLQCbqaUjb5Rwy14M9upBWiQ4NutcmW04LJSRw== - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" - integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== - dependencies: - prepend-http "^2.0.0" - query-string "^5.0.1" - sort-keys "^2.0.0" - -normalize-url@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" - integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -npm-conf@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" - integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== - dependencies: - config-chain "^1.1.11" - pify "^3.0.0" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npmlog@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -nwsapi@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-hash@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" - integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== - -object-inspect@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" - integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.0, object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.values@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" - integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.2" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -optipng-bin@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/optipng-bin/-/optipng-bin-7.0.0.tgz#2dfcc68a5f006e7746e76ad64d317d6fb7c7f9ed" - integrity sha512-mesUAwfedu5p9gRQwlYgD6Svw5IH3VUIWDJj/9cNpP3yFNbbEVqkTMWYhrIEn/cxmbGA3LpZrdoV2Yl8OfmnIA== - dependencies: - bin-build "^3.0.0" - bin-wrapper "^4.0.0" - logalot "^2.0.0" - -ora@^5.3.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - -os-filter-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/os-filter-obj/-/os-filter-obj-2.0.0.tgz#1c0b62d5f3a2442749a2d139e6dddee6e81d8d16" - integrity sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg== - dependencies: - arch "^2.1.0" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-cancelable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" - integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== - -p-cancelable@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" - integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - -p-each-series@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" - integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== - -p-event@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-1.3.0.tgz#8e6b4f4f65c72bc5b6fe28b75eda874f96a4a085" - integrity sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU= - dependencies: - p-timeout "^1.1.1" - -p-event@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" - integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== - dependencies: - p-timeout "^2.0.1" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" - integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-map-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" - integrity sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco= - dependencies: - p-reduce "^1.0.0" - -p-pipe@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-4.0.0.tgz#7e5424569351b2ab452a47826acb93ce09ad6a2c" - integrity sha512-HkPfFklpZQPUKBFXzKFB6ihLriIHxnmuQdK9WmLDwe4hf2PdhhfWT/FJa+pc3bA1ywvKXtedxIRmd4Y7BTXE4w== - -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= - -p-timeout@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" - integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= - dependencies: - p-finally "^1.0.0" - -p-timeout@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" - integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== - dependencies: - p-finally "^1.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0, p-try@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-json@^6.3.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" - integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== - dependencies: - got "^9.6.0" - registry-auth-token "^4.0.0" - registry-url "^5.0.0" - semver "^6.2.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse5@6.0.1, parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -peek-readable@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.1.tgz#9a045f291db254111c3412c1ce4fec27ddd4d202" - integrity sha512-7qmhptnR0WMSpxT5rMHG9bW/mYSR1uqaPFj2MHvT+y/aOUu6msJijpKt5SkTDKySwg65OWG2JwTMBlgcbwMHrQ== - -pend@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" - integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pirates@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -png2icons@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/png2icons/-/png2icons-2.0.1.tgz#09d8f10b71302e98ca178d3324bc4deff9b90124" - integrity sha512-GDEQJr8OG4e6JMp7mABtXFSEpgJa1CCpbQiAR+EjhkHJHnUL9zPPtbOrjsMD8gUbikgv3j7x404b0YJsV3aVFA== - -prebuild-install@^6.1.2: - version "6.1.3" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.3.tgz#8ea1f9d7386a0b30f7ef20247e36f8b2b82825a2" - integrity sha512-iqqSR84tNYQUQHRXalSKdIaM8Ov1QxOVuBNWI7+BzZWv6Ih9k75wOnH1rGQ9WWTaaLkTpxWKIciOF0KyfM74+Q== - dependencies: - detect-libc "^1.0.3" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^2.21.0" - npmlog "^4.0.1" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^3.0.3" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -prettier@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" - integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== - -pretty-format@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.6.tgz#ab770c47b2c6f893a21aefc57b75da63ef49a11f" - integrity sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ== - dependencies: - "@jest/types" "^27.0.6" - ansi-regex "^5.0.0" - ansi-styles "^5.0.0" - react-is "^17.0.1" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" - integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q== - dependencies: - asap "~2.0.6" - -prompts@^2.0.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" - integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.33: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -pupa@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" - integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== - dependencies: - escape-goat "^2.0.0" - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -rc@^1.2.7, rc@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -read-chunk@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-3.2.0.tgz#2984afe78ca9bfbbdb74b19387bf9e86289c16ca" - integrity sha512-CEjy9LCzhmD7nUpJ1oVOE6s/hBkejlcJEgLQHVnQznOSilOPb+kpKktlLfFDK3/WP43+F80xkUTM2VOkYoSYvQ== - dependencies: - pify "^4.0.1" - with-open-file "^0.1.6" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -readable-stream@^2.0.0, readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-web-to-node-stream@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" - integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== - dependencies: - readable-stream "^3.6.0" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== - dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - -regenerator-transform@^0.14.2: - version "0.14.5" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" - integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== - dependencies: - "@babel/runtime" "^7.8.4" - -regexpp@^3.0.0, regexpp@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -regexpu-core@^4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" - integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" - -registry-auth-token@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" - integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== - dependencies: - rc "^1.2.8" - -registry-url@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" - integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== - dependencies: - rc "^1.2.8" - -regjsgen@^0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== - -regjsparser@^0.6.4: - version "0.6.9" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" - integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== - dependencies: - jsesc "~0.5.0" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -replace-ext@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-2.0.0.tgz#9471c213d22e1bcc26717cd6e50881d88f812b06" - integrity sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug== - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -resolve-alpn@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28" - integrity sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -responselike@1.0.2, responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - -responselike@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" - integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== - dependencies: - lowercase-keys "^2.0.0" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rimraf@^2.5.4: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -roarr@^2.15.3: - version "2.15.4" - resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd" - integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A== - dependencies: - boolean "^3.0.1" - detect-node "^2.0.4" - globalthis "^1.0.1" - json-stringify-safe "^5.0.1" - semver-compare "^1.0.0" - sprintf-js "^1.1.2" - -rollup-plugin-terser@7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" - integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== - dependencies: - "@babel/code-frame" "^7.10.4" - jest-worker "^26.2.1" - serialize-javascript "^4.0.0" - terser "^5.0.0" - -rollup@2.56.2: - version "2.56.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.56.2.tgz#a045ff3f6af53ee009b5f5016ca3da0329e5470f" - integrity sha512-s8H00ZsRi29M2/lGdm1u8DJpJ9ML8SUOpVVBd33XNeEeL3NVaTiUcSBHzBdF3eAyR0l7VSpsuoVUGrRHq7aPwQ== - optionalDependencies: - fsevents "~2.3.2" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rxjs@^6.4.0: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - -rxjs@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.2.0.tgz#5cd12409639e9514a71c9f5f9192b2c4ae94de31" - integrity sha512-aX8w9OpKrQmiPKfT1bqETtUr9JygIz6GZ+gql8v7CijClsP0laoFUdKzxFAoWuRdSlOdU2+crss+cMf+cqMTnw== - dependencies: - tslib "~2.1.0" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - -seek-bzip@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" - integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== - dependencies: - commander "^2.8.1" - -semver-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" - integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= - -semver-diff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" - integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== - dependencies: - semver "^6.3.0" - -semver-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" - integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== - -semver-truncate@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8" - integrity sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g= - dependencies: - semver "^5.3.0" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -semver@7.3.5, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -serialize-error@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18" - integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== - dependencies: - type-fest "^0.13.1" - -serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" - -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -sharp@0.28.3: - version "0.28.3" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.28.3.tgz#ecd74cefd020bee4891bb137c9850ee2ce277a8b" - integrity sha512-21GEP45Rmr7q2qcmdnjDkNP04Ooh5v0laGS5FDpojOO84D1DJwUijLiSq8XNNM6e8aGXYtoYRh3sVNdm8NodMA== - dependencies: - color "^3.1.3" - detect-libc "^1.0.3" - node-addon-api "^3.2.0" - prebuild-install "^6.1.2" - semver "^7.3.5" - simple-get "^3.1.0" - tar-fs "^2.1.1" - tunnel-agent "^0.6.0" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^3.0.3, simple-get@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" - integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== - dependencies: - decompress-response "^4.2.0" - once "^1.3.1" - simple-concat "^1.0.0" - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -sort-keys-length@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" - integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg= - dependencies: - sort-keys "^1.0.0" - -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= - dependencies: - is-plain-obj "^1.0.0" - -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= - dependencies: - is-plain-obj "^1.0.0" - -source-map-support@^0.5.6, source-map-support@~0.5.19: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.7.3, source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -sourcemap-codec@^1.4.4: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" - integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== - -sprintf-js@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -squeak@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/squeak/-/squeak-1.3.0.tgz#33045037b64388b567674b84322a6521073916c3" - integrity sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM= - dependencies: - chalk "^1.0.0" - console-stream "^0.1.1" - lpad-align "^1.0.1" - -stack-utils@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" - integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== - dependencies: - escape-string-regexp "^2.0.0" - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-dirs@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" - integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== - dependencies: - is-natural-number "^4.0.1" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= - dependencies: - get-stdin "^4.0.1" - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -strip-outer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" - integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== - dependencies: - escape-string-regexp "^1.0.2" - -strtok3@^6.2.4: - version "6.2.4" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.2.4.tgz#302aea64c0fa25d12a0385069ba66253fdc38a81" - integrity sha512-GO8IcFF9GmFDvqduIspUBwCzCbqzegyVKIsSymcMgiZKeCfrN9SowtUoi8+b59WZMAjIzVZic/Ft97+pynR3Iw== - dependencies: - "@tokenizer/token" "^0.3.0" - peek-readable "^4.0.1" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -table@^6.0.9: - version "6.7.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" - integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== - dependencies: - ajv "^8.0.1" - lodash.clonedeep "^4.5.0" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - -tar-fs@^2.0.0, tar-fs@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^1.5.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== - dependencies: - bl "^1.0.0" - buffer-alloc "^1.2.0" - end-of-stream "^1.0.0" - fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.1" - xtend "^4.0.0" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -temp-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= - -tempfile@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" - integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU= - dependencies: - temp-dir "^1.0.0" - uuid "^3.0.1" - -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - -terser@^5.0.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784" - integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.19" - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== - -through@^2.3.6, through@^2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timed-out@^4.0.0, timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= - -to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -token-types@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.1.1.tgz#ef9e8c8e2e0ded9f1b3f8dbaa46a3228b113ba1a" - integrity sha512-hD+QyuUAyI2spzsI0B7gf/jJ2ggR4RjkAo37j3StuePhApJUwcWDjnHDOFdIWYSwNR28H14hpwm4EI+V1Ted1w== - dependencies: - "@tokenizer/token" "^0.3.0" - ieee754 "^1.2.1" - -toml-loader@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toml-loader/-/toml-loader-1.0.0.tgz#05249b9294b623601148260caa480b22a653a19a" - integrity sha1-BSSbkpS2I2ARSCYMqkgLIqZToZo= - dependencies: - toml "^2.2.2" - -toml@^2.2.2: - version "2.3.6" - resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.6.tgz#25b0866483a9722474895559088b436fd11f861b" - integrity sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ== - -tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.1.2" - -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - -trim-newlines@4.0.2, trim-newlines@^1.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-4.0.2.tgz#d6aaaf6a0df1b4b536d183879a6b939489808c7c" - integrity sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew== - -trim-repeated@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" - integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= - dependencies: - escape-string-regexp "^1.0.2" - -tsconfig-paths@^3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" - integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -tslib@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== - -tslib@^1.8.1, tslib@^1.9.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" - integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typescript@4.3.5: - version "4.3.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - -unbzip2-stream@^1.0.9: - version "1.4.3" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" - integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== - dependencies: - buffer "^5.2.1" - through "^2.3.8" - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - -unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" - integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== - -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - -universalify@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -update-notifier@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" - integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== - dependencies: - boxen "^5.0.0" - chalk "^4.1.0" - configstore "^5.0.1" - has-yarn "^2.1.0" - import-lazy "^2.1.0" - is-ci "^2.0.0" - is-installed-globally "^0.4.0" - is-npm "^5.0.0" - is-yarn-global "^0.3.0" - latest-version "^5.1.0" - pupa "^2.1.1" - semver "^7.3.4" - semver-diff "^3.1.1" - xdg-basedir "^4.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -url-to-options@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" - integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@^3.0.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -v8-to-istanbul@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz#4229f2a99e367f3f018fa1d5c2b8ec684667c69c" - integrity sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - source-map "^0.7.3" - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - -walker@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= - dependencies: - makeerror "1.0.x" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.6.0.tgz#27c0205a4902084b872aecb97cf0f2a7a3011f4c" - integrity sha512-os0KkeeqUOl7ccdDT1qqUcS4KH4tcBTSKK5Nl5WKb2lyxInIZ/CpjkqKa1Ss12mjfdcRX9mHmPPs7/SxG1Hbdw== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -with-open-file@^0.1.6: - version "0.1.7" - resolved "https://registry.yarnpkg.com/with-open-file/-/with-open-file-0.1.7.tgz#e2de8d974e8a8ae6e58886be4fe8e7465b58a729" - integrity sha512-ecJS2/oHtESJ1t3ZfMI3B7KIDKyfN0O16miWxdn30zdh66Yd3LsRFebXZXq6GU4xfxLf6nVxp9kIqElb5fqczA== - dependencies: - p-finally "^1.0.0" - p-try "^2.1.0" - pify "^4.0.1" - -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -ws@^7.4.5: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -xdg-basedir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" - integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== - -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.7.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargs-parser@^20.2.2: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== - -yargs@^16.0.0, yargs@^16.0.3: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yauzl@^2.4.2: - version "2.10.0" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" - integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= - dependencies: - buffer-crc32 "~0.2.3" - fd-slicer "~1.1.0" - -zopflipng-bin@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/zopflipng-bin/-/zopflipng-bin-6.0.1.tgz#a91ef81bdba18e151dda3f34df23d3ecd7d04a1f" - integrity sha512-+aybvXv/xafL6I67uSH5yLHrSy4/OaSOV9tniw4yZFIHpINXUcctVHE/WzHxOONrL2GHzJ8Fd4iDrNyaS6TVbg== - dependencies: - bin-build "^3.0.0" - bin-wrapper "^4.0.1" - logalot "^2.1.0" diff --git a/tooling/cli.rs/Cargo.lock b/tooling/cli.rs/Cargo.lock deleted file mode 100755 index 7ed7f7e6ae2e..000000000000 --- a/tooling/cli.rs/Cargo.lock +++ /dev/null @@ -1,2435 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" - -[[package]] -name = "ar" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "450575f58f7bee32816abbff470cbc47797397c2a81e0eaced4b98436daf52e1" - -[[package]] -name = "attohttpc" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8bda305457262b339322106c776e3fd21df860018e566eb6a5b1aa4b6ae02d" -dependencies = [ - "flate2", - "http", - "log", - "native-tls", - "openssl", - "url", - "wildmatch", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bitflags" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da1976d75adbe5fbc88130ecd119529cf1cc6a93ae1546d8696ee66f0d21af1" - -[[package]] -name = "bitness" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57792b99d555ebf109c83169228076f7d997e2b37ba1a653850ccd703ac7bab0" -dependencies = [ - "sysctl", - "thiserror", - "uname", - "winapi 0.3.9", -] - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - -[[package]] -name = "bumpalo" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] -name = "bytemuck" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" - -[[package]] -name = "bzip2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "cc" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi 0.3.9", -] - -[[package]] -name = "chunked_transfer" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "clap" -version = "3.0.0-beta.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406" -dependencies = [ - "atty", - "bitflags", - "clap_derive", - "indexmap", - "lazy_static", - "os_str_bytes", - "strsim", - "termcolor", - "textwrap", - "vec_map", - "yaml-rust", -] - -[[package]] -name = "clap_derive" -version = "3.0.0-beta.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - -[[package]] -name = "colored" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" -dependencies = [ - "atty", - "lazy_static", - "winapi 0.3.9", -] - -[[package]] -name = "combine" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d47c1b11006b87e492b53b313bb699ce60e16613c4dddaa91f8f7c220ab2fa" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "core-foundation" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" - -[[package]] -name = "cpufeatures" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if 1.0.0", - "lazy_static", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array 0.14.4", - "subtle", -] - -[[package]] -name = "darling" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "757c0ded2af11d8e739c4daea1ac623dd1624b06c844cf3f5a39f1bdbd99bb12" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c34d8efb62d0c2d7f60ece80f75e5c63c1588ba68032740494b0b9a996466e3" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade7bff147130fe5e6d39f089c6bd49ec0250f35d70b2eebf72afdfc919f15cc" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "deflate" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" -dependencies = [ - "adler32", - "byteorder", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi 0.3.9", -] - -[[package]] -name = "dyn-clone" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] -name = "filetime" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall", - "winapi 0.3.9", -] - -[[package]] -name = "flate2" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "miniz_oxide 0.4.4", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "fsevent" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" -dependencies = [ - "bitflags", - "fsevent-sys", -] - -[[package]] -name = "fsevent-sys" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" -dependencies = [ - "libc", -] - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "gif" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a668f699973d0f573d15749b7002a9ac9e1f9c6b220e7b165601334c173d8de" -dependencies = [ - "color_quant", - "weezl", -] - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "handlebars" -version = "4.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd85ecabdb47308d28d3a4113224fefcab2510ccb4e463aee0a1362eb84c756a" -dependencies = [ - "log", - "pest", - "pest_derive", - "quick-error", - "serde", - "serde_json", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest 0.9.0", -] - -[[package]] -name = "http" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "icns" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ccfbad7e08da70a5b48a924994a5afd93125ce5d45a3b0ba0b8da7bda59a40" -dependencies = [ - "byteorder", - "png", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "image" -version = "0.23.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "gif", - "jpeg-decoder", - "num-iter", - "num-rational", - "num-traits", - "png", - "scoped_threadpool", - "tiff", -] - -[[package]] -name = "include_dir" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31a924bd335356c7622dff9ee33d06920afcf7f762a1a991236645e08c8a484b" -dependencies = [ - "glob", - "include_dir_impl", - "proc-macro-hack", -] - -[[package]] -name = "include_dir_impl" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afae3917f781921d7c7813992ccadff7e816f7e6ecb4b70a9ec3e740d51da3d6" -dependencies = [ - "anyhow", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "inotify" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" -dependencies = [ - "bitflags", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "itoa" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "jpeg-decoder" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" -dependencies = [ - "rayon", -] - -[[package]] -name = "js-sys" -version = "0.3.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json-patch" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" -dependencies = [ - "serde", - "serde_json", - "treediff", -] - -[[package]] -name = "json-pointer" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe841b94e719a482213cee19dd04927cf412f26d8dc84c5a446c081e49c2997" -dependencies = [ - "serde_json", -] - -[[package]] -name = "jsonway" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effcb749443c905fbaef49d214f8b1049c240e0adb7af9baa0e201e625e4f9de" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" - -[[package]] -name = "libflate" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d87eae36b3f680f7f01645121b782798b56ef33c53f83d1c66ba3a22b60bfe3" -dependencies = [ - "adler32", - "crc32fast", - "libflate_lz77", -] - -[[package]] -name = "libflate_lz77" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a734c0493409afcd49deee13c006a04e3586b9761a03543c6272c9c51f2f5a" -dependencies = [ - "rle-decode-fast", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" - -[[package]] -name = "memchr" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" - -[[package]] -name = "memoffset" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" -dependencies = [ - "autocfg", -] - -[[package]] -name = "minisign" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7701e737ba365ae6a551155687d3697b759512c27ec6d0f56e283826fb20f2c2" -dependencies = [ - "getrandom 0.2.3", - "rpassword", - "scrypt", -] - -[[package]] -name = "miniz_oxide" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" -dependencies = [ - "adler32", -] - -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg", -] - -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-extras" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" -dependencies = [ - "lazycell", - "log", - "mio", - "slab", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - -[[package]] -name = "native-tls" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "net2" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "notify" -version = "4.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" -dependencies = [ - "bitflags", - "filetime", - "fsevent", - "fsevent-sys", - "inotify", - "libc", - "mio", - "mio-extras", - "walkdir", - "winapi 0.3.9", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" - -[[package]] -name = "openssl-sys" -version = "0.9.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "os_info" -version = "3.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac91020bfed8cc3f8aa450d4c3b5fa1d3373fc091c8a92009f3b27749d5a227" -dependencies = [ - "log", - "serde", - "winapi 0.3.9", -] - -[[package]] -name = "os_str_bytes" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d" - -[[package]] -name = "pbkdf2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" -dependencies = [ - "crypto-mac", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" -dependencies = [ - "maplit", - "pest", - "sha-1", -] - -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_shared", -] - -[[package]] -name = "phf_codegen" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" -dependencies = [ - "phf_generator", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared", - "rand 0.7.3", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pkg-config" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" - -[[package]] -name = "png" -version = "0.16.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" -dependencies = [ - "bitflags", - "crc32fast", - "deflate", - "miniz_oxide 0.3.7", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "publicsuffix" -version = "1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b4ce31ff0a27d93c8de1849cf58162283752f065a90d508f1105fa6c9a213f" -dependencies = [ - "idna", - "url", -] - -[[package]] -name = "quick-error" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg", -] - -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", - "rand_hc 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rayon" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" -dependencies = [ - "getrandom 0.2.3", - "redox_syscall", -] - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi 0.3.9", -] - -[[package]] -name = "rle-decode-fast" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" - -[[package]] -name = "rpassword" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" -dependencies = [ - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64", - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "rustversion" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "salsa20" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecbd2eb639fd7cab5804a0837fe373cc2172d15437e804c054a9fb885cb923b0" -dependencies = [ - "cipher", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi 0.3.9", -] - -[[package]] -name = "schemars" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902fdfbcf871ae8f653bddf4b2c05905ddaabc08f69d32a915787e3be0d31356" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "scoped_threadpool" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scrypt" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879588d8f90906e73302547e20fffefdd240eb3e0e744e142321f5d49dea0518" -dependencies = [ - "hmac", - "pbkdf2", - "salsa20", - "sha2", -] - -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "security-framework" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" - -[[package]] -name = "serde" -version = "1.0.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_derive_internals" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad9fdbb69badc8916db738c25efd04f0a65297d26c2f8de4b62e57b8c12bc72" -dependencies = [ - "rustversion", - "serde", - "serde_with_macros", -] - -[[package]] -name = "serde_with_macros" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1569374bd54623ec8bd592cf22ba6e03c0f177ff55fbc8c29a49e296e7adecf" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - -[[package]] -name = "sha2" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - -[[package]] -name = "shared_child" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6be9f7d5565b1483af3e72975e2dee33879b3b86bd48c0929fccf6585d79e65a" -dependencies = [ - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "siphasher" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" - -[[package]] -name = "slab" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "sysctl" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963488c73b34185a9028742c2be0219ed1d8558e59f85c3b466a4f54affba936" -dependencies = [ - "bitflags", - "byteorder", - "libc", - "thiserror", - "walkdir", -] - -[[package]] -name = "tar" -version = "0.4.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "tauri-bundler" -version = "1.0.0-beta.4" -dependencies = [ - "anyhow", - "ar", - "attohttpc", - "bitness", - "chrono", - "dirs-next", - "glob", - "handlebars", - "heck", - "hex", - "icns", - "image", - "libflate", - "md5", - "regex", - "serde", - "serde_json", - "sha2", - "strsim", - "tar", - "tempfile", - "termcolor", - "thiserror", - "toml", - "uuid", - "walkdir", - "winreg", - "zip", -] - -[[package]] -name = "tauri-cli" -version = "1.0.0-beta.7" -dependencies = [ - "anyhow", - "base64", - "clap", - "colored", - "encode_unicode", - "handlebars", - "heck", - "include_dir", - "json-patch", - "lazy_static", - "libc", - "minisign", - "notify", - "once_cell", - "os_info", - "regex", - "schemars", - "semver", - "serde", - "serde_json", - "serde_with", - "shared_child", - "tauri-bundler", - "tempfile", - "terminal_size", - "toml", - "toml_edit", - "unicode-width", - "ureq", - "valico", - "winapi 0.3.9", - "zeroize", -] - -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "rand 0.8.4", - "redox_syscall", - "remove_dir_all", - "winapi 0.3.9", -] - -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "terminal_size" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" -dependencies = [ - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "textwrap" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tiff" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" -dependencies = [ - "jpeg-decoder", - "miniz_oxide 0.4.4", - "weezl", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "tinyvec" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "toml" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbdcf4f749dd33b1f1ea19b547bf789d87442ec40767d6015e5e2d39158d69a" -dependencies = [ - "chrono", - "combine", - "linked-hash-map", -] - -[[package]] -name = "treediff" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" -dependencies = [ - "serde_json", -] - -[[package]] -name = "typenum" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "uname" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" -dependencies = [ - "libc", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "ureq" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2475a6781e9bc546e7b64f4013d2f4032c8c6a40fcffd7c6f4ee734a890972ab" -dependencies = [ - "base64", - "chunked_transfer", - "log", - "once_cell", - "rustls", - "url", - "webpki", - "webpki-roots", -] - -[[package]] -name = "uritemplate-next" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcde98d1fc3f528255b1ecb22fb688ee0d23deb672a8c57127df10b98b4bd18c" -dependencies = [ - "regex", -] - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom 0.2.3", - "sha1", -] - -[[package]] -name = "valico" -version = "3.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d81a70f930f9e6cd04669d38abcf232f96b193acceb0f4c006427ddec6e08b10" -dependencies = [ - "base64", - "chrono", - "json-pointer", - "jsonway", - "percent-encoding", - "phf", - "phf_codegen", - "publicsuffix", - "regex", - "serde", - "serde_json", - "uritemplate-next", - "url", - "uuid", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi 0.3.9", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasm-bindgen" -version = "0.2.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2" - -[[package]] -name = "web-sys" -version = "0.3.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki", -] - -[[package]] -name = "weezl" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" - -[[package]] -name = "wildmatch" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "winreg" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16cdb3898397cf7f624c294948669beafaeebc5577d5ec53d0afb76633593597" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "xattr" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" -dependencies = [ - "libc", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "zeroize" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" - -[[package]] -name = "zip" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" -dependencies = [ - "byteorder", - "bzip2", - "crc32fast", - "flate2", - "thiserror", - "time", -] diff --git a/tooling/cli.rs/Cargo.toml b/tooling/cli.rs/Cargo.toml deleted file mode 100644 index 544c7f636881..000000000000 --- a/tooling/cli.rs/Cargo.toml +++ /dev/null @@ -1,64 +0,0 @@ -workspace = { } - -[package] -name = "tauri-cli" -version = "1.0.0-beta.7" -authors = [ "Tauri Programme within The Commons Conservancy" ] -edition = "2018" -categories = [ "gui", "web-programming" ] -license = "Apache-2.0 OR MIT" -homepage = "https://tauri.studio" -repository = "https://github.com/tauri-apps/tauri" -description = "Command line interface for building Tauri apps" -include = [ "src/", "/templates", "MergeModules/", "*.json", "*.rs" ] - -[[bin]] -name = "cargo-tauri" -path = "src/main.rs" - -[dependencies] -clap = { version = "3.0.0-beta.2", features = [ "yaml" ] } -anyhow = "1.0" -tauri-bundler = { version = "1.0.0-beta.4", path = "../bundler" } -colored = "2.0" -once_cell = "1.8" -serde = { version = "1.0", features = [ "derive" ] } -serde_json = "1.0" -serde_with = "1.9" -notify = "4.0" -shared_child = "0.3" -toml_edit = "0.2" -json-patch = "0.2" -schemars = "0.8" -toml = "0.5" -valico = "3.6" -handlebars = "4.1" -include_dir = "0.6" -minisign = "0.6" -base64 = "0.13.0" -ureq = "2.1" -os_info = "3.0" -semver = "1.0" -regex = "1.5" -lazy_static = "1" -libc = "0.2" -terminal_size = "0.1" -unicode-width = "0.1" -tempfile = "3" -zeroize = "1.4" - -[target."cfg(windows)".dependencies] -winapi = { version = "0.3", features = [ "winbase", "winuser", "consoleapi", "processenv", "wincon" ] } -encode_unicode = "0.3" - -[target."cfg(target_os = \"linux\")".dependencies] -heck = "0.3" - -[target."cfg(target_os = \"linux\")".build-dependencies] -heck = "0.3" - -[build-dependencies] -schemars = "0.8" -serde = { version = "1.0", features = [ "derive" ] } -serde_json = "1.0" -serde_with = "1.9" diff --git a/tooling/cli.rs/build.rs b/tooling/cli.rs/build.rs deleted file mode 100644 index 919166014389..000000000000 --- a/tooling/cli.rs/build.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::{ - env::current_dir, - error::Error, - fs::File, - io::{BufWriter, Write}, -}; - -mod config_definition; - -pub fn main() -> Result<(), Box> { - let schema = schemars::schema_for!(config_definition::Config); - let schema_file_path = current_dir()?.join("schema.json"); - let mut schema_file = BufWriter::new(File::create(&schema_file_path)?); - write!( - schema_file, - "{}", - serde_json::to_string_pretty(&schema).unwrap() - )?; - - Ok(()) -} diff --git a/tooling/cli.rs/config_definition.rs b/tooling/cli.rs/config_definition.rs deleted file mode 100644 index 16cee4e3ad80..000000000000 --- a/tooling/cli.rs/config_definition.rs +++ /dev/null @@ -1,880 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -#![allow(clippy::field_reassign_with_default)] - -#[cfg(target_os = "linux")] -use heck::KebabCase; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use serde_json::Value as JsonValue; -use serde_with::skip_serializing_none; - -use std::{collections::HashMap, path::PathBuf}; - -#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(untagged)] -pub enum BundleTarget { - All(Vec), - One(String), -} - -impl BundleTarget { - #[allow(dead_code)] - pub fn to_vec(&self) -> Vec { - match self { - Self::All(list) => list.clone(), - Self::One(i) => vec![i.clone()], - } - } -} - -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct DebConfig { - /// The list of deb dependencies your application relies on. - pub depends: Option>, - /// Enable the boostrapper script. - #[serde(default)] - pub use_bootstrapper: bool, - /// The files to include on the package. - #[serde(default)] - pub files: HashMap, -} - -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct MacConfig { - /// A list of strings indicating any macOS X frameworks that need to be bundled with the application. - /// - /// If a name is used, ".framework" must be omitted and it will look for standard install locations. You may also use a path to a specific framework. - pub frameworks: Option>, - /// A version string indicating the minimum macOS X version that the bundled application supports. - pub minimum_system_version: Option, - /// Allows your application to communicate with the outside world. - /// It should be a lowercase, without port and protocol domain name. - pub exception_domain: Option, - /// The path to the license file to add to the DMG bundle. - pub license: Option, - /// Enable the boostrapper script. - #[serde(default)] - pub use_bootstrapper: bool, - /// Identity to use for code signing. - pub signing_identity: Option, - /// Path to the entitlements file. - pub entitlements: Option, -} - -fn default_language() -> String { - "en-US".into() -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct WixConfig { - /// The installer language. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables. - #[serde(default = "default_language")] - pub language: String, - /// A custom .wxs template to use. - pub template: Option, - /// A list of paths to .wxs files with WiX fragments to use. - #[serde(default)] - pub fragment_paths: Vec, - /// The ComponentGroup element ids you want to reference from the fragments. - #[serde(default)] - pub component_group_refs: Vec, - /// The Component element ids you want to reference from the fragments. - #[serde(default)] - pub component_refs: Vec, - /// The FeatureGroup element ids you want to reference from the fragments. - #[serde(default)] - pub feature_group_refs: Vec, - /// The Feature element ids you want to reference from the fragments. - #[serde(default)] - pub feature_refs: Vec, - /// The Merge element ids you want to reference from the fragments. - #[serde(default)] - pub merge_refs: Vec, - /// Disables the Webview2 runtime installation after app install. - #[serde(default)] - pub skip_webview_install: bool, - /// The path to the license file to render on the installer. - /// - /// Must be an RTF file, so if a different extension is provided, we convert it to the RTF format. - pub license: Option, - #[serde(default)] - pub enable_elevated_update_task: bool, - /// Path to a bitmap file to use as the installation user interface banner. - /// This bitmap will appear at the top of all but the first page of the installer. - /// - /// The required dimensions are 493px × 58px. - pub banner_path: Option, - /// Path to a bitmap file to use on the installation user interface dialogs. - /// It is used on the welcome and completion dialogs. - - /// The required dimensions are 493px × 312px. - pub dialog_image_path: Option, -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct WindowsConfig { - /// Specifies the file digest algorithm to use for creating file signatures. - /// Required for code signing. SHA-256 is recommended. - pub digest_algorithm: Option, - /// Specifies the SHA1 hash of the signing certificate. - pub certificate_thumbprint: Option, - /// Server to use during timestamping. - pub timestamp_url: Option, - /// Configuration for the MSI generated with WiX. - pub wix: Option, -} - -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct PackageConfig { - /// Application name. Automatically converted to kebab-case on Linux. - pub product_name: Option, - /// Application version. - pub version: Option, -} - -impl PackageConfig { - #[allow(dead_code)] - pub fn binary_name(&self) -> Option { - #[cfg(target_os = "linux")] - { - self.product_name.as_ref().map(|n| n.to_kebab_case()) - } - #[cfg(not(target_os = "linux"))] - { - self.product_name.clone() - } - } -} - -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct BundleConfig { - /// Whether we should build your app with tauri-bundler or plain `cargo build` - #[serde(default)] - pub active: bool, - /// The bundle targets, currently supports ["deb", "app", "msi", "appimage", "dmg"] or "all" - pub targets: Option, - /// The app's identifier - pub identifier: Option, - /// The app's icons - pub icon: Option>, - /// App resources to bundle. - /// Each resource is a path to a file or directory. - /// Glob patterns are supported. - pub resources: Option>, - /// A copyright string associated with your application. - pub copyright: Option, - /// The application kind. - pub category: Option, - /// A short description of your application. - pub short_description: Option, - /// A longer, multi-line description of the application. - pub long_description: Option, - /// Configuration for the Debian bundle. - #[serde(default)] - pub deb: DebConfig, - /// Configuration for the macOS bundles. - #[serde(rename = "macOS", default)] - pub macos: MacConfig, - /// A list of—either absolute or relative—paths to binaries to embed with your application. - /// - /// Note that Tauri will look for system-specific binaries following the pattern "binary-name{-target-triple}{.system-extension}". - /// - /// E.g. for the external binary "my-binary", Tauri looks for: - /// - /// - "my-binary-x86_64-pc-windows-msvc.exe" for Windows - /// - "my-binary-x86_64-apple-darwin" for macOS - /// - "my-binary-x86_64-unknown-linux-gnu" for Linux - /// - /// so don't forget to provide binaries for all targeted platforms. - pub external_bin: Option>, - /// Configuration for the Windows bundle. - #[serde(default)] - pub windows: WindowsConfig, -} - -/// A CLI argument definition -#[skip_serializing_none] -#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct CliArg { - /// The short version of the argument, without the preceding -. - /// - /// NOTE: Any leading - characters will be stripped, and only the first non - character will be used as the short version. - pub short: Option, - /// The unique argument name - pub name: String, - /// The argument description which will be shown on the help information. - /// Typically, this is a short (one line) description of the arg. - pub description: Option, - /// The argument long description which will be shown on the help information. - /// Typically this a more detailed (multi-line) message that describes the argument. - pub long_description: Option, - /// Specifies that the argument takes a value at run time. - /// - /// NOTE: values for arguments may be specified in any of the following methods - /// - Using a space such as -o value or --option value - /// - Using an equals and no space such as -o=value or --option=value - /// - Use a short and no space such as -ovalue - pub takes_value: Option, - /// Specifies that the argument may appear more than once. - /// - /// - For flags, this results in the number of occurrences of the flag being recorded. - /// For example -ddd or -d -d -d would count as three occurrences. - /// - For options there is a distinct difference in multiple occurrences vs multiple values. - /// For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences. - pub multiple: Option, - /// specifies that the argument may appear more than once. - pub multiple_occurrences: Option, - /// - pub number_of_values: Option, - /// Specifies a list of possible values for this argument. - /// At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message. - pub possible_values: Option>, - /// Specifies the minimum number of values for this argument. - /// For example, if you had a -f argument where you wanted at least 2 'files', - /// you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values. - pub min_values: Option, - /// Specifies the maximum number of values are for this argument. - /// For example, if you had a -f argument where you wanted up to 3 'files', - /// you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values. - pub max_values: Option, - /// Sets whether or not the argument is required by default. - /// - /// - Required by default means it is required, when no other conflicting rules have been evaluated - /// - Conflicting rules take precedence over being required. - pub required: Option, - /// Sets an arg that override this arg's required setting - /// i.e. this arg will be required unless this other argument is present. - pub required_unless_present: Option, - /// Sets args that override this arg's required setting - /// i.e. this arg will be required unless all these other arguments are present. - pub required_unless_present_all: Option>, - /// Sets args that override this arg's required setting - /// i.e. this arg will be required unless at least one of these other arguments are present. - pub required_unless_present_any: Option>, - /// Sets a conflicting argument by name - /// i.e. when using this argument, the following argument can't be present and vice versa. - pub conflicts_with: Option, - /// The same as conflictsWith but allows specifying multiple two-way conflicts per argument. - pub conflicts_with_all: Option>, - /// Tets an argument by name that is required when this one is present - /// i.e. when using this argument, the following argument must be present. - pub requires: Option, - /// Sts multiple arguments by names that are required when this one is present - /// i.e. when using this argument, the following arguments must be present. - pub requires_all: Option>, - /// Allows a conditional requirement with the signature [arg, value] - /// the requirement will only become valid if `arg`'s value equals `${value}`. - pub requires_if: Option>, - /// Allows specifying that an argument is required conditionally with the signature [arg, value] - /// the requirement will only become valid if the `arg`'s value equals `${value}`. - pub required_if_eq: Option>, - /// Requires that options use the --option=val syntax - /// i.e. an equals between the option and associated value. - pub require_equals: Option, - /// The positional argument index, starting at 1. - /// - /// The index refers to position according to other positional argument. - /// It does not define position in the argument list as a whole. When utilized with multiple=true, - /// only the last positional argument may be defined as multiple (i.e. the one with the highest index). - pub index: Option, -} - -/// describes a CLI configuration -#[skip_serializing_none] -#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct CliConfig { - /// command description which will be shown on the help information - description: Option, - /// command long description which will be shown on the help information - long_description: Option, - /// adds additional help information to be displayed in addition to auto-generated help - /// this information is displayed before the auto-generated help information. - /// this is often used for header information - before_help: Option, - /// adds additional help information to be displayed in addition to auto-generated help - /// this information is displayed after the auto-generated help information - /// this is often used to describe how to use the arguments, or caveats to be noted. - after_help: Option, - /// list of args for the command - args: Option>, - /// list of subcommands of this command. - /// - /// subcommands are effectively sub-apps, because they can contain their own arguments, subcommands, usage, etc. - /// they also function just like the app command, in that they get their own auto generated help and usage - subcommands: Option>, -} - -#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(untagged)] -pub enum Port { - /// Port with a numeric value. - Value(u16), - /// Random port. - Random, -} - -/// The window configuration object. -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct WindowConfig { - /// The window identifier. - pub label: Option, - /// The window webview URL. - pub url: Option, - /// Whether the file drop is enabled or not on the webview. By default it is enabled. - /// - /// Disabling it is required to use drag and drop on the frontend on Windows. - #[serde(default = "default_file_drop_enabled")] - pub file_drop_enabled: bool, - /// Whether or not the window starts centered or not. - #[serde(default)] - pub center: bool, - /// The horizontal position of the window's top left corner - pub x: Option, - /// The vertical position of the window's top left corner - pub y: Option, - /// The window width. - pub width: Option, - /// The window height. - pub height: Option, - /// The min window width. - pub min_width: Option, - /// The min window height. - pub min_height: Option, - /// The max window width. - pub max_width: Option, - /// The max window height. - pub max_height: Option, - /// Whether the window is resizable or not. - #[serde(default)] - pub resizable: bool, - /// The window title. - pub title: Option, - /// Whether the window starts as fullscreen or not. - #[serde(default)] - pub fullscreen: bool, - /// Whether the window will be initially hidden or focused. - #[serde(default = "default_focus")] - pub focus: bool, - /// Whether the window is transparent or not. - #[serde(default)] - pub transparent: bool, - /// Whether the window is maximized or not. - #[serde(default)] - pub maximized: bool, - /// Whether the window is visible or not. - #[serde(default = "default_visible")] - pub visible: bool, - /// Whether the window should have borders and bars. - #[serde(default = "default_decorations")] - pub decorations: bool, - /// Whether the window should always be on top of other windows. - #[serde(default)] - pub always_on_top: bool, - /// Whether or not the window icon should be added to the taskbar. - #[serde(default)] - pub skip_taskbar: bool, -} - -fn default_focus() -> bool { - true -} - -fn default_visible() -> bool { - true -} - -fn default_decorations() -> bool { - true -} - -fn default_file_drop_enabled() -> bool { - true -} - -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct SecurityConfig { - /// The Content Security Policy that will be injected on all HTML files. - /// - /// This is a really important part of the configuration since it helps you ensure your WebView is secured. - /// See https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP. - pub csp: Option, -} - -pub trait Allowlist { - fn to_features(&self) -> Vec<&str>; -} - -macro_rules! check_feature { - ($self:ident, $features:ident, $flag:ident, $feature_name: expr) => { - if $self.$flag { - $features.push($feature_name) - } - }; -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct FsAllowlistConfig { - /// Use this flag to enable all file system API features. - #[serde(default)] - pub all: bool, - /// Read text file from local filesystem. - #[serde(default)] - pub read_text_file: bool, - /// Read binary file from local filesystem. - #[serde(default)] - pub read_binary_file: bool, - /// Write text file to local filesystem. - #[serde(default)] - pub write_file: bool, - /// Write binary file to local filesystem. - #[serde(default)] - pub write_binary_file: bool, - /// Read directory from local filesystem. - #[serde(default)] - pub read_dir: bool, - /// Copy file from local filesystem. - #[serde(default)] - pub copy_file: bool, - /// Create directory from local filesystem. - #[serde(default)] - pub create_dir: bool, - /// Remove directory from local filesystem. - #[serde(default)] - pub remove_dir: bool, - /// Remove file from local filesystem. - #[serde(default)] - pub remove_file: bool, - /// Rename file from local filesystem. - #[serde(default)] - pub rename_file: bool, -} - -impl Allowlist for FsAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["fs-all"] - } else { - let mut features = Vec::new(); - check_feature!(self, features, read_text_file, "fs-read-text-file"); - check_feature!(self, features, read_binary_file, "fs-read-binary-file"); - check_feature!(self, features, write_file, "fs-write-file"); - check_feature!(self, features, write_binary_file, "fs-write-binary-file"); - check_feature!(self, features, read_dir, "fs-read-dir"); - check_feature!(self, features, copy_file, "fs-copy-file"); - check_feature!(self, features, create_dir, "fs-create-dir"); - check_feature!(self, features, remove_dir, "fs-remove-dir"); - check_feature!(self, features, remove_file, "fs-remove-file"); - check_feature!(self, features, rename_file, "fs-rename-file"); - features - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct WindowAllowlistConfig { - /// Use this flag to enable all window API features. - #[serde(default)] - pub all: bool, - /// Allows dynamic window creation. - #[serde(default)] - pub create: bool, -} - -impl Allowlist for WindowAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["window-all"] - } else { - let mut features = Vec::new(); - check_feature!(self, features, create, "window-create"); - features - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct ShellAllowlistConfig { - /// Use this flag to enable all shell API features. - #[serde(default)] - pub all: bool, - /// Enable binary execution. - #[serde(default)] - pub execute: bool, - /// Open URL with the user's default application. - #[serde(default)] - pub open: bool, -} - -impl Allowlist for ShellAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["shell-all"] - } else { - let mut features = Vec::new(); - check_feature!(self, features, execute, "shell-execute"); - check_feature!(self, features, open, "shell-open"); - features - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct DialogAllowlistConfig { - /// Use this flag to enable all dialog API features. - #[serde(default)] - pub all: bool, - /// Open dialog window to pick files. - #[serde(default)] - pub open: bool, - /// Open dialog window to pick where to save files. - #[serde(default)] - pub save: bool, -} - -impl Allowlist for DialogAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["dialog-all"] - } else { - let mut features = Vec::new(); - check_feature!(self, features, open, "dialog-open"); - check_feature!(self, features, save, "dialog-save"); - features - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct HttpAllowlistConfig { - /// Use this flag to enable all HTTP API features. - #[serde(default)] - pub all: bool, - /// Allows making HTTP requests. - #[serde(default)] - pub request: bool, -} - -impl Allowlist for HttpAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["http-all"] - } else { - let mut features = Vec::new(); - check_feature!(self, features, request, "http-request"); - features - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct NotificationAllowlistConfig { - /// Use this flag to enable all notification API features. - #[serde(default)] - pub all: bool, -} - -impl Allowlist for NotificationAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["notification-all"] - } else { - vec![] - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct GlobalShortcutAllowlistConfig { - /// Use this flag to enable all global shortcut API features. - #[serde(default)] - pub all: bool, -} - -impl Allowlist for GlobalShortcutAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["global-shortcut-all"] - } else { - vec![] - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct OsAllowlistConfig { - /// Use this flag to enable all OS API features. - #[serde(default)] - pub all: bool, -} - -impl Allowlist for OsAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["os-all"] - } else { - vec![] - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct PathAllowlistConfig { - /// Use this flag to enable all path API features. - #[serde(default)] - pub all: bool, -} - -impl Allowlist for PathAllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["path-all"] - } else { - vec![] - } - } -} - -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct AllowlistConfig { - /// Use this flag to enable all API features. - #[serde(default)] - pub all: bool, - /// File system API allowlist. - #[serde(default)] - pub fs: FsAllowlistConfig, - /// Window API allowlist. - #[serde(default)] - pub window: WindowAllowlistConfig, - /// Shell API allowlist. - #[serde(default)] - pub shell: ShellAllowlistConfig, - /// Dialog API allowlist. - #[serde(default)] - pub dialog: DialogAllowlistConfig, - /// HTTP API allowlist. - #[serde(default)] - pub http: HttpAllowlistConfig, - /// Notification API allowlist. - #[serde(default)] - pub notification: NotificationAllowlistConfig, - /// Global shortcut API allowlist. - #[serde(default)] - pub global_shortcut: GlobalShortcutAllowlistConfig, - /// OS allowlist. - #[serde(default)] - pub os: OsAllowlistConfig, - /// Path API allowlist. - #[serde(default)] - pub path: PathAllowlistConfig, -} - -impl Allowlist for AllowlistConfig { - fn to_features(&self) -> Vec<&str> { - if self.all { - vec!["api-all"] - } else { - let mut features = Vec::new(); - features.extend(self.fs.to_features()); - features.extend(self.window.to_features()); - features.extend(self.shell.to_features()); - features.extend(self.dialog.to_features()); - features.extend(self.http.to_features()); - features.extend(self.notification.to_features()); - features.extend(self.global_shortcut.to_features()); - features.extend(self.os.to_features()); - features.extend(self.path.to_features()); - features - } - } -} - -/// The Tauri configuration object. -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct TauriConfig { - /// The windows configuration. - #[serde(default)] - pub windows: Vec, - /// The CLI configuration. - pub cli: Option, - /// The bundler configuration. - #[serde(default)] - pub bundle: BundleConfig, - /// The allowlist configuration. - #[serde(default)] - allowlist: AllowlistConfig, - /// Security configuration. - pub security: Option, - /// The updater configuration. - #[serde(default = "default_updater")] - pub updater: UpdaterConfig, - /// Configuration for app system tray. - pub system_tray: Option, -} - -impl TauriConfig { - #[allow(dead_code)] - pub fn features(&self) -> Vec<&str> { - self.allowlist.to_features() - } -} - -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct UpdaterConfig { - /// Whether the updater is active or not. - #[serde(default)] - pub active: bool, - /// Display built-in dialog or use event system if disabled. - #[serde(default = "default_dialog")] - pub dialog: Option, - /// The updater endpoints. - pub endpoints: Option>, - /// Optional pubkey. - pub pubkey: Option, -} - -#[skip_serializing_none] -#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct SystemTrayConfig { - /// Path to the icon to use on the system tray. - /// - /// It is forced to be a `.png` file on Linux and macOS, and a `.ico` file on Windows. - pub icon_path: PathBuf, - /// A Boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS. - #[serde(default)] - pub icon_as_template: bool, -} - -// We enable the unnecessary_wraps because we need -// to use an Option for dialog otherwise the CLI schema will mark -// the dialog as a required field which is not as we default it to true. -#[allow(clippy::unnecessary_wraps)] -fn default_dialog() -> Option { - Some(true) -} - -/// The `dev_path` and `dist_dir` options. -#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(untagged, deny_unknown_fields)] -pub enum AppUrl { - /// The app's external URL, or the path to the directory containing the app assets. - Url(String), - /// An array of files to embed on the app. - Files(Vec), -} - -impl std::fmt::Display for AppUrl { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Url(url) => write!(f, "{}", url), - Self::Files(files) => write!(f, "{}", serde_json::to_string(files).unwrap()), - } - } -} - -/// The Build configuration object. -#[skip_serializing_none] -#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct BuildConfig { - /// The binary used to build and run the application. - pub runner: Option, - /// The path or URL to use on development. - #[serde(default = "default_dev_path")] - pub dev_path: AppUrl, - /// the path to the app's dist dir. This path must contain your index.html file. - #[serde(default = "default_dist_dir")] - pub dist_dir: AppUrl, - /// a shell command to run before `tauri dev` kicks in - pub before_dev_command: Option, - /// a shell command to run before `tauri build` kicks in - pub before_build_command: Option, - /// features passed to `cargo` commands - pub features: Option>, - /// Whether we should inject the Tauri API on `window.__TAURI__` or not. - #[serde(default)] - pub with_global_tauri: bool, -} - -fn default_dev_path() -> AppUrl { - AppUrl::Url("".to_string()) -} - -fn default_dist_dir() -> AppUrl { - AppUrl::Url("../dist".to_string()) -} - -type JsonObject = HashMap; - -/// The tauri.conf.json mapper. -#[skip_serializing_none] -#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub struct Config { - /// Package settings. - #[serde(default)] - pub package: PackageConfig, - /// The Tauri configuration. - #[serde(default)] - pub tauri: TauriConfig, - /// The build configuration. - #[serde(default = "default_build")] - pub build: BuildConfig, - /// The plugins config. - #[serde(default)] - pub plugins: HashMap, -} - -fn default_build() -> BuildConfig { - BuildConfig { - runner: None, - dev_path: default_dev_path(), - dist_dir: default_dist_dir(), - before_dev_command: None, - before_build_command: None, - features: None, - with_global_tauri: false, - } -} - -fn default_updater() -> UpdaterConfig { - UpdaterConfig { - active: false, - dialog: Some(true), - endpoints: None, - pubkey: None, - } -} diff --git a/tooling/cli.rs/metadata.json b/tooling/cli.rs/metadata.json deleted file mode 100644 index a63f63eb60e0..000000000000 --- a/tooling/cli.rs/metadata.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "cli.js": { - "version": "1.0.0-beta.10", - "node": ">= 12.13.0" - }, - "tauri": "1.0.0-beta.8", - "tauri-build": "1.0.0-beta.4" -} diff --git a/tooling/cli.rs/schema.json b/tooling/cli.rs/schema.json deleted file mode 100644 index 55606c527229..000000000000 --- a/tooling/cli.rs/schema.json +++ /dev/null @@ -1,1481 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Config", - "description": "The tauri.conf.json mapper.", - "type": "object", - "properties": { - "build": { - "description": "The build configuration.", - "default": { - "devPath": "", - "distDir": "../dist", - "withGlobalTauri": false - }, - "allOf": [ - { - "$ref": "#/definitions/BuildConfig" - } - ] - }, - "package": { - "description": "Package settings.", - "default": {}, - "allOf": [ - { - "$ref": "#/definitions/PackageConfig" - } - ] - }, - "plugins": { - "description": "The plugins config.", - "default": {}, - "type": "object", - "additionalProperties": { - "type": "object", - "additionalProperties": true - } - }, - "tauri": { - "description": "The Tauri configuration.", - "default": { - "allowlist": { - "all": false, - "dialog": { - "all": false, - "open": false, - "save": false - }, - "fs": { - "all": false, - "copyFile": false, - "createDir": false, - "readBinaryFile": false, - "readDir": false, - "readTextFile": false, - "removeDir": false, - "removeFile": false, - "renameFile": false, - "writeBinaryFile": false, - "writeFile": false - }, - "globalShortcut": { - "all": false - }, - "http": { - "all": false, - "request": false - }, - "notification": { - "all": false - }, - "os": { - "all": false - }, - "path": { - "all": false - }, - "shell": { - "all": false, - "execute": false, - "open": false - }, - "window": { - "all": false, - "create": false - } - }, - "bundle": { - "active": false, - "deb": { - "files": {}, - "useBootstrapper": false - }, - "macOS": { - "useBootstrapper": false - }, - "windows": { - "certificateThumbprint": null, - "digestAlgorithm": null, - "timestampUrl": null, - "wix": null - } - }, - "updater": { - "active": false - }, - "windows": [] - }, - "allOf": [ - { - "$ref": "#/definitions/TauriConfig" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all API features.", - "default": false, - "type": "boolean" - }, - "dialog": { - "description": "Dialog API allowlist.", - "default": { - "all": false, - "open": false, - "save": false - }, - "allOf": [ - { - "$ref": "#/definitions/DialogAllowlistConfig" - } - ] - }, - "fs": { - "description": "File system API allowlist.", - "default": { - "all": false, - "copyFile": false, - "createDir": false, - "readBinaryFile": false, - "readDir": false, - "readTextFile": false, - "removeDir": false, - "removeFile": false, - "renameFile": false, - "writeBinaryFile": false, - "writeFile": false - }, - "allOf": [ - { - "$ref": "#/definitions/FsAllowlistConfig" - } - ] - }, - "globalShortcut": { - "description": "Global shortcut API allowlist.", - "default": { - "all": false - }, - "allOf": [ - { - "$ref": "#/definitions/GlobalShortcutAllowlistConfig" - } - ] - }, - "http": { - "description": "HTTP API allowlist.", - "default": { - "all": false, - "request": false - }, - "allOf": [ - { - "$ref": "#/definitions/HttpAllowlistConfig" - } - ] - }, - "notification": { - "description": "Notification API allowlist.", - "default": { - "all": false - }, - "allOf": [ - { - "$ref": "#/definitions/NotificationAllowlistConfig" - } - ] - }, - "os": { - "description": "OS allowlist.", - "default": { - "all": false - }, - "allOf": [ - { - "$ref": "#/definitions/OsAllowlistConfig" - } - ] - }, - "path": { - "description": "Path API allowlist.", - "default": { - "all": false - }, - "allOf": [ - { - "$ref": "#/definitions/PathAllowlistConfig" - } - ] - }, - "shell": { - "description": "Shell API allowlist.", - "default": { - "all": false, - "execute": false, - "open": false - }, - "allOf": [ - { - "$ref": "#/definitions/ShellAllowlistConfig" - } - ] - }, - "window": { - "description": "Window API allowlist.", - "default": { - "all": false, - "create": false - }, - "allOf": [ - { - "$ref": "#/definitions/WindowAllowlistConfig" - } - ] - } - }, - "additionalProperties": false - }, - "AppUrl": { - "description": "The `dev_path` and `dist_dir` options.", - "anyOf": [ - { - "description": "The app's external URL, or the path to the directory containing the app assets.", - "type": "string" - }, - { - "description": "An array of files to embed on the app.", - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "BuildConfig": { - "description": "The Build configuration object.", - "type": "object", - "properties": { - "beforeBuildCommand": { - "description": "a shell command to run before `tauri build` kicks in", - "type": [ - "string", - "null" - ] - }, - "beforeDevCommand": { - "description": "a shell command to run before `tauri dev` kicks in", - "type": [ - "string", - "null" - ] - }, - "devPath": { - "description": "The path or URL to use on development.", - "default": "", - "allOf": [ - { - "$ref": "#/definitions/AppUrl" - } - ] - }, - "distDir": { - "description": "the path to the app's dist dir. This path must contain your index.html file.", - "default": "../dist", - "allOf": [ - { - "$ref": "#/definitions/AppUrl" - } - ] - }, - "features": { - "description": "features passed to `cargo` commands", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "runner": { - "description": "The binary used to build and run the application.", - "type": [ - "string", - "null" - ] - }, - "withGlobalTauri": { - "description": "Whether we should inject the Tauri API on `window.__TAURI__` or not.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "BundleConfig": { - "type": "object", - "properties": { - "active": { - "description": "Whether we should build your app with tauri-bundler or plain `cargo build`", - "default": false, - "type": "boolean" - }, - "category": { - "description": "The application kind.", - "type": [ - "string", - "null" - ] - }, - "copyright": { - "description": "A copyright string associated with your application.", - "type": [ - "string", - "null" - ] - }, - "deb": { - "description": "Configuration for the Debian bundle.", - "default": { - "files": {}, - "useBootstrapper": false - }, - "allOf": [ - { - "$ref": "#/definitions/DebConfig" - } - ] - }, - "externalBin": { - "description": "A list of—either absolute or relative—paths to binaries to embed with your application.\n\nNote that Tauri will look for system-specific binaries following the pattern \"binary-name{-target-triple}{.system-extension}\".\n\nE.g. for the external binary \"my-binary\", Tauri looks for:\n\n- \"my-binary-x86_64-pc-windows-msvc.exe\" for Windows - \"my-binary-x86_64-apple-darwin\" for macOS - \"my-binary-x86_64-unknown-linux-gnu\" for Linux\n\nso don't forget to provide binaries for all targeted platforms.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "icon": { - "description": "The app's icons", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "identifier": { - "description": "The app's identifier", - "type": [ - "string", - "null" - ] - }, - "longDescription": { - "description": "A longer, multi-line description of the application.", - "type": [ - "string", - "null" - ] - }, - "macOS": { - "description": "Configuration for the macOS bundles.", - "default": { - "useBootstrapper": false - }, - "allOf": [ - { - "$ref": "#/definitions/MacConfig" - } - ] - }, - "resources": { - "description": "App resources to bundle. Each resource is a path to a file or directory. Glob patterns are supported.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "shortDescription": { - "description": "A short description of your application.", - "type": [ - "string", - "null" - ] - }, - "targets": { - "description": "The bundle targets, currently supports [\"deb\", \"app\", \"msi\", \"appimage\", \"dmg\"] or \"all\"", - "anyOf": [ - { - "$ref": "#/definitions/BundleTarget" - }, - { - "type": "null" - } - ] - }, - "windows": { - "description": "Configuration for the Windows bundle.", - "default": { - "certificateThumbprint": null, - "digestAlgorithm": null, - "timestampUrl": null, - "wix": null - }, - "allOf": [ - { - "$ref": "#/definitions/WindowsConfig" - } - ] - } - }, - "additionalProperties": false - }, - "BundleTarget": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "string" - } - ] - }, - "CliArg": { - "description": "A CLI argument definition", - "type": "object", - "required": [ - "name" - ], - "properties": { - "conflictsWith": { - "description": "Sets a conflicting argument by name i.e. when using this argument, the following argument can't be present and vice versa.", - "type": [ - "string", - "null" - ] - }, - "conflictsWithAll": { - "description": "The same as conflictsWith but allows specifying multiple two-way conflicts per argument.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "description": { - "description": "The argument description which will be shown on the help information. Typically, this is a short (one line) description of the arg.", - "type": [ - "string", - "null" - ] - }, - "index": { - "description": "The positional argument index, starting at 1.\n\nThe index refers to position according to other positional argument. It does not define position in the argument list as a whole. When utilized with multiple=true, only the last positional argument may be defined as multiple (i.e. the one with the highest index).", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "longDescription": { - "description": "The argument long description which will be shown on the help information. Typically this a more detailed (multi-line) message that describes the argument.", - "type": [ - "string", - "null" - ] - }, - "maxValues": { - "description": "Specifies the maximum number of values are for this argument. For example, if you had a -f argument where you wanted up to 3 'files', you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values.", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "minValues": { - "description": "Specifies the minimum number of values for this argument. For example, if you had a -f argument where you wanted at least 2 'files', you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values.", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "multiple": { - "description": "Specifies that the argument may appear more than once.\n\n- For flags, this results in the number of occurrences of the flag being recorded. For example -ddd or -d -d -d would count as three occurrences. - For options there is a distinct difference in multiple occurrences vs multiple values. For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences.", - "type": [ - "boolean", - "null" - ] - }, - "multipleOccurrences": { - "description": "specifies that the argument may appear more than once.", - "type": [ - "boolean", - "null" - ] - }, - "name": { - "description": "The unique argument name", - "type": "string" - }, - "numberOfValues": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "possibleValues": { - "description": "Specifies a list of possible values for this argument. At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "requireEquals": { - "description": "Requires that options use the --option=val syntax i.e. an equals between the option and associated value.", - "type": [ - "boolean", - "null" - ] - }, - "required": { - "description": "Sets whether or not the argument is required by default.\n\n- Required by default means it is required, when no other conflicting rules have been evaluated - Conflicting rules take precedence over being required.", - "type": [ - "boolean", - "null" - ] - }, - "requiredIfEq": { - "description": "Allows specifying that an argument is required conditionally with the signature [arg, value] the requirement will only become valid if the `arg`'s value equals `${value}`.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "requiredUnlessPresent": { - "description": "Sets an arg that override this arg's required setting i.e. this arg will be required unless this other argument is present.", - "type": [ - "string", - "null" - ] - }, - "requiredUnlessPresentAll": { - "description": "Sets args that override this arg's required setting i.e. this arg will be required unless all these other arguments are present.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "requiredUnlessPresentAny": { - "description": "Sets args that override this arg's required setting i.e. this arg will be required unless at least one of these other arguments are present.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "requires": { - "description": "Tets an argument by name that is required when this one is present i.e. when using this argument, the following argument must be present.", - "type": [ - "string", - "null" - ] - }, - "requiresAll": { - "description": "Sts multiple arguments by names that are required when this one is present i.e. when using this argument, the following arguments must be present.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "requiresIf": { - "description": "Allows a conditional requirement with the signature [arg, value] the requirement will only become valid if `arg`'s value equals `${value}`.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "short": { - "description": "The short version of the argument, without the preceding -.\n\nNOTE: Any leading - characters will be stripped, and only the first non - character will be used as the short version.", - "type": [ - "string", - "null" - ], - "maxLength": 1, - "minLength": 1 - }, - "takesValue": { - "description": "Specifies that the argument takes a value at run time.\n\nNOTE: values for arguments may be specified in any of the following methods - Using a space such as -o value or --option value - Using an equals and no space such as -o=value or --option=value - Use a short and no space such as -ovalue", - "type": [ - "boolean", - "null" - ] - } - }, - "additionalProperties": false - }, - "CliConfig": { - "description": "describes a CLI configuration", - "type": "object", - "properties": { - "afterHelp": { - "description": "adds additional help information to be displayed in addition to auto-generated help this information is displayed after the auto-generated help information this is often used to describe how to use the arguments, or caveats to be noted.", - "type": [ - "string", - "null" - ] - }, - "args": { - "description": "list of args for the command", - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/CliArg" - } - }, - "beforeHelp": { - "description": "adds additional help information to be displayed in addition to auto-generated help this information is displayed before the auto-generated help information. this is often used for header information", - "type": [ - "string", - "null" - ] - }, - "description": { - "description": "command description which will be shown on the help information", - "type": [ - "string", - "null" - ] - }, - "longDescription": { - "description": "command long description which will be shown on the help information", - "type": [ - "string", - "null" - ] - }, - "subcommands": { - "description": "list of subcommands of this command.\n\nsubcommands are effectively sub-apps, because they can contain their own arguments, subcommands, usage, etc. they also function just like the app command, in that they get their own auto generated help and usage", - "type": [ - "object", - "null" - ], - "additionalProperties": { - "$ref": "#/definitions/CliConfig" - } - } - }, - "additionalProperties": false - }, - "DebConfig": { - "type": "object", - "properties": { - "depends": { - "description": "The list of deb dependencies your application relies on.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "files": { - "description": "The files to include on the package.", - "default": {}, - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "useBootstrapper": { - "description": "Enable the boostrapper script.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "DialogAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all dialog API features.", - "default": false, - "type": "boolean" - }, - "open": { - "description": "Open dialog window to pick files.", - "default": false, - "type": "boolean" - }, - "save": { - "description": "Open dialog window to pick where to save files.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "FsAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all file system API features.", - "default": false, - "type": "boolean" - }, - "copyFile": { - "description": "Copy file from local filesystem.", - "default": false, - "type": "boolean" - }, - "createDir": { - "description": "Create directory from local filesystem.", - "default": false, - "type": "boolean" - }, - "readBinaryFile": { - "description": "Read binary file from local filesystem.", - "default": false, - "type": "boolean" - }, - "readDir": { - "description": "Read directory from local filesystem.", - "default": false, - "type": "boolean" - }, - "readTextFile": { - "description": "Read text file from local filesystem.", - "default": false, - "type": "boolean" - }, - "removeDir": { - "description": "Remove directory from local filesystem.", - "default": false, - "type": "boolean" - }, - "removeFile": { - "description": "Remove file from local filesystem.", - "default": false, - "type": "boolean" - }, - "renameFile": { - "description": "Rename file from local filesystem.", - "default": false, - "type": "boolean" - }, - "writeBinaryFile": { - "description": "Write binary file to local filesystem.", - "default": false, - "type": "boolean" - }, - "writeFile": { - "description": "Write text file to local filesystem.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "GlobalShortcutAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all global shortcut API features.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "HttpAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all HTTP API features.", - "default": false, - "type": "boolean" - }, - "request": { - "description": "Allows making HTTP requests.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "MacConfig": { - "type": "object", - "properties": { - "entitlements": { - "description": "Path to the entitlements file.", - "type": [ - "string", - "null" - ] - }, - "exceptionDomain": { - "description": "Allows your application to communicate with the outside world. It should be a lowercase, without port and protocol domain name.", - "type": [ - "string", - "null" - ] - }, - "frameworks": { - "description": "A list of strings indicating any macOS X frameworks that need to be bundled with the application.\n\nIf a name is used, \".framework\" must be omitted and it will look for standard install locations. You may also use a path to a specific framework.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "license": { - "description": "The path to the license file to add to the DMG bundle.", - "type": [ - "string", - "null" - ] - }, - "minimumSystemVersion": { - "description": "A version string indicating the minimum macOS X version that the bundled application supports.", - "type": [ - "string", - "null" - ] - }, - "signingIdentity": { - "description": "Identity to use for code signing.", - "type": [ - "string", - "null" - ] - }, - "useBootstrapper": { - "description": "Enable the boostrapper script.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "NotificationAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all notification API features.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "OsAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all OS API features.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "PackageConfig": { - "type": "object", - "properties": { - "productName": { - "description": "Application name. Automatically converted to kebab-case on Linux.", - "type": [ - "string", - "null" - ] - }, - "version": { - "description": "Application version.", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "PathAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all path API features.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "SecurityConfig": { - "type": "object", - "properties": { - "csp": { - "description": "The Content Security Policy that will be injected on all HTML files.\n\nThis is a really important part of the configuration since it helps you ensure your WebView is secured. See https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP.", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "ShellAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all shell API features.", - "default": false, - "type": "boolean" - }, - "execute": { - "description": "Enable binary execution.", - "default": false, - "type": "boolean" - }, - "open": { - "description": "Open URL with the user's default application.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "SystemTrayConfig": { - "type": "object", - "required": [ - "iconPath" - ], - "properties": { - "iconAsTemplate": { - "description": "A Boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS.", - "default": false, - "type": "boolean" - }, - "iconPath": { - "description": "Path to the icon to use on the system tray.\n\nIt is forced to be a `.png` file on Linux and macOS, and a `.ico` file on Windows.", - "type": "string" - } - }, - "additionalProperties": false - }, - "TauriConfig": { - "description": "The Tauri configuration object.", - "type": "object", - "properties": { - "allowlist": { - "description": "The allowlist configuration.", - "default": { - "all": false, - "dialog": { - "all": false, - "open": false, - "save": false - }, - "fs": { - "all": false, - "copyFile": false, - "createDir": false, - "readBinaryFile": false, - "readDir": false, - "readTextFile": false, - "removeDir": false, - "removeFile": false, - "renameFile": false, - "writeBinaryFile": false, - "writeFile": false - }, - "globalShortcut": { - "all": false - }, - "http": { - "all": false, - "request": false - }, - "notification": { - "all": false - }, - "os": { - "all": false - }, - "path": { - "all": false - }, - "shell": { - "all": false, - "execute": false, - "open": false - }, - "window": { - "all": false, - "create": false - } - }, - "allOf": [ - { - "$ref": "#/definitions/AllowlistConfig" - } - ] - }, - "bundle": { - "description": "The bundler configuration.", - "default": { - "active": false, - "deb": { - "files": {}, - "useBootstrapper": false - }, - "macOS": { - "useBootstrapper": false - }, - "windows": { - "certificateThumbprint": null, - "digestAlgorithm": null, - "timestampUrl": null, - "wix": null - } - }, - "allOf": [ - { - "$ref": "#/definitions/BundleConfig" - } - ] - }, - "cli": { - "description": "The CLI configuration.", - "anyOf": [ - { - "$ref": "#/definitions/CliConfig" - }, - { - "type": "null" - } - ] - }, - "security": { - "description": "Security configuration.", - "anyOf": [ - { - "$ref": "#/definitions/SecurityConfig" - }, - { - "type": "null" - } - ] - }, - "systemTray": { - "description": "Configuration for app system tray.", - "anyOf": [ - { - "$ref": "#/definitions/SystemTrayConfig" - }, - { - "type": "null" - } - ] - }, - "updater": { - "description": "The updater configuration.", - "default": { - "active": false, - "dialog": true - }, - "allOf": [ - { - "$ref": "#/definitions/UpdaterConfig" - } - ] - }, - "windows": { - "description": "The windows configuration.", - "default": [], - "type": "array", - "items": { - "$ref": "#/definitions/WindowConfig" - } - } - }, - "additionalProperties": false - }, - "UpdaterConfig": { - "type": "object", - "properties": { - "active": { - "description": "Whether the updater is active or not.", - "default": false, - "type": "boolean" - }, - "dialog": { - "description": "Display built-in dialog or use event system if disabled.", - "default": true, - "type": [ - "boolean", - "null" - ] - }, - "endpoints": { - "description": "The updater endpoints.", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "pubkey": { - "description": "Optional pubkey.", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "WindowAllowlistConfig": { - "type": "object", - "properties": { - "all": { - "description": "Use this flag to enable all window API features.", - "default": false, - "type": "boolean" - }, - "create": { - "description": "Allows dynamic window creation.", - "default": false, - "type": "boolean" - } - }, - "additionalProperties": false - }, - "WindowConfig": { - "description": "The window configuration object.", - "type": "object", - "properties": { - "alwaysOnTop": { - "description": "Whether the window should always be on top of other windows.", - "default": false, - "type": "boolean" - }, - "center": { - "description": "Whether or not the window starts centered or not.", - "default": false, - "type": "boolean" - }, - "decorations": { - "description": "Whether the window should have borders and bars.", - "default": true, - "type": "boolean" - }, - "fileDropEnabled": { - "description": "Whether the file drop is enabled or not on the webview. By default it is enabled.\n\nDisabling it is required to use drag and drop on the frontend on Windows.", - "default": true, - "type": "boolean" - }, - "focus": { - "description": "Whether the window will be initially hidden or focused.", - "default": true, - "type": "boolean" - }, - "fullscreen": { - "description": "Whether the window starts as fullscreen or not.", - "default": false, - "type": "boolean" - }, - "height": { - "description": "The window height.", - "type": [ - "number", - "null" - ], - "format": "double" - }, - "label": { - "description": "The window identifier.", - "type": [ - "string", - "null" - ] - }, - "maxHeight": { - "description": "The max window height.", - "type": [ - "number", - "null" - ], - "format": "double" - }, - "maxWidth": { - "description": "The max window width.", - "type": [ - "number", - "null" - ], - "format": "double" - }, - "maximized": { - "description": "Whether the window is maximized or not.", - "default": false, - "type": "boolean" - }, - "minHeight": { - "description": "The min window height.", - "type": [ - "number", - "null" - ], - "format": "double" - }, - "minWidth": { - "description": "The min window width.", - "type": [ - "number", - "null" - ], - "format": "double" - }, - "resizable": { - "description": "Whether the window is resizable or not.", - "default": false, - "type": "boolean" - }, - "skipTaskbar": { - "description": "Whether or not the window icon should be added to the taskbar.", - "default": false, - "type": "boolean" - }, - "title": { - "description": "The window title.", - "type": [ - "string", - "null" - ] - }, - "transparent": { - "description": "Whether the window is transparent or not.", - "default": false, - "type": "boolean" - }, - "url": { - "description": "The window webview URL.", - "type": [ - "string", - "null" - ] - }, - "visible": { - "description": "Whether the window is visible or not.", - "default": true, - "type": "boolean" - }, - "width": { - "description": "The window width.", - "type": [ - "number", - "null" - ], - "format": "double" - }, - "x": { - "description": "The horizontal position of the window's top left corner", - "type": [ - "number", - "null" - ], - "format": "double" - }, - "y": { - "description": "The vertical position of the window's top left corner", - "type": [ - "number", - "null" - ], - "format": "double" - } - }, - "additionalProperties": false - }, - "WindowsConfig": { - "type": "object", - "properties": { - "certificateThumbprint": { - "description": "Specifies the SHA1 hash of the signing certificate.", - "type": [ - "string", - "null" - ] - }, - "digestAlgorithm": { - "description": "Specifies the file digest algorithm to use for creating file signatures. Required for code signing. SHA-256 is recommended.", - "type": [ - "string", - "null" - ] - }, - "timestampUrl": { - "description": "Server to use during timestamping.", - "type": [ - "string", - "null" - ] - }, - "wix": { - "description": "Configuration for the MSI generated with WiX.", - "anyOf": [ - { - "$ref": "#/definitions/WixConfig" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "WixConfig": { - "type": "object", - "properties": { - "bannerPath": { - "description": "Path to a bitmap file to use as the installation user interface banner. This bitmap will appear at the top of all but the first page of the installer.\n\nThe required dimensions are 493px × 58px.", - "type": [ - "string", - "null" - ] - }, - "componentGroupRefs": { - "description": "The ComponentGroup element ids you want to reference from the fragments.", - "default": [], - "type": "array", - "items": { - "type": "string" - } - }, - "componentRefs": { - "description": "The Component element ids you want to reference from the fragments.", - "default": [], - "type": "array", - "items": { - "type": "string" - } - }, - "dialogImagePath": { - "description": "Path to a bitmap file to use on the installation user interface dialogs. It is used on the welcome and completion dialogs. The required dimensions are 493px × 312px.", - "type": [ - "string", - "null" - ] - }, - "enableElevatedUpdateTask": { - "default": false, - "type": "boolean" - }, - "featureGroupRefs": { - "description": "The FeatureGroup element ids you want to reference from the fragments.", - "default": [], - "type": "array", - "items": { - "type": "string" - } - }, - "featureRefs": { - "description": "The Feature element ids you want to reference from the fragments.", - "default": [], - "type": "array", - "items": { - "type": "string" - } - }, - "fragmentPaths": { - "description": "A list of paths to .wxs files with WiX fragments to use.", - "default": [], - "type": "array", - "items": { - "type": "string" - } - }, - "language": { - "description": "The installer language. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables.", - "default": "en-US", - "type": "string" - }, - "license": { - "description": "The path to the license file to render on the installer.\n\nMust be an RTF file, so if a different extension is provided, we convert it to the RTF format.", - "type": [ - "string", - "null" - ] - }, - "mergeRefs": { - "description": "The Merge element ids you want to reference from the fragments.", - "default": [], - "type": "array", - "items": { - "type": "string" - } - }, - "skipWebviewInstall": { - "description": "Disables the Webview2 runtime installation after app install.", - "default": false, - "type": "boolean" - }, - "template": { - "description": "A custom .wxs template to use.", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} \ No newline at end of file diff --git a/tooling/cli.rs/src/build.rs b/tooling/cli.rs/src/build.rs deleted file mode 100644 index 0abc6a825c8d..000000000000 --- a/tooling/cli.rs/src/build.rs +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use anyhow::Context; -#[cfg(target_os = "linux")] -use heck::KebabCase; -use tauri_bundler::bundle::{bundle_project, PackageType}; - -use crate::helpers::{ - app_paths::{app_dir, tauri_dir}, - config::{get as get_config, AppUrl}, - execute_with_output, - manifest::rewrite_manifest, - updater_signature::sign_file_from_env_variables, - Logger, -}; - -use std::{env::set_current_dir, fs::rename, path::PathBuf, process::Command}; - -#[derive(Default)] -pub struct Build { - runner: Option, - debug: bool, - verbose: bool, - target: Option, - features: Option>, - bundles: Option>, - config: Option, -} - -impl Build { - pub fn new() -> Self { - Default::default() - } - - pub fn debug(mut self) -> Self { - self.debug = true; - self - } - - pub fn verbose(mut self) -> Self { - self.verbose = true; - self - } - - pub fn runner(mut self, runner: String) -> Self { - self.runner.replace(runner); - self - } - - pub fn target(mut self, target: String) -> Self { - self.target.replace(target); - self - } - - pub fn features(mut self, features: Vec) -> Self { - self.features.replace(features); - self - } - - pub fn bundles(mut self, bundles: Vec) -> Self { - self.bundles.replace(bundles); - self - } - - pub fn config(mut self, config: String) -> Self { - self.config.replace(config); - self - } - - pub fn run(self) -> crate::Result<()> { - let logger = Logger::new("tauri:build"); - let config = get_config(self.config.as_deref())?; - - let tauri_path = tauri_dir(); - set_current_dir(&tauri_path).with_context(|| "failed to change current working directory")?; - - let manifest = rewrite_manifest(config.clone())?; - - let config_guard = config.lock().unwrap(); - let config_ = config_guard.as_ref().unwrap(); - - if let Some(before_build) = &config_.build.before_build_command { - if !before_build.is_empty() { - logger.log(format!("Running `{}`", before_build)); - #[cfg(target_os = "windows")] - execute_with_output( - &mut Command::new("cmd") - .arg("/C") - .arg(before_build) - .current_dir(app_dir()), - ) - .with_context(|| format!("failed to run `{}` with `cmd /C`", before_build))?; - #[cfg(not(target_os = "windows"))] - execute_with_output( - &mut Command::new("sh") - .arg("-c") - .arg(before_build) - .current_dir(app_dir()), - ) - .with_context(|| format!("failed to run `{}` with `sh -c`", before_build))?; - } - } - - if let AppUrl::Url(url) = &config_.build.dist_dir { - let web_asset_path = PathBuf::from(url); - if !web_asset_path.exists() { - return Err(anyhow::anyhow!( - "Unable to find your web assets, did you forget to build your web app? Your distDir is set to \"{:?}\".", - web_asset_path - )); - } - } - - let runner_from_config = config_.build.runner.clone(); - let runner = self - .runner - .or(runner_from_config) - .unwrap_or_else(|| "cargo".to_string()); - - let mut cargo_features = config_.build.features.clone().unwrap_or_default(); - if let Some(features) = self.features { - cargo_features.extend(features); - } - - crate::interface::rust::build_project(runner, &self.target, cargo_features, self.debug) - .with_context(|| "failed to build app")?; - - let app_settings = crate::interface::rust::AppSettings::new(config_)?; - - let out_dir = app_settings - .get_out_dir(self.target.clone(), self.debug) - .with_context(|| "failed to get project out directory")?; - if let Some(product_name) = config_.package.product_name.clone() { - let bin_name = app_settings.cargo_package_settings().name.clone(); - #[cfg(windows)] - let (bin_path, product_path) = { - ( - out_dir.join(format!("{}.exe", bin_name)), - out_dir.join(format!("{}.exe", product_name)), - ) - }; - #[cfg(target_os = "macos")] - let (bin_path, product_path) = { (out_dir.join(bin_name), out_dir.join(product_name)) }; - #[cfg(target_os = "linux")] - let (bin_path, product_path) = { - ( - out_dir.join(bin_name), - out_dir.join(product_name.to_kebab_case()), - ) - }; - rename(&bin_path, &product_path).with_context(|| { - format!( - "failed to rename `{}` to `{}`", - bin_path.display(), - product_path.display(), - ) - })?; - } - - if config_.tauri.bundle.active { - // move merge modules to the out dir so the bundler can load it - #[cfg(windows)] - { - let arch = if let Some(t) = &self.target { - if t.starts_with("x86_64") { - "x86_64" - } else if t.starts_with('i') { - "x86" - } else if t.starts_with("arm") { - "arm" - } else if t.starts_with("aarch64") { - "aarch64" - } else { - panic!("Unexpected target triple {}", t) - } - } else if cfg!(target_arch = "x86") { - "x86" - } else { - "x86_64" - }; - let (filename, vcruntime_msm) = if arch == "x86" { - let _ = std::fs::remove_file(out_dir.join("Microsoft_VC142_CRT_x64.msm")); - ( - "Microsoft_VC142_CRT_x86.msm", - include_bytes!("../MergeModules/Microsoft_VC142_CRT_x86.msm").to_vec(), - ) - } else { - let _ = std::fs::remove_file(out_dir.join("Microsoft_VC142_CRT_x86.msm")); - ( - "Microsoft_VC142_CRT_x64.msm", - include_bytes!("../MergeModules/Microsoft_VC142_CRT_x64.msm").to_vec(), - ) - }; - std::fs::write(out_dir.join(filename), vcruntime_msm)?; - } - - let package_types = if let Some(names) = self.bundles { - let mut types = vec![]; - for name in names { - if name == "none" { - break; - } - match PackageType::from_short_name(&name) { - Some(package_type) => { - types.push(package_type); - } - None => { - return Err(anyhow::anyhow!(format!( - "Unsupported bundle format: {}", - name - ))); - } - } - } - Some(types) - } else if let Some(targets) = &config_.tauri.bundle.targets { - let mut types = vec![]; - let targets = targets.to_vec(); - if !targets.contains(&"all".into()) { - for name in targets { - match PackageType::from_short_name(&name) { - Some(package_type) => { - types.push(package_type); - } - None => { - return Err(anyhow::anyhow!(format!( - "Unsupported bundle format: {}", - name - ))); - } - } - } - Some(types) - } else { - None - } - } else { - None - }; - - let settings = crate::interface::get_bundler_settings( - app_settings, - self.target.clone(), - &manifest, - config_, - &out_dir, - self.verbose, - package_types, - ) - .with_context(|| "failed to build bundler settings")?; - - settings.copy_resources(&out_dir)?; - settings.copy_binaries(&out_dir)?; - - let bundles = bundle_project(settings).with_context(|| "failed to bundle project")?; - - // If updater is active and pubkey is available - if config_.tauri.updater.active && config_.tauri.updater.pubkey.is_some() { - // make sure we have our package builts - let mut signed_paths = Vec::new(); - for elem in bundles - .iter() - .filter(|bundle| bundle.package_type == PackageType::Updater) - { - // we expect to have only one path in the vec but we iter if we add - // another type of updater package who require multiple file signature - for path in elem.bundle_paths.iter() { - // sign our path from environment variables - let (signature_path, _signature) = sign_file_from_env_variables(path)?; - signed_paths.append(&mut vec![signature_path]); - } - } - if !signed_paths.is_empty() { - print_signed_updater_archive(&signed_paths)?; - } - } - } - - Ok(()) - } -} - -fn print_signed_updater_archive(output_paths: &[PathBuf]) -> crate::Result<()> { - let pluralised = if output_paths.len() == 1 { - "updater archive" - } else { - "updater archives" - }; - let msg = format!("{} {} at:", output_paths.len(), pluralised); - let logger = Logger::new("Signed"); - logger.log(&msg); - for path in output_paths { - println!(" {}", path.display()); - } - Ok(()) -} diff --git a/tooling/cli.rs/src/cli.yml b/tooling/cli.rs/src/cli.yml deleted file mode 100644 index 41cedfc891e7..000000000000 --- a/tooling/cli.rs/src/cli.yml +++ /dev/null @@ -1,173 +0,0 @@ -name: cargo-tauri -bin_name: cargo tauri -author: Tauri Programme within The Commons Conservancy. -about: The Tauri command line interface. -subcommands: - - dev: - about: Tauri dev. - setting: TrailingVarArg - args: - - runner: - short: r - long: runner - about: binary to use to run the application - takes_value: true - - config: - short: c - long: config - about: config JSON to merge with tauri.conf.json - takes_value: true - - exit-on-panic: - short: e - long: exit-on-panic - about: Exit on panic - - target: - short: t - long: target - about: target triple to build against - takes_value: true - multiple_values: true - - features: - short: f - long: features - about: list of cargo features to activate - takes_value: true - multiple_values: true - - args: - about: Args passed to the binary - index: 1 - takes_value: true - multiple_values: true - - release: - long: release - about: Run the code in release mode - - build: - about: Tauri build. - args: - - runner: - short: r - long: runner - about: binary to use to build the application - takes_value: true - - debug: - short: d - long: debug - about: Builds with the debug flag - - verbose: - short: v - long: verbose - about: Enables verbose logging - - bundle: - short: b - long: bundle - about: list of bundles to package - takes_value: true - multiple_values: true - - config: - short: c - long: config - about: config JSON to merge with tauri.conf.json - takes_value: true - - target: - short: t - long: target - about: target triple to build against - takes_value: true - multiple_values: true - - features: - short: f - long: features - about: list of cargo features to activate - takes_value: true - multiple_values: true - - sign: - about: Tauri updates signer. - args: - - generate: - short: g - long: generate - about: Generate keypair to sign files - - sign-file: - long: sign-file - about: Sign the specified file - takes_value: true - - private-key-path: - short: f - long: private-key-path - about: Load the private key from a file - takes_value: true - conflicts_with: private-key - - private-key: - short: k - long: private-key - about: Load the private key from a string - takes_value: true - conflicts_with: private-key-path - requires: sign-file - - write-keys: - short: w - long: write-keys - about: Write private key to a file - takes_value: true - requires: generate - - password: - short: p - long: password - about: Set private key password when signing - takes_value: true - conflicts_with: no-password - - no-password: - long: no-password - about: Set empty password for your private key - conflicts_with: password - - force: - long: force - about: Overwrite private key even if it exists on the specified path - requires: generate - - - info: - about: Shows information about Tauri dependencies - - init: - about: Initializes a Tauri project - args: - - ci: - long: ci - about: Skip prompting for values - - force: - short: f - long: force - about: Force init to overwrite the src-tauri folder - - log: - short: l - long: log - about: Enables logging - - directory: - short: d - long: directory - about: Set target directory for init - takes_value: true - - tauri-path: - short: t - long: tauri-path - about: Path of the Tauri project to use (relative to the cwd) - takes_value: true - - app-name: - short: A - long: app-name - about: Name of your Tauri application - takes_value: true - - window-title: - short: W - long: window-title - about: Window title of your Tauri application - takes_value: true - - dist-dir: - short: D - long: dist-dir - about: Web assets location, relative to /src-tauri - takes_value: true - - dev-path: - short: P - long: dev-path - about: Url of your dev server - takes_value: true diff --git a/tooling/cli.rs/src/console/ansi.rs b/tooling/cli.rs/src/console/ansi.rs deleted file mode 100644 index b4109e77b5a2..000000000000 --- a/tooling/cli.rs/src/console/ansi.rs +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::borrow::Cow; - -use regex::{Matches, Regex}; - -lazy_static::lazy_static! { - static ref STRIP_ANSI_RE: Regex = - Regex::new(r"[\x1b\x9b]([()][012AB]|[\[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><])") - .unwrap(); -} - -/// Helper function to strip ansi codes. -pub fn strip_ansi_codes(s: &str) -> Cow { - STRIP_ANSI_RE.replace_all(s, "") -} - -/// An iterator over ansi codes in a string. -/// -/// This type can be used to scan over ansi codes in a string. -/// It yields tuples in the form `(s, is_ansi)` where `s` is a slice of -/// the original string and `is_ansi` indicates if the slice contains -/// ansi codes or string values. -pub struct AnsiCodeIterator<'a> { - s: &'a str, - pending_item: Option<(&'a str, bool)>, - last_idx: usize, - cur_idx: usize, - iter: Matches<'static, 'a>, -} - -impl<'a> AnsiCodeIterator<'a> { - /// Creates a new ansi code iterator. - pub fn new(s: &'a str) -> AnsiCodeIterator<'a> { - AnsiCodeIterator { - s, - pending_item: None, - last_idx: 0, - cur_idx: 0, - iter: STRIP_ANSI_RE.find_iter(s), - } - } - - /// Returns the string slice up to the current match. - pub fn current_slice(&self) -> &str { - &self.s[..self.cur_idx] - } - - /// Returns the string slice from the current match to the end. - pub fn rest_slice(&self) -> &str { - &self.s[self.cur_idx..] - } -} - -impl<'a> Iterator for AnsiCodeIterator<'a> { - type Item = (&'a str, bool); - - fn next(&mut self) -> Option<(&'a str, bool)> { - if let Some(pending_item) = self.pending_item.take() { - self.cur_idx += pending_item.0.len(); - Some(pending_item) - } else if let Some(m) = self.iter.next() { - let s = &self.s[self.last_idx..m.start()]; - self.last_idx = m.end(); - if s.is_empty() { - self.cur_idx = m.end(); - Some((m.as_str(), true)) - } else { - self.cur_idx = m.start(); - self.pending_item = Some((m.as_str(), true)); - Some((s, false)) - } - } else if self.last_idx < self.s.len() { - let rv = &self.s[self.last_idx..]; - self.cur_idx = self.s.len(); - self.last_idx = self.s.len(); - Some((rv, false)) - } else { - None - } - } -} - -#[test] -fn test_ansi_iter_re_vt100() { - let s = "\x1b(0lpq\x1b)Benglish"; - let mut iter = AnsiCodeIterator::new(s); - assert_eq!(iter.next(), Some(("\x1b(0", true))); - assert_eq!(iter.next(), Some(("lpq", false))); - assert_eq!(iter.next(), Some(("\x1b)B", true))); - assert_eq!(iter.next(), Some(("english", false))); -} - -#[test] -fn test_ansi_iter_re() { - use super::style; - let s = format!("Hello {}!", style("World").red().force_styling(true)); - let mut iter = AnsiCodeIterator::new(&s); - assert_eq!(iter.next(), Some(("Hello ", false))); - assert_eq!(iter.current_slice(), "Hello "); - assert_eq!(iter.rest_slice(), "\x1b[31mWorld\x1b[0m!"); - assert_eq!(iter.next(), Some(("\x1b[31m", true))); - assert_eq!(iter.current_slice(), "Hello \x1b[31m"); - assert_eq!(iter.rest_slice(), "World\x1b[0m!"); - assert_eq!(iter.next(), Some(("World", false))); - assert_eq!(iter.current_slice(), "Hello \x1b[31mWorld"); - assert_eq!(iter.rest_slice(), "\x1b[0m!"); - assert_eq!(iter.next(), Some(("\x1b[0m", true))); - assert_eq!(iter.current_slice(), "Hello \x1b[31mWorld\x1b[0m"); - assert_eq!(iter.rest_slice(), "!"); - assert_eq!(iter.next(), Some(("!", false))); - assert_eq!(iter.current_slice(), "Hello \x1b[31mWorld\x1b[0m!"); - assert_eq!(iter.rest_slice(), ""); - assert_eq!(iter.next(), None); -} - -#[test] -fn test_ansi_iter_re_on_multi() { - use super::style; - let s = format!("{}", style("a").red().bold().force_styling(true)); - let mut iter = AnsiCodeIterator::new(&s); - assert_eq!(iter.next(), Some(("\x1b[31m", true))); - assert_eq!(iter.current_slice(), "\x1b[31m"); - assert_eq!(iter.rest_slice(), "\x1b[1ma\x1b[0m"); - assert_eq!(iter.next(), Some(("\x1b[1m", true))); - assert_eq!(iter.current_slice(), "\x1b[31m\x1b[1m"); - assert_eq!(iter.rest_slice(), "a\x1b[0m"); - assert_eq!(iter.next(), Some(("a", false))); - assert_eq!(iter.current_slice(), "\x1b[31m\x1b[1ma"); - assert_eq!(iter.rest_slice(), "\x1b[0m"); - assert_eq!(iter.next(), Some(("\x1b[0m", true))); - assert_eq!(iter.current_slice(), "\x1b[31m\x1b[1ma\x1b[0m"); - assert_eq!(iter.rest_slice(), ""); - assert_eq!(iter.next(), None); -} diff --git a/tooling/cli.rs/src/console/common_term.rs b/tooling/cli.rs/src/console/common_term.rs deleted file mode 100644 index 7c81bcb4c826..000000000000 --- a/tooling/cli.rs/src/console/common_term.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::io; - -use super::term::Term; - -pub fn move_cursor_down(out: &Term, n: usize) -> io::Result<()> { - if n > 0 { - out.write_str(&format!("\x1b[{}B", n)) - } else { - Ok(()) - } -} - -pub fn move_cursor_up(out: &Term, n: usize) -> io::Result<()> { - if n > 0 { - out.write_str(&format!("\x1b[{}A", n)) - } else { - Ok(()) - } -} -pub fn move_cursor_left(out: &Term, n: usize) -> io::Result<()> { - if n > 0 { - out.write_str(&format!("\x1b[{}D", n)) - } else { - Ok(()) - } -} - -pub fn move_cursor_right(out: &Term, n: usize) -> io::Result<()> { - if n > 0 { - out.write_str(&format!("\x1b[{}C", n)) - } else { - Ok(()) - } -} - -#[inline] -pub fn move_cursor_to(out: &Term, x: usize, y: usize) -> io::Result<()> { - out.write_str(&format!("\x1B[{};{}H", y + 1, x + 1)) -} - -pub fn clear_chars(out: &Term, n: usize) -> io::Result<()> { - if n > 0 { - out.write_str(&format!("\x1b[{}D\x1b[0K", n)) - } else { - Ok(()) - } -} - -#[inline] -pub fn clear_line(out: &Term) -> io::Result<()> { - out.write_str("\r\x1b[2K") -} - -#[inline] -pub fn clear_screen(out: &Term) -> io::Result<()> { - out.write_str("\r\x1b[2J\r\x1b[H") -} - -#[inline] -pub fn clear_to_end_of_screen(out: &Term) -> io::Result<()> { - out.write_str("\r\x1b[0J") -} - -#[inline] -pub fn show_cursor(out: &Term) -> io::Result<()> { - out.write_str("\x1b[?25h") -} - -#[inline] -pub fn hide_cursor(out: &Term) -> io::Result<()> { - out.write_str("\x1b[?25l") -} diff --git a/tooling/cli.rs/src/console/kb.rs b/tooling/cli.rs/src/console/kb.rs deleted file mode 100644 index e54f0f2f160f..000000000000 --- a/tooling/cli.rs/src/console/kb.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -/// Key mapping -/// -/// This is an incomplete mapping of keys that are supported for reading -/// from the keyboard. -#[non_exhaustive] -#[derive(Clone, PartialEq, Eq, Debug)] -pub enum Key { - Unknown, - /// Unrecognized sequence containing Esc and a list of chars - UnknownEscSeq(Vec), - ArrowLeft, - ArrowRight, - ArrowUp, - ArrowDown, - Enter, - Escape, - Backspace, - Home, - End, - Tab, - BackTab, - Del, - Shift, - Insert, - PageUp, - PageDown, - Char(char), -} diff --git a/tooling/cli.rs/src/console/mod.rs b/tooling/cli.rs/src/console/mod.rs deleted file mode 100644 index be3d9689b110..000000000000 --- a/tooling/cli.rs/src/console/mod.rs +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -//! console is a library for Rust that provides access to various terminal -//! features so you can build nicer looking command line interfaces. It -//! comes with various tools and utilities for working with Terminals and -//! formatting text. -//! -//! Best paired with other libraries in the family: -//! -//! * [dialoguer](https://docs.rs/dialoguer) -//! * [indicatif](https://docs.rs/indicatif) -//! -//! # Terminal Access -//! -//! The terminal is abstracted through the `console::Term` type. It can -//! either directly provide access to the connected terminal or by buffering -//! up commands. A buffered terminal will however not be completely buffered -//! on windows where cursor movements are currently directly passed through. -//! -//! Example usage: -//! -//! ``` -//! # fn test() -> Result<(), Box> { -//! use std::thread; -//! use std::time::Duration; -//! -//! use console::Term; -//! -//! let term = Term::stdout(); -//! term.write_line("Hello World!")?; -//! thread::sleep(Duration::from_millis(2000)); -//! term.clear_line()?; -//! # Ok(()) } test().unwrap(); -//! ``` -//! -//! # Colors and Styles -//! -//! `console` uses `clicolors-control` to control colors. It also -//! provides higher level wrappers for styling text and other things -//! that can be displayed with the `style` function and utility types. -//! -//! Example usage: -//! -//! ``` -//! use console::style; -//! -//! println!("This is {} neat", style("quite").cyan()); -//! ``` -//! -//! You can also store styles and apply them to text later: -//! -//! ``` -//! use console::Style; -//! -//! let cyan = Style::new().cyan(); -//! println!("This is {} neat", cyan.apply_to("quite")); -//! ``` -//! -//! # Working with ANSI Codes -//! -//! The crate provids the function `strip_ansi_codes` to remove ANSI codes -//! from a string as well as `measure_text_width` to calculate the width of a -//! string as it would be displayed by the terminal. Both of those together -//! are useful for more complex formatting. -//! -//! # Unicode Width Support -//! -//! By default this crate depends on the `unicode-width` crate to calculate -//! the width of terminal characters. If you do not need this you can disable -//! the `unicode-width` feature which will cut down on dependencies. -//! -//! # Features -//! -//! By default all features are enabled. The following features exist: -//! -//! * `unicode-width`: adds support for unicode width calculations -//! * `ansi-parsing`: adds support for parsing ansi codes (this adds support -//! for stripping and taking ansi escape codes into account for length -//! calculations). - -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -pub use kb::Key; -pub use term::{user_attended, user_attended_stderr, Term, TermFamily, TermFeatures, TermTarget}; -pub use utils::{ - colors_enabled, colors_enabled_stderr, measure_text_width, pad_str, pad_str_with, - set_colors_enabled, set_colors_enabled_stderr, style, truncate_str, Alignment, Attribute, Color, - Emoji, Style, StyledObject, -}; - -pub use ansi::{strip_ansi_codes, AnsiCodeIterator}; - -mod common_term; -mod kb; -mod term; -#[cfg(unix)] -mod unix_term; -mod utils; -#[cfg(target_arch = "wasm32")] -mod wasm_term; -#[cfg(windows)] -mod windows_term; - -mod ansi; diff --git a/tooling/cli.rs/src/console/term.rs b/tooling/cli.rs/src/console/term.rs deleted file mode 100644 index 90ec693c017a..000000000000 --- a/tooling/cli.rs/src/console/term.rs +++ /dev/null @@ -1,624 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::fmt::{Debug, Display}; -use std::io::{self, Read, Write}; -use std::sync::{Arc, Mutex}; - -#[cfg(unix)] -use std::os::unix::io::{AsRawFd, RawFd}; -#[cfg(windows)] -use std::os::windows::io::{AsRawHandle, RawHandle}; - -use super::{kb::Key, utils::Style}; - -#[cfg(unix)] -trait TermWrite: Write + Debug + AsRawFd + Send {} -#[cfg(unix)] -impl TermWrite for T {} - -#[cfg(unix)] -trait TermRead: Read + Debug + AsRawFd + Send {} -#[cfg(unix)] -impl TermRead for T {} - -#[cfg(unix)] -#[derive(Debug, Clone)] -pub struct ReadWritePair { - read: Arc>, - write: Arc>, - style: Style, -} - -/// Where the term is writing. -#[derive(Debug, Clone)] -pub enum TermTarget { - Stdout, - Stderr, - #[cfg(unix)] - ReadWritePair(ReadWritePair), -} - -#[derive(Debug)] -pub struct TermInner { - target: TermTarget, - buffer: Option>>, -} - -/// The family of the terminal. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum TermFamily { - /// Redirected to a file or file like thing. - File, - /// A standard unix terminal. - UnixTerm, - /// A cmd.exe like windows console. - WindowsConsole, - /// A dummy terminal (for instance on wasm) - Dummy, -} - -/// Gives access to the terminal features. -#[derive(Debug, Clone)] -pub struct TermFeatures<'a>(&'a Term); - -impl<'a> TermFeatures<'a> { - /// Checks if this is a real user attended terminal (`isatty`) - #[inline] - pub fn is_attended(&self) -> bool { - is_a_terminal(self.0) - } - - /// Checks if colors are supported by this terminal. - /// - /// This does not check if colors are enabled. Currently all terminals - /// are considered to support colors - #[inline] - pub fn colors_supported(&self) -> bool { - is_a_color_terminal(self.0) - } - - /// Checks if this terminal is an msys terminal. - /// - /// This is sometimes useful to disable features that are known to not - /// work on msys terminals or require special handling. - #[inline] - pub fn is_msys_tty(&self) -> bool { - #[cfg(windows)] - { - msys_tty_on(self.0) - } - #[cfg(not(windows))] - { - false - } - } - - /// Checks if this terminal wants emojis. - #[inline] - pub fn wants_emoji(&self) -> bool { - self.is_attended() && wants_emoji() - } - - /// Returns the family of the terminal. - #[inline] - pub fn family(&self) -> TermFamily { - if !self.is_attended() { - return TermFamily::File; - } - #[cfg(windows)] - { - TermFamily::WindowsConsole - } - #[cfg(unix)] - { - TermFamily::UnixTerm - } - #[cfg(target_arch = "wasm32")] - { - TermFamily::Dummy - } - } -} - -/// Abstraction around a terminal. -/// -/// A terminal can be cloned. If a buffer is used it's shared across all -/// clones which means it largely acts as a handle. -#[derive(Clone, Debug)] -pub struct Term { - inner: Arc, - pub(crate) is_msys_tty: bool, - pub(crate) is_tty: bool, -} - -impl Term { - fn with_inner(inner: TermInner) -> Term { - let mut term = Term { - inner: Arc::new(inner), - is_msys_tty: false, - is_tty: false, - }; - - term.is_msys_tty = term.features().is_msys_tty(); - term.is_tty = term.features().is_attended(); - term - } - - /// Return a new unbuffered terminal - #[inline] - pub fn stdout() -> Term { - Term::with_inner(TermInner { - target: TermTarget::Stdout, - buffer: None, - }) - } - - /// Return a new unbuffered terminal to stderr - #[inline] - pub fn stderr() -> Term { - Term::with_inner(TermInner { - target: TermTarget::Stderr, - buffer: None, - }) - } - - /// Return a new buffered terminal - pub fn buffered_stdout() -> Term { - Term::with_inner(TermInner { - target: TermTarget::Stdout, - buffer: Some(Mutex::new(vec![])), - }) - } - - /// Return a new buffered terminal to stderr - pub fn buffered_stderr() -> Term { - Term::with_inner(TermInner { - target: TermTarget::Stderr, - buffer: Some(Mutex::new(vec![])), - }) - } - - /// Return a terminal for the given Read/Write pair styled-like Stderr. - #[cfg(unix)] - pub fn read_write_pair(read: R, write: W) -> Term - where - R: Read + Debug + AsRawFd + Send + 'static, - W: Write + Debug + AsRawFd + Send + 'static, - { - Self::read_write_pair_with_style(read, write, Style::new().for_stderr()) - } - - /// Return a terminal for the given Read/Write pair. - #[cfg(unix)] - pub fn read_write_pair_with_style(read: R, write: W, style: Style) -> Term - where - R: Read + Debug + AsRawFd + Send + 'static, - W: Write + Debug + AsRawFd + Send + 'static, - { - Term::with_inner(TermInner { - target: TermTarget::ReadWritePair(ReadWritePair { - read: Arc::new(Mutex::new(read)), - write: Arc::new(Mutex::new(write)), - style, - }), - buffer: None, - }) - } - - /// Returns the style for the term - #[inline] - pub fn style(&self) -> Style { - match self.inner.target { - TermTarget::Stderr => Style::new().for_stderr(), - TermTarget::Stdout => Style::new().for_stdout(), - #[cfg(unix)] - TermTarget::ReadWritePair(ReadWritePair { ref style, .. }) => style.clone(), - } - } - - /// Returns the target - #[inline] - pub fn target(&self) -> TermTarget { - self.inner.target.clone() - } - - #[doc(hidden)] - pub fn write_str(&self, s: &str) -> io::Result<()> { - match self.inner.buffer { - Some(ref buffer) => buffer.lock().unwrap().write_all(s.as_bytes()), - None => self.write_through(s.as_bytes()), - } - } - - /// Writes a string to the terminal and adds a newline. - pub fn write_line(&self, s: &str) -> io::Result<()> { - match self.inner.buffer { - Some(ref mutex) => { - let mut buffer = mutex.lock().unwrap(); - buffer.extend_from_slice(s.as_bytes()); - buffer.push(b'\n'); - Ok(()) - } - None => self.write_through(format!("{}\n", s).as_bytes()), - } - } - - /// Read a single character from the terminal - /// - /// This does not echo the character and blocks until a single character - /// is entered. - pub fn read_char(&self) -> io::Result { - loop { - match self.read_key()? { - Key::Char(c) => { - return Ok(c); - } - Key::Enter => { - return Ok('\n'); - } - Key::Unknown => { - return Err(io::Error::new( - io::ErrorKind::NotConnected, - "Not a terminal", - )) - } - _ => {} - } - } - } - - /// Read a single key form the terminal. - /// - /// This does not echo anything. If the terminal is not user attended - /// the return value will always be the unknown key. - pub fn read_key(&self) -> io::Result { - if !self.is_tty { - Ok(Key::Unknown) - } else { - read_single_key() - } - } - - /// Read one line of input. - /// - /// This does not include the trailing newline. If the terminal is not - /// user attended the return value will always be an empty string. - pub fn read_line(&self) -> io::Result { - if !self.is_tty { - return Ok("".into()); - } - let mut rv = String::new(); - io::stdin().read_line(&mut rv)?; - let len = rv.trim_end_matches(&['\r', '\n'][..]).len(); - rv.truncate(len); - Ok(rv) - } - - /// Read one line of input with initial text. - /// - /// This does not include the trailing newline. If the terminal is not - /// user attended the return value will always be an empty string. - pub fn read_line_initial_text(&self, initial: &str) -> io::Result { - if !self.is_tty { - return Ok("".into()); - } - self.write_str(initial)?; - - let mut chars: Vec = initial.chars().collect(); - - loop { - match self.read_key()? { - Key::Backspace => { - if chars.pop().is_some() { - self.clear_chars(1)?; - } - self.flush()?; - } - Key::Char(chr) => { - chars.push(chr); - let mut bytes_char = [0; 4]; - chr.encode_utf8(&mut bytes_char); - self.write_str(chr.encode_utf8(&mut bytes_char))?; - self.flush()?; - } - Key::Enter => break, - Key::Unknown => { - return Err(io::Error::new( - io::ErrorKind::NotConnected, - "Not a terminal", - )) - } - _ => (), - } - } - Ok(chars.iter().collect::()) - } - - /// Read securely a line of input. - /// - /// This is similar to `read_line` but will not echo the output. This - /// also switches the terminal into a different mode where not all - /// characters might be accepted. - pub fn read_secure_line(&self) -> io::Result { - if !self.is_tty { - return Ok("".into()); - } - match read_secure() { - Ok(rv) => { - self.write_line("")?; - Ok(rv) - } - Err(err) => Err(err), - } - } - - /// Flushes internal buffers. - /// - /// This forces the contents of the internal buffer to be written to - /// the terminal. This is unnecessary for unbuffered terminals which - /// will automatically flush. - pub fn flush(&self) -> io::Result<()> { - if let Some(ref buffer) = self.inner.buffer { - let mut buffer = buffer.lock().unwrap(); - if !buffer.is_empty() { - self.write_through(&buffer[..])?; - buffer.clear(); - } - } - Ok(()) - } - - /// Checks if the terminal is indeed a terminal. - #[inline] - pub fn is_term(&self) -> bool { - self.is_tty - } - - /// Checks for common terminal features. - #[inline] - pub fn features(&self) -> TermFeatures<'_> { - TermFeatures(self) - } - - /// Returns the terminal size in rows and columns or gets sensible defaults. - #[inline] - pub fn size(&self) -> (u16, u16) { - self.size_checked().unwrap_or((24, DEFAULT_WIDTH)) - } - - /// Returns the terminal size in rows and columns. - /// - /// If the size cannot be reliably determined None is returned. - #[inline] - pub fn size_checked(&self) -> Option<(u16, u16)> { - terminal_size(self) - } - - /// Moves the cursor to `x` and `y` - #[inline] - pub fn move_cursor_to(&self, x: usize, y: usize) -> io::Result<()> { - move_cursor_to(self, x, y) - } - - /// Moves the cursor up `n` lines - #[inline] - pub fn move_cursor_up(&self, n: usize) -> io::Result<()> { - move_cursor_up(self, n) - } - - /// Moves the cursor down `n` lines - #[inline] - pub fn move_cursor_down(&self, n: usize) -> io::Result<()> { - move_cursor_down(self, n) - } - - /// Moves the cursor left `n` lines - #[inline] - pub fn move_cursor_left(&self, n: usize) -> io::Result<()> { - move_cursor_left(self, n) - } - - /// Moves the cursor down `n` lines - #[inline] - pub fn move_cursor_right(&self, n: usize) -> io::Result<()> { - move_cursor_right(self, n) - } - - /// Clears the current line. - /// - /// The positions the cursor at the beginning of the line again. - #[inline] - pub fn clear_line(&self) -> io::Result<()> { - clear_line(self) - } - - /// Clear the last `n` lines. - /// - /// This positions the cursor at the beginning of the first line - /// that was cleared. - pub fn clear_last_lines(&self, n: usize) -> io::Result<()> { - self.move_cursor_up(n)?; - for _ in 0..n { - self.clear_line()?; - self.move_cursor_down(1)?; - } - self.move_cursor_up(n)?; - Ok(()) - } - - /// Clears the entire screen. - #[inline] - pub fn clear_screen(&self) -> io::Result<()> { - clear_screen(self) - } - - /// Clears the entire screen. - #[inline] - pub fn clear_to_end_of_screen(&self) -> io::Result<()> { - clear_to_end_of_screen(self) - } - - /// Clears the last char in the the current line. - #[inline] - pub fn clear_chars(&self, n: usize) -> io::Result<()> { - clear_chars(self, n) - } - - /// Set the terminal title - pub fn set_title(&self, title: T) { - if !self.is_tty { - return; - } - set_title(title); - } - - /// Makes cursor visible again - #[inline] - pub fn show_cursor(&self) -> io::Result<()> { - show_cursor(self) - } - - /// Hides cursor - #[inline] - pub fn hide_cursor(&self) -> io::Result<()> { - hide_cursor(self) - } - - // helpers - - #[cfg(all(windows, feature = "windows-console-colors"))] - fn write_through(&self, bytes: &[u8]) -> io::Result<()> { - if self.is_msys_tty || !self.is_tty { - self.write_through_common(bytes) - } else { - use winapi_util::console::Console; - - match self.inner.target { - TermTarget::Stdout => console_colors(self, Console::stdout()?, bytes), - TermTarget::Stderr => console_colors(self, Console::stderr()?, bytes), - } - } - } - - #[cfg(not(all(windows, feature = "windows-console-colors")))] - fn write_through(&self, bytes: &[u8]) -> io::Result<()> { - self.write_through_common(bytes) - } - - pub(crate) fn write_through_common(&self, bytes: &[u8]) -> io::Result<()> { - match self.inner.target { - TermTarget::Stdout => { - io::stdout().write_all(bytes)?; - io::stdout().flush()?; - } - TermTarget::Stderr => { - io::stderr().write_all(bytes)?; - io::stderr().flush()?; - } - #[cfg(unix)] - TermTarget::ReadWritePair(ReadWritePair { ref write, .. }) => { - let mut write = write.lock().unwrap(); - write.write_all(bytes)?; - write.flush()?; - } - } - Ok(()) - } -} - -/// A fast way to check if the application has a user attended for stdout. -/// -/// This means that stdout is connected to a terminal instead of a -/// file or redirected by other means. This is a shortcut for -/// checking the `is_attended` feature on the stdout terminal. -#[inline] -pub fn user_attended() -> bool { - Term::stdout().features().is_attended() -} - -/// A fast way to check if the application has a user attended for stderr. -/// -/// This means that stderr is connected to a terminal instead of a -/// file or redirected by other means. This is a shortcut for -/// checking the `is_attended` feature on the stderr terminal. -#[inline] -pub fn user_attended_stderr() -> bool { - Term::stderr().features().is_attended() -} - -#[cfg(unix)] -impl AsRawFd for Term { - fn as_raw_fd(&self) -> RawFd { - match self.inner.target { - TermTarget::Stdout => libc::STDOUT_FILENO, - TermTarget::Stderr => libc::STDERR_FILENO, - TermTarget::ReadWritePair(ReadWritePair { ref write, .. }) => { - write.lock().unwrap().as_raw_fd() - } - } - } -} - -#[cfg(windows)] -impl AsRawHandle for Term { - fn as_raw_handle(&self) -> RawHandle { - use winapi::um::processenv::GetStdHandle; - use winapi::um::winbase::{STD_ERROR_HANDLE, STD_OUTPUT_HANDLE}; - - unsafe { - GetStdHandle(match self.inner.target { - TermTarget::Stdout => STD_OUTPUT_HANDLE, - TermTarget::Stderr => STD_ERROR_HANDLE, - }) as RawHandle - } - } -} - -impl Write for Term { - fn write(&mut self, buf: &[u8]) -> io::Result { - match self.inner.buffer { - Some(ref buffer) => buffer.lock().unwrap().write_all(buf), - None => self.write_through(buf), - }?; - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Term::flush(self) - } -} - -impl<'a> Write for &'a Term { - fn write(&mut self, buf: &[u8]) -> io::Result { - match self.inner.buffer { - Some(ref buffer) => buffer.lock().unwrap().write_all(buf), - None => self.write_through(buf), - }?; - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Term::flush(self) - } -} - -impl Read for Term { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - io::stdin().read(buf) - } -} - -impl<'a> Read for &'a Term { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - io::stdin().read(buf) - } -} - -#[cfg(unix)] -pub use super::unix_term::*; -#[cfg(target_arch = "wasm32")] -pub use super::wasm_term::*; -#[cfg(windows)] -pub use super::windows_term::*; diff --git a/tooling/cli.rs/src/console/unix_term.rs b/tooling/cli.rs/src/console/unix_term.rs deleted file mode 100644 index efab8a55d698..000000000000 --- a/tooling/cli.rs/src/console/unix_term.rs +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::env; -use std::fmt::Display; -use std::fs; -use std::io; -use std::io::{BufRead, BufReader}; -use std::os::unix::io::AsRawFd; -use std::str; - -use super::kb::Key; -use super::term::Term; - -pub use super::common_term::*; - -pub const DEFAULT_WIDTH: u16 = 80; - -#[inline] -pub fn is_a_terminal(out: &Term) -> bool { - unsafe { libc::isatty(out.as_raw_fd()) != 0 } -} - -pub fn is_a_color_terminal(out: &Term) -> bool { - if !is_a_terminal(out) { - return false; - } - - if env::var("NO_COLOR").is_ok() { - return false; - } - - match env::var("TERM") { - Ok(term) => term != "dumb", - Err(_) => false, - } -} - -pub fn c_result libc::c_int>(f: F) -> io::Result<()> { - let res = f(); - if res != 0 { - Err(io::Error::last_os_error()) - } else { - Ok(()) - } -} - -#[inline] -pub fn terminal_size(out: &Term) -> Option<(u16, u16)> { - terminal_size::terminal_size_using_fd(out.as_raw_fd()).map(|x| ((x.1).0, (x.0).0)) -} - -pub fn read_secure() -> io::Result { - let f_tty; - let fd = unsafe { - if libc::isatty(libc::STDIN_FILENO) == 1 { - f_tty = None; - libc::STDIN_FILENO - } else { - let f = fs::File::open("/dev/tty")?; - let fd = f.as_raw_fd(); - f_tty = Some(BufReader::new(f)); - fd - } - }; - - let mut termios = core::mem::MaybeUninit::uninit(); - c_result(|| unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) })?; - let mut termios = unsafe { termios.assume_init() }; - let original = termios; - termios.c_lflag &= !libc::ECHO; - c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSAFLUSH, &termios) })?; - let mut rv = String::new(); - - let read_rv = if let Some(mut f) = f_tty { - f.read_line(&mut rv) - } else { - io::stdin().read_line(&mut rv) - }; - - c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSAFLUSH, &original) })?; - - read_rv.map(|_| { - let len = rv.trim_end_matches(&['\r', '\n'][..]).len(); - rv.truncate(len); - rv - }) -} - -fn read_single_char(fd: i32) -> io::Result> { - let mut pollfd = libc::pollfd { - fd, - events: libc::POLLIN, - revents: 0, - }; - - // timeout of zero means that it will not block - let ret = unsafe { libc::poll(&mut pollfd as *mut _, 1, 0) }; - if ret < 0 { - return Err(io::Error::last_os_error()); - } - - let is_ready = pollfd.revents & libc::POLLIN != 0; - - if is_ready { - // if there is something to be read, take 1 byte from it - let mut buf: [u8; 1] = [0]; - - read_bytes(fd, &mut buf, 1)?; - Ok(Some(buf[0] as char)) - } else { - //there is nothing to be read - Ok(None) - } -} - -// Similar to libc::read. Read count bytes into slice buf from descriptor fd. -// If successful, return the number of bytes read. -// Will return an error if nothing was read, i.e when called at end of file. -fn read_bytes(fd: i32, buf: &mut [u8], count: u8) -> io::Result { - let read = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut _, count as usize) }; - if read < 0 { - Err(io::Error::last_os_error()) - } else if read == 0 { - Err(io::Error::new( - io::ErrorKind::UnexpectedEof, - "Reached end of file", - )) - } else if buf[0] == b'\x03' { - Err(io::Error::new( - io::ErrorKind::Interrupted, - "read interrupted", - )) - } else { - Ok(read as u8) - } -} - -pub fn read_single_key() -> io::Result { - let tty_f; - let fd = unsafe { - if libc::isatty(libc::STDIN_FILENO) == 1 { - libc::STDIN_FILENO - } else { - tty_f = fs::File::open("/dev/tty")?; - tty_f.as_raw_fd() - } - }; - let mut termios = core::mem::MaybeUninit::uninit(); - c_result(|| unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) })?; - let mut termios = unsafe { termios.assume_init() }; - let original = termios; - unsafe { libc::cfmakeraw(&mut termios) }; - c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &termios) })?; - - let rv = match read_single_char(fd)? { - Some('\x1b') => { - // Escape was read, keep reading in case we find a familiar key - if let Some(c1) = read_single_char(fd)? { - if c1 == '[' { - if let Some(c2) = read_single_char(fd)? { - match c2 { - 'A' => Ok(Key::ArrowUp), - 'B' => Ok(Key::ArrowDown), - 'C' => Ok(Key::ArrowRight), - 'D' => Ok(Key::ArrowLeft), - 'H' => Ok(Key::Home), - 'F' => Ok(Key::End), - 'Z' => Ok(Key::BackTab), - _ => { - let c3 = read_single_char(fd)?; - if let Some(c3) = c3 { - if c3 == '~' { - match c2 { - '1' => Ok(Key::Home), // tmux - '2' => Ok(Key::Insert), - '3' => Ok(Key::Del), - '4' => Ok(Key::End), // tmux - '5' => Ok(Key::PageUp), - '6' => Ok(Key::PageDown), - '7' => Ok(Key::Home), // xrvt - '8' => Ok(Key::End), // xrvt - _ => Ok(Key::UnknownEscSeq(vec![c1, c2, c3])), - } - } else { - Ok(Key::UnknownEscSeq(vec![c1, c2, c3])) - } - } else { - // \x1b[ and 1 more char - Ok(Key::UnknownEscSeq(vec![c1, c2])) - } - } - } - } else { - // \x1b[ and no more input - Ok(Key::UnknownEscSeq(vec![c1])) - } - } else { - // char after escape is not [ - Ok(Key::UnknownEscSeq(vec![c1])) - } - } else { - //nothing after escape - Ok(Key::Escape) - } - } - Some(c) => { - let byte = c as u8; - let mut buf: [u8; 4] = [byte, 0, 0, 0]; - - if byte & 224u8 == 192u8 { - // a two byte unicode character - read_bytes(fd, &mut buf[1..], 1)?; - Ok(key_from_utf8(&buf[..2])) - } else if byte & 240u8 == 224u8 { - // a three byte unicode character - read_bytes(fd, &mut buf[1..], 2)?; - Ok(key_from_utf8(&buf[..3])) - } else if byte & 248u8 == 240u8 { - // a four byte unicode character - read_bytes(fd, &mut buf[1..], 3)?; - Ok(key_from_utf8(&buf[..4])) - } else { - Ok(match c { - '\n' | '\r' => Key::Enter, - '\x7f' => Key::Backspace, - '\t' => Key::Tab, - '\x01' => Key::Home, // Control-A (home) - '\x05' => Key::End, // Control-E (end) - '\x08' => Key::Backspace, // Control-H (8) (Identical to '\b') - _ => Key::Char(c), - }) - } - } - None => { - // there is no subsequent byte ready to be read, block and wait for input - - let mut pollfd = libc::pollfd { - fd, - events: libc::POLLIN, - revents: 0, - }; - - // negative timeout means that it will block indefinitely - let ret = unsafe { libc::poll(&mut pollfd as *mut _, 1, -1) }; - if ret < 0 { - return Err(io::Error::last_os_error()); - } - - read_single_key() - } - }; - c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &original) })?; - - // if the user hit ^C we want to signal SIGINT to outselves. - if let Err(ref err) = rv { - if err.kind() == io::ErrorKind::Interrupted { - unsafe { - libc::raise(libc::SIGINT); - } - } - } - - rv -} - -pub fn key_from_utf8(buf: &[u8]) -> Key { - if let Ok(s) = str::from_utf8(buf) { - if let Some(c) = s.chars().next() { - return Key::Char(c); - } - } - Key::Unknown -} - -#[cfg(not(target_os = "macos"))] -lazy_static::lazy_static! { - static ref IS_LANG_UTF8: bool = { - match std::env::var("LANG") { - Ok(lang) => lang.to_uppercase().ends_with("UTF-8"), - _ => false, - } - }; -} - -#[cfg(target_os = "macos")] -pub fn wants_emoji() -> bool { - true -} - -#[cfg(not(target_os = "macos"))] -pub fn wants_emoji() -> bool { - *IS_LANG_UTF8 -} - -pub fn set_title(title: T) { - print!("\x1b]0;{}\x07", title); -} diff --git a/tooling/cli.rs/src/console/utils.rs b/tooling/cli.rs/src/console/utils.rs deleted file mode 100644 index fbebd18f2d96..000000000000 --- a/tooling/cli.rs/src/console/utils.rs +++ /dev/null @@ -1,900 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::borrow::Cow; -use std::collections::BTreeSet; -use std::env; -use std::fmt; -use std::sync::atomic::{AtomicBool, Ordering}; - -use super::term::{wants_emoji, Term}; -use lazy_static::lazy_static; - -use super::ansi::{strip_ansi_codes, AnsiCodeIterator}; - -fn default_colors_enabled(out: &Term) -> bool { - (out.features().colors_supported() && &env::var("CLICOLOR").unwrap_or_else(|_| "1".into()) != "0") - || &env::var("CLICOLOR_FORCE").unwrap_or_else(|_| "0".into()) != "0" -} - -lazy_static! { - static ref STDOUT_COLORS: AtomicBool = AtomicBool::new(default_colors_enabled(&Term::stdout())); - static ref STDERR_COLORS: AtomicBool = AtomicBool::new(default_colors_enabled(&Term::stderr())); -} - -/// Returns `true` if colors should be enabled for stdout. -/// -/// This honors the [clicolors spec](http://bixense.com/clicolors/). -/// -/// * `CLICOLOR != 0`: ANSI colors are supported and should be used when the program isn't piped. -/// * `CLICOLOR == 0`: Don't output ANSI color escape codes. -/// * `CLICOLOR_FORCE != 0`: ANSI colors should be enabled no matter what. -#[inline] -pub fn colors_enabled() -> bool { - STDOUT_COLORS.load(Ordering::Relaxed) -} - -/// Forces colorization on or off for stdout. -/// -/// This overrides the default for the current process and changes the return value of the -/// `colors_enabled` function. -#[inline] -pub fn set_colors_enabled(val: bool) { - STDOUT_COLORS.store(val, Ordering::Relaxed) -} - -/// Returns `true` if colors should be enabled for stderr. -/// -/// This honors the [clicolors spec](http://bixense.com/clicolors/). -/// -/// * `CLICOLOR != 0`: ANSI colors are supported and should be used when the program isn't piped. -/// * `CLICOLOR == 0`: Don't output ANSI color escape codes. -/// * `CLICOLOR_FORCE != 0`: ANSI colors should be enabled no matter what. -#[inline] -pub fn colors_enabled_stderr() -> bool { - STDERR_COLORS.load(Ordering::Relaxed) -} - -/// Forces colorization on or off for stderr. -/// -/// This overrides the default for the current process and changes the return value of the -/// `colors_enabled` function. -#[inline] -pub fn set_colors_enabled_stderr(val: bool) { - STDERR_COLORS.store(val, Ordering::Relaxed) -} - -/// Measure the width of a string in terminal characters. -pub fn measure_text_width(s: &str) -> usize { - str_width(&strip_ansi_codes(s)) -} - -/// A terminal color. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Color { - Black, - Red, - Green, - Yellow, - Blue, - Magenta, - Cyan, - White, - Color256(u8), -} - -impl Color { - #[inline] - fn ansi_num(self) -> usize { - match self { - Color::Black => 0, - Color::Red => 1, - Color::Green => 2, - Color::Yellow => 3, - Color::Blue => 4, - Color::Magenta => 5, - Color::Cyan => 6, - Color::White => 7, - Color::Color256(x) => x as usize, - } - } - - #[inline] - fn is_color256(self) -> bool { - #[allow(clippy::match_like_matches_macro)] - match self { - Color::Color256(_) => true, - _ => false, - } - } -} - -/// A terminal style attribute. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] -pub enum Attribute { - Bold, - Dim, - Italic, - Underlined, - Blink, - Reverse, - Hidden, -} - -impl Attribute { - #[inline] - fn ansi_num(self) -> usize { - match self { - Attribute::Bold => 1, - Attribute::Dim => 2, - Attribute::Italic => 3, - Attribute::Underlined => 4, - Attribute::Blink => 5, - Attribute::Reverse => 7, - Attribute::Hidden => 8, - } - } -} - -/// Defines the alignment for padding operations. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Alignment { - Left, - Center, - Right, -} - -/// A stored style that can be applied. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Style { - fg: Option, - bg: Option, - fg_bright: bool, - bg_bright: bool, - attrs: BTreeSet, - force: Option, - for_stderr: bool, -} - -impl Default for Style { - fn default() -> Style { - Style::new() - } -} - -impl Style { - /// Returns an empty default style. - pub fn new() -> Style { - Style { - fg: None, - bg: None, - fg_bright: false, - bg_bright: false, - attrs: BTreeSet::new(), - force: None, - for_stderr: false, - } - } - - /// Creates a style from a dotted string. - /// - /// Effectively the string is split at each dot and then the - /// terms in between are applied. For instance `red.on_blue` will - /// create a string that is red on blue background. Unknown terms - /// are ignored. - pub fn from_dotted_str(s: &str) -> Style { - let mut rv = Style::new(); - for part in s.split('.') { - rv = match part { - "black" => rv.black(), - "red" => rv.red(), - "green" => rv.green(), - "yellow" => rv.yellow(), - "blue" => rv.blue(), - "magenta" => rv.magenta(), - "cyan" => rv.cyan(), - "white" => rv.white(), - "bright" => rv.bright(), - "on_black" => rv.on_black(), - "on_red" => rv.on_red(), - "on_green" => rv.on_green(), - "on_yellow" => rv.on_yellow(), - "on_blue" => rv.on_blue(), - "on_magenta" => rv.on_magenta(), - "on_cyan" => rv.on_cyan(), - "on_white" => rv.on_white(), - "on_bright" => rv.on_bright(), - "bold" => rv.bold(), - "dim" => rv.dim(), - "underlined" => rv.underlined(), - "blink" => rv.blink(), - "reverse" => rv.reverse(), - "hidden" => rv.hidden(), - _ => { - continue; - } - }; - } - rv - } - - /// Apply the style to something that can be displayed. - pub fn apply_to(&self, val: D) -> StyledObject { - StyledObject { - style: self.clone(), - val, - } - } - - /// Forces styling on or off. - /// - /// This overrides the detection from `clicolors-control`. - #[inline] - pub fn force_styling(mut self, value: bool) -> Style { - self.force = Some(value); - self - } - - /// Specifies that style is applying to something being written on stderr. - #[inline] - pub fn for_stderr(mut self) -> Style { - self.for_stderr = true; - self - } - - /// Specifies that style is applying to something being written on stdout. - /// - /// This is the default behaviour. - #[inline] - pub fn for_stdout(mut self) -> Style { - self.for_stderr = false; - self - } - - /// Sets a foreground color. - #[inline] - pub fn fg(mut self, color: Color) -> Style { - self.fg = Some(color); - self - } - - /// Sets a background color. - #[inline] - pub fn bg(mut self, color: Color) -> Style { - self.bg = Some(color); - self - } - - /// Adds a attr. - #[inline] - pub fn attr(mut self, attr: Attribute) -> Style { - self.attrs.insert(attr); - self - } - - #[inline] - pub fn black(self) -> Style { - self.fg(Color::Black) - } - #[inline] - pub fn red(self) -> Style { - self.fg(Color::Red) - } - #[inline] - pub fn green(self) -> Style { - self.fg(Color::Green) - } - #[inline] - pub fn yellow(self) -> Style { - self.fg(Color::Yellow) - } - #[inline] - pub fn blue(self) -> Style { - self.fg(Color::Blue) - } - #[inline] - pub fn magenta(self) -> Style { - self.fg(Color::Magenta) - } - #[inline] - pub fn cyan(self) -> Style { - self.fg(Color::Cyan) - } - #[inline] - pub fn white(self) -> Style { - self.fg(Color::White) - } - #[inline] - pub fn color256(self, color: u8) -> Style { - self.fg(Color::Color256(color)) - } - - #[inline] - pub fn bright(mut self) -> Style { - self.fg_bright = true; - self - } - - #[inline] - pub fn on_black(self) -> Style { - self.bg(Color::Black) - } - #[inline] - pub fn on_red(self) -> Style { - self.bg(Color::Red) - } - #[inline] - pub fn on_green(self) -> Style { - self.bg(Color::Green) - } - #[inline] - pub fn on_yellow(self) -> Style { - self.bg(Color::Yellow) - } - #[inline] - pub fn on_blue(self) -> Style { - self.bg(Color::Blue) - } - #[inline] - pub fn on_magenta(self) -> Style { - self.bg(Color::Magenta) - } - #[inline] - pub fn on_cyan(self) -> Style { - self.bg(Color::Cyan) - } - #[inline] - pub fn on_white(self) -> Style { - self.bg(Color::White) - } - #[inline] - pub fn on_color256(self, color: u8) -> Style { - self.bg(Color::Color256(color)) - } - - #[inline] - pub fn on_bright(mut self) -> Style { - self.bg_bright = true; - self - } - - #[inline] - pub fn bold(self) -> Style { - self.attr(Attribute::Bold) - } - #[inline] - pub fn dim(self) -> Style { - self.attr(Attribute::Dim) - } - #[inline] - pub fn italic(self) -> Style { - self.attr(Attribute::Italic) - } - #[inline] - pub fn underlined(self) -> Style { - self.attr(Attribute::Underlined) - } - #[inline] - pub fn blink(self) -> Style { - self.attr(Attribute::Blink) - } - #[inline] - pub fn reverse(self) -> Style { - self.attr(Attribute::Reverse) - } - #[inline] - pub fn hidden(self) -> Style { - self.attr(Attribute::Hidden) - } -} - -/// Wraps an object for formatting for styling. -/// -/// Example: -/// -/// ```rust,no_run -/// # use console::style; -/// format!("Hello {}", style("World").cyan()); -/// ``` -/// -/// This is a shortcut for making a new style and applying it -/// to a value: -/// -/// ```rust,no_run -/// # use console::Style; -/// format!("Hello {}", Style::new().cyan().apply_to("World")); -/// ``` -pub fn style(val: D) -> StyledObject { - Style::new().apply_to(val) -} - -/// A formatting wrapper that can be styled for a terminal. -#[derive(Clone)] -pub struct StyledObject { - style: Style, - val: D, -} - -impl StyledObject { - /// Forces styling on or off. - /// - /// This overrides the detection from `clicolors-control`. - #[inline] - pub fn force_styling(mut self, value: bool) -> StyledObject { - self.style = self.style.force_styling(value); - self - } - - /// Specifies that style is applying to something being written on stderr - #[inline] - pub fn for_stderr(mut self) -> StyledObject { - self.style = self.style.for_stderr(); - self - } - - /// Specifies that style is applying to something being written on stdout - /// - /// This is the default - #[inline] - pub fn for_stdout(mut self) -> StyledObject { - self.style = self.style.for_stdout(); - self - } - - /// Sets a foreground color. - #[inline] - pub fn fg(mut self, color: Color) -> StyledObject { - self.style = self.style.fg(color); - self - } - - /// Sets a background color. - #[inline] - pub fn bg(mut self, color: Color) -> StyledObject { - self.style = self.style.bg(color); - self - } - - /// Adds a attr. - #[inline] - pub fn attr(mut self, attr: Attribute) -> StyledObject { - self.style = self.style.attr(attr); - self - } - - #[inline] - pub fn black(self) -> StyledObject { - self.fg(Color::Black) - } - #[inline] - pub fn red(self) -> StyledObject { - self.fg(Color::Red) - } - #[inline] - pub fn green(self) -> StyledObject { - self.fg(Color::Green) - } - #[inline] - pub fn yellow(self) -> StyledObject { - self.fg(Color::Yellow) - } - #[inline] - pub fn blue(self) -> StyledObject { - self.fg(Color::Blue) - } - #[inline] - pub fn magenta(self) -> StyledObject { - self.fg(Color::Magenta) - } - #[inline] - pub fn cyan(self) -> StyledObject { - self.fg(Color::Cyan) - } - #[inline] - pub fn white(self) -> StyledObject { - self.fg(Color::White) - } - #[inline] - pub fn color256(self, color: u8) -> StyledObject { - self.fg(Color::Color256(color)) - } - - #[inline] - pub fn bright(mut self) -> StyledObject { - self.style = self.style.bright(); - self - } - - #[inline] - pub fn on_black(self) -> StyledObject { - self.bg(Color::Black) - } - #[inline] - pub fn on_red(self) -> StyledObject { - self.bg(Color::Red) - } - #[inline] - pub fn on_green(self) -> StyledObject { - self.bg(Color::Green) - } - #[inline] - pub fn on_yellow(self) -> StyledObject { - self.bg(Color::Yellow) - } - #[inline] - pub fn on_blue(self) -> StyledObject { - self.bg(Color::Blue) - } - #[inline] - pub fn on_magenta(self) -> StyledObject { - self.bg(Color::Magenta) - } - #[inline] - pub fn on_cyan(self) -> StyledObject { - self.bg(Color::Cyan) - } - #[inline] - pub fn on_white(self) -> StyledObject { - self.bg(Color::White) - } - #[inline] - pub fn on_color256(self, color: u8) -> StyledObject { - self.bg(Color::Color256(color)) - } - - #[inline] - pub fn on_bright(mut self) -> StyledObject { - self.style = self.style.on_bright(); - self - } - - #[inline] - pub fn bold(self) -> StyledObject { - self.attr(Attribute::Bold) - } - #[inline] - pub fn dim(self) -> StyledObject { - self.attr(Attribute::Dim) - } - #[inline] - pub fn italic(self) -> StyledObject { - self.attr(Attribute::Italic) - } - #[inline] - pub fn underlined(self) -> StyledObject { - self.attr(Attribute::Underlined) - } - #[inline] - pub fn blink(self) -> StyledObject { - self.attr(Attribute::Blink) - } - #[inline] - pub fn reverse(self) -> StyledObject { - self.attr(Attribute::Reverse) - } - #[inline] - pub fn hidden(self) -> StyledObject { - self.attr(Attribute::Hidden) - } -} - -macro_rules! impl_fmt { - ($name:ident) => { - impl fmt::$name for StyledObject { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut reset = false; - if self - .style - .force - .unwrap_or_else(|| match self.style.for_stderr { - true => colors_enabled_stderr(), - false => colors_enabled(), - }) - { - if let Some(fg) = self.style.fg { - if fg.is_color256() { - write!(f, "\x1b[38;5;{}m", fg.ansi_num())?; - } else if self.style.fg_bright { - write!(f, "\x1b[38;5;{}m", fg.ansi_num() + 8)?; - } else { - write!(f, "\x1b[{}m", fg.ansi_num() + 30)?; - } - reset = true; - } - if let Some(bg) = self.style.bg { - if bg.is_color256() { - write!(f, "\x1b[48;5;{}m", bg.ansi_num())?; - } else if self.style.bg_bright { - write!(f, "\x1b[48;5;{}m", bg.ansi_num() + 8)?; - } else { - write!(f, "\x1b[{}m", bg.ansi_num() + 40)?; - } - reset = true; - } - for attr in &self.style.attrs { - write!(f, "\x1b[{}m", attr.ansi_num())?; - reset = true; - } - } - fmt::$name::fmt(&self.val, f)?; - if reset { - write!(f, "\x1b[0m")?; - } - Ok(()) - } - } - }; -} - -impl_fmt!(Binary); -impl_fmt!(Debug); -impl_fmt!(Display); -impl_fmt!(LowerExp); -impl_fmt!(LowerHex); -impl_fmt!(Octal); -impl_fmt!(Pointer); -impl_fmt!(UpperExp); -impl_fmt!(UpperHex); - -/// "Intelligent" emoji formatter. -/// -/// This struct intelligently wraps an emoji so that it is rendered -/// only on systems that want emojis and renders a fallback on others. -/// -/// Example: -/// -/// ```rust -/// use console::Emoji; -/// println!("[3/4] {}Downloading ...", Emoji("🚚 ", "")); -/// println!("[4/4] {} Done!", Emoji("✨", ":-)")); -/// ``` -#[derive(Copy, Clone)] -pub struct Emoji<'a, 'b>(pub &'a str, pub &'b str); - -impl<'a, 'b> Emoji<'a, 'b> { - pub fn new(emoji: &'a str, fallback: &'b str) -> Emoji<'a, 'b> { - Emoji(emoji, fallback) - } -} - -impl<'a, 'b> fmt::Display for Emoji<'a, 'b> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if wants_emoji() { - write!(f, "{}", self.0) - } else { - write!(f, "{}", self.1) - } - } -} - -fn str_width(s: &str) -> usize { - #[cfg(feature = "unicode-width")] - { - use unicode_width::UnicodeWidthStr; - s.width() - } - #[cfg(not(feature = "unicode-width"))] - { - s.chars().count() - } -} - -fn char_width(c: char) -> usize { - #[cfg(feature = "unicode-width")] - { - use unicode_width::UnicodeWidthChar; - c.width().unwrap_or(0) - } - #[cfg(not(feature = "unicode-width"))] - { - let _c = c; - 1 - } -} - -/// Truncates a string to a certain number of characters. -/// -/// This ensures that escape codes are not screwed up in the process. -/// If the maximum length is hit the string will be truncated but -/// escapes code will still be honored. If truncation takes place -/// the tail string will be appended. -pub fn truncate_str<'a>(s: &'a str, width: usize, tail: &str) -> Cow<'a, str> { - { - use std::cmp::Ordering; - let mut iter = AnsiCodeIterator::new(s); - let mut length = 0; - let mut rv = None; - - while let Some(item) = iter.next() { - match item { - (s, false) => { - if rv.is_none() { - if str_width(s) + length > width - str_width(tail) { - let ts = iter.current_slice(); - - let mut s_byte = 0; - let mut s_width = 0; - let rest_width = width - str_width(tail) - length; - for c in s.chars() { - s_byte += c.len_utf8(); - s_width += char_width(c); - match s_width.cmp(&rest_width) { - Ordering::Equal => break, - Ordering::Greater => { - s_byte -= c.len_utf8(); - break; - } - Ordering::Less => continue, - } - } - - let idx = ts.len() - s.len() + s_byte; - let mut buf = ts[..idx].to_string(); - buf.push_str(tail); - rv = Some(buf); - } - length += str_width(s); - } - } - (s, true) => { - if rv.is_some() { - rv.as_mut().unwrap().push_str(s); - } - } - } - } - - if let Some(buf) = rv { - Cow::Owned(buf) - } else { - Cow::Borrowed(s) - } - } -} - -/// Pads a string to fill a certain number of characters. -/// -/// This will honor ansi codes correctly and allows you to align a string -/// on the left, right or centered. Additionally truncation can be enabled -/// by setting `truncate` to a string that should be used as a truncation -/// marker. -pub fn pad_str<'a>( - s: &'a str, - width: usize, - align: Alignment, - truncate: Option<&str>, -) -> Cow<'a, str> { - pad_str_with(s, width, align, truncate, ' ') -} -/// Pads a string with specific padding to fill a certain number of characters. -/// -/// This will honor ansi codes correctly and allows you to align a string -/// on the left, right or centered. Additionally truncation can be enabled -/// by setting `truncate` to a string that should be used as a truncation -/// marker. -pub fn pad_str_with<'a>( - s: &'a str, - width: usize, - align: Alignment, - truncate: Option<&str>, - pad: char, -) -> Cow<'a, str> { - let cols = measure_text_width(s); - - if cols >= width { - return match truncate { - None => Cow::Borrowed(s), - Some(tail) => truncate_str(s, width, tail), - }; - } - - let diff = width - cols; - - let (left_pad, right_pad) = match align { - Alignment::Left => (0, diff), - Alignment::Right => (diff, 0), - Alignment::Center => (diff / 2, diff - diff / 2), - }; - - let mut rv = String::new(); - for _ in 0..left_pad { - rv.push(pad); - } - rv.push_str(s); - for _ in 0..right_pad { - rv.push(pad); - } - Cow::Owned(rv) -} - -#[test] -fn test_text_width() { - let s = style("foo") - .red() - .on_black() - .bold() - .force_styling(true) - .to_string(); - assert_eq!(measure_text_width(&s), 3); -} - -#[test] -#[cfg(all(feature = "unicode-width", feature = "ansi-parsing"))] -fn test_truncate_str() { - let s = format!("foo {}", style("bar").red().force_styling(true)); - assert_eq!( - &truncate_str(&s, 5, ""), - &format!("foo {}", style("b").red().force_styling(true)) - ); - let s = format!("foo {}", style("bar").red().force_styling(true)); - assert_eq!( - &truncate_str(&s, 5, "!"), - &format!("foo {}", style("!").red().force_styling(true)) - ); - let s = format!("foo {} baz", style("bar").red().force_styling(true)); - assert_eq!( - &truncate_str(&s, 10, "..."), - &format!("foo {}...", style("bar").red().force_styling(true)) - ); - let s = format!("foo {}", style("バー").red().force_styling(true)); - assert_eq!( - &truncate_str(&s, 5, ""), - &format!("foo {}", style("").red().force_styling(true)) - ); - let s = format!("foo {}", style("バー").red().force_styling(true)); - assert_eq!( - &truncate_str(&s, 6, ""), - &format!("foo {}", style("バ").red().force_styling(true)) - ); -} - -#[test] -fn test_truncate_str_no_ansi() { - assert_eq!(&truncate_str("foo bar", 5, ""), "foo b"); - assert_eq!(&truncate_str("foo bar", 5, "!"), "foo !"); - assert_eq!(&truncate_str("foo bar baz", 10, "..."), "foo bar..."); -} - -#[test] -fn test_pad_str() { - assert_eq!(pad_str("foo", 7, Alignment::Center, None), " foo "); - assert_eq!(pad_str("foo", 7, Alignment::Left, None), "foo "); - assert_eq!(pad_str("foo", 7, Alignment::Right, None), " foo"); - assert_eq!(pad_str("foo", 3, Alignment::Left, None), "foo"); - assert_eq!(pad_str("foobar", 3, Alignment::Left, None), "foobar"); - assert_eq!(pad_str("foobar", 3, Alignment::Left, Some("")), "foo"); - assert_eq!( - pad_str("foobarbaz", 6, Alignment::Left, Some("...")), - "foo..." - ); -} - -#[test] -fn test_pad_str_with() { - assert_eq!( - pad_str_with("foo", 7, Alignment::Center, None, '#'), - "##foo##" - ); - assert_eq!( - pad_str_with("foo", 7, Alignment::Left, None, '#'), - "foo####" - ); - assert_eq!( - pad_str_with("foo", 7, Alignment::Right, None, '#'), - "####foo" - ); - assert_eq!(pad_str_with("foo", 3, Alignment::Left, None, '#'), "foo"); - assert_eq!( - pad_str_with("foobar", 3, Alignment::Left, None, '#'), - "foobar" - ); - assert_eq!( - pad_str_with("foobar", 3, Alignment::Left, Some(""), '#'), - "foo" - ); - assert_eq!( - pad_str_with("foobarbaz", 6, Alignment::Left, Some("..."), '#'), - "foo..." - ); -} diff --git a/tooling/cli.rs/src/console/wasm_term.rs b/tooling/cli.rs/src/console/wasm_term.rs deleted file mode 100644 index 3452b56f2f17..000000000000 --- a/tooling/cli.rs/src/console/wasm_term.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::fmt::Display; -use std::io; - -use super::kb::Key; -use super::term::Term; - -pub use super::common_term::*; - -pub const DEFAULT_WIDTH: u16 = 80; - -#[inline] -pub fn is_a_terminal(_out: &Term) -> bool { - false -} - -#[inline] -pub fn is_a_color_terminal(_out: &Term) -> bool { - false -} - -#[inline] -pub fn terminal_size(_out: &Term) -> Option<(u16, u16)> { - None -} - -pub fn read_secure() -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "unsupported operation", - )) -} - -pub fn read_single_key() -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "unsupported operation", - )) -} - -#[inline] -pub fn wants_emoji() -> bool { - false -} - -pub fn set_title(_title: T) {} diff --git a/tooling/cli.rs/src/console/windows_term.rs b/tooling/cli.rs/src/console/windows_term.rs deleted file mode 100644 index 6c48cfde9d8c..000000000000 --- a/tooling/cli.rs/src/console/windows_term.rs +++ /dev/null @@ -1,600 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::cmp; -use std::env; -use std::ffi::OsStr; -use std::fmt::Display; -use std::io; -use std::iter::once; -use std::mem; -use std::os::windows::ffi::OsStrExt; -use std::os::windows::io::AsRawHandle; -use std::slice; -use std::{char, mem::MaybeUninit}; - -use encode_unicode::error::InvalidUtf16Tuple; -use encode_unicode::CharExt; -#[cfg(feature = "windows-console-colors")] -use regex::Regex; -use winapi::ctypes::c_void; -use winapi::shared::minwindef::DWORD; -use winapi::shared::minwindef::MAX_PATH; -use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode}; -use winapi::um::consoleapi::{GetNumberOfConsoleInputEvents, ReadConsoleInputW}; -use winapi::um::fileapi::FILE_NAME_INFO; -use winapi::um::handleapi::INVALID_HANDLE_VALUE; -use winapi::um::minwinbase::FileNameInfo; -use winapi::um::processenv::GetStdHandle; -use winapi::um::winbase::GetFileInformationByHandleEx; -use winapi::um::winbase::{STD_ERROR_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE}; -use winapi::um::wincon::{ - FillConsoleOutputAttribute, FillConsoleOutputCharacterA, GetConsoleCursorInfo, - GetConsoleScreenBufferInfo, SetConsoleCursorInfo, SetConsoleCursorPosition, SetConsoleTitleW, - CONSOLE_CURSOR_INFO, CONSOLE_SCREEN_BUFFER_INFO, COORD, INPUT_RECORD, KEY_EVENT, - KEY_EVENT_RECORD, -}; -use winapi::um::winnt::{CHAR, HANDLE, INT, WCHAR}; -#[cfg(feature = "windows-console-colors")] -use winapi_util::console::{Color, Console, Intense}; - -use super::common_term; -use super::kb::Key; -use super::term::{Term, TermTarget}; - -#[cfg(feature = "windows-console-colors")] -lazy_static::lazy_static! { - static ref INTENSE_COLOR_RE: Regex = Regex::new(r"\x1b\[(3|4)8;5;(8|9|1[0-5])m").unwrap(); - static ref NORMAL_COLOR_RE: Regex = Regex::new(r"\x1b\[(3|4)([0-7])m").unwrap(); - static ref ATTR_RE: Regex = Regex::new(r"\x1b\[([1-8])m").unwrap(); -} - -const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x4; -pub const DEFAULT_WIDTH: u16 = 79; - -pub fn as_handle(term: &Term) -> HANDLE { - // convert between winapi::um::winnt::HANDLE and std::os::windows::raw::HANDLE - // which are both c_void. would be nice to find a better way to do this - term.as_raw_handle() as HANDLE -} - -pub fn is_a_terminal(out: &Term) -> bool { - let (fd, others) = match out.target() { - TermTarget::Stdout => (STD_OUTPUT_HANDLE, [STD_INPUT_HANDLE, STD_ERROR_HANDLE]), - TermTarget::Stderr => (STD_ERROR_HANDLE, [STD_INPUT_HANDLE, STD_OUTPUT_HANDLE]), - }; - - if unsafe { console_on_any(&[fd]) } { - // False positives aren't possible. If we got a console then - // we definitely have a tty on stdin. - return true; - } - - // At this point, we *could* have a false negative. We can determine that - // this is true negative if we can detect the presence of a console on - // any of the other streams. If another stream has a console, then we know - // we're in a Windows console and can therefore trust the negative. - if unsafe { console_on_any(&others) } { - return false; - } - - msys_tty_on(out) -} - -pub fn is_a_color_terminal(out: &Term) -> bool { - if !is_a_terminal(out) { - return false; - } - if msys_tty_on(out) { - return match env::var("TERM") { - Ok(term) => term != "dumb", - Err(_) => true, - }; - } - enable_ansi_on(out) -} - -fn enable_ansi_on(out: &Term) -> bool { - unsafe { - let handle = as_handle(out); - - let mut dw_mode = 0; - if GetConsoleMode(handle, &mut dw_mode) == 0 { - return false; - } - - dw_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - if SetConsoleMode(handle, dw_mode) == 0 { - return false; - } - - true - } -} - -unsafe fn console_on_any(fds: &[DWORD]) -> bool { - for &fd in fds { - let mut out = 0; - let handle = GetStdHandle(fd); - if GetConsoleMode(handle, &mut out) != 0 { - return true; - } - } - false -} - -#[inline] -pub fn terminal_size(out: &Term) -> Option<(u16, u16)> { - terminal_size::terminal_size_using_handle(out.as_raw_handle()).map(|x| ((x.1).0, (x.0).0)) -} - -pub fn move_cursor_to(out: &Term, x: usize, y: usize) -> io::Result<()> { - if out.is_msys_tty { - return common_term::move_cursor_to(out, x, y); - } - if let Some((hand, _)) = get_console_screen_buffer_info(as_handle(out)) { - unsafe { - SetConsoleCursorPosition( - hand, - COORD { - X: x as i16, - Y: y as i16, - }, - ); - } - } - Ok(()) -} - -pub fn move_cursor_up(out: &Term, n: usize) -> io::Result<()> { - if out.is_msys_tty { - return common_term::move_cursor_up(out, n); - } - - if let Some((_, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - move_cursor_to(out, 0, csbi.dwCursorPosition.Y as usize - n)?; - } - Ok(()) -} - -pub fn move_cursor_down(out: &Term, n: usize) -> io::Result<()> { - if out.is_msys_tty { - return common_term::move_cursor_down(out, n); - } - - if let Some((_, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - move_cursor_to(out, 0, csbi.dwCursorPosition.Y as usize + n)?; - } - Ok(()) -} - -pub fn move_cursor_left(out: &Term, n: usize) -> io::Result<()> { - if out.is_msys_tty { - return common_term::move_cursor_left(out, n); - } - - if let Some((_, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - move_cursor_to( - out, - csbi.dwCursorPosition.X as usize - n, - csbi.dwCursorPosition.Y as usize, - )?; - } - Ok(()) -} - -pub fn move_cursor_right(out: &Term, n: usize) -> io::Result<()> { - if out.is_msys_tty { - return common_term::move_cursor_right(out, n); - } - - if let Some((_, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - move_cursor_to( - out, - csbi.dwCursorPosition.X as usize + n, - csbi.dwCursorPosition.Y as usize, - )?; - } - Ok(()) -} - -pub fn clear_line(out: &Term) -> io::Result<()> { - if out.is_msys_tty { - return common_term::clear_line(out); - } - if let Some((hand, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - unsafe { - let width = csbi.srWindow.Right - csbi.srWindow.Left; - let pos = COORD { - X: 0, - Y: csbi.dwCursorPosition.Y, - }; - let mut written = 0; - FillConsoleOutputCharacterA(hand, b' ' as CHAR, width as DWORD, pos, &mut written); - FillConsoleOutputAttribute(hand, csbi.wAttributes, width as DWORD, pos, &mut written); - SetConsoleCursorPosition(hand, pos); - } - } - Ok(()) -} - -pub fn clear_chars(out: &Term, n: usize) -> io::Result<()> { - if out.is_msys_tty { - return common_term::clear_chars(out, n); - } - if let Some((hand, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - unsafe { - let width = cmp::min(csbi.dwCursorPosition.X, n as i16); - let pos = COORD { - X: csbi.dwCursorPosition.X - width, - Y: csbi.dwCursorPosition.Y, - }; - let mut written = 0; - FillConsoleOutputCharacterA(hand, b' ' as CHAR, width as DWORD, pos, &mut written); - FillConsoleOutputAttribute(hand, csbi.wAttributes, width as DWORD, pos, &mut written); - SetConsoleCursorPosition(hand, pos); - } - } - Ok(()) -} - -pub fn clear_screen(out: &Term) -> io::Result<()> { - if out.is_msys_tty { - return common_term::clear_screen(out); - } - if let Some((hand, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - unsafe { - let cells = csbi.dwSize.X as DWORD * csbi.dwSize.Y as DWORD; // as DWORD, or else this causes stack overflows. - let pos = COORD { X: 0, Y: 0 }; - let mut written = 0; - FillConsoleOutputCharacterA(hand, b' ' as CHAR, cells, pos, &mut written); // cells as DWORD no longer needed. - FillConsoleOutputAttribute(hand, csbi.wAttributes, cells, pos, &mut written); - SetConsoleCursorPosition(hand, pos); - } - } - Ok(()) -} - -pub fn clear_to_end_of_screen(out: &Term) -> io::Result<()> { - if out.is_msys_tty { - return common_term::clear_to_end_of_screen(out); - } - if let Some((hand, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - unsafe { - let bottom = csbi.srWindow.Right as DWORD * csbi.srWindow.Bottom as DWORD; - let cells = bottom - (csbi.dwCursorPosition.X as DWORD * csbi.dwCursorPosition.Y as DWORD); // as DWORD, or else this causes stack overflows. - let pos = COORD { - X: 0, - Y: csbi.dwCursorPosition.Y, - }; - let mut written = 0; - FillConsoleOutputCharacterA(hand, b' ' as CHAR, cells, pos, &mut written); // cells as DWORD no longer needed. - FillConsoleOutputAttribute(hand, csbi.wAttributes, cells, pos, &mut written); - SetConsoleCursorPosition(hand, pos); - } - } - Ok(()) -} - -pub fn show_cursor(out: &Term) -> io::Result<()> { - if out.is_msys_tty { - return common_term::show_cursor(out); - } - if let Some((hand, mut cci)) = get_console_cursor_info(as_handle(out)) { - unsafe { - cci.bVisible = 1; - SetConsoleCursorInfo(hand, &cci); - } - } - Ok(()) -} - -pub fn hide_cursor(out: &Term) -> io::Result<()> { - if out.is_msys_tty { - return common_term::hide_cursor(out); - } - if let Some((hand, mut cci)) = get_console_cursor_info(as_handle(out)) { - unsafe { - cci.bVisible = 0; - SetConsoleCursorInfo(hand, &cci); - } - } - Ok(()) -} - -fn get_console_screen_buffer_info(hand: HANDLE) -> Option<(HANDLE, CONSOLE_SCREEN_BUFFER_INFO)> { - let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = unsafe { mem::zeroed() }; - match unsafe { GetConsoleScreenBufferInfo(hand, &mut csbi) } { - 0 => None, - _ => Some((hand, csbi)), - } -} - -fn get_console_cursor_info(hand: HANDLE) -> Option<(HANDLE, CONSOLE_CURSOR_INFO)> { - let mut cci: CONSOLE_CURSOR_INFO = unsafe { mem::zeroed() }; - match unsafe { GetConsoleCursorInfo(hand, &mut cci) } { - 0 => None, - _ => Some((hand, cci)), - } -} - -pub fn key_from_key_code(code: INT) -> Key { - match code { - winapi::um::winuser::VK_LEFT => Key::ArrowLeft, - winapi::um::winuser::VK_RIGHT => Key::ArrowRight, - winapi::um::winuser::VK_UP => Key::ArrowUp, - winapi::um::winuser::VK_DOWN => Key::ArrowDown, - winapi::um::winuser::VK_RETURN => Key::Enter, - winapi::um::winuser::VK_ESCAPE => Key::Escape, - winapi::um::winuser::VK_BACK => Key::Backspace, - winapi::um::winuser::VK_TAB => Key::Tab, - winapi::um::winuser::VK_HOME => Key::Home, - winapi::um::winuser::VK_END => Key::End, - winapi::um::winuser::VK_DELETE => Key::Del, - winapi::um::winuser::VK_SHIFT => Key::Shift, - _ => Key::Unknown, - } -} - -pub fn read_secure() -> io::Result { - let mut rv = String::new(); - loop { - match read_single_key()? { - Key::Enter => { - break; - } - Key::Char('\x08') => { - if !rv.is_empty() { - let new_len = rv.len() - 1; - rv.truncate(new_len); - } - } - Key::Char(c) => { - rv.push(c); - } - _ => {} - } - } - Ok(rv) -} - -pub fn read_single_key() -> io::Result { - let key_event = read_key_event()?; - - let unicode_char = unsafe { *key_event.uChar.UnicodeChar() }; - if unicode_char == 0 { - Ok(key_from_key_code(key_event.wVirtualKeyCode as INT)) - } else { - // This is a unicode character, in utf-16. Try to decode it by itself. - match char::from_utf16_tuple((unicode_char, None)) { - Ok(c) => { - // Maintain backward compatibility. The previous implementation (_getwch()) would return - // a special keycode for `Enter`, while ReadConsoleInputW() prefers to use '\r'. - if c == '\r' { - Ok(Key::Enter) - } else if c == '\x08' { - Ok(Key::Backspace) - } else if c == '\x1B' { - Ok(Key::Escape) - } else { - Ok(Key::Char(c)) - } - } - // This is part of a surrogate pair. Try to read the second half. - Err(InvalidUtf16Tuple::MissingSecond) => { - // Confirm that there is a next character to read. - if get_key_event_count()? == 0 { - let message = format!( - "Read invlid utf16 {}: {}", - unicode_char, - InvalidUtf16Tuple::MissingSecond - ); - return Err(io::Error::new(io::ErrorKind::InvalidData, message)); - } - - // Read the next character. - let next_event = read_key_event()?; - let next_surrogate = unsafe { *next_event.uChar.UnicodeChar() }; - - // Attempt to decode it. - match char::from_utf16_tuple((unicode_char, Some(next_surrogate))) { - Ok(c) => Ok(Key::Char(c)), - - // Return an InvalidData error. This is the recommended value for UTF-related I/O errors. - // (This error is given when reading a non-UTF8 file into a String, for example.) - Err(e) => { - let message = format!( - "Read invalid surrogate pair ({}, {}): {}", - unicode_char, next_surrogate, e - ); - Err(io::Error::new(io::ErrorKind::InvalidData, message)) - } - } - } - - // Return an InvalidData error. This is the recommended value for UTF-related I/O errors. - // (This error is given when reading a non-UTF8 file into a String, for example.) - Err(e) => { - let message = format!("Read invalid utf16 {}: {}", unicode_char, e); - Err(io::Error::new(io::ErrorKind::InvalidData, message)) - } - } - } -} - -fn get_stdin_handle() -> io::Result { - let handle = unsafe { GetStdHandle(STD_INPUT_HANDLE) }; - if handle == INVALID_HANDLE_VALUE { - Err(io::Error::last_os_error()) - } else { - Ok(handle) - } -} - -/// Get the number of pending events in the ReadConsoleInput queue. Note that while -/// these aren't necessarily key events, the only way that multiple events can be -/// put into the queue simultaneously is if a unicode character spanning multiple u16's -/// is read. -/// -/// Therefore, this is accurate as long as at least one KEY_EVENT has already been read. -fn get_key_event_count() -> io::Result { - let handle = get_stdin_handle()?; - let mut event_count: DWORD = unsafe { mem::zeroed() }; - - let success = unsafe { GetNumberOfConsoleInputEvents(handle, &mut event_count) }; - if success == 0 { - Err(io::Error::last_os_error()) - } else { - Ok(event_count) - } -} - -fn read_key_event() -> io::Result { - let handle = get_stdin_handle()?; - let mut buffer: INPUT_RECORD = unsafe { mem::zeroed() }; - - let mut events_read: DWORD = unsafe { mem::zeroed() }; - - let mut key_event: KEY_EVENT_RECORD; - loop { - let success = unsafe { ReadConsoleInputW(handle, &mut buffer, 1, &mut events_read) }; - if success == 0 { - return Err(io::Error::last_os_error()); - } - if events_read == 0 { - return Err(io::Error::new( - io::ErrorKind::Other, - "ReadConsoleInput returned no events, instead of waiting for an event", - )); - } - - if events_read == 1 && buffer.EventType != KEY_EVENT { - // This isn't a key event; ignore it. - continue; - } - - key_event = unsafe { mem::transmute(buffer.Event) }; - - if key_event.bKeyDown == 0 { - // This is a key being released; ignore it. - continue; - } - - return Ok(key_event); - } -} - -pub fn wants_emoji() -> bool { - // If WT_SESSION is set, we can assume we're running in the nne - // Windows Terminal. The correct way to detect this is not available - // yet. See https://github.com/microsoft/terminal/issues/1040 - env::var("WT_SESSION").is_ok() -} - -/// Returns true if there is an MSYS tty on the given handle. -pub fn msys_tty_on(term: &Term) -> bool { - let handle = term.as_raw_handle(); - unsafe { - // Check whether the Windows 10 native pty is enabled - { - let mut out = MaybeUninit::uninit(); - let res = GetConsoleMode(handle as *mut _, out.as_mut_ptr()); - if res != 0 // If res is true then out was initialized. - && (out.assume_init() & ENABLE_VIRTUAL_TERMINAL_PROCESSING) - == ENABLE_VIRTUAL_TERMINAL_PROCESSING - { - return true; - } - } - - let size = mem::size_of::(); - let mut name_info_bytes = vec![0u8; size + MAX_PATH * mem::size_of::()]; - let res = GetFileInformationByHandleEx( - handle as *mut _, - FileNameInfo, - &mut *name_info_bytes as *mut _ as *mut c_void, - name_info_bytes.len() as u32, - ); - if res == 0 { - return false; - } - let name_info: &FILE_NAME_INFO = &*(name_info_bytes.as_ptr() as *const FILE_NAME_INFO); - let s = slice::from_raw_parts( - name_info.FileName.as_ptr(), - name_info.FileNameLength as usize / 2, - ); - let name = String::from_utf16_lossy(s); - // This checks whether 'pty' exists in the file name, which indicates that - // a pseudo-terminal is attached. To mitigate against false positives - // (e.g., an actual file name that contains 'pty'), we also require that - // either the strings 'msys-' or 'cygwin-' are in the file name as well.) - let is_msys = name.contains("msys-") || name.contains("cygwin-"); - let is_pty = name.contains("-pty"); - is_msys && is_pty - } -} - -pub fn set_title(title: T) { - let buffer: Vec = OsStr::new(&format!("{}", title)) - .encode_wide() - .chain(once(0)) - .collect(); - unsafe { - SetConsoleTitleW(buffer.as_ptr()); - } -} - -#[cfg(feature = "windows-console-colors")] -pub fn console_colors(out: &Term, mut con: Console, bytes: &[u8]) -> io::Result<()> { - use super::ansi::AnsiCodeIterator; - use std::str::from_utf8; - - let s = from_utf8(bytes).expect("data to be printed is not an ansi string"); - let mut iter = AnsiCodeIterator::new(s); - - while !iter.rest_slice().is_empty() { - if let Some((part, is_esc)) = iter.next() { - if !is_esc { - out.write_through_common(part.as_bytes())?; - } else if part == "\x1b[0m" { - con.reset()?; - } else if let Some(cap) = INTENSE_COLOR_RE.captures(part) { - let color = get_color_from_ansi(cap.get(2).unwrap().as_str()); - - match cap.get(1).unwrap().as_str() { - "3" => con.fg(Intense::Yes, color)?, - "4" => con.bg(Intense::Yes, color)?, - _ => unreachable!(), - }; - } else if let Some(cap) = NORMAL_COLOR_RE.captures(part) { - let color = get_color_from_ansi(cap.get(2).unwrap().as_str()); - - match cap.get(1).unwrap().as_str() { - "3" => con.fg(Intense::No, color)?, - "4" => con.bg(Intense::No, color)?, - _ => unreachable!(), - }; - } else if !ATTR_RE.is_match(part) { - out.write_through_common(part.as_bytes())?; - } - } - } - - Ok(()) -} - -#[cfg(feature = "windows-console-colors")] -fn get_color_from_ansi(ansi: &str) -> Color { - match ansi { - "0" | "8" => Color::Black, - "1" | "9" => Color::Red, - "2" | "10" => Color::Green, - "3" | "11" => Color::Yellow, - "4" | "12" => Color::Blue, - "5" | "13" => Color::Magenta, - "6" | "14" => Color::Cyan, - "7" | "15" => Color::White, - _ => unreachable!(), - } -} diff --git a/tooling/cli.rs/src/dev.rs b/tooling/cli.rs/src/dev.rs deleted file mode 100644 index ff2135c59068..000000000000 --- a/tooling/cli.rs/src/dev.rs +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use crate::helpers::{ - app_paths::{app_dir, tauri_dir}, - config::{get as get_config, reload as reload_config}, - manifest::{get_workspace_members, rewrite_manifest}, - Logger, -}; - -use anyhow::Context; -use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher}; -use once_cell::sync::OnceCell; -use shared_child::SharedChild; - -use std::{ - env::set_current_dir, - ffi::OsStr, - process::{exit, Child, Command}, - sync::{ - mpsc::{channel, Receiver}, - Arc, Mutex, - }, - time::Duration, -}; - -static BEFORE_DEV: OnceCell> = OnceCell::new(); - -fn kill_before_dev_process() { - if let Some(child) = BEFORE_DEV.get() { - let mut child = child.lock().unwrap(); - #[cfg(windows)] - let _ = Command::new("powershell") - .arg("-NoProfile") - .arg("-Command") - .arg(format!("function Kill-Tree {{ Param([int]$ppid); Get-CimInstance Win32_Process | Where-Object {{ $_.ParentProcessId -eq $ppid }} | ForEach-Object {{ Kill-Tree $_.ProcessId }}; Stop-Process -Id $ppid }}; Kill-Tree {}", child.id())) - .status(); - #[cfg(not(windows))] - let _ = Command::new("pkill") - .args(&["-TERM", "-P"]) - .arg(child.id().to_string()) - .status(); - let _ = child.kill(); - } -} - -#[derive(Default)] -pub struct Dev { - runner: Option, - target: Option, - features: Option>, - exit_on_panic: bool, - config: Option, - args: Vec, - release_mode: bool, -} - -impl Dev { - pub fn new() -> Self { - Default::default() - } - - pub fn runner(mut self, runner: String) -> Self { - self.runner.replace(runner); - self - } - - pub fn target(mut self, target: String) -> Self { - self.target.replace(target); - self - } - - pub fn features(mut self, features: Vec) -> Self { - self.features.replace(features); - self - } - - pub fn config(mut self, config: String) -> Self { - self.config.replace(config); - self - } - - pub fn exit_on_panic(mut self, exit_on_panic: bool) -> Self { - self.exit_on_panic = exit_on_panic; - self - } - - pub fn args(mut self, args: Vec) -> Self { - self.args = args; - self - } - - pub fn release_mode(mut self, release_mode: bool) -> Self { - self.release_mode = release_mode; - self - } - - pub fn run(self) -> crate::Result<()> { - let logger = Logger::new("tauri:dev"); - let tauri_path = tauri_dir(); - set_current_dir(&tauri_path).with_context(|| "failed to change current working directory")?; - let merge_config = self.config.clone(); - let config = get_config(merge_config.as_deref())?; - let mut process: Arc; - - let (settings, out_dir) = { - let config_guard = config.lock().unwrap(); - let config_ = config_guard.as_ref().unwrap(); - let app_settings = crate::interface::rust::AppSettings::new(config_)?; - let out_dir = app_settings - .get_out_dir(self.target.clone(), true) - .with_context(|| "failed to get project out directory")?; - let settings = crate::interface::get_bundler_settings( - app_settings, - self.target.clone(), - &Default::default(), - config_, - &out_dir, - false, - None, - ) - .with_context(|| "failed to build bundler settings")?; - (settings, out_dir) - }; - settings.copy_resources(&out_dir)?; - settings.copy_binaries(&out_dir)?; - - if let Some(before_dev) = &config - .lock() - .unwrap() - .as_ref() - .unwrap() - .build - .before_dev_command - { - if !before_dev.is_empty() { - logger.log(format!("Running `{}`", before_dev)); - #[cfg(target_os = "windows")] - let child = Command::new("cmd") - .arg("/C") - .arg(before_dev) - .current_dir(app_dir()) - .spawn() - .with_context(|| format!("failed to run `{}` with `cmd /C`", before_dev))?; - #[cfg(not(target_os = "windows"))] - let child = Command::new("sh") - .arg("-c") - .arg(before_dev) - .current_dir(app_dir()) - .spawn() - .with_context(|| format!("failed to run `{}` with `sh -c`", before_dev))?; - BEFORE_DEV.set(Mutex::new(child)).unwrap(); - } - } - - let runner_from_config = config - .lock() - .unwrap() - .as_ref() - .unwrap() - .build - .runner - .clone(); - let runner = self - .runner - .clone() - .or(runner_from_config) - .unwrap_or_else(|| "cargo".to_string()); - - { - let (tx, rx) = channel(); - let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); - watcher.watch(tauri_path.join("Cargo.toml"), RecursiveMode::Recursive)?; - rewrite_manifest(config.clone())?; - loop { - if let Ok(DebouncedEvent::NoticeWrite(_)) = rx.recv() { - break; - } - } - } - - let mut cargo_features = config - .lock() - .unwrap() - .as_ref() - .unwrap() - .build - .features - .clone() - .unwrap_or_default(); - if let Some(features) = &self.features { - cargo_features.extend(features.clone()); - } - - let (child_wait_tx, child_wait_rx) = channel(); - let child_wait_rx = Arc::new(Mutex::new(child_wait_rx)); - - process = self.start_app(&runner, &cargo_features, child_wait_rx.clone()); - - let (tx, rx) = channel(); - - let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); - watcher.watch(tauri_path.join("src"), RecursiveMode::Recursive)?; - watcher.watch(tauri_path.join("Cargo.toml"), RecursiveMode::Recursive)?; - watcher.watch(tauri_path.join("tauri.conf.json"), RecursiveMode::Recursive)?; - - for member in get_workspace_members()? { - let workspace_path = tauri_path.join(member); - watcher.watch(workspace_path.join("src"), RecursiveMode::Recursive)?; - watcher.watch(workspace_path.join("Cargo.toml"), RecursiveMode::Recursive)?; - } - - loop { - if let Ok(event) = rx.recv() { - let event_path = match event { - DebouncedEvent::Create(path) => Some(path), - DebouncedEvent::Remove(path) => Some(path), - DebouncedEvent::Rename(_, dest) => Some(dest), - DebouncedEvent::Write(path) => Some(path), - _ => None, - }; - - if let Some(event_path) = event_path { - if event_path.file_name() == Some(OsStr::new("tauri.conf.json")) { - reload_config(merge_config.as_deref())?; - rewrite_manifest(config.clone())?; - } else { - // When tauri.conf.json is changed, rewrite_manifest will be called - // which will trigger the watcher again - // So the app should only be started when a file other than tauri.conf.json is changed - let _ = child_wait_tx.send(()); - process - .kill() - .with_context(|| "failed to kill app process")?; - // wait for the process to exit - loop { - if let Ok(Some(_)) = process.try_wait() { - break; - } - } - process = self.start_app(&runner, &cargo_features, child_wait_rx.clone()); - } - } - } - } - } - - fn start_app( - &self, - runner: &str, - features: &[String], - child_wait_rx: Arc>>, - ) -> Arc { - let mut command = Command::new(runner); - command.args(&["run", "--no-default-features"]); - - if self.release_mode { - command.args(&["--release"]); - } - - if let Some(target) = &self.target { - command.args(&["--target", target]); - } - - if !features.is_empty() { - command.args(&["--features", &features.join(",")]); - } - - if !self.args.is_empty() { - command.arg("--").args(&self.args); - } - - let child = - SharedChild::spawn(&mut command).unwrap_or_else(|_| panic!("failed to run {}", runner)); - let child_arc = Arc::new(child); - - let child_clone = child_arc.clone(); - let exit_on_panic = self.exit_on_panic; - std::thread::spawn(move || { - let status = child_clone.wait().expect("failed to wait on child"); - if exit_on_panic { - // we exit if the status is a success code (app closed) or code is 101 (compilation error) - // if the process wasn't killed by the file watcher - if (status.success() || status.code() == Some(101)) - // `child_wait_rx` indicates that the process was killed by the file watcher - && child_wait_rx - .lock() - .expect("failed to get child_wait_rx lock") - .try_recv() - .is_err() - { - kill_before_dev_process(); - exit(0); - } - } else if status.success() { - // if we're no exiting on panic, we only exit if the status is a success code (app closed) - kill_before_dev_process(); - exit(0); - } - }); - - child_arc - } -} diff --git a/tooling/cli.rs/src/dialoguer/edit.rs b/tooling/cli.rs/src/dialoguer/edit.rs deleted file mode 100644 index 3ef83637fe5d..000000000000 --- a/tooling/cli.rs/src/dialoguer/edit.rs +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::{ - env, - ffi::{OsStr, OsString}, - fs, io, - io::{Read, Write}, - process, -}; - -/// Launches the default editor to edit a string. -/// -/// ## Example -/// -/// ```rust,no_run -/// use dialoguer::Editor; -/// -/// if let Some(rv) = Editor::new().edit("Enter a commit message").unwrap() { -/// println!("Your message:"); -/// println!("{}", rv); -/// } else { -/// println!("Abort!"); -/// } -/// ``` -pub struct Editor { - editor: OsString, - extension: String, - require_save: bool, - trim_newlines: bool, -} - -fn get_default_editor() -> OsString { - if let Some(prog) = env::var_os("VISUAL") { - return prog; - } - if let Some(prog) = env::var_os("EDITOR") { - return prog; - } - if cfg!(windows) { - "notepad.exe".into() - } else { - "vi".into() - } -} - -impl Default for Editor { - fn default() -> Editor { - Editor::new() - } -} - -impl Editor { - /// Creates a new editor. - pub fn new() -> Editor { - Editor { - editor: get_default_editor(), - extension: ".txt".into(), - require_save: true, - trim_newlines: true, - } - } - - /// Sets a specific editor executable. - pub fn executable>(&mut self, val: S) -> &mut Editor { - self.editor = val.as_ref().into(); - self - } - - /// Sets a specific extension - pub fn extension(&mut self, val: &str) -> &mut Editor { - self.extension = val.into(); - self - } - - /// Enables or disables the save requirement. - pub fn require_save(&mut self, val: bool) -> &mut Editor { - self.require_save = val; - self - } - - /// Enables or disables trailing newline stripping. - /// - /// This is on by default. - pub fn trim_newlines(&mut self, val: bool) -> &mut Editor { - self.trim_newlines = val; - self - } - - /// Launches the editor to edit a string. - /// - /// Returns `None` if the file was not saved or otherwise the - /// entered text. - pub fn edit(&self, s: &str) -> io::Result> { - let mut f = tempfile::Builder::new() - .prefix("edit-") - .suffix(&self.extension) - .rand_bytes(12) - .tempfile()?; - f.write_all(s.as_bytes())?; - f.flush()?; - let ts = fs::metadata(f.path())?.modified()?; - - let s: String = self.editor.clone().into_string().unwrap(); - let mut iterator = s.split(' '); - let cmd = iterator.next().unwrap(); - let args: Vec<&str> = iterator.collect(); - - let rv = process::Command::new(cmd) - .args(args) - .arg(f.path()) - .spawn()? - .wait()?; - - if rv.success() && self.require_save && ts >= fs::metadata(f.path())?.modified()? { - return Ok(None); - } - - let mut new_f = fs::File::open(f.path())?; - let mut rv = String::new(); - new_f.read_to_string(&mut rv)?; - - if self.trim_newlines { - let len = rv.trim_end_matches(&['\n', '\r'][..]).len(); - rv.truncate(len); - } - - Ok(Some(rv)) - } -} diff --git a/tooling/cli.rs/src/dialoguer/mod.rs b/tooling/cli.rs/src/dialoguer/mod.rs deleted file mode 100644 index 7d2646e30d93..000000000000 --- a/tooling/cli.rs/src/dialoguer/mod.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -//! dialoguer is a library for Rust that helps you build useful small -//! interactive user inputs for the command line. It provides utilities -//! to render various simple dialogs like confirmation prompts, text -//! inputs and more. -//! -//! Best paired with other libraries in the family: -//! -//! * [indicatif](https://docs.rs/indicatif) -//! * [console](https://docs.rs/console) -//! -//! # Crate Contents -//! -//! * Confirmation prompts -//! * Input prompts (regular and password) -//! * Input validation -//! * Selections prompts (single and multi) -//! * Other kind of prompts -//! * Editor launching - -pub use edit::Editor; -pub use prompts::{ - confirm::Confirm, input::Input, multi_select::MultiSelect, password::Password, select::Select, - sort::Sort, -}; -pub use validate::Validator; - -mod edit; -mod prompts; -pub mod theme; -mod validate; diff --git a/tooling/cli.rs/src/dialoguer/prompts/confirm.rs b/tooling/cli.rs/src/dialoguer/prompts/confirm.rs deleted file mode 100644 index 1aaff5985fba..000000000000 --- a/tooling/cli.rs/src/dialoguer/prompts/confirm.rs +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::io; - -use super::super::theme::{SimpleTheme, TermThemeRenderer, Theme}; - -use crate::console::{Key, Term}; - -/// Renders a confirm prompt. -/// -/// ## Example usage -/// -/// ```rust,no_run -/// # fn test() -> Result<(), Box> { -/// use dialoguer::Confirm; -/// -/// if Confirm::new().with_prompt("Do you want to continue?").interact()? { -/// println!("Looks like you want to continue"); -/// } else { -/// println!("nevermind then :("); -/// } -/// # Ok(()) } fn main() { test().unwrap(); } -/// ``` -pub struct Confirm<'a> { - prompt: String, - default: Option, - show_default: bool, - wait_for_newline: bool, - theme: &'a dyn Theme, -} - -impl<'a> Default for Confirm<'a> { - fn default() -> Confirm<'a> { - Confirm::new() - } -} - -impl<'a> Confirm<'a> { - /// Creates a confirm prompt. - pub fn new() -> Confirm<'static> { - Confirm::with_theme(&SimpleTheme) - } - - /// Creates a confirm prompt with a specific theme. - /// - /// ## Examples - /// ```rust,no_run - /// use dialoguer::{ - /// Confirm, - /// theme::ColorfulTheme - /// }; - /// - /// # fn main() -> std::io::Result<()> { - /// let proceed = Confirm::with_theme(&ColorfulTheme::default()) - /// .with_prompt("Do you wish to continue?") - /// .interact()?; - /// # Ok(()) - /// # } - /// ``` - pub fn with_theme(theme: &'a dyn Theme) -> Confirm<'a> { - Confirm { - prompt: "".into(), - default: None, - show_default: true, - wait_for_newline: false, - theme, - } - } - - /// Sets the confirm prompt. - pub fn with_prompt>(&mut self, prompt: S) -> &mut Confirm<'a> { - self.prompt = prompt.into(); - self - } - - #[deprecated(note = "Use with_prompt() instead", since = "0.6.0")] - #[inline] - pub fn with_text(&mut self, text: &str) -> &mut Confirm<'a> { - self.with_prompt(text) - } - - /// Sets when to react to user input. - /// - /// When `false` (default), we check on each user keystroke immediately as - /// it is typed. Valid inputs can be one of 'y', 'n', or a newline to accept - /// the default. - /// - /// When `true`, the user must type their choice and hit the Enter key before - /// proceeding. Valid inputs can be "yes", "no", "y", "n", or an empty string - /// to accept the default. - pub fn wait_for_newline(&mut self, wait: bool) -> &mut Confirm<'a> { - self.wait_for_newline = wait; - self - } - - /// Sets a default. - /// - /// Out of the box the prompt does not have a default and will continue - /// to display until the user inputs something and hits enter. If a default is set the user - /// can instead accept the default with enter. - pub fn default(&mut self, val: bool) -> &mut Confirm<'a> { - self.default = Some(val); - self - } - - /// Disables or enables the default value display. - /// - /// The default is to append the default value to the prompt to tell the user. - pub fn show_default(&mut self, val: bool) -> &mut Confirm<'a> { - self.show_default = val; - self - } - - /// Enables user interaction and returns the result. - /// - /// If the user confirms the result is `true`, `false` if declines or default (configured in [default](#method.default)) if pushes enter. - /// Otherwise function discards input waiting for valid one. - /// - /// The dialog is rendered on stderr. - pub fn interact(&self) -> io::Result { - self.interact_on(&Term::stderr()) - } - - /// Enables user interaction and returns the result. - /// - /// This method is similar to [interact_on_opt](#method.interact_on_opt) except for the fact that it does not allow selection of the terminal. - /// The dialog is rendered on stderr. - /// Result contains `Some(bool)` if user answered "yes" or "no" or `None` if user cancelled with 'Esc' or 'q'. - pub fn interact_opt(&self) -> io::Result> { - self.interact_on_opt(&Term::stderr()) - } - - /// Like [interact](#method.interact) but allows a specific terminal to be set. - /// - /// ## Examples - /// - /// ```rust,no_run - /// use dialoguer::Confirm; - /// use console::Term; - /// - /// # fn main() -> std::io::Result<()> { - /// let proceed = Confirm::new() - /// .with_prompt("Do you wish to continue?") - /// .interact_on(&Term::stderr())?; - /// # Ok(()) - /// # } - /// ``` - pub fn interact_on(&self, term: &Term) -> io::Result { - self - ._interact_on(term, false)? - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Quit not allowed in this case")) - } - - /// Like [interact_opt](#method.interact_opt) but allows a specific terminal to be set. - /// - /// ## Examples - /// ```rust,no_run - /// use dialoguer::Confirm; - /// use console::Term; - /// - /// fn main() -> std::io::Result<()> { - /// let confirmation = Confirm::new() - /// .interact_on_opt(&Term::stdout())?; - /// - /// match confirmation { - /// Some(answer) => println!("User answered {}", if answer { "yes" } else { "no " }), - /// None => println!("User did not answer") - /// } - /// - /// Ok(()) - /// } - /// ``` - pub fn interact_on_opt(&self, term: &Term) -> io::Result> { - self._interact_on(term, true) - } - - fn _interact_on(&self, term: &Term, allow_quit: bool) -> io::Result> { - let mut render = TermThemeRenderer::new(term, self.theme); - - let default_if_show = if self.show_default { - self.default - } else { - None - }; - - render.confirm_prompt(&self.prompt, default_if_show)?; - - term.hide_cursor()?; - term.flush()?; - - let rv; - - if self.wait_for_newline { - // Waits for user input and for the user to hit the Enter key - // before validation. - let mut value = default_if_show; - - loop { - let input = term.read_key()?; - - match input { - Key::Char('y') | Key::Char('Y') => { - value = Some(true); - } - Key::Char('n') | Key::Char('N') => { - value = Some(false); - } - Key::Enter => { - if !allow_quit { - value = value.or(self.default); - } - - if value.is_some() || allow_quit { - rv = value; - break; - } - continue; - } - Key::Escape | Key::Char('q') if allow_quit => { - value = None; - } - _ => { - continue; - } - }; - - term.clear_line()?; - render.confirm_prompt(&self.prompt, value)?; - } - } else { - // Default behavior: matches continuously on every keystroke, - // and does not wait for user to hit the Enter key. - loop { - let input = term.read_key()?; - let value = match input { - Key::Char('y') | Key::Char('Y') => Some(true), - Key::Char('n') | Key::Char('N') => Some(false), - Key::Enter if self.default.is_some() => Some(self.default.unwrap()), - Key::Escape | Key::Char('q') if allow_quit => None, - _ => { - continue; - } - }; - - rv = value; - break; - } - } - - term.clear_line()?; - render.confirm_prompt_selection(&self.prompt, rv)?; - term.show_cursor()?; - term.flush()?; - - Ok(rv) - } -} diff --git a/tooling/cli.rs/src/dialoguer/prompts/input.rs b/tooling/cli.rs/src/dialoguer/prompts/input.rs deleted file mode 100644 index f90bbc1af8cd..000000000000 --- a/tooling/cli.rs/src/dialoguer/prompts/input.rs +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::{ - fmt::{Debug, Display}, - io, iter, - str::FromStr, -}; - -use super::super::{ - theme::{SimpleTheme, TermThemeRenderer, Theme}, - validate::Validator, -}; - -use crate::console::{Key, Term}; - -/// Renders an input prompt. -/// -/// ## Example usage -/// -/// ```rust,no_run -/// use dialoguer::Input; -/// -/// # fn test() -> Result<(), Box> { -/// let input : String = Input::new() -/// .with_prompt("Tea or coffee?") -/// .with_initial_text("Yes") -/// .default("No".into()) -/// .interact_text()?; -/// # Ok(()) -/// # } -/// ``` -/// It can also be used with turbofish notation: -/// -/// ```rust,no_run -/// # fn test() -> Result<(), Box> { -/// # use dialoguer::Input; -/// let input = Input::::new() -/// .interact_text()?; -/// # Ok(()) -/// # } -/// ``` -pub struct Input<'a, T> { - prompt: String, - default: Option, - show_default: bool, - initial_text: Option, - theme: &'a dyn Theme, - permit_empty: bool, - validator: Option Option + 'a>>, -} - -impl<'a, T> Default for Input<'a, T> -where - T: Clone + FromStr + Display, - T::Err: Display + Debug, -{ - fn default() -> Input<'a, T> { - Input::new() - } -} - -impl<'a, T> Input<'a, T> -where - T: Clone + FromStr + Display, - T::Err: Display + Debug, -{ - /// Creates an input prompt. - pub fn new() -> Input<'a, T> { - Input::with_theme(&SimpleTheme) - } - - /// Creates an input prompt with a specific theme. - pub fn with_theme(theme: &'a dyn Theme) -> Input<'a, T> { - Input { - prompt: "".into(), - default: None, - show_default: true, - initial_text: None, - theme, - permit_empty: false, - validator: None, - } - } - - /// Sets the input prompt. - pub fn with_prompt>(&mut self, prompt: S) -> &mut Input<'a, T> { - self.prompt = prompt.into(); - self - } - - /// Sets initial text that user can accept or erase. - pub fn with_initial_text>(&mut self, val: S) -> &mut Input<'a, T> { - self.initial_text = Some(val.into()); - self - } - - /// Sets a default. - /// - /// Out of the box the prompt does not have a default and will continue - /// to display until the user inputs something and hits enter. If a default is set the user - /// can instead accept the default with enter. - pub fn default(&mut self, value: T) -> &mut Input<'a, T> { - self.default = Some(value); - self - } - - /// Enables or disables an empty input - /// - /// By default, if there is no default value set for the input, the user must input a non-empty string. - pub fn allow_empty(&mut self, val: bool) -> &mut Input<'a, T> { - self.permit_empty = val; - self - } - - /// Disables or enables the default value display. - /// - /// The default behaviour is to append [`default`] to the prompt to tell the - /// user what is the default value. - /// - /// This method does not affect existence of default value, only its display in the prompt! - pub fn show_default(&mut self, val: bool) -> &mut Input<'a, T> { - self.show_default = val; - self - } - - /// Registers a validator. - /// - /// # Example - /// - /// ```no_run - /// # use dialoguer::Input; - /// let mail: String = Input::new() - /// .with_prompt("Enter email") - /// .validate_with(|input: &String| -> Result<(), &str> { - /// if input.contains('@') { - /// Ok(()) - /// } else { - /// Err("This is not a mail address") - /// } - /// }) - /// .interact() - /// .unwrap(); - /// ``` - pub fn validate_with(&mut self, mut validator: V) -> &mut Input<'a, T> - where - V: Validator + 'a, - T: 'a, - { - let mut old_validator_func = self.validator.take(); - - self.validator = Some(Box::new(move |value: &T| -> Option { - if let Some(old) = old_validator_func.as_mut() { - if let Some(err) = old(value) { - return Some(err); - } - } - - match validator.validate(value) { - Ok(()) => None, - Err(err) => Some(err.to_string()), - } - })); - - self - } - - /// Enables the user to enter a printable ascii sequence and returns the result. - /// - /// Its difference from [`interact`](#method.interact) is that it only allows ascii characters for string, - /// while [`interact`](#method.interact) allows virtually any character to be used e.g arrow keys. - /// - /// The dialog is rendered on stderr. - pub fn interact_text(&mut self) -> io::Result { - self.interact_text_on(&Term::stderr()) - } - - /// Like [`interact_text`](#method.interact_text) but allows a specific terminal to be set. - pub fn interact_text_on(&mut self, term: &Term) -> io::Result { - let mut render = TermThemeRenderer::new(term, self.theme); - - loop { - let default_string = self.default.as_ref().map(|x| x.to_string()); - - render.input_prompt( - &self.prompt, - if self.show_default { - default_string.as_deref() - } else { - None - }, - )?; - term.flush()?; - - // Read input by keystroke so that we can suppress ascii control characters - if !term.features().is_attended() { - return Ok("".to_owned().parse::().unwrap()); - } - - let mut chars: Vec = Vec::new(); - let mut position = 0; - - if let Some(initial) = self.initial_text.as_ref() { - term.write_str(initial)?; - chars = initial.chars().collect(); - position = chars.len(); - } - - loop { - match term.read_key()? { - Key::Backspace if position > 0 => { - position -= 1; - chars.remove(position); - term.clear_chars(1)?; - - let tail: String = chars[position..].iter().collect(); - - if !tail.is_empty() { - term.write_str(&tail)?; - term.move_cursor_left(tail.len())?; - } - - term.flush()?; - } - Key::Char(chr) if !chr.is_ascii_control() => { - chars.insert(position, chr); - position += 1; - let tail: String = iter::once(&chr).chain(chars[position..].iter()).collect(); - term.write_str(&tail)?; - term.move_cursor_left(tail.len() - 1)?; - term.flush()?; - } - Key::ArrowLeft if position > 0 => { - term.move_cursor_left(1)?; - position -= 1; - term.flush()?; - } - Key::ArrowRight if position < chars.len() => { - term.move_cursor_right(1)?; - position += 1; - term.flush()?; - } - Key::Enter => break, - Key::Unknown => { - return Err(io::Error::new( - io::ErrorKind::NotConnected, - "Not a terminal", - )) - } - _ => (), - } - } - let input = chars.iter().collect::(); - - term.clear_line()?; - render.clear()?; - - if chars.is_empty() { - if let Some(ref default) = self.default { - render.input_prompt_selection(&self.prompt, &default.to_string())?; - term.flush()?; - return Ok(default.clone()); - } else if !self.permit_empty { - continue; - } - } - - match input.parse::() { - Ok(value) => { - if let Some(ref mut validator) = self.validator { - if let Some(err) = validator(&value) { - render.error(&err)?; - continue; - } - } - - render.input_prompt_selection(&self.prompt, &input)?; - term.flush()?; - - return Ok(value); - } - Err(err) => { - render.error(&err.to_string())?; - continue; - } - } - } - } - - /// Enables user interaction and returns the result. - /// - /// Allows any characters as input, including e.g arrow keys. - /// Some of the keys might have undesired behavior. - /// For more limited version, see [`interact_text`](#method.interact_text). - /// - /// If the user confirms the result is `true`, `false` otherwise. - /// The dialog is rendered on stderr. - pub fn interact(&mut self) -> io::Result { - self.interact_on(&Term::stderr()) - } - - /// Like [`interact`](#method.interact) but allows a specific terminal to be set. - pub fn interact_on(&mut self, term: &Term) -> io::Result { - let mut render = TermThemeRenderer::new(term, self.theme); - - loop { - let default_string = self.default.as_ref().map(|x| x.to_string()); - - render.input_prompt( - &self.prompt, - if self.show_default { - default_string.as_deref() - } else { - None - }, - )?; - term.flush()?; - - let input = if let Some(initial_text) = self.initial_text.as_ref() { - term.read_line_initial_text(initial_text)? - } else { - term.read_line()? - }; - - render.add_line(); - term.clear_line()?; - render.clear()?; - - if input.is_empty() { - if let Some(ref default) = self.default { - render.input_prompt_selection(&self.prompt, &default.to_string())?; - term.flush()?; - return Ok(default.clone()); - } else if !self.permit_empty { - continue; - } - } - - match input.parse::() { - Ok(value) => { - if let Some(ref mut validator) = self.validator { - if let Some(err) = validator(&value) { - render.error(&err)?; - continue; - } - } - - render.input_prompt_selection(&self.prompt, &input)?; - term.flush()?; - - return Ok(value); - } - Err(err) => { - render.error(&err.to_string())?; - continue; - } - } - } - } -} diff --git a/tooling/cli.rs/src/dialoguer/prompts/mod.rs b/tooling/cli.rs/src/dialoguer/prompts/mod.rs deleted file mode 100644 index 6bb19ed10216..000000000000 --- a/tooling/cli.rs/src/dialoguer/prompts/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -#![allow(clippy::needless_doctest_main)] - -pub mod confirm; -pub mod input; -pub mod multi_select; -pub mod password; -pub mod select; -pub mod sort; diff --git a/tooling/cli.rs/src/dialoguer/prompts/multi_select.rs b/tooling/cli.rs/src/dialoguer/prompts/multi_select.rs deleted file mode 100644 index 55d56baeb172..000000000000 --- a/tooling/cli.rs/src/dialoguer/prompts/multi_select.rs +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::{io, iter::repeat, ops::Rem}; - -use super::super::theme::{SimpleTheme, TermThemeRenderer, Theme}; - -use crate::console::{Key, Term}; - -/// Renders a multi select prompt. -/// -/// ## Example usage -/// ```rust,no_run -/// # fn test() -> Result<(), Box> { -/// use dialoguer::MultiSelect; -/// -/// let items = vec!["Option 1", "Option 2"]; -/// let chosen : Vec = MultiSelect::new() -/// .items(&items) -/// .interact()?; -/// # Ok(()) -/// # } -/// ``` -pub struct MultiSelect<'a> { - defaults: Vec, - items: Vec, - prompt: Option, - clear: bool, - theme: &'a dyn Theme, - paged: bool, -} - -impl<'a> Default for MultiSelect<'a> { - fn default() -> MultiSelect<'a> { - MultiSelect::new() - } -} - -impl<'a> MultiSelect<'a> { - /// Creates a multi select prompt. - pub fn new() -> MultiSelect<'static> { - MultiSelect::with_theme(&SimpleTheme) - } - - /// Creates a multi select prompt with a specific theme. - pub fn with_theme(theme: &'a dyn Theme) -> MultiSelect<'a> { - MultiSelect { - items: vec![], - defaults: vec![], - clear: true, - prompt: None, - theme, - paged: false, - } - } - - /// Enables or disables paging - pub fn paged(&mut self, val: bool) -> &mut MultiSelect<'a> { - self.paged = val; - self - } - - /// Sets the clear behavior of the menu. - /// - /// The default is to clear the menu. - pub fn clear(&mut self, val: bool) -> &mut MultiSelect<'a> { - self.clear = val; - self - } - - /// Sets a defaults for the menu. - pub fn defaults(&mut self, val: &[bool]) -> &mut MultiSelect<'a> { - self.defaults = val - .to_vec() - .iter() - .cloned() - .chain(repeat(false)) - .take(self.items.len()) - .collect(); - self - } - - /// Add a single item to the selector. - #[inline] - pub fn item(&mut self, item: T) -> &mut MultiSelect<'a> { - self.item_checked(item, false) - } - - /// Add a single item to the selector with a default checked state. - pub fn item_checked(&mut self, item: T, checked: bool) -> &mut MultiSelect<'a> { - self.items.push(item.to_string()); - self.defaults.push(checked); - self - } - - /// Adds multiple items to the selector. - pub fn items(&mut self, items: &[T]) -> &mut MultiSelect<'a> { - for item in items { - self.items.push(item.to_string()); - self.defaults.push(false); - } - self - } - - /// Adds multiple items to the selector with checked state - pub fn items_checked(&mut self, items: &[(T, bool)]) -> &mut MultiSelect<'a> { - for &(ref item, checked) in items { - self.items.push(item.to_string()); - self.defaults.push(checked); - } - self - } - - /// Prefaces the menu with a prompt. - /// - /// When a prompt is set the system also prints out a confirmation after - /// the selection. - pub fn with_prompt>(&mut self, prompt: S) -> &mut MultiSelect<'a> { - self.prompt = Some(prompt.into()); - self - } - - /// Enables user interaction and returns the result. - /// - /// The user can select the items with the space bar and on enter - /// the selected items will be returned. - pub fn interact(&self) -> io::Result> { - self.interact_on(&Term::stderr()) - } - - /// Like [interact](#method.interact) but allows a specific terminal to be set. - pub fn interact_on(&self, term: &Term) -> io::Result> { - let mut page = 0; - - if self.items.is_empty() { - return Err(io::Error::new( - io::ErrorKind::Other, - "Empty list of items given to `MultiSelect`", - )); - } - - let capacity = if self.paged { - term.size().0 as usize - 1 - } else { - self.items.len() - }; - - let pages = (self.items.len() as f64 / capacity as f64).ceil() as usize; - - let mut render = TermThemeRenderer::new(term, self.theme); - let mut sel = 0; - - if let Some(ref prompt) = self.prompt { - render.multi_select_prompt(prompt)?; - } - - let mut size_vec = Vec::new(); - - for items in self - .items - .iter() - .flat_map(|i| i.split('\n')) - .collect::>() - { - let size = &items.len(); - size_vec.push(*size); - } - - let mut checked: Vec = self.defaults.clone(); - - loop { - for (idx, item) in self - .items - .iter() - .enumerate() - .skip(page * capacity) - .take(capacity) - { - render.multi_select_prompt_item(item, checked[idx], sel == idx)?; - } - - term.hide_cursor()?; - term.flush()?; - - match term.read_key()? { - Key::ArrowDown | Key::Char('j') => { - if sel == !0 { - sel = 0; - } else { - sel = (sel as u64 + 1).rem(self.items.len() as u64) as usize; - } - } - Key::ArrowUp | Key::Char('k') => { - if sel == !0 { - sel = self.items.len() - 1; - } else { - sel = ((sel as i64 - 1 + self.items.len() as i64) % (self.items.len() as i64)) as usize; - } - } - Key::ArrowLeft | Key::Char('h') => { - if self.paged { - if page == 0 { - page = pages - 1; - } else { - page -= 1; - } - - sel = page * capacity; - } - } - Key::ArrowRight | Key::Char('l') => { - if self.paged { - if page == pages - 1 { - page = 0; - } else { - page += 1; - } - - sel = page * capacity; - } - } - Key::Char(' ') => { - checked[sel] = !checked[sel]; - } - Key::Escape => { - if self.clear { - render.clear()?; - } - - if let Some(ref prompt) = self.prompt { - render.multi_select_prompt_selection(prompt, &[][..])?; - } - - term.show_cursor()?; - term.flush()?; - - return Ok( - self - .defaults - .clone() - .into_iter() - .enumerate() - .filter_map(|(idx, checked)| if checked { Some(idx) } else { None }) - .collect(), - ); - } - Key::Enter => { - if self.clear { - render.clear()?; - } - - if let Some(ref prompt) = self.prompt { - let selections: Vec<_> = checked - .iter() - .enumerate() - .filter_map(|(idx, &checked)| { - if checked { - Some(self.items[idx].as_str()) - } else { - None - } - }) - .collect(); - - render.multi_select_prompt_selection(prompt, &selections[..])?; - } - - term.show_cursor()?; - term.flush()?; - - return Ok( - checked - .into_iter() - .enumerate() - .filter_map(|(idx, checked)| if checked { Some(idx) } else { None }) - .collect(), - ); - } - _ => {} - } - - if sel < page * capacity || sel >= (page + 1) * capacity { - page = sel / capacity; - } - - render.clear_preserve_prompt(&size_vec)?; - } - } -} diff --git a/tooling/cli.rs/src/dialoguer/prompts/password.rs b/tooling/cli.rs/src/dialoguer/prompts/password.rs deleted file mode 100644 index 2ba208152fe1..000000000000 --- a/tooling/cli.rs/src/dialoguer/prompts/password.rs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::io; - -use super::super::theme::{SimpleTheme, TermThemeRenderer, Theme}; - -use crate::console::Term; -use zeroize::Zeroizing; - -/// Renders a password input prompt. -/// -/// ## Example usage -/// -/// ```rust,no_run -/// # fn test() -> Result<(), Box> { -/// use dialoguer::Password; -/// -/// let password = Password::new().with_prompt("New Password") -/// .with_confirmation("Confirm password", "Passwords mismatching") -/// .interact()?; -/// println!("Length of the password is: {}", password.len()); -/// # Ok(()) } fn main() { test().unwrap(); } -/// ``` -pub struct Password<'a> { - prompt: String, - theme: &'a dyn Theme, - allow_empty_password: bool, - confirmation_prompt: Option<(String, String)>, -} - -impl<'a> Default for Password<'a> { - fn default() -> Password<'a> { - Password::new() - } -} - -impl<'a> Password<'a> { - /// Creates a password input prompt. - pub fn new() -> Password<'static> { - Password::with_theme(&SimpleTheme) - } - - /// Creates a password input prompt with a specific theme. - pub fn with_theme(theme: &'a dyn Theme) -> Password<'a> { - Password { - prompt: "".into(), - theme, - allow_empty_password: false, - confirmation_prompt: None, - } - } - - /// Sets the password input prompt. - pub fn with_prompt>(&mut self, prompt: S) -> &mut Password<'a> { - self.prompt = prompt.into(); - self - } - - /// Enables confirmation prompting. - pub fn with_confirmation(&mut self, prompt: A, mismatch_err: B) -> &mut Password<'a> - where - A: Into, - B: Into, - { - self.confirmation_prompt = Some((prompt.into(), mismatch_err.into())); - self - } - - /// Allows/Disables empty password. - /// - /// By default this setting is set to false (i.e. password is not empty). - pub fn allow_empty_password(&mut self, allow_empty_password: bool) -> &mut Password<'a> { - self.allow_empty_password = allow_empty_password; - self - } - - /// Enables user interaction and returns the result. - /// - /// If the user confirms the result is `true`, `false` otherwise. - /// The dialog is rendered on stderr. - pub fn interact(&self) -> io::Result { - self.interact_on(&Term::stderr()) - } - - /// Like `interact` but allows a specific terminal to be set. - pub fn interact_on(&self, term: &Term) -> io::Result { - let mut render = TermThemeRenderer::new(term, self.theme); - render.set_prompts_reset_height(false); - - loop { - let password = Zeroizing::new(self.prompt_password(&mut render, &self.prompt)?); - - if let Some((ref prompt, ref err)) = self.confirmation_prompt { - let pw2 = Zeroizing::new(self.prompt_password(&mut render, prompt)?); - - if *password == *pw2 { - render.clear()?; - render.password_prompt_selection(&self.prompt)?; - term.flush()?; - return Ok((*password).clone()); - } - - render.error(err)?; - } else { - render.clear()?; - render.password_prompt_selection(&self.prompt)?; - term.flush()?; - - return Ok((*password).clone()); - } - } - } - - fn prompt_password(&self, render: &mut TermThemeRenderer, prompt: &str) -> io::Result { - loop { - render.password_prompt(prompt)?; - render.term().flush()?; - - let input = render.term().read_secure_line()?; - - render.add_line(); - - if !input.is_empty() || self.allow_empty_password { - return Ok(input); - } - } - } -} diff --git a/tooling/cli.rs/src/dialoguer/prompts/select.rs b/tooling/cli.rs/src/dialoguer/prompts/select.rs deleted file mode 100644 index dd8702771008..000000000000 --- a/tooling/cli.rs/src/dialoguer/prompts/select.rs +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::{io, ops::Rem}; - -use super::super::theme::{SimpleTheme, TermThemeRenderer, Theme}; - -use crate::console::{Key, Term}; - -/// Renders a select prompt. -/// -/// User can select from one or more options. -/// Interaction returns index of an item selected in the order they appear in `item` invocation or `items` slice. -/// -/// ## Examples -/// -/// ```rust,no_run -/// use dialoguer::{ -/// Select, -/// theme::ColorfulTheme -/// }; -/// use console::Term; -/// -/// fn main() -> std::io::Result<()> { -/// let items = vec!["Item 1", "item 2"]; -/// let selection = Select::with_theme(&ColorfulTheme::default()) -/// .items(&items) -/// .default(0) -/// .interact_on_opt(&Term::stderr())?; -/// -/// match selection { -/// Some(index) => println!("User selected item : {}", items[index]), -/// None => println!("User did not select anything") -/// } -/// -/// Ok(()) -/// } -/// ``` -pub struct Select<'a> { - default: usize, - items: Vec, - prompt: Option, - clear: bool, - theme: &'a dyn Theme, - paged: bool, -} - -impl<'a> Default for Select<'a> { - fn default() -> Select<'a> { - Select::new() - } -} - -impl<'a> Select<'a> { - /// Creates a select prompt builder with default theme. - pub fn new() -> Select<'static> { - Select::with_theme(&SimpleTheme) - } - - /// Creates a select prompt builder with a specific theme. - /// - /// ## Examples - /// ```rust,no_run - /// use dialoguer::{ - /// Select, - /// theme::ColorfulTheme - /// }; - /// - /// fn main() -> std::io::Result<()> { - /// let selection = Select::with_theme(&ColorfulTheme::default()) - /// .item("Option A") - /// .item("Option B") - /// .interact()?; - /// - /// Ok(()) - /// } - /// ``` - pub fn with_theme(theme: &'a dyn Theme) -> Select<'a> { - Select { - default: !0, - items: vec![], - prompt: None, - clear: true, - theme, - paged: false, - } - } - - /// Enables or disables paging - /// - /// Paging is disabled by default - pub fn paged(&mut self, val: bool) -> &mut Select<'a> { - self.paged = val; - self - } - - /// Indicates whether select menu should be erased from the screen after interaction. - /// - /// The default is to clear the menu. - pub fn clear(&mut self, val: bool) -> &mut Select<'a> { - self.clear = val; - self - } - - /// Sets initial selected element when select menu is rendered - /// - /// Element is indicated by the index at which it appears in `item` method invocation or `items` slice. - pub fn default(&mut self, val: usize) -> &mut Select<'a> { - self.default = val; - self - } - - /// Add a single item to the selector. - /// - /// ## Examples - /// ```rust,no_run - /// use dialoguer::Select; - /// - /// fn main() -> std::io::Result<()> { - /// let selection: usize = Select::new() - /// .item("Item 1") - /// .item("Item 2") - /// .interact()?; - /// - /// Ok(()) - /// } - /// ``` - pub fn item(&mut self, item: T) -> &mut Select<'a> { - self.items.push(item.to_string()); - self - } - - /// Adds multiple items to the selector. - /// - /// ## Examples - /// ```rust,no_run - /// use dialoguer::Select; - /// - /// fn main() -> std::io::Result<()> { - /// let items = vec!["Item 1", "Item 2"]; - /// let selection: usize = Select::new() - /// .items(&items) - /// .interact()?; - /// - /// println!("{}", items[selection]); - /// - /// Ok(()) - /// } - /// ``` - pub fn items(&mut self, items: &[T]) -> &mut Select<'a> { - for item in items { - self.items.push(item.to_string()); - } - self - } - - /// Sets the select prompt. - /// - /// When a prompt is set the system also prints out a confirmation after - /// the selection. - /// - /// ## Examples - /// ```rust,no_run - /// use dialoguer::Select; - /// - /// fn main() -> std::io::Result<()> { - /// let selection = Select::new() - /// .with_prompt("Which option do you prefer?") - /// .item("Option A") - /// .item("Option B") - /// .interact()?; - /// - /// Ok(()) - /// } - /// ``` - pub fn with_prompt>(&mut self, prompt: S) -> &mut Select<'a> { - self.prompt = Some(prompt.into()); - self - } - - /// Enables user interaction and returns the result. - /// - /// Similar to [interact_on](#method.interact_on) except for the fact that it does not allow selection of the terminal. - /// The dialog is rendered on stderr. - /// Result contains index of a selected item. - pub fn interact(&self) -> io::Result { - self.interact_on(&Term::stderr()) - } - - /// Enables user interaction and returns the result. - /// - /// This method is similar to [interact_on_opt](#method.interact_on_opt) except for the fact that it does not allow selection of the terminal. - /// The dialog is rendered on stderr. - /// Result contains `Some(index)` if user selected one of items or `None` if user cancelled with 'Esc' or 'q'. - pub fn interact_opt(&self) -> io::Result> { - self.interact_on_opt(&Term::stderr()) - } - - /// Like [interact](#method.interact) but allows a specific terminal to be set. - /// - /// ## Examples - ///```rust,no_run - /// use dialoguer::Select; - /// use console::Term; - /// - /// fn main() -> std::io::Result<()> { - /// let selection = Select::new() - /// .item("Option A") - /// .item("Option B") - /// .interact_on(&Term::stderr())?; - /// - /// println!("User selected option at index {}", selection); - /// - /// Ok(()) - /// } - ///``` - pub fn interact_on(&self, term: &Term) -> io::Result { - self - ._interact_on(term, false)? - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Quit not allowed in this case")) - } - - /// Like [interact_opt](#method.interact_opt) but allows a specific terminal to be set. - /// - /// ## Examples - /// ```rust,no_run - /// use dialoguer::Select; - /// use console::Term; - /// - /// fn main() -> std::io::Result<()> { - /// let selection = Select::new() - /// .item("Option A") - /// .item("Option B") - /// .interact_on_opt(&Term::stdout())?; - /// - /// match selection { - /// Some(position) => println!("User selected option at index {}", position), - /// None => println!("User did not select anything") - /// } - /// - /// Ok(()) - /// } - /// ``` - #[inline] - pub fn interact_on_opt(&self, term: &Term) -> io::Result> { - self._interact_on(term, true) - } - - /// Like `interact` but allows a specific terminal to be set. - fn _interact_on(&self, term: &Term, allow_quit: bool) -> io::Result> { - let mut page = 0; - - if self.items.is_empty() { - return Err(io::Error::new( - io::ErrorKind::Other, - "Empty list of items given to `Select`", - )); - } - - let capacity = if self.paged { - term.size().0 as usize - 1 - } else { - self.items.len() - }; - - let pages = (self.items.len() as f64 / capacity as f64).ceil() as usize; - - let mut render = TermThemeRenderer::new(term, self.theme); - let mut sel = self.default; - - if let Some(ref prompt) = self.prompt { - render.select_prompt(prompt)?; - } - - let mut size_vec = Vec::new(); - - for items in self - .items - .iter() - .flat_map(|i| i.split('\n')) - .collect::>() - { - let size = &items.len(); - size_vec.push(*size); - } - - loop { - for (idx, item) in self - .items - .iter() - .enumerate() - .skip(page * capacity) - .take(capacity) - { - render.select_prompt_item(item, sel == idx)?; - } - - term.hide_cursor()?; - term.flush()?; - - match term.read_key()? { - Key::ArrowDown | Key::Char('j') => { - if sel == !0 { - sel = 0; - } else { - sel = (sel as u64 + 1).rem(self.items.len() as u64) as usize; - } - } - Key::Escape | Key::Char('q') => { - if allow_quit { - if self.clear { - term.clear_last_lines(self.items.len())?; - term.show_cursor()?; - term.flush()?; - } - - return Ok(None); - } - } - Key::ArrowUp | Key::Char('k') => { - if sel == !0 { - sel = self.items.len() - 1; - } else { - sel = ((sel as i64 - 1 + self.items.len() as i64) % (self.items.len() as i64)) as usize; - } - } - Key::ArrowLeft | Key::Char('h') => { - if self.paged { - if page == 0 { - page = pages - 1; - } else { - page -= 1; - } - - sel = page * capacity; - } - } - Key::ArrowRight | Key::Char('l') => { - if self.paged { - if page == pages - 1 { - page = 0; - } else { - page += 1; - } - - sel = page * capacity; - } - } - - Key::Enter | Key::Char(' ') if sel != !0 => { - if self.clear { - render.clear()?; - } - - if let Some(ref prompt) = self.prompt { - render.select_prompt_selection(prompt, &self.items[sel])?; - } - - term.show_cursor()?; - term.flush()?; - - return Ok(Some(sel)); - } - _ => {} - } - - if sel != !0 && (sel < page * capacity || sel >= (page + 1) * capacity) { - page = sel / capacity; - } - - render.clear_preserve_prompt(&size_vec)?; - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_str() { - let selections = &[ - "Ice Cream", - "Vanilla Cupcake", - "Chocolate Muffin", - "A Pile of sweet, sweet mustard", - ]; - - assert_eq!( - Select::new().default(0).items(&selections[..]).items, - selections - ); - } - - #[test] - fn test_string() { - let selections = vec!["a".to_string(), "b".to_string()]; - - assert_eq!( - Select::new().default(0).items(&selections[..]).items, - selections - ); - } - - #[test] - fn test_ref_str() { - let a = "a"; - let b = "b"; - - let selections = &[a, b]; - - assert_eq!( - Select::new().default(0).items(&selections[..]).items, - selections - ); - } -} diff --git a/tooling/cli.rs/src/dialoguer/prompts/sort.rs b/tooling/cli.rs/src/dialoguer/prompts/sort.rs deleted file mode 100644 index 45133e738640..000000000000 --- a/tooling/cli.rs/src/dialoguer/prompts/sort.rs +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::{io, ops::Rem}; - -use super::super::theme::{SimpleTheme, TermThemeRenderer, Theme}; - -use crate::console::{Key, Term}; - -/// Renders a sort prompt. -/// -/// Returns list of indices in original items list sorted according to user input. -/// -/// ## Example usage -/// ```rust,no_run -/// use dialoguer::Sort; -/// -/// # fn test() -> Result<(), Box> { -/// let items_to_order = vec!["Item 1", "Item 2", "Item 3"]; -/// let ordered = Sort::new() -/// .with_prompt("Order the items") -/// .items(&items_to_order) -/// .interact()?; -/// # Ok(()) -/// # } -/// ``` -pub struct Sort<'a> { - items: Vec, - prompt: Option, - clear: bool, - theme: &'a dyn Theme, - paged: bool, -} - -impl<'a> Default for Sort<'a> { - fn default() -> Sort<'a> { - Sort::new() - } -} - -impl<'a> Sort<'a> { - /// Creates a sort prompt. - pub fn new() -> Sort<'static> { - Sort::with_theme(&SimpleTheme) - } - - /// Creates a sort prompt with a specific theme. - pub fn with_theme(theme: &'a dyn Theme) -> Sort<'a> { - Sort { - items: vec![], - clear: true, - prompt: None, - theme, - paged: false, - } - } - - /// Enables or disables paging - pub fn paged(&mut self, val: bool) -> &mut Sort<'a> { - self.paged = val; - self - } - - /// Sets the clear behavior of the menu. - /// - /// The default is to clear the menu after user interaction. - pub fn clear(&mut self, val: bool) -> &mut Sort<'a> { - self.clear = val; - self - } - - /// Add a single item to the selector. - pub fn item(&mut self, item: T) -> &mut Sort<'a> { - self.items.push(item.to_string()); - self - } - - /// Adds multiple items to the selector. - pub fn items(&mut self, items: &[T]) -> &mut Sort<'a> { - for item in items { - self.items.push(item.to_string()); - } - self - } - - /// Prefaces the menu with a prompt. - /// - /// When a prompt is set the system also prints out a confirmation after - /// the selection. - pub fn with_prompt>(&mut self, prompt: S) -> &mut Sort<'a> { - self.prompt = Some(prompt.into()); - self - } - - /// Enables user interaction and returns the result. - /// - /// The user can order the items with the space bar and the arrows. - /// On enter the ordered list will be returned. - pub fn interact(&self) -> io::Result> { - self.interact_on(&Term::stderr()) - } - - /// Like [interact](#method.interact) but allows a specific terminal to be set. - pub fn interact_on(&self, term: &Term) -> io::Result> { - let mut page = 0; - - if self.items.is_empty() { - return Err(io::Error::new( - io::ErrorKind::Other, - "Empty list of items given to `Sort`", - )); - } - - let capacity = if self.paged { - term.size().0 as usize - 1 - } else { - self.items.len() - }; - - let pages = (self.items.len() as f64 / capacity as f64).ceil() as usize; - - let mut render = TermThemeRenderer::new(term, self.theme); - let mut sel = 0; - - if let Some(ref prompt) = self.prompt { - render.sort_prompt(prompt)?; - } - - let mut size_vec = Vec::new(); - - for items in self.items.iter().as_slice() { - let size = &items.len(); - size_vec.push(*size); - } - - let mut order: Vec<_> = (0..self.items.len()).collect(); - let mut checked: bool = false; - - loop { - for (idx, item) in order - .iter() - .enumerate() - .skip(page * capacity) - .take(capacity) - { - render.sort_prompt_item(&self.items[*item], checked, sel == idx)?; - } - - term.hide_cursor()?; - term.flush()?; - - match term.read_key()? { - Key::ArrowDown | Key::Char('j') => { - let old_sel = sel; - - if sel == !0 { - sel = 0; - } else { - sel = (sel as u64 + 1).rem(self.items.len() as u64) as usize; - } - - if checked && old_sel != sel { - order.swap(old_sel, sel); - } - } - Key::ArrowUp | Key::Char('k') => { - let old_sel = sel; - - if sel == !0 { - sel = self.items.len() - 1; - } else { - sel = ((sel as i64 - 1 + self.items.len() as i64) % (self.items.len() as i64)) as usize; - } - - if checked && old_sel != sel { - order.swap(old_sel, sel); - } - } - Key::ArrowLeft | Key::Char('h') => { - if self.paged { - let old_sel = sel; - let old_page = page; - - if page == 0 { - page = pages - 1; - } else { - page -= 1; - } - - sel = page * capacity; - - if checked { - let indexes: Vec<_> = if old_page == 0 { - let indexes1: Vec<_> = (0..=old_sel).rev().collect(); - let indexes2: Vec<_> = (sel..self.items.len()).rev().collect(); - [indexes1, indexes2].concat() - } else { - (sel..=old_sel).rev().collect() - }; - - for index in 0..(indexes.len() - 1) { - order.swap(indexes[index], indexes[index + 1]); - } - } - } - } - Key::ArrowRight | Key::Char('l') => { - if self.paged { - let old_sel = sel; - let old_page = page; - - if page == pages - 1 { - page = 0; - } else { - page += 1; - } - - sel = page * capacity; - - if checked { - let indexes: Vec<_> = if old_page == pages - 1 { - let indexes1: Vec<_> = (old_sel..self.items.len()).collect(); - let indexes2: Vec<_> = vec![0]; - [indexes1, indexes2].concat() - } else { - (old_sel..=sel).collect() - }; - - for index in 0..(indexes.len() - 1) { - order.swap(indexes[index], indexes[index + 1]); - } - } - } - } - Key::Char(' ') => { - checked = !checked; - } - // TODO: Key::Escape - Key::Enter => { - if self.clear { - render.clear()?; - } - - if let Some(ref prompt) = self.prompt { - let list: Vec<_> = order - .iter() - .enumerate() - .map(|(_, item)| self.items[*item].as_str()) - .collect(); - render.sort_prompt_selection(prompt, &list[..])?; - } - - term.show_cursor()?; - term.flush()?; - - return Ok(order); - } - _ => {} - } - - if sel < page * capacity || sel >= (page + 1) * capacity { - page = sel / capacity; - } - - render.clear_preserve_prompt(&size_vec)?; - } - } -} diff --git a/tooling/cli.rs/src/dialoguer/theme.rs b/tooling/cli.rs/src/dialoguer/theme.rs deleted file mode 100644 index 70090a246cf3..000000000000 --- a/tooling/cli.rs/src/dialoguer/theme.rs +++ /dev/null @@ -1,722 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -//! Customizes the rendering of the elements. -use std::{fmt, io}; - -use crate::console::{style, Style, StyledObject, Term}; - -/// Implements a theme for dialoguer. -pub trait Theme { - /// Formats a prompt. - #[inline] - fn format_prompt(&self, f: &mut dyn fmt::Write, prompt: &str) -> fmt::Result { - write!(f, "{}:", prompt) - } - - /// Formats out an error. - #[inline] - fn format_error(&self, f: &mut dyn fmt::Write, err: &str) -> fmt::Result { - write!(f, "error: {}", err) - } - - /// Formats a confirm prompt. - fn format_confirm_prompt( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - default: Option, - ) -> fmt::Result { - if !prompt.is_empty() { - write!(f, "{} ", &prompt)?; - } - match default { - None => write!(f, "[y/n] ")?, - Some(true) => write!(f, "[Y/n] ")?, - Some(false) => write!(f, "[y/N] ")?, - } - Ok(()) - } - - /// Formats a confirm prompt after selection. - fn format_confirm_prompt_selection( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - selection: Option, - ) -> fmt::Result { - let selection = selection.map(|b| if b { "yes" } else { "no" }); - - match selection { - Some(selection) if prompt.is_empty() => { - write!(f, "{}", selection) - } - Some(selection) => { - write!(f, "{} {}", &prompt, selection) - } - None if prompt.is_empty() => Ok(()), - None => { - write!(f, "{}", &prompt) - } - } - } - - /// Formats an input prompt. - fn format_input_prompt( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - default: Option<&str>, - ) -> fmt::Result { - match default { - Some(default) if prompt.is_empty() => write!(f, "[{}]: ", default), - Some(default) => write!(f, "{} [{}]: ", prompt, default), - None => write!(f, "{}: ", prompt), - } - } - - /// Formats an input prompt after selection. - #[inline] - fn format_input_prompt_selection( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - sel: &str, - ) -> fmt::Result { - write!(f, "{}: {}", prompt, sel) - } - - /// Formats a password prompt. - #[inline] - fn format_password_prompt(&self, f: &mut dyn fmt::Write, prompt: &str) -> fmt::Result { - self.format_input_prompt(f, prompt, None) - } - - /// Formats a password prompt after selection. - #[inline] - fn format_password_prompt_selection(&self, f: &mut dyn fmt::Write, prompt: &str) -> fmt::Result { - self.format_input_prompt_selection(f, prompt, "[hidden]") - } - - /// Formats a select prompt. - #[inline] - fn format_select_prompt(&self, f: &mut dyn fmt::Write, prompt: &str) -> fmt::Result { - self.format_prompt(f, prompt) - } - - /// Formats a select prompt after selection. - #[inline] - fn format_select_prompt_selection( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - sel: &str, - ) -> fmt::Result { - self.format_input_prompt_selection(f, prompt, sel) - } - - /// Formats a multi select prompt. - #[inline] - fn format_multi_select_prompt(&self, f: &mut dyn fmt::Write, prompt: &str) -> fmt::Result { - self.format_prompt(f, prompt) - } - - /// Formats a sort prompt. - #[inline] - fn format_sort_prompt(&self, f: &mut dyn fmt::Write, prompt: &str) -> fmt::Result { - self.format_prompt(f, prompt) - } - - /// Formats a multi_select prompt after selection. - fn format_multi_select_prompt_selection( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - selections: &[&str], - ) -> fmt::Result { - write!(f, "{}: ", prompt)?; - for (idx, sel) in selections.iter().enumerate() { - write!(f, "{}{}", if idx == 0 { "" } else { ", " }, sel)?; - } - Ok(()) - } - - /// Formats a sort prompt after selection. - #[inline] - fn format_sort_prompt_selection( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - selections: &[&str], - ) -> fmt::Result { - self.format_multi_select_prompt_selection(f, prompt, selections) - } - - /// Formats a select prompt item. - fn format_select_prompt_item( - &self, - f: &mut dyn fmt::Write, - text: &str, - active: bool, - ) -> fmt::Result { - write!(f, "{} {}", if active { ">" } else { " " }, text) - } - - /// Formats a multi select prompt item. - fn format_multi_select_prompt_item( - &self, - f: &mut dyn fmt::Write, - text: &str, - checked: bool, - active: bool, - ) -> fmt::Result { - write!( - f, - "{} {}", - match (checked, active) { - (true, true) => "> [x]", - (true, false) => " [x]", - (false, true) => "> [ ]", - (false, false) => " [ ]", - }, - text - ) - } - - /// Formats a sort prompt item. - fn format_sort_prompt_item( - &self, - f: &mut dyn fmt::Write, - text: &str, - picked: bool, - active: bool, - ) -> fmt::Result { - write!( - f, - "{} {}", - match (picked, active) { - (true, true) => "> [x]", - (false, true) => "> [ ]", - (_, false) => " [ ]", - }, - text - ) - } -} - -/// The default theme. -pub struct SimpleTheme; - -impl Theme for SimpleTheme {} - -/// A colorful theme -pub struct ColorfulTheme { - /// The style for default values - pub defaults_style: Style, - /// The style for prompt - pub prompt_style: Style, - /// Prompt prefix value and style - pub prompt_prefix: StyledObject, - /// Prompt suffix value and style - pub prompt_suffix: StyledObject, - /// Prompt on success prefix value and style - pub success_prefix: StyledObject, - /// Prompt on success suffix value and style - pub success_suffix: StyledObject, - /// Error prefix value and style - pub error_prefix: StyledObject, - /// The style for error message - pub error_style: Style, - /// The style for hints - pub hint_style: Style, - /// The style for values on prompt success - pub values_style: Style, - /// The style for active items - pub active_item_style: Style, - /// The style for inactive items - pub inactive_item_style: Style, - /// Active item in select prefix value and style - pub active_item_prefix: StyledObject, - /// Inctive item in select prefix value and style - pub inactive_item_prefix: StyledObject, - /// Checked item in multi select prefix value and style - pub checked_item_prefix: StyledObject, - /// Unchecked item in multi select prefix value and style - pub unchecked_item_prefix: StyledObject, - /// Picked item in sort prefix value and style - pub picked_item_prefix: StyledObject, - /// Unpicked item in sort prefix value and style - pub unpicked_item_prefix: StyledObject, - /// Show the selections from certain prompts inline - pub inline_selections: bool, -} - -impl Default for ColorfulTheme { - fn default() -> ColorfulTheme { - ColorfulTheme { - defaults_style: Style::new().for_stderr().cyan(), - prompt_style: Style::new().for_stderr().bold(), - prompt_prefix: style("?".to_string()).for_stderr().yellow(), - prompt_suffix: style("›".to_string()).for_stderr().black().bright(), - success_prefix: style("✔".to_string()).for_stderr().green(), - success_suffix: style("·".to_string()).for_stderr().black().bright(), - error_prefix: style("✘".to_string()).for_stderr().red(), - error_style: Style::new().for_stderr().red(), - hint_style: Style::new().for_stderr().black().bright(), - values_style: Style::new().for_stderr().green(), - active_item_style: Style::new().for_stderr().cyan(), - inactive_item_style: Style::new().for_stderr(), - active_item_prefix: style("❯".to_string()).for_stderr().green(), - inactive_item_prefix: style(" ".to_string()).for_stderr(), - checked_item_prefix: style("✔".to_string()).for_stderr().green(), - unchecked_item_prefix: style("✔".to_string()).for_stderr().black(), - picked_item_prefix: style("❯".to_string()).for_stderr().green(), - unpicked_item_prefix: style(" ".to_string()).for_stderr(), - inline_selections: true, - } - } -} - -impl Theme for ColorfulTheme { - /// Formats a prompt. - fn format_prompt(&self, f: &mut dyn fmt::Write, prompt: &str) -> fmt::Result { - if !prompt.is_empty() { - write!( - f, - "{} {} ", - &self.prompt_prefix, - self.prompt_style.apply_to(prompt) - )?; - } - - write!(f, "{}", &self.prompt_suffix) - } - - /// Formats an error - fn format_error(&self, f: &mut dyn fmt::Write, err: &str) -> fmt::Result { - write!( - f, - "{} {}", - &self.error_prefix, - self.error_style.apply_to(err) - ) - } - - /// Formats an input prompt. - fn format_input_prompt( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - default: Option<&str>, - ) -> fmt::Result { - if !prompt.is_empty() { - write!( - f, - "{} {} ", - &self.prompt_prefix, - self.prompt_style.apply_to(prompt) - )?; - } - - match default { - Some(default) => write!( - f, - "{} {} ", - self.hint_style.apply_to(&format!("({})", default)), - &self.prompt_suffix - ), - None => write!(f, "{} ", &self.prompt_suffix), - } - } - - /// Formats a confirm prompt. - fn format_confirm_prompt( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - default: Option, - ) -> fmt::Result { - if !prompt.is_empty() { - write!( - f, - "{} {} ", - &self.prompt_prefix, - self.prompt_style.apply_to(prompt) - )?; - } - - match default { - None => write!( - f, - "{} {}", - self.hint_style.apply_to("(y/n)"), - &self.prompt_suffix - ), - Some(true) => write!( - f, - "{} {} {}", - self.hint_style.apply_to("(y/n)"), - &self.prompt_suffix, - self.defaults_style.apply_to("yes") - ), - Some(false) => write!( - f, - "{} {} {}", - self.hint_style.apply_to("(y/n)"), - &self.prompt_suffix, - self.defaults_style.apply_to("no") - ), - } - } - - /// Formats a confirm prompt after selection. - fn format_confirm_prompt_selection( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - selection: Option, - ) -> fmt::Result { - if !prompt.is_empty() { - write!( - f, - "{} {} ", - &self.success_prefix, - self.prompt_style.apply_to(prompt) - )?; - } - let selection = selection.map(|b| if b { "yes" } else { "no" }); - - match selection { - Some(selection) => { - write!( - f, - "{} {}", - &self.success_suffix, - self.values_style.apply_to(selection) - ) - } - None => { - write!(f, "{}", &self.success_suffix) - } - } - } - - /// Formats an input prompt after selection. - fn format_input_prompt_selection( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - sel: &str, - ) -> fmt::Result { - if !prompt.is_empty() { - write!( - f, - "{} {} ", - &self.success_prefix, - self.prompt_style.apply_to(prompt) - )?; - } - - write!( - f, - "{} {}", - &self.success_suffix, - self.values_style.apply_to(sel) - ) - } - - /// Formats a password prompt after selection. - fn format_password_prompt_selection(&self, f: &mut dyn fmt::Write, prompt: &str) -> fmt::Result { - self.format_input_prompt_selection(f, prompt, "********") - } - - /// Formats a multi select prompt after selection. - fn format_multi_select_prompt_selection( - &self, - f: &mut dyn fmt::Write, - prompt: &str, - selections: &[&str], - ) -> fmt::Result { - if !prompt.is_empty() { - write!( - f, - "{} {} ", - &self.success_prefix, - self.prompt_style.apply_to(prompt) - )?; - } - - write!(f, "{} ", &self.success_suffix)?; - - if self.inline_selections { - for (idx, sel) in selections.iter().enumerate() { - write!( - f, - "{}{}", - if idx == 0 { "" } else { ", " }, - self.values_style.apply_to(sel) - )?; - } - } - - Ok(()) - } - - /// Formats a select prompt item. - fn format_select_prompt_item( - &self, - f: &mut dyn fmt::Write, - text: &str, - active: bool, - ) -> fmt::Result { - let details = match active { - true => ( - &self.active_item_prefix, - self.active_item_style.apply_to(text), - ), - false => ( - &self.inactive_item_prefix, - self.inactive_item_style.apply_to(text), - ), - }; - - write!(f, "{} {}", details.0, details.1) - } - - /// Formats a multi select prompt item. - fn format_multi_select_prompt_item( - &self, - f: &mut dyn fmt::Write, - text: &str, - checked: bool, - active: bool, - ) -> fmt::Result { - let details = match (checked, active) { - (true, true) => ( - &self.checked_item_prefix, - self.active_item_style.apply_to(text), - ), - (true, false) => ( - &self.checked_item_prefix, - self.inactive_item_style.apply_to(text), - ), - (false, true) => ( - &self.unchecked_item_prefix, - self.active_item_style.apply_to(text), - ), - (false, false) => ( - &self.unchecked_item_prefix, - self.inactive_item_style.apply_to(text), - ), - }; - - write!(f, "{} {}", details.0, details.1) - } - - /// Formats a sort prompt item. - fn format_sort_prompt_item( - &self, - f: &mut dyn fmt::Write, - text: &str, - picked: bool, - active: bool, - ) -> fmt::Result { - let details = match (picked, active) { - (true, true) => ( - &self.picked_item_prefix, - self.active_item_style.apply_to(text), - ), - (false, true) => ( - &self.unpicked_item_prefix, - self.active_item_style.apply_to(text), - ), - (_, false) => ( - &self.unpicked_item_prefix, - self.inactive_item_style.apply_to(text), - ), - }; - - write!(f, "{} {}", details.0, details.1) - } -} - -/// Helper struct to conveniently render a theme ot a term. -pub(crate) struct TermThemeRenderer<'a> { - term: &'a Term, - theme: &'a dyn Theme, - height: usize, - prompt_height: usize, - prompts_reset_height: bool, -} - -impl<'a> TermThemeRenderer<'a> { - pub fn new(term: &'a Term, theme: &'a dyn Theme) -> TermThemeRenderer<'a> { - TermThemeRenderer { - term, - theme, - height: 0, - prompt_height: 0, - prompts_reset_height: true, - } - } - - pub fn set_prompts_reset_height(&mut self, val: bool) { - self.prompts_reset_height = val; - } - - pub fn term(&self) -> &Term { - self.term - } - - pub fn add_line(&mut self) { - self.height += 1; - } - - fn write_formatted_str fmt::Result>( - &mut self, - f: F, - ) -> io::Result<()> { - let mut buf = String::new(); - f(self, &mut buf).map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - self.height += buf.chars().filter(|&x| x == '\n').count(); - self.term.write_str(&buf) - } - - fn write_formatted_line fmt::Result>( - &mut self, - f: F, - ) -> io::Result<()> { - let mut buf = String::new(); - f(self, &mut buf).map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - self.height += buf.chars().filter(|&x| x == '\n').count() + 1; - self.term.write_line(&buf) - } - - fn write_formatted_prompt< - F: FnOnce(&mut TermThemeRenderer, &mut dyn fmt::Write) -> fmt::Result, - >( - &mut self, - f: F, - ) -> io::Result<()> { - self.write_formatted_line(f)?; - if self.prompts_reset_height { - self.prompt_height = self.height; - self.height = 0; - } - Ok(()) - } - - pub fn error(&mut self, err: &str) -> io::Result<()> { - self.write_formatted_line(|this, buf| this.theme.format_error(buf, err)) - } - - pub fn confirm_prompt(&mut self, prompt: &str, default: Option) -> io::Result<()> { - self.write_formatted_str(|this, buf| this.theme.format_confirm_prompt(buf, prompt, default)) - } - - pub fn confirm_prompt_selection(&mut self, prompt: &str, sel: Option) -> io::Result<()> { - self.write_formatted_prompt(|this, buf| { - this.theme.format_confirm_prompt_selection(buf, prompt, sel) - }) - } - - pub fn input_prompt(&mut self, prompt: &str, default: Option<&str>) -> io::Result<()> { - self.write_formatted_str(|this, buf| this.theme.format_input_prompt(buf, prompt, default)) - } - - pub fn input_prompt_selection(&mut self, prompt: &str, sel: &str) -> io::Result<()> { - self.write_formatted_prompt(|this, buf| { - this.theme.format_input_prompt_selection(buf, prompt, sel) - }) - } - - pub fn password_prompt(&mut self, prompt: &str) -> io::Result<()> { - self.write_formatted_str(|this, buf| { - write!(buf, "\r")?; - this.theme.format_password_prompt(buf, prompt) - }) - } - - pub fn password_prompt_selection(&mut self, prompt: &str) -> io::Result<()> { - self - .write_formatted_prompt(|this, buf| this.theme.format_password_prompt_selection(buf, prompt)) - } - - pub fn select_prompt(&mut self, prompt: &str) -> io::Result<()> { - self.write_formatted_prompt(|this, buf| this.theme.format_select_prompt(buf, prompt)) - } - - pub fn select_prompt_selection(&mut self, prompt: &str, sel: &str) -> io::Result<()> { - self.write_formatted_prompt(|this, buf| { - this.theme.format_select_prompt_selection(buf, prompt, sel) - }) - } - - pub fn select_prompt_item(&mut self, text: &str, active: bool) -> io::Result<()> { - self.write_formatted_line(|this, buf| this.theme.format_select_prompt_item(buf, text, active)) - } - - pub fn multi_select_prompt(&mut self, prompt: &str) -> io::Result<()> { - self.write_formatted_prompt(|this, buf| this.theme.format_multi_select_prompt(buf, prompt)) - } - - pub fn multi_select_prompt_selection(&mut self, prompt: &str, sel: &[&str]) -> io::Result<()> { - self.write_formatted_prompt(|this, buf| { - this - .theme - .format_multi_select_prompt_selection(buf, prompt, sel) - }) - } - - pub fn multi_select_prompt_item( - &mut self, - text: &str, - checked: bool, - active: bool, - ) -> io::Result<()> { - self.write_formatted_line(|this, buf| { - this - .theme - .format_multi_select_prompt_item(buf, text, checked, active) - }) - } - - pub fn sort_prompt(&mut self, prompt: &str) -> io::Result<()> { - self.write_formatted_prompt(|this, buf| this.theme.format_sort_prompt(buf, prompt)) - } - - pub fn sort_prompt_selection(&mut self, prompt: &str, sel: &[&str]) -> io::Result<()> { - self - .write_formatted_prompt(|this, buf| this.theme.format_sort_prompt_selection(buf, prompt, sel)) - } - - pub fn sort_prompt_item(&mut self, text: &str, picked: bool, active: bool) -> io::Result<()> { - self.write_formatted_line(|this, buf| { - this - .theme - .format_sort_prompt_item(buf, text, picked, active) - }) - } - - pub fn clear(&mut self) -> io::Result<()> { - self - .term - .clear_last_lines(self.height + self.prompt_height)?; - self.height = 0; - Ok(()) - } - - pub fn clear_preserve_prompt(&mut self, size_vec: &[usize]) -> io::Result<()> { - let mut new_height = self.height; - //Check each item size, increment on finding an overflow - for size in size_vec { - if *size > self.term.size().1 as usize { - new_height += 1; - } - } - self.term.clear_last_lines(new_height)?; - self.height = 0; - Ok(()) - } -} diff --git a/tooling/cli.rs/src/dialoguer/validate.rs b/tooling/cli.rs/src/dialoguer/validate.rs deleted file mode 100644 index 0e62b8daeed9..000000000000 --- a/tooling/cli.rs/src/dialoguer/validate.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -//! Provides validation for text inputs -use std::fmt::{Debug, Display}; - -/// Trait for input validators. -/// -/// A generic implementation for `Fn(&str) -> Result<(), E>` is provided -/// to facilitate development. -pub trait Validator { - type Err: Debug + Display; - - /// Invoked with the value to validate. - /// - /// If this produces `Ok(())` then the value is used and parsed, if - /// an error is returned validation fails with that error. - fn validate(&mut self, input: &T) -> Result<(), Self::Err>; -} - -impl Result<(), E>, E: Debug + Display> Validator for F { - type Err = E; - - fn validate(&mut self, input: &T) -> Result<(), Self::Err> { - self(input) - } -} diff --git a/tooling/cli.rs/src/helpers/app_paths.rs b/tooling/cli.rs/src/helpers/app_paths.rs deleted file mode 100644 index 070006bd6b09..000000000000 --- a/tooling/cli.rs/src/helpers/app_paths.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::{env::current_dir, path::PathBuf}; - -use once_cell::sync::Lazy; - -fn get_app_dir() -> PathBuf { - let mut dir = current_dir().expect("failed to read cwd"); - - let mut count = 0; - - // only go up three folders max - while count <= 2 { - let test_path = dir.join("src-tauri/tauri.conf.json"); - if test_path.exists() { - return dir; - } - count += 1; - match dir.parent() { - Some(parent) => { - dir = parent.to_path_buf(); - } - None => break, - } - } - - panic!("Couldn't recognize the current folder as a Tauri project.") -} - -pub fn app_dir() -> &'static PathBuf { - static APP_DIR: Lazy = Lazy::new(get_app_dir); - &APP_DIR -} - -pub fn tauri_dir() -> PathBuf { - app_dir().join("src-tauri") -} diff --git a/tooling/cli.rs/src/helpers/config.rs b/tooling/cli.rs/src/helpers/config.rs deleted file mode 100644 index bf659a2c6503..000000000000 --- a/tooling/cli.rs/src/helpers/config.rs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use anyhow::Context; -use json_patch::merge; -use once_cell::sync::Lazy; -use serde_json::Value as JsonValue; - -#[path = "../../config_definition.rs"] -mod config_definition; -pub use config_definition::*; - -impl From for tauri_bundler::WixSettings { - fn from(config: WixConfig) -> tauri_bundler::WixSettings { - tauri_bundler::WixSettings { - language: config.language, - template: config.template, - fragment_paths: config.fragment_paths, - component_group_refs: config.component_group_refs, - component_refs: config.component_refs, - feature_group_refs: config.feature_group_refs, - feature_refs: config.feature_refs, - merge_refs: config.merge_refs, - skip_webview_install: config.skip_webview_install, - license: config.license, - enable_elevated_update_task: config.enable_elevated_update_task, - banner_path: config.banner_path, - dialog_image_path: config.dialog_image_path, - } - } -} - -use std::{ - env::set_var, - fs::File, - io::BufReader, - process::exit, - sync::{Arc, Mutex}, -}; - -pub type ConfigHandle = Arc>>; - -fn config_handle() -> &'static ConfigHandle { - static CONFING_HANDLE: Lazy = Lazy::new(Default::default); - &CONFING_HANDLE -} - -/// Gets the static parsed config from `tauri.conf.json`. -fn get_internal(merge_config: Option<&str>, reload: bool) -> crate::Result { - if !reload && config_handle().lock().unwrap().is_some() { - return Ok(config_handle().clone()); - } - - let path = super::app_paths::tauri_dir().join("tauri.conf.json"); - let file = File::open(path)?; - let buf = BufReader::new(file); - let mut config: JsonValue = - serde_json::from_reader(buf).with_context(|| "failed to parse `tauri.conf.json`")?; - - let schema: JsonValue = serde_json::from_str(include_str!("../../schema.json"))?; - let mut scope = valico::json_schema::Scope::new(); - let schema = scope.compile_and_return(schema, false).unwrap(); - let state = schema.validate(&config); - if !state.errors.is_empty() { - for error in state.errors { - eprintln!( - "`tauri.conf.json` error on `{}`: {}", - error - .get_path() - .chars() - .skip(1) - .collect::() - .replace("/", " > "), - error.get_detail().unwrap_or_else(|| error.get_title()), - ); - } - exit(1); - } - - if let Some(merge_config) = merge_config { - let merge_config: JsonValue = - serde_json::from_str(merge_config).with_context(|| "failed to parse config to merge")?; - merge(&mut config, &merge_config); - } - - let platform_config_filename = if cfg!(target_os = "macos") { - "tauri.macos.conf.json" - } else if cfg!(windows) { - "tauri.windows.conf.json" - } else { - "tauri.linux.conf.json" - }; - let platform_config_path = super::app_paths::tauri_dir().join(platform_config_filename); - if platform_config_path.exists() { - let platform_config_file = File::open(platform_config_path)?; - let platform_config: JsonValue = serde_json::from_reader(BufReader::new(platform_config_file)) - .with_context(|| format!("failed to parse `{}`", platform_config_filename))?; - merge(&mut config, &platform_config); - } - - let config: Config = serde_json::from_value(config)?; - set_var("TAURI_CONFIG", serde_json::to_string(&config)?); - *config_handle().lock().unwrap() = Some(config); - - Ok(config_handle().clone()) -} - -pub fn get(merge_config: Option<&str>) -> crate::Result { - get_internal(merge_config, false) -} - -pub fn reload(merge_config: Option<&str>) -> crate::Result<()> { - get_internal(merge_config, true)?; - Ok(()) -} - -pub fn all_allowlist_features() -> Vec<&'static str> { - AllowlistConfig { - all: true, - fs: FsAllowlistConfig { - all: true, - read_text_file: true, - read_binary_file: true, - write_file: true, - write_binary_file: true, - read_dir: true, - copy_file: true, - create_dir: true, - remove_dir: true, - remove_file: true, - rename_file: true, - }, - window: WindowAllowlistConfig { - all: true, - create: true, - }, - shell: ShellAllowlistConfig { - all: true, - execute: true, - open: true, - }, - dialog: DialogAllowlistConfig { - all: true, - open: true, - save: true, - }, - http: HttpAllowlistConfig { - all: true, - request: true, - }, - notification: NotificationAllowlistConfig { all: true }, - global_shortcut: GlobalShortcutAllowlistConfig { all: true }, - os: OsAllowlistConfig { all: true }, - path: PathAllowlistConfig { all: true }, - } - .to_features() -} diff --git a/tooling/cli.rs/src/helpers/manifest.rs b/tooling/cli.rs/src/helpers/manifest.rs deleted file mode 100644 index a568b1778af1..000000000000 --- a/tooling/cli.rs/src/helpers/manifest.rs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use super::{ - app_paths::tauri_dir, - config::{all_allowlist_features, ConfigHandle}, -}; - -use anyhow::Context; -use toml_edit::{Array, Document, InlineTable, Item, Value}; - -use std::{ - collections::HashSet, - fs::File, - io::{Read, Write}, - path::Path, -}; - -#[derive(Default)] -pub struct Manifest { - pub features: HashSet, -} - -fn read_manifest(manifest_path: &Path) -> crate::Result { - let mut manifest_str = String::new(); - - let mut manifest_file = File::open(manifest_path) - .with_context(|| format!("failed to open `{:?}` file", manifest_path))?; - manifest_file.read_to_string(&mut manifest_str)?; - - let manifest: Document = manifest_str - .parse::() - .with_context(|| "failed to parse Cargo.toml")?; - - Ok(manifest) -} - -fn toml_array(features: &HashSet) -> Array { - let mut f = Array::default(); - let mut features: Vec = features.iter().map(|f| f.to_string()).collect(); - features.sort(); - for feature in features { - f.push(feature.as_str()).unwrap(); - } - f -} - -pub fn rewrite_manifest(config: ConfigHandle) -> crate::Result { - let manifest_path = tauri_dir().join("Cargo.toml"); - let mut manifest = read_manifest(&manifest_path)?; - let dependencies = manifest - .as_table_mut() - .entry("dependencies") - .as_table_mut() - .expect("manifest dependencies isn't a table"); - - let tauri_entry = dependencies.entry("tauri"); - - let config_guard = config.lock().unwrap(); - let config = config_guard.as_ref().unwrap(); - - let allowlist_features = config.tauri.features(); - let mut features = HashSet::new(); - for feature in allowlist_features { - features.insert(feature.to_string()); - } - if config.tauri.cli.is_some() { - features.insert("cli".to_string()); - } - if config.tauri.updater.active { - features.insert("updater".to_string()); - } - if config.tauri.system_tray.is_some() { - features.insert("system-tray".to_string()); - } - - let mut cli_managed_features = all_allowlist_features(); - cli_managed_features.extend(vec!["cli", "updater", "system-tray"]); - - if let Some(tauri) = tauri_entry.as_table_mut() { - let manifest_features = tauri.entry("features"); - if let Item::Value(Value::Array(f)) = &manifest_features { - for feat in f.iter() { - if let Value::String(feature) = feat { - if !cli_managed_features.contains(&feature.value().as_str()) { - features.insert(feature.value().to_string()); - } - } - } - } - *manifest_features = Item::Value(Value::Array(toml_array(&features))); - } else if let Some(tauri) = tauri_entry.as_value_mut() { - match tauri { - Value::InlineTable(table) => { - let manifest_features = table.get_or_insert("features", Value::Array(Default::default())); - if let Value::Array(f) = &manifest_features { - for feat in f.iter() { - if let Value::String(feature) = feat { - if !cli_managed_features.contains(&feature.value().as_str()) { - features.insert(feature.value().to_string()); - } - } - } - } - *manifest_features = Value::Array(toml_array(&features)); - } - Value::String(version) => { - let mut def = InlineTable::default(); - def.get_or_insert( - "version", - version.to_string().replace("\"", "").replace(" ", ""), - ); - def.get_or_insert("features", Value::Array(toml_array(&features))); - *tauri = Value::InlineTable(def); - } - _ => { - return Err(anyhow::anyhow!( - "Unsupported tauri dependency format on Cargo.toml" - )) - } - } - } else { - return Ok(Manifest { features }); - } - - let mut manifest_file = - File::create(&manifest_path).with_context(|| "failed to open Cargo.toml for rewrite")?; - manifest_file.write_all( - manifest - .to_string_in_original_order() - // apply some formatting fixes - .replace(r#"" ,features =["#, r#"", features = ["#) - .replace("]}", "] }") - .replace("={", "= {") - .replace("=[", "= [") - .as_bytes(), - )?; - manifest_file.flush()?; - - Ok(Manifest { features }) -} - -pub fn get_workspace_members() -> crate::Result> { - let mut manifest = read_manifest(&tauri_dir().join("Cargo.toml"))?; - let workspace = manifest.as_table_mut().entry("workspace").as_table_mut(); - - match workspace { - Some(workspace) => { - let members = workspace - .entry("members") - .as_array() - .expect("workspace members aren't an array"); - Ok( - members - .iter() - .map(|v| v.as_str().unwrap().to_string()) - .collect(), - ) - } - None => Ok(vec![]), - } -} diff --git a/tooling/cli.rs/src/helpers/mod.rs b/tooling/cli.rs/src/helpers/mod.rs deleted file mode 100644 index 20f1d11d2115..000000000000 --- a/tooling/cli.rs/src/helpers/mod.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -pub mod app_paths; -pub mod config; -pub mod framework; -mod logger; -pub mod manifest; -pub mod updater_signature; - -pub use logger::Logger; - -use std::{ - io::{BufRead, BufReader}, - process::{Command, Stdio}, -}; - -pub fn execute_with_output(cmd: &mut Command) -> crate::Result<()> { - let mut child = cmd - .stdout(Stdio::piped()) - .spawn() - .expect("failed to spawn command"); - { - let stdout = child.stdout.as_mut().expect("Failed to get stdout handle"); - let reader = BufReader::new(stdout); - - for line in reader.lines() { - println!("{}", line.expect("Failed to get line")); - } - } - - let status = child.wait()?; - if status.success() { - Ok(()) - } else { - Err(anyhow::anyhow!("command failed")) - } -} diff --git a/tooling/cli.rs/src/info.rs b/tooling/cli.rs/src/info.rs deleted file mode 100644 index 79afd61b346c..000000000000 --- a/tooling/cli.rs/src/info.rs +++ /dev/null @@ -1,578 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use crate::helpers::{ - app_paths::{app_dir, tauri_dir}, - config::get as get_config, - framework::infer_from_package_json as infer_framework, -}; -use serde::Deserialize; - -use std::{ - collections::HashMap, - fs::{read_dir, read_to_string}, - panic, - path::{Path, PathBuf}, - process::Command, -}; - -#[derive(Deserialize)] -struct YarnVersionInfo { - data: Vec, -} - -#[derive(Clone, Deserialize)] -struct CargoLockPackage { - name: String, - version: String, -} - -#[derive(Deserialize)] -struct CargoLock { - package: Vec, -} - -#[derive(Deserialize)] -struct JsCliVersionMetadata { - version: String, - node: String, -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct VersionMetadata { - #[serde(rename = "cli.js")] - js_cli: JsCliVersionMetadata, -} - -#[derive(Clone, Deserialize)] -struct CargoManifestDependencyPackage { - version: Option, - path: Option, - #[serde(default)] - features: Vec, -} - -#[derive(Clone, Deserialize)] -#[serde(untagged)] -enum CargoManifestDependency { - Version(String), - Package(CargoManifestDependencyPackage), -} - -#[derive(Deserialize)] -struct CargoManifestPackage { - version: String, -} - -#[derive(Deserialize)] -struct CargoManifest { - package: CargoManifestPackage, - dependencies: HashMap, -} - -#[derive(Default)] -pub struct Info; - -fn crate_latest_version(name: &str) -> Option { - let url = format!("https://docs.rs/crate/{}/", name); - match ureq::get(&url).call() { - Ok(response) => match (response.status(), response.header("location")) { - (302, Some(location)) => Some(location.replace(&url, "")), - _ => None, - }, - Err(_) => None, - } -} - -fn npm_latest_version(use_yarn: bool, name: &str) -> crate::Result> { - let mut cmd; - if use_yarn { - #[cfg(target_os = "windows")] - { - cmd = Command::new("cmd"); - cmd.arg("/c").arg("yarn"); - } - - #[cfg(not(target_os = "windows"))] - { - cmd = Command::new("yarn") - } - - let output = cmd - .arg("info") - .arg(name) - .args(&["version", "--json"]) - .output()?; - if output.status.success() { - let stdout = String::from_utf8_lossy(&output.stdout); - let info: YarnVersionInfo = serde_json::from_str(&stdout)?; - Ok(Some(info.data.last().unwrap().to_string())) - } else { - Ok(None) - } - } else { - #[cfg(target_os = "windows")] - { - cmd = Command::new("cmd"); - cmd.arg("/c").arg("npm"); - } - - #[cfg(not(target_os = "windows"))] - { - cmd = Command::new("npm") - } - - let output = cmd.arg("show").arg(name).arg("version").output()?; - if output.status.success() { - let stdout = String::from_utf8_lossy(&output.stdout); - Ok(Some(stdout.replace("\n", ""))) - } else { - Ok(None) - } - } -} - -fn npm_package_version>( - use_yarn: bool, - name: &str, - app_dir: P, -) -> crate::Result> { - let mut cmd; - let output = if use_yarn { - #[cfg(target_os = "windows")] - { - cmd = Command::new("cmd"); - cmd.arg("/c").arg("yarn"); - } - - #[cfg(not(target_os = "windows"))] - { - cmd = Command::new("yarn") - } - - cmd - .args(&["list", "--pattern"]) - .arg(name) - .args(&["--depth", "0"]) - .current_dir(app_dir) - .output()? - } else { - #[cfg(target_os = "windows")] - { - cmd = Command::new("cmd"); - cmd.arg("/c").arg("npm"); - } - - #[cfg(not(target_os = "windows"))] - { - cmd = Command::new("npm") - } - - cmd - .arg("list") - .arg(name) - .args(&["version", "--depth", "0"]) - .current_dir(app_dir) - .output()? - }; - if output.status.success() { - let stdout = String::from_utf8_lossy(&output.stdout); - let regex = regex::Regex::new("@([\\da-zA-Z\\-\\.]+)").unwrap(); - Ok( - regex - .captures_iter(&stdout) - .last() - .and_then(|cap| cap.get(1).map(|v| v.as_str().to_string())), - ) - } else { - Ok(None) - } -} - -fn get_version(command: &str, args: &[&str]) -> crate::Result> { - let mut cmd; - #[cfg(target_os = "windows")] - { - cmd = Command::new("cmd"); - cmd.arg("/c").arg(command); - } - - #[cfg(not(target_os = "windows"))] - { - cmd = Command::new(command) - } - - let output = cmd.args(args).arg("--version").output()?; - let version = if output.status.success() { - Some( - String::from_utf8_lossy(&output.stdout) - .replace("\n", "") - .replace("\r", ""), - ) - } else { - None - }; - Ok(version) -} - -#[cfg(windows)] -fn webview2_version() -> crate::Result> { - let output = Command::new("powershell") - .args(&["-NoProfile", "-Command"]) - .arg("Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' | ForEach-Object {$_.pv}") - .output()?; - let version = if output.status.success() { - Some(String::from_utf8_lossy(&output.stdout).replace("\n", "")) - } else { - // check 32bit installation - let output = Command::new("powershell") - .args(&["-NoProfile", "-Command"]) - .arg("Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' | ForEach-Object {$_.pv}") - .output()?; - if output.status.success() { - Some(String::from_utf8_lossy(&output.stdout).replace("\n", "")) - } else { - None - } - }; - Ok(version) -} - -struct InfoBlock { - section: bool, - key: &'static str, - value: Option, - suffix: Option, -} - -impl InfoBlock { - fn new(key: &'static str) -> Self { - Self { - section: false, - key, - value: None, - suffix: None, - } - } - - fn section(mut self) -> Self { - self.section = true; - self - } - - fn value>>(mut self, value: V) -> Self { - self.value = value.into(); - self - } - - fn suffix>>(mut self, suffix: S) -> Self { - self.suffix = suffix.into(); - self - } - - fn display(&self) { - if self.section { - println!(); - } - print!("{}", self.key); - if let Some(value) = &self.value { - print!(" - {}", value); - } - if let Some(suffix) = &self.suffix { - print!("{}", suffix); - } - println!(); - } -} - -struct VersionBlock { - section: bool, - key: &'static str, - version: Option, - target_version: Option, -} - -impl VersionBlock { - fn new>>(key: &'static str, version: V) -> Self { - Self { - section: false, - key, - version: version.into(), - target_version: None, - } - } - - fn target_version>>(mut self, version: V) -> Self { - self.target_version = version.into(); - self - } - - fn display(&self) { - if self.section { - println!(); - } - print!("{}", self.key); - if let Some(version) = &self.version { - print!(" - {}", version); - } else { - print!(" - Not installed"); - } - if let (Some(version), Some(target_version)) = (&self.version, &self.target_version) { - let version = semver::Version::parse(version).unwrap(); - let target_version = semver::Version::parse(target_version).unwrap(); - if version < target_version { - print!(" (outdated, latest: {})", target_version); - } - } - println!(); - } -} - -impl Info { - pub fn new() -> Self { - Default::default() - } - - pub fn run(self) -> crate::Result<()> { - let os_info = os_info::get(); - InfoBlock { - section: true, - key: "Operating System", - value: Some(format!( - "{}, version {} {:?}", - os_info.os_type(), - os_info.version(), - os_info.bitness() - )), - suffix: None, - } - .display(); - - #[cfg(windows)] - VersionBlock::new("Webview2", webview2_version().unwrap_or_default()).display(); - - let hook = panic::take_hook(); - panic::set_hook(Box::new(|_info| { - // do nothing - })); - let app_dir = panic::catch_unwind(app_dir).map(Some).unwrap_or_default(); - panic::set_hook(hook); - - let use_yarn = app_dir - .map(|dir| dir.join("yarn.lock").exists()) - .unwrap_or_default(); - - if let Some(node_version) = get_version("node", &[]).unwrap_or_default() { - InfoBlock::new("Node.js environment").section().display(); - let metadata = serde_json::from_str::(include_str!("../metadata.json"))?; - VersionBlock::new( - " Node.js", - node_version.chars().skip(1).collect::(), - ) - .target_version(metadata.js_cli.node.replace(">= ", "")) - .display(); - - VersionBlock::new(" @tauri-apps/cli", metadata.js_cli.version) - .target_version(npm_latest_version(use_yarn, "@tauri-apps/cli").unwrap_or_default()) - .display(); - if let Some(app_dir) = &app_dir { - VersionBlock::new( - " @tauri-apps/api", - npm_package_version(use_yarn, "@tauri-apps/api", app_dir).unwrap_or_default(), - ) - .target_version(npm_latest_version(use_yarn, "@tauri-apps/api").unwrap_or_default()) - .display(); - } - - InfoBlock::new("Global packages").section().display(); - - VersionBlock::new(" npm", get_version("npm", &[]).unwrap_or_default()).display(); - VersionBlock::new(" yarn", get_version("yarn", &[]).unwrap_or_default()).display(); - } - - InfoBlock::new("Rust environment").section().display(); - VersionBlock::new( - " rustc", - get_version("rustc", &[]).unwrap_or_default().map(|v| { - let mut s = v.split(' '); - s.next(); - s.next().unwrap().to_string() - }), - ) - .display(); - VersionBlock::new( - " cargo", - get_version("cargo", &[]).unwrap_or_default().map(|v| { - let mut s = v.split(' '); - s.next(); - s.next().unwrap().to_string() - }), - ) - .display(); - - if let Some(app_dir) = app_dir { - InfoBlock::new("App directory structure") - .section() - .display(); - for entry in read_dir(app_dir)? { - let entry = entry?; - if entry.path().is_dir() { - println!("/{}", entry.path().file_name().unwrap().to_string_lossy()); - } - } - - InfoBlock::new("App").section().display(); - let tauri_dir = tauri_dir(); - let manifest: Option = - if let Ok(manifest_contents) = read_to_string(tauri_dir.join("Cargo.toml")) { - toml::from_str(&manifest_contents).ok() - } else { - None - }; - let lock: Option = - if let Ok(lock_contents) = read_to_string(tauri_dir.join("Cargo.lock")) { - toml::from_str(&lock_contents).ok() - } else { - None - }; - let tauri_lock_packages: Vec = lock - .as_ref() - .map(|lock| { - lock - .package - .iter() - .filter(|p| p.name == "tauri") - .cloned() - .collect() - }) - .unwrap_or_default(); - let (tauri_version_string, found_tauri_versions) = - match (&manifest, &lock, tauri_lock_packages.len()) { - (Some(_manifest), Some(_lock), 1) => { - let tauri_lock_package = tauri_lock_packages.first().unwrap(); - ( - tauri_lock_package.version.clone(), - vec![tauri_lock_package.version.clone()], - ) - } - (None, Some(_lock), 1) => { - let tauri_lock_package = tauri_lock_packages.first().unwrap(); - ( - format!("{} (no manifest)", tauri_lock_package.version), - vec![tauri_lock_package.version.clone()], - ) - } - _ => { - let mut found_tauri_versions = Vec::new(); - let manifest_version = match manifest.and_then(|m| m.dependencies.get("tauri").cloned()) - { - Some(tauri) => match tauri { - CargoManifestDependency::Version(v) => { - found_tauri_versions.push(v.clone()); - v - } - CargoManifestDependency::Package(p) => { - if let Some(v) = p.version { - found_tauri_versions.push(v.clone()); - v - } else if let Some(p) = p.path { - let manifest_path = tauri_dir.join(&p).join("Cargo.toml"); - let v = match read_to_string(&manifest_path) - .map_err(|_| ()) - .and_then(|m| toml::from_str::(&m).map_err(|_| ())) - { - Ok(manifest) => manifest.package.version, - Err(_) => "unknown version".to_string(), - }; - format!("path:{:?} [{}]", p, v) - } else { - "unknown manifest".to_string() - } - } - }, - None => "no manifest".to_string(), - }; - - let lock_version = match (lock, tauri_lock_packages.is_empty()) { - (Some(_lock), true) => tauri_lock_packages - .iter() - .map(|p| p.version.clone()) - .collect::>() - .join(", "), - (Some(_lock), false) => "unknown lockfile".to_string(), - _ => "no lockfile".to_string(), - }; - - ( - format!("{} ({})", manifest_version, lock_version), - found_tauri_versions, - ) - } - }; - - let tauri_version = found_tauri_versions - .into_iter() - .map(|v| semver::Version::parse(&v).unwrap()) - .max(); - let suffix = match (tauri_version, crate_latest_version("tauri")) { - (Some(version), Some(target_version)) => { - let target_version = semver::Version::parse(&target_version).unwrap(); - if version < target_version { - Some(format!(" (outdated, latest: {})", target_version)) - } else { - None - } - } - _ => None, - }; - InfoBlock::new(" tauri.rs") - .value(tauri_version_string) - .suffix(suffix) - .display(); - - if let Ok(config) = get_config(None) { - let config_guard = config.lock().unwrap(); - let config = config_guard.as_ref().unwrap(); - InfoBlock::new(" build-type") - .value(if config.tauri.bundle.active { - "bundle".to_string() - } else { - "build".to_string() - }) - .display(); - InfoBlock::new(" CSP") - .value(if let Some(security) = &config.tauri.security { - security.csp.clone().unwrap_or_else(|| "unset".to_string()) - } else { - "unset".to_string() - }) - .display(); - InfoBlock::new(" distDir") - .value(config.build.dist_dir.to_string()) - .display(); - InfoBlock::new(" devPath") - .value(config.build.dev_path.to_string()) - .display(); - } - if let Ok(package_json) = read_to_string(app_dir.join("package.json")) { - let (framework, bundler) = infer_framework(&package_json); - if let Some(framework) = framework { - InfoBlock::new(" framework") - .value(framework.to_string()) - .display(); - } - if let Some(bundler) = bundler { - InfoBlock::new(" bundler") - .value(bundler.to_string()) - .display(); - } - } else { - println!("package.json not found"); - } - } - - Ok(()) - } -} diff --git a/tooling/cli.rs/src/init.rs b/tooling/cli.rs/src/init.rs deleted file mode 100644 index ca775aed0228..000000000000 --- a/tooling/cli.rs/src/init.rs +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use std::{ - collections::BTreeMap, - env::current_dir, - fs::{create_dir_all, remove_dir_all, File}, - io::Write, - path::{Path, PathBuf}, -}; - -use crate::helpers::Logger; -use anyhow::Context; -use handlebars::{to_json, Handlebars}; -use include_dir::{include_dir, Dir}; -use serde::Deserialize; - -const TEMPLATE_DIR: Dir = include_dir!("templates"); - -#[derive(Deserialize)] -struct VersionMetadata { - tauri: String, - #[serde(rename = "tauri-build")] - tauri_build: String, -} - -pub struct Init { - force: bool, - directory: PathBuf, - tauri_path: Option, - app_name: Option, - window_title: Option, - dist_dir: Option, - dev_path: Option, -} - -impl Default for Init { - fn default() -> Self { - Self { - force: false, - directory: current_dir().expect("failed to read cwd"), - tauri_path: None, - app_name: None, - window_title: None, - dist_dir: None, - dev_path: None, - } - } -} - -impl Init { - pub fn new() -> Self { - Default::default() - } - - pub fn force(mut self) -> Self { - self.force = true; - self - } - - pub fn directory(mut self, directory: impl Into) -> Self { - self.directory = directory.into(); - self - } - - pub fn tauri_path(mut self, tauri_path: impl Into) -> Self { - self.tauri_path = Some(tauri_path.into()); - self - } - - pub fn app_name(mut self, app_name: impl Into) -> Self { - self.app_name = Some(app_name.into()); - self - } - - pub fn window_title(mut self, window_title: impl Into) -> Self { - self.window_title = Some(window_title.into()); - self - } - - pub fn dist_dir(mut self, dist_dir: impl Into) -> Self { - self.dist_dir = Some(dist_dir.into()); - self - } - - pub fn dev_path(mut self, dev_path: impl Into) -> Self { - self.dev_path = Some(dev_path.into()); - self - } - - pub fn run(self) -> crate::Result<()> { - let logger = Logger::new("tauri:init"); - let template_target_path = self.directory.join("src-tauri"); - let metadata = serde_json::from_str::(include_str!("../metadata.json"))?; - if template_target_path.exists() && !self.force { - logger.warn(format!( - "Tauri dir ({:?}) not empty. Run `init --force template` to overwrite.", - template_target_path - )); - } else { - let (tauri_dep, tauri_build_dep) = if let Some(tauri_path) = self.tauri_path { - ( - format!( - "{{ path = {:?} }}", - resolve_tauri_path(&tauri_path, "core/tauri") - ), - format!( - "{{ path = {:?} }}", - resolve_tauri_path(&tauri_path, "core/tauri-build") - ), - ) - } else { - ( - format!(r#"{{ version = "{}" }}"#, metadata.tauri), - format!(r#"{{ version = "{}" }}"#, metadata.tauri_build), - ) - }; - - let _ = remove_dir_all(&template_target_path); - let handlebars = Handlebars::new(); - - let mut data = BTreeMap::new(); - data.insert("tauri_dep", to_json(tauri_dep)); - data.insert("tauri_build_dep", to_json(tauri_build_dep)); - data.insert( - "dist_dir", - to_json(self.dist_dir.unwrap_or_else(|| "../dist".to_string())), - ); - data.insert( - "dev_path", - to_json( - self - .dev_path - .unwrap_or_else(|| "http://localhost:4000".to_string()), - ), - ); - data.insert( - "app_name", - to_json(self.app_name.unwrap_or_else(|| "Tauri App".to_string())), - ); - data.insert( - "window_title", - to_json(self.window_title.unwrap_or_else(|| "Tauri".to_string())), - ); - - render_template(&handlebars, &data, &TEMPLATE_DIR, &self.directory) - .with_context(|| "failed to render Tauri template")?; - } - - Ok(()) - } -} - -fn render_template>( - handlebars: &Handlebars, - data: &BTreeMap<&str, serde_json::Value>, - dir: &Dir, - out_dir: P, -) -> crate::Result<()> { - create_dir_all(out_dir.as_ref().join(dir.path()))?; - for file in dir.files() { - let mut file_path = file.path().to_path_buf(); - // cargo for some reason ignores the /templates folder packaging when it has a Cargo.toml file inside - // so we rename the extension to `.crate-manifest` - if let Some(extension) = file_path.extension() { - if extension == "crate-manifest" { - file_path.set_extension("toml"); - } - } - let mut output_file = File::create(out_dir.as_ref().join(file_path))?; - if let Some(utf8) = file.contents_utf8() { - handlebars - .render_template_to_write(utf8, &data, &mut output_file) - .expect("Failed to render template"); - } else { - output_file.write_all(file.contents())?; - } - } - for dir in dir.dirs() { - render_template(handlebars, data, dir, out_dir.as_ref())?; - } - Ok(()) -} - -fn resolve_tauri_path>(path: P, crate_name: &str) -> PathBuf { - let path = path.as_ref(); - if path.is_absolute() { - path.join(crate_name) - } else { - PathBuf::from("..").join(path).join(crate_name) - } -} diff --git a/tooling/cli.rs/src/main.rs b/tooling/cli.rs/src/main.rs deleted file mode 100644 index d65fb5686ac1..000000000000 --- a/tooling/cli.rs/src/main.rs +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -pub use anyhow::Result; -use clap::{crate_version, load_yaml, App, AppSettings, ArgMatches}; -use dialoguer::Input; -use serde::Deserialize; - -mod build; -mod dev; -mod helpers; -mod info; -mod init; -mod interface; -mod sign; - -// temporary fork from https://github.com/mitsuhiko/console until 0.14.1+ release -#[allow(dead_code)] -mod console; -// temporary fork from https://github.com/mitsuhiko/dialoguer until 0.8.0+ release -#[allow(dead_code)] -mod dialoguer; - -use helpers::framework::{infer_from_package_json as infer_framework, Framework}; - -use std::{env::current_dir, fs::read_to_string, path::PathBuf}; - -#[derive(Deserialize)] -struct PackageJson { - name: Option, - product_name: Option, -} - -#[derive(Default)] -struct InitDefaults { - app_name: Option, - framework: Option, -} - -macro_rules! value_or_prompt { - ($init_runner: ident, $setter_fn: ident, $value: ident, $ci: ident, $prompt_message: expr, $prompt_default: expr) => {{ - let mut init_runner = $init_runner; - if let Some(value) = $value { - init_runner = init_runner.$setter_fn(value); - } else if !$ci { - let mut builder = Input::::new(); - builder.with_prompt($prompt_message); - if let Some(default) = $prompt_default { - builder.default(default); - } - let input = builder.interact_text()?; - init_runner = init_runner.$setter_fn(input); - } - init_runner - }}; -} - -fn init_command(matches: &ArgMatches) -> Result<()> { - let force = matches.is_present("force"); - let directory = matches.value_of("directory"); - let tauri_path = matches.value_of("tauri-path"); - let app_name = matches.value_of("app-name"); - let window_title = matches.value_of("window-title"); - let dist_dir = matches.value_of("dist-dir"); - let dev_path = matches.value_of("dev-path"); - let ci = matches.is_present("ci") || std::env::var("CI").is_ok(); - - let mut init_runner = init::Init::new(); - if force { - init_runner = init_runner.force(); - } - let base_directory = if let Some(directory) = directory { - init_runner = init_runner.directory(directory); - PathBuf::from(directory) - } else { - current_dir().expect("failed to read cwd") - }; - if let Some(tauri_path) = tauri_path { - init_runner = init_runner.tauri_path(tauri_path); - } - - let package_json_path = base_directory.join("package.json"); - let init_defaults = if package_json_path.exists() { - let package_json_text = read_to_string(package_json_path)?; - let package_json: PackageJson = serde_json::from_str(&package_json_text)?; - let (framework, _) = infer_framework(&package_json_text); - InitDefaults { - app_name: package_json.product_name.or(package_json.name), - framework, - } - } else { - Default::default() - }; - - init_runner = value_or_prompt!( - init_runner, - app_name, - app_name, - ci, - "What is your app name?", - init_defaults.app_name.clone() - ); - init_runner = value_or_prompt!( - init_runner, - window_title, - window_title, - ci, - "What should the window title be?", - init_defaults.app_name.clone() - ); - init_runner = value_or_prompt!( - init_runner, - dist_dir, - dist_dir, - ci, - r#"Where are your web assets (HTML/CSS/JS) located, relative to the "/src-tauri/tauri.conf.json" file that will be created?"#, - init_defaults.framework.as_ref().map(|f| f.dist_dir()) - ); - init_runner = value_or_prompt!( - init_runner, - dev_path, - dev_path, - ci, - "What is the url of your dev server?", - init_defaults.framework.map(|f| f.dev_path()) - ); - - init_runner.run() -} - -fn dev_command(matches: &ArgMatches) -> Result<()> { - let runner = matches.value_of("runner"); - let target = matches.value_of("target"); - let features: Vec = matches - .values_of("features") - .map(|a| a.into_iter().map(|v| v.to_string()).collect()) - .unwrap_or_default(); - let exit_on_panic = matches.is_present("exit-on-panic"); - let config = matches.value_of("config"); - let args: Vec = matches - .values_of("args") - .map(|a| a.into_iter().map(|v| v.to_string()).collect()) - .unwrap_or_default(); - let release_mode = matches.is_present("release"); - - let mut dev_runner = dev::Dev::new() - .exit_on_panic(exit_on_panic) - .args(args) - .features(features) - .release_mode(release_mode); - - if let Some(runner) = runner { - dev_runner = dev_runner.runner(runner.to_string()); - } - if let Some(target) = target { - dev_runner = dev_runner.target(target.to_string()); - } - if let Some(config) = config { - dev_runner = dev_runner.config(config.to_string()); - } - - dev_runner.run() -} - -fn build_command(matches: &ArgMatches) -> Result<()> { - let runner = matches.value_of("runner"); - let target = matches.value_of("target"); - let features: Vec = matches - .values_of("features") - .map(|a| a.into_iter().map(|v| v.to_string()).collect()) - .unwrap_or_default(); - let debug = matches.is_present("debug"); - let verbose = matches.is_present("verbose"); - let bundles = matches.values_of_lossy("bundle"); - let config = matches.value_of("config"); - - let mut build_runner = build::Build::new().features(features); - if let Some(runner) = runner { - build_runner = build_runner.runner(runner.to_string()); - } - if let Some(target) = target { - build_runner = build_runner.target(target.to_string()); - } - if debug { - build_runner = build_runner.debug(); - } - if verbose { - build_runner = build_runner.verbose(); - } - if let Some(bundles) = bundles { - build_runner = build_runner.bundles(bundles); - } - if let Some(config) = config { - build_runner = build_runner.config(config.to_string()); - } - - build_runner.run() -} - -fn info_command() -> Result<()> { - info::Info::new().run() -} - -fn sign_command(matches: &ArgMatches) -> Result<()> { - let private_key = matches.value_of("private-key"); - let private_key_path = matches.value_of("private-key-path"); - let file = matches.value_of("sign-file"); - let password = matches.value_of("password"); - let no_password = matches.is_present("no-password"); - let write_keys = matches.value_of("write-keys"); - let force = matches.is_present("force"); - - // generate keypair - if matches.is_present("generate") { - let mut keygen_runner = sign::KeyGenerator::new(); - - if no_password { - keygen_runner = keygen_runner.empty_password(); - } - - if force { - keygen_runner = keygen_runner.force(); - } - - if let Some(write_keys) = write_keys { - keygen_runner = keygen_runner.output_path(write_keys); - } - - if let Some(password) = password { - keygen_runner = keygen_runner.password(password); - } - - return keygen_runner.generate_keys(); - } - - // sign our binary / archive - let mut sign_runner = sign::Signer::new(); - if let Some(private_key) = private_key { - sign_runner = sign_runner.private_key(private_key); - } - - if let Some(private_key_path) = private_key_path { - sign_runner = sign_runner.private_key_path(private_key_path); - } - - if let Some(file) = file { - sign_runner = sign_runner.file_to_sign(file); - } - - if let Some(password) = password { - sign_runner = sign_runner.password(password); - } - - if no_password { - sign_runner = sign_runner.empty_password(); - } - - sign_runner.run() -} - -fn main() -> Result<()> { - let yaml = load_yaml!("cli.yml"); - let app = App::from(yaml) - .version(crate_version!()) - .setting(AppSettings::ArgRequiredElseHelp) - .setting(AppSettings::PropagateVersion) - .setting(AppSettings::SubcommandRequired) - .arg(clap::Arg::new("cargo").hidden(true).possible_value("tauri")); - let matches = app.get_matches(); - - if let Some(matches) = matches.subcommand_matches("init") { - init_command(matches)?; - } else if let Some(matches) = matches.subcommand_matches("dev") { - dev_command(matches)?; - } else if let Some(matches) = matches.subcommand_matches("build") { - build_command(matches)?; - } else if matches.subcommand_matches("info").is_some() { - info_command()?; - } else if let Some(matches) = matches.subcommand_matches("sign") { - sign_command(matches)?; - } - - Ok(()) -} diff --git a/tooling/cli.rs/src/sign.rs b/tooling/cli.rs/src/sign.rs deleted file mode 100644 index 89ad91074f72..000000000000 --- a/tooling/cli.rs/src/sign.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -use crate::helpers::updater_signature::{ - generate_key, read_key_from_file, save_keypair, sign_file, -}; -use std::path::{Path, PathBuf}; - -use anyhow::Context; - -#[derive(Default)] -pub struct Signer { - private_key: Option, - password: Option, - file: Option, -} - -impl Signer { - pub fn new() -> Self { - Default::default() - } - - pub fn private_key(mut self, private_key: &str) -> Self { - self.private_key = Some(private_key.to_owned()); - self - } - - pub fn password(mut self, password: &str) -> Self { - self.password = Some(password.to_owned()); - self - } - - pub fn empty_password(mut self) -> Self { - self.password = Some("".to_owned()); - self - } - - pub fn file_to_sign(mut self, file_path: &str) -> Self { - self.file = Some(Path::new(file_path).to_path_buf()); - self - } - - pub fn private_key_path(mut self, private_key: &str) -> Self { - self.private_key = - Some(read_key_from_file(Path::new(private_key)).expect("Unable to extract private key")); - self - } - - pub fn run(self) -> crate::Result<()> { - if self.private_key.is_none() { - return Err(anyhow::anyhow!( - "Key generation aborted: Unable to find the private key".to_string(), - )); - } - - if self.password.is_none() { - return Err(anyhow::anyhow!( - "Please use --no-password to set empty password or add --password if your private key have a password.".to_string(), - )); - } - - let (manifest_dir, signature) = sign_file( - self.private_key.unwrap(), - self.password.unwrap(), - self.file.unwrap(), - false, - ) - .with_context(|| "failed to sign file")?; - - println!( - "\nYour file was signed successfully, You can find the signature here:\n{}\n\nPublic signature:\n{}\n\nMake sure to include this into the signature field of your update server.", - manifest_dir.display(), - signature - ); - - Ok(()) - } -} - -#[derive(Default)] -pub struct KeyGenerator { - password: Option, - output_path: Option, - force: bool, -} - -impl KeyGenerator { - pub fn new() -> Self { - Default::default() - } - - pub fn empty_password(mut self) -> Self { - self.password = Some("".to_owned()); - self - } - - pub fn force(mut self) -> Self { - self.force = true; - self - } - - pub fn password(mut self, password: &str) -> Self { - self.password = Some(password.to_owned()); - self - } - - pub fn output_path(mut self, output_path: &str) -> Self { - self.output_path = Some(Path::new(output_path).to_path_buf()); - self - } - - pub fn generate_keys(self) -> crate::Result<()> { - let keypair = generate_key(self.password).expect("Failed to generate key"); - - if let Some(output_path) = self.output_path { - let (secret_path, public_path) = - save_keypair(self.force, output_path, &keypair.sk, &keypair.pk) - .expect("Unable to write keypair"); - - println!( - "\nYour keypair was generated successfully\nPrivate: {} (Keep it secret!)\nPublic: {}\n---------------------------", - secret_path.display(), - public_path.display() - ) - } else { - println!( - "\nYour secret key was generated successfully - Keep it secret!\n{}\n\n", - keypair.sk - ); - println!( - "Your public key was generated successfully:\n{}\n\nAdd the public key in your tauri.conf.json\n---------------------------\n", - keypair.pk - ); - } - - println!("\nEnvironment variabled used to sign:\n`TAURI_PRIVATE_KEY` Path or String of your private key\n`TAURI_KEY_PASSWORD` Your private key password (optional)\n\nATTENTION: If you lose your private key OR password, you'll not be able to sign your update package and updates will not works.\n---------------------------\n"); - - Ok(()) - } -} diff --git a/tooling/cli.rs/templates/src-tauri/Cargo.crate-manifest b/tooling/cli.rs/templates/src-tauri/Cargo.crate-manifest deleted file mode 100755 index 5af78028ac6c..000000000000 --- a/tooling/cli.rs/templates/src-tauri/Cargo.crate-manifest +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "app" -version = "0.1.0" -description = "A Tauri App" -authors = ["you"] -license = "" -repository = "" -default-run = "app" -edition = "2018" -build = "src/build.rs" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[build-dependencies] -tauri-build = {{{ tauri_build_dep }}} - -[dependencies] -serde_json = "1.0" -serde = { version = "1.0", features = ["derive"] } -tauri = {{{ tauri_dep }}} - -[features] -default = [ "custom-protocol" ] -custom-protocol = [ "tauri/custom-protocol" ] diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square107x107Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square107x107Logo.png deleted file mode 100644 index 0ca4f2719883..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square107x107Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square142x142Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square142x142Logo.png deleted file mode 100644 index b81f820394d1..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square142x142Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square150x150Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square150x150Logo.png deleted file mode 100644 index 624c7bfba049..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square150x150Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square284x284Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square284x284Logo.png deleted file mode 100644 index c021d2ba7661..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square284x284Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square30x30Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square30x30Logo.png deleted file mode 100644 index 621970023096..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square30x30Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square310x310Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square310x310Logo.png deleted file mode 100644 index f9bc04839491..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square310x310Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square44x44Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square44x44Logo.png deleted file mode 100644 index d5fbfb2ab4e5..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square44x44Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square71x71Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square71x71Logo.png deleted file mode 100644 index 63440d798493..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square71x71Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/Square89x89Logo.png b/tooling/cli.rs/templates/src-tauri/icons/Square89x89Logo.png deleted file mode 100644 index f3f705af2f2e..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/Square89x89Logo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/StoreLogo.png b/tooling/cli.rs/templates/src-tauri/icons/StoreLogo.png deleted file mode 100644 index 455638826192..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/StoreLogo.png and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/icon.icns b/tooling/cli.rs/templates/src-tauri/icons/icon.icns deleted file mode 100644 index 43c73bda9674..000000000000 Binary files a/tooling/cli.rs/templates/src-tauri/icons/icon.icns and /dev/null differ diff --git a/tooling/cli.rs/templates/src-tauri/rustfmt.toml b/tooling/cli.rs/templates/src-tauri/rustfmt.toml deleted file mode 100644 index 136f5f330967..000000000000 --- a/tooling/cli.rs/templates/src-tauri/rustfmt.toml +++ /dev/null @@ -1,14 +0,0 @@ -max_width = 100 -hard_tabs = false -tab_spaces = 2 -newline_style = "Auto" -use_small_heuristics = "Default" -reorder_imports = true -reorder_modules = true -remove_nested_parens = true -edition = "2018" -merge_derives = true -use_try_shorthand = false -use_field_init_shorthand = false -force_explicit_abi = true -imports_granularity = "Crate" diff --git a/tooling/cli.rs/templates/src-tauri/tauri.conf.json b/tooling/cli.rs/templates/src-tauri/tauri.conf.json deleted file mode 100644 index 3c6a77003225..000000000000 --- a/tooling/cli.rs/templates/src-tauri/tauri.conf.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "package": { - "productName": "{{ app_name }}", - "version": "0.1.0" - }, - "build": { - "distDir": "{{ dist_dir }}", - "devPath": "{{ dev_path }}", - "beforeDevCommand": "", - "beforeBuildCommand": "" - }, - "tauri": { - "bundle": { - "active": true, - "targets": "all", - "identifier": "com.tauri.dev", - "icon": [ - "icons/32x32.png", - "icons/128x128.png", - "icons/128x128@2x.png", - "icons/icon.icns", - "icons/icon.ico" - ], - "resources": [], - "externalBin": [], - "copyright": "", - "category": "DeveloperTool", - "shortDescription": "", - "longDescription": "", - "deb": { - "depends": [], - "useBootstrapper": false - }, - "macOS": { - "frameworks": [], - "minimumSystemVersion": "", - "useBootstrapper": false, - "exceptionDomain": "", - "signingIdentity": null, - "entitlements": null - }, - "windows": { - "certificateThumbprint": null, - "digestAlgorithm": "sha256", - "timestampUrl": "" - } - }, - "updater": { - "active": false - }, - "allowlist": { - "all": true - }, - "windows": [ - { - "title": "{{ window_title }}", - "width": 800, - "height": 600, - "resizable": true, - "fullscreen": false - } - ], - "security": { - "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'" - } - } -} diff --git a/tooling/cli/.license_template b/tooling/cli/.license_template new file mode 100644 index 000000000000..9601f8a1b49f --- /dev/null +++ b/tooling/cli/.license_template @@ -0,0 +1,3 @@ +// Copyright {20\d{2}(-20\d{2})?} Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT \ No newline at end of file diff --git a/tooling/cli.rs/CHANGELOG.md b/tooling/cli/CHANGELOG.md similarity index 100% rename from tooling/cli.rs/CHANGELOG.md rename to tooling/cli/CHANGELOG.md diff --git a/tooling/cli/Cargo.lock b/tooling/cli/Cargo.lock new file mode 100644 index 000000000000..5e1e2a5e0007 --- /dev/null +++ b/tooling/cli/Cargo.lock @@ -0,0 +1,3332 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array 0.14.5", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "opaque-debug 0.3.0", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" + +[[package]] +name = "ar" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69" + +[[package]] +name = "attohttpc" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e69e13a99a7e6e070bb114f7ff381e58c7ccc188630121fc4c2fe4bcf24cd072" +dependencies = [ + "flate2", + "http", + "log", + "native-tls", + "openssl", + "url", + "wildmatch", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitness" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57792b99d555ebf109c83169228076f7d997e2b37ba1a653850ccd703ac7bab0" +dependencies = [ + "sysctl", + "thiserror", + "uname", + "winapi 0.3.9", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array 0.14.5", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "bumpalo" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "bytemuck" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time 0.1.43", + "winapi 0.3.9", +] + +[[package]] +name = "chunked_transfer" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.5", +] + +[[package]] +name = "clap" +version = "3.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63edc3f163b3c71ec8aa23f9bd6070f77edbf3d1d198b164afa90ff00e4ec62" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1132dc3944b31c20dd8b906b3a9f0a5d0243e092d59171414969657ac6aa85" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi 0.3.9", +] + +[[package]] +name = "combine" +version = "4.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b727aacc797f9fc28e355d21f34709ac4fc9adecfe470ad07b8f4464f53062" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "console" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "regex", + "terminal_size", + "unicode-width", + "winapi 0.3.9", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array 0.14.5", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + +[[package]] +name = "darling" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "deflate" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f95bf05dffba6e6cce8dfbb30def788154949ccd9aed761b472119c21e01c70" +dependencies = [ + "adler32", +] + +[[package]] +name = "deflate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +dependencies = [ + "adler32", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "dialoguer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61579ada4ec0c6031cfac3f86fdba0d195a7ebeb5e36693bd53cb5999a25beeb" +dependencies = [ + "console", + "lazy_static", + "tempfile", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", + "generic-array 0.14.5", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.9", +] + +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dtoa-short" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +dependencies = [ + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + +[[package]] +name = "exr" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4badb9489a465cb2c555af1f00f0bfd8cecd6fc12ac11da9d5b40c5dd5f0200" +dependencies = [ + "bit_field", + "deflate 1.0.0", + "flume", + "half", + "inflate", + "lebe", + "smallvec", + "threadpool", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "winapi 0.3.9", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "flume" +version = "0.10.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d04dafd11240188e146b6f6476a898004cace3be31d4ec5e08e216bf4947ac0" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin 0.9.2", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "fsevent" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +dependencies = [ + "bitflags", + "fsevent-sys", +] + +[[package]] +name = "fsevent-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" +dependencies = [ + "libc", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug 0.3.0", + "polyval", +] + +[[package]] +name = "gif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "handlebars" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25546a65e5cf1f471f3438796fc634650b31d7fcde01d444c309aeb28b92e3a8" +dependencies = [ + "log", + "pest", + "pest_derive", + "quick-error", + "serde", + "serde_json", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddca131f3e7f2ce2df364b57949a9d47915cfbd35e46cfee355ccebbf794d6a2" +dependencies = [ + "digest 0.10.1", +] + +[[package]] +name = "html5ever" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.1", +] + +[[package]] +name = "humansize" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" + +[[package]] +name = "icns" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ccfbad7e08da70a5b48a924994a5afd93125ce5d45a3b0ba0b8da7bda59a40" +dependencies = [ + "byteorder", + "png 0.16.8", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94ac3d41f882c624a82d7945952032388488681f45f9d4077999a6c85688d61" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder 0.2.1", + "num-iter", + "num-rational", + "num-traits", + "png 0.17.2", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "include_dir" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "482a2e29200b7eed25d7fdbd14423326760b7f6658d21a4cf12d55a50713c69f" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e074c19deab2501407c91ba1860fa3d6820bfde307db6d8cb851b55a10be89b" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "inflate" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" +dependencies = [ + "adler32", +] + +[[package]] +name = "inotify" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" + +[[package]] +name = "jpeg-decoder" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcf0244f6597be39ab8d9203f574cafb529ae8c698afa2182f7b3c3205a4a9c" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" +dependencies = [ + "serde", + "serde_json", + "treediff", +] + +[[package]] +name = "json-pointer" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe841b94e719a482213cee19dd04927cf412f26d8dc84c5a446c081e49c2997" +dependencies = [ + "serde_json", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "jsonway" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effcb749443c905fbaef49d214f8b1049c240e0adb7af9baa0e201e625e4f9de" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "kstring" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b310ccceade8121d7d77fee406160e457c2f4e7c7982d589da3499bc7ea4526" +dependencies = [ + "serde", +] + +[[package]] +name = "kuchiki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +dependencies = [ + "cssparser", + "html5ever", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lebe" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff" + +[[package]] +name = "libc" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" + +[[package]] +name = "libflate" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d57e534717ac3e0b8dc459fe338bdfb4e29d7eea8fd0926ba649ddd3f4765f" +dependencies = [ + "adler32", + "crc32fast", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39a734c0493409afcd49deee13c006a04e3586b9761a03543c6272c9c51f2f5a" +dependencies = [ + "rle-decode-fast", +] + +[[package]] +name = "lock_api" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "markup5ever" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +dependencies = [ + "log", + "phf 0.8.0", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minisign" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43935b78ea0886357ab9259bd227879a54b12a83de261c3270aad584500cba2f" +dependencies = [ + "getrandom 0.2.4", + "rpassword", + "scrypt", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "nanorand" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729eb334247daa1803e0a094d0a5c55711b85571179f5ec6e53eccfdf7008958" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "napi" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ec66e60f000c78dd7c6215b6fa260e0591e09805024332bc5b3f55acc12244" +dependencies = [ + "ctor", + "lazy_static", + "napi-sys", + "windows", +] + +[[package]] +name = "napi-build" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd4419172727423cf30351406c54f6cc1b354a2cfb4f1dba3e6cd07f6d5522b" + +[[package]] +name = "napi-derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ac5287a5e94a8728fc82d16c5127acc5eb5b8ad6404ef5f82d6a4ce8d5bdd2" +dependencies = [ + "convert_case 0.5.0", + "napi-derive-backend", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "napi-derive-backend" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427f4f04525635cdf22005d1be62d6d671bcb5550d694a1efb480a315422b4af" +dependencies = [ + "convert_case 0.5.0", + "once_cell", + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "napi-sys" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a385494dac3c52cbcacb393bb3b42669e7db8ab240c7ad5115f549eb061f2cc" + +[[package]] +name = "native-tls" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "notify" +version = "4.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" +dependencies = [ + "bitflags", + "filetime", + "fsevent", + "fsevent-sys", + "inotify", + "libc", + "mio", + "mio-extras", + "walkdir", + "winapi 0.3.9", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15" +dependencies = [ + "libc", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +dependencies = [ + "bitflags", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "os_info" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023df84d545ef479cf67fd2f4459a613585c9db4852c2fad12ab70587859d340" +dependencies = [ + "log", + "serde", + "winapi 0.3.9", +] + +[[package]] +name = "os_pipe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3492ebca331b895fe23ed427dce2013d9b2e00c45964f12040b0db38b8ab27" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + +[[package]] +name = "pbkdf2" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4628cc3cf953b82edcd3c1388c5715401420ce5524fedbab426bd5aba017434" +dependencies = [ + "digest 0.10.1", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +dependencies = [ + "maplit", + "pest", + "sha-1", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.4", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.8.6", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "png" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c845088517daa61e8a57eee40309347cea13f273694d1385c553e7a57127763b" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.9.1", + "encoding", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "publicsuffix" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b4ce31ff0a27d93c8de1849cf58162283752f065a90d508f1105fa6c9a213f" +dependencies = [ + "idna", + "url", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.4", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi 0.3.9", +] + +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + +[[package]] +name = "rpassword" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "salsa20" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi 0.3.9", +] + +[[package]] +name = "schemars" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "schemars_derive" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scrypt" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e73d6d7c6311ebdbd9184ad6c4447b2f36337e327bda107d3ba9e3c374f9d325" +dependencies = [ + "hmac", + "pbkdf2", + "salsa20", + "sha2", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +dependencies = [ + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1e6ec4d8950e5b1e894eac0d360742f3b1407a6078a604a731c4b3f49cefbc" +dependencies = [ + "rustversion", + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha-1" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha1" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.1", +] + +[[package]] +name = "shared_child" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "siphasher" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "string_cache" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "sysctl" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feb3f7a32e17639e3705d2e05da40f485877cb97fdf0f3240e519e525e6cdb4d" +dependencies = [ + "bitflags", + "byteorder", + "libc", + "thiserror", + "walkdir", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tauri-bundler" +version = "1.0.0-beta.4" +dependencies = [ + "anyhow", + "ar", + "attohttpc", + "bitness", + "dirs-next", + "glob", + "handlebars", + "heck", + "hex", + "icns", + "image", + "libflate", + "md5", + "os_pipe", + "regex", + "serde", + "serde_json", + "sha2", + "strsim", + "tar", + "tauri-utils", + "tempfile", + "termcolor", + "thiserror", + "time 0.3.7", + "toml", + "uuid", + "walkdir", + "winreg", + "zip", +] + +[[package]] +name = "tauri-cli" +version = "1.0.0-beta.7" +dependencies = [ + "anyhow", + "base64", + "clap", + "colored", + "dialoguer", + "encode_unicode", + "glob", + "handlebars", + "heck", + "humansize", + "include_dir", + "json-patch", + "lazy_static", + "libc", + "minisign", + "notify", + "once_cell", + "os_info", + "os_pipe", + "regex", + "schemars", + "semver", + "serde", + "serde_json", + "serde_with", + "shared_child", + "tauri-bundler", + "tauri-utils", + "tempfile", + "terminal_size", + "toml", + "toml_edit", + "unicode-width", + "ureq", + "url", + "valico", + "zeroize", +] + +[[package]] +name = "tauri-cli-node" +version = "0.0.0" +dependencies = [ + "napi", + "napi-build", + "napi-derive", + "tauri-cli", +] + +[[package]] +name = "tauri-utils" +version = "1.0.0-beta.3" +dependencies = [ + "aes-gcm", + "ctor", + "glob", + "heck", + "html5ever", + "json-patch", + "json5", + "kuchiki", + "once_cell", + "phf 0.10.1", + "ring", + "schemars", + "serde", + "serde_json", + "serde_with", + "serialize-to-javascript", + "thiserror", + "url", + "walkdir", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi 0.3.9", +] + +[[package]] +name = "tendril" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "textwrap" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0247608e998cb6ce39dfc8f4a16c50361ce71e5b52e6d24ea1227ea8ea8ee0b2" +dependencies = [ + "flate2", + "jpeg-decoder 0.1.22", + "weezl", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "time" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d" +dependencies = [ + "itoa 1.0.1", + "libc", + "num_threads", +] + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744e9ed5b352340aa47ce033716991b5589e23781acb97cad37d4ea70560f55b" +dependencies = [ + "combine", + "indexmap", + "itertools", + "kstring", +] + +[[package]] +name = "treediff" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" +dependencies = [ + "serde_json", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array 0.14.5", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "ureq" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9399fa2f927a3d327187cbd201480cee55bee6ac5d3c77dd27f0c6814cff16d5" +dependencies = [ + "base64", + "chunked_transfer", + "flate2", + "log", + "once_cell", + "rustls", + "url", + "webpki", + "webpki-roots", +] + +[[package]] +name = "uritemplate-next" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcde98d1fc3f528255b1ecb22fb688ee0d23deb672a8c57127df10b98b4bd18c" +dependencies = [ + "regex", +] + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.4", + "sha1", +] + +[[package]] +name = "valico" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d81a70f930f9e6cd04669d38abcf232f96b193acceb0f4c006427ddec6e08b10" +dependencies = [ + "base64", + "chrono", + "json-pointer", + "jsonway", + "percent-encoding", + "phf 0.8.0", + "phf_codegen", + "publicsuffix", + "regex", + "serde", + "serde_json", + "uritemplate-next", + "url", + "uuid", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" + +[[package]] +name = "web-sys" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449" +dependencies = [ + "webpki", +] + +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" + +[[package]] +name = "wildmatch" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca" + +[[package]] +name = "windows_i686_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8" + +[[package]] +name = "windows_i686_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] + +[[package]] +name = "zeroize" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "bzip2", + "crc32fast", + "flate2", + "thiserror", + "time 0.1.43", +] diff --git a/tooling/cli/Cargo.toml b/tooling/cli/Cargo.toml new file mode 100644 index 000000000000..7e8ca9d6425f --- /dev/null +++ b/tooling/cli/Cargo.toml @@ -0,0 +1,77 @@ +[workspace] +members = [ + "node" +] + +[package] +name = "tauri-cli" +version = "1.0.0-beta.7" +authors = [ "Tauri Programme within The Commons Conservancy" ] +edition = "2021" +rust-version = "1.57" +categories = [ "gui", "web-programming" ] +license = "Apache-2.0 OR MIT" +homepage = "https://tauri.studio" +repository = "https://github.com/tauri-apps/tauri" +description = "Command line interface for building Tauri apps" +include = [ "src/", "/templates", "MergeModules/", "*.json", "*.rs" ] + +[[bin]] +name = "cargo-tauri" +path = "src/main.rs" + +[dependencies] +clap = { version = "3", features = [ "derive" ] } +anyhow = "1.0" +tauri-bundler = { version = "1.0.0-beta.4", path = "../bundler" } +colored = "2.0" +once_cell = "1.9" +serde = { version = "1.0", features = [ "derive" ] } +serde_json = "1.0" +serde_with = "1.12" +notify = "4.0" +shared_child = "1.0" +toml_edit = "0.13" +json-patch = "0.2" +tauri-utils = { version = "1.0.0-beta.3", path = "../../core/tauri-utils", features = ["isolation", "schema", "config-json5"] } +toml = "0.5" +valico = "3.6" +handlebars = "4.2" +include_dir = "0.7" +minisign = "0.7" +base64 = "0.13.0" +ureq = "2.4" +os_info = "3.2" +semver = "1.0" +regex = "1.5" +lazy_static = "1" +libc = "0.2" +terminal_size = "0.1" +unicode-width = "0.1" +tempfile = "3" +zeroize = "1.5" +glob = "0.3" +heck = "0.4" +dialoguer = "0.9" +url = { version = "2.2", features = [ "serde" ] } +os_pipe = "1" + +[target."cfg(windows)".dependencies] +encode_unicode = "0.3" + +[target."cfg(not(windows))".dependencies] +humansize = "1.1" + +[target."cfg(target_os = \"linux\")".build-dependencies] +heck = "0.4" + +[build-dependencies] +tauri-utils = { version = "1.0.0-beta.3", features = ["schema", "isolation"], path = "../../core/tauri-utils" } +schemars = { version = "0.8", features = ["url"] } +serde = { version = "1.0", features = [ "derive" ] } +serde_json = "1.0" +serde_with = "1.12" +url = { version = "2.2", features = [ "serde" ] } + +[profile.release] +lto = true diff --git a/tooling/cli.rs/MergeModules/Microsoft_VC142_CRT_x64.msm b/tooling/cli/MergeModules/Microsoft_VC142_CRT_x64.msm similarity index 100% rename from tooling/cli.rs/MergeModules/Microsoft_VC142_CRT_x64.msm rename to tooling/cli/MergeModules/Microsoft_VC142_CRT_x64.msm diff --git a/tooling/cli.rs/MergeModules/Microsoft_VC142_CRT_x86.msm b/tooling/cli/MergeModules/Microsoft_VC142_CRT_x86.msm similarity index 100% rename from tooling/cli.rs/MergeModules/Microsoft_VC142_CRT_x86.msm rename to tooling/cli/MergeModules/Microsoft_VC142_CRT_x86.msm diff --git a/tooling/cli.rs/README.md b/tooling/cli/README.md similarity index 100% rename from tooling/cli.rs/README.md rename to tooling/cli/README.md diff --git a/tooling/cli/build.rs b/tooling/cli/build.rs new file mode 100644 index 000000000000..380ce3aac301 --- /dev/null +++ b/tooling/cli/build.rs @@ -0,0 +1,23 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::{ + env::current_dir, + error::Error, + fs::File, + io::{BufWriter, Write}, +}; + +pub fn main() -> Result<(), Box> { + let schema = schemars::schema_for!(tauri_utils::config::Config); + let schema_file_path = current_dir()?.join("schema.json"); + let mut schema_file = BufWriter::new(File::create(&schema_file_path)?); + write!( + schema_file, + "{}", + serde_json::to_string_pretty(&schema).unwrap() + )?; + + Ok(()) +} diff --git a/tooling/cli/metadata.json b/tooling/cli/metadata.json new file mode 100644 index 000000000000..84a60cca11c0 --- /dev/null +++ b/tooling/cli/metadata.json @@ -0,0 +1,8 @@ +{ + "cli.js": { + "version": "1.0.0-rc.-1", + "node": ">= 12.13.0" + }, + "tauri": "1.0.0-rc.-1", + "tauri-build": "1.0.0-rc.-1" +} diff --git a/tooling/cli/node/.cargo/config.toml b/tooling/cli/node/.cargo/config.toml new file mode 100644 index 000000000000..6890aa910ba3 --- /dev/null +++ b/tooling/cli/node/.cargo/config.toml @@ -0,0 +1,7 @@ +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" +[target.aarch64-unknown-linux-musl] +linker = "aarch64-linux-musl-gcc" +rustflags = ["-C", "target-feature=-crt-static"] +[target.armv7-unknown-linux-gnueabihf] +linker = "arm-linux-gnueabihf-gcc" \ No newline at end of file diff --git a/tooling/cli/node/.github-example/workflows/CI.yml b/tooling/cli/node/.github-example/workflows/CI.yml new file mode 100644 index 000000000000..a9fb57f0baad --- /dev/null +++ b/tooling/cli/node/.github-example/workflows/CI.yml @@ -0,0 +1,469 @@ +name: CI +env: + DEBUG: napi:* + APP_NAME: cli + MACOSX_DEPLOYMENT_TARGET: '10.13' +'on': + push: + branches: + - main + tags-ignore: + - '**' + paths-ignore: + - '**/*.md' + - LICENSE + - '**/*.gitignore' + - .editorconfig + - docs/** + pull_request: null +jobs: + build: + if: "!contains(github.event.head_commit.message, 'skip ci')" + strategy: + fail-fast: false + matrix: + settings: + - host: macos-latest + target: x86_64-apple-darwin + architecture: x64 + build: | + yarn build + strip -x *.node + - host: windows-latest + build: yarn build + target: x86_64-pc-windows-msvc + architecture: x64 + - host: ubuntu-18.04 + target: x86_64-unknown-linux-gnu + architecture: x64 + docker: | + docker pull $DOCKER_REGISTRY_URL/napi-rs/napi-rs/nodejs-rust:lts-debian + docker tag $DOCKER_REGISTRY_URL/napi-rs/napi-rs/nodejs-rust:lts-debian builder + build: | + docker run --rm -v ~/.cargo/git:/root/.cargo/git -v ~/.cargo/registry:/root/.cargo/registry -v $(pwd):/build -w /build builder yarn build && strip *.node + - host: ubuntu-18.04 + target: x86_64-unknown-linux-musl + architecture: x64 + docker: | + docker pull $DOCKER_REGISTRY_URL/napi-rs/napi-rs/nodejs-rust:lts-alpine + docker tag $DOCKER_REGISTRY_URL/napi-rs/napi-rs/nodejs-rust:lts-alpine builder + build: docker run --rm -v ~/.cargo/git:/root/.cargo/git -v ~/.cargo/registry:/root/.cargo/registry -v $(pwd):/build -w /build builder yarn build && strip *.node + - host: macos-latest + target: aarch64-apple-darwin + build: | + yarn build --target=aarch64-apple-darwin + strip -x *.node + - host: ubuntu-18.04 + architecture: x64 + target: aarch64-unknown-linux-gnu + setup: | + sudo apt-get update + sudo apt-get install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu -y + build: | + yarn build --target=aarch64-unknown-linux-gnu + aarch64-linux-gnu-strip *.node + - host: ubuntu-18.04 + architecture: x64 + target: armv7-unknown-linux-gnueabihf + setup: | + sudo apt-get update + sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y + build: | + yarn build --target=armv7-unknown-linux-gnueabihf + arm-linux-gnueabihf-strip *.node + - host: ubuntu-18.04 + architecture: x64 + target: aarch64-unknown-linux-musl + downloadTarget: aarch64-unknown-linux-musl + docker: | + docker pull ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine + docker tag ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine builder + build: | + docker run --rm -v ~/.cargo/git:/root/.cargo/git -v ~/.cargo/registry:/root/.cargo/registry -v $(pwd):/build -w /build builder sh -c "yarn build --target=aarch64-unknown-linux-musl && /aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip *.node" + - host: windows-latest + architecture: x64 + target: aarch64-pc-windows-msvc + build: yarn build --target aarch64-pc-windows-msvc + name: stable - ${{ matrix.settings.target }} - node@16 + runs-on: ${{ matrix.settings.host }} + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 16 + check-latest: true + cache: yarn + architecture: ${{ matrix.settings.architecture }} + - name: Install + uses: actions-rs/toolchain@v1 + with: + profile: minimal + override: true + toolchain: stable + target: ${{ matrix.settings.target }} + - name: Generate Cargo.lock + uses: actions-rs/cargo@v1 + with: + command: generate-lockfile + - name: Cache cargo registry + uses: actions/cache@v2 + with: + path: ~/.cargo/registry + key: ${{ matrix.settings.target }}-node@16-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} + - name: Cache cargo index + uses: actions/cache@v2 + with: + path: ~/.cargo/git + key: ${{ matrix.settings.target }}-node@16-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} + - name: Cache NPM dependencies + uses: actions/cache@v2 + with: + path: node_modules + key: npm-cache-${{ matrix.settings.target }}-node@16-${{ hashFiles('yarn.lock') }} + - name: Pull latest image + run: ${{ matrix.settings.docker }} + env: + DOCKER_REGISTRY_URL: ghcr.io + if: ${{ matrix.settings.docker }} + - name: Setup toolchain + run: ${{ matrix.settings.setup }} + if: ${{ matrix.settings.setup }} + shell: bash + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Build + run: ${{ matrix.settings.build }} + shell: bash + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: bindings-${{ matrix.settings.target }} + path: ${{ env.APP_NAME }}.*.node + if-no-files-found: error + build-freebsd: + runs-on: macos-10.15 + name: Build FreeBSD + steps: + - uses: actions/checkout@v2 + - name: Build + id: build + uses: vmactions/freebsd-vm@v0.1.5 + env: + DEBUG: napi:* + RUSTUP_HOME: /usr/local/rustup + CARGO_HOME: /usr/local/cargo + RUSTUP_IO_THREADS: 1 + with: + envs: DEBUG RUSTUP_HOME CARGO_HOME RUSTUP_IO_THREADS + usesh: true + mem: 3000 + prepare: | + pkg install -y curl node14 python2 + curl -qL https://www.npmjs.com/install.sh | sh + npm install -g yarn + curl https://sh.rustup.rs -sSf --output rustup.sh + sh rustup.sh -y --profile minimal --default-toolchain stable + export PATH="/usr/local/cargo/bin:$PATH" + echo "~~~~ rustc --version ~~~~" + rustc --version + echo "~~~~ node -v ~~~~" + node -v + echo "~~~~ yarn --version ~~~~" + yarn --version + run: | + export PATH="/usr/local/cargo/bin:$PATH" + pwd + ls -lah + whoami + env + freebsd-version + yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + yarn build + strip -x *.node + yarn test + rm -rf node_modules + rm -rf target + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: bindings-freebsd + path: ${{ env.APP_NAME }}.*.node + if-no-files-found: error + test-macOS-windows-binding: + name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + settings: + - host: windows-latest + target: x86_64-pc-windows-msvc + node: + - '12' + - '14' + - '16' + runs-on: ${{ matrix.settings.host }} + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + check-latest: true + cache: yarn + - name: Cache NPM dependencies + uses: actions/cache@v2 + with: + path: node_modules + key: npm-cache-test-${{ matrix.settings.target }}-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-${{ matrix.settings.target }} + path: . + - name: List packages + run: ls -R . + shell: bash + - name: Test bindings + run: yarn test + test-linux-x64-gnu-binding: + name: Test bindings on Linux-x64-gnu - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: + - '12' + - '14' + - '16' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + check-latest: true + cache: yarn + - name: Cache NPM dependencies + uses: actions/cache@v2 + with: + path: node_modules + key: npm-cache-test-linux-x64-gnu-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-x86_64-unknown-linux-gnu + path: . + - name: List packages + run: ls -R . + shell: bash + - name: Test bindings + run: docker run --rm -v $(pwd):/build -w /build node:${{ matrix.node }}-slim yarn test + test-linux-x64-musl-binding: + name: Test bindings on x86_64-unknown-linux-musl - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: + - '12' + - '14' + - '16' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + check-latest: true + cache: yarn + - name: Cache NPM dependencies + uses: actions/cache@v2 + with: + path: node_modules + key: npm-cache-test-x86_64-unknown-linux-musl-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-x86_64-unknown-linux-musl + path: . + - name: List packages + run: ls -R . + shell: bash + - name: Test bindings + run: docker run --rm -v $(pwd):/build -w /build node:${{ matrix.node }}-alpine yarn test + test-linux-aarch64-gnu-binding: + name: Test bindings on aarch64-unknown-linux-gnu - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: + - '12' + - '14' + - '16' + runs-on: ubuntu-latest + steps: + - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + - uses: actions/checkout@v2 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-aarch64-unknown-linux-gnu + path: . + - name: List packages + run: ls -R . + shell: bash + - name: Cache NPM dependencies + uses: actions/cache@v2 + with: + path: node_modules + key: npm-cache-test-linux-aarch64-gnu-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} + - name: Install dependencies + run: yarn install --ignore-scripts --ignore-platform --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Setup and run tests + uses: addnab/docker-run-action@v3 + with: + image: ghcr.io/napi-rs/napi-rs/nodejs:aarch64-${{ matrix.node }} + options: '-v ${{ github.workspace }}:/build -w /build' + run: | + set -e + yarn test + ls -la + test-linux-aarch64-musl-binding: + name: Test bindings on aarch64-unknown-linux-musl - node@${{ matrix.node }} + needs: + - build + runs-on: ubuntu-latest + steps: + - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + - uses: actions/checkout@v2 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-aarch64-unknown-linux-musl + path: . + - name: List packages + run: ls -R . + shell: bash + - name: Cache NPM dependencies + uses: actions/cache@v2 + with: + path: node_modules + key: npm-cache-test-linux-aarch64-musl-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} + - name: Install dependencies + run: yarn install --ignore-scripts --ignore-platform --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Setup and run tests + uses: addnab/docker-run-action@v3 + with: + image: multiarch/alpine:aarch64-latest-stable + options: '-v ${{ github.workspace }}:/build -w /build' + run: | + set -e + apk add nodejs npm yarn + yarn test + test-linux-arm-gnueabihf-binding: + name: Test bindings on armv7-unknown-linux-gnueabihf - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: + - '12' + - '14' + - '16' + runs-on: ubuntu-latest + steps: + - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + - uses: actions/checkout@v2 + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-armv7-unknown-linux-gnueabihf + path: . + - name: List packages + run: ls -R . + shell: bash + - name: Cache NPM dependencies + uses: actions/cache@v2 + with: + path: node_modules + key: npm-cache-test-linux-arm-gnueabihf-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} + - name: Install dependencies + run: yarn install --ignore-scripts --ignore-platform --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Setup and run tests + uses: addnab/docker-run-action@v3 + with: + image: ghcr.io/napi-rs/napi-rs/nodejs:armhf-${{ matrix.node }} + options: '-v ${{ github.workspace }}:/build -w /build' + run: | + set -e + yarn test + ls -la + publish: + name: Publish + runs-on: ubuntu-latest + needs: + - build-freebsd + - test-macOS-windows-binding + - test-linux-x64-gnu-binding + - test-linux-x64-musl-binding + - test-linux-aarch64-gnu-binding + - test-linux-aarch64-musl-binding + - test-linux-arm-gnueabihf-binding + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 16 + check-latest: true + cache: yarn + - name: Cache NPM dependencies + uses: actions/cache@v2 + with: + path: node_modules + key: npm-cache-ubuntu-latest-${{ hashFiles('yarn.lock') }} + restore-keys: | + npm-cache- + - name: Install dependencies + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + - name: Download all artifacts + uses: actions/download-artifact@v2 + with: + path: artifacts + - name: Move artifacts + run: yarn artifacts + - name: List packages + run: ls -R ./npm + shell: bash + - name: Publish + run: | + if git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$"; + then + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + npm publish --access public + elif git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+"; + then + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + npm publish --tag next --access public + else + echo "Not a release, skipping publish" + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/tooling/cli/node/.gitignore b/tooling/cli/node/.gitignore new file mode 100644 index 000000000000..a56b097017b5 --- /dev/null +++ b/tooling/cli/node/.gitignore @@ -0,0 +1,2 @@ +# Automatically generated +/*.node \ No newline at end of file diff --git a/tooling/cli/node/.npmignore b/tooling/cli/node/.npmignore new file mode 100644 index 000000000000..f96abe0b8c9b --- /dev/null +++ b/tooling/cli/node/.npmignore @@ -0,0 +1,10 @@ +target +Cargo.lock +.cargo +.github +npm +.eslintrc +.prettierignore +rustfmt.toml +yarn.lock +*.node diff --git a/tooling/cli/node/Cargo.toml b/tooling/cli/node/Cargo.toml new file mode 100644 index 000000000000..4f8383c457b6 --- /dev/null +++ b/tooling/cli/node/Cargo.toml @@ -0,0 +1,16 @@ +[package] +edition = "2021" +name = "tauri-cli-node" +version = "0.0.0" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix +napi = { version = "2.0", default-features = false, features = ["napi4"] } +napi-derive = "2.0" +tauri-cli = { path = ".." } + +[build-dependencies] +napi-build = "1.2" diff --git a/tooling/cli/node/README.md b/tooling/cli/node/README.md new file mode 100644 index 000000000000..929460b226c9 --- /dev/null +++ b/tooling/cli/node/README.md @@ -0,0 +1,45 @@ +# @tauri-apps/cli + + +[![status](https://img.shields.io/badge/Status-Beta-green.svg)](https://github.com/tauri-apps/tauri) +[![Chat Server](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/SpmNs4S) +[![devto](https://img.shields.io/badge/blog-dev.to-black.svg)](https://dev.to/tauri) + +![](https://img.shields.io/github/workflow/status/tauri-apps/tauri/test%20library?label=test%20library +) +[![devto](https://img.shields.io/badge/documentation-site-purple.svg)](https://tauri.studio) + +[![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) +[![support](https://img.shields.io/badge/sponsor-Opencollective-blue.svg)](https://opencollective.com/tauri) + +| Component | Version | +| --------- | ------------------------------------------- | +| @tauri-apps/cli | ![](https://img.shields.io/npm/v/@tauri-apps/cli.svg) | + +## About Tauri +Tauri is a polyglot and generic system that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. In fact, developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily. + +Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the system's webview. They do not ship a runtime, since the final binary is compiled from rust. This makes the reversing of Tauri apps not a trivial task. +## This module +Written in Typescript and packaged such that it can be used with `npm`, `pnpm`, and `yarn`, this library provides a node.js runner for common tasks when using Tauri, like `yarn tauri dev`. For the most part it is a wrapper around [cli.rs](https://github.com/tauri-apps/tauri/blob/dev/tooling/cli). + +To 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. + + +## Installation + +The preferred method is to install this module locally as a development dependency: +``` +$ npm install --save-dev @tauri-apps/cli +$ yarn add --dev @tauri-apps/cli +``` + +## Semver +**tauri** is following [Semantic Versioning 2.0](https://semver.org/). +## Licenses +Code: (c) 2019 - 2021 - The Tauri Programme within The Commons Conservancy. + +MIT or MIT/Apache 2.0 where applicable. + +Logo: CC-BY-NC-ND +- Original Tauri Logo Designs by [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum) diff --git a/tooling/cli/node/build.rs b/tooling/cli/node/build.rs new file mode 100644 index 000000000000..ff05c1667f34 --- /dev/null +++ b/tooling/cli/node/build.rs @@ -0,0 +1,7 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +fn main() { + ::napi_build::setup(); +} diff --git a/tooling/cli/node/index.d.ts b/tooling/cli/node/index.d.ts new file mode 100644 index 000000000000..82c933de7c25 --- /dev/null +++ b/tooling/cli/node/index.d.ts @@ -0,0 +1,12 @@ +/* tslint:disable */ +/* eslint-disable */ + +/* auto-generated by NAPI-RS */ + +export class ExternalObject { + readonly '': { + readonly '': unique symbol + [K: symbol]: T + } +} +export function run(args: Array, binName?: string | undefined | null): void diff --git a/tooling/cli/node/index.js b/tooling/cli/node/index.js new file mode 100644 index 000000000000..7ca66a61d329 --- /dev/null +++ b/tooling/cli/node/index.js @@ -0,0 +1,241 @@ +const { existsSync, readFileSync } = require('fs') +const { join } = require('path') + +const { platform, arch } = process + +let nativeBinding = null +let localFileExisted = false +let loadError = null + +function isMusl() { + // For Node 10 + if (!process.report || typeof process.report.getReport !== 'function') { + try { + return readFileSync('/usr/bin/ldd', 'utf8').includes('musl') + } catch (e) { + return true + } + } else { + const { glibcVersionRuntime } = process.report.getReport().header + return !glibcVersionRuntime + } +} + +switch (platform) { + case 'android': + switch (arch) { + case 'arm64': + localFileExisted = existsSync(join(__dirname, 'cli.android-arm64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./cli.android-arm64.node') + } else { + nativeBinding = require('@tauri-apps/cli-android-arm64') + } + } catch (e) { + loadError = e + } + break + case 'arm': + localFileExisted = existsSync(join(__dirname, 'cli.android-arm-eabi.node')) + try { + if (localFileExisted) { + nativeBinding = require('./cli.android-arm-eabi.node') + } else { + nativeBinding = require('@tauri-apps/cli-android-arm-eabi') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Android ${arch}`) + } + break + case 'win32': + switch (arch) { + case 'x64': + localFileExisted = existsSync( + join(__dirname, 'cli.win32-x64-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.win32-x64-msvc.node') + } else { + nativeBinding = require('@tauri-apps/cli-win32-x64-msvc') + } + } catch (e) { + loadError = e + } + break + case 'ia32': + localFileExisted = existsSync( + join(__dirname, 'cli.win32-ia32-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.win32-ia32-msvc.node') + } else { + nativeBinding = require('@tauri-apps/cli-win32-ia32-msvc') + } + } catch (e) { + loadError = e + } + break + case 'arm64': + localFileExisted = existsSync( + join(__dirname, 'cli.win32-arm64-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.win32-arm64-msvc.node') + } else { + nativeBinding = require('@tauri-apps/cli-win32-arm64-msvc') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Windows: ${arch}`) + } + break + case 'darwin': + switch (arch) { + case 'x64': + localFileExisted = existsSync(join(__dirname, 'cli.darwin-x64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./cli.darwin-x64.node') + } else { + nativeBinding = require('@tauri-apps/cli-darwin-x64') + } + } catch (e) { + loadError = e + } + break + case 'arm64': + localFileExisted = existsSync( + join(__dirname, 'cli.darwin-arm64.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.darwin-arm64.node') + } else { + nativeBinding = require('@tauri-apps/cli-darwin-arm64') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on macOS: ${arch}`) + } + break + case 'freebsd': + if (arch !== 'x64') { + throw new Error(`Unsupported architecture on FreeBSD: ${arch}`) + } + localFileExisted = existsSync(join(__dirname, 'cli.freebsd-x64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./cli.freebsd-x64.node') + } else { + nativeBinding = require('@tauri-apps/cli-freebsd-x64') + } + } catch (e) { + loadError = e + } + break + case 'linux': + switch (arch) { + case 'x64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'cli.linux-x64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.linux-x64-musl.node') + } else { + nativeBinding = require('@tauri-apps/cli-linux-x64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'cli.linux-x64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.linux-x64-gnu.node') + } else { + nativeBinding = require('@tauri-apps/cli-linux-x64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 'arm64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'cli.linux-arm64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.linux-arm64-musl.node') + } else { + nativeBinding = require('@tauri-apps/cli-linux-arm64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'cli.linux-arm64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.linux-arm64-gnu.node') + } else { + nativeBinding = require('@tauri-apps/cli-linux-arm64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 'arm': + localFileExisted = existsSync( + join(__dirname, 'cli.linux-arm-gnueabihf.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./cli.linux-arm-gnueabihf.node') + } else { + nativeBinding = require('@tauri-apps/cli-linux-arm-gnueabihf') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Linux: ${arch}`) + } + break + default: + throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) +} + +if (!nativeBinding) { + if (loadError) { + throw loadError + } + throw new Error(`Failed to load native binding`) +} + +const { run } = nativeBinding + +module.exports.run = run diff --git a/tooling/cli/node/jest.config.js b/tooling/cli/node/jest.config.js new file mode 100644 index 000000000000..d01d4b3c3b5d --- /dev/null +++ b/tooling/cli/node/jest.config.js @@ -0,0 +1,14 @@ +module.exports = { + setupFilesAfterEnv: ['/test/jest/jest.setup.js'], + testMatch: [ + '/test/jest/__tests__/**/*.spec.js', + '/test/jest/__tests__/**/*.test.js' + ], + moduleFileExtensions: ['ts', 'js', 'json'], + moduleNameMapper: { + '^~/(.*)$': '/$1' + }, + transform: { + '\\.toml$': 'jest-transform-toml' + } +} diff --git a/tooling/cli/node/npm/darwin-arm64/README.md b/tooling/cli/node/npm/darwin-arm64/README.md new file mode 100644 index 000000000000..3af0749d6e21 --- /dev/null +++ b/tooling/cli/node/npm/darwin-arm64/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-darwin-arm64` + +This is the **aarch64-apple-darwin** binary for `@tauri-apps/cli` diff --git a/tooling/cli/node/npm/darwin-arm64/package.json b/tooling/cli/node/npm/darwin-arm64/package.json new file mode 100644 index 000000000000..bd0eb651f501 --- /dev/null +++ b/tooling/cli/node/npm/darwin-arm64/package.json @@ -0,0 +1,21 @@ +{ + "name": "@tauri-apps/cli-darwin-arm64", + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "os": [ + "darwin" + ], + "cpu": [ + "arm64" + ], + "main": "cli.darwin-arm64.node", + "files": [ + "cli.darwin-arm64.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/tooling/cli/node/npm/darwin-x64/README.md b/tooling/cli/node/npm/darwin-x64/README.md new file mode 100644 index 000000000000..2945287832c8 --- /dev/null +++ b/tooling/cli/node/npm/darwin-x64/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-darwin-x64` + +This is the **x86_64-apple-darwin** binary for `@tauri-apps/cli` diff --git a/tooling/cli/node/npm/darwin-x64/package.json b/tooling/cli/node/npm/darwin-x64/package.json new file mode 100644 index 000000000000..1e38685a4914 --- /dev/null +++ b/tooling/cli/node/npm/darwin-x64/package.json @@ -0,0 +1,21 @@ +{ + "name": "@tauri-apps/cli-darwin-x64", + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "os": [ + "darwin" + ], + "cpu": [ + "x64" + ], + "main": "cli.darwin-x64.node", + "files": [ + "cli.darwin-x64.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/tooling/cli/node/npm/linux-arm-gnueabihf/README.md b/tooling/cli/node/npm/linux-arm-gnueabihf/README.md new file mode 100644 index 000000000000..28eabad07ff2 --- /dev/null +++ b/tooling/cli/node/npm/linux-arm-gnueabihf/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-linux-arm-gnueabihf` + +This is the **armv7-unknown-linux-gnueabihf** binary for `@tauri-apps/cli` diff --git a/tooling/cli/node/npm/linux-arm-gnueabihf/package.json b/tooling/cli/node/npm/linux-arm-gnueabihf/package.json new file mode 100644 index 000000000000..0e34825528b4 --- /dev/null +++ b/tooling/cli/node/npm/linux-arm-gnueabihf/package.json @@ -0,0 +1,21 @@ +{ + "name": "@tauri-apps/cli-linux-arm-gnueabihf", + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "os": [ + "linux" + ], + "cpu": [ + "arm" + ], + "main": "cli.linux-arm-gnueabihf.node", + "files": [ + "cli.linux-arm-gnueabihf.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/tooling/cli/node/npm/linux-arm64-gnu/README.md b/tooling/cli/node/npm/linux-arm64-gnu/README.md new file mode 100644 index 000000000000..7cb17b836646 --- /dev/null +++ b/tooling/cli/node/npm/linux-arm64-gnu/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-linux-arm64-gnu` + +This is the **aarch64-unknown-linux-gnu** binary for `@tauri-apps/cli` diff --git a/tooling/cli/node/npm/linux-arm64-gnu/package.json b/tooling/cli/node/npm/linux-arm64-gnu/package.json new file mode 100644 index 000000000000..28790ab76177 --- /dev/null +++ b/tooling/cli/node/npm/linux-arm64-gnu/package.json @@ -0,0 +1,21 @@ +{ + "name": "@tauri-apps/cli-linux-arm64-gnu", + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "os": [ + "linux" + ], + "cpu": [ + "arm64" + ], + "main": "cli.linux-arm64-gnu.node", + "files": [ + "cli.linux-arm64-gnu.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/tooling/cli/node/npm/linux-arm64-musl/README.md b/tooling/cli/node/npm/linux-arm64-musl/README.md new file mode 100644 index 000000000000..fc83b51ceae4 --- /dev/null +++ b/tooling/cli/node/npm/linux-arm64-musl/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-linux-arm64-musl` + +This is the **aarch64-unknown-linux-musl** binary for `@tauri-apps/cli` diff --git a/tooling/cli/node/npm/linux-arm64-musl/package.json b/tooling/cli/node/npm/linux-arm64-musl/package.json new file mode 100644 index 000000000000..4ff96ff8e7ef --- /dev/null +++ b/tooling/cli/node/npm/linux-arm64-musl/package.json @@ -0,0 +1,21 @@ +{ + "name": "@tauri-apps/cli-linux-arm64-musl", + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "os": [ + "linux" + ], + "cpu": [ + "arm64" + ], + "main": "cli.linux-arm64-musl.node", + "files": [ + "cli.linux-arm64-musl.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/tooling/cli/node/npm/linux-x64-gnu/README.md b/tooling/cli/node/npm/linux-x64-gnu/README.md new file mode 100644 index 000000000000..38e990a52dd7 --- /dev/null +++ b/tooling/cli/node/npm/linux-x64-gnu/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-linux-x64-gnu` + +This is the **x86_64-unknown-linux-gnu** binary for `@tauri-apps/cli` diff --git a/tooling/cli/node/npm/linux-x64-gnu/package.json b/tooling/cli/node/npm/linux-x64-gnu/package.json new file mode 100644 index 000000000000..18ed37403b4a --- /dev/null +++ b/tooling/cli/node/npm/linux-x64-gnu/package.json @@ -0,0 +1,21 @@ +{ + "name": "@tauri-apps/cli-linux-x64-gnu", + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "main": "cli.linux-x64-gnu.node", + "files": [ + "cli.linux-x64-gnu.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/tooling/cli/node/npm/linux-x64-musl/README.md b/tooling/cli/node/npm/linux-x64-musl/README.md new file mode 100644 index 000000000000..a987fb53c0e5 --- /dev/null +++ b/tooling/cli/node/npm/linux-x64-musl/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-linux-x64-musl` + +This is the **x86_64-unknown-linux-musl** binary for `@tauri-apps/cli` diff --git a/tooling/cli/node/npm/linux-x64-musl/package.json b/tooling/cli/node/npm/linux-x64-musl/package.json new file mode 100644 index 000000000000..74d55d0fe6e4 --- /dev/null +++ b/tooling/cli/node/npm/linux-x64-musl/package.json @@ -0,0 +1,21 @@ +{ + "name": "@tauri-apps/cli-linux-x64-musl", + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "main": "cli.linux-x64-musl.node", + "files": [ + "cli.linux-x64-musl.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/tooling/cli/node/npm/win32-x64-msvc/README.md b/tooling/cli/node/npm/win32-x64-msvc/README.md new file mode 100644 index 000000000000..c22490ba757c --- /dev/null +++ b/tooling/cli/node/npm/win32-x64-msvc/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-win32-x64-msvc` + +This is the **x86_64-pc-windows-msvc** binary for `@tauri-apps/cli` diff --git a/tooling/cli/node/npm/win32-x64-msvc/package.json b/tooling/cli/node/npm/win32-x64-msvc/package.json new file mode 100644 index 000000000000..b1e5d30c1584 --- /dev/null +++ b/tooling/cli/node/npm/win32-x64-msvc/package.json @@ -0,0 +1,21 @@ +{ + "name": "@tauri-apps/cli-win32-x64-msvc", + "version": "0.0.0", + "publishConfig": { + "access": "public" + }, + "os": [ + "win32" + ], + "cpu": [ + "x64" + ], + "main": "cli.win32-x64-msvc.node", + "files": [ + "cli.win32-x64-msvc.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + } +} diff --git a/tooling/cli/node/package.json b/tooling/cli/node/package.json new file mode 100644 index 000000000000..3333c69191db --- /dev/null +++ b/tooling/cli/node/package.json @@ -0,0 +1,63 @@ +{ + "name": "@tauri-apps/cli", + "version": "1.0.0-beta.10", + "description": "Command line interface for building Tauri apps", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tauri-apps/tauri.git" + }, + "contributors": [ + "Tauri Team (https://tauri.studio)" + ], + "license": "Apache-2.0 OR MIT", + "bugs": { + "url": "https://github.com/tauri-apps/tauri/issues" + }, + "homepage": "https://github.com/tauri-apps/tauri#readme", + "publishConfig": { + "access": "public" + }, + "main": "index.js", + "types": "index.d.ts", + "napi": { + "name": "cli", + "triples": { + "additional": [ + "aarch64-apple-darwin", + "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", + "armv7-unknown-linux-gnueabihf", + "x86_64-unknown-linux-musl" + ] + } + }, + "devDependencies": { + "@napi-rs/cli": "2.4.2", + "cross-spawn": "7.0.3", + "fs-extra": "10.0.0", + "jest": "27.5.1", + "jest-transform-toml": "1.0.0", + "prettier": "2.5.1" + }, + "engines": { + "node": ">= 10" + }, + "bin": { + "tauri": "./tauri.js" + }, + "scripts": { + "artifacts": "napi artifacts", + "build": "napi build --platform --release", + "build:debug": "napi build --platform", + "prepublishOnly": "napi prepublish -t npm", + "test": "jest --runInBand --forceExit --no-cache", + "version": "napi version", + "tauri": "node ./tauri.js", + "format": "prettier --write ./package.json ./tauri.js", + "format:check": "prettier --check ./package.json ./tauri.js" + } +} diff --git a/tooling/cli/node/src/lib.rs b/tooling/cli/node/src/lib.rs new file mode 100644 index 000000000000..d328061ec2a1 --- /dev/null +++ b/tooling/cli/node/src/lib.rs @@ -0,0 +1,10 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use napi::{Error, Result, Status}; + +#[napi_derive::napi] +pub fn run(args: Vec, bin_name: Option) -> Result<()> { + tauri_cli::run(args, bin_name).map_err(|e| Error::new(Status::GenericFailure, e.to_string())) +} diff --git a/tooling/cli/node/tauri.js b/tooling/cli/node/tauri.js new file mode 100755 index 000000000000..30d59a4d9a55 --- /dev/null +++ b/tooling/cli/node/tauri.js @@ -0,0 +1,50 @@ +#!/usr/bin/env node + +const cli = require('./index') +const path = require('path') + +const [bin, script, ...arguments] = process.argv +const binStem = path.parse(bin).name.toLowerCase() + +// We want to make a helpful binary name for the underlying CLI helper, if we +// can successfully detect what command likely started the execution. +let binName + +// Even if started by a package manager, the binary will be NodeJS. +// Some distribution still use "nodejs" as the binary name. +if (binStem === 'node' || binStem === 'nodejs') { + const managerStem = process.env.npm_execpath + ? path.parse(process.env.npm_execpath).name.toLowerCase() + : null + if (managerStem) { + let manager + switch (managerStem) { + // Only supported package manager that has a different filename is npm. + case 'npm-cli': + manager = 'npm' + break + + // Yarn and pnpm have the same stem name as their bin. + // We assume all unknown package managers do as well. + default: + manager = managerStem + break + } + + binName = `${manager} run ${process.env.npm_lifecycle_event}` + } else { + // Assume running NodeJS if we didn't detect a manager from the env. + // We normalize the path to prevent the script's absolute path being used. + const scriptNormal = path.normalize(path.relative(process.cwd(), script)) + binName = `${binStem} ${scriptNormal}` + } +} else { + // We don't know what started it, assume it's already stripped. + arguments.unshift(bin) +} + +try { + cli.run(arguments, binName) +} catch (e) { + console.log(`Eror running CLI: ${e.message}`) +} diff --git a/tooling/cli/node/test/jest/__tests__/template.spec.js b/tooling/cli/node/test/jest/__tests__/template.spec.js new file mode 100644 index 000000000000..8725d5650d4a --- /dev/null +++ b/tooling/cli/node/test/jest/__tests__/template.spec.js @@ -0,0 +1,41 @@ +const fixtureSetup = require('../fixtures/app-test-setup.js') +const { resolve } = require('path') +const { existsSync, readFileSync, writeFileSync } = require('fs') +const { move } = require('fs-extra') +const cli = require('~/index.js') + +const currentDirName = __dirname + +describe('[CLI] cli.js template', () => { + it('init a project and builds it', async () => { + const cwd = process.cwd() + const fixturePath = resolve(currentDirName, '../fixtures/empty') + const tauriFixturePath = resolve(fixturePath, 'src-tauri') + const outPath = resolve(tauriFixturePath, 'target') + const cacheOutPath = resolve(fixturePath, 'target') + + fixtureSetup.initJest('empty') + + process.chdir(fixturePath) + + const outExists = existsSync(outPath) + if (outExists) { + await move(outPath, cacheOutPath) + } + + cli.run(['init', '--directory', process.cwd(), '--force', '--tauri-path', resolve(currentDirName, '../../../../../..'), '--ci']) + + if (outExists) { + await move(cacheOutPath, outPath) + } + + process.chdir(tauriFixturePath) + + const manifestPath = resolve(tauriFixturePath, 'Cargo.toml') + const manifestFile = readFileSync(manifestPath).toString() + writeFileSync(manifestPath, `workspace = { }\n${manifestFile}`) + + cli.run(['build', '--verbose']) + process.chdir(cwd) + }) +}) diff --git a/tooling/cli.js/test/jest/fixtures/app-test-setup.js b/tooling/cli/node/test/jest/fixtures/app-test-setup.js similarity index 85% rename from tooling/cli.js/test/jest/fixtures/app-test-setup.js rename to tooling/cli/node/test/jest/fixtures/app-test-setup.js index e3effafc04e1..410ad3637573 100644 --- a/tooling/cli.js/test/jest/fixtures/app-test-setup.js +++ b/tooling/cli/node/test/jest/fixtures/app-test-setup.js @@ -1,21 +1,19 @@ -import { jest } from '@jest/globals' -import path from 'path' -import http from 'http' -import { fileURLToPath } from 'url' +const path = require('path') +const http = require('http') -const currentDirName = path.dirname(fileURLToPath(import.meta.url)) +const currentDirName = __dirname const mockFixtureDir = path.resolve(currentDirName, '../fixtures') -export const fixtureDir = mockFixtureDir +module.exports.fixtureDir = mockFixtureDir -export const initJest = (mockFixture) => { +module.exports.initJest = (mockFixture) => { jest.setTimeout(1200000) const mockAppDir = path.join(mockFixtureDir, mockFixture) process.env.__TAURI_TEST_APP_DIR = mockAppDir } -export const startServer = (onSuccess) => { +module.exports.startServer = (onSuccess) => { const responses = { writeFile: null, readFile: null, diff --git a/tooling/cli.js/test/jest/fixtures/app/dist/index.html b/tooling/cli/node/test/jest/fixtures/app/dist/index.html similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/dist/index.html rename to tooling/cli/node/test/jest/fixtures/app/dist/index.html diff --git a/tooling/cli.js/test/jest/fixtures/app/index.js b/tooling/cli/node/test/jest/fixtures/app/index.js similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/index.js rename to tooling/cli/node/test/jest/fixtures/app/index.js diff --git a/tooling/cli.js/test/jest/fixtures/app/package.json b/tooling/cli/node/test/jest/fixtures/app/package.json similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/package.json rename to tooling/cli/node/test/jest/fixtures/app/package.json diff --git a/tooling/cli/node/test/jest/fixtures/app/src-tauri/.gitignore b/tooling/cli/node/test/jest/fixtures/app/src-tauri/.gitignore new file mode 100644 index 000000000000..1301e7dd34a7 --- /dev/null +++ b/tooling/cli/node/test/jest/fixtures/app/src-tauri/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock diff --git a/tooling/cli/node/test/jest/fixtures/app/src-tauri/Cargo.toml b/tooling/cli/node/test/jest/fixtures/app/src-tauri/Cargo.toml new file mode 100644 index 000000000000..25afa7c0ca43 --- /dev/null +++ b/tooling/cli/node/test/jest/fixtures/app/src-tauri/Cargo.toml @@ -0,0 +1,34 @@ +workspace = { } + +[package] +name = "app" +version = "0.1.0" +description = "A Tauri App" +authors = [ "Tauri Programme within The Commons Conservancy" ] +license = "" +repository = "" +edition = "2021" +rust-version = "1.57" + +[package.metadata.bundle] +identifier = "com.tauri.dev" +icon = [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" +] + +[build-dependencies] +tauri-build = { path = "../../../../../../../core/tauri-build", features = [] } + +[dependencies] +serde_json = "1.0.74" +serde = "1.0" +serde_derive = "1.0" +tauri = { path = "../../../../../../../core/tauri", features = ["api-all"] } + +[features] +default = [ "custom-protocol" ] +custom-protocol = [ "tauri/custom-protocol" ] diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/build.rs b/tooling/cli/node/test/jest/fixtures/app/src-tauri/build.rs similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/build.rs rename to tooling/cli/node/test/jest/fixtures/app/src-tauri/build.rs diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/128x128.png b/tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/128x128.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/128x128.png rename to tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/128x128.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/128x128@2x.png b/tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/128x128@2x.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/128x128@2x.png rename to tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/128x128@2x.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/32x32.png b/tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/32x32.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/32x32.png rename to tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/32x32.png diff --git a/tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/icon.icns b/tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/icon.icns new file mode 100644 index 000000000000..8254645a797e Binary files /dev/null and b/tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/icon.icns differ diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/icon.ico b/tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/icon.ico similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/icon.ico rename to tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/icon.ico diff --git a/examples/api/public/icon.png b/tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/icon.png similarity index 100% rename from examples/api/public/icon.png rename to tooling/cli/node/test/jest/fixtures/app/src-tauri/icons/icon.png diff --git a/tooling/cli/node/test/jest/fixtures/app/src-tauri/rustfmt.toml b/tooling/cli/node/test/jest/fixtures/app/src-tauri/rustfmt.toml new file mode 100644 index 000000000000..550a09853f31 --- /dev/null +++ b/tooling/cli/node/test/jest/fixtures/app/src-tauri/rustfmt.toml @@ -0,0 +1,14 @@ +max_width = 100 +hard_tabs = false +tab_spaces = 2 +newline_style = "Auto" +use_small_heuristics = "Default" +reorder_imports = true +reorder_modules = true +remove_nested_parens = true +edition = "2021" +merge_derives = true +use_try_shorthand = false +use_field_init_shorthand = false +force_explicit_abi = true +imports_granularity = "Crate" diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/src/main.rs b/tooling/cli/node/test/jest/fixtures/app/src-tauri/src/main.rs similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/src/main.rs rename to tooling/cli/node/test/jest/fixtures/app/src-tauri/src/main.rs diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/tauri.conf.json b/tooling/cli/node/test/jest/fixtures/app/src-tauri/tauri.conf.json similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/tauri.conf.json rename to tooling/cli/node/test/jest/fixtures/app/src-tauri/tauri.conf.json diff --git a/tooling/cli.js/test/jest/fixtures/empty/.gitignore b/tooling/cli/node/test/jest/fixtures/empty/.gitignore similarity index 100% rename from tooling/cli.js/test/jest/fixtures/empty/.gitignore rename to tooling/cli/node/test/jest/fixtures/empty/.gitignore diff --git a/tooling/cli.js/test/jest/fixtures/empty/dist/index.html b/tooling/cli/node/test/jest/fixtures/empty/dist/index.html similarity index 100% rename from tooling/cli.js/test/jest/fixtures/empty/dist/index.html rename to tooling/cli/node/test/jest/fixtures/empty/dist/index.html diff --git a/tooling/cli.js/test/jest/fixtures/empty/package.json b/tooling/cli/node/test/jest/fixtures/empty/package.json similarity index 100% rename from tooling/cli.js/test/jest/fixtures/empty/package.json rename to tooling/cli/node/test/jest/fixtures/empty/package.json diff --git a/tooling/cli/node/test/jest/helpers/logger.js b/tooling/cli/node/test/jest/helpers/logger.js new file mode 100644 index 000000000000..0115020135ba --- /dev/null +++ b/tooling/cli/node/test/jest/helpers/logger.js @@ -0,0 +1,25 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +const ms = require('ms') + +let prevTime + +module.exports = (banner) => { + return (msg) => { + const curr = +new Date() + const diff = curr - (prevTime || curr) + + prevTime = curr + + if (msg) { + console.log( + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-call + ` ${String(banner)} ${msg} ${`+${ms(diff)}`}` + ) + } else { + console.log() + } + } +} diff --git a/tooling/cli/node/test/jest/helpers/spawn.js b/tooling/cli/node/test/jest/helpers/spawn.js new file mode 100644 index 000000000000..1cbaff3b5d8e --- /dev/null +++ b/tooling/cli/node/test/jest/helpers/spawn.js @@ -0,0 +1,73 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +const crossSpawn = require('cross-spawn') +const logger = require('./logger') + +const log = logger('app:spawn') +const warn = logger('app:spawn') + +/* + Returns pid, takes onClose + */ +module.exports.spawn = ( + cmd, + params, + cwd, + onClose +) => { + log(`Running "${cmd} ${params.join(' ')}"`) + log() + + // TODO: move to execa? + const runner = crossSpawn(cmd, params, { + stdio: 'inherit', + cwd, + env: process.env + }) + + runner.on('close', (code) => { + log() + if (code) { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + log(`Command "${cmd}" failed with exit code: ${code}`) + } + + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain + onClose && onClose(code || 0, runner.pid || 0) + }) + + return runner.pid || 0 +} + +/* + Returns nothing, takes onFail + */ +module.exports.spawnSync = ( + cmd, + params, + cwd, + onFail +) => { + log(`[sync] Running "${cmd} ${params.join(' ')}"`) + log() + + const runner = crossSpawn.sync(cmd, params, { + stdio: 'inherit', + cwd + }) + + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + if (runner.status || runner.error) { + warn() + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + warn(`⚠️ Command "${cmd}" failed with exit code: ${runner.status}`) + if (runner.status === null) { + warn(`⚠️ Please globally install "${cmd}"`) + } + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain + onFail && onFail() + process.exit(1) + } +} diff --git a/tooling/cli/node/test/jest/jest.setup.js b/tooling/cli/node/test/jest/jest.setup.js new file mode 100644 index 000000000000..a9bb1fd2a636 --- /dev/null +++ b/tooling/cli/node/test/jest/jest.setup.js @@ -0,0 +1,6 @@ +// 30 minute timeout: 20 minutes wasn't always enough for compilation in GitHub Actions. +jest.setTimeout(1800000) + +setTimeout(() => { + // do nothing +}, 1) diff --git a/tooling/cli/node/yarn.lock b/tooling/cli/node/yarn.lock new file mode 100644 index 000000000000..d698ef1e4bce --- /dev/null +++ b/tooling/cli/node/yarn.lock @@ -0,0 +1,2585 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.0.tgz#72becdf17ee44b2d1ac5651fb12f1952c336fe23" + integrity sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/compat-data@^7.16.4": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" + integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== + +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.2.tgz#2c77fc430e95139d816d39b113b31bf40fb22337" + integrity sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw== + dependencies: + "@ampproject/remapping" "^2.0.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.0" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helpers" "^7.17.2" + "@babel/parser" "^7.17.0" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + +"@babel/generator@^7.17.0", "@babel/generator@^7.7.2": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" + integrity sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-compilation-targets@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-transforms@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" + integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== + +"@babel/helper-simple-access@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" + integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + +"@babel/helpers@^7.17.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" + integrity sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" + +"@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" + integrity sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" + integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/template@^7.16.7", "@babel/template@^7.3.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/traverse@^7.16.7", "@babel/traverse@^7.17.0", "@babel/traverse@^7.7.2": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" + integrity sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.0" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.0" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + +"@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== + dependencies: + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== + dependencies: + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" + +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.9" + source-map "^0.6.0" + +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== + dependencies: + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== + dependencies: + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" + +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz#b876e3feefb9c8d3aa84014da28b5e52a0640d72" + integrity sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.10" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz#baf57b4e2a690d4f38560171f91783656b7f8186" + integrity sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@napi-rs/cli@2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@napi-rs/cli/-/cli-2.4.2.tgz#89b32c7d8776004bc9617915605aea769339cf6f" + integrity sha512-+yCOuPqernvD8BMphbadF87ElaJ0rjanOZrbnauaEdR07YyoalGw3FTk15HHyflIwQKlYd69gkG5EM4WFkICKw== + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.18" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.18.tgz#1a29abcc411a9c05e2094c98f9a1b7da6cdf49f8" + integrity sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + dependencies: + "@babel/types" "^7.3.0" + +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/node@*": + version "17.0.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.16.tgz#e3733f46797b9df9e853ca9f719c8a6f7b84cd26" + integrity sha512-ydLaGVfQOQ6hI1xK2A5nVh8bl0OGoIfYMxPWHqqYe9bTkWCfqiVvZoh2I/QF2sNSkZzZyROBoTefIEI+PB6iIA== + +"@types/prettier@^2.1.5": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" + integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== + +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "20.2.1" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" + integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== + +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.2.4: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== + dependencies: + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browserslist@^4.17.5: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001286: + version "1.0.30001310" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001310.tgz#da02cd07432c9eece6992689d1b84ca18139eea8" + integrity sha512-cb9xTV8k9HTIUA3GnPUJCk0meUnrHL5gy5QePfDjxHyNBcnzPzrHFv5GqfP7ue5b1ZyzZL0RJboD6hQlPXjhjg== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cross-spawn@7.0.3, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + +debug@4, debug@^4.1.0, debug@^4.1.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== + +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + +electron-to-chromium@^1.4.17: + version "1.4.68" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz#d79447b6bd1bec9183f166bb33d4bef0d5e4e568" + integrity sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA== + +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== + dependencies: + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +fs-extra@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" + integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== + dependencies: + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + prompts "^2.0.1" + yargs "^16.2.0" + +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== + dependencies: + detect-newline "^3.0.0" + +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" + +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== + dependencies: + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== + dependencies: + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== + +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== + dependencies: + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" + +jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + source-map-support "^0.5.6" + throat "^6.0.1" + +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + natural-compare "^1.4.0" + pretty-format "^27.5.1" + semver "^7.3.2" + +jest-transform-toml@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jest-transform-toml/-/jest-transform-toml-1.0.0.tgz#0a255066d4e59620ec3c3cc5a555321bb05f153d" + integrity sha1-CiVQZtTlliDsPDzFpVUyG7BfFT0= + dependencies: + toml-loader "^1.0.0" + +jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" + leven "^3.1.0" + pretty-format "^27.5.1" + +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== + dependencies: + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" + +jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== + dependencies: + "@jest/core" "^27.5.1" + import-local "^3.0.2" + jest-cli "^27.5.1" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.6" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@^2.1.12: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@^3.0.4: + version "3.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" + integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-releases@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== + +pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + +resolve@^1.20.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.2: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-support@^0.5.6: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toml-loader@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toml-loader/-/toml-loader-1.0.0.tgz#05249b9294b623601148260caa480b22a653a19a" + integrity sha1-BSSbkpS2I2ARSCYMqkgLIqZToZo= + dependencies: + toml "^2.2.2" + +toml@^2.2.2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.6.tgz#25b0866483a9722474895559088b436fd11f861b" + integrity sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ== + +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + +walker@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.4.6: + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" diff --git a/tooling/cli/schema.json b/tooling/cli/schema.json new file mode 100644 index 000000000000..5ad8acac53e9 --- /dev/null +++ b/tooling/cli/schema.json @@ -0,0 +1,2201 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "description": "The config type mapped to `tauri.conf.json`.", + "type": "object", + "properties": { + "build": { + "description": "The build configuration.", + "default": { + "devPath": "http://localhost:8080/", + "distDir": "../dist", + "withGlobalTauri": false + }, + "allOf": [ + { + "$ref": "#/definitions/BuildConfig" + } + ] + }, + "package": { + "description": "Package settings.", + "default": { + "productName": null, + "version": null + }, + "allOf": [ + { + "$ref": "#/definitions/PackageConfig" + } + ] + }, + "plugins": { + "description": "The plugins config.", + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/PluginConfig" + } + ] + }, + "tauri": { + "description": "The Tauri configuration.", + "default": { + "allowlist": { + "all": false, + "clipboard": { + "all": false, + "readText": false, + "writeText": false + }, + "dialog": { + "all": false, + "ask": false, + "confirm": false, + "message": false, + "open": false, + "save": false + }, + "fs": { + "all": false, + "copyFile": false, + "createDir": false, + "readDir": false, + "readFile": false, + "removeDir": false, + "removeFile": false, + "renameFile": false, + "scope": [], + "writeFile": false + }, + "globalShortcut": { + "all": false + }, + "http": { + "all": false, + "request": false, + "scope": [] + }, + "notification": { + "all": false + }, + "os": { + "all": false + }, + "path": { + "all": false + }, + "process": { + "all": false, + "exit": false, + "relaunch": false, + "relaunchDangerousAllowSymlinkMacos": false + }, + "protocol": { + "all": false, + "asset": false, + "assetScope": [] + }, + "shell": { + "all": false, + "execute": false, + "open": false, + "scope": [], + "sidecar": false + }, + "window": { + "all": false, + "center": false, + "close": false, + "create": false, + "hide": false, + "maximize": false, + "minimize": false, + "print": false, + "requestUserAttention": false, + "setAlwaysOnTop": false, + "setDecorations": false, + "setFocus": false, + "setFullscreen": false, + "setIcon": false, + "setMaxSize": false, + "setMinSize": false, + "setPosition": false, + "setResizable": false, + "setSize": false, + "setSkipTaskbar": false, + "setTitle": false, + "show": false, + "startDragging": false, + "unmaximize": false, + "unminimize": false + } + }, + "bundle": { + "active": false, + "deb": { + "files": {}, + "useBootstrapper": false + }, + "icon": [], + "identifier": "", + "macOS": { + "useBootstrapper": false + }, + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": null, + "timestampUrl": null, + "webviewFixedRuntimePath": null, + "wix": null + } + }, + "macOSPrivateApi": false, + "pattern": { + "use": "brownfield" + }, + "security": { + "freezePrototype": true + }, + "updater": { + "active": false, + "dialog": true, + "pubkey": "" + }, + "windows": [ + { + "alwaysOnTop": false, + "center": false, + "decorations": true, + "fileDropEnabled": true, + "focus": false, + "fullscreen": false, + "height": 600.0, + "label": "main", + "maximized": false, + "resizable": true, + "skipTaskbar": false, + "title": "Tauri App", + "transparent": false, + "url": "index.html", + "visible": true, + "width": 800.0 + } + ] + }, + "allOf": [ + { + "$ref": "#/definitions/TauriConfig" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "AllowlistConfig": { + "description": "Allowlist configuration.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all API features.", + "default": false, + "type": "boolean" + }, + "clipboard": { + "description": "Clipboard APIs allowlist.", + "default": { + "all": false, + "readText": false, + "writeText": false + }, + "allOf": [ + { + "$ref": "#/definitions/ClipboardAllowlistConfig" + } + ] + }, + "dialog": { + "description": "Dialog API allowlist.", + "default": { + "all": false, + "ask": false, + "confirm": false, + "message": false, + "open": false, + "save": false + }, + "allOf": [ + { + "$ref": "#/definitions/DialogAllowlistConfig" + } + ] + }, + "fs": { + "description": "File system API allowlist.", + "default": { + "all": false, + "copyFile": false, + "createDir": false, + "readDir": false, + "readFile": false, + "removeDir": false, + "removeFile": false, + "renameFile": false, + "scope": [], + "writeFile": false + }, + "allOf": [ + { + "$ref": "#/definitions/FsAllowlistConfig" + } + ] + }, + "globalShortcut": { + "description": "Global shortcut API allowlist.", + "default": { + "all": false + }, + "allOf": [ + { + "$ref": "#/definitions/GlobalShortcutAllowlistConfig" + } + ] + }, + "http": { + "description": "HTTP API allowlist.", + "default": { + "all": false, + "request": false, + "scope": [] + }, + "allOf": [ + { + "$ref": "#/definitions/HttpAllowlistConfig" + } + ] + }, + "notification": { + "description": "Notification API allowlist.", + "default": { + "all": false + }, + "allOf": [ + { + "$ref": "#/definitions/NotificationAllowlistConfig" + } + ] + }, + "os": { + "description": "OS allowlist.", + "default": { + "all": false + }, + "allOf": [ + { + "$ref": "#/definitions/OsAllowlistConfig" + } + ] + }, + "path": { + "description": "Path API allowlist.", + "default": { + "all": false + }, + "allOf": [ + { + "$ref": "#/definitions/PathAllowlistConfig" + } + ] + }, + "process": { + "description": "Process API allowlist.", + "default": { + "all": false, + "exit": false, + "relaunch": false, + "relaunchDangerousAllowSymlinkMacos": false + }, + "allOf": [ + { + "$ref": "#/definitions/ProcessAllowlistConfig" + } + ] + }, + "protocol": { + "description": "Custom protocol allowlist.", + "default": { + "all": false, + "asset": false, + "assetScope": [] + }, + "allOf": [ + { + "$ref": "#/definitions/ProtocolAllowlistConfig" + } + ] + }, + "shell": { + "description": "Shell API allowlist.", + "default": { + "all": false, + "execute": false, + "open": false, + "scope": [], + "sidecar": false + }, + "allOf": [ + { + "$ref": "#/definitions/ShellAllowlistConfig" + } + ] + }, + "window": { + "description": "Window API allowlist.", + "default": { + "all": false, + "center": false, + "close": false, + "create": false, + "hide": false, + "maximize": false, + "minimize": false, + "print": false, + "requestUserAttention": false, + "setAlwaysOnTop": false, + "setDecorations": false, + "setFocus": false, + "setFullscreen": false, + "setIcon": false, + "setMaxSize": false, + "setMinSize": false, + "setPosition": false, + "setResizable": false, + "setSize": false, + "setSkipTaskbar": false, + "setTitle": false, + "show": false, + "startDragging": false, + "unmaximize": false, + "unminimize": false + }, + "allOf": [ + { + "$ref": "#/definitions/WindowAllowlistConfig" + } + ] + } + }, + "additionalProperties": false + }, + "AppUrl": { + "description": "The `dev_path` and `dist_dir` options.", + "anyOf": [ + { + "description": "The app's external URL, or the path to the directory containing the app assets.", + "allOf": [ + { + "$ref": "#/definitions/WindowUrl" + } + ] + }, + { + "description": "An array of files to embed on the app.", + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "BuildConfig": { + "description": "The Build configuration object.", + "type": "object", + "properties": { + "beforeBuildCommand": { + "description": "A shell command to run before `tauri build` kicks in.\n\nThe TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation.", + "type": [ + "string", + "null" + ] + }, + "beforeDevCommand": { + "description": "A shell command to run before `tauri dev` kicks in.\n\nThe TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG environment variables are set if you perform conditional compilation.", + "type": [ + "string", + "null" + ] + }, + "devPath": { + "description": "The path or URL to use on development.", + "default": "http://localhost:8080/", + "allOf": [ + { + "$ref": "#/definitions/AppUrl" + } + ] + }, + "distDir": { + "description": "The path to the app's dist dir. This path must contain your index.html file.", + "default": "../dist", + "allOf": [ + { + "$ref": "#/definitions/AppUrl" + } + ] + }, + "features": { + "description": "Features passed to `cargo` commands.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "runner": { + "description": "The binary used to build and run the application.", + "type": [ + "string", + "null" + ] + }, + "withGlobalTauri": { + "description": "Whether we should inject the Tauri API on `window.__TAURI__` or not.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "BundleConfig": { + "description": "Configuration for tauri-bundler.", + "type": "object", + "required": [ + "identifier" + ], + "properties": { + "active": { + "description": "Whether we should build your app with tauri-bundler or plain `cargo build`", + "default": false, + "type": "boolean" + }, + "category": { + "description": "The application kind.", + "type": [ + "string", + "null" + ] + }, + "copyright": { + "description": "A copyright string associated with your application.", + "type": [ + "string", + "null" + ] + }, + "deb": { + "description": "Configuration for the Debian bundle.", + "default": { + "files": {}, + "useBootstrapper": false + }, + "allOf": [ + { + "$ref": "#/definitions/DebConfig" + } + ] + }, + "externalBin": { + "description": "A list of—either absolute or relative—paths to binaries to embed with your application.\n\nNote that Tauri will look for system-specific binaries following the pattern \"binary-name{-target-triple}{.system-extension}\".\n\nE.g. for the external binary \"my-binary\", Tauri looks for:\n\n- \"my-binary-x86_64-pc-windows-msvc.exe\" for Windows - \"my-binary-x86_64-apple-darwin\" for macOS - \"my-binary-x86_64-unknown-linux-gnu\" for Linux\n\nso don't forget to provide binaries for all targeted platforms.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "icon": { + "description": "The app's icons", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "identifier": { + "description": "The app's identifier", + "type": "string" + }, + "longDescription": { + "description": "A longer, multi-line description of the application.", + "type": [ + "string", + "null" + ] + }, + "macOS": { + "description": "Configuration for the macOS bundles.", + "default": { + "useBootstrapper": false + }, + "allOf": [ + { + "$ref": "#/definitions/MacConfig" + } + ] + }, + "resources": { + "description": "App resources to bundle. Each resource is a path to a file or directory. Glob patterns are supported.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "shortDescription": { + "description": "A short description of your application.", + "type": [ + "string", + "null" + ] + }, + "targets": { + "description": "The bundle targets, currently supports [\"deb\", \"app\", \"msi\", \"appimage\", \"dmg\"] or \"all\"", + "anyOf": [ + { + "$ref": "#/definitions/BundleTarget" + }, + { + "type": "null" + } + ] + }, + "windows": { + "description": "Configuration for the Windows bundle.", + "default": { + "certificateThumbprint": null, + "digestAlgorithm": null, + "timestampUrl": null, + "webviewFixedRuntimePath": null, + "wix": null + }, + "allOf": [ + { + "$ref": "#/definitions/WindowsConfig" + } + ] + } + }, + "additionalProperties": false + }, + "BundleTarget": { + "description": "Targets to bundle.", + "anyOf": [ + { + "description": "A list of bundle targets.", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "A single bundle target.", + "type": "string" + } + ] + }, + "CliArg": { + "description": "A CLI argument definition.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "conflictsWith": { + "description": "Sets a conflicting argument by name i.e. when using this argument, the following argument can't be present and vice versa.", + "type": [ + "string", + "null" + ] + }, + "conflictsWithAll": { + "description": "The same as conflictsWith but allows specifying multiple two-way conflicts per argument.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "description": { + "description": "The argument description which will be shown on the help information. Typically, this is a short (one line) description of the arg.", + "type": [ + "string", + "null" + ] + }, + "index": { + "description": "The positional argument index, starting at 1.\n\nThe index refers to position according to other positional argument. It does not define position in the argument list as a whole. When utilized with multiple=true, only the last positional argument may be defined as multiple (i.e. the one with the highest index).", + "type": [ + "integer", + "null" + ], + "format": "uint", + "minimum": 0.0 + }, + "longDescription": { + "description": "The argument long description which will be shown on the help information. Typically this a more detailed (multi-line) message that describes the argument.", + "type": [ + "string", + "null" + ] + }, + "maxValues": { + "description": "Specifies the maximum number of values are for this argument. For example, if you had a -f argument where you wanted up to 3 'files', you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values.", + "type": [ + "integer", + "null" + ], + "format": "uint", + "minimum": 0.0 + }, + "minValues": { + "description": "Specifies the minimum number of values for this argument. For example, if you had a -f argument where you wanted at least 2 'files', you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values.", + "type": [ + "integer", + "null" + ], + "format": "uint", + "minimum": 0.0 + }, + "multiple": { + "description": "Specifies that the argument may have an unknown number of multiple values. Without any other settings, this argument may appear only once.\n\nFor example, --opt val1 val2 is allowed, but --opt val1 val2 --opt val3 is not.\n\nNOTE: Setting this requires `takes_value` to be set to true.", + "type": [ + "boolean", + "null" + ] + }, + "multipleOccurrences": { + "description": "Specifies that the argument may appear more than once. For flags, this results in the number of occurrences of the flag being recorded. For example -ddd or -d -d -d would count as three occurrences. For options or arguments that take a value, this does not affect how many values they can accept. (i.e. only one at a time is allowed)\n\nFor example, --opt val1 --opt val2 is allowed, but --opt val1 val2 is not.", + "type": [ + "boolean", + "null" + ] + }, + "name": { + "description": "The unique argument name", + "type": "string" + }, + "numberOfValues": { + "description": "Specifies how many values are required to satisfy this argument. For example, if you had a `-f ` argument where you wanted exactly 3 'files' you would set `number_of_values = 3`, and this argument wouldn't be satisfied unless the user provided 3 and only 3 values.\n\n**NOTE:** Does *not* require `multiple_occurrences = true` to be set. Setting `multiple_occurrences = true` would allow `-f -f ` where as *not* setting it would only allow one occurrence of this argument.\n\n**NOTE:** implicitly sets `takes_value = true` and `multiple_values = true`.", + "type": [ + "integer", + "null" + ], + "format": "uint", + "minimum": 0.0 + }, + "possibleValues": { + "description": "Specifies a list of possible values for this argument. At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "requireEquals": { + "description": "Requires that options use the --option=val syntax i.e. an equals between the option and associated value.", + "type": [ + "boolean", + "null" + ] + }, + "required": { + "description": "Sets whether or not the argument is required by default.\n\n- Required by default means it is required, when no other conflicting rules have been evaluated - Conflicting rules take precedence over being required.", + "type": [ + "boolean", + "null" + ] + }, + "requiredIfEq": { + "description": "Allows specifying that an argument is required conditionally with the signature [arg, value] the requirement will only become valid if the `arg`'s value equals `${value}`.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "requiredUnlessPresent": { + "description": "Sets an arg that override this arg's required setting i.e. this arg will be required unless this other argument is present.", + "type": [ + "string", + "null" + ] + }, + "requiredUnlessPresentAll": { + "description": "Sets args that override this arg's required setting i.e. this arg will be required unless all these other arguments are present.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "requiredUnlessPresentAny": { + "description": "Sets args that override this arg's required setting i.e. this arg will be required unless at least one of these other arguments are present.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "requires": { + "description": "Tets an argument by name that is required when this one is present i.e. when using this argument, the following argument must be present.", + "type": [ + "string", + "null" + ] + }, + "requiresAll": { + "description": "Sts multiple arguments by names that are required when this one is present i.e. when using this argument, the following arguments must be present.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "requiresIf": { + "description": "Allows a conditional requirement with the signature [arg, value] the requirement will only become valid if `arg`'s value equals `${value}`.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "short": { + "description": "The short version of the argument, without the preceding -.\n\nNOTE: Any leading - characters will be stripped, and only the first non - character will be used as the short version.", + "type": [ + "string", + "null" + ], + "maxLength": 1, + "minLength": 1 + }, + "takesValue": { + "description": "Specifies that the argument takes a value at run time.\n\nNOTE: values for arguments may be specified in any of the following methods - Using a space such as -o value or --option value - Using an equals and no space such as -o=value or --option=value - Use a short and no space such as -ovalue", + "type": [ + "boolean", + "null" + ] + } + }, + "additionalProperties": false + }, + "CliConfig": { + "description": "describes a CLI configuration", + "type": "object", + "properties": { + "afterHelp": { + "description": "Adds additional help information to be displayed in addition to auto-generated help. This information is displayed after the auto-generated help information. This is often used to describe how to use the arguments, or caveats to be noted.", + "type": [ + "string", + "null" + ] + }, + "args": { + "description": "List of arguments for the command", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/CliArg" + } + }, + "beforeHelp": { + "description": "Adds additional help information to be displayed in addition to auto-generated help. This information is displayed before the auto-generated help information. This is often used for header information.", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "Command description which will be shown on the help information.", + "type": [ + "string", + "null" + ] + }, + "longDescription": { + "description": "Command long description which will be shown on the help information.", + "type": [ + "string", + "null" + ] + }, + "subcommands": { + "description": "List of subcommands of this command", + "type": [ + "object", + "null" + ], + "additionalProperties": { + "$ref": "#/definitions/CliConfig" + } + } + }, + "additionalProperties": false + }, + "ClipboardAllowlistConfig": { + "description": "Allowlist for the clipboard APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all clipboard APIs.", + "default": false, + "type": "boolean" + }, + "readText": { + "description": "Enables the clipboard's `readText` API.", + "default": false, + "type": "boolean" + }, + "writeText": { + "description": "Enables the clipboard's `writeText` API.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "DebConfig": { + "description": "Configuration for Debian (.deb) bundles.", + "type": "object", + "properties": { + "depends": { + "description": "The list of deb dependencies your application relies on.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "files": { + "description": "The files to include on the package.", + "default": {}, + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "useBootstrapper": { + "description": "Enable the boostrapper script.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "DialogAllowlistConfig": { + "description": "Allowlist for the dialog APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all dialog API features.", + "default": false, + "type": "boolean" + }, + "ask": { + "description": "Allows the API to show a dialog window with Yes/No buttons.", + "default": false, + "type": "boolean" + }, + "confirm": { + "description": "Allows the API to show a dialog window with Ok/Cancel buttons.", + "default": false, + "type": "boolean" + }, + "message": { + "description": "Allows the API to show a message dialog window.", + "default": false, + "type": "boolean" + }, + "open": { + "description": "Allows the API to open a dialog window to pick files.", + "default": false, + "type": "boolean" + }, + "save": { + "description": "Allows the API to open a dialog window to pick where to save files.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "FsAllowlistConfig": { + "description": "Allowlist for the file system APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all file system API features.", + "default": false, + "type": "boolean" + }, + "copyFile": { + "description": "Copy file from local filesystem.", + "default": false, + "type": "boolean" + }, + "createDir": { + "description": "Create directory from local filesystem.", + "default": false, + "type": "boolean" + }, + "readDir": { + "description": "Read directory from local filesystem.", + "default": false, + "type": "boolean" + }, + "readFile": { + "description": "Read file from local filesystem.", + "default": false, + "type": "boolean" + }, + "removeDir": { + "description": "Remove directory from local filesystem.", + "default": false, + "type": "boolean" + }, + "removeFile": { + "description": "Remove file from local filesystem.", + "default": false, + "type": "boolean" + }, + "renameFile": { + "description": "Rename file from local filesystem.", + "default": false, + "type": "boolean" + }, + "scope": { + "description": "The access scope for the filesystem APIs.", + "default": [], + "allOf": [ + { + "$ref": "#/definitions/FsAllowlistScope" + } + ] + }, + "writeFile": { + "description": "Write file to local filesystem.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "FsAllowlistScope": { + "description": "Filesystem scope definition. It is a list of glob patterns that restrict the API access from the webview.\n\nEach pattern can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$CWD`.", + "type": "array", + "items": { + "type": "string" + } + }, + "GlobalShortcutAllowlistConfig": { + "description": "Allowlist for the global shortcut APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all global shortcut API features.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "HttpAllowlistConfig": { + "description": "Allowlist for the HTTP APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all HTTP API features.", + "default": false, + "type": "boolean" + }, + "request": { + "description": "Allows making HTTP requests.", + "default": false, + "type": "boolean" + }, + "scope": { + "description": "The access scope for the HTTP APIs.", + "default": [], + "allOf": [ + { + "$ref": "#/definitions/HttpAllowlistScope" + } + ] + } + }, + "additionalProperties": false + }, + "HttpAllowlistScope": { + "description": "HTTP API scope definition. It is a list of URLs that can be accessed by the webview when using the HTTP APIs. The URL path is matched against the request URL using a glob pattern.", + "type": "array", + "items": { + "type": "string", + "format": "uri" + } + }, + "MacConfig": { + "description": "Configuration for the macOS bundles.", + "type": "object", + "properties": { + "entitlements": { + "description": "Path to the entitlements file.", + "type": [ + "string", + "null" + ] + }, + "exceptionDomain": { + "description": "Allows your application to communicate with the outside world. It should be a lowercase, without port and protocol domain name.", + "type": [ + "string", + "null" + ] + }, + "frameworks": { + "description": "A list of strings indicating any macOS X frameworks that need to be bundled with the application.\n\nIf a name is used, \".framework\" must be omitted and it will look for standard install locations. You may also use a path to a specific framework.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "license": { + "description": "The path to the license file to add to the DMG bundle.", + "type": [ + "string", + "null" + ] + }, + "minimumSystemVersion": { + "description": "A version string indicating the minimum macOS X version that the bundled application supports.", + "type": [ + "string", + "null" + ] + }, + "providerShortName": { + "description": "Provider short name for notarization.", + "type": [ + "string", + "null" + ] + }, + "signingIdentity": { + "description": "Identity to use for code signing.", + "type": [ + "string", + "null" + ] + }, + "useBootstrapper": { + "description": "Enable the boostrapper script.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "NotificationAllowlistConfig": { + "description": "Allowlist for the notification APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all notification API features.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "OsAllowlistConfig": { + "description": "Allowlist for the OS APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all OS API features.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "PackageConfig": { + "description": "The package configuration.", + "type": "object", + "properties": { + "productName": { + "description": "App name.", + "type": [ + "string", + "null" + ] + }, + "version": { + "description": "App version. It is a semver version number or a path to a `package.json` file contaning the `version` field.", + "default": null, + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "PathAllowlistConfig": { + "description": "Allowlist for the path APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all path API features.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "PatternKind": { + "description": "The application pattern.", + "oneOf": [ + { + "description": "Brownfield pattern.", + "type": "object", + "required": [ + "use" + ], + "properties": { + "use": { + "type": "string", + "enum": [ + "brownfield" + ] + } + } + }, + { + "description": "Isolation pattern. Recommended for security purposes.", + "type": "object", + "required": [ + "options", + "use" + ], + "properties": { + "options": { + "type": "object", + "required": [ + "dir" + ], + "properties": { + "dir": { + "description": "The dir containing the index.html file that contains the secure isolation application.", + "type": "string" + } + } + }, + "use": { + "type": "string", + "enum": [ + "isolation" + ] + } + } + } + ] + }, + "PluginConfig": { + "description": "The plugin configs holds a HashMap mapping a plugin name to its configuration object.", + "type": "object", + "additionalProperties": true + }, + "ProcessAllowlistConfig": { + "description": "Allowlist for the process APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all process APIs.", + "default": false, + "type": "boolean" + }, + "exit": { + "description": "Enables the exit API.", + "default": false, + "type": "boolean" + }, + "relaunch": { + "description": "Enables the relaunch API.", + "default": false, + "type": "boolean" + }, + "relaunchDangerousAllowSymlinkMacos": { + "description": "Dangerous option that allows macOS to relaunch even if the binary contains a symlink.\n\nThis is due to macOS having less symlink protection. Highly recommended to not set this flag unless you have a very specific reason too, and understand the implications of it.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "ProtocolAllowlistConfig": { + "description": "Allowlist for the custom protocols.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all custom protocols.", + "default": false, + "type": "boolean" + }, + "asset": { + "description": "Enables the asset protocol.", + "default": false, + "type": "boolean" + }, + "assetScope": { + "description": "The access scope for the asset protocol.", + "default": [], + "allOf": [ + { + "$ref": "#/definitions/FsAllowlistScope" + } + ] + } + }, + "additionalProperties": false + }, + "SecurityConfig": { + "description": "Security configuration.", + "type": "object", + "properties": { + "csp": { + "description": "The Content Security Policy that will be injected on all HTML files on the built application. If [`dev_csp`](SecurityConfig.dev_csp) is not specified, this value is also injected on dev.\n\nThis is a really important part of the configuration since it helps you ensure your WebView is secured. See .", + "type": [ + "string", + "null" + ] + }, + "devCsp": { + "description": "The Content Security Policy that will be injected on all HTML files on development.\n\nThis is a really important part of the configuration since it helps you ensure your WebView is secured. See .", + "type": [ + "string", + "null" + ] + }, + "freezePrototype": { + "description": "Freeze the `Object.prototype` when using the custom protocol.", + "default": true, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "ShellAllowedArg": { + "description": "A command argument allowed to be executed by the webview API.", + "anyOf": [ + { + "description": "A non-configurable argument that is passed to the command in the order it was specified.", + "type": "string" + }, + { + "description": "A variable that is set while calling the command from the webview API.", + "type": "object", + "properties": { + "validator": { + "description": "[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\n[regex]: https://docs.rs/regex/latest/regex/#syntax", + "default": "", + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ShellAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "anyOf": [ + { + "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", + "type": "boolean" + }, + { + "description": "A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.", + "type": "array", + "items": { + "$ref": "#/definitions/ShellAllowedArg" + } + } + ] + }, + "ShellAllowedCommand": { + "description": "A command allowed to be executed by the webview API.", + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "default": false, + "allOf": [ + { + "$ref": "#/definitions/ShellAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$CWD`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "default": false, + "type": "boolean" + } + } + }, + "ShellAllowlistConfig": { + "description": "Allowlist for the shell APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all shell API features.", + "default": false, + "type": "boolean" + }, + "execute": { + "description": "Enable binary execution.", + "default": false, + "type": "boolean" + }, + "open": { + "description": "Open URL with the user's default application.", + "default": false, + "allOf": [ + { + "$ref": "#/definitions/ShellAllowlistOpen" + } + ] + }, + "scope": { + "description": "Access scope for the binary execution APIs. Sidecars are automatically enabled.", + "default": [], + "allOf": [ + { + "$ref": "#/definitions/ShellAllowlistScope" + } + ] + }, + "sidecar": { + "description": "Enable sidecar execution, allowing the JavaScript layer to spawn a sidecar command, an executable that is shipped with the application. For more information see .", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "ShellAllowlistOpen": { + "description": "Defines the `shell > open` api scope.", + "anyOf": [ + { + "description": "If the shell open API should be enabled.\n\nIf enabled, the default validation regex (`^https?://`) is used.", + "type": "boolean" + }, + { + "description": "Enable the shell open API, with a custom regex that the opened path must match against.\n\nIf using a custom regex to support a non-http(s) schema, care should be used to prevent values that allow flag-like strings to pass validation. e.g. `--enable-debugging`, `-i`, `/R`.", + "type": "string" + } + ] + }, + "ShellAllowlistScope": { + "description": "Shell scope definition. It is a list of command names and associated CLI arguments that restrict the API access from the webview.", + "type": "array", + "items": { + "$ref": "#/definitions/ShellAllowedCommand" + } + }, + "SystemTrayConfig": { + "description": "Configuration for application system tray icon.", + "type": "object", + "required": [ + "iconPath" + ], + "properties": { + "iconAsTemplate": { + "description": "A Boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS.", + "default": false, + "type": "boolean" + }, + "iconPath": { + "description": "Path to the icon to use on the system tray.\n\nIt is forced to be a `.png` file on Linux and macOS, and a `.ico` file on Windows.", + "type": "string" + } + }, + "additionalProperties": false + }, + "TauriConfig": { + "description": "The Tauri configuration object.", + "type": "object", + "properties": { + "allowlist": { + "description": "The allowlist configuration.", + "default": { + "all": false, + "clipboard": { + "all": false, + "readText": false, + "writeText": false + }, + "dialog": { + "all": false, + "ask": false, + "confirm": false, + "message": false, + "open": false, + "save": false + }, + "fs": { + "all": false, + "copyFile": false, + "createDir": false, + "readDir": false, + "readFile": false, + "removeDir": false, + "removeFile": false, + "renameFile": false, + "scope": [], + "writeFile": false + }, + "globalShortcut": { + "all": false + }, + "http": { + "all": false, + "request": false, + "scope": [] + }, + "notification": { + "all": false + }, + "os": { + "all": false + }, + "path": { + "all": false + }, + "process": { + "all": false, + "exit": false, + "relaunch": false, + "relaunchDangerousAllowSymlinkMacos": false + }, + "protocol": { + "all": false, + "asset": false, + "assetScope": [] + }, + "shell": { + "all": false, + "execute": false, + "open": false, + "scope": [], + "sidecar": false + }, + "window": { + "all": false, + "center": false, + "close": false, + "create": false, + "hide": false, + "maximize": false, + "minimize": false, + "print": false, + "requestUserAttention": false, + "setAlwaysOnTop": false, + "setDecorations": false, + "setFocus": false, + "setFullscreen": false, + "setIcon": false, + "setMaxSize": false, + "setMinSize": false, + "setPosition": false, + "setResizable": false, + "setSize": false, + "setSkipTaskbar": false, + "setTitle": false, + "show": false, + "startDragging": false, + "unmaximize": false, + "unminimize": false + } + }, + "allOf": [ + { + "$ref": "#/definitions/AllowlistConfig" + } + ] + }, + "bundle": { + "description": "The bundler configuration.", + "default": { + "active": false, + "deb": { + "files": {}, + "useBootstrapper": false + }, + "icon": [], + "identifier": "", + "macOS": { + "useBootstrapper": false + }, + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": null, + "timestampUrl": null, + "webviewFixedRuntimePath": null, + "wix": null + } + }, + "allOf": [ + { + "$ref": "#/definitions/BundleConfig" + } + ] + }, + "cli": { + "description": "The CLI configuration.", + "anyOf": [ + { + "$ref": "#/definitions/CliConfig" + }, + { + "type": "null" + } + ] + }, + "macOSPrivateApi": { + "description": "MacOS private API configuration. Enables the transparent background API and sets the `fullScreenEnabled` preference to `true`.", + "default": false, + "type": "boolean" + }, + "pattern": { + "description": "The pattern to use.", + "default": { + "use": "brownfield" + }, + "allOf": [ + { + "$ref": "#/definitions/PatternKind" + } + ] + }, + "security": { + "description": "Security configuration.", + "default": { + "freezePrototype": true + }, + "allOf": [ + { + "$ref": "#/definitions/SecurityConfig" + } + ] + }, + "systemTray": { + "description": "Configuration for app system tray.", + "anyOf": [ + { + "$ref": "#/definitions/SystemTrayConfig" + }, + { + "type": "null" + } + ] + }, + "updater": { + "description": "The updater configuration.", + "default": { + "active": false, + "dialog": true, + "pubkey": "" + }, + "allOf": [ + { + "$ref": "#/definitions/UpdaterConfig" + } + ] + }, + "windows": { + "description": "The windows configuration.", + "default": [ + { + "alwaysOnTop": false, + "center": false, + "decorations": true, + "fileDropEnabled": true, + "focus": false, + "fullscreen": false, + "height": 600.0, + "label": "main", + "maximized": false, + "resizable": true, + "skipTaskbar": false, + "title": "Tauri App", + "transparent": false, + "url": "index.html", + "visible": true, + "width": 800.0 + } + ], + "type": "array", + "items": { + "$ref": "#/definitions/WindowConfig" + } + } + }, + "additionalProperties": false + }, + "UpdaterConfig": { + "description": "The Updater configuration object.", + "type": "object", + "properties": { + "active": { + "description": "Whether the updater is active or not.", + "default": false, + "type": "boolean" + }, + "dialog": { + "description": "Display built-in dialog or use event system if disabled.", + "default": true, + "type": "boolean" + }, + "endpoints": { + "description": "The updater endpoints. TLS is enforced on production.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/UpdaterEndpoint" + } + }, + "pubkey": { + "description": "Signature public key.", + "default": "", + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdaterEndpoint": { + "description": "A URL to an updater server.\n\nThe URL must use the `https` scheme on production.", + "type": "string", + "format": "uri" + }, + "WindowAllowlistConfig": { + "description": "Allowlist for the window APIs.", + "type": "object", + "properties": { + "all": { + "description": "Use this flag to enable all window API features.", + "default": false, + "type": "boolean" + }, + "center": { + "description": "Allows centering the window.", + "default": false, + "type": "boolean" + }, + "close": { + "description": "Allows closing the window.", + "default": false, + "type": "boolean" + }, + "create": { + "description": "Allows dynamic window creation.", + "default": false, + "type": "boolean" + }, + "hide": { + "description": "Allows hiding the window.", + "default": false, + "type": "boolean" + }, + "maximize": { + "description": "Allows maximizing the window.", + "default": false, + "type": "boolean" + }, + "minimize": { + "description": "Allows minimizing the window.", + "default": false, + "type": "boolean" + }, + "print": { + "description": "Allows opening the system dialog to print the window content.", + "default": false, + "type": "boolean" + }, + "requestUserAttention": { + "description": "Allows requesting user attention on the window.", + "default": false, + "type": "boolean" + }, + "setAlwaysOnTop": { + "description": "Allows setting the always_on_top flag of the window.", + "default": false, + "type": "boolean" + }, + "setDecorations": { + "description": "Allows setting the decorations flag of the window.", + "default": false, + "type": "boolean" + }, + "setFocus": { + "description": "Allows focusing the window.", + "default": false, + "type": "boolean" + }, + "setFullscreen": { + "description": "Allows setting the fullscreen flag of the window.", + "default": false, + "type": "boolean" + }, + "setIcon": { + "description": "Allows changing the window icon.", + "default": false, + "type": "boolean" + }, + "setMaxSize": { + "description": "Allows setting the window maximum size.", + "default": false, + "type": "boolean" + }, + "setMinSize": { + "description": "Allows setting the window minimum size.", + "default": false, + "type": "boolean" + }, + "setPosition": { + "description": "Allows changing the position of the window.", + "default": false, + "type": "boolean" + }, + "setResizable": { + "description": "Allows setting the resizable flag of the window.", + "default": false, + "type": "boolean" + }, + "setSize": { + "description": "Allows setting the window size.", + "default": false, + "type": "boolean" + }, + "setSkipTaskbar": { + "description": "Allows setting the skip_taskbar flag of the window.", + "default": false, + "type": "boolean" + }, + "setTitle": { + "description": "Allows changing the window title.", + "default": false, + "type": "boolean" + }, + "show": { + "description": "Allows showing the window.", + "default": false, + "type": "boolean" + }, + "startDragging": { + "description": "Allows start dragging on the window.", + "default": false, + "type": "boolean" + }, + "unmaximize": { + "description": "Allows unmaximizing the window.", + "default": false, + "type": "boolean" + }, + "unminimize": { + "description": "Allows unminimizing the window.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "WindowConfig": { + "description": "The window configuration object.", + "type": "object", + "properties": { + "alwaysOnTop": { + "description": "Whether the window should always be on top of other windows.", + "default": false, + "type": "boolean" + }, + "center": { + "description": "Whether or not the window starts centered or not.", + "default": false, + "type": "boolean" + }, + "decorations": { + "description": "Whether the window should have borders and bars.", + "default": true, + "type": "boolean" + }, + "fileDropEnabled": { + "description": "Whether the file drop is enabled or not on the webview. By default it is enabled.\n\nDisabling it is required to use drag and drop on the frontend on Windows.", + "default": true, + "type": "boolean" + }, + "focus": { + "description": "Whether the window will be initially hidden or focused.", + "default": true, + "type": "boolean" + }, + "fullscreen": { + "description": "Whether the window starts as fullscreen or not.", + "default": false, + "type": "boolean" + }, + "height": { + "description": "The window height.", + "default": 600.0, + "type": "number", + "format": "double" + }, + "label": { + "description": "The window identifier. It must be alphanumeric.", + "default": "main", + "type": "string" + }, + "maxHeight": { + "description": "The max window height.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "maxWidth": { + "description": "The max window width.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "maximized": { + "description": "Whether the window is maximized or not.", + "default": false, + "type": "boolean" + }, + "minHeight": { + "description": "The min window height.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "minWidth": { + "description": "The min window width.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "resizable": { + "description": "Whether the window is resizable or not.", + "default": true, + "type": "boolean" + }, + "skipTaskbar": { + "description": "Whether or not the window icon should be added to the taskbar.", + "default": false, + "type": "boolean" + }, + "title": { + "description": "The window title.", + "default": "Tauri App", + "type": "string" + }, + "transparent": { + "description": "Whether the window is transparent or not.\n\nNote that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri.conf.json > tauri > macosPrivateApi`. WARNING: Using private APIs on `macOS` prevents your application from being accepted for the `App Store`.", + "default": false, + "type": "boolean" + }, + "url": { + "description": "The window webview URL.", + "default": "index.html", + "allOf": [ + { + "$ref": "#/definitions/WindowUrl" + } + ] + }, + "visible": { + "description": "Whether the window is visible or not.", + "default": true, + "type": "boolean" + }, + "width": { + "description": "The window width.", + "default": 800.0, + "type": "number", + "format": "double" + }, + "x": { + "description": "The horizontal position of the window's top left corner", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "y": { + "description": "The vertical position of the window's top left corner", + "type": [ + "number", + "null" + ], + "format": "double" + } + }, + "additionalProperties": false + }, + "WindowUrl": { + "description": "An URL to open on a Tauri webview window.", + "anyOf": [ + { + "description": "An external URL.", + "type": "string", + "format": "uri" + }, + { + "description": "An app URL.", + "type": "string" + } + ] + }, + "WindowsConfig": { + "description": "Windows bundler configuration.", + "type": "object", + "properties": { + "certificateThumbprint": { + "description": "Specifies the SHA1 hash of the signing certificate.", + "type": [ + "string", + "null" + ] + }, + "digestAlgorithm": { + "description": "Specifies the file digest algorithm to use for creating file signatures. Required for code signing. SHA-256 is recommended.", + "type": [ + "string", + "null" + ] + }, + "timestampUrl": { + "description": "Server to use during timestamping.", + "type": [ + "string", + "null" + ] + }, + "webviewFixedRuntimePath": { + "description": "Path to the webview fixed runtime to use.\n\nThe fixed version can be downloaded [on the official website](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section). The `.cab` file must be extracted to a folder and this folder path must be defined on this field.", + "type": [ + "string", + "null" + ] + }, + "wix": { + "description": "Configuration for the MSI generated with WiX.", + "anyOf": [ + { + "$ref": "#/definitions/WixConfig" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "WixConfig": { + "description": "Configuration for the MSI bundle using WiX.", + "type": "object", + "properties": { + "bannerPath": { + "description": "Path to a bitmap file to use as the installation user interface banner. This bitmap will appear at the top of all but the first page of the installer.\n\nThe required dimensions are 493px × 58px.", + "type": [ + "string", + "null" + ] + }, + "componentGroupRefs": { + "description": "The ComponentGroup element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "componentRefs": { + "description": "The Component element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "dialogImagePath": { + "description": "Path to a bitmap file to use on the installation user interface dialogs. It is used on the welcome and completion dialogs. The required dimensions are 493px × 312px.", + "type": [ + "string", + "null" + ] + }, + "enableElevatedUpdateTask": { + "description": "Create an elevated update task within Windows Task Scheduler.", + "default": false, + "type": "boolean" + }, + "featureGroupRefs": { + "description": "The FeatureGroup element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "featureRefs": { + "description": "The Feature element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "fragmentPaths": { + "description": "A list of paths to .wxs files with WiX fragments to use.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "language": { + "description": "The installer languages to build. See .", + "default": "en-US", + "allOf": [ + { + "$ref": "#/definitions/WixLanguage" + } + ] + }, + "license": { + "description": "The path to the license file to render on the installer.\n\nMust be an RTF file, so if a different extension is provided, we convert it to the RTF format.", + "type": [ + "string", + "null" + ] + }, + "mergeRefs": { + "description": "The Merge element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "skipWebviewInstall": { + "description": "Disables the Webview2 runtime installation after app install.", + "default": false, + "type": "boolean" + }, + "template": { + "description": "A custom .wxs template to use.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "WixLanguage": { + "description": "The languages to build using WiX.", + "anyOf": [ + { + "description": "A single language to build, without configuration.", + "type": "string" + }, + { + "description": "A list of languages to build, without configuration.", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "A map of languages and its configuration.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/WixLanguageConfig" + } + } + ] + }, + "WixLanguageConfig": { + "description": "Configuration for a target language for the WiX build.", + "type": "object", + "properties": { + "localePath": { + "description": "The path to a locale (`.wxl`) file. See .", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/tooling/cli/src/build.rs b/tooling/cli/src/build.rs new file mode 100644 index 000000000000..db74ffbe732a --- /dev/null +++ b/tooling/cli/src/build.rs @@ -0,0 +1,380 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::helpers::{ + app_paths::{app_dir, tauri_dir}, + command_env, + config::{get as get_config, AppUrl, WindowUrl}, + manifest::rewrite_manifest, + updater_signature::sign_file_from_env_variables, + Logger, +}; +use crate::{CommandExt, Result}; +use anyhow::Context; +use clap::Parser; +#[cfg(target_os = "linux")] +use heck::ToKebabCase; +use std::{env::set_current_dir, fs::rename, path::PathBuf, process::Command}; +use tauri_bundler::bundle::{bundle_project, PackageType}; + +#[derive(Debug, Parser)] +#[clap(about = "Tauri build")] +pub struct Options { + /// Binary to use to build the application + #[clap(short, long)] + runner: Option, + /// Builds with the debug flag + #[clap(short, long)] + debug: bool, + /// Enables verbose logging + #[clap(short, long)] + verbose: bool, + /// Target triple to build against. + /// It must be one of the values outputted by `$rustc --print target-list` or `universal-apple-darwin` for an universal macOS application. + /// Note that compiling an universal macOS application requires both `aarch64-apple-darwin` and `x86_64-apple-darwin` targets to be installed. + #[clap(short, long)] + target: Option, + /// List of cargo features to activate + #[clap(short, long)] + features: Option>, + /// List of bundles to package + #[clap(short, long)] + bundles: Option>, + /// JSON string or path to JSON file to merge with tauri.conf.json + #[clap(short, long)] + config: Option, +} + +pub fn command(options: Options) -> Result<()> { + let logger = Logger::new("tauri:build"); + let merge_config = if let Some(config) = &options.config { + Some(if config.starts_with('{') { + config.to_string() + } else { + std::fs::read_to_string(&config)? + }) + } else { + None + }; + + let tauri_path = tauri_dir(); + set_current_dir(&tauri_path).with_context(|| "failed to change current working directory")?; + + let config = get_config(merge_config.as_deref())?; + + let manifest = rewrite_manifest(config.clone())?; + + let config_guard = config.lock().unwrap(); + let config_ = config_guard.as_ref().unwrap(); + + if let Some(before_build) = &config_.build.before_build_command { + if !before_build.is_empty() { + logger.log(format!("Running `{}`", before_build)); + #[cfg(target_os = "windows")] + let status = Command::new("cmd") + .arg("/S") + .arg("/C") + .arg(before_build) + .current_dir(app_dir()) + .envs(command_env(options.debug)) + .pipe()? + .status() + .with_context(|| format!("failed to run `{}` with `cmd /C`", before_build))?; + #[cfg(not(target_os = "windows"))] + let status = Command::new("sh") + .arg("-c") + .arg(before_build) + .current_dir(app_dir()) + .envs(command_env(options.debug)) + .pipe()? + .status() + .with_context(|| format!("failed to run `{}` with `sh -c`", before_build))?; + if !status.success() { + return Err(anyhow::anyhow!( + "beforeDevCommand `{}` failed with exit code {}", + before_build, + status.code().unwrap_or_default() + )); + } + } + } + + if let AppUrl::Url(WindowUrl::App(web_asset_path)) = &config_.build.dist_dir { + if !web_asset_path.exists() { + return Err(anyhow::anyhow!( + "Unable to find your web assets, did you forget to build your web app? Your distDir is set to \"{:?}\".", + web_asset_path + )); + } + if web_asset_path.canonicalize()?.file_name() == Some(std::ffi::OsStr::new("src-tauri")) { + return Err(anyhow::anyhow!( + "The configured distDir is the `src-tauri` folder. + Please isolate your web assets on a separate folder and update `tauri.conf.json > build > distDir`.", + )); + } + + let mut out_folders = Vec::new(); + for folder in &["node_modules", "src-tauri", "target"] { + if web_asset_path.join(folder).is_dir() { + out_folders.push(folder.to_string()); + } + } + if !out_folders.is_empty() { + return Err(anyhow::anyhow!( + "The configured distDir includes the `{:?}` {}. Please isolate your web assets on a separate folder and update `tauri.conf.json > build > distDir`.", + out_folders, + if out_folders.len() == 1 { "folder" }else { "folders" } + ) + ); + } + } + + let runner_from_config = config_.build.runner.clone(); + let runner = options + .runner + .or(runner_from_config) + .unwrap_or_else(|| "cargo".to_string()); + + let mut cargo_features = config_.build.features.clone().unwrap_or_default(); + if let Some(features) = options.features { + cargo_features.extend(features); + } + + let app_settings = crate::interface::rust::AppSettings::new(config_)?; + + let out_dir = app_settings + .get_out_dir(options.target.clone(), options.debug) + .with_context(|| "failed to get project out directory")?; + + let bin_name = app_settings + .cargo_package_settings() + .name + .clone() + .expect("Cargo manifest must have the `package.name` field"); + #[cfg(windows)] + let bin_path = out_dir.join(format!("{}.exe", bin_name)); + #[cfg(not(windows))] + let bin_path = out_dir.join(&bin_name); + + if options.target == Some("universal-apple-darwin".into()) { + std::fs::create_dir_all(&out_dir).with_context(|| "failed to create project out directory")?; + + let mut lipo_cmd = Command::new("lipo"); + lipo_cmd + .arg("-create") + .arg("-output") + .arg(out_dir.join(&bin_name)); + for triple in ["aarch64-apple-darwin", "x86_64-apple-darwin"] { + crate::interface::rust::build_project( + runner.clone(), + &Some(triple.into()), + cargo_features.clone(), + options.debug, + ) + .with_context(|| format!("failed to build {} binary", triple))?; + let triple_out_dir = app_settings + .get_out_dir(Some(triple.into()), options.debug) + .with_context(|| format!("failed to get {} out dir", triple))?; + lipo_cmd.arg(triple_out_dir.join(&bin_name)); + } + + let lipo_status = lipo_cmd.status()?; + if !lipo_status.success() { + return Err(anyhow::anyhow!(format!( + "Result of `lipo` command was unsuccessful: {}. (Is `lipo` installed?)", + lipo_status + ))); + } + } else { + crate::interface::rust::build_project(runner, &options.target, cargo_features, options.debug) + .with_context(|| "failed to build app")?; + } + + #[cfg(unix)] + if !options.debug { + strip(&bin_path, &logger)?; + } + + if let Some(product_name) = config_.package.product_name.clone() { + #[cfg(windows)] + let product_path = out_dir.join(format!("{}.exe", product_name)); + #[cfg(target_os = "macos")] + let product_path = out_dir.join(product_name); + #[cfg(target_os = "linux")] + let product_path = out_dir.join(product_name.to_kebab_case()); + rename(&bin_path, &product_path).with_context(|| { + format!( + "failed to rename `{}` to `{}`", + bin_path.display(), + product_path.display(), + ) + })?; + } + + if config_.tauri.bundle.active { + // move merge modules to the out dir so the bundler can load it + #[cfg(windows)] + { + let target = options + .target + .clone() + .unwrap_or_else(|| std::env::consts::ARCH.into()); + let arch = if target.starts_with("x86_64") { + "x86_64" + } else if target.starts_with('i') || target.starts_with("x86") { + "x86" + } else if target.starts_with("arm") { + "arm" + } else if target.starts_with("aarch64") { + "aarch64" + } else { + panic!( + "Unexpected target architecture {}", + target.split('_').next().unwrap() + ) + }; + let (filename, vcruntime_msm) = if arch == "x86" { + let _ = std::fs::remove_file(out_dir.join("Microsoft_VC142_CRT_x64.msm")); + ( + "Microsoft_VC142_CRT_x86.msm", + include_bytes!("../MergeModules/Microsoft_VC142_CRT_x86.msm").to_vec(), + ) + } else { + let _ = std::fs::remove_file(out_dir.join("Microsoft_VC142_CRT_x86.msm")); + ( + "Microsoft_VC142_CRT_x64.msm", + include_bytes!("../MergeModules/Microsoft_VC142_CRT_x64.msm").to_vec(), + ) + }; + std::fs::write(out_dir.join(filename), vcruntime_msm)?; + } + + let package_types = if let Some(names) = options.bundles { + let mut types = vec![]; + for name in names { + if name == "none" { + break; + } + match PackageType::from_short_name(&name) { + Some(package_type) => { + types.push(package_type); + } + None => { + return Err(anyhow::anyhow!(format!( + "Unsupported bundle format: {}", + name + ))); + } + } + } + Some(types) + } else if let Some(targets) = &config_.tauri.bundle.targets { + let mut types = vec![]; + let targets = targets.to_vec(); + if !targets.contains(&"all".into()) { + for name in targets { + match PackageType::from_short_name(&name) { + Some(package_type) => { + types.push(package_type); + } + None => { + return Err(anyhow::anyhow!(format!( + "Unsupported bundle format: {}", + name + ))); + } + } + } + Some(types) + } else { + None + } + } else { + None + }; + + let settings = crate::interface::get_bundler_settings( + app_settings, + options.target.clone(), + &manifest, + config_, + &out_dir, + options.verbose, + package_types, + ) + .with_context(|| "failed to build bundler settings")?; + + let bundles = bundle_project(settings).with_context(|| "failed to bundle project")?; + + // If updater is active + if config_.tauri.updater.active { + // make sure we have our package builts + let mut signed_paths = Vec::new(); + for elem in bundles + .iter() + .filter(|bundle| bundle.package_type == PackageType::Updater) + { + // we expect to have only one path in the vec but we iter if we add + // another type of updater package who require multiple file signature + for path in elem.bundle_paths.iter() { + // sign our path from environment variables + let (signature_path, _signature) = sign_file_from_env_variables(path)?; + signed_paths.append(&mut vec![signature_path]); + } + } + + if !signed_paths.is_empty() { + print_signed_updater_archive(&signed_paths)?; + } + } + } + + Ok(()) +} + +fn print_signed_updater_archive(output_paths: &[PathBuf]) -> crate::Result<()> { + let pluralised = if output_paths.len() == 1 { + "updater archive" + } else { + "updater archives" + }; + let msg = format!("{} {} at:", output_paths.len(), pluralised); + let logger = Logger::new("Signed"); + logger.log(&msg); + for path in output_paths { + println!(" {}", path.display()); + } + Ok(()) +} + +// TODO: drop this when https://github.com/rust-lang/rust/issues/72110 is stabilized +#[cfg(unix)] +fn strip(path: &std::path::Path, logger: &Logger) -> crate::Result<()> { + use humansize::{file_size_opts, FileSize}; + + let filesize_before = std::fs::metadata(&path) + .with_context(|| "failed to get executable file size")? + .len(); + + // Strip the binary + Command::new("strip") + .arg(&path) + .stdout(std::process::Stdio::null()) + .stderr(std::process::Stdio::null()) + .status() + .with_context(|| "failed to execute strip")?; + + let filesize_after = std::fs::metadata(&path) + .with_context(|| "failed to get executable file size")? + .len(); + + logger.log(format!( + "Binary stripped, size reduced by {}", + (filesize_before - filesize_after) + .file_size(file_size_opts::CONVENTIONAL) + .unwrap(), + )); + + Ok(()) +} diff --git a/tooling/cli/src/dev.rs b/tooling/cli/src/dev.rs new file mode 100644 index 000000000000..fff6cbc800b4 --- /dev/null +++ b/tooling/cli/src/dev.rs @@ -0,0 +1,353 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::{ + helpers::{ + app_paths::{app_dir, tauri_dir}, + command_env, + config::{get as get_config, reload as reload_config, AppUrl, WindowUrl}, + manifest::{get_workspace_members, rewrite_manifest}, + Logger, + }, + CommandExt, Result, +}; +use clap::{AppSettings, Parser}; + +use anyhow::Context; +use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher}; +use once_cell::sync::OnceCell; +use shared_child::SharedChild; + +use std::{ + env::set_current_dir, + ffi::OsStr, + process::{exit, Command}, + sync::{ + mpsc::{channel, Receiver}, + Arc, Mutex, + }, + time::Duration, +}; + +static BEFORE_DEV: OnceCell>> = OnceCell::new(); + +#[derive(Debug, Parser)] +#[clap(about = "Tauri dev")] +#[clap(setting(AppSettings::TrailingVarArg))] +pub struct Options { + /// Binary to use to run the application + #[clap(short, long)] + runner: Option, + /// Target triple to build against + #[clap(short, long)] + target: Option, + /// List of cargo features to activate + #[clap(short, long)] + features: Option>, + /// Exit on panic + #[clap(short, long)] + exit_on_panic: bool, + /// JSON string or path to JSON file to merge with tauri.conf.json + #[clap(short, long)] + config: Option, + /// Run the code in release mode + #[clap(long = "release")] + release_mode: bool, + /// Args passed to the binary + args: Vec, +} + +pub fn command(options: Options) -> Result<()> { + let logger = Logger::new("tauri:dev"); + + let tauri_path = tauri_dir(); + set_current_dir(&tauri_path).with_context(|| "failed to change current working directory")?; + let merge_config = if let Some(config) = &options.config { + Some(if config.starts_with('{') { + config.to_string() + } else { + std::fs::read_to_string(&config)? + }) + } else { + None + }; + let config = get_config(merge_config.as_deref())?; + + if let Some(before_dev) = &config + .lock() + .unwrap() + .as_ref() + .unwrap() + .build + .before_dev_command + { + if !before_dev.is_empty() { + logger.log(format!("Running `{}`", before_dev)); + #[cfg(target_os = "windows")] + let mut command = { + let mut command = Command::new("cmd"); + command + .arg("/S") + .arg("/C") + .arg(before_dev) + .current_dir(app_dir()) + .envs(command_env(true)) + .pipe()?; // development build always includes debug information + command + }; + #[cfg(not(target_os = "windows"))] + let mut command = { + let mut command = Command::new("sh"); + command + .arg("-c") + .arg(before_dev) + .current_dir(app_dir()) + .envs(command_env(true)) + .pipe()?; // development build always includes debug information + command + }; + + let child = SharedChild::spawn(&mut command) + .unwrap_or_else(|_| panic!("failed to run `{}`", before_dev)); + let child = Arc::new(child); + let child_ = child.clone(); + let logger_ = logger.clone(); + std::thread::spawn(move || { + let status = child_ + .wait() + .expect("failed to wait on \"beforeDevCommand\""); + if !status.success() { + logger_.error("The \"beforeDevCommand\" terminated with a non-zero status code."); + exit(status.code().unwrap_or(1)); + } + }); + + BEFORE_DEV.set(Mutex::new(child)).unwrap(); + } + } + + let runner_from_config = config + .lock() + .unwrap() + .as_ref() + .unwrap() + .build + .runner + .clone(); + let runner = options + .runner + .clone() + .or(runner_from_config) + .unwrap_or_else(|| "cargo".to_string()); + + { + let (tx, rx) = channel(); + let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); + watcher.watch(tauri_path.join("Cargo.toml"), RecursiveMode::Recursive)?; + rewrite_manifest(config.clone())?; + loop { + if let Ok(DebouncedEvent::NoticeWrite(_)) = rx.recv() { + break; + } + } + } + + let mut cargo_features = config + .lock() + .unwrap() + .as_ref() + .unwrap() + .build + .features + .clone() + .unwrap_or_default(); + if let Some(features) = &options.features { + cargo_features.extend(features.clone()); + } + + let (child_wait_tx, child_wait_rx) = channel(); + let child_wait_rx = Arc::new(Mutex::new(child_wait_rx)); + + if std::env::var_os("TAURI_SKIP_DEVSERVER_CHECK") != Some("true".into()) { + if let AppUrl::Url(WindowUrl::External(dev_server_url)) = config + .lock() + .unwrap() + .as_ref() + .unwrap() + .build + .dev_path + .clone() + { + let host = dev_server_url + .host() + .unwrap_or_else(|| panic!("No host name in the URL")); + let port = dev_server_url + .port_or_known_default() + .unwrap_or_else(|| panic!("No port number in the URL")); + let addrs; + let addr; + let addrs = match host { + url::Host::Domain(domain) => { + use std::net::ToSocketAddrs; + addrs = (domain, port).to_socket_addrs()?; + addrs.as_slice() + } + url::Host::Ipv4(ip) => { + addr = (ip, port).into(); + std::slice::from_ref(&addr) + } + url::Host::Ipv6(ip) => { + addr = (ip, port).into(); + std::slice::from_ref(&addr) + } + }; + let mut i = 0; + let sleep_interval = std::time::Duration::from_secs(2); + let max_attempts = 90; + loop { + if std::net::TcpStream::connect(addrs).is_ok() { + break; + } + if i % 3 == 0 { + logger.warn("Waiting for your dev server to start..."); + } + i += 1; + if i == max_attempts { + logger.error(format!( + "Could not connect to `{}` after {}s. Please make sure that is the URL to your dev server.", + dev_server_url, i * sleep_interval.as_secs() + )); + exit(1); + } + std::thread::sleep(sleep_interval); + } + } + } + + let mut process = start_app(&options, &runner, &cargo_features, child_wait_rx.clone()); + + let (tx, rx) = channel(); + + let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); + watcher.watch(tauri_path.join("src"), RecursiveMode::Recursive)?; + watcher.watch(tauri_path.join("Cargo.toml"), RecursiveMode::Recursive)?; + watcher.watch(tauri_path.join("tauri.conf.json"), RecursiveMode::Recursive)?; + + for member in get_workspace_members()? { + let workspace_path = tauri_path.join(member); + watcher.watch(workspace_path.join("src"), RecursiveMode::Recursive)?; + watcher.watch(workspace_path.join("Cargo.toml"), RecursiveMode::Recursive)?; + } + + loop { + if let Ok(event) = rx.recv() { + let event_path = match event { + DebouncedEvent::Create(path) => Some(path), + DebouncedEvent::Remove(path) => Some(path), + DebouncedEvent::Rename(_, dest) => Some(dest), + DebouncedEvent::Write(path) => Some(path), + _ => None, + }; + + if let Some(event_path) = event_path { + if event_path.file_name() == Some(OsStr::new("tauri.conf.json")) { + reload_config(merge_config.as_deref())?; + rewrite_manifest(config.clone())?; + } else { + // When tauri.conf.json is changed, rewrite_manifest will be called + // which will trigger the watcher again + // So the app should only be started when a file other than tauri.conf.json is changed + let _ = child_wait_tx.send(()); + process + .kill() + .with_context(|| "failed to kill app process")?; + // wait for the process to exit + loop { + if let Ok(Some(_)) = process.try_wait() { + break; + } + } + process = start_app(&options, &runner, &cargo_features, child_wait_rx.clone()); + } + } + } + } +} + +fn kill_before_dev_process() { + if let Some(child) = BEFORE_DEV.get() { + let child = child.lock().unwrap(); + #[cfg(windows)] + let _ = Command::new("powershell") + .arg("-NoProfile") + .arg("-Command") + .arg(format!("function Kill-Tree {{ Param([int]$ppid); Get-CimInstance Win32_Process | Where-Object {{ $_.ParentProcessId -eq $ppid }} | ForEach-Object {{ Kill-Tree $_.ProcessId }}; Stop-Process -Id $ppid }}; Kill-Tree {}", child.id())) + .status(); + #[cfg(not(windows))] + let _ = Command::new("pkill") + .args(&["-TERM", "-P"]) + .arg(child.id().to_string()) + .status(); + let _ = child.kill(); + } +} + +fn start_app( + options: &Options, + runner: &str, + features: &[String], + child_wait_rx: Arc>>, +) -> Arc { + let mut command = Command::new(runner); + command.args(&["run", "--no-default-features"]); + + if options.release_mode { + command.args(&["--release"]); + } + + if let Some(target) = &options.target { + command.args(&["--target", target]); + } + + if !features.is_empty() { + command.args(&["--features", &features.join(",")]); + } + + if !options.args.is_empty() { + command.arg("--").args(&options.args); + } + + command.pipe().unwrap(); + + let child = + SharedChild::spawn(&mut command).unwrap_or_else(|_| panic!("failed to run {}", runner)); + let child_arc = Arc::new(child); + + let child_clone = child_arc.clone(); + let exit_on_panic = options.exit_on_panic; + std::thread::spawn(move || { + let status = child_clone.wait().expect("failed to wait on child"); + if exit_on_panic { + // we exit if the status is a success code (app closed) or code is 101 (compilation error) + // if the process wasn't killed by the file watcher + if (status.success() || status.code() == Some(101)) + // `child_wait_rx` indicates that the process was killed by the file watcher + && child_wait_rx + .lock() + .expect("failed to get child_wait_rx lock") + .try_recv() + .is_err() + { + kill_before_dev_process(); + exit(0); + } + } else if status.success() { + // if we're no exiting on panic, we only exit if the status is a success code (app closed) + kill_before_dev_process(); + exit(0); + } + }); + + child_arc +} diff --git a/tooling/cli/src/helpers/app_paths.rs b/tooling/cli/src/helpers/app_paths.rs new file mode 100644 index 000000000000..a4e081a36eed --- /dev/null +++ b/tooling/cli/src/helpers/app_paths.rs @@ -0,0 +1,45 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::{env::current_dir, path::PathBuf}; + +use once_cell::sync::Lazy; + +fn get_tauri_dir() -> PathBuf { + glob::glob( + ¤t_dir() + .expect("failed to read cwd") + .join("**/tauri.conf.json") + .to_string_lossy(), + ) + .unwrap() + .filter_map(Result::ok) + .last() + .map(|p| p.parent().unwrap().to_path_buf()) + .expect("Couldn't recognize the current folder as a Tauri project. It must contain a `tauri.conf.json` file in any subfolder.") +} + +fn get_app_dir() -> Option { + glob::glob( + ¤t_dir() + .expect("failed to read cwd") + .join("**/package.json") + .to_string_lossy(), + ) + .unwrap() + .filter_map(Result::ok) + .filter(|p| !p.to_string_lossy().into_owned().contains("node_modules")) + .last() + .map(|p| p.parent().unwrap().to_path_buf()) +} + +pub fn app_dir() -> &'static PathBuf { + static APP_DIR: Lazy = + Lazy::new(|| get_app_dir().unwrap_or_else(|| get_tauri_dir().parent().unwrap().to_path_buf())); + &APP_DIR +} + +pub fn tauri_dir() -> PathBuf { + get_tauri_dir() +} diff --git a/tooling/cli/src/helpers/config.rs b/tooling/cli/src/helpers/config.rs new file mode 100644 index 000000000000..64614d9db5ef --- /dev/null +++ b/tooling/cli/src/helpers/config.rs @@ -0,0 +1,108 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use anyhow::Context; +use json_patch::merge; +use once_cell::sync::Lazy; +use serde_json::Value as JsonValue; + +pub use tauri_utils::config::*; + +use std::{ + env::set_var, + process::exit, + sync::{Arc, Mutex}, +}; + +pub type ConfigHandle = Arc>>; + +pub fn wix_settings(config: WixConfig) -> tauri_bundler::WixSettings { + tauri_bundler::WixSettings { + language: tauri_bundler::WixLanguage(match config.language { + WixLanguage::One(lang) => vec![(lang, Default::default())], + WixLanguage::List(languages) => languages + .into_iter() + .map(|lang| (lang, Default::default())) + .collect(), + WixLanguage::Localized(languages) => languages + .into_iter() + .map(|(lang, config)| { + ( + lang, + tauri_bundler::WixLanguageConfig { + locale_path: config.locale_path.map(Into::into), + }, + ) + }) + .collect(), + }), + template: config.template, + fragment_paths: config.fragment_paths, + component_group_refs: config.component_group_refs, + component_refs: config.component_refs, + feature_group_refs: config.feature_group_refs, + feature_refs: config.feature_refs, + merge_refs: config.merge_refs, + skip_webview_install: config.skip_webview_install, + license: config.license, + enable_elevated_update_task: config.enable_elevated_update_task, + banner_path: config.banner_path, + dialog_image_path: config.dialog_image_path, + } +} + +fn config_handle() -> &'static ConfigHandle { + static CONFING_HANDLE: Lazy = Lazy::new(Default::default); + &CONFING_HANDLE +} + +/// Gets the static parsed config from `tauri.conf.json`. +fn get_internal(merge_config: Option<&str>, reload: bool) -> crate::Result { + if !reload && config_handle().lock().unwrap().is_some() { + return Ok(config_handle().clone()); + } + + let mut config = tauri_utils::config::parse::read_from(super::app_paths::tauri_dir())?; + + if let Some(merge_config) = merge_config { + let merge_config: JsonValue = + serde_json::from_str(merge_config).with_context(|| "failed to parse config to merge")?; + merge(&mut config, &merge_config); + } + + let schema: JsonValue = serde_json::from_str(include_str!("../../schema.json"))?; + let mut scope = valico::json_schema::Scope::new(); + let schema = scope.compile_and_return(schema, false).unwrap(); + let state = schema.validate(&config); + if !state.errors.is_empty() { + for error in state.errors { + eprintln!( + "`tauri.conf.json` error on `{}`: {}", + error + .get_path() + .chars() + .skip(1) + .collect::() + .replace('/', " > "), + error.get_detail().unwrap_or_else(|| error.get_title()), + ); + } + exit(1); + } + + let config: Config = serde_json::from_value(config)?; + set_var("TAURI_CONFIG", serde_json::to_string(&config)?); + *config_handle().lock().unwrap() = Some(config); + + Ok(config_handle().clone()) +} + +pub fn get(merge_config: Option<&str>) -> crate::Result { + get_internal(merge_config, false) +} + +pub fn reload(merge_config: Option<&str>) -> crate::Result<()> { + get_internal(merge_config, true)?; + Ok(()) +} diff --git a/tooling/cli.rs/src/helpers/framework.rs b/tooling/cli/src/helpers/framework.rs similarity index 98% rename from tooling/cli.rs/src/helpers/framework.rs rename to tooling/cli/src/helpers/framework.rs index 585d6070c231..039ec197f20b 100644 --- a/tooling/cli.rs/src/helpers/framework.rs +++ b/tooling/cli/src/helpers/framework.rs @@ -21,7 +21,7 @@ pub enum Framework { impl Framework { pub fn dev_path(&self) -> String { match self { - Self::Svelte => "http://localhost:5000", + Self::Svelte => "http://localhost:8080", Self::Angular => "http://localhost:4200", Self::React => "http://localhost:3000", Self::Nextjs => "http://localhost:3000", diff --git a/tooling/cli.rs/src/helpers/logger.rs b/tooling/cli/src/helpers/logger.rs similarity index 97% rename from tooling/cli.rs/src/helpers/logger.rs rename to tooling/cli/src/helpers/logger.rs index 29f5c902db13..04a656bd618b 100644 --- a/tooling/cli.rs/src/helpers/logger.rs +++ b/tooling/cli/src/helpers/logger.rs @@ -4,6 +4,7 @@ use colored::Colorize; +#[derive(Clone)] pub struct Logger<'a> { context: &'a str, } diff --git a/tooling/cli/src/helpers/manifest.rs b/tooling/cli/src/helpers/manifest.rs new file mode 100644 index 000000000000..e33057a3b8d5 --- /dev/null +++ b/tooling/cli/src/helpers/manifest.rs @@ -0,0 +1,201 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use super::{ + app_paths::tauri_dir, + config::{ConfigHandle, PatternKind}, +}; + +use anyhow::Context; +use toml_edit::{Array, Document, InlineTable, Item, Table, Value}; + +use std::{ + collections::HashSet, + fs::File, + io::{Read, Write}, + iter::FromIterator, + path::Path, +}; + +#[derive(Default)] +pub struct Manifest { + pub features: HashSet, +} + +fn read_manifest(manifest_path: &Path) -> crate::Result { + let mut manifest_str = String::new(); + + let mut manifest_file = File::open(manifest_path) + .with_context(|| format!("failed to open `{:?}` file", manifest_path))?; + manifest_file.read_to_string(&mut manifest_str)?; + + let manifest: Document = manifest_str + .parse::() + .with_context(|| "failed to parse Cargo.toml")?; + + Ok(manifest) +} + +fn toml_array(features: &HashSet) -> Array { + let mut f = Array::default(); + let mut features: Vec = features.iter().map(|f| f.to_string()).collect(); + features.sort(); + for feature in features { + f.push(feature.as_str()); + } + f +} + +fn write_features( + dependencies: &mut Table, + dependency_name: &str, + all_features: Vec<&str>, + features: &mut HashSet, +) -> crate::Result { + let item = dependencies.entry(dependency_name).or_insert(Item::None); + + if let Some(dep) = item.as_table_mut() { + let manifest_features = dep.entry("features").or_insert(Item::None); + if let Item::Value(Value::Array(f)) = &manifest_features { + for feat in f.iter() { + if let Value::String(feature) = feat { + if !all_features.contains(&feature.value().as_str()) { + features.insert(feature.value().to_string()); + } + } + } + } + *manifest_features = Item::Value(Value::Array(toml_array(features))); + Ok(true) + } else if let Some(dep) = item.as_value_mut() { + match dep { + Value::InlineTable(table) => { + let manifest_features = table.get_or_insert("features", Value::Array(Default::default())); + if let Value::Array(f) = &manifest_features { + for feat in f.iter() { + if let Value::String(feature) = feat { + if !all_features.contains(&feature.value().as_str()) { + features.insert(feature.value().to_string()); + } + } + } + } + *manifest_features = Value::Array(toml_array(features)); + } + Value::String(version) => { + let mut def = InlineTable::default(); + def.get_or_insert( + "version", + version.to_string().replace('\"', "").replace(' ', ""), + ); + def.get_or_insert("features", Value::Array(toml_array(features))); + *dep = Value::InlineTable(def); + } + _ => { + return Err(anyhow::anyhow!( + "Unsupported {} dependency format on Cargo.toml", + dependency_name + )) + } + } + Ok(true) + } else { + Ok(false) + } +} + +pub fn rewrite_manifest(config: ConfigHandle) -> crate::Result { + let manifest_path = tauri_dir().join("Cargo.toml"); + let mut manifest = read_manifest(&manifest_path)?; + + let config_guard = config.lock().unwrap(); + let config = config_guard.as_ref().unwrap(); + + let mut tauri_build_features = HashSet::new(); + if let PatternKind::Isolation { .. } = config.tauri.pattern { + tauri_build_features.insert("isolation".to_string()); + } + let resp = write_features( + manifest + .as_table_mut() + .entry("build-dependencies") + .or_insert(Item::Table(Table::new())) + .as_table_mut() + .expect("manifest build-dependencies isn't a table"), + "tauri-build", + vec!["isolation"], + &mut tauri_build_features, + )?; + + let mut tauri_features = + HashSet::from_iter(config.tauri.features().into_iter().map(|f| f.to_string())); + let cli_managed_tauri_features = super::config::TauriConfig::all_features(); + let res = match write_features( + manifest + .as_table_mut() + .entry("dependencies") + .or_insert(Item::Table(Table::new())) + .as_table_mut() + .expect("manifest dependencies isn't a table"), + "tauri", + cli_managed_tauri_features, + &mut tauri_features, + ) { + Err(e) => Err(e), + Ok(t) if !resp => Ok(t), + _ => Ok(true), + }; + + match res { + Ok(true) => { + let mut manifest_file = + File::create(&manifest_path).with_context(|| "failed to open Cargo.toml for rewrite")?; + manifest_file.write_all( + manifest + .to_string() + // apply some formatting fixes + .replace(r#"" ,features =["#, r#"", features = ["#) + .replace(r#"" , features"#, r#"", features"#) + .replace("]}", "] }") + .replace("={", "= {") + .replace("=[", "= [") + .as_bytes(), + )?; + manifest_file.flush()?; + Ok(Manifest { + features: tauri_features, + }) + } + Ok(false) => Ok(Manifest { + features: tauri_features, + }), + Err(e) => Err(e), + } +} + +pub fn get_workspace_members() -> crate::Result> { + let mut manifest = read_manifest(&tauri_dir().join("Cargo.toml"))?; + let workspace = manifest + .as_table_mut() + .entry("workspace") + .or_insert(Item::None) + .as_table_mut(); + + match workspace { + Some(workspace) => { + let members = workspace + .entry("members") + .or_insert(Item::None) + .as_array() + .expect("workspace members aren't an array"); + Ok( + members + .iter() + .map(|v| v.as_str().unwrap().to_string()) + .collect(), + ) + } + None => Ok(vec![]), + } +} diff --git a/tooling/cli/src/helpers/mod.rs b/tooling/cli/src/helpers/mod.rs new file mode 100644 index 000000000000..1d2adabe7bcb --- /dev/null +++ b/tooling/cli/src/helpers/mod.rs @@ -0,0 +1,52 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +pub mod app_paths; +pub mod config; +pub mod framework; +mod logger; +pub mod manifest; +pub mod template; +pub mod updater_signature; + +pub use logger::Logger; + +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; + +pub fn command_env(debug: bool) -> HashMap { + let mut map = HashMap::new(); + + map.insert("TAURI_PLATFORM".into(), std::env::consts::OS.into()); + map.insert("TAURI_ARCH".into(), std::env::consts::ARCH.into()); + map.insert("TAURI_FAMILY".into(), std::env::consts::FAMILY.into()); + map.insert( + "TAURI_PLATFORM_VERSION".into(), + os_info::get().version().to_string(), + ); + + #[cfg(target_os = "linux")] + map.insert("TAURI_PLATFORM_TYPE".into(), "Linux".into()); + #[cfg(target_os = "windows")] + map.insert("TAURI_PLATFORM_TYPE".into(), "Windows_NT".into()); + #[cfg(target_os = "macos")] + map.insert("TAURI_PLATFORM_TYPE".into(), "Darwin".into()); + + if debug { + map.insert("TAURI_DEBUG".into(), "true".to_string()); + } + + map +} + +pub fn resolve_tauri_path>(path: P, crate_name: &str) -> PathBuf { + let path = path.as_ref(); + if path.is_absolute() { + path.join(crate_name) + } else { + PathBuf::from("..").join(path).join(crate_name) + } +} diff --git a/tooling/cli/src/helpers/template.rs b/tooling/cli/src/helpers/template.rs new file mode 100644 index 000000000000..5ff775d17c79 --- /dev/null +++ b/tooling/cli/src/helpers/template.rs @@ -0,0 +1,44 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::{ + collections::BTreeMap, + fs::{create_dir_all, File}, + io::Write, + path::Path, +}; + +use handlebars::Handlebars; +use include_dir::Dir; + +pub fn render>( + handlebars: &Handlebars<'_>, + data: &BTreeMap<&str, serde_json::Value>, + dir: &Dir<'_>, + out_dir: P, +) -> crate::Result<()> { + create_dir_all(out_dir.as_ref().join(dir.path()))?; + for file in dir.files() { + let mut file_path = file.path().to_path_buf(); + // cargo for some reason ignores the /templates folder packaging when it has a Cargo.toml file inside + // so we rename the extension to `.crate-manifest` + if let Some(extension) = file_path.extension() { + if extension == "crate-manifest" { + file_path.set_extension("toml"); + } + } + let mut output_file = File::create(out_dir.as_ref().join(file_path))?; + if let Some(utf8) = file.contents_utf8() { + handlebars + .render_template_to_write(utf8, &data, &mut output_file) + .expect("Failed to render template"); + } else { + output_file.write_all(file.contents())?; + } + } + for dir in dir.dirs() { + render(handlebars, data, dir, out_dir.as_ref())?; + } + Ok(()) +} diff --git a/tooling/cli.rs/src/helpers/updater_signature.rs b/tooling/cli/src/helpers/updater_signature.rs similarity index 88% rename from tooling/cli.rs/src/helpers/updater_signature.rs rename to tooling/cli/src/helpers/updater_signature.rs index 79ca6015d4db..778f38395415 100644 --- a/tooling/cli.rs/src/helpers/updater_signature.rs +++ b/tooling/cli/src/helpers/updater_signature.rs @@ -2,8 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -extern crate minisign; - use base64::{decode, encode}; use minisign::{sign, KeyPair as KP, SecretKeyBox}; use std::{ @@ -106,7 +104,6 @@ pub fn sign_file

    ( private_key: String, password: String, bin_path: P, - prehashed: bool, ) -> crate::Result<(PathBuf, String)> where P: AsRef, @@ -127,13 +124,12 @@ where bin_path.as_ref().display() ); - let (data_reader, should_be_prehashed) = open_data_file(bin_path)?; + let data_reader = open_data_file(bin_path)?; let signature_box = sign( None, &sk, data_reader, - prehashed | should_be_prehashed, Some(trusted_comment.as_str()), Some("signature from tauri secret key"), )?; @@ -166,10 +162,11 @@ where private_key_string = read_key_from_file(pk_dir)?; } // sign our file - return sign_file(private_key_string, password_string, path_to_sign, false); + sign_file(private_key_string, password_string, path_to_sign) + } else { + // reject if we don't have the private key + Err(anyhow::anyhow!("A public key has been found, but no private key. Make sure to set `TAURI_PRIVATE_KEY` environment variable.")) } - // reject if we don't have the private key - Err(anyhow::anyhow!("A public key has been found, but no private key. Make sure to set `TAURI_PRIVATE_KEY` environment variable.")) } fn unix_timestamp() -> u64 { @@ -180,7 +177,7 @@ fn unix_timestamp() -> u64 { since_the_epoch.as_secs() } -fn open_data_file

    (data_path: P) -> crate::Result<(BufReader, bool)> +fn open_data_file

    (data_path: P) -> crate::Result> where P: AsRef, { @@ -189,9 +186,5 @@ where .read(true) .open(data_path) .map_err(|e| minisign::PError::new(minisign::ErrorKind::Io, e))?; - let should_be_hashed = match file.metadata() { - Ok(metadata) => metadata.len() > (1u64 << 30), - Err(_) => true, - }; - Ok((BufReader::new(file), should_be_hashed)) + Ok(BufReader::new(file)) } diff --git a/tooling/cli/src/info.rs b/tooling/cli/src/info.rs new file mode 100644 index 000000000000..92dc1fcdcc3e --- /dev/null +++ b/tooling/cli/src/info.rs @@ -0,0 +1,801 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::helpers::{ + app_paths::{app_dir, tauri_dir}, + config::get as get_config, + framework::infer_from_package_json as infer_framework, +}; +use crate::Result; +use clap::Parser; +use serde::Deserialize; + +use std::{ + collections::HashMap, + fs::{read_dir, read_to_string}, + panic, + path::{Path, PathBuf}, + process::Command, +}; + +#[derive(Deserialize)] +struct YarnVersionInfo { + data: Vec, +} + +#[derive(Clone, Deserialize)] +struct CargoLockPackage { + name: String, + version: String, + source: Option, +} + +#[derive(Deserialize)] +struct CargoLock { + package: Vec, +} + +#[derive(Deserialize)] +struct JsCliVersionMetadata { + version: String, + node: String, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct VersionMetadata { + #[serde(rename = "cli.js")] + js_cli: JsCliVersionMetadata, +} + +#[derive(Clone, Deserialize)] +struct CargoManifestDependencyPackage { + version: Option, + git: Option, + branch: Option, + rev: Option, + path: Option, +} + +#[derive(Clone, Deserialize)] +#[serde(untagged)] +enum CargoManifestDependency { + Version(String), + Package(CargoManifestDependencyPackage), +} + +#[derive(Deserialize)] +struct CargoManifestPackage { + version: String, +} + +#[derive(Deserialize)] +struct CargoManifest { + package: CargoManifestPackage, + dependencies: HashMap, +} + +enum PackageManager { + Npm, + Pnpm, + Yarn, +} + +#[derive(Debug, Parser)] +#[clap(about = "Shows information about Tauri dependencies and project configuration")] +pub struct Options; + +fn crate_latest_version(name: &str) -> Option { + let url = format!("https://docs.rs/crate/{}/", name); + match ureq::get(&url).call() { + Ok(response) => match (response.status(), response.header("location")) { + (302, Some(location)) => Some(location.replace(&url, "")), + _ => None, + }, + Err(_) => None, + } +} + +#[allow(clippy::let_and_return)] +fn cross_command(bin: &str) -> Command { + #[cfg(target_os = "windows")] + let cmd = { + let mut cmd = Command::new("cmd"); + cmd.arg("/c").arg(bin); + cmd + }; + #[cfg(not(target_os = "windows"))] + let cmd = Command::new(bin); + cmd +} + +fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result> { + match pm { + PackageManager::Yarn => { + let mut cmd = cross_command("yarn"); + + let output = cmd + .arg("info") + .arg(name) + .args(&["version", "--json"]) + .output()?; + if output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + let info: YarnVersionInfo = serde_json::from_str(&stdout)?; + Ok(Some(info.data.last().unwrap().to_string())) + } else { + Ok(None) + } + } + PackageManager::Npm => { + let mut cmd = cross_command("npm"); + + let output = cmd.arg("show").arg(name).arg("version").output()?; + if output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + Ok(Some(stdout.replace('\n', ""))) + } else { + Ok(None) + } + } + PackageManager::Pnpm => { + let mut cmd = cross_command("pnpm"); + + let output = cmd.arg("info").arg(name).arg("version").output()?; + if output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + Ok(Some(stdout.replace('\n', ""))) + } else { + Ok(None) + } + } + } +} + +fn npm_package_version>( + pm: &PackageManager, + name: &str, + app_dir: P, +) -> crate::Result> { + let output = match pm { + PackageManager::Yarn => cross_command("yarn") + .args(&["list", "--pattern"]) + .arg(name) + .args(&["--depth", "0"]) + .current_dir(app_dir) + .output()?, + PackageManager::Npm => cross_command("npm") + .arg("list") + .arg(name) + .args(&["version", "--depth", "0"]) + .current_dir(app_dir) + .output()?, + PackageManager::Pnpm => cross_command("pnpm") + .arg("list") + .arg(name) + .args(&["--parseable", "--depth", "0"]) + .current_dir(app_dir) + .output()?, + }; + if output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + let regex = regex::Regex::new("@([\\da-zA-Z\\-\\.]+)").unwrap(); + Ok( + regex + .captures_iter(&stdout) + .last() + .and_then(|cap| cap.get(1).map(|v| v.as_str().to_string())), + ) + } else { + Ok(None) + } +} + +fn get_version(command: &str, args: &[&str]) -> crate::Result> { + let output = cross_command(command) + .args(args) + .arg("--version") + .output()?; + let version = if output.status.success() { + Some( + String::from_utf8_lossy(&output.stdout) + .replace('\n', "") + .replace('\r', ""), + ) + } else { + None + }; + Ok(version) +} + +#[cfg(windows)] +fn webview2_version() -> crate::Result> { + // check 64bit machine-wide installation + let output = Command::new("powershell") + .args(&["-NoProfile", "-Command"]) + .arg("Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' | ForEach-Object {$_.pv}") + .output()?; + if output.status.success() { + return Ok(Some( + String::from_utf8_lossy(&output.stdout).replace('\n', ""), + )); + } + // check 32bit machine-wide installation + let output = Command::new("powershell") + .args(&["-NoProfile", "-Command"]) + .arg("Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' | ForEach-Object {$_.pv}") + .output()?; + if output.status.success() { + return Ok(Some( + String::from_utf8_lossy(&output.stdout).replace('\n', ""), + )); + } + // check user-wide installation + let output = Command::new("powershell") + .args(&["-NoProfile", "-Command"]) + .arg("Get-ItemProperty -Path 'HKCU:\\SOFTWARE\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' | ForEach-Object {$_.pv}") + .output()?; + if output.status.success() { + return Ok(Some( + String::from_utf8_lossy(&output.stdout).replace('\n', ""), + )); + } + + Ok(None) +} + +#[cfg(windows)] +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct VsInstanceInfo { + display_name: String, +} + +#[cfg(windows)] +const VSWHERE: &[u8] = include_bytes!("../vswhere.exe"); + +#[cfg(windows)] +fn build_tools_version() -> crate::Result>> { + let mut vswhere = std::env::temp_dir(); + vswhere.push("vswhere.exe"); + + if !vswhere.exists() { + if let Ok(mut file) = std::fs::File::create(vswhere.clone()) { + use std::io::Write; + let _ = file.write_all(VSWHERE); + } + } + let output = cross_command(vswhere.to_str().unwrap()) + .args(&[ + "-prerelease", + "-products", + "*", + "-requiresAny", + "-requires", + "Microsoft.VisualStudio.Workload.NativeDesktop", + "-requires", + "Microsoft.VisualStudio.Workload.VCTools", + "-format", + "json", + ]) + .output()?; + Ok(if output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + let instances: Vec = serde_json::from_str(&stdout)?; + Some( + instances + .iter() + .map(|i| i.display_name.clone()) + .collect::>(), + ) + } else { + None + }) +} + +fn active_rust_toolchain() -> crate::Result> { + let output = cross_command("rustup") + .args(["show", "active-toolchain"]) + .output()?; + let toolchain = if output.status.success() { + Some( + String::from_utf8_lossy(&output.stdout) + .replace('\n', "") + .replace('\r', "") + .split('(') + .collect::>()[0] + .into(), + ) + } else { + None + }; + Ok(toolchain) +} + +struct InfoBlock { + section: bool, + key: &'static str, + value: Option, + suffix: Option, +} + +impl InfoBlock { + fn new(key: &'static str) -> Self { + Self { + section: false, + key, + value: None, + suffix: None, + } + } + + fn section(mut self) -> Self { + self.section = true; + self + } + + fn value>>(mut self, value: V) -> Self { + self.value = value.into(); + self + } + + fn suffix>>(mut self, suffix: S) -> Self { + self.suffix = suffix.into(); + self + } + + fn display(&self) { + if self.section { + println!(); + } + print!("{}", self.key); + if let Some(value) = &self.value { + print!(" - {}", value); + } + if let Some(suffix) = &self.suffix { + print!("{}", suffix); + } + println!(); + } +} + +struct VersionBlock { + section: bool, + key: &'static str, + version: Option, + target_version: Option, +} + +impl VersionBlock { + fn new>>(key: &'static str, version: V) -> Self { + Self { + section: false, + key, + version: version.into(), + target_version: None, + } + } + + fn target_version>>(mut self, version: V) -> Self { + self.target_version = version.into(); + self + } + + fn display(&self) { + if self.section { + println!(); + } + print!("{}", self.key); + if let Some(version) = &self.version { + print!(" - {}", version); + } else { + print!(" - Not installed"); + } + if let (Some(version), Some(target_version)) = (&self.version, &self.target_version) { + let version = semver::Version::parse(version).unwrap(); + let target_version = semver::Version::parse(target_version).unwrap(); + if version < target_version { + print!(" (outdated, latest: {})", target_version); + } + } + println!(); + } +} + +pub fn command(_options: Options) -> Result<()> { + let os_info = os_info::get(); + InfoBlock { + section: true, + key: "Operating System", + value: Some(format!( + "{}, version {} {:?}", + os_info.os_type(), + os_info.version(), + os_info.bitness() + )), + suffix: None, + } + .display(); + + #[cfg(windows)] + VersionBlock::new("Webview2", webview2_version().unwrap_or_default()).display(); + + #[cfg(windows)] + { + let build_tools = build_tools_version() + .unwrap_or_default() + .unwrap_or_default(); + + if build_tools.is_empty() { + InfoBlock { + section: false, + key: "Visual Studio Build Tools - Not installed", + value: None, + suffix: None, + } + .display(); + } else { + InfoBlock { + section: false, + key: "Visual Studio Build Tools:", + value: None, + suffix: None, + } + .display(); + + for i in build_tools { + VersionBlock::new(" ", i).display(); + } + } + } + + let hook = panic::take_hook(); + panic::set_hook(Box::new(|_info| { + // do nothing + })); + let app_dir = panic::catch_unwind(app_dir).map(Some).unwrap_or_default(); + panic::set_hook(hook); + + let mut package_manager = PackageManager::Npm; + if let Some(app_dir) = &app_dir { + let file_names = read_dir(app_dir) + .unwrap() + .filter(|e| { + e.as_ref() + .unwrap() + .metadata() + .unwrap() + .file_type() + .is_file() + }) + .map(|e| e.unwrap().file_name().to_string_lossy().into_owned()) + .collect::>(); + package_manager = get_package_manager(&file_names)?; + } + + if let Some(node_version) = get_version("node", &[]).unwrap_or_default() { + InfoBlock::new("Node.js environment").section().display(); + let metadata = serde_json::from_str::(include_str!("../metadata.json"))?; + VersionBlock::new( + " Node.js", + node_version.chars().skip(1).collect::(), + ) + .target_version(metadata.js_cli.node.replace(">= ", "")) + .display(); + + VersionBlock::new(" @tauri-apps/cli", metadata.js_cli.version) + .target_version(npm_latest_version(&package_manager, "@tauri-apps/cli").unwrap_or_default()) + .display(); + if let Some(app_dir) = &app_dir { + VersionBlock::new( + " @tauri-apps/api", + npm_package_version(&package_manager, "@tauri-apps/api", app_dir).unwrap_or_default(), + ) + .target_version(npm_latest_version(&package_manager, "@tauri-apps/api").unwrap_or_default()) + .display(); + } + + InfoBlock::new("Global packages").section().display(); + + VersionBlock::new(" npm", get_version("npm", &[]).unwrap_or_default()).display(); + VersionBlock::new(" pnpm", get_version("pnpm", &[]).unwrap_or_default()).display(); + VersionBlock::new(" yarn", get_version("yarn", &[]).unwrap_or_default()).display(); + } + + InfoBlock::new("Rust environment").section().display(); + VersionBlock::new( + " rustc", + get_version("rustc", &[]).unwrap_or_default().map(|v| { + let mut s = v.split(' '); + s.next(); + s.next().unwrap().to_string() + }), + ) + .display(); + VersionBlock::new( + " cargo", + get_version("cargo", &[]).unwrap_or_default().map(|v| { + let mut s = v.split(' '); + s.next(); + s.next().unwrap().to_string() + }), + ) + .display(); + + InfoBlock::new("Rust environment").section().display(); + VersionBlock::new( + " rustup", + get_version("rustup", &[]).unwrap_or_default().map(|v| { + let mut s = v.split(' '); + s.next(); + s.next().unwrap().to_string() + }), + ) + .display(); + VersionBlock::new( + " rustc", + get_version("rustc", &[]).unwrap_or_default().map(|v| { + let mut s = v.split(' '); + s.next(); + s.next().unwrap().to_string() + }), + ) + .display(); + VersionBlock::new( + " cargo", + get_version("cargo", &[]).unwrap_or_default().map(|v| { + let mut s = v.split(' '); + s.next(); + s.next().unwrap().to_string() + }), + ) + .display(); + VersionBlock::new(" toolchain", active_rust_toolchain().unwrap_or_default()).display(); + + if let Some(app_dir) = app_dir { + InfoBlock::new("App directory structure") + .section() + .display(); + for entry in read_dir(app_dir)? { + let entry = entry?; + if entry.path().is_dir() { + println!("/{}", entry.path().file_name().unwrap().to_string_lossy()); + } + } + } + + InfoBlock::new("App").section().display(); + let tauri_dir = tauri_dir(); + let manifest: Option = + if let Ok(manifest_contents) = read_to_string(tauri_dir.join("Cargo.toml")) { + toml::from_str(&manifest_contents).ok() + } else { + None + }; + let lock: Option = + if let Ok(lock_contents) = read_to_string(tauri_dir.join("Cargo.lock")) { + toml::from_str(&lock_contents).ok() + } else { + None + }; + let tauri_lock_packages: Vec = lock + .as_ref() + .map(|lock| { + lock + .package + .iter() + .filter(|p| p.name == "tauri") + .cloned() + .collect() + }) + .unwrap_or_default(); + let (tauri_version_string, found_tauri_versions) = + match (&manifest, &lock, tauri_lock_packages.len()) { + (Some(_manifest), Some(_lock), 1) => { + let tauri_lock_package = tauri_lock_packages.first().unwrap(); + let version_string = if let Some(s) = &tauri_lock_package.source { + if s.starts_with("git") { + format!("{} ({})", s, tauri_lock_package.version) + } else { + tauri_lock_package.version.clone() + } + } else { + tauri_lock_package.version.clone() + }; + (version_string, vec![tauri_lock_package.version.clone()]) + } + (None, Some(_lock), 1) => { + let tauri_lock_package = tauri_lock_packages.first().unwrap(); + let version_string = if let Some(s) = &tauri_lock_package.source { + if s.starts_with("git") { + format!("{} ({})", s, tauri_lock_package.version) + } else { + tauri_lock_package.version.clone() + } + } else { + tauri_lock_package.version.clone() + }; + ( + format!("{} (no manifest)", version_string), + vec![tauri_lock_package.version.clone()], + ) + } + _ => { + let mut found_tauri_versions = Vec::new(); + let mut is_git = false; + let manifest_version = match manifest.and_then(|m| m.dependencies.get("tauri").cloned()) { + Some(tauri) => match tauri { + CargoManifestDependency::Version(v) => { + found_tauri_versions.push(v.clone()); + v + } + CargoManifestDependency::Package(p) => { + if let Some(v) = p.version { + found_tauri_versions.push(v.clone()); + v + } else if let Some(p) = p.path { + let manifest_path = tauri_dir.join(&p).join("Cargo.toml"); + let v = match read_to_string(&manifest_path) + .map_err(|_| ()) + .and_then(|m| toml::from_str::(&m).map_err(|_| ())) + { + Ok(manifest) => manifest.package.version, + Err(_) => "unknown version".to_string(), + }; + format!("path:{:?} [{}]", p, v) + } else if let Some(g) = p.git { + is_git = true; + let mut v = format!("git:{}", g); + if let Some(branch) = p.branch { + v.push_str(&format!("&branch={}", branch)); + } else if let Some(rev) = p.rev { + v.push_str(&format!("#{}", rev)); + } + v + } else { + "unknown manifest".to_string() + } + } + }, + None => "no manifest".to_string(), + }; + + let lock_version = match (lock, tauri_lock_packages.is_empty()) { + (Some(_lock), true) => tauri_lock_packages + .iter() + .map(|p| p.version.clone()) + .collect::>() + .join(", "), + (Some(_lock), false) => "unknown lockfile".to_string(), + _ => "no lockfile".to_string(), + }; + + ( + format!( + "{} {}({})", + manifest_version, + if is_git { "(git manifest)" } else { "" }, + lock_version + ), + found_tauri_versions, + ) + } + }; + + let tauri_version = found_tauri_versions + .into_iter() + .map(|v| semver::Version::parse(&v).unwrap()) + .max(); + let suffix = match (tauri_version, crate_latest_version("tauri")) { + (Some(version), Some(target_version)) => { + let target_version = semver::Version::parse(&target_version).unwrap(); + if version < target_version { + Some(format!(" (outdated, latest: {})", target_version)) + } else { + None + } + } + _ => None, + }; + InfoBlock::new(" tauri.rs") + .value(tauri_version_string) + .suffix(suffix) + .display(); + + if let Ok(config) = get_config(None) { + let config_guard = config.lock().unwrap(); + let config = config_guard.as_ref().unwrap(); + InfoBlock::new(" build-type") + .value(if config.tauri.bundle.active { + "bundle".to_string() + } else { + "build".to_string() + }) + .display(); + InfoBlock::new(" CSP") + .value( + config + .tauri + .security + .csp + .clone() + .unwrap_or_else(|| "unset".to_string()), + ) + .display(); + InfoBlock::new(" distDir") + .value(config.build.dist_dir.to_string()) + .display(); + InfoBlock::new(" devPath") + .value(config.build.dev_path.to_string()) + .display(); + } + + if let Some(app_dir) = app_dir { + if let Ok(package_json) = read_to_string(app_dir.join("package.json")) { + let (framework, bundler) = infer_framework(&package_json); + if let Some(framework) = framework { + InfoBlock::new(" framework") + .value(framework.to_string()) + .display(); + } + if let Some(bundler) = bundler { + InfoBlock::new(" bundler") + .value(bundler.to_string()) + .display(); + } + } else { + println!("package.json not found"); + } + } + + Ok(()) +} + +fn get_package_manager>(file_names: &[T]) -> crate::Result { + let mut use_npm = false; + let mut use_pnpm = false; + let mut use_yarn = false; + + for name in file_names { + if name.as_ref() == "package-lock.json" { + use_npm = true; + } else if name.as_ref() == "pnpm-lock.yaml" { + use_pnpm = true; + } else if name.as_ref() == "yarn.lock" { + use_yarn = true; + } + } + + if !use_npm && !use_pnpm && !use_yarn { + println!("WARNING: no lock files found, defaulting to npm"); + return Ok(PackageManager::Npm); + } + + let mut found = Vec::new(); + + if use_npm { + found.push("npm"); + } + if use_pnpm { + found.push("pnpm"); + } + if use_yarn { + found.push("yarn"); + } + + if found.len() > 1 { + return Err(anyhow::anyhow!( + "only one package mangager should be used, but found {}\nplease remove unused package manager lock files", + found.join(" and ") + )); + } + + if use_npm { + Ok(PackageManager::Npm) + } else if use_pnpm { + Ok(PackageManager::Pnpm) + } else { + Ok(PackageManager::Yarn) + } +} diff --git a/tooling/cli/src/init.rs b/tooling/cli/src/init.rs new file mode 100644 index 000000000000..fb7cdc9bde23 --- /dev/null +++ b/tooling/cli/src/init.rs @@ -0,0 +1,206 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::{ + helpers::{ + framework::{infer_from_package_json as infer_framework, Framework}, + resolve_tauri_path, template, Logger, + }, + VersionMetadata, +}; +use std::{ + collections::BTreeMap, + env::current_dir, + fmt::Display, + fs::{read_to_string, remove_dir_all}, + path::PathBuf, + str::FromStr, +}; + +use crate::Result; +use anyhow::Context; +use clap::Parser; +use dialoguer::Input; +use handlebars::{to_json, Handlebars}; +use include_dir::{include_dir, Dir}; +use serde::Deserialize; + +const TEMPLATE_DIR: Dir<'_> = include_dir!("templates/app"); + +#[derive(Debug, Parser)] +#[clap(about = "Initializes a Tauri project")] +pub struct Options { + /// Skip prompting for values + #[clap(long)] + ci: bool, + /// Force init to overwrite the src-tauri folder + #[clap(short, long)] + force: bool, + /// Enables logging + #[clap(short, long)] + log: bool, + /// Set target directory for init + #[clap(short, long)] + #[clap(default_value_t = current_dir().expect("failed to read cwd").display().to_string())] + directory: String, + /// Path of the Tauri project to use (relative to the cwd) + #[clap(short, long)] + tauri_path: Option, + /// Name of your Tauri application + #[clap(short = 'A', long)] + app_name: Option, + /// Window title of your Tauri application + #[clap(short = 'W', long)] + window_title: Option, + /// Web assets location, relative to /src-tauri + #[clap(short = 'D', long)] + dist_dir: Option, + /// Url of your dev server + #[clap(short = 'P', long)] + dev_path: Option, +} + +#[derive(Deserialize)] +struct PackageJson { + name: Option, + product_name: Option, +} + +#[derive(Default)] +struct InitDefaults { + app_name: Option, + framework: Option, +} + +impl Options { + fn load(mut self) -> Result { + self.ci = self.ci || std::env::var("CI").is_ok(); + let package_json_path = PathBuf::from(&self.directory).join("package.json"); + + let init_defaults = if package_json_path.exists() { + let package_json_text = read_to_string(package_json_path)?; + let package_json: PackageJson = serde_json::from_str(&package_json_text)?; + let (framework, _) = infer_framework(&package_json_text); + InitDefaults { + app_name: package_json.product_name.or(package_json.name), + framework, + } + } else { + Default::default() + }; + + self.app_name = self.app_name.or(request_input( + "What is your app name?", + init_defaults.app_name.clone(), + self.ci, + )?); + + self.window_title = self.window_title.or(request_input( + "What should the window title be?", + init_defaults.app_name.clone(), + self.ci, + )?); + + self.dist_dir = self.dist_dir + .or(request_input( + r#"Where are your web assets (HTML/CSS/JS) located, relative to the "/src-tauri/tauri.conf.json" file that will be created?"#, + init_defaults.framework.as_ref().map(|f| f.dist_dir()), + self.ci)?); + + self.dev_path = self.dev_path.or(request_input( + "What is the url of your dev server?", + init_defaults.framework.map(|f| f.dev_path()), + self.ci, + )?); + + Ok(self) + } +} + +pub fn command(mut options: Options) -> Result<()> { + options = options.load()?; + let logger = Logger::new("tauri:init"); + + let template_target_path = PathBuf::from(&options.directory).join("src-tauri"); + let metadata = serde_json::from_str::(include_str!("../metadata.json"))?; + + if template_target_path.exists() && !options.force { + logger.warn(format!( + "Tauri dir ({:?}) not empty. Run `init --force` to overwrite.", + template_target_path + )); + } else { + let (tauri_dep, tauri_build_dep) = if let Some(tauri_path) = options.tauri_path { + ( + format!( + r#"{{ path = {:?}, features = [ "api-all" ] }}"#, + resolve_tauri_path(&tauri_path, "core/tauri") + ), + format!( + "{{ path = {:?} }}", + resolve_tauri_path(&tauri_path, "core/tauri-build") + ), + ) + } else { + ( + format!( + r#"{{ version = "{}", features = [ "api-all" ] }}"#, + metadata.tauri + ), + format!(r#"{{ version = "{}" }}"#, metadata.tauri_build), + ) + }; + + let _ = remove_dir_all(&template_target_path); + let handlebars = Handlebars::new(); + + let mut data = BTreeMap::new(); + data.insert("tauri_dep", to_json(tauri_dep)); + data.insert("tauri_build_dep", to_json(tauri_build_dep)); + data.insert( + "dist_dir", + to_json(options.dist_dir.unwrap_or_else(|| "../dist".to_string())), + ); + data.insert( + "dev_path", + to_json( + options + .dev_path + .unwrap_or_else(|| "http://localhost:4000".to_string()), + ), + ); + data.insert( + "app_name", + to_json(options.app_name.unwrap_or_else(|| "Tauri App".to_string())), + ); + data.insert( + "window_title", + to_json(options.window_title.unwrap_or_else(|| "Tauri".to_string())), + ); + + template::render(&handlebars, &data, &TEMPLATE_DIR, &options.directory) + .with_context(|| "failed to render Tauri template")?; + } + + Ok(()) +} + +fn request_input(prompt: &str, default: Option, skip: bool) -> Result> +where + T: Clone + FromStr + Display, + T::Err: Display + std::fmt::Debug, +{ + if skip { + Ok(default) + } else { + let mut builder = Input::new(); + builder.with_prompt(prompt); + + if let Some(v) = default { + builder.default(v); + } + + builder.interact_text().map(Some).map_err(Into::into) + } +} diff --git a/tooling/cli.rs/src/interface/mod.rs b/tooling/cli/src/interface/mod.rs similarity index 100% rename from tooling/cli.rs/src/interface/mod.rs rename to tooling/cli/src/interface/mod.rs diff --git a/tooling/cli.rs/src/interface/rust.rs b/tooling/cli/src/interface/rust.rs similarity index 82% rename from tooling/cli.rs/src/interface/rust.rs rename to tooling/cli/src/interface/rust.rs index 85b9903d4636..64ca0659b8a2 100644 --- a/tooling/cli.rs/src/interface/rust.rs +++ b/tooling/cli/src/interface/rust.rs @@ -12,13 +12,21 @@ use std::{ use anyhow::Context; #[cfg(target_os = "linux")] -use heck::KebabCase; +use heck::ToKebabCase; use serde::Deserialize; -use crate::helpers::{app_paths::tauri_dir, config::Config, manifest::Manifest}; +use crate::{ + helpers::{ + app_paths::tauri_dir, + config::{wix_settings, Config}, + manifest::Manifest, + Logger, + }, + CommandExt, +}; use tauri_bundler::{ AppCategory, BundleBinary, BundleSettings, DebianSettings, MacOsSettings, PackageSettings, - UpdaterSettings, WindowsSettings, WixSettings, + UpdaterSettings, WindowsSettings, }; /// The `workspace` section of the app configuration (read from Cargo.toml). @@ -38,11 +46,11 @@ struct BinarySettings { #[derive(Debug, Clone, Deserialize)] pub struct CargoPackageSettings { /// the package's name. - pub name: String, + pub name: Option, /// the package's version. - pub version: String, + pub version: Option, /// the package's description. - pub description: String, + pub description: Option, /// the package's homepage. pub homepage: Option, /// the package's authors. @@ -115,6 +123,8 @@ pub fn build_project( command.arg("--release"); } + command.pipe()?; + let status = command .status() .with_context(|| format!("failed to run {}", runner))?; @@ -148,17 +158,22 @@ impl AppSettings { }; let package_settings = PackageSettings { - product_name: config - .package - .product_name - .clone() - .unwrap_or_else(|| cargo_package_settings.name.clone()), - version: config - .package - .version + product_name: config.package.product_name.clone().unwrap_or_else(|| { + cargo_package_settings + .name + .clone() + .expect("Cargo manifest must have the `package.name` field") + }), + version: config.package.version.clone().unwrap_or_else(|| { + cargo_package_settings + .version + .clone() + .expect("Cargo manifest must have the `package.version` field") + }), + description: cargo_package_settings + .description .clone() - .unwrap_or_else(|| cargo_package_settings.version.clone()), - description: cargo_package_settings.description.clone(), + .unwrap_or_default(), homepage: cargo_package_settings.homepage.clone(), authors: cargo_package_settings.authors.clone(), default_run: cargo_package_settings.default_run.clone(), @@ -208,7 +223,7 @@ impl AppSettings { .unwrap_or_else(|| "".to_string()); for binary in bin { binaries.push( - if binary.name.as_str() == self.cargo_package_settings.name + if Some(&binary.name) == self.cargo_package_settings.name.as_ref() || binary.name.as_str() == default_run { BundleBinary::new( @@ -333,18 +348,33 @@ fn get_target_dir( pub fn get_workspace_dir(current_dir: &Path) -> PathBuf { let mut dir = current_dir.to_path_buf(); let project_path = dir.clone(); + let logger = Logger::new("tauri:rust"); while dir.pop() { - if let Ok(cargo_settings) = CargoSettings::load(&dir) { - if let Some(workspace_settings) = cargo_settings.workspace { - if let Some(members) = workspace_settings.members { - if members - .iter() - .any(|member| dir.join(member) == project_path) - { - return dir; + if dir.join("Cargo.toml").exists() { + match CargoSettings::load(&dir) { + Ok(cargo_settings) => { + if let Some(workspace_settings) = cargo_settings.workspace { + if let Some(members) = workspace_settings.members { + if members.iter().any(|member| { + glob::glob(&dir.join(member).to_string_lossy()) + .unwrap() + .any(|p| p.unwrap() == project_path) + }) { + return dir; + } + } } } + Err(e) => { + logger.warn(format!( + "Found `{}`, which may define a parent workspace, but \ + failed to parse it. If this is indeed a parent workspace, undefined behavior may occur: \ + \n {:#}", + dir.display(), + e + )); + } } } } @@ -364,8 +394,9 @@ fn tauri_config_to_bundle_settings( let windows_icon_path = PathBuf::from( config .icon - .as_ref() - .and_then(|icons| icons.iter().find(|i| i.ends_with(".ico")).cloned()) + .iter() + .find(|i| i.ends_with(".ico")) + .cloned() .expect("the bundle config must have a `.ico` icon"), ); #[cfg(not(windows))] @@ -390,6 +421,13 @@ fn tauri_config_to_bundle_settings( depends.push("libgtk-3-0".to_string()); } + #[cfg(windows)] + { + if let Some(webview_fixed_runtime_path) = &config.windows.webview_fixed_runtime_path { + resources.push(webview_fixed_runtime_path.display().to_string()); + } + } + let signing_identity = match std::env::var_os("APPLE_SIGNING_IDENTITY") { Some(signing_identity) => Some( signing_identity @@ -400,9 +438,19 @@ fn tauri_config_to_bundle_settings( None => config.macos.signing_identity, }; + let provider_short_name = match std::env::var_os("APPLE_PROVIDER_SHORT_NAME") { + Some(provider_short_name) => Some( + provider_short_name + .to_str() + .expect("failed to convert APPLE_PROVIDER_SHORT_NAME to string") + .to_string(), + ), + None => config.macos.provider_short_name, + }; + Ok(BundleSettings { - identifier: config.identifier, - icon: config.icon, + identifier: Some(config.identifier), + icon: Some(config.icon), resources: if resources.is_empty() { None } else { @@ -435,6 +483,7 @@ fn tauri_config_to_bundle_settings( use_bootstrapper: Some(config.macos.use_bootstrapper), exception_domain: config.macos.exception_domain, signing_identity, + provider_short_name, entitlements: config.macos.entitlements, info_plist_path: { let path = tauri_dir().join("Info.plist"); @@ -450,19 +499,22 @@ fn tauri_config_to_bundle_settings( digest_algorithm: config.windows.digest_algorithm, certificate_thumbprint: config.windows.certificate_thumbprint, wix: config.windows.wix.map(|w| { - let mut wix = WixSettings::from(w); + let mut wix = wix_settings(w); wix.license = wix.license.map(|l| tauri_dir().join(l)); wix }), icon_path: windows_icon_path, + webview_fixed_runtime_path: config.windows.webview_fixed_runtime_path, }, updater: Some(UpdaterSettings { active: updater_config.active, // we set it to true by default we shouldn't have to use // unwrap_or as we have a default value but used to prevent any failing - dialog: updater_config.dialog.unwrap_or(true), + dialog: updater_config.dialog, pubkey: updater_config.pubkey, - endpoints: updater_config.endpoints, + endpoints: updater_config + .endpoints + .map(|endpoints| endpoints.iter().map(|e| e.to_string()).collect()), }), ..Default::default() }) diff --git a/tooling/cli/src/lib.rs b/tooling/cli/src/lib.rs new file mode 100644 index 000000000000..c64af10d18e4 --- /dev/null +++ b/tooling/cli/src/lib.rs @@ -0,0 +1,104 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +pub use anyhow::Result; + +mod build; +mod dev; +mod helpers; +mod info; +mod init; +mod interface; +mod plugin; +mod signer; + +use clap::{AppSettings, FromArgMatches, IntoApp, Parser, Subcommand}; + +use std::ffi::OsString; + +pub(crate) trait CommandExt { + fn pipe(&mut self) -> Result<&mut Self>; +} + +impl CommandExt for std::process::Command { + fn pipe(&mut self) -> Result<&mut Self> { + self.stdout(os_pipe::dup_stdout()?); + self.stderr(os_pipe::dup_stderr()?); + Ok(self) + } +} + +#[derive(serde::Deserialize)] +pub struct VersionMetadata { + tauri: String, + #[serde(rename = "tauri-build")] + tauri_build: String, +} + +#[derive(Parser)] +#[clap(author, version, about, bin_name("cargo-tauri"))] +#[clap(global_setting(AppSettings::PropagateVersion))] +#[clap(global_setting(AppSettings::UseLongFormatForHelpSubcommand))] +#[clap(global_setting(AppSettings::NoBinaryName))] +#[clap(setting(AppSettings::SubcommandRequiredElseHelp))] +struct Cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + Build(build::Options), + Dev(dev::Options), + Info(info::Options), + Init(init::Options), + Plugin(plugin::Cli), + Signer(signer::Cli), +} + +fn format_error(err: clap::Error) -> clap::Error { + let mut app = I::into_app(); + err.format(&mut app) +} + +/// Run the Tauri CLI with the passed arguments. +/// +/// The passed arguments should have the binary argument(s) stripped out before being passed. +/// +/// e.g. +/// 1. `tauri-cli 1 2 3` -> `1 2 3` +/// 2. `cargo tauri 1 2 3` -> `1 2 3` +/// 3. `node tauri.js 1 2 3` -> `1 2 3` +/// +/// The passed `bin_name` parameter should be how you want the help messages to display the command. +/// This defaults to `cargo-tauri`, but should be set to how the program was called, such as +/// `cargo tauri`. +pub fn run(args: I, bin_name: Option) -> Result<()> +where + I: IntoIterator, + A: Into + Clone, +{ + let matches = match bin_name { + Some(bin_name) => Cli::into_app().bin_name(bin_name), + None => Cli::into_app(), + } + .get_matches_from(args); + + let res = Cli::from_arg_matches(&matches).map_err(format_error::); + let cli = match res { + Ok(s) => s, + Err(e) => e.exit(), + }; + + match cli.command { + Commands::Build(options) => build::command(options)?, + Commands::Dev(options) => dev::command(options)?, + Commands::Info(options) => info::command(options)?, + Commands::Init(options) => init::command(options)?, + Commands::Plugin(cli) => plugin::command(cli)?, + Commands::Signer(cli) => signer::command(cli)?, + } + + Ok(()) +} diff --git a/tooling/cli/src/main.rs b/tooling/cli/src/main.rs new file mode 100644 index 000000000000..0f088c4a6483 --- /dev/null +++ b/tooling/cli/src/main.rs @@ -0,0 +1,34 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::env::args_os; +use std::ffi::OsStr; +use std::path::Path; +use std::process::exit; + +fn main() -> tauri_cli::Result<()> { + let mut args = args_os(); + let bin_name = match args + .next() + .as_deref() + .map(Path::new) + .and_then(Path::file_stem) + .and_then(OsStr::to_str) + { + Some("cargo-tauri") => { + if args.by_ref().peekable().peek().and_then(|s| s.to_str()) == Some("tauri") { + Some("cargo tauri".into()) + } else { + Some("cargo-tauri".into()) + } + } + Some(stem) => Some(stem.to_string()), + None => { + eprintln!("cargo-tauri wrapper unable to read first argument"); + exit(1); + } + }; + + tauri_cli::run(args, bin_name) +} diff --git a/tooling/cli/src/plugin.rs b/tooling/cli/src/plugin.rs new file mode 100644 index 000000000000..dcb3c23fbb5a --- /dev/null +++ b/tooling/cli/src/plugin.rs @@ -0,0 +1,30 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use clap::{AppSettings, Parser, Subcommand}; + +use crate::Result; + +mod init; + +#[derive(Parser)] +#[clap(author, version, about = "Manage Tauri plugins")] +#[clap(setting(AppSettings::SubcommandRequiredElseHelp))] +pub struct Cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + Init(init::Options), +} + +pub fn command(cli: Cli) -> Result<()> { + match cli.command { + Commands::Init(options) => init::command(options)?, + } + + Ok(()) +} diff --git a/tooling/cli/src/plugin/init.rs b/tooling/cli/src/plugin/init.rs new file mode 100644 index 000000000000..3ae7f7287b85 --- /dev/null +++ b/tooling/cli/src/plugin/init.rs @@ -0,0 +1,149 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::Result; +use crate::{ + helpers::{resolve_tauri_path, template, Logger}, + VersionMetadata, +}; +use anyhow::Context; +use clap::{ArgSettings, Parser}; +use handlebars::{to_json, Handlebars}; +use heck::{ToKebabCase, ToSnakeCase}; +use include_dir::{include_dir, Dir}; +use std::{collections::BTreeMap, env::current_dir, fs::remove_dir_all, path::PathBuf}; + +const BACKEND_PLUGIN_DIR: Dir<'_> = include_dir!("templates/plugin/backend"); +const API_PLUGIN_DIR: Dir<'_> = include_dir!("templates/plugin/with-api"); + +#[derive(Debug, Parser)] +#[clap(about = "Initializes a Tauri plugin project")] +pub struct Options { + /// Name of your Tauri plugin + #[clap(short = 'n', long = "name")] + plugin_name: String, + /// Initializes a Tauri plugin with TypeScript API + #[clap(long)] + api: bool, + /// Initializes a Tauri core plugin (internal usage) + #[clap(long, hide(true))] + #[clap(setting(ArgSettings::Hidden))] + tauri: bool, + /// Set target directory for init + #[clap(short, long)] + #[clap(default_value_t = current_dir().expect("failed to read cwd").display().to_string())] + directory: String, + /// Path of the Tauri project to use (relative to the cwd) + #[clap(short, long)] + tauri_path: Option, + /// Author name + #[clap(short, long)] + author: Option, +} + +impl Options { + fn load(&mut self) { + if self.author.is_none() { + self.author.replace(if self.tauri { + "Tauri Programme within The Commons Conservancy".into() + } else { + "You".into() + }); + } + } +} + +pub fn command(mut options: Options) -> Result<()> { + options.load(); + let logger = Logger::new("tauri:init:plugin"); + let template_target_path = PathBuf::from(options.directory).join(&format!( + "tauri-plugin-{}", + options.plugin_name.to_kebab_case() + )); + let metadata = serde_json::from_str::(include_str!("../../metadata.json"))?; + if template_target_path.exists() { + logger.warn(format!( + "Plugin dir ({:?}) not empty.", + template_target_path + )); + } else { + let (tauri_dep, tauri_example_dep, tauri_build_dep) = + if let Some(tauri_path) = options.tauri_path { + ( + format!( + r#"{{ path = {:?} }}"#, + resolve_tauri_path(&tauri_path, "core/tauri") + ), + format!( + r#"{{ path = {:?}, features = [ "api-all" ] }}"#, + resolve_tauri_path(&tauri_path, "core/tauri") + ), + format!( + "{{ path = {:?} }}", + resolve_tauri_path(&tauri_path, "core/tauri-build") + ), + ) + } else { + ( + format!(r#"{{ version = "{}" }}"#, metadata.tauri), + format!( + r#"{{ version = "{}", features = [ "api-all" ] }}"#, + metadata.tauri + ), + format!(r#"{{ version = "{}" }}"#, metadata.tauri_build), + ) + }; + + let _ = remove_dir_all(&template_target_path); + let handlebars = Handlebars::new(); + + let mut data = BTreeMap::new(); + data.insert("plugin_name_original", to_json(&options.plugin_name)); + data.insert("plugin_name", to_json(options.plugin_name.to_kebab_case())); + data.insert( + "plugin_name_snake_case", + to_json(options.plugin_name.to_snake_case()), + ); + data.insert("tauri_dep", to_json(tauri_dep)); + data.insert("tauri_example_dep", to_json(tauri_example_dep)); + data.insert("tauri_build_dep", to_json(tauri_build_dep)); + data.insert("author", to_json(options.author)); + + if options.tauri { + data.insert( + "license_template", + to_json( + "// Copyright {20\\d{2}(-20\\d{2})?} Tauri Programme within The Commons Conservancy + // SPDX-License-Identifier: Apache-2.0 + // SPDX-License-Identifier: MIT\n\n" + .replace(" ", "") + .replace(" //", "//"), + ), + ); + data.insert( + "license_header", + to_json( + "// Copyright 2019-2021 Tauri Programme within The Commons Conservancy + // SPDX-License-Identifier: Apache-2.0 + // SPDX-License-Identifier: MIT\n\n" + .replace(" ", "") + .replace(" //", "//"), + ), + ); + } + + template::render( + &handlebars, + &data, + if options.api { + &API_PLUGIN_DIR + } else { + &BACKEND_PLUGIN_DIR + }, + &template_target_path, + ) + .with_context(|| "failed to render Tauri template")?; + } + Ok(()) +} diff --git a/tooling/cli/src/signer.rs b/tooling/cli/src/signer.rs new file mode 100644 index 000000000000..78c212e1d971 --- /dev/null +++ b/tooling/cli/src/signer.rs @@ -0,0 +1,31 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::Result; +use clap::{AppSettings, Parser, Subcommand}; + +mod generate; +mod sign; + +#[derive(Parser)] +#[clap(author, version, about = "Tauri updater signer")] +#[clap(setting(AppSettings::SubcommandRequiredElseHelp))] +pub struct Cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + Sign(sign::Options), + Generate(generate::Options), +} + +pub fn command(cli: Cli) -> Result<()> { + match cli.command { + Commands::Sign(options) => sign::command(options)?, + Commands::Generate(options) => generate::command(options)?, + } + Ok(()) +} diff --git a/tooling/cli/src/signer/generate.rs b/tooling/cli/src/signer/generate.rs new file mode 100644 index 000000000000..8ccaa94ab6db --- /dev/null +++ b/tooling/cli/src/signer/generate.rs @@ -0,0 +1,56 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::{ + helpers::updater_signature::{generate_key, save_keypair}, + Result, +}; +use clap::Parser; +use std::path::PathBuf; + +#[derive(Debug, Parser)] +#[clap(about = "Generate keypair to sign files")] +pub struct Options { + /// Set private key password when signing + #[clap(short, long)] + password: Option, + /// Write private key to a file + #[clap(short, long)] + write_keys: Option, + /// Overwrite private key even if it exists on the specified path + #[clap(short, long)] + force: bool, +} + +pub fn command(options: Options) -> Result<()> { + if options.password.is_none() { + println!("Generating new private key without password.") + } + let keypair = generate_key(options.password).expect("Failed to generate key"); + + if let Some(output_path) = options.write_keys { + let (secret_path, public_path) = + save_keypair(options.force, output_path, &keypair.sk, &keypair.pk) + .expect("Unable to write keypair"); + + println!( + "\nYour keypair was generated successfully\nPrivate: {} (Keep it secret!)\nPublic: {}\n---------------------------", + secret_path.display(), + public_path.display() + ) + } else { + println!( + "\nYour secret key was generated successfully - Keep it secret!\n{}\n\n", + keypair.sk + ); + println!( + "Your public key was generated successfully:\n{}\n\nAdd the public key in your tauri.conf.json\n---------------------------\n", + keypair.pk + ); + } + + println!("\nEnvironment variabled used to sign:\n`TAURI_PRIVATE_KEY` Path or String of your private key\n`TAURI_KEY_PASSWORD` Your private key password (optional)\n\nATTENTION: If you lose your private key OR password, you'll not be able to sign your update package and updates will not works.\n---------------------------\n"); + + Ok(()) +} diff --git a/tooling/cli/src/signer/sign.rs b/tooling/cli/src/signer/sign.rs new file mode 100644 index 000000000000..99c21b7b34ab --- /dev/null +++ b/tooling/cli/src/signer/sign.rs @@ -0,0 +1,61 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::path::{Path, PathBuf}; + +use crate::{ + helpers::updater_signature::{read_key_from_file, sign_file}, + Result, +}; +use anyhow::Context; +use clap::Parser; + +#[derive(Debug, Parser)] +#[clap(about = "Sign a file")] +pub struct Options { + /// Load the private key from a file + #[clap(short = 'k', long, conflicts_with("private_key_path"))] + private_key: Option, + /// Load the private key from a string + #[clap(short = 'f', long, conflicts_with("private_key"))] + private_key_path: Option, + /// Set private key password when signing + #[clap(short, long)] + password: Option, + /// Sign the specified file + #[clap(short, long)] + file: Option, +} + +pub fn command(mut options: Options) -> Result<()> { + options.private_key = if let Some(private_key) = options.private_key_path { + Some(read_key_from_file(Path::new(&private_key)).expect("Unable to extract private key")) + } else { + options.private_key + }; + if options.private_key.is_none() { + return Err(anyhow::anyhow!( + "Key generation aborted: Unable to find the private key".to_string(), + )); + } + + if options.password.is_none() { + println!("Signing without password."); + } + + let (manifest_dir, signature) = sign_file( + options.private_key.unwrap(), + options.password.unwrap(), + options.file.unwrap(), + ) + .with_context(|| "failed to sign file")?; + + println!( + "\nYour file was signed successfully, You can find the signature here:\n{}\n\nPublic signature:\n{}\n\nMake sure to include this into the signature field of your update server.", + manifest_dir.display(), + signature + ); + + Ok(()) +} diff --git a/tooling/cli.rs/templates/src-tauri/.gitignore b/tooling/cli/templates/app/src-tauri/.gitignore similarity index 100% rename from tooling/cli.rs/templates/src-tauri/.gitignore rename to tooling/cli/templates/app/src-tauri/.gitignore diff --git a/tooling/cli/templates/app/src-tauri/Cargo.crate-manifest b/tooling/cli/templates/app/src-tauri/Cargo.crate-manifest new file mode 100755 index 000000000000..af7a0e6439cc --- /dev/null +++ b/tooling/cli/templates/app/src-tauri/Cargo.crate-manifest @@ -0,0 +1,24 @@ +[package] +name = "app" +version = "0.1.0" +description = "A Tauri App" +authors = ["you"] +license = "" +repository = "" +default-run = "app" +edition = "2021" +rust-version = "1.57" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +tauri-build = {{{ tauri_build_dep }}} + +[dependencies] +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +tauri = {{{ tauri_dep }}} + +[features] +default = [ "custom-protocol" ] +custom-protocol = [ "tauri/custom-protocol" ] diff --git a/tooling/cli.rs/templates/src-tauri/src/build.rs b/tooling/cli/templates/app/src-tauri/build.rs similarity index 100% rename from tooling/cli.rs/templates/src-tauri/src/build.rs rename to tooling/cli/templates/app/src-tauri/build.rs diff --git a/tooling/cli.rs/templates/src-tauri/icons/128x128.png b/tooling/cli/templates/app/src-tauri/icons/128x128.png similarity index 100% rename from tooling/cli.rs/templates/src-tauri/icons/128x128.png rename to tooling/cli/templates/app/src-tauri/icons/128x128.png diff --git a/tooling/cli.rs/templates/src-tauri/icons/128x128@2x.png b/tooling/cli/templates/app/src-tauri/icons/128x128@2x.png similarity index 100% rename from tooling/cli.rs/templates/src-tauri/icons/128x128@2x.png rename to tooling/cli/templates/app/src-tauri/icons/128x128@2x.png diff --git a/tooling/cli.rs/templates/src-tauri/icons/32x32.png b/tooling/cli/templates/app/src-tauri/icons/32x32.png similarity index 100% rename from tooling/cli.rs/templates/src-tauri/icons/32x32.png rename to tooling/cli/templates/app/src-tauri/icons/32x32.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square107x107Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square107x107Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square107x107Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square107x107Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square142x142Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square142x142Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square142x142Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square142x142Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square150x150Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square150x150Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square150x150Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square150x150Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square284x284Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square284x284Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square284x284Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square284x284Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square30x30Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square30x30Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square30x30Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square30x30Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square310x310Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square310x310Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square310x310Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square310x310Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square44x44Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square44x44Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square44x44Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square44x44Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square71x71Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square71x71Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square71x71Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square71x71Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square89x89Logo.png b/tooling/cli/templates/app/src-tauri/icons/Square89x89Logo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/Square89x89Logo.png rename to tooling/cli/templates/app/src-tauri/icons/Square89x89Logo.png diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/StoreLogo.png b/tooling/cli/templates/app/src-tauri/icons/StoreLogo.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/StoreLogo.png rename to tooling/cli/templates/app/src-tauri/icons/StoreLogo.png diff --git a/tooling/cli/templates/app/src-tauri/icons/icon.icns b/tooling/cli/templates/app/src-tauri/icons/icon.icns new file mode 100644 index 000000000000..8254645a797e Binary files /dev/null and b/tooling/cli/templates/app/src-tauri/icons/icon.icns differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/icon.ico b/tooling/cli/templates/app/src-tauri/icons/icon.ico similarity index 100% rename from tooling/cli.rs/templates/src-tauri/icons/icon.ico rename to tooling/cli/templates/app/src-tauri/icons/icon.ico diff --git a/tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/icon.png b/tooling/cli/templates/app/src-tauri/icons/icon.png similarity index 100% rename from tooling/cli.js/test/jest/fixtures/app/src-tauri/icons/icon.png rename to tooling/cli/templates/app/src-tauri/icons/icon.png diff --git a/tooling/cli.rs/templates/src-tauri/src/main.rs b/tooling/cli/templates/app/src-tauri/src/main.rs similarity index 100% rename from tooling/cli.rs/templates/src-tauri/src/main.rs rename to tooling/cli/templates/app/src-tauri/src/main.rs diff --git a/tooling/cli/templates/app/src-tauri/tauri.conf.json b/tooling/cli/templates/app/src-tauri/tauri.conf.json new file mode 100644 index 000000000000..18a565facd7e --- /dev/null +++ b/tooling/cli/templates/app/src-tauri/tauri.conf.json @@ -0,0 +1,68 @@ +{ + "package": { + "productName": "{{ app_name }}", + "version": "0.1.0" + }, + "build": { + "distDir": "{{ dist_dir }}", + "devPath": "{{ dev_path }}", + "beforeDevCommand": "", + "beforeBuildCommand": "" + }, + "tauri": { + "bundle": { + "active": true, + "targets": "all", + "identifier": "com.tauri.dev", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ], + "resources": [], + "externalBin": [], + "copyright": "", + "category": "DeveloperTool", + "shortDescription": "", + "longDescription": "", + "deb": { + "depends": [], + "useBootstrapper": false + }, + "macOS": { + "frameworks": [], + "minimumSystemVersion": "", + "useBootstrapper": false, + "exceptionDomain": "", + "signingIdentity": null, + "providerShortName": null, + "entitlements": null + }, + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "" + } + }, + "updater": { + "active": false + }, + "allowlist": { + "all": true + }, + "windows": [ + { + "title": "{{ window_title }}", + "width": 800, + "height": 600, + "resizable": true, + "fullscreen": false + } + ], + "security": { + "csp": "default-src 'self'" + } + } +} diff --git a/tooling/cli/templates/plugin/backend/.changes/config.json b/tooling/cli/templates/plugin/backend/.changes/config.json new file mode 100755 index 000000000000..b3198aabbdb8 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.changes/config.json @@ -0,0 +1,16 @@ +{ + "gitSiteUrl": "https://www.github.com/your-org/tauri-plugin-{{ plugin_name }}/", + "pkgManagers": { + "rust": { + "version": true, + "publish": true, + "getPublishedVersion": "cargo search ${ pkg.pkg } --limit 1 | sed -nE 's/^[^\"]*\"//; s/\".*//1p' -" + } + }, + "packages": { + "tauri-plugin-{{ plugin_name }}": { + "path": ".", + "manager": "rust" + } + } +} diff --git a/tooling/cli/templates/plugin/backend/.changes/initial-release.md b/tooling/cli/templates/plugin/backend/.changes/initial-release.md new file mode 100644 index 000000000000..fce69c81832a --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.changes/initial-release.md @@ -0,0 +1,5 @@ +--- +"tauri-plugin-{{ plugin_name }}": "minor" +--- + +Initial release. diff --git a/tooling/cli/templates/plugin/backend/.changes/readme.md b/tooling/cli/templates/plugin/backend/.changes/readme.md new file mode 100755 index 000000000000..a45c980ddfd1 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.changes/readme.md @@ -0,0 +1,16 @@ +# Changes +##### via https://github.com/jbolda/covector + +As you create PRs and make changes that require a version bump, please add a new markdown file in this folder. You do not note the version *number*, but rather the type of bump that you expect: major, minor, or patch. The filename is not important, as long as it is a `.md`, but we recommend it represents the overall change for our sanity. + +When you select the version bump required, you do *not* need to consider depedencies. Only note the package with the actual change, and any packages that depend on that package will be bumped automatically in the process. + +Use the following format: +```md +--- +"tauri-plugin-{{ plugin_name }}": patch +--- + +Change summary goes here + +``` \ No newline at end of file diff --git a/tooling/cli/templates/plugin/backend/.github/workflows/audit.yml b/tooling/cli/templates/plugin/backend/.github/workflows/audit.yml new file mode 100644 index 000000000000..725615b410ee --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.github/workflows/audit.yml @@ -0,0 +1,28 @@ +{{{{raw}}}} +name: Audit + +on: + schedule: + - cron: '0 0 * * *' + push: + branches: + - main + paths: + - "**/Cargo.lock" + - "**/Cargo.toml" + pull_request: + branches: + - main + paths: + - "**/Cargo.lock" + - "**/Cargo.toml" + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/backend/.github/workflows/covector-status.yml b/tooling/cli/templates/plugin/backend/.github/workflows/covector-status.yml new file mode 100755 index 000000000000..e963b37cb842 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.github/workflows/covector-status.yml @@ -0,0 +1,17 @@ +{{{{raw}}}} +name: covector status +on: [pull_request] + +jobs: + covector: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: covector status + uses: jbolda/covector/packages/action@covector-v0 + with: + command: 'status' +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/backend/.github/workflows/covector-version-or-publish.yml b/tooling/cli/templates/plugin/backend/.github/workflows/covector-version-or-publish.yml new file mode 100755 index 000000000000..a055cf1caaf2 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.github/workflows/covector-version-or-publish.yml @@ -0,0 +1,39 @@ +{{{{raw}}}} +name: covector version or publish +on: + push: + branches: + - dev + +jobs: + covector: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-node@v2 + with: + node-version: 12 + registry-url: 'https://registry.npmjs.org' + - name: git config + run: | + git config --global user.name "${{ github.event.pusher.name }}" + git config --global user.email "${{ github.event.pusher.email }}" + - name: covector version-or-publish + uses: jbolda/covector/packages/action@covector-v0 + id: covector + with: + token: ${{ secrets.GITHUB_TOKEN }} + command: 'version-or-publish' + createRelease: true + - name: create pull request + id: cpr + uses: tauri-apps/create-pull-request@v2.8.0 + with: + title: "Publish New Versions" + labels: "version updates" + branch: "release" + body: ${{ steps.covector.outputs.change }} +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/backend/.github/workflows/format.yml b/tooling/cli/templates/plugin/backend/.github/workflows/format.yml new file mode 100644 index 000000000000..2474d1612036 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.github/workflows/format.yml @@ -0,0 +1,32 @@ +{{{{raw}}}} +name: Format + +on: + push: + branches: + - main + pull_request: + branches: + - main + - dev + +jobs: + format: + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - name: Install rustfmt with nightly toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true + components: rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --manifest-path=Cargo.toml --all -- --check +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/backend/.github/workflows/lint.yml b/tooling/cli/templates/plugin/backend/.github/workflows/lint.yml new file mode 100644 index 000000000000..037e7b3b55f8 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.github/workflows/lint.yml @@ -0,0 +1,37 @@ +{{{{raw}}}} +name: Clippy + +on: + push: + branches: + - main + pull_request: + branches: + - main + - dev + +jobs: + clippy: + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - name: install webkit2gtk + run: | + sudo apt-get update + sudo apt-get install -y webkit2gtk-4.0 + - name: Install clippy with stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + components: clippy + - uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --manifest-path=Cargo.toml --all-targets --all-features -- -D warnings + name: clippy +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/backend/.github/workflows/test.yml b/tooling/cli/templates/plugin/backend/.github/workflows/test.yml new file mode 100755 index 000000000000..54435f68ce8e --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.github/workflows/test.yml @@ -0,0 +1,82 @@ +{{{{raw}}}} +name: Test + +on: + push: + branches: + - main + pull_request: + branches: + - main + - dev + paths-ignore: + - 'webview-src/**' + - 'webview-dist/**' + - 'examples/**' + +jobs: + build-and-test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + steps: + - uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Install gtk on Ubuntu + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y webkit2gtk-4.0 + - name: Get current date + if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' + run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV + + - name: Get current date + if: matrix.os == 'windows-latest' + run: echo "CURRENT_DATE=$(Get-Date -Format "yyyy-MM-dd")" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Cache cargo registry + uses: actions/cache@v2 + with: + path: ~/.cargo/registry + # Add date to the cache to keep it up to date + key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-registry-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ${{ matrix.os }}-${{ matrix.rust }}-cargo-registry-${{ hashFiles('**/Cargo.toml') }} + + - name: Cache cargo index + uses: actions/cache@v2 + with: + path: ~/.cargo/git + # Add date to the cache to keep it up to date + key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-index-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ${{ matrix.os }}-${{ matrix.rust }}-cargo-index-${{ hashFiles('**/Cargo.toml') }} + + - name: Cache cargo target + uses: actions/cache@v2 + with: + path: ${{ matrix.project}}/target + # Add date to the cache to keep it up to date + key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-build-target-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ${{ matrix.os }}-${{ matrix.rust }}-cargo-build-target-${{ hashFiles('**/Cargo.toml') }} + + - name: Run tests + uses: actions-rs/cargo@v1 + with: + command: test + args: --manifest-path=Cargo.toml --release +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/backend/.gitignore b/tooling/cli/templates/plugin/backend/.gitignore new file mode 100755 index 000000000000..4fffb2f89cbd --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/tooling/cli/templates/plugin/backend/.license_template b/tooling/cli/templates/plugin/backend/.license_template new file mode 100644 index 000000000000..ca31e10b538f --- /dev/null +++ b/tooling/cli/templates/plugin/backend/.license_template @@ -0,0 +1 @@ +{{ license_template }} \ No newline at end of file diff --git a/tooling/cli/templates/plugin/backend/Cargo.crate-manifest b/tooling/cli/templates/plugin/backend/Cargo.crate-manifest new file mode 100755 index 000000000000..08963b9c9531 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/Cargo.crate-manifest @@ -0,0 +1,11 @@ +[package] +name = "tauri-plugin-{{ plugin_name }}" +version = "0.0.0" +authors = [ "{{ author }}" ] +description = "" +edition = "2021" +rust-version = "1.57" +exclude = ["/examples"] + +[dependencies] +tauri = {{{ tauri_dep }}} diff --git a/tooling/cli/templates/plugin/backend/README.md b/tooling/cli/templates/plugin/backend/README.md new file mode 100644 index 000000000000..84a8a04d53f4 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/README.md @@ -0,0 +1 @@ +# Tauri Plugin {{ plugin_name_original }} diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/.gitignore b/tooling/cli/templates/plugin/backend/examples/vanilla/.gitignore new file mode 100644 index 000000000000..c2658d7d1b31 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/package.json b/tooling/cli/templates/plugin/backend/examples/vanilla/package.json new file mode 100644 index 000000000000..8c608e030e0d --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/package.json @@ -0,0 +1,14 @@ +{ + "name": "app", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "MIT", + "dependencies": { + "@tauri-apps/cli": "^1.0.0-beta.10" + } +} diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/public/index.html b/tooling/cli/templates/plugin/backend/examples/vanilla/public/index.html new file mode 100644 index 000000000000..9c95f40ebe53 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/public/index.html @@ -0,0 +1,5 @@ + + +

    Plugin example
    + + diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/.gitignore b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/.gitignore new file mode 100644 index 000000000000..c1237045915f --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/.gitignore @@ -0,0 +1,4 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +WixTools diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/Cargo.crate-manifest b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/Cargo.crate-manifest new file mode 100644 index 000000000000..4d1f62dcf327 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/Cargo.crate-manifest @@ -0,0 +1,21 @@ +[package] +name = "app" +version = "0.1.0" +description = "A Tauri App" +authors = [ "{{ author }}" ] +repository = "" +edition = "2021" +rust-version = "1.57" + +[dependencies] +serde_json = "1.0" +serde = { version = "1.0", features = [ "derive" ] } +tauri = {{{ tauri_example_dep }}} +tauri-plugin-{{ plugin_name }} = { path = "../../../" } + +[build-dependencies] +tauri-build = {{{ tauri_build_dep }}} + +[features] +default = [ "custom-protocol" ] +custom-protocol = [ "tauri/custom-protocol" ] diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/build.rs b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/build.rs new file mode 100644 index 000000000000..795b9b7c83db --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/128x128.png b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/128x128.png new file mode 100644 index 000000000000..6be5e50e9b9a Binary files /dev/null and b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/128x128.png differ diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/128x128@2x.png b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/128x128@2x.png new file mode 100644 index 000000000000..e81becee571e Binary files /dev/null and b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/128x128@2x.png differ diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/32x32.png b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/32x32.png new file mode 100644 index 000000000000..a437dd51741e Binary files /dev/null and b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/32x32.png differ diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/icon.icns b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/icon.icns new file mode 100644 index 000000000000..8254645a797e Binary files /dev/null and b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/icon.icns differ diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/icon.ico b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/icon.ico new file mode 100644 index 000000000000..b3636e4b22ba Binary files /dev/null and b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/icon.ico differ diff --git a/tooling/cli.rs/templates/src-tauri/icons/icon.png b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/icon.png similarity index 100% rename from tooling/cli.rs/templates/src-tauri/icons/icon.png rename to tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/icons/icon.png diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/rustfmt.toml b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/rustfmt.toml new file mode 100644 index 000000000000..550a09853f31 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/rustfmt.toml @@ -0,0 +1,14 @@ +max_width = 100 +hard_tabs = false +tab_spaces = 2 +newline_style = "Auto" +use_small_heuristics = "Default" +reorder_imports = true +reorder_modules = true +remove_nested_parens = true +edition = "2021" +merge_derives = true +use_try_shorthand = false +use_field_init_shorthand = false +force_explicit_abi = true +imports_granularity = "Crate" diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/src/main.rs b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/src/main.rs new file mode 100644 index 000000000000..dca030873b95 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/src/main.rs @@ -0,0 +1,11 @@ +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] + +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_{{ plugin_name_snake_case }}::YourPlugin::default()) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} diff --git a/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/tauri.conf.json b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/tauri.conf.json new file mode 100644 index 000000000000..67397e517795 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/examples/vanilla/src-tauri/tauri.conf.json @@ -0,0 +1,65 @@ +{ + "package": { + "productName": "app", + "version": "0.1.0" + }, + "build": { + "distDir": "../public", + "devPath": "../public" + }, + "tauri": { + "bundle": { + "active": true, + "targets": "all", + "identifier": "com.tauri.{{ plugin_name }}", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ], + "resources": [], + "externalBin": [], + "copyright": "", + "category": "DeveloperTool", + "shortDescription": "", + "longDescription": "", + "deb": { + "depends": [], + "useBootstrapper": false + }, + "macOS": { + "frameworks": [], + "minimumSystemVersion": "", + "useBootstrapper": false, + "exceptionDomain": "", + "signingIdentity": null, + "entitlements": null + }, + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "" + } + }, + "updater": { + "active": false + }, + "allowlist": { + "all": true + }, + "windows": [ + { + "title": "app", + "width": 800, + "height": 600, + "resizable": true, + "fullscreen": false + } + ], + "security": { + "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'" + } + } +} diff --git a/tooling/cli/templates/plugin/backend/src/lib.rs b/tooling/cli/templates/plugin/backend/src/lib.rs new file mode 100755 index 000000000000..6d8ad8393307 --- /dev/null +++ b/tooling/cli/templates/plugin/backend/src/lib.rs @@ -0,0 +1,13 @@ +{{#if license_header}} +{{ license_header }} +{{/if}} +use tauri::{plugin::Plugin, Runtime}; + +#[derive(Default)] +pub struct YourPlugin {} + +impl Plugin for YourPlugin { + fn name(&self) -> &'static str { + "{{ plugin_name }}" + } +} diff --git a/tooling/cli/templates/plugin/with-api/.changes/config.json b/tooling/cli/templates/plugin/with-api/.changes/config.json new file mode 100755 index 000000000000..7dfed64ecb3a --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.changes/config.json @@ -0,0 +1,26 @@ +{ + "gitSiteUrl": "https://www.github.com/your-org/tauri-plugin-{{ plugin_name }}/", + "pkgManagers": { + "rust": { + "version": true, + "publish": true, + "getPublishedVersion": "cargo search ${ pkg.pkg } --limit 1 | sed -nE 's/^[^\"]*\"//; s/\".*//1p' -" + }, + "javascript": { + "version": true, + "publish": true, + "getPublishedVersion": "npm view ${ pkgFile.pkg.name } version" + } + }, + "packages": { + "tauri-plugin-{{ plugin_name }}": { + "path": ".", + "manager": "rust" + }, + "tauri-plugin-{{ plugin_name }}-api": { + "path": ".", + "manager": "javascript", + "dependencies": ["tauri-plugin-{{ plugin_name }}"] + } + } +} diff --git a/tooling/cli/templates/plugin/with-api/.changes/initial-release.md b/tooling/cli/templates/plugin/with-api/.changes/initial-release.md new file mode 100644 index 000000000000..25379021be15 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.changes/initial-release.md @@ -0,0 +1,6 @@ +--- +"tauri-plugin-{{ plugin_name }}": "minor" +"tauri-plugin-{{ plugin_name }}-api": "minor" +--- + +Initial release. diff --git a/tooling/cli/templates/plugin/with-api/.changes/readme.md b/tooling/cli/templates/plugin/with-api/.changes/readme.md new file mode 100755 index 000000000000..18c42eb10884 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.changes/readme.md @@ -0,0 +1,16 @@ +# Changes +##### via https://github.com/jbolda/covector + +As you create PRs and make changes that require a version bump, please add a new markdown file in this folder. You do not note the version *number*, but rather the type of bump that you expect: major, minor, or patch. The filename is not important, as long as it is a `.md`, but we recommend it represents the overall change for our sanity. + +When you select the version bump required, you do *not* need to consider depedencies. Only note the package with the actual change, and any packages that depend on that package will be bumped automatically in the process. + +Use the following format: +```md +--- +"tauri-plugin-{{ plugin_name }}": patch +--- + +Change summary goes here + +``` diff --git a/tooling/cli/templates/plugin/with-api/.github/workflows/audit.yml b/tooling/cli/templates/plugin/with-api/.github/workflows/audit.yml new file mode 100644 index 000000000000..725615b410ee --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.github/workflows/audit.yml @@ -0,0 +1,28 @@ +{{{{raw}}}} +name: Audit + +on: + schedule: + - cron: '0 0 * * *' + push: + branches: + - main + paths: + - "**/Cargo.lock" + - "**/Cargo.toml" + pull_request: + branches: + - main + paths: + - "**/Cargo.lock" + - "**/Cargo.toml" + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/with-api/.github/workflows/clippy.yml b/tooling/cli/templates/plugin/with-api/.github/workflows/clippy.yml new file mode 100644 index 000000000000..037e7b3b55f8 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.github/workflows/clippy.yml @@ -0,0 +1,37 @@ +{{{{raw}}}} +name: Clippy + +on: + push: + branches: + - main + pull_request: + branches: + - main + - dev + +jobs: + clippy: + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - name: install webkit2gtk + run: | + sudo apt-get update + sudo apt-get install -y webkit2gtk-4.0 + - name: Install clippy with stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + components: clippy + - uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --manifest-path=Cargo.toml --all-targets --all-features -- -D warnings + name: clippy +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/with-api/.github/workflows/covector-version-or-publish.yml b/tooling/cli/templates/plugin/with-api/.github/workflows/covector-version-or-publish.yml new file mode 100644 index 000000000000..a055cf1caaf2 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.github/workflows/covector-version-or-publish.yml @@ -0,0 +1,39 @@ +{{{{raw}}}} +name: covector version or publish +on: + push: + branches: + - dev + +jobs: + covector: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-node@v2 + with: + node-version: 12 + registry-url: 'https://registry.npmjs.org' + - name: git config + run: | + git config --global user.name "${{ github.event.pusher.name }}" + git config --global user.email "${{ github.event.pusher.email }}" + - name: covector version-or-publish + uses: jbolda/covector/packages/action@covector-v0 + id: covector + with: + token: ${{ secrets.GITHUB_TOKEN }} + command: 'version-or-publish' + createRelease: true + - name: create pull request + id: cpr + uses: tauri-apps/create-pull-request@v2.8.0 + with: + title: "Publish New Versions" + labels: "version updates" + branch: "release" + body: ${{ steps.covector.outputs.change }} +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/with-api/.github/workflows/format.yml b/tooling/cli/templates/plugin/with-api/.github/workflows/format.yml new file mode 100644 index 000000000000..2474d1612036 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.github/workflows/format.yml @@ -0,0 +1,32 @@ +{{{{raw}}}} +name: Format + +on: + push: + branches: + - main + pull_request: + branches: + - main + - dev + +jobs: + format: + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - name: Install rustfmt with nightly toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true + components: rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --manifest-path=Cargo.toml --all -- --check +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/with-api/.github/workflows/test.yml b/tooling/cli/templates/plugin/with-api/.github/workflows/test.yml new file mode 100644 index 000000000000..54435f68ce8e --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.github/workflows/test.yml @@ -0,0 +1,82 @@ +{{{{raw}}}} +name: Test + +on: + push: + branches: + - main + pull_request: + branches: + - main + - dev + paths-ignore: + - 'webview-src/**' + - 'webview-dist/**' + - 'examples/**' + +jobs: + build-and-test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + steps: + - uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Install gtk on Ubuntu + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y webkit2gtk-4.0 + - name: Get current date + if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' + run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV + + - name: Get current date + if: matrix.os == 'windows-latest' + run: echo "CURRENT_DATE=$(Get-Date -Format "yyyy-MM-dd")" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Cache cargo registry + uses: actions/cache@v2 + with: + path: ~/.cargo/registry + # Add date to the cache to keep it up to date + key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-registry-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ${{ matrix.os }}-${{ matrix.rust }}-cargo-registry-${{ hashFiles('**/Cargo.toml') }} + + - name: Cache cargo index + uses: actions/cache@v2 + with: + path: ~/.cargo/git + # Add date to the cache to keep it up to date + key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-index-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ${{ matrix.os }}-${{ matrix.rust }}-cargo-index-${{ hashFiles('**/Cargo.toml') }} + + - name: Cache cargo target + uses: actions/cache@v2 + with: + path: ${{ matrix.project}}/target + # Add date to the cache to keep it up to date + key: ${{ matrix.os }}-${{ matrix.rust }}-cargo-build-target-${{ hashFiles('**/Cargo.toml') }}-${{ env.CURRENT_DATE }} + # Restore from outdated cache for speed + restore-keys: | + ${{ matrix.os }}-${{ matrix.rust }}-cargo-build-target-${{ hashFiles('**/Cargo.toml') }} + + - name: Run tests + uses: actions-rs/cargo@v1 + with: + command: test + args: --manifest-path=Cargo.toml --release +{{{{/raw}}}} diff --git a/tooling/cli/templates/plugin/with-api/.gitignore b/tooling/cli/templates/plugin/with-api/.gitignore new file mode 100644 index 000000000000..9ad8f194640d --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.gitignore @@ -0,0 +1,13 @@ +/.vs +.DS_Store +.Thumbs.db +*.sublime* +.idea/ +debug.log +package-lock.json +.vscode/settings.json +yarn.lock + +/target +Cargo.lock +node_modules/ diff --git a/tooling/cli/templates/plugin/with-api/.license_template b/tooling/cli/templates/plugin/with-api/.license_template new file mode 100644 index 000000000000..ca31e10b538f --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/.license_template @@ -0,0 +1 @@ +{{ license_template }} \ No newline at end of file diff --git a/tooling/cli/templates/plugin/with-api/Cargo.crate-manifest b/tooling/cli/templates/plugin/with-api/Cargo.crate-manifest new file mode 100644 index 000000000000..5ef4b0fff88f --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/Cargo.crate-manifest @@ -0,0 +1,14 @@ +[package] +name = "tauri-plugin-{{ plugin_name }}" +version = "0.0.0" +authors = [ "{{ author }}" ] +description = "" +edition = "2021" +rust-version = "1.57" +exclude = ["/examples", "/webview-dist", "/webview-src", "node_modules"] + +[dependencies] +tauri = {{{ tauri_dep }}} +serde = "1.0" +serde_json = "1.0" +thiserror = "1.0" diff --git a/tooling/cli/templates/plugin/with-api/README.md b/tooling/cli/templates/plugin/with-api/README.md new file mode 100644 index 000000000000..84a8a04d53f4 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/README.md @@ -0,0 +1 @@ +# Tauri Plugin {{ plugin_name_original }} diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/.gitignore b/tooling/cli/templates/plugin/with-api/examples/svelte-app/.gitignore new file mode 100644 index 000000000000..072f27e9df58 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +public/build/ +public/index.tauri.html diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/package.json b/tooling/cli/templates/plugin/with-api/examples/svelte-app/package.json new file mode 100644 index 000000000000..99ffa00728e7 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/package.json @@ -0,0 +1,32 @@ +{ + "name": "svelte-app", + "version": "1.0.0", + "scripts": { + "build": "rollup -c", + "dev": "rollup -c -w", + "start": "sirv public", + "validate": "svelte-check", + "tauri": "tauri" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "21.0.1", + "@rollup/plugin-node-resolve": "13.1.3", + "@rollup/plugin-typescript": "8.3.0", + "@tauri-apps/cli": "1.0.0-beta.10", + "@tsconfig/svelte": "3.0.0", + "rollup": "2.67.1", + "rollup-plugin-css-only": "3.1.0", + "rollup-plugin-livereload": "2.0.5", + "rollup-plugin-svelte": "7.1.0", + "rollup-plugin-terser": "7.0.2", + "svelte": "3.46.4", + "svelte-check": "2.4.3", + "svelte-preprocess": "4.10.2", + "tslib": "2.3.1", + "typescript": "4.5.5" + }, + "dependencies": { + "sirv-cli": "2.0.2", + "tauri-plugin-{{ plugin_name }}-api": "link:../../" + } +} diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/favicon.png b/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/favicon.png new file mode 100644 index 000000000000..7e6f5eb5a2f1 Binary files /dev/null and b/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/favicon.png differ diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/global.css b/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/global.css new file mode 100644 index 000000000000..619a92f33190 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/global.css @@ -0,0 +1,68 @@ +html, +body { + position: relative; + width: 100%; + height: 100%; +} + +body { + color: #333; + margin: 0; + padding: 8px; + box-sizing: border-box; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; +} + +a { + color: rgb(0, 100, 200); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:visited { + color: rgb(0, 80, 160); +} + +label { + display: block; +} + +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + -webkit-padding: 0.4em 0; + padding: 0.4em; + margin: 0 0 0.5em 0; + box-sizing: border-box; + border: 1px solid #ccc; + border-radius: 2px; +} + +input:disabled { + color: #ccc; +} + +button { + color: #333; + background-color: #f4f4f4; + outline: none; +} + +button:disabled { + color: #999; +} + +button:not(:disabled):active { + background-color: #ddd; +} + +button:focus { + border-color: #666; +} diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/index.html b/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/index.html new file mode 100644 index 000000000000..1e84363f6b27 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/public/index.html @@ -0,0 +1,17 @@ + + + + + + + Svelte app + + + + + + + + + + diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/rollup.config.js b/tooling/cli/templates/plugin/with-api/examples/svelte-app/rollup.config.js new file mode 100644 index 000000000000..e546b7180702 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/rollup.config.js @@ -0,0 +1,87 @@ +import svelte from 'rollup-plugin-svelte' +import commonjs from '@rollup/plugin-commonjs' +import resolve from '@rollup/plugin-node-resolve' +import livereload from 'rollup-plugin-livereload' +import { terser } from 'rollup-plugin-terser' +import sveltePreprocess from 'svelte-preprocess' +import typescript from '@rollup/plugin-typescript' +import css from 'rollup-plugin-css-only' + +const production = !process.env.ROLLUP_WATCH + +function serve() { + let server + + function toExit() { + if (server) server.kill(0) + } + + return { + writeBundle() { + if (server) return + server = require('child_process').spawn( + 'npm', + ['run', 'start', '--', '--dev'], + { + stdio: ['ignore', 'inherit', 'inherit'], + shell: true + } + ) + + process.on('SIGTERM', toExit) + process.on('exit', toExit) + } + } +} + +export default { + input: 'src/main.ts', + output: { + sourcemap: true, + format: 'iife', + name: 'app', + file: 'public/build/bundle.js' + }, + plugins: [ + svelte({ + preprocess: sveltePreprocess(), + compilerOptions: { + // enable run-time checks when not in production + dev: !production + } + }), + // we'll extract any component CSS out into + // a separate file - better for performance + css({ output: 'bundle.css' }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration - + // consult the documentation for details: + // https://github.com/rollup/plugins/tree/master/packages/commonjs + resolve({ + browser: true, + dedupe: ['svelte'] + }), + commonjs(), + typescript({ + sourceMap: !production, + inlineSources: !production + }), + + // In dev mode, call `npm run start` once + // the bundle has been generated + !production && serve(), + + // Watch the `public` directory and refresh the + // browser on changes when not in production + !production && livereload('public'), + + // If we're building for production (npm run build + // instead of npm run dev), minify + production && terser() + ], + watch: { + clearScreen: false + } +} diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/.gitignore b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/.gitignore new file mode 100644 index 000000000000..c1237045915f --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/.gitignore @@ -0,0 +1,4 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +WixTools diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/Cargo.crate-manifest b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/Cargo.crate-manifest new file mode 100644 index 000000000000..4d1f62dcf327 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/Cargo.crate-manifest @@ -0,0 +1,21 @@ +[package] +name = "app" +version = "0.1.0" +description = "A Tauri App" +authors = [ "{{ author }}" ] +repository = "" +edition = "2021" +rust-version = "1.57" + +[dependencies] +serde_json = "1.0" +serde = { version = "1.0", features = [ "derive" ] } +tauri = {{{ tauri_example_dep }}} +tauri-plugin-{{ plugin_name }} = { path = "../../../" } + +[build-dependencies] +tauri-build = {{{ tauri_build_dep }}} + +[features] +default = [ "custom-protocol" ] +custom-protocol = [ "tauri/custom-protocol" ] diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/build.rs b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/build.rs new file mode 100644 index 000000000000..795b9b7c83db --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/128x128.png b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/128x128.png new file mode 100644 index 000000000000..f8d9962cc219 Binary files /dev/null and b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/128x128.png differ diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/128x128@2x.png b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/128x128@2x.png new file mode 100644 index 000000000000..44d26d04b6f6 Binary files /dev/null and b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/128x128@2x.png differ diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/32x32.png b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/32x32.png new file mode 100644 index 000000000000..b6bf7d610338 Binary files /dev/null and b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/32x32.png differ diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.icns b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.icns new file mode 100644 index 000000000000..8254645a797e Binary files /dev/null and b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.icns differ diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.ico b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.ico new file mode 100644 index 000000000000..db7fd9820442 Binary files /dev/null and b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.ico differ diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.png b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.png new file mode 100644 index 000000000000..e65ea7e866a6 Binary files /dev/null and b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/icons/icon.png differ diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/rustfmt.toml b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/rustfmt.toml new file mode 100644 index 000000000000..d962cdac2267 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/rustfmt.toml @@ -0,0 +1,13 @@ +max_width = 100 +hard_tabs = false +tab_spaces = 2 +newline_style = "Auto" +use_small_heuristics = "Default" +reorder_imports = true +reorder_modules = true +remove_nested_parens = true +edition = "2021" +merge_derives = true +use_try_shorthand = false +use_field_init_shorthand = false +force_explicit_abi = true diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/src/main.rs b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/src/main.rs new file mode 100644 index 000000000000..3484c5abe63f --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/src/main.rs @@ -0,0 +1,11 @@ +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] + +fn main() { + tauri::Builder::default() + .plugin(tauri_plugin_{{ plugin_name_snake_case }}::YourPlugin::default()) + .run(tauri::generate_context!()) + .expect("failed to run app"); +} diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/tauri.conf.json b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/tauri.conf.json new file mode 100644 index 000000000000..5e7b27be26cd --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src-tauri/tauri.conf.json @@ -0,0 +1,53 @@ +{ + "build": { + "distDir": "../public", + "devPath": "http://localhost:8080", + "beforeDevCommand": "yarn dev", + "beforeBuildCommand": "yarn build" + }, + "tauri": { + "bundle": { + "active": true, + "targets": "all", + "identifier": "com.tauri.{{ plugin_name }}", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ], + "resources": [], + "externalBin": [], + "copyright": "", + "category": "DeveloperTool", + "shortDescription": "", + "longDescription": "", + "deb": { + "depends": [], + "useBootstrapper": false + }, + "macOS": { + "frameworks": [], + "minimumSystemVersion": "", + "useBootstrapper": false, + "exceptionDomain": "" + } + }, + "allowlist": { + "all": true + }, + "windows": [ + { + "title": "Tauri App", + "width": 800, + "height": 600, + "resizable": true, + "fullscreen": false + } + ], + "security": { + "csp": "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'" + } + } +} diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src/App.svelte b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src/App.svelte new file mode 100644 index 000000000000..24e618e8d82a --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src/App.svelte @@ -0,0 +1,18 @@ + + +
    + +
    {@html response}
    +
    diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/src/main.ts b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src/main.ts new file mode 100644 index 000000000000..0651393408ff --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/src/main.ts @@ -0,0 +1,8 @@ +import App from './App.svelte' + +const app = new App({ + target: document.body, + props: {} +}) + +export default app diff --git a/tooling/cli/templates/plugin/with-api/examples/svelte-app/tsconfig.json b/tooling/cli/templates/plugin/with-api/examples/svelte-app/tsconfig.json new file mode 100644 index 000000000000..543124837b37 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/examples/svelte-app/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + + "include": ["src/**/*"], + "exclude": ["node_modules/*", "__sapper__/*", "public/*"] +} diff --git a/tooling/cli/templates/plugin/with-api/package.json b/tooling/cli/templates/plugin/with-api/package.json new file mode 100644 index 000000000000..b6e1e5c5e990 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/package.json @@ -0,0 +1,25 @@ +{ + "name": "tauri-plugin-{{ plugin_name }}-api", + "version": "0.0.0", + "author": "{{ author }}", + "description": "", + "browser": "webview-dist/index.js", + "main": "webview-dist/index.js", + "types": "webview-dist/index.d.ts", + "scripts": { + "build": "rollup -c ./webview-src/rollup.config.js", + "prepublishOnly": "yarn build", + "pretest": "yarn build" + }, + "devDependencies": { + "@rollup/plugin-node-resolve": "13.1.3", + "@rollup/plugin-typescript": "8.3.0", + "rollup": "2.67.1", + "rollup-plugin-terser": "7.0.2", + "typescript": "4.5.5" + }, + "dependencies": { + "@tauri-apps/api": "1.0.0-beta.8", + "tslib": "^2.1.0" + } +} diff --git a/tooling/cli/templates/plugin/with-api/src/lib.rs b/tooling/cli/templates/plugin/with-api/src/lib.rs new file mode 100644 index 000000000000..1f3ba65c7c25 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/src/lib.rs @@ -0,0 +1,67 @@ +{{#if license_header}} +{{ license_header }} +{{/if}} + +use serde::{ser::Serializer, Serialize}; +use serde_json::Value as JsonValue; +use tauri::{command, plugin::Plugin, AppHandle, Invoke, Manager, Runtime, State, Window}; + +use std::{collections::HashMap, sync::Mutex}; + +type Result = std::result::Result; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error(transparent)] + Io(#[from] std::io::Error), +} + +impl Serialize for Error { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: Serializer, + { + serializer.serialize_str(self.to_string().as_ref()) + } +} + +#[derive(Default)] +struct MyState(Mutex>); + +#[command] +async fn execute( + _app: AppHandle, + _window: Window, + state: State<'_, MyState>, +) -> Result { + state.0.lock().unwrap().insert("key".into(), "value".into()); + Ok("success".to_string()) +} + +/// Tauri plugin. +pub struct YourPlugin { + invoke_handler: Box) + Send + Sync>, +} + +impl Default for YourPlugin { + fn default() -> Self { + Self { + invoke_handler: Box::new(tauri::generate_handler![execute]), + } + } +} + +impl Plugin for YourPlugin { + fn name(&self) -> &'static str { + "{{ plugin_name }}" + } + + fn initialize(&mut self, app: &AppHandle, _config: JsonValue) -> tauri::plugin::Result<()> { + app.manage(MyState::default()); + Ok(()) + } + + fn extend_api(&mut self, message: Invoke) { + (self.invoke_handler)(message) + } +} diff --git a/tooling/cli/templates/plugin/with-api/webview-dist/index.d.ts b/tooling/cli/templates/plugin/with-api/webview-dist/index.d.ts new file mode 100644 index 000000000000..fb4a9c9dde7d --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/webview-dist/index.d.ts @@ -0,0 +1 @@ +export declare function execute(): Promise diff --git a/tooling/cli/templates/plugin/with-api/webview-dist/index.js b/tooling/cli/templates/plugin/with-api/webview-dist/index.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tooling/cli/templates/plugin/with-api/webview-src/.gitignore b/tooling/cli/templates/plugin/with-api/webview-src/.gitignore new file mode 100644 index 000000000000..82eea5f8ab08 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/webview-src/.gitignore @@ -0,0 +1,66 @@ +# Build output +/dist +/api + + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +/.vs +.DS_Store +.Thumbs.db +*.sublime* +.idea/ +debug.log +package-lock.json +.vscode/settings.json diff --git a/tooling/cli/templates/plugin/with-api/webview-src/index.ts b/tooling/cli/templates/plugin/with-api/webview-src/index.ts new file mode 100644 index 000000000000..4dd15ebdf834 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/webview-src/index.ts @@ -0,0 +1,8 @@ +{{#if license_header}} +{{ license_header }} +{{/if}} +import { invoke } from '@tauri-apps/api/tauri' + +export async function execute() { + await invoke('plugin:{{ plugin_name }}|execute') +} diff --git a/tooling/cli/templates/plugin/with-api/webview-src/rollup.config.js b/tooling/cli/templates/plugin/with-api/webview-src/rollup.config.js new file mode 100644 index 000000000000..cf5affb2bff4 --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/webview-src/rollup.config.js @@ -0,0 +1,21 @@ +import { nodeResolve } from '@rollup/plugin-node-resolve' +import { terser } from 'rollup-plugin-terser' +import typescript from '@rollup/plugin-typescript' + +export default { + input: './webview-src/index.ts', + output: { + dir: './webview-dist', + entryFileNames: '[name].js', + format: 'es', + exports: 'auto' + }, + plugins: [ + nodeResolve(), + terser(), + typescript({ + tsconfig: './webview-src/tsconfig.json', + moduleResolution: 'node' + }) + ] +} diff --git a/tooling/cli/templates/plugin/with-api/webview-src/tsconfig.json b/tooling/cli/templates/plugin/with-api/webview-src/tsconfig.json new file mode 100644 index 000000000000..a120087deedc --- /dev/null +++ b/tooling/cli/templates/plugin/with-api/webview-src/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES5", + "strict": true, + "allowJs": true, + "esModuleInterop": true, + "baseUrl": ".", + "paths": { + "types": ["@types"] + }, + "declaration": true, + "declarationDir": "../webview-dist", + "rootDir": "./" + }, + "include": ["./"] +} diff --git a/tooling/cli/vswhere.exe b/tooling/cli/vswhere.exe new file mode 100644 index 000000000000..1731aa6ed279 Binary files /dev/null and b/tooling/cli/vswhere.exe differ diff --git a/tooling/create-tauri-app/package.json b/tooling/create-tauri-app/package.json index 21720856d7c1..86797c7d1d2d 100644 --- a/tooling/create-tauri-app/package.json +++ b/tooling/create-tauri-app/package.json @@ -32,36 +32,35 @@ "test": "node ./test/spawn.test.mjs" }, "dependencies": { - "chalk": "4.1.1", - "execa": "^5.0.0", - "inquirer": "^8.0.0", - "minimist": "^1.2.5", - "scaffe": "1.1.0" + "chalk": "4.1.2", + "commander": "8.3.0", + "execa": "5.1.1", + "inquirer": "8.2.0", + "scaffe": "1.2.0" }, "devDependencies": { - "@effection/process": "2.0.0-beta.8", - "@rollup/plugin-commonjs": "20.0.0", - "@rollup/plugin-node-resolve": "13.0.0", - "@rollup/plugin-typescript": "8.2.1", + "@effection/process": "2.0.4", + "@rollup/plugin-commonjs": "21.0.1", + "@rollup/plugin-node-resolve": "13.1.3", + "@rollup/plugin-typescript": "8.3.0", "@types/cross-spawn": "6.0.2", - "@types/inquirer": "7.3.1", - "@types/minimist": "1.2.1", - "@types/semver": "7.3.6", - "@typescript-eslint/eslint-plugin": "4.27.0", - "@typescript-eslint/parser": "4.27.0", - "effection": "2.0.0-beta.8", - "eslint": "7.28.0", + "@types/inquirer": "8.2.0", + "@types/semver": "7.3.9", + "@typescript-eslint/eslint-plugin": "5.11.0", + "@typescript-eslint/parser": "5.11.0", + "effection": "2.0.4", + "eslint": "8.8.0", "eslint-config-prettier": "8.3.0", - "eslint-config-standard-with-typescript": "20.0.0", - "eslint-plugin-import": "2.23.4", + "eslint-config-standard-with-typescript": "21.0.1", + "eslint-plugin-import": "2.25.4", "eslint-plugin-lodash-template": "0.19.0", "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "5.1.0", + "eslint-plugin-promise": "5.2.0", "eslint-plugin-security": "1.4.0", - "prettier": "2.3.1", - "rollup": "2.52.1", - "temp-dir": "^2.0.0", - "tslib": "2.3.0", - "typescript": "4.3.4" + "prettier": "2.5.1", + "rollup": "2.67.1", + "temp-dir": "2.0.0", + "tslib": "2.3.1", + "typescript": "4.5.5" } } diff --git a/tooling/create-tauri-app/src/dependency-manager.ts b/tooling/create-tauri-app/src/dependency-manager.ts index 48f7cdc65a69..4cbfa1d7552a 100644 --- a/tooling/create-tauri-app/src/dependency-manager.ts +++ b/tooling/create-tauri-app/src/dependency-manager.ts @@ -53,14 +53,18 @@ async function installNpmPackage( const packages = packageNames.filter((p) => p !== '') if (packages.length !== 0) { console.log(`- Installing ${packages.join(', ')}...`) - if (packageManager === 'npm') { - await shell('npm', ['install', packageNames.join(' ')], { - cwd: appDir - }) - } else { - await shell(packageManager, ['add', packageNames.join(' ')], { - cwd: appDir - }) + switch (packageManager) { + case 'pnpm': + case 'yarn': + await shell(packageManager, ['add', packageNames.join(' ')], { + cwd: appDir + }) + break + case 'npm': + await shell('npm', ['install', packageNames.join(' ')], { + cwd: appDir + }) + break } } } @@ -73,22 +77,27 @@ async function installNpmDevPackage( const packages = packageNames.filter((p) => p !== '') if (packages.length !== 0) { console.log(`- Installing ${packages.join(', ')}...`) - if (packageManager === 'npm') { - await shell( - 'npm', - ['install', '--save-dev', '--ignore-scripts', packageNames.join(' ')], - { - cwd: appDir - } - ) - } else { - await shell( - packageManager, - ['add', '-D', '--ignore-scripts', packageNames.join(' ')], - { - cwd: appDir - } - ) + + switch (packageManager) { + case 'pnpm': + case 'yarn': + await shell( + packageManager, + ['add', '-D', '--ignore-scripts', packageNames.join(' ')], + { + cwd: appDir + } + ) + break + case 'npm': + await shell( + 'npm', + ['install', '--save-dev', '--ignore-scripts', packageNames.join(' ')], + { + cwd: appDir + } + ) + break } } } diff --git a/tooling/create-tauri-app/src/helpers/empty-dir.ts b/tooling/create-tauri-app/src/helpers/empty-dir.ts new file mode 100644 index 000000000000..459bf390fd7d --- /dev/null +++ b/tooling/create-tauri-app/src/helpers/empty-dir.ts @@ -0,0 +1,17 @@ +import { existsSync, readdirSync, lstatSync, rmdirSync, unlinkSync } from 'fs' +import { resolve } from 'path' + +export function emptyDir(dir: string): void { + if (!existsSync(dir)) return + + for (const file of readdirSync(dir)) { + const abs = resolve(dir, file) + // baseline is Node 12 so can't use rmSync :( + if (lstatSync(abs).isDirectory()) { + emptyDir(abs) + rmdirSync(abs) + } else { + unlinkSync(abs) + } + } +} diff --git a/tooling/create-tauri-app/src/helpers/package-manager.ts b/tooling/create-tauri-app/src/helpers/package-manager.ts new file mode 100644 index 000000000000..dd931dcaed40 --- /dev/null +++ b/tooling/create-tauri-app/src/helpers/package-manager.ts @@ -0,0 +1,14 @@ +export function pkgManagerFromUserAgent(userAgent: string | undefined): + | { + name: string + version: string + } + | undefined { + if (!userAgent) return undefined + const pkgSpec = userAgent.split(' ')[0] + const pkgSpecArr = pkgSpec.split('/') + return { + name: pkgSpecArr[0], + version: pkgSpecArr[1] + } +} diff --git a/tooling/create-tauri-app/src/helpers/update-package-json.ts b/tooling/create-tauri-app/src/helpers/update-package-json.ts index a76a2a415aaa..25311805ad64 100644 --- a/tooling/create-tauri-app/src/helpers/update-package-json.ts +++ b/tooling/create-tauri-app/src/helpers/update-package-json.ts @@ -5,22 +5,17 @@ import { readFileSync, writeFileSync } from 'fs' import { join } from 'path' -interface Package { +interface PackageJSON { name?: string - scripts?: {} + scripts?: Record } -export function updatePackageJson(appDirectory: string, appName: string): void { - const pkgPath = join(appDirectory, 'package.json') - const pkgString = readFileSync(pkgPath, 'utf8') - const pkg = JSON.parse(pkgString) as Package - const outputPkg = { - ...pkg, - name: appName, - scripts: { - ...pkg.scripts, - tauri: 'tauri' - } - } - writeFileSync(pkgPath, JSON.stringify(outputPkg, undefined, 2)) +export function updatePackageJson( + f: (pkg: PackageJSON) => PackageJSON, + cwd: string = process.cwd() +): void { + const pkgPath = join(cwd, 'package.json') + const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJSON + const output = f(pkg) + writeFileSync(pkgPath, JSON.stringify(output, undefined, 2)) } diff --git a/tooling/create-tauri-app/src/helpers/update-tauri-conf.ts b/tooling/create-tauri-app/src/helpers/update-tauri-conf.ts index 39aded52c067..8fcdb235f09a 100644 --- a/tooling/create-tauri-app/src/helpers/update-tauri-conf.ts +++ b/tooling/create-tauri-app/src/helpers/update-tauri-conf.ts @@ -4,26 +4,25 @@ import { readFileSync, writeFileSync } from 'fs' import { join } from 'path' -import { TauriBuildConfig } from '../types/config' -export function updateTauriConf( - appDirectory: string, - cfg: TauriBuildConfig -): void { - const tauriConfPath = join(appDirectory, 'src-tauri', 'tauri.conf.json') - const tauriConfString = readFileSync(tauriConfPath, 'utf8') - const tauriConf = JSON.parse(tauriConfString) as { - build: TauriBuildConfig - } - - const outputPkg: { build: TauriBuildConfig } = { - ...tauriConf, - build: { - ...tauriConf.build, - beforeBuildCommand: cfg.beforeBuildCommand, - beforeDevCommand: cfg.beforeDevCommand - } +interface TauriConfJSON { + build?: { + beforeDevCommand?: string + beforeBuildCommand?: string + distDir?: string + devPath?: string + withGlobalTauri?: boolean } +} - writeFileSync(tauriConfPath, JSON.stringify(outputPkg, undefined, 2)) +export function updateTauriConf( + f: (tauriConf: TauriConfJSON) => TauriConfJSON, + cwd: string = process.cwd() +): void { + const tauriConfPath = join(cwd, 'src-tauri', 'tauri.conf.json') + const tauriConf = JSON.parse( + readFileSync(tauriConfPath, 'utf8') + ) as TauriConfJSON + const output = f(tauriConf) + writeFileSync(tauriConfPath, JSON.stringify(output, undefined, 2)) } diff --git a/tooling/create-tauri-app/src/index.ts b/tooling/create-tauri-app/src/index.ts index 0ff2b45bb379..7b6d5744d3bb 100644 --- a/tooling/create-tauri-app/src/index.ts +++ b/tooling/create-tauri-app/src/index.ts @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import minimist from 'minimist' import inquirer from 'inquirer' +import { program, createOption } from 'commander' import { bold, cyan, green, reset, yellow } from 'chalk' import { platform } from 'os' import { resolve, join, relative } from 'path' @@ -14,100 +14,110 @@ import { vite } from './recipes/vite' import { dominator } from './recipes/dominator' import { ngcli } from './recipes/ng-cli' import { svelte } from './recipes/svelte' -import { install, checkPackageManager } from './dependency-manager' +import { solid } from './recipes/solid' +import { cljs } from './recipes/cljs' +import { + install, + checkPackageManager, + PackageManager +} from './dependency-manager' import { shell } from './shell' import { updatePackageJson } from './helpers/update-package-json' import { Recipe } from './types/recipe' import { updateTauriConf } from './helpers/update-tauri-conf' +import { pkgManagerFromUserAgent } from './helpers/package-manager' + +const allRecipes: Recipe[] = [ + vanillajs, + cra, + vite, + vuecli, + ngcli, + svelte, + solid, + dominator, + cljs +] +const recipeShortNames = allRecipes.map((r) => r.shortName) +const recipeDescriptiveNames = allRecipes.map((r) => r.descriptiveName) +const recipeByShortName = (name: string): Recipe | undefined => + allRecipes.find((r) => r.shortName === name) +const recipeByDescriptiveName = (name: string): Recipe | undefined => + allRecipes.find((r) => r.descriptiveName.value === name) interface Argv { - h: boolean help: boolean - v: string version: string ci: boolean dev: boolean - b: string binary: string - f: string force: string - l: boolean log: boolean - m: string manager: string - d: string directory: string - t: string - tauriPath: string - A: string appName: string - W: string windowTitle: string - D: string distDir: string - P: string devPath: string - r: string recipe: string } -const printUsage = (): void => { - console.log(` - Description - Starts a new tauri app from a "recipe" or pre-built template. - Usage - $ yarn create tauri-app # npm create-tauri-app - Options - --help, -h Displays this message - -v, --version Displays the Tauri CLI version - --ci Skip prompts - --force, -f Force init to overwrite [conf|template|all] - --log, -l Logging [boolean] - --manager, -m Set package manager to use [npm|yarn|pnpm] - --directory, -d Set target directory for init - --app-name, -A Name of your Tauri application - --window-title, -W Window title of your Tauri application - --dist-dir, -D Web assets location, relative to /src-tauri - --dev-path, -P Url of your dev server - --recipe, -r Add UI framework recipe. None by default. - Supported recipes: [${recipeShortNames.join('|')}] - `) -} - export const createTauriApp = async (cliArgs: string[]): Promise => { - const argv = minimist(cliArgs, { - alias: { - h: 'help', - v: 'version', - f: 'force', - l: 'log', - m: 'manager', - d: 'directory', - t: 'tauri-path', - A: 'app-name', - W: 'window-title', - D: 'dist-dir', - P: 'dev-path', - r: 'recipe' - }, - boolean: ['h', 'l', 'ci', 'dev'] - }) as unknown as Argv - - if (argv.help) { - printUsage() - return 0 - } - - if (argv.v) { - /* eslint-disable @typescript-eslint/no-var-requires */ - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - console.log(require('../package.json').version) - return false // do this for node consumers and tests - /* eslint-enable @typescript-eslint/no-var-requires */ - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - } + program + .description( + 'Bootstrap a new tauri app from a "recipe" or a pre-built template.' + ) + .addOption( + createOption( + '-r, --recipe ', + 'Specify UI framework recipe' + ).choices(recipeShortNames) + ) + .option(' --ci', 'Skip prompts') + .option(' --dev', 'Use local development packages') + .addOption( + createOption('-f, --force [option]', 'Force init to overwrite') + .choices(['conf', 'template', 'all']) + .default('all') + ) + .option('-d, --directory ', 'Set target directory for init') + .option('-A, --app-name ', 'Name of your Tauri application') + .option( + '-W, --window-title ', + 'Title of your Tauri application window' + ) + .option( + '-D, --dist-dir <path>', + 'Web assets location, relative to "<project-dir>/src-tauri/tauri.conf.json"' + ) + .option('-p, --dev-path <path>', 'Url of your dev server') + .addOption( + createOption( + '-m, --manager <package-manager>', + 'Set package manager to use' + ).choices(['npm', 'yarn', 'pnpm']) + ) + .addOption( + createOption('-b, --binary <path>', 'Use a prebuilt Tauri CLI binary') + ) + .option('-l, --log', 'Add log messages') + .version( + // eslint-disable-next-line + require('../package.json').version, + '-v, --version', + 'Displays create-tauri-app version' + ) + .helpOption('-h, --help', 'Displays this message') + .showHelpAfterError('For more information try --help') + .configureHelp({ + optionTerm: (option) => cyan(option.flags), + commandUsage: (command) => cyan(command.name()) + ' [options]', + commandDescription: (command) => yellow(command.description()) + }) + .parse(process.argv) - return await runInit(argv) + const argv = program.opts() + return await runInit(argv as Argv) } interface Responses { @@ -117,26 +127,6 @@ interface Responses { installApi: boolean } -const allRecipes: Recipe[] = [ - vanillajs, - cra, - vite, - vuecli, - ngcli, - svelte, - dominator -] - -const recipeByShortName = (name: string): Recipe | undefined => - allRecipes.find((r) => r.shortName === name) - -const recipeByDescriptiveName = (name: string): Recipe | undefined => - allRecipes.find((r) => r.descriptiveName.value === name) - -const recipeShortNames = allRecipes.map((r) => r.shortName) - -const recipeDescriptiveNames = allRecipes.map((r) => r.descriptiveName) - const keypress = async (skip: boolean): Promise<void> => { if (skip) return process.stdin.setRawMode(true) @@ -155,36 +145,31 @@ const keypress = async (skip: boolean): Promise<void> => { } const runInit = async (argv: Argv): Promise<void> => { - console.log( - `We hope to help you create something special with ${bold( - yellow('Tauri') - )}!` - ) - console.log( - 'You will have a choice of one of the UI frameworks supported by the greater web tech community.' - ) - console.log( - `This should get you started. See our docs at https://tauri.studio/` - ) - const setupLink = platform() === 'win32' - ? 'https://tauri.studio/en/docs/getting-started/setup-windows/' + ? 'https://tauri.studio/en/docs/get-started/setup-windows/' : platform() === 'darwin' - ? 'https://tauri.studio/en/docs/getting-started/setup-macos/' - : 'https://tauri.studio/en/docs/getting-started/setup-linux/' + ? 'https://tauri.studio/en/docs/get-started/setup-macos/' + : 'https://tauri.studio/en/docs/get-started/setup-linux/' + // prettier-ignore console.log( - `If you haven't already, please take a moment to setup your system.` + ` +We hope to help you create something special with ${bold(yellow('Tauri'))}! +You will have a choice of one of the UI frameworks supported by the greater web tech community. +This tool should get you quickly started. See our docs at ${cyan('https://tauri.studio/')} + +If you haven't already, please take a moment to setup your system. +You may find the requirements here: ${cyan(setupLink)} + ` ) - console.log(`You may find the requirements here: ${setupLink}`) await keypress(argv.ci) const defaults = { appName: 'tauri-app', tauri: { window: { title: 'Tauri App' } }, - recipeName: 'vanillajs', + recipeName: 'Vanilla.js', installApi: true } @@ -196,14 +181,14 @@ const runInit = async (argv: Argv): Promise<void> => { name: 'appName', message: 'What is your app name?', default: defaults.appName, - when: !argv.ci && !argv.A + when: !argv.ci && !argv.appName }, { type: 'input', name: 'tauri.window.title', message: 'What should the window title be?', default: defaults.tauri.window.title, - when: !argv.ci && !argv.W + when: !argv.ci && !argv.windowTitle }, { type: 'list', @@ -211,7 +196,7 @@ const runInit = async (argv: Argv): Promise<void> => { message: 'What UI recipe would you like to add?', choices: recipeDescriptiveNames, default: defaults.recipeName, - when: !argv.ci && !argv.r + when: !argv.ci && !argv.recipe }, { type: 'confirm', @@ -243,8 +228,8 @@ const runInit = async (argv: Argv): Promise<void> => { } = { ...defaults, ...answers } let recipe: Recipe | undefined - if (argv.r) { - recipe = recipeByShortName(argv.r) + if (argv.recipe) { + recipe = recipeByShortName(argv.recipe) } else if (recipeName !== undefined) { recipe = recipeByDescriptiveName(recipeName) } @@ -254,26 +239,19 @@ const runInit = async (argv: Argv): Promise<void> => { throw new Error('Could not find the recipe specified.') } - const packageManager = - argv.m === 'yarn' || argv.m === 'npm' || argv.m === 'pnpm' - ? argv.m - : // @ts-expect-error - // this little fun snippet pulled from vite determines the package manager the script was run from - /yarn/.test(process?.env?.npm_execpath) - ? 'yarn' - : // @ts-expect-error - /pnpm/.test(process?.env?.npm_execpath) - ? 'pnpm' - : 'npm' + const pkgManagerInfo = pkgManagerFromUserAgent( + process.env.npm_config_user_agent + ) + const packageManager = (pkgManagerInfo?.name ?? 'npm') as PackageManager const buildConfig = { - distDir: argv.D, - devPath: argv.P, - appName: argv.A || appName, - windowTitle: argv.W || title + distDir: argv.distDir, + devPath: argv.devPath, + appName: argv.appName || appName, + windowTitle: argv.windowTitle || title } - const directory = argv.d || process.cwd() + const directory = argv.directory || process.cwd() // prompt additional recipe questions let recipeAnswers @@ -307,7 +285,7 @@ const runInit = async (argv: Argv): Promise<void> => { packageManager, ci: argv.ci, cwd: directory, - answers: recipeAnswers + answers: recipeAnswers ?? {} }) } const cfg = { @@ -317,7 +295,7 @@ const runInit = async (argv: Argv): Promise<void> => { // note that our app directory is reliant on the appName and // generally there are issues if the path has spaces (see Windows) - // future TODO prevent app names with spaces or escape here? + // TODO: prevent app names with spaces or escape here? const appDirectory = join(directory, cfg.appName) // this throws an error if we can't run the package manager they requested @@ -330,7 +308,7 @@ const runInit = async (argv: Argv): Promise<void> => { cfg, packageManager, ci: argv.ci, - answers: recipeAnswers + answers: recipeAnswers ?? {} }) } @@ -346,17 +324,20 @@ const runInit = async (argv: Argv): Promise<void> => { return final } }, []) - - const tauriCLIVersion = !argv.dev + // TODO: const tauriCLIVersion = !argv.dev ? + // 'latest' + // :`file:${relative(appDirectory, join(__dirname, '../../cli.js'))}` + const tauriCLIVersion = 'latest' + const apiVersion = !argv.dev ? 'latest' - : `file:${relative(appDirectory, join(__dirname, '../../cli.js'))}` + : `file:${relative(appDirectory, join(__dirname, '../../api/dist'))}` // Vue CLI plugin automatically runs these if (recipe.shortName !== 'vuecli') { logStep('Installing any additional needed dependencies') await install({ appDir: appDirectory, - dependencies: [installApi ? '@tauri-apps/api@latest' : ''].concat( + dependencies: [installApi ? `@tauri-apps/api@${apiVersion}` : ''].concat( recipe.extraNpmDependencies ), devDependencies: [`@tauri-apps/cli@${tauriCLIVersion}`].concat( @@ -366,14 +347,25 @@ const runInit = async (argv: Argv): Promise<void> => { }) logStep(`Updating ${reset(yellow('"package.json"'))}`) - updatePackageJson(appDirectory, appName) + updatePackageJson((pkg) => { + return { + ...pkg, + name: appName, + scripts: { + ...pkg.scripts, + tauri: 'tauri' + } + } + }, appDirectory) logStep(`Running ${reset(yellow('"tauri init"'))}`) - const binary = !argv.b ? packageManager : resolve(appDirectory, argv.b) - // pnpm is equivalent to yarn and can run srcipts without using "run" but due to this bug https://github.com/pnpm/pnpm/issues/2764 - // we need to pass "--" to pnpm or arguments won't be parsed correctly so for this command only we are gonna treat pnpm as npm equivalent/ + const binary = !argv.binary + ? packageManager + : resolve(appDirectory, argv.binary) + // "pnpm" is mostly interchangable with "yarn" but due to this bug https://github.com/pnpm/pnpm/issues/2764 + // we need to pass "--" to pnpm or arguments won't be parsed correctly so we treat "pnpm" here like "npm" const runTauriArgs = - packageManager === 'yarn' || argv.b + packageManager === 'yarn' || argv.binary ? ['tauri', 'init'] : ['run', 'tauri', '--', 'init'] @@ -382,7 +374,16 @@ const runInit = async (argv: Argv): Promise<void> => { }) logStep(`Updating ${reset(yellow('"tauri.conf.json"'))}`) - updateTauriConf(appDirectory, cfg) + updateTauriConf((tauriConf) => { + return { + ...tauriConf, + build: { + ...tauriConf.build, + beforeDevCommand: cfg.beforeDevCommand, + beforeBuildCommand: cfg.beforeBuildCommand + } + } + }, appDirectory) } if (recipe.postInit) { @@ -392,7 +393,7 @@ const runInit = async (argv: Argv): Promise<void> => { cfg, packageManager, ci: argv.ci, - answers: recipeAnswers + answers: recipeAnswers ?? {} }) } } diff --git a/tooling/create-tauri-app/src/recipes/cljs.ts b/tooling/create-tauri-app/src/recipes/cljs.ts new file mode 100644 index 000000000000..8ac2d8f87891 --- /dev/null +++ b/tooling/create-tauri-app/src/recipes/cljs.ts @@ -0,0 +1,91 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { join } from 'path' +import { shell } from '../shell' +import { Recipe } from '../types/recipe' +import { unlinkSync, existsSync } from 'fs' +import { emptyDir } from '../helpers/empty-dir' + +const cljs: Recipe = { + descriptiveName: { + name: 'ClojureScript (https://github.com/filipesilva/create-cljs-app)', + value: 'cljs' + }, + shortName: 'cljs', + extraNpmDevDependencies: [], + extraNpmDependencies: [], + configUpdate: ({ cfg, packageManager }) => ({ + ...cfg, + distDir: `../public`, + devPath: 'http://localhost:3000', + beforeDevCommand: `${ + packageManager === 'npm' ? 'npm run' : packageManager + } start`, + beforeBuildCommand: `${ + packageManager === 'npm' ? 'npm run' : packageManager + } build` + }), + preInit: async ({ cwd, cfg, packageManager, ci }) => { + const npmLock = join(cwd, cfg.appName, 'package-lock.json') + const yarnLock = join(cwd, cfg.appName, 'yarn.lock') + const nodeModules = join(cwd, cfg.appName, 'node_modules') + + switch (packageManager) { + case 'yarn': + await shell('yarn', ['create', 'cljs-app', `${cfg.appName}`], { + cwd + }) + + // `create-cljs-app` has both a `package-lock.json` and a `yarn.lock` + // so it is better to remove conflicting lock files and install fresh node_modules + if (existsSync(npmLock)) unlinkSync(npmLock) + emptyDir(nodeModules) + + await shell('yarn', ['install'], { cwd: join(cwd, cfg.appName) }) + break + + case 'npm': + await shell( + 'npx', + [ci ? '--yes' : '', 'create-cljs-app@latest', `${cfg.appName}`], + { + cwd + } + ) + + if (existsSync(yarnLock)) unlinkSync(yarnLock) + emptyDir(nodeModules) + + await shell('npm', ['install'], { cwd: join(cwd, cfg.appName) }) + break + + case 'pnpm': + await shell( + 'npx', + [ci ? '--yes' : '', 'create-cljs-app@latest', `${cfg.appName}`], + { + cwd + } + ) + + if (existsSync(npmLock)) unlinkSync(npmLock) + emptyDir(nodeModules) + + await shell('pnpm', ['install'], { cwd: join(cwd, cfg.appName) }) + break + } + }, + postInit: async ({ cfg, packageManager }) => { + console.log(` + Your installation completed. + + $ cd ${cfg.appName} + $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev + `) + return await Promise.resolve() + } +} + +export { cljs } diff --git a/tooling/create-tauri-app/src/recipes/dominator.ts b/tooling/create-tauri-app/src/recipes/dominator.ts index 771bbc86547d..06707ad2bab5 100644 --- a/tooling/create-tauri-app/src/recipes/dominator.ts +++ b/tooling/create-tauri-app/src/recipes/dominator.ts @@ -50,9 +50,7 @@ export const dominator: Recipe = { $ cd ${cfg.appName} $ ${packageManager} install - $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri ${ - packageManager === 'npm' ? '--' : '' - }dev + $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev `) return await Promise.resolve() } diff --git a/tooling/create-tauri-app/src/recipes/ng-cli.ts b/tooling/create-tauri-app/src/recipes/ng-cli.ts index b0fff28b9c16..44a8c508292b 100644 --- a/tooling/create-tauri-app/src/recipes/ng-cli.ts +++ b/tooling/create-tauri-app/src/recipes/ng-cli.ts @@ -11,14 +11,19 @@ const addAdditionalPackage = async ( ): Promise<void> => { const ngCommand = ['ng', 'add', packageName, '--skip-confirmation'] - if (packageManager === 'npm') { - await shell('npm', ['run', ...ngCommand], { - cwd: join(cwd, appName) - }) - } else { - await shell(packageManager, ngCommand, { - cwd: join(cwd, appName) - }) + switch (packageManager) { + case 'pnpm': + case 'yarn': + await shell(packageManager, ngCommand, { + cwd: join(cwd, appName) + }) + break + + case 'npm': + await shell('npm', ['run', ...ngCommand], { + cwd: join(cwd, appName) + }) + break } } @@ -58,11 +63,11 @@ const ngcli: Recipe = { } ] }, - preInit: async ({ cwd, cfg, answers, packageManager }) => { - // Angular CLI creates the folder for you + preInit: async ({ cwd, cfg, answers, packageManager, ci }) => { await shell( 'npx', [ + ci ? '--yes' : '', '-p', '@angular/cli', 'ng', @@ -75,24 +80,22 @@ const ngcli: Recipe = { } ) - if (answers) { - if (answers.material) { - await addAdditionalPackage( - packageManager, - cwd, - cfg.appName, - '@angular/material' - ) - } + if (answers?.material) { + await addAdditionalPackage( + packageManager, + cwd, + cfg.appName, + '@angular/material' + ) + } - if (answers.eslint) { - await addAdditionalPackage( - packageManager, - cwd, - cfg.appName, - '@angular-eslint/schematics' - ) - } + if (answers?.eslint) { + await addAdditionalPackage( + packageManager, + cwd, + cfg.appName, + '@angular-eslint/schematics' + ) } }, postInit: async ({ packageManager, cfg }) => { @@ -100,9 +103,7 @@ const ngcli: Recipe = { Your installation completed. $ cd ${cfg.appName} - $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri ${ - packageManager === 'npm' ? '--' : '' - }dev + $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev `) return await Promise.resolve() diff --git a/tooling/create-tauri-app/src/recipes/react.ts b/tooling/create-tauri-app/src/recipes/react.ts index c2e75688e3b2..208a6719ab53 100644 --- a/tooling/create-tauri-app/src/recipes/react.ts +++ b/tooling/create-tauri-app/src/recipes/react.ts @@ -7,7 +7,9 @@ import { join } from 'path' import scaffe from 'scaffe' import { shell } from '../shell' import { Recipe } from '../types/recipe' -import { rmSync, existsSync } from 'fs' +import { unlinkSync, existsSync } from 'fs' +import { emptyDir } from '../helpers/empty-dir' +import { updatePackageJson } from '../helpers/update-package-json' const afterCra = async ( cwd: string, @@ -24,6 +26,15 @@ const afterCra = async ( await scaffe.generate(templateDir, join(cwd, appName), { overwrite: true }) + updatePackageJson((pkg) => { + return { + ...pkg, + scripts: { + ...pkg.scripts, + start: `${'cross-env BROWSER=none '}${pkg.scripts?.start as string}` + } + } + }, join(cwd, appName)) } catch (err) { console.log(err) } @@ -46,7 +57,7 @@ export const cra: Recipe = { packageManager === 'npm' ? 'npm run' : packageManager } build` }), - extraNpmDevDependencies: [], + extraNpmDevDependencies: ['cross-env'], extraNpmDependencies: [], extraQuestions: ({ ci }) => { return [ @@ -64,53 +75,52 @@ export const cra: Recipe = { } ] }, - preInit: async ({ cwd, cfg, packageManager, answers }) => { - let template = 'cra.js' - if (answers) { - template = answers.template ? (answers.template as string) : 'vue' - } - // CRA creates the folder for you - if (packageManager === 'yarn') { - await shell( - 'yarn', - [ - 'create', - 'react-app', - ...(template === 'cra.ts' ? ['--template', 'typescript'] : []), - `${cfg.appName}` - ], - { - cwd - } - ) - } else { - await shell( - 'npx', - [ - 'create-react-app@latest', - ...(template === 'cra.ts' ? ['--template', 'typescript'] : []), - `${cfg.appName}`, - '--use-npm' - ], - { - cwd + preInit: async ({ cwd, cfg, packageManager, answers, ci }) => { + const template = (answers?.template as string) ?? 'cra.js' + switch (packageManager) { + case 'yarn': + await shell( + 'yarn', + [ + ci ? '--non-interactive' : '', + 'create', + 'react-app', + ...(template === 'cra.ts' ? ['--template', 'typescript'] : []), + `${cfg.appName}` + ], + { + cwd + } + ) + break + case 'npm': + case 'pnpm': + await shell( + 'npx', + [ + ci ? '--yes' : '', + 'create-react-app@latest', + ...(template === 'cra.ts' ? ['--template', 'typescript'] : []), + `${cfg.appName}`, + '--use-npm' + ], + { + cwd + } + ) + + // create-react-app doesn't support pnpm, so we remove `node_modules` and any lock files then install them again using pnpm + if (packageManager === 'pnpm') { + const npmLock = join(cwd, cfg.appName, 'package-lock.json') + const yarnLock = join(cwd, cfg.appName, 'yarn.lock') + const nodeModules = join(cwd, cfg.appName, 'node_modules') + if (existsSync(npmLock)) unlinkSync(npmLock) + if (existsSync(yarnLock)) unlinkSync(yarnLock) + emptyDir(nodeModules) + await shell('pnpm', ['install'], { cwd: join(cwd, cfg.appName) }) } - ) - } - // create-react-app doesn't support pnpm, so we remove `node_modules` and any lock files then install them again using pnpm - if (packageManager === 'pnpm') { - const npmLock = join(cwd, cfg.appName, 'package-lock.json') - const yarnLock = join(cwd, cfg.appName, 'yarn.lock') - const nodeModules = join(cwd, cfg.appName, 'node_modules') - if (existsSync(npmLock)) rmSync(npmLock) - if (existsSync(yarnLock)) rmSync(yarnLock) - if (existsSync(nodeModules)) - rmSync(nodeModules, { - recursive: true, - force: true - }) - await shell('pnpm', ['install'], { cwd }) + break } await afterCra(cwd, cfg.appName, template === 'cra.ts') @@ -120,9 +130,7 @@ export const cra: Recipe = { Your installation completed. $ cd ${cfg.appName} - $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri ${ - packageManager === 'npm' ? '--' : '' - }dev + $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev `) return await Promise.resolve() } diff --git a/tooling/create-tauri-app/src/recipes/solid.ts b/tooling/create-tauri-app/src/recipes/solid.ts new file mode 100644 index 000000000000..60632c462ebe --- /dev/null +++ b/tooling/create-tauri-app/src/recipes/solid.ts @@ -0,0 +1,72 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { shell } from '../shell' +import { Recipe } from '../types/recipe' + +const solid: Recipe = { + descriptiveName: { + name: 'Solid (https://github.com/solidjs/templates)', + value: 'solid' + }, + shortName: 'solid', + extraNpmDevDependencies: [], + extraNpmDependencies: [], + extraQuestions: ({ ci }) => { + return [ + { + type: 'list', + name: 'template', + message: 'Which Solid template would you like to use?', + choices: [ + 'js', + 'ts-bootstrap', + 'ts-minimal', + 'ts-router', + 'ts-windicss', + 'ts' + ], + default: 'ts', + loop: false, + when: !ci + } + ] + }, + configUpdate: ({ cfg, packageManager }) => ({ + ...cfg, + distDir: `../public`, + devPath: 'http://localhost:3000', + beforeDevCommand: `${ + packageManager === 'npm' ? 'npm run' : packageManager + } dev`, + beforeBuildCommand: `${ + packageManager === 'npm' ? 'npm run' : packageManager + } build` + }), + preInit: async ({ cwd, cfg, answers, ci }) => { + await shell( + 'npx', + [ + ci ? '--yes' : '', + 'degit', + `solidjs/templates/${(answers?.template as string) ?? 'js'}`, + cfg.appName + ], + { cwd } + ) + }, + postInit: async ({ cfg, packageManager }) => { + console.log(` + Your installation completed. + + $ cd ${cfg.appName} + $ ${packageManager} install + $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev + `) + + return await Promise.resolve() + } +} + +export { solid } diff --git a/tooling/create-tauri-app/src/recipes/svelte.ts b/tooling/create-tauri-app/src/recipes/svelte.ts index c8365db39d15..9b9250dc38e2 100644 --- a/tooling/create-tauri-app/src/recipes/svelte.ts +++ b/tooling/create-tauri-app/src/recipes/svelte.ts @@ -29,25 +29,28 @@ const svelte: Recipe = { configUpdate: ({ cfg, packageManager }) => ({ ...cfg, distDir: `../public`, - devPath: 'http://localhost:5000', + devPath: 'http://localhost:8080', beforeDevCommand: `${ - packageManager === 'yarn' ? 'npm run' : packageManager + packageManager === 'npm' ? 'npm run' : packageManager } dev`, beforeBuildCommand: `${ - packageManager === 'yarn' ? 'npm run' : packageManager + packageManager === 'npm' ? 'npm run' : packageManager } build` }), - preInit: async ({ cwd, cfg, answers }) => { + preInit: async ({ cwd, cfg, answers, ci }) => { let typescript = false if (answers) { typescript = !!answers.typescript } - await shell('npx', ['degit', 'sveltejs/template', `${cfg.appName}`], { - cwd - }) + await shell( + 'npx', + [ci ? '--yes' : '', 'degit', 'sveltejs/template', `${cfg.appName}`], + { + cwd + } + ) - // Add Typescript if (typescript) { await shell('node', ['scripts/setupTypeScript.js'], { cwd: join(cwd, cfg.appName) @@ -60,9 +63,7 @@ const svelte: Recipe = { $ cd ${cfg.appName} $ ${packageManager} install - $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri ${ - packageManager === 'npm' ? '--' : '' - }dev + $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev `) return await Promise.resolve() diff --git a/tooling/create-tauri-app/src/recipes/vanilla.ts b/tooling/create-tauri-app/src/recipes/vanilla.ts index e083d0e482f8..6c77820c2b5e 100644 --- a/tooling/create-tauri-app/src/recipes/vanilla.ts +++ b/tooling/create-tauri-app/src/recipes/vanilla.ts @@ -45,9 +45,7 @@ export const vanillajs: Recipe = { $ cd ${cfg.appName} $ ${packageManager} install - $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri ${ - packageManager === 'npm' ? '--' : '' - }dev + $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev `) return await Promise.resolve() } diff --git a/tooling/create-tauri-app/src/recipes/vite.ts b/tooling/create-tauri-app/src/recipes/vite.ts index 456852b33ea3..e9eab3752725 100644 --- a/tooling/create-tauri-app/src/recipes/vite.ts +++ b/tooling/create-tauri-app/src/recipes/vite.ts @@ -9,7 +9,7 @@ import { Recipe } from '../types/recipe' const vite: Recipe = { descriptiveName: { - name: 'create-vite (https://vitejs.dev/guide/#scaffolding-your-first-vite-project)', + name: 'create-vite (vanilla, vue, react, svelte, preact, lit) (https://vitejs.dev/guide/#scaffolding-your-first-vite-project)', value: 'create-vite' }, shortName: 'vite', @@ -52,48 +52,73 @@ const vite: Recipe = { } ] }, - preInit: async ({ cwd, cfg, packageManager, answers }) => { - let template = 'vue' - if (answers) { - template = answers.template ? (answers.template as string) : 'vue' - } + preInit: async ({ cwd, cfg, packageManager, answers, ci }) => { + const template = (answers?.template as string) ?? 'vue' + + switch (packageManager) { + case 'yarn': + await shell( + 'yarn', + [ + ci ? '--non-interactive' : '', + 'create', + 'vite', + `${cfg.appName}`, + '--template', + `${template}` + ], + { + cwd + } + ) + break + + case 'npm': + await shell( + 'npx', + [ + ci ? '--yes' : '', + 'create-vite@latest', + `${cfg.appName}`, + '--template', + `${template}` + ], + { + cwd + } + ) + break - // Vite creates the folder for you - if (packageManager === 'yarn') { - await shell( - 'yarn', - ['create', 'vite', `${cfg.appName}`, '--template', `${template}`], - { - cwd - } - ) - } else { - await shell( - packageManager === 'pnpm' ? 'pnpx' : 'npx', - ['create-vite@latest', `${cfg.appName}`, '--template', `${template}`], - { - cwd - } - ) + case 'pnpm': + await shell( + 'pnpm', + ['create', 'vite', `${cfg.appName}`, '--template', `${template}`], + { + cwd + } + ) + break } }, postInit: async ({ cwd, packageManager, cfg }) => { // we don't have a consistent way to rebuild and // esbuild has hit all the bugs and struggles to install on the postinstall await shell('node', ['./node_modules/esbuild/install.js'], { cwd }) - if (packageManager === 'npm') { - await shell('npm', ['run', 'build'], { cwd }) - } else { - await shell(packageManager, ['build'], { cwd }) + switch (packageManager) { + case 'pnpm': + case 'yarn': + await shell(packageManager, ['build'], { cwd }) + break + case 'npm': + await shell('npm', ['run', 'build'], { cwd }) + break } console.log(` Your installation completed. $ cd ${cfg.appName} - $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri ${ - packageManager === 'npm' ? '--' : '' - }dev + $ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev `) return await Promise.resolve() } diff --git a/tooling/create-tauri-app/src/recipes/vue-cli.ts b/tooling/create-tauri-app/src/recipes/vue-cli.ts index fdb19d9940f4..ed9b5de641ec 100644 --- a/tooling/create-tauri-app/src/recipes/vue-cli.ts +++ b/tooling/create-tauri-app/src/recipes/vue-cli.ts @@ -16,10 +16,10 @@ const vuecli: Recipe = { extraNpmDependencies: [], configUpdate: ({ cfg }) => cfg, preInit: async ({ cwd, cfg, ci, packageManager }) => { - // Vue CLI creates the folder for you await shell( 'npx', [ + ci ? '--yes' : '', '@vue/cli@latest', 'create', `${cfg.appName}`, @@ -32,6 +32,7 @@ const vuecli: Recipe = { await shell( 'npx', [ + ci ? '--yes' : '', '@vue/cli', 'add', 'tauri', diff --git a/tooling/create-tauri-app/src/shell.ts b/tooling/create-tauri-app/src/shell.ts index 5ffd710df7b5..ba7043b40061 100644 --- a/tooling/create-tauri-app/src/shell.ts +++ b/tooling/create-tauri-app/src/shell.ts @@ -2,14 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import execa from 'execa' +import execa, { Options, ExecaChildProcess } from 'execa' export const shell = async ( command: string, args?: string[], - options?: execa.Options, + options?: Options, log: boolean = false -): Promise<execa.ExecaReturnValue> => { +): Promise<ExecaChildProcess> => { try { if (options && options.shell === true) { const stringCommand = [command, ...(args ?? [])].join(' ') diff --git a/tooling/create-tauri-app/src/templates/dominator/_Cargo.toml b/tooling/create-tauri-app/src/templates/dominator/_Cargo.toml index d0ffcf8993d6..f9e45337e7c2 100644 --- a/tooling/create-tauri-app/src/templates/dominator/_Cargo.toml +++ b/tooling/create-tauri-app/src/templates/dominator/_Cargo.toml @@ -2,7 +2,9 @@ name = "<%= name %>" version = "1.0.0" categories = ["wasm"] -edition = "2018" +edition = "2021" +rust-version = "1.57" +description = "" [profile.release] lto = true diff --git a/tooling/create-tauri-app/src/types/recipe.ts b/tooling/create-tauri-app/src/types/recipe.ts index a127a708ad6c..1ee99108b3b2 100644 --- a/tooling/create-tauri-app/src/types/recipe.ts +++ b/tooling/create-tauri-app/src/types/recipe.ts @@ -7,8 +7,7 @@ export interface RecipeArgs { cfg: TauriBuildConfig packageManager: PackageManager ci: boolean - // eslint-disable-next-line @typescript-eslint/no-invalid-void-type - answers?: undefined | void | Answers + answers?: Answers } export interface Recipe { diff --git a/tooling/create-tauri-app/test/spawn.test.mjs b/tooling/create-tauri-app/test/spawn.test.mjs index 5d5d3c6b716f..082a18916437 100644 --- a/tooling/create-tauri-app/test/spawn.test.mjs +++ b/tooling/create-tauri-app/test/spawn.test.mjs @@ -18,13 +18,13 @@ if (nodeVersion === '14') { } const ctaBinary = path.resolve('./bin/create-tauri-app.js') -const clijs = path.resolve('../cli.js/') -const api = path.resolve('../api/') +//const clijs = path.resolve('../cli.js/') +//const api = path.resolve('../api/') const manager = process.env.TAURI_RUN_MANAGER || 'yarn' const recipes = process.env.TAURI_RECIPE ? process.env.TAURI_RECIPE.split(',') - : ['vanillajs', 'cra', 'vite', 'ngcli'] + : ['vanillajs', 'cra', 'vite', 'ngcli', 'solid', 'cljs'] const parallelize = process.env.TAURI_RECIPE_PARALLELIZE || false main(function* start() { diff --git a/tooling/create-tauri-app/yarn.lock b/tooling/create-tauri-app/yarn.lock index af945abca953..3d5a5dffc433 100644 --- a/tooling/create-tauri-app/yarn.lock +++ b/tooling/create-tauri-app/yarn.lock @@ -2,93 +2,101 @@ # yarn lockfile v1 -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/helper-validator-identifier@^7.14.5": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" - integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== - -"@babel/highlight@^7.10.4": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@effection/channel@2.0.0-beta.8": - version "2.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@effection/channel/-/channel-2.0.0-beta.8.tgz#d4cfbf1d4c5ed1c96646fed8ccb089b4e39c1713" - integrity sha512-PkBGUfowzcnUWt+XT67iGap/OHKJAHg7TsC3I0zDRi6nH8ujvsW4FFpUBQEZgvHeGeWJtzk2al5mvTsGkBgQQg== - dependencies: - "@effection/core" "2.0.0-beta.7" - "@effection/events" "2.0.0-beta.8" - "@effection/subscription" "2.0.0-beta.8" - -"@effection/core@2.0.0-beta.7": - version "2.0.0-beta.7" - resolved "https://registry.yarnpkg.com/@effection/core/-/core-2.0.0-beta.7.tgz#7520eced8efe8db6c97040ba9c5ca285274110aa" - integrity sha512-xU6oO9k/uaNkPP9TaYSvbFCimcS53k12NwyqNIaDoQdiF5N2xDUJ+rUTkal/CYFFY2XmgvETj/bi3uSKmKp08g== - -"@effection/events@2.0.0-beta.8": - version "2.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@effection/events/-/events-2.0.0-beta.8.tgz#36ae6deae3399cde6c2db3414ce64d44ef639660" - integrity sha512-W53Jw3SwUx04Ypn5uXvHjAqYupM6yB/WjAntdORWIcNnhyT3ZVqDvmvn6p58ZPvd4p+HrWXfEHyta8TPQd7RIA== - dependencies: - "@effection/core" "2.0.0-beta.7" - "@effection/subscription" "2.0.0-beta.8" - -"@effection/main@2.0.0-beta.8": - version "2.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@effection/main/-/main-2.0.0-beta.8.tgz#5e21f1b436e81aac8cd4e7efc5e0734dfd4e7136" - integrity sha512-Eaudhpu5d+UyKprE3lfLoXjY+xwAbMeLB4lMpWkA7vjESbZhskhE04jgyHqpkZED/fP/BtwWkZA6LQWU8QtBog== - dependencies: - "@effection/core" "2.0.0-beta.7" - chalk "^4.1.1" +"@effection/channel@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/channel/-/channel-2.0.3.tgz#825ade1a4a09b860efdf7077fc02f81d6c7614bb" + integrity sha512-HZE2q7dtErIur0g+BVMPqa+dVBgrIIaYMrzMBNM1UoIB6urMGgr+uPWXwgQb3Vzm4Il9SCiCzoM3RE3gDiV1Ig== + dependencies: + "@effection/core" "2.2.0" + "@effection/events" "2.0.3" + "@effection/stream" "2.0.3" + +"@effection/core@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@effection/core/-/core-2.2.0.tgz#4d11d7948144aecd70a26daf8abaa29ee89bc259" + integrity sha512-1RBMrDS0Ya02NEM0TQQRwzlGDSZmwoHhuD3qmWp9NLjZowhO1gJBZ16fQL2NbKvcpS71xho+oZsDedId+C1q8Q== + dependencies: + abort-controller "^3.0.0" + +"@effection/events@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/events/-/events-2.0.3.tgz#cf212748f8e433dcf776e5e1dd0145716213a7bc" + integrity sha512-x8NBNXHZxI4SJ/db1zy7zs6BRtMIKu8NgymUMpbyrRdapPSIu6rmf4WgXyWrk1uvQPSViEkxOXPw8B2MLu/YnA== + dependencies: + "@effection/core" "2.2.0" + "@effection/stream" "2.0.3" + +"@effection/fetch@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@effection/fetch/-/fetch-2.0.4.tgz#8f76f0b630b3974ef267bd8803599448db956cda" + integrity sha512-IhUYqSAM0stEB6VCWK9Mz8F56jWFFpM9yQ4boxGs4F/sdoHnY/9KKW1zxAY05jyYPUHxuUky7sazZVFJm5xRmw== + dependencies: + "@effection/core" "2.2.0" + cross-fetch "3.1.5" + +"@effection/main@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/main/-/main-2.0.3.tgz#10dceb9c8340fd98b7c6704db0b6e8f652f32802" + integrity sha512-UHMRECFMzX+OU6I0Mg2653MyxNTIT8qXpRtl0bZT4E0rSoYnxsV+gSCEbTZFkDIZWFakp0K6awYvtyYhCeugpg== + dependencies: + "@effection/core" "2.2.0" + chalk "^4.1.2" stacktrace-parser "^0.1.10" -"@effection/process@2.0.0-beta.8": - version "2.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@effection/process/-/process-2.0.0-beta.8.tgz#3a4abfa743cbcb68bb8b7ff2d3e723dd61398108" - integrity sha512-HSb/Vq3hQy9wHA2QZb3pzPRVRNYAOYwPBKwiTjcDkBJCM+zjH+C+X9TFPMNSrbJW2Pm9Ok0Vh95YRdPcroxKyw== +"@effection/process@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@effection/process/-/process-2.0.4.tgz#de52485d19a46df9d8cfd91c94657f4bb6d5e03a" + integrity sha512-gKMI5j+OY7DshkO/u50xSP3ASCSYz2g4IwLaKLVQEOT5kIedApIEOYz9nChPps/mQ1PXgQr4OqKofvUkf6Mf1Q== dependencies: - "@effection/channel" "2.0.0-beta.8" - "@effection/core" "2.0.0-beta.7" - "@effection/events" "2.0.0-beta.8" - "@effection/subscription" "2.0.0-beta.8" cross-spawn "^7.0.3" ctrlc-windows "^2.0.0" + effection "2.0.4" shellwords "^0.1.1" -"@effection/subscription@2.0.0-beta.8": - version "2.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@effection/subscription/-/subscription-2.0.0-beta.8.tgz#0d62aa7b94a0334504e5fff1621b8f03f21ea3df" - integrity sha512-HklR2JJP/s2x1tDJm3y9IkPc+j8PcQzRpVHQiSCVyochiVYkNHoXET22PeXJbydFVdB9n7hYF20wJFH8UDkV/Q== +"@effection/stream@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/stream/-/stream-2.0.3.tgz#c1610c63dfe6d10b0b6aeda6969fea24018364b0" + integrity sha512-l1A8PUfxR04eyUBOD1H5gdCu4U5OMwUh2TB/O/IeUlfVoP9tg64daTu7zpZGij9uDcDWV5IP9LJYoWe2lVGbKg== + dependencies: + "@effection/core" "2.2.0" + "@effection/subscription" "2.0.3" + +"@effection/subscription@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/subscription/-/subscription-2.0.3.tgz#ab6e56bf52663b769eb00d0022195b2e753a127d" + integrity sha512-P+bAh0iqCduvzAM+0hbn29HJ+J4TT+lkJTDydw3tI6lSe/OVX9+FJhX/zx2QW3APjFpseMJphjRiEyzf21b/Xw== dependencies: - "@effection/core" "2.0.0-beta.7" + "@effection/core" "2.2.0" -"@eslint/eslintrc@^0.4.2": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== +"@eslint/eslintrc@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.5.tgz#33f1b838dbf1f923bfa517e008362b78ddbbf318" + integrity sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" + debug "^4.3.2" + espree "^9.2.0" globals "^13.9.0" ignore "^4.0.6" import-fresh "^3.2.1" - js-yaml "^3.13.1" + js-yaml "^4.1.0" minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@humanwhocodes/config-array@^0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914" + integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@mapbox/node-pre-gyp@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz#2a0b32fcb416fb3f2250fd24cb2a81421a4f5950" @@ -125,10 +133,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@rollup/plugin-commonjs@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-20.0.0.tgz#3246872dcbcb18a54aaa6277a8c7d7f1b155b745" - integrity sha512-5K0g5W2Ol8hAcTHqcTBHiA7M58tfmYi1o9KxeJuuRNpGaTa5iLjcyemBitCBcKXaHamOBBEH2dGom6v6Unmqjg== +"@rollup/plugin-commonjs@21.0.1": + version "21.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz#1e57c81ae1518e4df0954d681c642e7d94588fee" + integrity sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg== dependencies: "@rollup/pluginutils" "^3.1.0" commondir "^1.0.1" @@ -138,10 +146,10 @@ magic-string "^0.25.7" resolve "^1.17.0" -"@rollup/plugin-node-resolve@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.0.tgz#352f07e430ff377809ec8ec8a6fd636547162dc4" - integrity sha512-41X411HJ3oikIDivT5OKe9EZ6ud6DXudtfNrGbC4nniaxx2esiWjkLOzgnZsWq1IM8YIeL2rzRGLZLBjlhnZtQ== +"@rollup/plugin-node-resolve@13.1.3": + version "13.1.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz#2ed277fb3ad98745424c1d2ba152484508a92d79" + integrity sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ== dependencies: "@rollup/pluginutils" "^3.1.0" "@types/resolve" "1.17.1" @@ -150,10 +158,10 @@ is-module "^1.0.0" resolve "^1.19.0" -"@rollup/plugin-typescript@8.2.1": - version "8.2.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.2.1.tgz#f1a32d4030cc83432ce36a80a922280f0f0b5d44" - integrity sha512-Qd2E1pleDR4bwyFxqbjt4eJf+wB0UKVMLc7/BAFDGVdAXQMCsD4DUv5/7/ww47BZCYxWtJqe1Lo0KVNswBJlRw== +"@rollup/plugin-typescript@8.3.0": + version "8.3.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz#bc1077fa5897b980fc27e376c4e377882c63e68b" + integrity sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA== dependencies: "@rollup/pluginutils" "^3.1.0" resolve "^1.17.0" @@ -184,23 +192,23 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/inquirer@7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-7.3.1.tgz#1f231224e7df11ccfaf4cf9acbcc3b935fea292d" - integrity sha512-osD38QVIfcdgsPCT0V3lD7eH0OFurX71Jft18bZrsVQWVRt6TuxRzlr0GJLrxoHZR2V5ph7/qP8se/dcnI7o0g== +"@types/inquirer@8.2.0": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.2.0.tgz#b9566d048f5ff65159f2ed97aff45fe0f00b35ec" + integrity sha512-BNoMetRf3gmkpAlV5we+kxyZTle7YibdOntIZbU5pyIfMdcwy784KfeZDAcuyMznkh5OLa17RVXZOGA5LTlkgQ== dependencies: "@types/through" "*" - rxjs "^6.4.0" + rxjs "^7.2.0" -"@types/json-schema@^7.0.7": +"@types/json-schema@^7.0.9": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== -"@types/minimist@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" - integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/node@*": version "16.6.0" @@ -214,10 +222,10 @@ dependencies: "@types/node" "*" -"@types/semver@7.3.6": - version "7.3.6" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.6.tgz#e9831776f4512a7ba6da53e71c26e5fb67882d63" - integrity sha512-0caWDWmpCp0uifxFh+FaqK3CuZ2SkRR/ZRxAV5+zNdC3QVUi6wyOJnefhPvtNt8NQWXB5OA93BUvZsXpWat2Xw== +"@types/semver@7.3.9": + version "7.3.9" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc" + integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ== "@types/through@*": version "0.0.30" @@ -226,41 +234,30 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.27.0.tgz#0b7fc974e8bc9b2b5eb98ed51427b0be529b4ad0" - integrity sha512-DsLqxeUfLVNp3AO7PC3JyaddmEHTtI9qTSAs+RB6ja27QvIM0TA8Cizn1qcS6vOu+WDLFJzkwkgweiyFhssDdQ== +"@typescript-eslint/eslint-plugin@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.11.0.tgz#3b866371d8d75c70f9b81535e7f7d3aa26527c7a" + integrity sha512-HJh33bgzXe6jGRocOj4FmefD7hRY4itgjzOrSs3JPrTNXsX7j5+nQPciAUj/1nZtwo2kAc3C75jZO+T23gzSGw== dependencies: - "@typescript-eslint/experimental-utils" "4.27.0" - "@typescript-eslint/scope-manager" "4.27.0" - debug "^4.3.1" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/type-utils" "5.11.0" + "@typescript-eslint/utils" "5.11.0" + debug "^4.3.2" functional-red-black-tree "^1.0.1" - lodash "^4.17.21" - regexpp "^3.1.0" + ignore "^5.1.8" + regexpp "^3.2.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.27.0.tgz#78192a616472d199f084eab8f10f962c0757cd1c" - integrity sha512-n5NlbnmzT2MXlyT+Y0Jf0gsmAQzCnQSWXKy4RGSXVStjDvS5we9IWbh7qRVKdGcxT0WYlgcCYUK/HRg7xFhvjQ== - dependencies: - "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.27.0" - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/typescript-estree" "4.27.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/parser@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.27.0.tgz#85447e573364bce4c46c7f64abaa4985aadf5a94" - integrity sha512-XpbxL+M+gClmJcJ5kHnUpBGmlGdgNvy6cehgR6ufyxkEJMGP25tZKCaKyC0W/JVpuhU3VU1RBn7SYUPKSMqQvQ== +"@typescript-eslint/parser@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.11.0.tgz#b4fcaf65513f9b34bdcbffdda055724a5efb7e04" + integrity sha512-x0DCjetHZYBRovJdr3U0zG9OOdNXUaFLJ82ehr1AlkArljJuwEsgnud+Q7umlGDFLFrs8tU8ybQDFocp/eX8mQ== dependencies: - "@typescript-eslint/scope-manager" "4.27.0" - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/typescript-estree" "4.27.0" - debug "^4.3.1" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/typescript-estree" "5.11.0" + debug "^4.3.2" "@typescript-eslint/parser@^4.0.0": version "4.29.1" @@ -272,14 +269,6 @@ "@typescript-eslint/typescript-estree" "4.29.1" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.27.0.tgz#b0b1de2b35aaf7f532e89c8e81d0fa298cae327d" - integrity sha512-DY73jK6SEH6UDdzc6maF19AHQJBFVRf6fgAXHPXCGEmpqD4vYgPEzqpFz1lf/daSbOcMpPPj9tyXXDPW2XReAw== - dependencies: - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/visitor-keys" "4.27.0" - "@typescript-eslint/scope-manager@4.29.1": version "4.29.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.1.tgz#f25da25bc6512812efa2ce5ebd36619d68e61358" @@ -288,28 +277,32 @@ "@typescript-eslint/types" "4.29.1" "@typescript-eslint/visitor-keys" "4.29.1" -"@typescript-eslint/types@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.27.0.tgz#712b408519ed699baff69086bc59cd2fc13df8d8" - integrity sha512-I4ps3SCPFCKclRcvnsVA/7sWzh7naaM/b4pBO2hVxnM3wrU51Lveybdw5WoIktU/V4KfXrTt94V9b065b/0+wA== +"@typescript-eslint/scope-manager@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.11.0.tgz#f5aef83ff253f457ecbee5f46f762298f0101e4b" + integrity sha512-z+K4LlahDFVMww20t/0zcA7gq/NgOawaLuxgqGRVKS0PiZlCTIUtX0EJbC0BK1JtR4CelmkPK67zuCgpdlF4EA== + dependencies: + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/visitor-keys" "5.11.0" + +"@typescript-eslint/type-utils@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.11.0.tgz#58be0ba73d1f6ef8983d79f7f0bc2209b253fefe" + integrity sha512-wDqdsYO6ofLaD4DsGZ0jGwxp4HrzD2YKulpEZXmgN3xo4BHJwf7kq49JTRpV0Gx6bxkSUmc9s0EIK1xPbFFpIA== + dependencies: + "@typescript-eslint/utils" "5.11.0" + debug "^4.3.2" + tsutils "^3.21.0" "@typescript-eslint/types@4.29.1": version "4.29.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.1.tgz#94cce6cf7cc83451df03339cda99d326be2feaf5" integrity sha512-Jj2yu78IRfw4nlaLtKjVaGaxh/6FhofmQ/j8v3NXmAiKafbIqtAPnKYrf0sbGjKdj0hS316J8WhnGnErbJ4RCA== -"@typescript-eslint/typescript-estree@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.27.0.tgz#189a7b9f1d0717d5cccdcc17247692dedf7a09da" - integrity sha512-KH03GUsUj41sRLLEy2JHstnezgpS5VNhrJouRdmh6yNdQ+yl8w5LrSwBkExM+jWwCJa7Ct2c8yl8NdtNRyQO6g== - dependencies: - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/visitor-keys" "4.27.0" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" - semver "^7.3.5" - tsutils "^3.21.0" +"@typescript-eslint/types@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.11.0.tgz#ba345818a2540fdf2755c804dc2158517ab61188" + integrity sha512-cxgBFGSRCoBEhvSVLkKw39+kMzUKHlJGVwwMbPcTZX3qEhuXhrjwaZXWMxVfxDgyMm+b5Q5b29Llo2yow8Y7xQ== "@typescript-eslint/typescript-estree@4.29.1": version "4.29.1" @@ -324,13 +317,30 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.27.0.tgz#f56138b993ec822793e7ebcfac6ffdce0a60cb81" - integrity sha512-es0GRYNZp0ieckZ938cEANfEhsfHrzuLrePukLKtY3/KPXcq1Xd555Mno9/GOgXhKzn0QfkDLVgqWO3dGY80bg== +"@typescript-eslint/typescript-estree@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.11.0.tgz#53f9e09b88368191e52020af77c312a4777ffa43" + integrity sha512-yVH9hKIv3ZN3lw8m/Jy5I4oXO4ZBMqijcXCdA4mY8ull6TPTAoQnKKrcZ0HDXg7Bsl0Unwwx7jcXMuNZc0m4lg== dependencies: - "@typescript-eslint/types" "4.27.0" - eslint-visitor-keys "^2.0.0" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/visitor-keys" "5.11.0" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.11.0.tgz#d91548ef180d74c95d417950336d9260fdbe1dc5" + integrity sha512-g2I480tFE1iYRDyMhxPAtLQ9HAn0jjBtipgTCZmd9I9s11OV8CTsG+YfFciuNDcHqm4csbAgC2aVZCHzLxMSUw== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/typescript-estree" "5.11.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" "@typescript-eslint/visitor-keys@4.29.1": version "4.29.1" @@ -340,20 +350,40 @@ "@typescript-eslint/types" "4.29.1" eslint-visitor-keys "^2.0.0" +"@typescript-eslint/visitor-keys@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.11.0.tgz#888542381f1a2ac745b06d110c83c0b261487ebb" + integrity sha512-E8w/vJReMGuloGxJDkpPlGwhxocxOpSVgSvjiLO5IxZPmxZF30weOeJYyPSEACwM+X4NziYS9q+WkN/2DHYQwA== + dependencies: + "@typescript-eslint/types" "5.11.0" + eslint-visitor-keys "^3.0.0" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + acorn-jsx@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.6.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== + +acorn@^8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== agent-base@6: version "6.0.2" @@ -372,21 +402,6 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.6.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" - integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -409,6 +424,11 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -416,7 +436,7 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -436,12 +456,10 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-back@^3.0.1, array-back@^3.1.0: version "3.1.0" @@ -453,35 +471,30 @@ array-back@^4.0.1: resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== -array-includes@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" - integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== +array-includes@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" + integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" + es-abstract "^1.19.1" get-intrinsic "^1.1.1" - is-string "^1.0.5" + is-string "^1.0.7" array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.flat@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" - integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== +array.prototype.flat@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" + integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + es-abstract "^1.19.0" async@0.9.x: version "0.9.2" @@ -553,15 +566,15 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -chalk@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^2.0.0, chalk@^2.4.2: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -570,14 +583,6 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -596,9 +601,9 @@ cli-cursor@^3.1.0: restore-cursor "^3.1.0" cli-spinners@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" - integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cli-width@^3.0.0: version "3.0.0" @@ -666,6 +671,11 @@ command-line-usage@^6.1.0: table-layout "^1.0.1" typical "^5.2.0" +commander@8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -686,6 +696,13 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +cross-fetch@3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -703,7 +720,7 @@ ctrlc-windows@^2.0.0: "@mapbox/node-pre-gyp" "^1.0.5" neon-cli "^0.8.1" -debug@4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: +debug@4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== @@ -784,16 +801,18 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -effection@2.0.0-beta.8: - version "2.0.0-beta.8" - resolved "https://registry.yarnpkg.com/effection/-/effection-2.0.0-beta.8.tgz#80fa2bea4f6a481822a5dc56dba70fe08f236c92" - integrity sha512-FlGELoXUEra1ueawOT846sc/GZ5taB4oOI8MApZk1lX5Mh5hkES2qp7Xa9GajzBm5QCjBso4636gmSLTDg181g== +effection@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/effection/-/effection-2.0.4.tgz#2ca9defcebfa75b408f83f6a16ae10ec6c70b48a" + integrity sha512-8haobRaTJbwNM32GeSS5Do0WHB/Xev94SukFtQHEli+3TTDxYwW+NQcp0lAb8J4ISzvKjL+OyodGPMEyegbjog== dependencies: - "@effection/channel" "2.0.0-beta.8" - "@effection/core" "2.0.0-beta.7" - "@effection/events" "2.0.0-beta.8" - "@effection/main" "2.0.0-beta.8" - "@effection/subscription" "2.0.0-beta.8" + "@effection/channel" "2.0.3" + "@effection/core" "2.2.0" + "@effection/events" "2.0.3" + "@effection/fetch" "2.0.4" + "@effection/main" "2.0.3" + "@effection/stream" "2.0.3" + "@effection/subscription" "2.0.3" ejs@^3.1.5: version "3.1.6" @@ -807,36 +826,25 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: - version "1.18.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.5.tgz#9b10de7d4c206a3581fd5b2124233e04db49ae19" - integrity sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA== +es-abstract@^1.19.0, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" has "^1.0.3" has-symbols "^1.0.2" internal-slot "^1.0.3" - is-callable "^1.2.3" + is-callable "^1.2.4" is-negative-zero "^2.0.1" - is-regex "^1.1.3" - is-string "^1.0.6" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" object-inspect "^1.11.0" object-keys "^1.1.1" object.assign "^4.1.2" @@ -868,10 +876,10 @@ eslint-config-prettier@8.3.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== -eslint-config-standard-with-typescript@20.0.0: - version "20.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-20.0.0.tgz#0c550eca0a216cbf8da9013eb6e311acd3102d87" - integrity sha512-IoySf3r0a2+P3Z6GMjv8p1HuOQ6GWQbMpdt9G8uEbkGpnNWAGBXpgaiutbZHbaQAvG5pkVtYepCfHUxYbVDLCA== +eslint-config-standard-with-typescript@21.0.1: + version "21.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-21.0.1.tgz#f4c8bb883d8dfd634005239a54c3c222746e3c64" + integrity sha512-FeiMHljEJ346Y0I/HpAymNKdrgKEpHpcg/D93FvPHWfCzbT4QyUJba/0FwntZeGLXfUiWDSeKmdJD597d9wwiw== dependencies: "@typescript-eslint/parser" "^4.0.0" eslint-config-standard "^16.0.0" @@ -881,21 +889,21 @@ eslint-config-standard@^16.0.0: resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516" integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg== -eslint-import-resolver-node@^0.3.4: - version "0.3.5" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.5.tgz#939bbb0f74e179e757ca87f7a4a890dabed18ac4" - integrity sha512-XMoPKjSpXbkeJ7ZZ9icLnJMTY5Mc1kZbCakHquaFsXPpyWOwK0TK6CODO+0ca54UoM9LKOxyUNnoVZRl8TeaAg== +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== dependencies: debug "^3.2.7" resolve "^1.20.0" -eslint-module-utils@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" - integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== +eslint-module-utils@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz#1d0aa455dcf41052339b63cada8ab5fd57577129" + integrity sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg== dependencies: debug "^3.2.7" - pkg-dir "^2.0.0" + find-up "^2.1.0" eslint-plugin-es@^3.0.0: version "3.0.1" @@ -905,26 +913,24 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@2.23.4: - version "2.23.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz#8dceb1ed6b73e46e50ec9a5bb2411b645e7d3d97" - integrity sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ== +eslint-plugin-import@2.25.4: + version "2.25.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1" + integrity sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA== dependencies: - array-includes "^3.1.3" - array.prototype.flat "^1.2.4" + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" debug "^2.6.9" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.1" - find-up "^2.0.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.2" has "^1.0.3" - is-core-module "^2.4.0" + is-core-module "^2.8.0" + is-glob "^4.0.3" minimatch "^3.0.4" - object.values "^1.1.3" - pkg-up "^2.0.0" - read-pkg-up "^3.0.0" + object.values "^1.1.5" resolve "^1.20.0" - tsconfig-paths "^3.9.0" + tsconfig-paths "^3.12.0" eslint-plugin-lodash-template@0.19.0: version "0.19.0" @@ -946,10 +952,10 @@ eslint-plugin-node@11.1.0: resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-promise@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz#fb2188fb734e4557993733b41aa1a688f46c6f24" - integrity sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng== +eslint-plugin-promise@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz#a596acc32981627eb36d9d75f9666ac1a4564971" + integrity sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw== eslint-plugin-security@1.4.0: version "1.4.0" @@ -966,7 +972,15 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.0.0, eslint-utils@^2.1.0: +eslint-scope@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153" + integrity sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== @@ -980,7 +994,7 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: +eslint-visitor-keys@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== @@ -990,64 +1004,79 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint@7.28.0: - version "7.28.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.28.0.tgz#435aa17a0b82c13bb2be9d51408b617e49c1e820" - integrity sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g== +eslint-visitor-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186" + integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== + +eslint-visitor-keys@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz#eee4acea891814cda67a7d8812d9647dd0179af2" + integrity sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA== + +eslint-visitor-keys@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1" + integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ== + +eslint@8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.8.0.tgz#9762b49abad0cb4952539ffdb0a046392e571a2d" + integrity sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ== dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.2" + "@eslint/eslintrc" "^1.0.5" + "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" + eslint-scope "^7.1.0" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.2.0" + espree "^9.3.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" + glob-parent "^6.0.1" globals "^13.6.0" - ignore "^4.0.6" + ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" + regexpp "^3.2.0" + strip-ansi "^6.0.1" strip-json-comments "^3.1.0" - table "^6.0.9" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.2.0.tgz#c50814e01611c2d0f8bd4daa83c369eabba80dbc" + integrity sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg== dependencies: - acorn "^7.4.0" + acorn "^8.6.0" acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" + eslint-visitor-keys "^3.1.0" -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +espree@^9.3.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.0.tgz#c1240d79183b72aaee6ccfa5a90bc9111df085a8" + integrity sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ== + dependencies: + acorn "^8.7.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.1.0" esquery@^1.0.1, esquery@^1.4.0: version "1.4.0" @@ -1088,7 +1117,12 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -execa@^5.0.0: +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +execa@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -1180,7 +1214,7 @@ find-replace@^3.0.0: dependencies: array-back "^3.0.1" -find-up@^2.0.0, find-up@^2.1.0: +find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= @@ -1255,6 +1289,14 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + git-config@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/git-config/-/git-config-0.0.7.tgz#a9c8a3ef07a776c3d72261356d8b727b62202b28" @@ -1269,6 +1311,13 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + glob@^7.1.3, glob@^7.1.6: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" @@ -1288,7 +1337,7 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" -globby@^11.0.3: +globby@^11.0.3, globby@^11.0.4: version "11.0.4" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== @@ -1300,11 +1349,6 @@ globby@^11.0.3: merge2 "^1.3.0" slash "^3.0.0" -graceful-fs@^4.1.2: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - handlebars@^4.7.6: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" @@ -1356,11 +1400,6 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - https-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -1391,11 +1430,16 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1, ignore@^5.1.4: +ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -1427,41 +1471,41 @@ iniparser@~1.0.5: resolved "https://registry.yarnpkg.com/iniparser/-/iniparser-1.0.5.tgz#836d6befe6dfbfcee0bccf1cf9f2acc7027f783d" integrity sha1-g21r7+bfv87gvM8c+fKsxwJ/eD0= -inquirer@^7.3.3: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== +inquirer@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" + integrity sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ== dependencies: ansi-escapes "^4.2.1" - chalk "^4.1.0" + chalk "^4.1.1" cli-cursor "^3.1.0" cli-width "^3.0.0" external-editor "^3.0.3" figures "^3.0.0" - lodash "^4.17.19" + lodash "^4.17.21" mute-stream "0.0.8" + ora "^5.4.1" run-async "^2.4.0" - rxjs "^6.6.0" + rxjs "^7.2.0" string-width "^4.1.0" strip-ansi "^6.0.0" through "^2.3.6" -inquirer@^8.0.0: - version "8.1.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.1.2.tgz#65b204d2cd7fb63400edd925dfe428bafd422e3d" - integrity sha512-DHLKJwLPNgkfwNmsuEUKSejJFbkv0FMO9SMiQbjI3n5NQuCrSIBqP66ggqyz2a6t2qEolKrMjhQ3+W/xXgUQ+Q== +inquirer@^7.3.3: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== dependencies: ansi-escapes "^4.2.1" - chalk "^4.1.1" + chalk "^4.1.0" cli-cursor "^3.1.0" cli-width "^3.0.0" external-editor "^3.0.3" figures "^3.0.0" - lodash "^4.17.21" + lodash "^4.17.19" mute-stream "0.0.8" - ora "^5.3.0" run-async "^2.4.0" - rxjs "^7.2.0" + rxjs "^6.6.0" string-width "^4.1.0" strip-ansi "^6.0.0" through "^2.3.6" @@ -1475,11 +1519,6 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - is-bigint@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.3.tgz#fc9d9e364210480675653ddaea0518528d49a581" @@ -1493,18 +1532,25 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-callable@^1.1.4, is-callable@^1.2.3: +is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== -is-core-module@^2.2.0, is-core-module@^2.4.0: +is-core-module@^2.2.0: version "2.5.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491" integrity sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg== dependencies: has "^1.0.3" +is-core-module@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== + dependencies: + has "^1.0.3" + is-date-object@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" @@ -1541,6 +1587,13 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -1575,7 +1628,7 @@ is-reference@^1.2.1: dependencies: "@types/estree" "*" -is-regex@^1.1.3: +is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -1583,12 +1636,17 @@ is-regex@^1.1.3: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-string@^1.0.5, is-string@^1.0.6: +is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== @@ -1607,6 +1665,13 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-weakref@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" + integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== + dependencies: + call-bind "^1.0.0" + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1627,45 +1692,29 @@ jake@^10.6.1: filelist "^1.0.1" minimatch "^3.0.4" -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + argparse "^2.0.1" json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json5@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" - integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== dependencies: - minimist "^1.2.5" + minimist "^1.2.0" levn@^0.4.1: version "0.4.1" @@ -1675,16 +1724,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -1698,21 +1737,11 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= - lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -1857,6 +1886,13 @@ neon-cli@^0.8.1: validate-npm-package-license "^3.0.4" validate-npm-package-name "^3.0.0" +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -1869,16 +1905,6 @@ nopt@^5.0.0: dependencies: abbrev "1" -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -1926,14 +1952,14 @@ object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.values@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" - integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== +object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.2" + es-abstract "^1.19.1" once@^1.3.0: version "1.4.0" @@ -1961,7 +1987,7 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -ora@^5.3.0: +ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== @@ -2007,14 +2033,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -2040,13 +2058,6 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -2057,45 +2068,21 @@ picomatch@^2.2.2, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6" - integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA== +prettier@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2106,23 +2093,6 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - readable-stream@^2.0.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -2150,22 +2120,17 @@ reduce-flatten@^2.0.0: resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== -regexpp@^3.0.0, regexpp@^3.1.0: +regexpp@^3.0.0, regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0: +resolve@^1.10.1, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -2198,10 +2163,10 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rollup@2.52.1: - version "2.52.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.52.1.tgz#dd1cc178d70cf35c48d943fc06fdc32d546e6876" - integrity sha512-/SPqz8UGnp4P1hq6wc9gdTqA2bXQXGx13TtoL03GBm6qGRI6Hm3p4Io7GeiHNLl0BsQAne1JNYY+q/apcY933w== +rollup@2.67.1: + version "2.67.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.67.1.tgz#4402665706fa00f321d446ce45f880e02cf54f01" + integrity sha512-1Sbcs4OuW+aD+hhqpIRl+RqooIpF6uQcfzU/QSI7vGkwADY6cM4iLsBGRM2CGLXDTDN5y/yShohFmnKegSPWzg== optionalDependencies: fsevents "~2.3.2" @@ -2217,7 +2182,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^6.4.0, rxjs@^6.6.0: +rxjs@^6.6.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== @@ -2253,25 +2218,20 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -scaffe@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/scaffe/-/scaffe-1.1.0.tgz#336bedf0c4e35bfab20043cb71c7f95ba6294bcb" - integrity sha512-YosRRAwwUEdrBwIVq3HQ8bTXe/KB573WcGEooX0gjB0XgSwgtlAJW7+makrxXauF7KAtsFeRKuS3z+apC9VAlg== +scaffe@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/scaffe/-/scaffe-1.2.0.tgz#0d1c0e1bf0d1ffacf275153190e45c5d57fe2da0" + integrity sha512-IHp+tYYVt7V0FDh5REd/EqydMUBaRSIB0iJgNi5+FZTvtDOePMc6tIn/h134cMQwYHonCYYnLg0eGjnr2dRzHA== dependencies: ejs "^3.1.5" fast-glob "^3.2.5" -"semver@2 || 3 || 4 || 5": - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.0.0, semver@^6.1.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -2309,25 +2269,21 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +signal-exit@^3.0.3: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -2364,11 +2320,6 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - stacktrace-parser@^0.1.10: version "0.1.10" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" @@ -2393,7 +2344,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^4.1.0, string-width@^4.2.0: +string-width@^4.1.0: version "4.2.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== @@ -2453,6 +2404,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -2492,22 +2450,10 @@ table-layout@^1.0.1: typical "^5.2.0" wordwrapjs "^4.0.0" -table@^6.0.9: - version "6.7.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" - integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== - dependencies: - ajv "^8.0.1" - lodash.clonedeep "^4.5.0" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - tar@^6.1.0: - version "6.1.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.8.tgz#4fc50cfe56511c538ce15b71e05eebe66530cbd4" - integrity sha512-sb9b0cp855NbkMJcskdSYA7b11Q8JsX4qe4pyUAfHp+Y6jBjJeek2ZVlwEfWayshEIwlIzXx0Fain3QG9JPm2A== + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -2516,7 +2462,7 @@ tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" -temp-dir@^2.0.0: +temp-dir@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== @@ -2550,24 +2496,30 @@ toml@^3.0.0: resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + ts-typed-json@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/ts-typed-json/-/ts-typed-json-0.3.2.tgz#f4f20f45950bae0a383857f7b0a94187eca1b56a" integrity sha512-Tdu3BWzaer7R5RvBIJcg9r8HrTZgpJmsX+1meXMJzYypbkj8NK2oJN0yvm4Dp/Iv6tzFa/L5jKRmEVTga6K3nA== -tsconfig-paths@^3.9.0: - version "3.10.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz#79ae67a68c15289fdf5c51cb74f397522d795ed7" - integrity sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q== +tsconfig-paths@^3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b" + integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg== dependencies: - json5 "^2.2.0" + "@types/json5" "^0.0.29" + json5 "^1.0.1" minimist "^1.2.0" strip-bom "^3.0.0" -tslib@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== +tslib@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" @@ -2608,10 +2560,10 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== -typescript@4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc" - integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew== +typescript@4.5.5: + version "4.5.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" + integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== typical@^4.0.0: version "4.0.0" @@ -2655,7 +2607,7 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: +validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== @@ -2677,6 +2629,19 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" diff --git a/tooling/webdriver/Cargo.lock b/tooling/webdriver/Cargo.lock index 98593fb503c8..ed25ad7271fd 100644 --- a/tooling/webdriver/Cargo.lock +++ b/tooling/webdriver/Cargo.lock @@ -4,21 +4,15 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.40" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cfg-if" @@ -40,9 +34,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "futures" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -55,9 +49,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -65,15 +59,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -82,18 +76,16 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-macro" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -101,23 +93,22 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.15" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ - "autocfg", "futures-channel", "futures-core", "futures-io", @@ -127,27 +118,25 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] [[package]] name = "http" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.1", ] [[package]] name = "http-body" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" dependencies = [ "bytes", "http", @@ -156,21 +145,21 @@ dependencies = [ [[package]] name = "httparse" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68" +checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" [[package]] name = "httpdate" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.8" +version = "0.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f71a7eea53a3f8257a7b4795373ff886397178cd634430ea94e12d7fe4fe34" +checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" dependencies = [ "bytes", "futures-channel", @@ -180,8 +169,8 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa", - "pin-project", + "itoa 0.4.8", + "pin-project-lite", "socket2", "tokio", "tower-service", @@ -191,9 +180,15 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "lazy_static" @@ -203,9 +198,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.95" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "log" @@ -218,15 +213,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "mio" -version = "0.7.11" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", @@ -255,35 +250,15 @@ dependencies = [ [[package]] name = "pico-args" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d7afeb98c5a10e0bffcc7fc16e105b04d06729fac5fd6384aebf7ff5cb5a67d" - -[[package]] -name = "pin-project" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.7" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468" [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -291,56 +266,44 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "serde" -version = "1.0.126" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -349,20 +312,20 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" dependencies = [ - "itoa", + "itoa 1.0.1", "ryu", "serde", ] [[package]] name = "signal-hook" -version = "0.3.9" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" +checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" dependencies = [ "libc", "signal-hook-registry", @@ -379,9 +342,9 @@ dependencies = [ [[package]] name = "signal-hook-tokio" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c5d32165ff8b94e68e7b3bdecb1b082e958c22434b363482cfb89dcd6f3ff8" +checksum = "213241f76fb1e37e27de3b6aa1b068a2c333233b59cca6634f634b80a27ecf1e" dependencies = [ "futures-core", "libc", @@ -391,15 +354,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "socket2" -version = "0.4.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", "winapi", @@ -407,9 +370,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.72" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -434,22 +397,22 @@ dependencies = [ [[package]] name = "tokio" -version = "1.6.1" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a38d31d7831c6ed7aad00aa4c12d9375fd225a6dd77da1d25b707346319a975" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" dependencies = [ - "autocfg", "libc", "mio", "pin-project-lite", "tokio-macros", + "winapi", ] [[package]] name = "tokio-macros" -version = "1.2.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", @@ -464,9 +427,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "2d8d93354fe2a8e50d5953f5ae2e47a3fc2ef03292e7ea46e3cc38f549525fb9" dependencies = [ "cfg-if", "pin-project-lite", @@ -475,9 +438,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.18" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" +checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" dependencies = [ "lazy_static", ] @@ -506,11 +469,12 @@ dependencies = [ [[package]] name = "which" -version = "4.1.0" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe" +checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" dependencies = [ "either", + "lazy_static", "libc", ] diff --git a/tooling/webdriver/Cargo.toml b/tooling/webdriver/Cargo.toml index 57545d242d83..7c508940968e 100644 --- a/tooling/webdriver/Cargo.toml +++ b/tooling/webdriver/Cargo.toml @@ -11,7 +11,8 @@ repository = "https://github.com/tauri-apps/tauri" description = "Webdriver server for Tauri applications" readme = "README.md" exclude = [ ".license_template", "/target" ] -edition = "2018" +edition = "2021" +rust-version = "1.57" [dependencies] anyhow = "1" diff --git a/tooling/webdriver/README.md b/tooling/webdriver/README.md index 4f23bead7e4f..4021d2669d59 100644 --- a/tooling/webdriver/README.md +++ b/tooling/webdriver/README.md @@ -23,7 +23,7 @@ will be used that wraps around [wry]._ ## Trying it out -Check out the documentation at https://tauri.studio/en/docs/usage/guides/webdriver/ci to build a small example +Check out the documentation at https://tauri.studio/en/docs/guides/webdriver/ci to build a small example application that had WebDriver tests. [WebDriver Intermediary Node]: https://www.w3.org/TR/webdriver/#dfn-intermediary-nodes diff --git a/tooling/webdriver/src/server.rs b/tooling/webdriver/src/server.rs index 15c44c399ce0..be87e238a884 100644 --- a/tooling/webdriver/src/server.rs +++ b/tooling/webdriver/src/server.rs @@ -22,6 +22,8 @@ const TAURI_OPTIONS: &str = "tauri:options"; #[derive(Debug, Deserialize)] struct TauriOptions { application: PathBuf, + #[serde(default)] + args: Vec<String>, } impl TauriOptions { @@ -30,7 +32,7 @@ impl TauriOptions { let mut map = Map::new(); map.insert( "webkitgtk:browserOptions".into(), - json!({"binary": self.application}), + json!({"binary": self.application, "args": self.args}), ); map } @@ -40,7 +42,10 @@ impl TauriOptions { let mut map = Map::new(); map.insert("ms:edgeChromium".into(), json!(true)); map.insert("browserName".into(), json!("webview2")); - map.insert("ms:edgeOptions".into(), json!({"binary": self.application})); + map.insert( + "ms:edgeOptions".into(), + json!({"binary": self.application, "args": self.args}), + ); map } }