mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-05-03 12:15:11 +02:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d8bfdc73a6 | |||
| 22bb0e5b61 | |||
| 37cb9a6681 | |||
| 725ff4295e | |||
| 117c67da13 | |||
| 490d4208d7 | |||
| 1adf7e3872 | |||
| 21bf0a4f84 | |||
| 644807bf01 | |||
| 93bdb6d133 | |||
| 4c120d4176 | |||
| 8824a24e15 | |||
| f83b9e9813 | |||
| 77ee644afd | |||
| 288e7b9ae2 | |||
| 12b78a23c4 | |||
| 97e2e75e29 |
+12
-2
@@ -3,12 +3,22 @@
|
||||
"pkgManagers": {
|
||||
"javascript": {
|
||||
"version": true,
|
||||
"getPublishedVersion": "node ../../.scripts/covector/package-latest-version.cjs npm ${ pkgFile.pkg.name } ${ pkgFile.pkg.version }",
|
||||
"getPublishedVersion": {
|
||||
"use": "fetch:check",
|
||||
"options": {
|
||||
"url": "https://registry.npmjs.com/${ pkg.pkgFile.pkg.name }/${ pkg.pkgFile.version }"
|
||||
}
|
||||
},
|
||||
"publish": ["pnpm build", "pnpm publish --access public --no-git-checks"]
|
||||
},
|
||||
"rust": {
|
||||
"version": true,
|
||||
"getPublishedVersion": "node ../../.scripts/covector/package-latest-version.cjs cargo ${ pkgFile.pkg.package.name } ${ pkgFile.pkg.package.version }",
|
||||
"getPublishedVersion": {
|
||||
"use": "fetch:check",
|
||||
"options": {
|
||||
"url": "https://crates.io/api/v1/crates/${ pkg.pkgFile.pkg.package.name }/${ pkg.pkgFile.version }"
|
||||
}
|
||||
},
|
||||
"publish": [
|
||||
{
|
||||
"command": "cargo package --no-verify",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
notification: patch
|
||||
---
|
||||
|
||||
Fixed an issue that caused the `notification` plugin's initialization script to cause the WebView on Windows to throw a `STATUS_ACCESS_VIOLATION` error on remote websites.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"updater": patch
|
||||
---
|
||||
|
||||
On Windows, use a named tempfile with `<app name>-<version>-installer.exe` (or `.msi`) for v2 updater
|
||||
|
||||
**Breaking Change**: `UpdaterBuilder::new` now takes one more argument `app_name: String`
|
||||
@@ -36,6 +36,7 @@
|
||||
".changes/fix-fs-watcher-basedir.md",
|
||||
".changes/fix-http-default-features.md",
|
||||
".changes/fix-http-scope-url-match.md",
|
||||
".changes/fix-notification-access-violation.md",
|
||||
".changes/fix-shutdown-timing.md",
|
||||
".changes/fix-updater-cleanup.md",
|
||||
".changes/fix-updater-default-features.md",
|
||||
@@ -61,6 +62,7 @@
|
||||
".changes/http-user-agent.md",
|
||||
".changes/impl-ext-for-webview-windows.md",
|
||||
".changes/msrv-1.75.md",
|
||||
".changes/named-tempfile-updater-windows.md",
|
||||
".changes/notifcation-permission-commands.md",
|
||||
".changes/notification-fix-dev-check.md",
|
||||
".changes/notification-fix-dev-name.md",
|
||||
@@ -81,6 +83,7 @@
|
||||
".changes/single-instance.macos.md",
|
||||
".changes/sql-column-order.md",
|
||||
".changes/sql-public-db-instances.md",
|
||||
".changes/sql-update-sqlx-0-8.md",
|
||||
".changes/target-sdk-34.md",
|
||||
".changes/tauri-beta-14-dependencies.md",
|
||||
".changes/tauri-beta-14.md",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
sql: patch
|
||||
---
|
||||
|
||||
Update sqlx to 0.8 - Check out their changelog for behavior changes: https://github.com/launchbadge/sqlx/blob/main/CHANGELOG.md#080---2024-07-22
|
||||
@@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
// Copyright 2019-2023 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 publish` step to
|
||||
check the latest version of a crate, considering the current minor version.
|
||||
*/
|
||||
|
||||
const https = require("https");
|
||||
|
||||
const kind = process.argv[2];
|
||||
const packageName = process.argv[3];
|
||||
const packageVersion = process.argv[4];
|
||||
const target = packageVersion.substring(0, packageVersion.lastIndexOf("."));
|
||||
|
||||
let url = null;
|
||||
switch (kind) {
|
||||
case "cargo":
|
||||
url = `https://crates.io/api/v1/crates/${packageName}`;
|
||||
break;
|
||||
case "npm":
|
||||
url = `https://registry.npmjs.org/${packageName}`;
|
||||
break;
|
||||
default:
|
||||
throw new Error("unexpected kind " + kind);
|
||||
}
|
||||
|
||||
const options = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
"User-Agent": "tauri (https://github.com/tauri-apps/tauri)",
|
||||
},
|
||||
};
|
||||
|
||||
https.get(url, options, (response) => {
|
||||
let chunks = [];
|
||||
response.on("data", function (chunk) {
|
||||
chunks.push(chunk);
|
||||
});
|
||||
|
||||
response.on("end", function () {
|
||||
const data = JSON.parse(chunks.join(""));
|
||||
if (kind === "cargo") {
|
||||
if (data.versions) {
|
||||
const versions = data.versions.filter((v) => v.num.startsWith(target));
|
||||
console.log(versions.length ? versions[0].num : "0.0.0");
|
||||
} else {
|
||||
console.log("0.0.0");
|
||||
}
|
||||
} else if (kind === "npm") {
|
||||
const versions = Object.keys(data.versions || {}).filter((v) =>
|
||||
v.startsWith(target),
|
||||
);
|
||||
console.log(versions[versions.length - 1] || "0.0.0");
|
||||
}
|
||||
});
|
||||
});
|
||||
Generated
+208
-215
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.14]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `notification@2.0.0-beta.11`
|
||||
- Upgraded to `updater@2.0.0-beta.11`
|
||||
|
||||
## \[2.0.0-beta.13]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "api"
|
||||
publish = false
|
||||
version = "2.0.0-beta.13"
|
||||
version = "2.0.0-beta.14"
|
||||
description = "An example Tauri Application showcasing the api"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
@@ -24,7 +24,7 @@ tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.0.0-beta.11", fea
|
||||
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.1.0-beta.6" }
|
||||
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.0.0-beta.11" }
|
||||
tauri-plugin-http = { path = "../../../plugins/http", features = [ "multipart" ], version = "2.0.0-beta.12" }
|
||||
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.0.0-beta.10", features = [ "windows7-compat" ] }
|
||||
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.0.0-beta.11", features = [ "windows7-compat" ] }
|
||||
tauri-plugin-os = { path = "../../../plugins/os", version = "2.0.0-beta.8" }
|
||||
tauri-plugin-process = { path = "../../../plugins/process", version = "2.0.0-beta.8" }
|
||||
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-beta.9" }
|
||||
@@ -43,7 +43,7 @@ tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-beta.9"
|
||||
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.0.0-beta.8" }
|
||||
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.0.0-beta.8" }
|
||||
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.0.0-beta.10" }
|
||||
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.0.0-beta.11" }
|
||||
|
||||
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
|
||||
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.0.0-beta.9" }
|
||||
|
||||
+5
-5
@@ -10,19 +10,19 @@
|
||||
"format-check": "prettier --check \"./**/*.{cjs,mjs,js,jsx,mts,ts,tsx,html,css,json}\" --ignore-path .prettierignore"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.6.0",
|
||||
"@eslint/js": "9.7.0",
|
||||
"@rollup/plugin-node-resolve": "15.2.3",
|
||||
"@rollup/plugin-terser": "0.4.4",
|
||||
"@rollup/plugin-typescript": "11.1.6",
|
||||
"@types/eslint__js": "8.42.3",
|
||||
"covector": "^0.12.0",
|
||||
"eslint": "9.6.0",
|
||||
"eslint": "9.7.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-security": "3.0.1",
|
||||
"prettier": "3.3.2",
|
||||
"rollup": "4.18.1",
|
||||
"prettier": "3.3.3",
|
||||
"rollup": "4.19.0",
|
||||
"tslib": "2.6.3",
|
||||
"typescript": "5.5.3",
|
||||
"typescript": "5.5.4",
|
||||
"typescript-eslint": "rc-v8"
|
||||
},
|
||||
"resolutions": {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use serde::de::DeserializeOwned;
|
||||
use tauri::{
|
||||
plugin::{Builder, PluginApi, TauriPlugin},
|
||||
AppHandle, Emitter, Manager, Runtime,
|
||||
AppHandle, Manager, Runtime,
|
||||
};
|
||||
|
||||
mod commands;
|
||||
@@ -23,7 +23,10 @@ fn init_deep_link<R: Runtime, C: DeserializeOwned>(
|
||||
) -> crate::Result<DeepLink<R>> {
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
use tauri::ipc::{Channel, InvokeBody};
|
||||
use tauri::{
|
||||
ipc::{Channel, InvokeBody},
|
||||
Emitter,
|
||||
};
|
||||
|
||||
let handle = _api.register_android_plugin(PLUGIN_IDENTIFIER, "DeepLinkPlugin")?;
|
||||
|
||||
@@ -388,6 +391,8 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
|
||||
.on_event(|_app, _event| {
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
if let tauri::RunEvent::Opened { urls } = _event {
|
||||
use tauri::Emitter;
|
||||
|
||||
let _ = _app.emit("deep-link://new-url", urls);
|
||||
_app.state::<DeepLink<R>>()
|
||||
.current
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.11]
|
||||
|
||||
- [`725ff429`](https://github.com/tauri-apps/plugins-workspace/commit/725ff4295e56df9c30c099813bd64b96fe61b945) ([#1556](https://github.com/tauri-apps/plugins-workspace/pull/1556) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Fixed an issue that caused the `notification` plugin's initialization script to cause the WebView on Windows to throw a `STATUS_ACCESS_VIOLATION` error on remote websites.
|
||||
|
||||
## \[2.0.0-beta.7]
|
||||
|
||||
- [`22a17980`](https://github.com/tauri-apps/plugins-workspace/commit/22a17980ff4f6f8c40adb1b8f4ffc6dae2fe7e30) ([#1537](https://github.com/tauri-apps/plugins-workspace/pull/1537) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Update to tauri beta.24.
|
||||
@@ -100,4 +104,3 @@
|
||||
717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
!
|
||||
717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-plugin-notification"
|
||||
version = "2.0.0-beta.10"
|
||||
version = "2.0.0-beta.11"
|
||||
description = "Send desktop and mobile notifications on your Tauri application."
|
||||
edition = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
|
||||
@@ -57,10 +57,40 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Then you need to add the permissions to your capabilities file:
|
||||
|
||||
`src-tauri/capabilities/main.json`
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"permissions": [
|
||||
...
|
||||
"notification:default"
|
||||
],
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
|
||||
|
||||
```javascript
|
||||
import { isPermissionGranted, requestPermission, sendNotification } from '@tauri-apps/plugin-notification';
|
||||
|
||||
async function checkPermission() {
|
||||
if (!(await isPermissionGranted())) {
|
||||
return (await requestPermission()) === 'granted';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function enqueueNotification(title, body) {
|
||||
if (!(await checkPermission())) {
|
||||
return;
|
||||
}
|
||||
sendNotification({ title, body });
|
||||
}
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -10,7 +10,8 @@ import type { Options } from "./index";
|
||||
let permissionValue = "default";
|
||||
|
||||
async function isPermissionGranted(): Promise<boolean> {
|
||||
if (window.Notification.permission !== "default") {
|
||||
// @ts-expect-error __TEMPLATE_windows__ will be replaced in rust before it's injected.
|
||||
if (window.Notification.permission !== "default" || __TEMPLATE_windows__) {
|
||||
return await Promise.resolve(
|
||||
window.Notification.permission === "granted",
|
||||
);
|
||||
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";async function i(i,n={},t){return window.__TAURI_INTERNALS__.invoke(i,n,t)}"function"==typeof SuppressedError&&SuppressedError,function(){let n=!1,t="default";function o(i){n=!0,window.Notification.permission=i,n=!1}window.Notification=function(n,t){const o=t||{};!async function(n){"object"==typeof n&&Object.freeze(n),await i("plugin:notification|notify",{options:"string"==typeof n?{title:n}:n})}(Object.assign(o,{title:n}))},window.Notification.requestPermission=async function(){return await i("plugin:notification|request_permission").then((i=>(o("prompt"===i?"default":i),i)))},Object.defineProperty(window.Notification,"permission",{enumerable:!0,get:()=>t,set:i=>{if(!n)throw new Error("Readonly property");t=i}}),async function(){return"default"!==window.Notification.permission?await Promise.resolve("granted"===window.Notification.permission):await i("plugin:notification|is_permission_granted")}().then((function(i){o(null===i?"default":i?"granted":"denied")}))}()}();
|
||||
!function(){"use strict";async function i(i,n={},t){return window.__TAURI_INTERNALS__.invoke(i,n,t)}"function"==typeof SuppressedError&&SuppressedError,function(){let n=!1,t="default";function o(i){n=!0,window.Notification.permission=i,n=!1}window.Notification=function(n,t){const o=t||{};!async function(n){"object"==typeof n&&Object.freeze(n),await i("plugin:notification|notify",{options:"string"==typeof n?{title:n}:n})}(Object.assign(o,{title:n}))},window.Notification.requestPermission=async function(){return await i("plugin:notification|request_permission").then((i=>(o("prompt"===i?"default":i),i)))},Object.defineProperty(window.Notification,"permission",{enumerable:!0,get:()=>t,set:i=>{if(!n)throw new Error("Readonly property");t=i}}),async function(){return"default"!==window.Notification.permission||__TEMPLATE_windows__?await Promise.resolve("granted"===window.Notification.permission):await i("plugin:notification|is_permission_granted")}().then((function(i){o(null===i?"default":i?"granted":"denied")}))}()}();
|
||||
|
||||
@@ -227,7 +227,10 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
commands::request_permission,
|
||||
commands::is_permission_granted
|
||||
])
|
||||
.js_init_script(include_str!("init-iife.js").to_string())
|
||||
.js_init_script(include_str!("init-iife.js").replace(
|
||||
"__TEMPLATE_windows__",
|
||||
if cfg!(windows) { "true" } else { "false" },
|
||||
))
|
||||
.setup(|app, api| {
|
||||
#[cfg(mobile)]
|
||||
let notification = mobile::init(app, api)?;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.10]
|
||||
|
||||
- [`37cb9a66`](https://github.com/tauri-apps/plugins-workspace/commit/37cb9a6681b948908cd9443340f6b23401607df7) ([#1575](https://github.com/tauri-apps/plugins-workspace/pull/1575) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Update sqlx to 0.8 - Check out their changelog for behavior changes: https://github.com/launchbadge/sqlx/blob/main/CHANGELOG.md#080---2024-07-22
|
||||
|
||||
## \[2.0.0-beta.7]
|
||||
|
||||
- [`22a17980`](https://github.com/tauri-apps/plugins-workspace/commit/22a17980ff4f6f8c40adb1b8f4ffc6dae2fe7e30) ([#1537](https://github.com/tauri-apps/plugins-workspace/pull/1537) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Update to tauri beta.24.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-plugin-sql"
|
||||
version = "2.0.0-beta.9"
|
||||
version = "2.0.0-beta.10"
|
||||
description = "Interface with SQL databases."
|
||||
authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
@@ -24,7 +24,7 @@ tauri = { workspace = true }
|
||||
log = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
futures-core = "0.3"
|
||||
sqlx = { version = "0.7", features = [ "json", "time" ] }
|
||||
sqlx = { version = "0.8", features = [ "json", "time" ] }
|
||||
time = "0.3"
|
||||
tokio = { version = "1", features = [ "sync" ] }
|
||||
indexmap = { version = "2.2.6", features = [ "serde" ] }
|
||||
|
||||
+20
-1
@@ -158,7 +158,26 @@ fn main() {
|
||||
|
||||
### Applying Migrations
|
||||
|
||||
Migrations are applied automatically when the plugin is initialized. The plugin runs these migrations against the database specified by the connection string. Ensure that the migrations are defined in the correct order and are idempotent (safe to run multiple times).
|
||||
To apply the migrations when the plugin is initialized, add the connection string to the `tauri.conf.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"sql": {
|
||||
"preload": ["sqlite:mydatabase.db"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, the client side `load()` also runs the migrations for a given connection string:
|
||||
|
||||
```ts
|
||||
import Database from "@tauri-apps/plugin-sql";
|
||||
const db = await Database.load("sqlite:mydatabase.db");
|
||||
```
|
||||
|
||||
Ensure that the migrations are defined in the correct order and are safe to run multiple times.
|
||||
|
||||
### Migration Management
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@ impl MigrationSource<'static> for MigrationList {
|
||||
migration.description.into(),
|
||||
migration.kind.into(),
|
||||
migration.sql.into(),
|
||||
false,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## \[2.0.0-beta.11]
|
||||
|
||||
- [`f83b9e98`](https://github.com/tauri-apps/plugins-workspace/commit/f83b9e9813843df19b03b6af1018d848111b2a62) ([#1544](https://github.com/tauri-apps/plugins-workspace/pull/1544) by [@Legend-Master](https://github.com/tauri-apps/plugins-workspace/../../Legend-Master)) On Windows, use a named tempfile with `<app name>-<version>-installer.exe` (or `.msi`) for v2 updater
|
||||
|
||||
**Breaking Change**: `UpdaterBuilder::new` now takes one more argument `app_name: String`
|
||||
|
||||
## \[2.0.0-beta.7]
|
||||
|
||||
- [`22a17980`](https://github.com/tauri-apps/plugins-workspace/commit/22a17980ff4f6f8c40adb1b8f4ffc6dae2fe7e30) ([#1537](https://github.com/tauri-apps/plugins-workspace/pull/1537) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Update to tauri beta.24.
|
||||
@@ -144,4 +150,3 @@
|
||||
717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
92fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
717ae670978feb4492fac1f295998b93f2b9347f)([#371](https://github.com/tauri-apps/plugins-workspace/pull/371)) First v2 alpha release!
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-plugin-updater"
|
||||
version = "2.0.0-beta.10"
|
||||
version = "2.0.0-beta.11"
|
||||
description = "In-app updates for Tauri applications."
|
||||
edition = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
|
||||
@@ -70,10 +70,14 @@ pub trait UpdaterExt<R: Runtime> {
|
||||
impl<R: Runtime, T: Manager<R>> UpdaterExt<R> for T {
|
||||
fn updater_builder(&self) -> UpdaterBuilder {
|
||||
let app = self.app_handle();
|
||||
let version = app.package_info().version.clone();
|
||||
let package_info = app.package_info();
|
||||
let UpdaterState { config, target } = self.state::<UpdaterState>().inner();
|
||||
|
||||
let mut builder = UpdaterBuilder::new(version, config.clone());
|
||||
let mut builder = UpdaterBuilder::new(
|
||||
package_info.name.clone(),
|
||||
package_info.version.clone(),
|
||||
config.clone(),
|
||||
);
|
||||
|
||||
if let Some(target) = target {
|
||||
builder = builder.target(target);
|
||||
|
||||
@@ -94,6 +94,7 @@ impl RemoteRelease {
|
||||
pub type OnBeforeExit = Arc<dyn Fn() + Send + Sync + 'static>;
|
||||
|
||||
pub struct UpdaterBuilder {
|
||||
app_name: String,
|
||||
current_version: Version,
|
||||
config: Config,
|
||||
version_comparator: Option<Box<dyn Fn(Version, RemoteRelease) -> bool + Send + Sync>>,
|
||||
@@ -109,7 +110,9 @@ pub struct UpdaterBuilder {
|
||||
}
|
||||
|
||||
impl UpdaterBuilder {
|
||||
pub fn new(current_version: Version, config: crate::Config) -> Self {
|
||||
/// It's prefered to use [`crate::UpdaterExt::updater_builder`] instead of
|
||||
/// constructing a [`UpdaterBuilder`] with this function yourself
|
||||
pub fn new(app_name: String, current_version: Version, config: crate::Config) -> Self {
|
||||
Self {
|
||||
installer_args: config
|
||||
.windows
|
||||
@@ -117,6 +120,7 @@ impl UpdaterBuilder {
|
||||
.map(|w| w.installer_args.clone())
|
||||
.unwrap_or_default(),
|
||||
current_exe_args: Vec::new(),
|
||||
app_name,
|
||||
current_version,
|
||||
config,
|
||||
version_comparator: None,
|
||||
@@ -239,6 +243,7 @@ impl UpdaterBuilder {
|
||||
|
||||
Ok(Updater {
|
||||
config: self.config,
|
||||
app_name: self.app_name,
|
||||
current_version: self.current_version,
|
||||
version_comparator: self.version_comparator,
|
||||
timeout: self.timeout,
|
||||
@@ -270,6 +275,7 @@ impl UpdaterBuilder {
|
||||
|
||||
pub struct Updater {
|
||||
config: Config,
|
||||
app_name: String,
|
||||
current_version: Version,
|
||||
version_comparator: Option<Box<dyn Fn(Version, RemoteRelease) -> bool + Send + Sync>>,
|
||||
timeout: Option<Duration>,
|
||||
@@ -386,6 +392,7 @@ impl Updater {
|
||||
Some(Update {
|
||||
config: self.config.clone(),
|
||||
on_before_exit: self.on_before_exit.clone(),
|
||||
app_name: self.app_name.clone(),
|
||||
current_version: self.current_version.to_string(),
|
||||
target: self.target.clone(),
|
||||
extract_path: self.extract_path.clone(),
|
||||
@@ -436,6 +443,9 @@ pub struct Update {
|
||||
/// Extract path
|
||||
#[allow(unused)]
|
||||
extract_path: PathBuf,
|
||||
/// App name, used for creating named tempfiles on Windows
|
||||
#[allow(unused)]
|
||||
app_name: String,
|
||||
#[allow(unused)]
|
||||
installer_args: Vec<OsString>,
|
||||
#[allow(unused)]
|
||||
@@ -584,7 +594,7 @@ impl Update {
|
||||
Win32::UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOW},
|
||||
};
|
||||
|
||||
let updater_type = Self::extract(bytes)?;
|
||||
let updater_type = self.extract(bytes)?;
|
||||
|
||||
let install_mode = self.config.install_mode();
|
||||
let current_args = &self.current_exe_args()[1..];
|
||||
@@ -663,24 +673,31 @@ impl Update {
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn extract(bytes: &[u8]) -> Result<WindowsUpdaterType> {
|
||||
fn extract(&self, bytes: &[u8]) -> Result<WindowsUpdaterType> {
|
||||
#[cfg(feature = "zip")]
|
||||
if infer::archive::is_zip(bytes) {
|
||||
return Self::extract_zip(bytes);
|
||||
return self.extract_zip(bytes);
|
||||
}
|
||||
|
||||
Self::extract_exe(bytes)
|
||||
self.extract_exe(bytes)
|
||||
}
|
||||
|
||||
fn make_temp_dir(&self) -> Result<PathBuf> {
|
||||
Ok(tempfile::Builder::new()
|
||||
.prefix(&format!("{}-{}-updater-", self.app_name, self.version))
|
||||
.tempdir()?
|
||||
.into_path())
|
||||
}
|
||||
|
||||
#[cfg(feature = "zip")]
|
||||
fn extract_zip(bytes: &[u8]) -> Result<WindowsUpdaterType> {
|
||||
let tmp_dir = tempfile::Builder::new().tempdir()?.into_path();
|
||||
fn extract_zip(&self, bytes: &[u8]) -> Result<WindowsUpdaterType> {
|
||||
let temp_dir = self.make_temp_dir()?;
|
||||
|
||||
let archive = Cursor::new(bytes);
|
||||
let mut extractor = zip::ZipArchive::new(archive)?;
|
||||
extractor.extract(&tmp_dir)?;
|
||||
extractor.extract(&temp_dir)?;
|
||||
|
||||
let paths = std::fs::read_dir(&tmp_dir)?;
|
||||
let paths = std::fs::read_dir(&temp_dir)?;
|
||||
for path in paths {
|
||||
let path = path?.path();
|
||||
let ext = path.extension();
|
||||
@@ -694,22 +711,31 @@ impl Update {
|
||||
Err(crate::Error::BinaryNotFoundInArchive)
|
||||
}
|
||||
|
||||
fn extract_exe(bytes: &[u8]) -> Result<WindowsUpdaterType> {
|
||||
fn extract_exe(&self, bytes: &[u8]) -> Result<WindowsUpdaterType> {
|
||||
if infer::app::is_exe(bytes) {
|
||||
let (path, temp) = Self::write_to_temp(bytes, ".exe")?;
|
||||
let (path, temp) = self.write_to_temp(bytes, ".exe")?;
|
||||
Ok(WindowsUpdaterType::nsis(path, temp))
|
||||
} else if infer::archive::is_msi(bytes) {
|
||||
let (path, temp) = Self::write_to_temp(bytes, ".msi")?;
|
||||
let (path, temp) = self.write_to_temp(bytes, ".msi")?;
|
||||
Ok(WindowsUpdaterType::msi(path, temp))
|
||||
} else {
|
||||
Err(crate::Error::InvalidUpdaterFormat)
|
||||
}
|
||||
}
|
||||
|
||||
fn write_to_temp(bytes: &[u8], ext: &str) -> Result<(PathBuf, Option<tempfile::TempPath>)> {
|
||||
fn write_to_temp(
|
||||
&self,
|
||||
bytes: &[u8],
|
||||
ext: &str,
|
||||
) -> Result<(PathBuf, Option<tempfile::TempPath>)> {
|
||||
use std::io::Write;
|
||||
|
||||
let mut temp_file = tempfile::Builder::new().suffix(ext).tempfile()?;
|
||||
let temp_dir = self.make_temp_dir()?;
|
||||
let mut temp_file = tempfile::Builder::new()
|
||||
.prefix(&format!("{}-{}-installer", self.app_name, self.version))
|
||||
.suffix(ext)
|
||||
.rand_bytes(0)
|
||||
.tempfile_in(temp_dir)?;
|
||||
temp_file.write_all(bytes)?;
|
||||
|
||||
let temp = temp_file.into_temp_path();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"createUpdaterArtifacts": true,
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
@@ -23,6 +24,9 @@
|
||||
"windows": {
|
||||
"webviewInstallMode": {
|
||||
"type": "skip"
|
||||
},
|
||||
"nsis": {
|
||||
"compression": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,22 +162,25 @@ fn update_app() {
|
||||
// bundle app update
|
||||
build_app(&manifest_dir, &config, true, Default::default());
|
||||
|
||||
let updater_zip_ext = if cfg!(windows) { "zip" } else { "tar.gz" };
|
||||
let updater_zip_ext = if cfg!(target_os = "macos") {
|
||||
Some("tar.gz")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
for (bundle_target, out_bundle_path) in bundle_paths(&root_dir, "1.0.0") {
|
||||
let bundle_updater_ext = out_bundle_path
|
||||
.extension()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.replace("exe", "nsis");
|
||||
let signature_path =
|
||||
out_bundle_path.with_extension(format!("{bundle_updater_ext}.{updater_zip_ext}.sig"));
|
||||
let bundle_updater_ext = out_bundle_path.extension().unwrap().to_str().unwrap();
|
||||
let updater_extension = if let Some(updater_zip_ext) = updater_zip_ext {
|
||||
format!("{bundle_updater_ext}.{updater_zip_ext}")
|
||||
} else {
|
||||
format!("{bundle_updater_ext}")
|
||||
};
|
||||
let signature_extension = format!("{updater_extension}.sig");
|
||||
let signature_path = out_bundle_path.with_extension(signature_extension);
|
||||
let signature = std::fs::read_to_string(&signature_path).unwrap_or_else(|_| {
|
||||
panic!("failed to read signature file {}", signature_path.display())
|
||||
});
|
||||
let out_updater_path =
|
||||
out_bundle_path.with_extension(format!("{}.{}", bundle_updater_ext, updater_zip_ext));
|
||||
let out_updater_path = out_bundle_path.with_extension(updater_extension);
|
||||
let updater_path = root_dir.join(format!(
|
||||
"target/debug/{}",
|
||||
out_updater_path.file_name().unwrap().to_str().unwrap()
|
||||
|
||||
Generated
+546
-655
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user