mirror of
https://github.com/tauri-apps/tauri-plugin-updater.git
synced 2026-01-31 00:55:19 +01:00
fix(updater): format Update.date to RFC 3339 (#2573)
* fix(updater): format `Update.date` to RFC 3339 * Messed up on argument in #2572 * Format * Update example * Avoid extra to_string * Deprecate `Update.available` Committed via a GitHub action: https://github.com/tauri-apps/plugins-workspace/actions/runs/14140323725 Co-authored-by: Legend-Master <Legend-Master@users.noreply.github.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_UPDATER__=function(e){"use strict";function t(e,t,s,n){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?n:"a"===s?n.call(e):n?n.value:t.get(e)}function s(e,t,s,n,i){if("function"==typeof t||!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return t.set(e,s),s}var n,i,a,r;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class d{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,n.set(this,(()=>{})),i.set(this,0),a.set(this,[]),this.id=function(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}((({message:e,id:r})=>{if(r==t(this,i,"f"))for(t(this,n,"f").call(this,e),s(this,i,t(this,i,"f")+1);t(this,i,"f")in t(this,a,"f");){const e=t(this,a,"f")[t(this,i,"f")];t(this,n,"f").call(this,e),delete t(this,a,"f")[t(this,i,"f")],s(this,i,t(this,i,"f")+1)}else t(this,a,"f")[r]=e}))}set onmessage(e){s(this,n,e)}get onmessage(){return t(this,n,"f")}[(n=new WeakMap,i=new WeakMap,a=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function l(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}class h{get rid(){return t(this,r,"f")}constructor(e){r.set(this,void 0),s(this,r,e)}async close(){return l("plugin:resources|close",{rid:this.rid})}}r=new WeakMap;class c extends h{constructor(e){super(e.rid),this.available=e.available,this.currentVersion=e.currentVersion,this.version=e.version,this.date=e.date,this.body=e.body,this.rawJson=e.rawJson}async download(e,t){const s=new d;e&&(s.onmessage=e);const n=await l("plugin:updater|download",{onEvent:s,rid:this.rid,...t});this.downloadedBytes=new h(n)}async install(){if(!this.downloadedBytes)throw new Error("Update.install called before Update.download");await l("plugin:updater|install",{updateRid:this.rid,bytesRid:this.downloadedBytes.rid}),this.downloadedBytes=void 0}async downloadAndInstall(e,t){const s=new d;e&&(s.onmessage=e),await l("plugin:updater|download_and_install",{onEvent:s,rid:this.rid,...t})}async close(){await(this.downloadedBytes?.close()),await super.close()}}return e.Update=c,e.check=async function(e){return e?.headers&&(e.headers=Array.from(new Headers(e.headers).entries())),await l("plugin:updater|check",{...e}).then((e=>e.available?new c(e):null))},e}({});Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_PLUGIN_UPDATER__})}
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_UPDATER__=function(t){"use strict";function e(t,e,s,n){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===s?n:"a"===s?n.call(t):n?n.value:e.get(t)}function s(t,e,s,n,i){if("function"==typeof e||!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return e.set(t,s),s}var n,i,r,a;"function"==typeof SuppressedError&&SuppressedError;const o="__TAURI_TO_IPC_KEY__";class d{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,n.set(this,(()=>{})),i.set(this,0),r.set(this,[]),this.id=function(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}((({message:t,id:a})=>{if(a==e(this,i,"f"))for(e(this,n,"f").call(this,t),s(this,i,e(this,i,"f")+1);e(this,i,"f")in e(this,r,"f");){const t=e(this,r,"f")[e(this,i,"f")];e(this,n,"f").call(this,t),delete e(this,r,"f")[e(this,i,"f")],s(this,i,e(this,i,"f")+1)}else e(this,r,"f")[a]=t}))}set onmessage(t){s(this,n,t)}get onmessage(){return e(this,n,"f")}[(n=new WeakMap,i=new WeakMap,r=new WeakMap,o)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[o]()}}async function c(t,e={},s){return window.__TAURI_INTERNALS__.invoke(t,e,s)}class h{get rid(){return e(this,a,"f")}constructor(t){a.set(this,void 0),s(this,a,t)}async close(){return c("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;class l extends h{constructor(t){super(t.rid),this.available=!0,this.currentVersion=t.currentVersion,this.version=t.version,this.date=t.date,this.body=t.body,this.rawJson=t.rawJson}async download(t,e){const s=new d;t&&(s.onmessage=t);const n=await c("plugin:updater|download",{onEvent:s,rid:this.rid,...e});this.downloadedBytes=new h(n)}async install(){if(!this.downloadedBytes)throw new Error("Update.install called before Update.download");await c("plugin:updater|install",{updateRid:this.rid,bytesRid:this.downloadedBytes.rid}),this.downloadedBytes=void 0}async downloadAndInstall(t,e){const s=new d;t&&(s.onmessage=t),await c("plugin:updater|download_and_install",{onEvent:s,rid:this.rid,...e})}async close(){await(this.downloadedBytes?.close()),await super.close()}}return t.Update=l,t.check=async function(t){t?.headers&&(t.headers=Array.from(new Headers(t.headers).entries()));const e=await c("plugin:updater|check",{...t});return e?new l(e):null},t}({});Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_PLUGIN_UPDATER__})}
|
||||
|
||||
@@ -8,7 +8,7 @@ var core = require('@tauri-apps/api/core');
|
||||
class Update extends core.Resource {
|
||||
constructor(metadata) {
|
||||
super(metadata.rid);
|
||||
this.available = metadata.available;
|
||||
this.available = true;
|
||||
this.currentVersion = metadata.currentVersion;
|
||||
this.version = metadata.version;
|
||||
this.date = metadata.date;
|
||||
@@ -62,11 +62,10 @@ async function check(options) {
|
||||
if (options?.headers) {
|
||||
options.headers = Array.from(new Headers(options.headers).entries());
|
||||
}
|
||||
return await core.invoke('plugin:updater|check', {
|
||||
const metadata = await core.invoke('plugin:updater|check', {
|
||||
...options
|
||||
}).then((meta) =>
|
||||
// TODO: Handle this in the rust side
|
||||
meta.available ? new Update(meta) : null);
|
||||
});
|
||||
return metadata ? new Update(metadata) : null;
|
||||
}
|
||||
|
||||
exports.Update = Update;
|
||||
|
||||
2
dist-js/index.d.ts
vendored
2
dist-js/index.d.ts
vendored
@@ -31,7 +31,6 @@ interface DownloadOptions {
|
||||
}
|
||||
interface UpdateMetadata {
|
||||
rid: number;
|
||||
available: boolean;
|
||||
currentVersion: string;
|
||||
version: string;
|
||||
date?: string;
|
||||
@@ -53,6 +52,7 @@ type DownloadEvent = {
|
||||
event: 'Finished';
|
||||
};
|
||||
declare class Update extends Resource {
|
||||
/** @deprecated This is always true, check if the return value is `null` instead when using {@linkcode check} */
|
||||
available: boolean;
|
||||
currentVersion: string;
|
||||
version: string;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Resource, Channel, invoke } from '@tauri-apps/api/core';
|
||||
class Update extends Resource {
|
||||
constructor(metadata) {
|
||||
super(metadata.rid);
|
||||
this.available = metadata.available;
|
||||
this.available = true;
|
||||
this.currentVersion = metadata.currentVersion;
|
||||
this.version = metadata.version;
|
||||
this.date = metadata.date;
|
||||
@@ -60,11 +60,10 @@ async function check(options) {
|
||||
if (options?.headers) {
|
||||
options.headers = Array.from(new Headers(options.headers).entries());
|
||||
}
|
||||
return await invoke('plugin:updater|check', {
|
||||
const metadata = await invoke('plugin:updater|check', {
|
||||
...options
|
||||
}).then((meta) =>
|
||||
// TODO: Handle this in the rust side
|
||||
meta.available ? new Update(meta) : null);
|
||||
});
|
||||
return metadata ? new Update(metadata) : null;
|
||||
}
|
||||
|
||||
export { Update, check };
|
||||
|
||||
@@ -38,7 +38,6 @@ interface DownloadOptions {
|
||||
|
||||
interface UpdateMetadata {
|
||||
rid: number
|
||||
available: boolean
|
||||
currentVersion: string
|
||||
version: string
|
||||
date?: string
|
||||
@@ -53,6 +52,8 @@ type DownloadEvent =
|
||||
| { event: 'Finished' }
|
||||
|
||||
class Update extends Resource {
|
||||
// TODO: remove this field in v3
|
||||
/** @deprecated This is always true, check if the return value is `null` instead when using {@linkcode check} */
|
||||
available: boolean
|
||||
currentVersion: string
|
||||
version: string
|
||||
@@ -63,7 +64,7 @@ class Update extends Resource {
|
||||
|
||||
constructor(metadata: UpdateMetadata) {
|
||||
super(metadata.rid)
|
||||
this.available = metadata.available
|
||||
this.available = true
|
||||
this.currentVersion = metadata.currentVersion
|
||||
this.version = metadata.version
|
||||
this.date = metadata.date
|
||||
@@ -131,12 +132,10 @@ async function check(options?: CheckOptions): Promise<Update | null> {
|
||||
options.headers = Array.from(new Headers(options.headers).entries())
|
||||
}
|
||||
|
||||
return await invoke<UpdateMetadata>('plugin:updater|check', {
|
||||
const metadata = await invoke<UpdateMetadata | null>('plugin:updater|check', {
|
||||
...options
|
||||
}).then((meta) =>
|
||||
// TODO: Handle this in the rust side
|
||||
meta.available ? new Update(meta) : null
|
||||
)
|
||||
})
|
||||
return metadata ? new Update(metadata) : null
|
||||
}
|
||||
|
||||
export type { CheckOptions, DownloadOptions, DownloadEvent }
|
||||
|
||||
@@ -28,8 +28,7 @@ pub enum DownloadEvent {
|
||||
#[derive(Serialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct Metadata {
|
||||
rid: Option<ResourceId>,
|
||||
available: bool,
|
||||
rid: ResourceId,
|
||||
current_version: String,
|
||||
version: String,
|
||||
date: Option<String>,
|
||||
@@ -40,8 +39,6 @@ pub(crate) struct Metadata {
|
||||
struct DownloadedBytes(pub Vec<u8>);
|
||||
impl Resource for DownloadedBytes {}
|
||||
|
||||
// TODO: Align this with the result of `updater.check` to Result<Option<Metadata>>
|
||||
// and remove `available` instead of handling this in the js side
|
||||
#[tauri::command]
|
||||
pub(crate) async fn check<R: Runtime>(
|
||||
webview: Webview<R>,
|
||||
@@ -49,7 +46,7 @@ pub(crate) async fn check<R: Runtime>(
|
||||
timeout: Option<u64>,
|
||||
proxy: Option<String>,
|
||||
target: Option<String>,
|
||||
) -> Result<Metadata> {
|
||||
) -> Result<Option<Metadata>> {
|
||||
let mut builder = webview.updater_builder();
|
||||
if let Some(headers) = headers {
|
||||
for (k, v) in headers {
|
||||
@@ -69,18 +66,28 @@ pub(crate) async fn check<R: Runtime>(
|
||||
|
||||
let updater = builder.build()?;
|
||||
let update = updater.check().await?;
|
||||
let mut metadata = Metadata::default();
|
||||
if let Some(update) = update {
|
||||
metadata.available = true;
|
||||
metadata.current_version.clone_from(&update.current_version);
|
||||
metadata.version.clone_from(&update.version);
|
||||
metadata.date = update.date.map(|d| d.to_string());
|
||||
metadata.body.clone_from(&update.body);
|
||||
metadata.raw_json.clone_from(&update.raw_json);
|
||||
metadata.rid = Some(webview.resources_table().add(update));
|
||||
}
|
||||
|
||||
Ok(metadata)
|
||||
if let Some(update) = update {
|
||||
let formatted_date = if let Some(date) = update.date {
|
||||
let formatted_date = date
|
||||
.format(&time::format_description::well_known::Rfc3339)
|
||||
.map_err(|_| crate::Error::FormatDate)?;
|
||||
Some(formatted_date)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let metadata = Metadata {
|
||||
current_version: update.current_version.clone(),
|
||||
version: update.version.clone(),
|
||||
date: formatted_date,
|
||||
body: update.body.clone(),
|
||||
raw_json: update.raw_json.clone(),
|
||||
rid: webview.resources_table().add(update),
|
||||
};
|
||||
Ok(Some(metadata))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@@ -77,6 +77,8 @@ pub enum Error {
|
||||
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
|
||||
#[error(transparent)]
|
||||
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
|
||||
#[error("Failed to format date")]
|
||||
FormatDate,
|
||||
/// The configured updater endpoint must use a secure protocol like `https`
|
||||
#[error("The configured updater endpoint must use a secure protocol like `https`.")]
|
||||
InsecureTransportProtocol,
|
||||
|
||||
@@ -310,7 +310,8 @@ impl UpdaterBuilder {
|
||||
I: IntoIterator<Item = S>,
|
||||
S: Into<OsString>,
|
||||
{
|
||||
self.installer_args.extend(args.into_iter().map(Into::into));
|
||||
self.current_exe_args
|
||||
.extend(args.into_iter().map(Into::into));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user