Compare commits

..

22 Commits

Author SHA1 Message Date
github-actions[bot] 647d8894fe publish new versions (#1580)
Co-authored-by: lucasfernog <lucasfernog@users.noreply.github.com>
2024-07-24 22:10:38 -03:00
Jacob Bolda 5ec310199f remove cargo package, publish without verification (#1581)
* remove cargo package, publish without verification

* remove custom publish with features, --no-verify should handle it now
2024-07-24 21:57:33 -03:00
Jacob Bolda bb09c7ca6e ci: npm publish with provenance (#1582)
* npm publish with provenance

* update token to allow creating id-token
2024-07-24 16:40:11 +03:00
Lucas Fernandes Nogueira 20a1d24ee0 feat(log): add Builder::split to get the raw logger implementation (#1579)
* feat(log): add Builder::split to get the raw logger implementation

This function lets you split the Builder to return the raw logger implementation along the TauriPlugin to be registered. Useful to pipe the logger to other implementations such as multi_log or tauri-plugin-devtools, allowing the plugin to be used along other logging systems.

* clippy

* covector
2024-07-23 23:32:21 -03:00
Jacob Bolda fa275731be (chore) covector comment on forks (#1566) 2024-07-24 05:20:42 +03:00
FabianLars d8bfdc73a6 ci: Fix covector getPublishedVersion url config 2024-07-23 14:50:30 +02:00
github-actions[bot] 22bb0e5b61 publish new versions (#1551)
Co-authored-by: FabianLars <FabianLars@users.noreply.github.com>
2024-07-23 13:54:08 +02:00
renovate[bot] 37cb9a6681 fix(deps): update rust crate sqlx to 0.8 (v2) (#1575)
* fix(deps): update rust crate sqlx to 0.8

* fix build

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: FabianLars <fabianlars@fabianlars.de>
2024-07-23 13:40:59 +02:00
Fabian-Lars 725ff4295e fix(notification/windows): Grant permission without invoking backend (#1556)
* fix(notification/windows): Grant permission without invoking backend

* fmt
2024-07-23 13:10:58 +02:00
renovate[bot] 117c67da13 chore(deps): update dependency typescript to v5.5.4 (#1572)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-23 12:35:17 +08:00
Gabriel Silva (Gabe) 490d4208d7 docs(sql): add preload config example for migrations (#1557)
* docs(sql): add `preload` config example for migrations

* improve idempotency explanation
2024-07-22 15:52:34 +02:00
sadao komaki 1adf7e3872 docs(notification): Add capability instructions and usage example (#1569) 2024-07-22 13:17:22 +02:00
renovate[bot] 21bf0a4f84 chore(deps): update dependency rollup to v4.19.0 (#1565)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-22 11:43:10 +02:00
renovate[bot] 644807bf01 chore(deps): lock file maintenance (#1570)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-22 11:11:02 +02:00
FabianLars 93bdb6d133 Revert "fix(notification/windows): Grant permission without invoking backend"
This reverts commit 4c120d4176.
2024-07-16 13:22:21 +02:00
FabianLars 4c120d4176 fix(notification/windows): Grant permission without invoking backend 2024-07-16 13:21:10 +02:00
Jacob Bolda 8824a24e15 covector published pkg check with built-in API call (#1541) 2024-07-15 11:48:40 -05:00
Tony f83b9e9813 enhance(updater): use named tempfile on Windows (#1544)
* Use named tempfile on Windows

* append installer

* Add change file

* Fix ci

* Wrap in a folder

* Name temp dir for eaiser debugging

* format

* temp_dir

* target_os

* Document use updater_builder instead
2024-07-15 18:43:42 +08:00
renovate[bot] 77ee644afd chore(deps): lock file maintenance (#1549)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-15 11:38:04 +08:00
renovate[bot] 288e7b9ae2 chore(deps): lock file maintenance (#1548)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-15 09:27:30 +08:00
renovate[bot] 12b78a23c4 chore(deps): update dependency prettier to v3.3.3 (#1542)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 14:55:06 +02:00
renovate[bot] 97e2e75e29 chore(deps): update eslint monorepo to v9.7.0 (#1539)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 12:40:39 +02:00
35 changed files with 1181 additions and 1180 deletions
+25 -30
View File
@@ -3,24 +3,40 @@
"pkgManagers": {
"javascript": {
"version": true,
"getPublishedVersion": "node ../../.scripts/covector/package-latest-version.cjs npm ${ pkgFile.pkg.name } ${ pkgFile.pkg.version }",
"publish": ["pnpm build", "pnpm publish --access public --no-git-checks"]
"getPublishedVersion": {
"use": "fetch:check",
"options": {
"url": "https://registry.npmjs.com/${ pkg.pkgFile.pkg.name }/${ pkg.pkgFile.version }"
}
},
"publish": [
{
"command": "pnpm build",
"dryRunCommand": "pnpm build"
},
{
"command": "npm publish --provenance --access public",
"dryRunCommand": "npm publish --provenance --access public --dry-run",
"pipe": true
}
]
},
"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",
"dryRunCommand": true
},
{
"command": "echo '<details>\n<summary><em><h4>Cargo Publish</h4></em></summary>\n\n```'",
"dryRunCommand": true,
"pipe": true
},
{
"command": "cargo publish",
"command": "cargo publish --no-verify",
"dryRunCommand": "cargo publish --dry-run",
"pipe": true
},
@@ -246,28 +262,7 @@
},
"sql": {
"path": "./plugins/sql",
"manager": "rust",
"publish": [
{
"command": "cargo package --no-verify",
"dryRunCommand": true
},
{
"command": "echo '<details>\n<summary><em><h4>Cargo Publish</h4></em></summary>\n\n```'",
"dryRunCommand": true,
"pipe": true
},
{
"command": "cargo publish --features sqlite",
"dryRunCommand": "cargo publish --features sqlite --dry-run",
"pipe": true
},
{
"command": "echo '```\n\n</details>\n'",
"dryRunCommand": true,
"pipe": true
}
]
"manager": "rust"
},
"sql-js": {
"path": "./plugins/sql",
@@ -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.
+5
View File
@@ -0,0 +1,5 @@
---
"log-plugin": patch
---
Added `Builder::split` which returns the raw logger implementation so you can pipe to other loggers such as `multi_log` or `tauri-plugin-devtools`.
@@ -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`
+4
View File
@@ -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",
@@ -60,7 +61,9 @@
".changes/http-unsafe-headers.md",
".changes/http-user-agent.md",
".changes/impl-ext-for-webview-windows.md",
".changes/log-split.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 +84,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",
+5
View File
@@ -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
@@ -0,0 +1,30 @@
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
# SPDX-License-Identifier: Apache-2.0
# SPDX-License-Identifier: MIT
name: covector comment
on:
workflow_run:
workflows: [covector status] # the `name` of the workflow run on `pull_request` running `status` with `comment: true`
types:
- completed
# note all other permissions are set to none if not specified
# and these set the permissions for `secrets.GITHUB_TOKEN`
permissions:
# to read the action artifacts on `covector status` workflows
actions: read
# to write the comment
pull-requests: write
jobs:
download:
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success' &&
(github.event.workflow_run.head_repository.full_name != github.repository || github.actor == 'dependabot[bot]')
steps:
- name: covector status
uses: jbolda/covector/packages/action@covector-v0
with:
token: ${{ secrets.GITHUB_TOKEN }}
command: "status"
@@ -1,76 +0,0 @@
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
# SPDX-License-Identifier: Apache-2.0
# SPDX-License-Identifier: MIT
name: version or publish
on:
push:
branches:
- v2
jobs:
version-or-publish:
runs-on: ubuntu-latest
timeout-minutes: 65
outputs:
change: ${{ steps.covector.outputs.change }}
commandRan: ${{ steps.covector.outputs.commandRan }}
successfulPublish: ${{ steps.covector.outputs.successfulPublish }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # required for use of git history
- uses: actions/setup-node@v4
with:
node-version: "lts/*"
registry-url: "https://registry.npmjs.org"
- uses: pnpm/action-setup@v4
with:
version: 9.x.x
run_install: true
- name: install webkit2gtk and libudev for [authenticator]
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libudev-dev
- name: cargo login
run: cargo login ${{ secrets.ORG_CRATES_IO_TOKEN }}
- name: git config
run: |
git config --global user.name "${{ github.event.pusher.name }}"
git config --global user.email "${{ github.event.pusher.email }}"
- name: Setup target dir on /mnt
run: |
sudo mkdir /mnt/target
WORKSPACE_OWNER="$(stat -c '%U:%G' "${GITHUB_WORKSPACE}")"
sudo chown -R "${WORKSPACE_OWNER}" /mnt/target
- name: covector version or publish (publish when no change files present)
uses: jbolda/covector/packages/action@covector-v0
id: covector
env:
CARGO_TARGET_DIR: /mnt/target
NODE_AUTH_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
command: "version-or-publish"
createRelease: true
recognizeContributors: true
- name: Create Pull Request With Versions Bumped
id: cpr
uses: tauri-apps/create-pull-request@v3
if: steps.covector.outputs.commandRan == 'version'
with:
title: "Publish New Versions (v2)"
commit-message: "publish new versions"
labels: "version updates"
branch: "ci/release-v2"
body: ${{ steps.covector.outputs.change }}
@@ -8,6 +8,15 @@ on:
push:
branches:
- v1
- v2
permissions:
# required for npm provenance
id-token: write
# required to create the GitHub Release
contents: write
# required for creating the Version Packages Release
pull-requests: write
jobs:
version-or-publish:
@@ -33,11 +42,6 @@ jobs:
version: 9.x.x
run_install: true
- name: install webkit2gtk and libudev for [authenticator]
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libudev-dev
- name: cargo login
run: cargo login ${{ secrets.ORG_CRATES_IO_TOKEN }}
@@ -46,10 +50,18 @@ jobs:
git config --global user.name "${{ github.event.pusher.name }}"
git config --global user.email "${{ github.event.pusher.email }}"
- name: Setup target dir on /mnt
# This directory has a larger partition size
run: |
sudo mkdir /mnt/target
WORKSPACE_OWNER="$(stat -c '%U:%G' "${GITHUB_WORKSPACE}")"
sudo chown -R "${WORKSPACE_OWNER}" /mnt/target
- name: covector version or publish (publish when no change files present)
uses: jbolda/covector/packages/action@covector-v0
id: covector
env:
CARGO_TARGET_DIR: /mnt/target
NODE_AUTH_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -57,13 +69,17 @@ jobs:
createRelease: true
recognizeContributors: true
- name: Sync Cargo.lock
if: steps.covector.outputs.commandRan == 'version'
run: cargo tree --depth 0
- name: Create Pull Request With Versions Bumped
id: cpr
uses: tauri-apps/create-pull-request@v3
if: steps.covector.outputs.commandRan == 'version'
with:
title: "Publish New Versions"
title: "Publish New Versions (${{ github.ref_name }})"
commit-message: "publish new versions"
labels: "version updates"
branch: "ci/release-v1"
branch: "ci/release-${{ github.ref_name }}"
body: ${{ steps.covector.outputs.change }}
@@ -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
+209 -215
View File
File diff suppressed because it is too large Load Diff
+13
View File
@@ -1,5 +1,18 @@
# Changelog
## \[2.0.0-beta.15]
### Dependencies
- Upgraded to `log-plugin@2.0.0-beta.9`
## \[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
+4 -4
View File
@@ -1,7 +1,7 @@
[package]
name = "api"
publish = false
version = "2.0.0-beta.13"
version = "2.0.0-beta.15"
description = "An example Tauri Application showcasing the api"
edition = "2021"
rust-version = { workspace = true }
@@ -19,12 +19,12 @@ serde_json = { workspace = true }
serde = { workspace = true }
tiny_http = "0.12"
log = { workspace = true }
tauri-plugin-log = { path = "../../../plugins/log", version = "2.0.0-beta.8" }
tauri-plugin-log = { path = "../../../plugins/log", version = "2.0.0-beta.9" }
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.0.0-beta.11", features = [ "watch" ] }
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
View File
@@ -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": {
+7 -2
View File
@@ -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
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.0.0-beta.9]
- [`20a1d24e`](https://github.com/tauri-apps/plugins-workspace/commit/20a1d24ee004e77c2d12a0e20d258ce120216ed1) ([#1579](https://github.com/tauri-apps/plugins-workspace/pull/1579) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Added `Builder::split` which returns the raw logger implementation so you can pipe to other loggers such as `multi_log` or `tauri-plugin-devtools`.
## \[2.0.0-beta.8]
- [`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.
+2 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-log"
version = "2.0.0-beta.8"
version = "2.0.0-beta.9"
description = "Configurable logging for your Tauri app."
authors = { workspace = true }
license = { workspace = true }
@@ -25,6 +25,7 @@ byte-unit = "5"
log = { workspace = true, features = [ "kv_unstable" ] }
time = { version = "0.3", features = [ "formatting", "local-offset" ] }
fern = "0.6"
thiserror = "1"
[target."cfg(target_os = \"android\")".dependencies]
android_logger = "0.14"
+147 -88
View File
@@ -24,11 +24,11 @@ use std::{
iter::FromIterator,
path::{Path, PathBuf},
};
use tauri::Emitter;
use tauri::{
plugin::{self, TauriPlugin},
Manager, Runtime,
};
use tauri::{AppHandle, Emitter};
pub use fern;
use time::OffsetDateTime;
@@ -75,6 +75,18 @@ const DEFAULT_LOG_TARGETS: [Target; 2] = [
Target::new(TargetKind::LogDir { file_name: None }),
];
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Tauri(#[from] tauri::Error),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
TimeFormat(#[from] time::error::Format),
#[error(transparent)]
InvalidFormatDescription(#[from] time::error::InvalidFormatDescription),
}
/// An enum representing the available verbosity levels of the logger.
///
/// It is very similar to the [`log::Level`], but serializes to unsigned ints instead of strings.
@@ -395,97 +407,134 @@ impl Builder {
})
}
pub fn build<R: Runtime>(mut self) -> TauriPlugin<R> {
plugin::Builder::new("log")
.invoke_handler(tauri::generate_handler![log])
.setup(move |app_handle, _api| {
let app_name = &app_handle.package_info().name;
fn acquire_logger<R: Runtime>(
app_handle: &AppHandle<R>,
mut dispatch: fern::Dispatch,
rotation_strategy: RotationStrategy,
timezone_strategy: TimezoneStrategy,
max_file_size: u128,
targets: Vec<Target>,
) -> Result<(log::LevelFilter, Box<dyn log::Log>), Error> {
let app_name = &app_handle.package_info().name;
// setup targets
for target in self.targets {
let mut target_dispatch = fern::Dispatch::new();
for filter in target.filters {
target_dispatch = target_dispatch.filter(filter);
// setup targets
for target in targets {
let mut target_dispatch = fern::Dispatch::new();
for filter in target.filters {
target_dispatch = target_dispatch.filter(filter);
}
let logger = match target.kind {
#[cfg(target_os = "android")]
TargetKind::Stdout | TargetKind::Stderr => fern::Output::call(android_logger::log),
#[cfg(target_os = "ios")]
TargetKind::Stdout | TargetKind::Stderr => fern::Output::call(move |record| {
let message = format!("{}", record.args());
unsafe {
ios::tauri_log(
match record.level() {
log::Level::Trace | log::Level::Debug => 1,
log::Level::Info => 2,
log::Level::Warn | log::Level::Error => 3,
},
ios::NSString::new(message.as_str()).0 as _,
);
}
}),
#[cfg(desktop)]
TargetKind::Stdout => std::io::stdout().into(),
#[cfg(desktop)]
TargetKind::Stderr => std::io::stderr().into(),
TargetKind::Folder { path, file_name } => {
if !path.exists() {
fs::create_dir_all(&path)?;
}
let logger = match target.kind {
#[cfg(target_os = "android")]
TargetKind::Stdout | TargetKind::Stderr => {
fern::Output::call(android_logger::log)
}
#[cfg(target_os = "ios")]
TargetKind::Stdout | TargetKind::Stderr => {
fern::Output::call(move |record| {
let message = format!("{}", record.args());
unsafe {
ios::tauri_log(
match record.level() {
log::Level::Trace | log::Level::Debug => 1,
log::Level::Info => 2,
log::Level::Warn | log::Level::Error => 3,
},
ios::NSString::new(message.as_str()).0 as _,
);
}
})
}
#[cfg(desktop)]
TargetKind::Stdout => std::io::stdout().into(),
#[cfg(desktop)]
TargetKind::Stderr => std::io::stderr().into(),
TargetKind::Folder { path, file_name } => {
if !path.exists() {
fs::create_dir_all(&path)?;
}
fern::log_file(get_log_file_path(
&path,
file_name.as_deref().unwrap_or(app_name),
&self.rotation_strategy,
&self.timezone_strategy,
self.max_file_size,
)?)?
.into()
}
#[cfg(mobile)]
TargetKind::LogDir { .. } => continue,
#[cfg(desktop)]
TargetKind::LogDir { file_name } => {
let path = app_handle.path().app_log_dir()?;
if !path.exists() {
fs::create_dir_all(&path)?;
}
fern::log_file(get_log_file_path(
&path,
file_name.as_deref().unwrap_or(app_name),
&self.rotation_strategy,
&self.timezone_strategy,
self.max_file_size,
)?)?
.into()
}
TargetKind::Webview => {
let app_handle = app_handle.clone();
fern::Output::call(move |record| {
let payload = RecordPayload {
message: record.args().to_string(),
level: record.level().into(),
};
let app_handle = app_handle.clone();
tauri::async_runtime::spawn(async move {
let _ = app_handle.emit("log://log", payload);
});
})
}
};
target_dispatch = target_dispatch.chain(logger);
self.dispatch = self.dispatch.chain(target_dispatch);
fern::log_file(get_log_file_path(
&path,
file_name.as_deref().unwrap_or(app_name),
&rotation_strategy,
&timezone_strategy,
max_file_size,
)?)?
.into()
}
#[cfg(mobile)]
TargetKind::LogDir { .. } => continue,
#[cfg(desktop)]
TargetKind::LogDir { file_name } => {
let path = app_handle.path().app_log_dir()?;
if !path.exists() {
fs::create_dir_all(&path)?;
}
self.dispatch.apply()?;
fern::log_file(get_log_file_path(
&path,
file_name.as_deref().unwrap_or(app_name),
&rotation_strategy,
&timezone_strategy,
max_file_size,
)?)?
.into()
}
TargetKind::Webview => {
let app_handle = app_handle.clone();
fern::Output::call(move |record| {
let payload = RecordPayload {
message: record.args().to_string(),
level: record.level().into(),
};
let app_handle = app_handle.clone();
tauri::async_runtime::spawn(async move {
let _ = app_handle.emit("log://log", payload);
});
})
}
};
target_dispatch = target_dispatch.chain(logger);
dispatch = dispatch.chain(target_dispatch);
}
Ok(dispatch.into_log())
}
fn plugin_builder<R: Runtime>() -> plugin::Builder<R> {
plugin::Builder::new("log").invoke_handler(tauri::generate_handler![log])
}
#[allow(clippy::type_complexity)]
pub fn split<R: Runtime>(
self,
app_handle: &AppHandle<R>,
) -> Result<(TauriPlugin<R>, log::LevelFilter, Box<dyn log::Log>), Error> {
let plugin = Self::plugin_builder();
let (max_level, log) = Self::acquire_logger(
app_handle,
self.dispatch,
self.rotation_strategy,
self.timezone_strategy,
self.max_file_size,
self.targets,
)?;
Ok((plugin.build(), max_level, log))
}
pub fn build<R: Runtime>(self) -> TauriPlugin<R> {
Self::plugin_builder()
.setup(move |app_handle, _api| {
let (max_level, log) = Self::acquire_logger(
app_handle,
self.dispatch,
self.rotation_strategy,
self.timezone_strategy,
self.max_file_size,
self.targets,
)?;
attach_logger(max_level, log)?;
Ok(())
})
@@ -493,13 +542,23 @@ impl Builder {
}
}
/// Attaches the given logger
pub fn attach_logger(
max_level: log::LevelFilter,
log: Box<dyn log::Log>,
) -> Result<(), log::SetLoggerError> {
log::set_boxed_logger(log)?;
log::set_max_level(max_level);
Ok(())
}
fn get_log_file_path(
dir: &impl AsRef<Path>,
file_name: &str,
rotation_strategy: &RotationStrategy,
timezone_strategy: &TimezoneStrategy,
max_file_size: u128,
) -> Result<PathBuf, Box<dyn std::error::Error>> {
) -> Result<PathBuf, Error> {
let path = dir.as_ref().join(format!("{file_name}.log"));
if path.exists() {
+4 -1
View File
@@ -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 -1
View File
@@ -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 }
+30
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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")}))}()}();
+4 -1
View File
@@ -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)?;
+4
View File
@@ -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.
+2 -2
View File
@@ -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
View File
@@ -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
+1
View File
@@ -135,6 +135,7 @@ impl MigrationSource<'static> for MigrationList {
migration.description.into(),
migration.kind.into(),
migration.sql.into(),
false,
));
}
}
+6 -1
View File
@@ -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 -1
View File
@@ -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 }
+6 -2
View File
@@ -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);
+40 -14
View File
@@ -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()
+546 -655
View File
File diff suppressed because it is too large Load Diff