feat(plugins): inject API on window.__TAURI__ (#383)

pull/393/head
Lucas Fernandes Nogueira 2 years ago committed by GitHub
parent 3c8577bc9a
commit b131bc8f7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,3 +2,4 @@ target
node_modules node_modules
dist dist
dist-js dist-js
api-iife.js

@ -0,0 +1,155 @@
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
# SPDX-License-Identifier: Apache-2.0
# SPDX-License-Identifier: MIT
name: check generated files
on:
pull_request:
paths:
- ".github/workflows/check-generated-files.yml"
- "**/guest-js/**"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changes:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.filter.outputs.changes }}
steps:
- uses: actions/checkout@v3
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
app:
- .github/workflows/check-generated-files.yml
- plugins/app/guest-js/**
- plugins/app/src/api-iife.js
authenticator:
- .github/workflows/check-generated-files.yml
- plugins/authenticator/guest-js/**
- plugins/authenticator/src/api-iife.js
autostart:
- .github/workflows/check-generated-files.yml
- plugins/autostart/guest-js/**
- plugins/autostart/src/api-iife.js
cli:
- .github/workflows/check-generated-files.yml
- plugins/cli/guest-js/**
- plugins/cli/src/api-iife.js
clipboard:
- .github/workflows/check-generated-files.yml
- plugins/clipboard/guest-js/**
- plugins/clipboard/src/api-iife.js
dialog:
- .github/workflows/check-generated-files.yml
- plugins/dialog/guest-js/**
- plugins/dialog/src/api-iife.js
fs:
- .github/workflows/check-generated-files.yml
- plugins/fs/guest-js/**
- plugins/fs/src/api-iife.js
global-shortcut:
- .github/workflows/check-generated-files.yml
- plugins/global-shortcut/guest-js/**
- plugins/global-shortcut/src/api-iife.js
http:
- .github/workflows/check-generated-files.yml
- plugins/http/guest-js/**
- plugins/http/src/api-iife.js
log:
- .github/workflows/check-generated-files.yml
- plugins/log/guest-js/**
- plugins/log/src/api-iife.js
notification:
- .github/workflows/check-generated-files.yml
- plugins/notification/guest-js/**
- plugins/notification/src/api-iife.js
os:
- .github/workflows/check-generated-files.yml
- plugins/os/guest-js/**
- plugins/os/src/api-iife.js
positioner:
- .github/workflows/check-generated-files.yml
- plugins/positioner/guest-js/**
- plugins/positioner/src/api-iife.js
process:
- .github/workflows/check-generated-files.yml
- plugins/process/guest-js/**
- plugins/process/src/api-iife.js
shell:
- .github/workflows/check-generated-files.yml
- plugins/shell/guest-js/**
- plugins/shell/src/api-iife.js
sql:
- .github/workflows/check-generated-files.yml
- plugins/sql/guest-js/**
- plugins/sql/src/api-iife.js
store:
- .github/workflows/check-generated-files.yml
- plugins/store/guest-js/**
- plugins/store/src/api-iife.js
stronghold:
- .github/workflows/check-generated-files.yml
- plugins/stronghold/guest-js/**
- plugins/stronghold/src/api-iife.js
updater:
- .github/workflows/check-generated-files.yml
- plugins/updater/guest-js/**
- plugins/updater/src/api-iife.js
upload:
- .github/workflows/check-generated-files.yml
- plugins/upload/guest-js/**
- plugins/upload/src/api-iife.js
websocket:
- .github/workflows/check-generated-files.yml
- plugins/websocket/guest-js/**
- plugins/websocket/src/api-iife.js
window:
- .github/workflows/check-generated-files.yml
- plugins/window/guest-js/**
- plugins/window/src/api-iife.js
window-state:
- .github/workflows/check-generated-files.yml
- plugins/window-state/guest-js/**
- plugins/window-state/src/api-iife.js
test:
needs: changes
if: ${{ needs.changes.outputs.packages != '[]' && needs.changes.outputs.packages != '' }}
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.changes.outputs.packages) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache pnpm modules
uses: actions/cache@v3
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-
- uses: actions/setup-node@v3
with:
node-version: 18
- uses: pnpm/action-setup@v2
with:
version: 7.x.x
run_install: true
- name: build api
working-directory: plugins/${{ matrix.package }}
run: pnpm install && pnpm build
- name: check diff
run: |
./.scripts/ci/has-diff.sh

@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
name: Check generated files name: check license header
on: on:
pull_request: pull_request:

@ -12,6 +12,7 @@ on:
paths: paths:
- ".github/workflows/lint-rust.yml" - ".github/workflows/lint-rust.yml"
- "plugins/*/src/**" - "plugins/*/src/**"
- "!plugins/*/src/api-iife.js"
- "**/Cargo.toml" - "**/Cargo.toml"
pull_request: pull_request:
branches: branches:
@ -20,6 +21,7 @@ on:
paths: paths:
- ".github/workflows/lint-rust.yml" - ".github/workflows/lint-rust.yml"
- "plugins/*/src/**" - "plugins/*/src/**"
- "!plugins/*/src/api-iife.js"
- "**/Cargo.toml" - "**/Cargo.toml"
concurrency: concurrency:

@ -12,6 +12,7 @@ on:
paths: paths:
- ".github/workflows/test-rust.yml" - ".github/workflows/test-rust.yml"
- "plugins/*/src/**" - "plugins/*/src/**"
- "!plugins/*/src/api-iife.js"
- "**/Cargo.toml" - "**/Cargo.toml"
- "**/Cargo.lock" - "**/Cargo.lock"
pull_request: pull_request:
@ -21,6 +22,7 @@ on:
paths: paths:
- ".github/workflows/test-rust.yml" - ".github/workflows/test-rust.yml"
- "plugins/*/src/**" - "plugins/*/src/**"
- "!plugins/*/src/api-iife.js"
- "**/Cargo.toml" - "**/Cargo.toml"
- "**/Cargo.lock" - "**/Cargo.lock"

@ -1,6 +1,8 @@
target target
node_modules node_modules
dist dist
dist-js
pnpm-lock.yaml pnpm-lock.yaml
Cargo.lock Cargo.lock
.build .build
api-iife.js

@ -24,7 +24,10 @@ const ignore = [
]; ];
async function checkFile(file) { async function checkFile(file) {
if (extensions.some((e) => file.endsWith(e))) { if (
extensions.some((e) => file.endsWith(e)) &&
!ignore.some((i) => file.endsWith(i))
) {
const fileStream = fs.createReadStream(file); const fileStream = fs.createReadStream(file);
const rl = readline.createInterface({ const rl = readline.createInterface({
input: fileStream, input: fileStream,

@ -0,0 +1,9 @@
#!/bin/bash
if git diff --quiet --ignore-submodules HEAD
then
echo "working directory is clean"
else
echo "found diff"
exit 1
fi

@ -8,7 +8,11 @@
* @module * @module
*/ */
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
/** /**
* Gets the application version. * Gets the application version.
@ -21,7 +25,7 @@ import { invoke } from "@tauri-apps/api/tauri";
* @since 1.0.0 * @since 1.0.0
*/ */
async function getVersion(): Promise<string> { async function getVersion(): Promise<string> {
return invoke("plugin:app|version"); return window.__TAURI_INVOKE__("plugin:app|version");
} }
/** /**
@ -35,7 +39,7 @@ async function getVersion(): Promise<string> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function getName(): Promise<string> { async function getName(): Promise<string> {
return invoke("plugin:app|name"); return window.__TAURI_INVOKE__("plugin:app|name");
} }
/** /**
@ -50,7 +54,7 @@ async function getName(): Promise<string> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function getTauriVersion(): Promise<string> { async function getTauriVersion(): Promise<string> {
return invoke("plugin:app|tauri_version"); return window.__TAURI_INVOKE__("plugin:app|tauri_version");
} }
/** /**
@ -65,7 +69,7 @@ async function getTauriVersion(): Promise<string> {
* @since 1.2.0 * @since 1.2.0
*/ */
async function show(): Promise<void> { async function show(): Promise<void> {
return invoke("plugin:app|show"); return window.__TAURI_INVOKE__("plugin:app|show");
} }
/** /**
@ -80,7 +84,7 @@ async function show(): Promise<void> {
* @since 1.2.0 * @since 1.2.0
*/ */
async function hide(): Promise<void> { async function hide(): Promise<void> {
return invoke("plugin:app|hide"); return window.__TAURI_INVOKE__("plugin:app|hide");
} }
export { getName, getVersion, getTauriVersion, show, hide }; export { getName, getVersion, getTauriVersion, show, hide };

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_APP__=function(_){"use strict";return _.getName=async function(){return window.__TAURI_INVOKE__("plugin:app|name")},_.getTauriVersion=async function(){return window.__TAURI_INVOKE__("plugin:app|tauri_version")},_.getVersion=async function(){return window.__TAURI_INVOKE__("plugin:app|version")},_.hide=async function(){return window.__TAURI_INVOKE__("plugin:app|hide")},_.show=async function(){return window.__TAURI_INVOKE__("plugin:app|show")},_}({});Object.defineProperty(window.__TAURI__,"app",{value:__TAURI_APP__})}

@ -11,6 +11,7 @@ mod commands;
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("app") Builder::new("app")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
commands::version, commands::version,
commands::name, commands::name,

@ -2,15 +2,19 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
export class Authenticator { export class Authenticator {
async init(): Promise<void> { async init(): Promise<void> {
return await invoke("plugin:authenticator|init_auth"); return await window.__TAURI_INVOKE__("plugin:authenticator|init_auth");
} }
async register(challenge: string, application: string): Promise<string> { async register(challenge: string, application: string): Promise<string> {
return await invoke("plugin:authenticator|register", { return await window.__TAURI_INVOKE__("plugin:authenticator|register", {
timeout: 10000, timeout: 10000,
challenge, challenge,
application, application,
@ -23,12 +27,15 @@ export class Authenticator {
registerData: string, registerData: string,
clientData: string clientData: string
): Promise<string> { ): Promise<string> {
return await invoke("plugin:authenticator|verify_registration", { return await window.__TAURI_INVOKE__(
challenge, "plugin:authenticator|verify_registration",
application, {
registerData, challenge,
clientData, application,
}); registerData,
clientData,
}
);
} }
async sign( async sign(
@ -36,7 +43,7 @@ export class Authenticator {
application: string, application: string,
keyHandle: string keyHandle: string
): Promise<string> { ): Promise<string> {
return await invoke("plugin:authenticator|sign", { return await window.__TAURI_INVOKE__("plugin:authenticator|sign", {
timeout: 10000, timeout: 10000,
challenge, challenge,
application, application,
@ -52,13 +59,16 @@ export class Authenticator {
keyHandle: string, keyHandle: string,
pubkey: string pubkey: string
): Promise<number> { ): Promise<number> {
return await invoke("plugin:authenticator|verify_signature", { return await window.__TAURI_INVOKE__(
challenge, "plugin:authenticator|verify_signature",
application, {
signData, challenge,
clientData, application,
keyHandle, signData,
pubkey, clientData,
}); keyHandle,
pubkey,
}
);
} }
} }

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_AUTHENTICATOR__=function(t){"use strict";return t.Authenticator=class{async init(){return await window.__TAURI_INVOKE__("plugin:authenticator|init_auth")}async register(t,i){return await window.__TAURI_INVOKE__("plugin:authenticator|register",{timeout:1e4,challenge:t,application:i})}async verifyRegistration(t,i,a,n){return await window.__TAURI_INVOKE__("plugin:authenticator|verify_registration",{challenge:t,application:i,registerData:a,clientData:n})}async sign(t,i,a){return await window.__TAURI_INVOKE__("plugin:authenticator|sign",{timeout:1e4,challenge:t,application:i,keyHandle:a})}async verifySignature(t,i,a,n,e,_){return await window.__TAURI_INVOKE__("plugin:authenticator|verify_signature",{challenge:t,application:i,signData:a,clientData:n,keyHandle:e,pubkey:_})}},t}({});Object.defineProperty(window.__TAURI__,"authenticator",{value:__TAURI_AUTHENTICATOR__})}

@ -67,6 +67,7 @@ fn verify_signature(
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
PluginBuilder::new("authenticator") PluginBuilder::new("authenticator")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
init_auth, init_auth,
register, register,

@ -2,16 +2,20 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
export async function isEnabled(): Promise<boolean> { export async function isEnabled(): Promise<boolean> {
return await invoke("plugin:autostart|is_enabled"); return await window.__TAURI_INVOKE__("plugin:autostart|is_enabled");
} }
export async function enable(): Promise<void> { export async function enable(): Promise<void> {
await invoke("plugin:autostart|enable"); await window.__TAURI_INVOKE__("plugin:autostart|enable");
} }
export async function disable(): Promise<void> { export async function disable(): Promise<void> {
await invoke("plugin:autostart|disable"); await window.__TAURI_INVOKE__("plugin:autostart|disable");
} }

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_AUTOSTART__=function(_){"use strict";return _.disable=async function(){await window.__TAURI_INVOKE__("plugin:autostart|disable")},_.enable=async function(){await window.__TAURI_INVOKE__("plugin:autostart|enable")},_.isEnabled=async function(){return await window.__TAURI_INVOKE__("plugin:autostart|is_enabled")},_}({});Object.defineProperty(window.__TAURI__,"autostart",{value:__TAURI_AUTOSTART__})}

@ -99,6 +99,7 @@ pub fn init<R: Runtime>(
args: Option<Vec<&'static str>>, args: Option<Vec<&'static str>>,
) -> TauriPlugin<R> { ) -> TauriPlugin<R> {
Builder::new("autostart") Builder::new("autostart")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![enable, disable, is_enabled]) .invoke_handler(tauri::generate_handler![enable, disable, is_enabled])
.setup(move |app, _api| { .setup(move |app, _api| {
let mut builder = AutoLaunchBuilder::new(); let mut builder = AutoLaunchBuilder::new();

@ -8,7 +8,11 @@
* @module * @module
*/ */
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
/** /**
* @since 1.0.0 * @since 1.0.0
@ -64,7 +68,7 @@ interface CliMatches {
* @since 1.0.0 * @since 1.0.0
*/ */
async function getMatches(): Promise<CliMatches> { async function getMatches(): Promise<CliMatches> {
return await invoke("plugin:cli|cli_matches"); return await window.__TAURI_INVOKE__("plugin:cli|cli_matches");
} }
export type { ArgMatch, SubcommandMatch, CliMatches }; export type { ArgMatch, SubcommandMatch, CliMatches };

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_CLI__=function(_){"use strict";return _.getMatches=async function(){return await window.__TAURI_INVOKE__("plugin:cli|cli_matches")},_}({});Object.defineProperty(window.__TAURI__,"cli",{value:__TAURI_CLI__})}

@ -40,6 +40,7 @@ fn cli_matches<R: Runtime>(_app: AppHandle<R>, cli: State<'_, Cli<R>>) -> Result
pub fn init<R: Runtime>() -> TauriPlugin<R, Config> { pub fn init<R: Runtime>() -> TauriPlugin<R, Config> {
Builder::new("cli") Builder::new("cli")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![cli_matches]) .invoke_handler(tauri::generate_handler![cli_matches])
.setup(|app, api| { .setup(|app, api| {
app.manage(Cli(api)); app.manage(Cli(api));

@ -8,7 +8,11 @@
* @module * @module
*/ */
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
interface Clip<K, T> { interface Clip<K, T> {
kind: K; kind: K;
@ -34,7 +38,7 @@ async function writeText(
text: string, text: string,
opts?: { label?: string } opts?: { label?: string }
): Promise<void> { ): Promise<void> {
return invoke("plugin:clipboard|write", { return window.__TAURI_INVOKE__("plugin:clipboard|write", {
data: { data: {
kind: "PlainText", kind: "PlainText",
options: { options: {
@ -55,7 +59,9 @@ async function writeText(
* @since 1.0.0. * @since 1.0.0.
*/ */
async function readText(): Promise<string> { async function readText(): Promise<string> {
const kind: ClipResponse = await invoke("plugin:clipboard|read"); const kind: ClipResponse = await window.__TAURI_INVOKE__(
"plugin:clipboard|read"
);
return kind.options; return kind.options;
} }

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_CLIPBOARD__=function(_){"use strict";return _.readText=async function(){return(await window.__TAURI_INVOKE__("plugin:clipboard|read")).options},_.writeText=async function(_,i){return window.__TAURI_INVOKE__("plugin:clipboard|write",{data:{kind:"PlainText",options:{label:null==i?void 0:i.label,text:_}}})},_}({});Object.defineProperty(window.__TAURI__,"clipboard",{value:__TAURI_CLIPBOARD__})}

@ -39,6 +39,7 @@ impl<R: Runtime, T: Manager<R>> crate::ClipboardExt<R> for T {
/// Initializes the plugin. /// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("clipboard") Builder::new("clipboard")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![commands::write, commands::read]) .invoke_handler(tauri::generate_handler![commands::write, commands::read])
.setup(|app, api| { .setup(|app, api| {
#[cfg(mobile)] #[cfg(mobile)]

@ -2,7 +2,11 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
interface FileResponse { interface FileResponse {
base64Data?: string; base64Data?: string;
@ -169,7 +173,7 @@ async function open(
Object.freeze(options); Object.freeze(options);
} }
return invoke("plugin:dialog|open", { options }); return window.__TAURI_INVOKE__("plugin:dialog|open", { options });
} }
/** /**
@ -201,7 +205,7 @@ async function save(options: SaveDialogOptions = {}): Promise<string | null> {
Object.freeze(options); Object.freeze(options);
} }
return invoke("plugin:dialog|save", { options }); return window.__TAURI_INVOKE__("plugin:dialog|save", { options });
} }
/** /**
@ -226,7 +230,7 @@ async function message(
options?: string | MessageDialogOptions options?: string | MessageDialogOptions
): Promise<void> { ): Promise<void> {
const opts = typeof options === "string" ? { title: options } : options; const opts = typeof options === "string" ? { title: options } : options;
return invoke("plugin:dialog|message", { return window.__TAURI_INVOKE__("plugin:dialog|message", {
message: message.toString(), message: message.toString(),
title: opts?.title?.toString(), title: opts?.title?.toString(),
type_: opts?.type, type_: opts?.type,
@ -255,7 +259,7 @@ async function ask(
options?: string | ConfirmDialogOptions options?: string | ConfirmDialogOptions
): Promise<boolean> { ): Promise<boolean> {
const opts = typeof options === "string" ? { title: options } : options; const opts = typeof options === "string" ? { title: options } : options;
return invoke("plugin:dialog|ask", { return window.__TAURI_INVOKE__("plugin:dialog|ask", {
message: message.toString(), message: message.toString(),
title: opts?.title?.toString(), title: opts?.title?.toString(),
type_: opts?.type, type_: opts?.type,
@ -285,7 +289,7 @@ async function confirm(
options?: string | ConfirmDialogOptions options?: string | ConfirmDialogOptions
): Promise<boolean> { ): Promise<boolean> {
const opts = typeof options === "string" ? { title: options } : options; const opts = typeof options === "string" ? { title: options } : options;
return invoke("plugin:dialog|confirm", { return window.__TAURI_INVOKE__("plugin:dialog|confirm", {
message: message.toString(), message: message.toString(),
title: opts?.title?.toString(), title: opts?.title?.toString(),
type_: opts?.type, type_: opts?.type,

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_DIALOG__=function(n){"use strict";return n.ask=async function(n,o){var t,i,l,e,u;const _="string"==typeof o?{title:o}:o;return window.__TAURI_INVOKE__("plugin:dialog|ask",{message:n.toString(),title:null===(t=null==_?void 0:_.title)||void 0===t?void 0:t.toString(),type_:null==_?void 0:_.type,okButtonLabel:null!==(l=null===(i=null==_?void 0:_.okLabel)||void 0===i?void 0:i.toString())&&void 0!==l?l:"Yes",cancelButtonLabel:null!==(u=null===(e=null==_?void 0:_.cancelLabel)||void 0===e?void 0:e.toString())&&void 0!==u?u:"No"})},n.confirm=async function(n,o){var t,i,l,e,u;const _="string"==typeof o?{title:o}:o;return window.__TAURI_INVOKE__("plugin:dialog|confirm",{message:n.toString(),title:null===(t=null==_?void 0:_.title)||void 0===t?void 0:t.toString(),type_:null==_?void 0:_.type,okButtonLabel:null!==(l=null===(i=null==_?void 0:_.okLabel)||void 0===i?void 0:i.toString())&&void 0!==l?l:"Ok",cancelButtonLabel:null!==(u=null===(e=null==_?void 0:_.cancelLabel)||void 0===e?void 0:e.toString())&&void 0!==u?u:"Cancel"})},n.message=async function(n,o){var t,i;const l="string"==typeof o?{title:o}:o;return window.__TAURI_INVOKE__("plugin:dialog|message",{message:n.toString(),title:null===(t=null==l?void 0:l.title)||void 0===t?void 0:t.toString(),type_:null==l?void 0:l.type,okButtonLabel:null===(i=null==l?void 0:l.okLabel)||void 0===i?void 0:i.toString()})},n.open=async function(n={}){return"object"==typeof n&&Object.freeze(n),window.__TAURI_INVOKE__("plugin:dialog|open",{options:n})},n.save=async function(n={}){return"object"==typeof n&&Object.freeze(n),window.__TAURI_INVOKE__("plugin:dialog|save",{options:n})},n}({});Object.defineProperty(window.__TAURI__,"dialog",{value:__TAURI_DIALOG__})}

@ -75,7 +75,13 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
// Dialogs are implemented natively on Android // Dialogs are implemented natively on Android
#[cfg(not(target_os = "android"))] #[cfg(not(target_os = "android"))]
{ {
builder = builder.js_init_script(include_str!("init.js").to_string()); let mut init_script = include_str!("init.js").to_string();
init_script.push_str(include_str!("api-iife.js"));
builder = builder.js_init_script(init_script);
}
#[cfg(target_os = "android")]
{
builder = builder.js_init_script(include_str!("api-iife.js").to_string());
} }
builder builder

@ -45,9 +45,14 @@
* @module * @module
*/ */
import { invoke } from "@tauri-apps/api/tauri";
import { BaseDirectory } from "@tauri-apps/api/path"; import { BaseDirectory } from "@tauri-apps/api/path";
declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
interface Permissions { interface Permissions {
/** /**
* `true` if these permissions describe a readonly (unwritable) file. * `true` if these permissions describe a readonly (unwritable) file.
@ -226,7 +231,7 @@ async function readTextFile(
filePath: string, filePath: string,
options: FsOptions = {} options: FsOptions = {}
): Promise<string> { ): Promise<string> {
return await invoke("plugin:fs|read_text_file", { return await window.__TAURI_INVOKE__("plugin:fs|read_text_file", {
path: filePath, path: filePath,
options, options,
}); });
@ -247,7 +252,7 @@ async function readBinaryFile(
filePath: string, filePath: string,
options: FsOptions = {} options: FsOptions = {}
): Promise<Uint8Array> { ): Promise<Uint8Array> {
const arr = await invoke<number[]>("plugin:fs|read_file", { const arr = await window.__TAURI_INVOKE__<number[]>("plugin:fs|read_file", {
path: filePath, path: filePath,
options, options,
}); });
@ -323,7 +328,7 @@ async function writeTextFile(
fileOptions = contents; fileOptions = contents;
} }
return await invoke("plugin:fs|write_file", { return await window.__TAURI_INVOKE__("plugin:fs|write_file", {
path: file.path, path: file.path,
contents: Array.from(new TextEncoder().encode(file.contents)), contents: Array.from(new TextEncoder().encode(file.contents)),
options: fileOptions, options: fileOptions,
@ -405,7 +410,7 @@ async function writeBinaryFile(
file.contents = contents ?? []; file.contents = contents ?? [];
} }
return await invoke("plugin:fs|write_binary_file", { return await window.__TAURI_INVOKE__("plugin:fs|write_binary_file", {
path: file.path, path: file.path,
contents: Array.from( contents: Array.from(
file.contents instanceof ArrayBuffer file.contents instanceof ArrayBuffer
@ -440,7 +445,7 @@ async function readDir(
dir: string, dir: string,
options: FsDirOptions = {} options: FsDirOptions = {}
): Promise<FileEntry[]> { ): Promise<FileEntry[]> {
return await invoke("plugin:fs|read_dir", { return await window.__TAURI_INVOKE__("plugin:fs|read_dir", {
path: dir, path: dir,
options, options,
}); });
@ -465,7 +470,7 @@ async function createDir(
dir: string, dir: string,
options: FsDirOptions = {} options: FsDirOptions = {}
): Promise<void> { ): Promise<void> {
return await invoke("plugin:fs|create_dir", { return await window.__TAURI_INVOKE__("plugin:fs|create_dir", {
path: dir, path: dir,
options, options,
}); });
@ -489,7 +494,7 @@ async function removeDir(
dir: string, dir: string,
options: FsDirOptions = {} options: FsDirOptions = {}
): Promise<void> { ): Promise<void> {
return await invoke("plugin:fs|remove_dir", { return await window.__TAURI_INVOKE__("plugin:fs|remove_dir", {
path: dir, path: dir,
options, options,
}); });
@ -513,7 +518,7 @@ async function copyFile(
destination: string, destination: string,
options: FsOptions = {} options: FsOptions = {}
): Promise<void> { ): Promise<void> {
return await invoke("plugin:fs|copy_file", { return await window.__TAURI_INVOKE__("plugin:fs|copy_file", {
source, source,
destination, destination,
options, options,
@ -537,7 +542,7 @@ async function removeFile(
file: string, file: string,
options: FsOptions = {} options: FsOptions = {}
): Promise<void> { ): Promise<void> {
return await invoke("plugin:fs|remove_file", { return await window.__TAURI_INVOKE__("plugin:fs|remove_file", {
path: file, path: file,
options, options,
}); });
@ -561,7 +566,7 @@ async function renameFile(
newPath: string, newPath: string,
options: FsOptions = {} options: FsOptions = {}
): Promise<void> { ): Promise<void> {
return await invoke("plugin:fs|rename_file", { return await window.__TAURI_INVOKE__("plugin:fs|rename_file", {
oldPath, oldPath,
newPath, newPath,
options, options,
@ -580,7 +585,7 @@ async function renameFile(
* @since 1.0.0 * @since 1.0.0
*/ */
async function exists(path: string): Promise<boolean> { async function exists(path: string): Promise<boolean> {
return await invoke("plugin:fs|exists", { path }); return await window.__TAURI_INVOKE__("plugin:fs|exists", { path });
} }
/** /**
@ -589,17 +594,19 @@ async function exists(path: string): Promise<boolean> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function metadata(path: string): Promise<Metadata> { async function metadata(path: string): Promise<Metadata> {
return await invoke<BackendMetadata>("plugin:fs|metadata", { return await window
path, .__TAURI_INVOKE__<BackendMetadata>("plugin:fs|metadata", {
}).then((metadata) => { path,
const { accessedAtMs, createdAtMs, modifiedAtMs, ...data } = metadata; })
return { .then((metadata) => {
accessedAt: new Date(accessedAtMs), const { accessedAtMs, createdAtMs, modifiedAtMs, ...data } = metadata;
createdAt: new Date(createdAtMs), return {
modifiedAt: new Date(modifiedAtMs), accessedAt: new Date(accessedAtMs),
...data, createdAt: new Date(createdAtMs),
}; modifiedAt: new Date(modifiedAtMs),
}); ...data,
};
});
} }
export type { export type {

File diff suppressed because one or more lines are too long

@ -38,6 +38,7 @@ impl<R: Runtime, T: Manager<R>> FsExt<R> for T {
pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> { pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> {
PluginBuilder::<R, Option<Config>>::new("fs") PluginBuilder::<R, Option<Config>>::new("fs")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
commands::read_file, commands::read_file,
commands::read_text_file, commands::read_text_file,

@ -8,7 +8,14 @@
* @module * @module
*/ */
import { invoke, transformCallback } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
__TAURI__: {
transformCallback: <T>(cb: (payload: T) => void) => number;
};
}
}
export type ShortcutHandler = (shortcut: string) => void; export type ShortcutHandler = (shortcut: string) => void;
@ -31,9 +38,9 @@ async function register(
shortcut: string, shortcut: string,
handler: ShortcutHandler handler: ShortcutHandler
): Promise<void> { ): Promise<void> {
return await invoke("plugin:globalShortcut|register", { return await window.__TAURI_INVOKE__("plugin:globalShortcut|register", {
shortcut, shortcut,
handler: transformCallback(handler), handler: window.__TAURI__.transformCallback(handler),
}); });
} }
@ -56,9 +63,9 @@ async function registerAll(
shortcuts: string[], shortcuts: string[],
handler: ShortcutHandler handler: ShortcutHandler
): Promise<void> { ): Promise<void> {
return await invoke("plugin:globalShortcut|register_all", { return await window.__TAURI_INVOKE__("plugin:globalShortcut|register_all", {
shortcuts, shortcuts,
handler: transformCallback(handler), handler: window.__TAURI__.transformCallback(handler),
}); });
} }
@ -78,7 +85,7 @@ async function registerAll(
* @since 1.0.0 * @since 1.0.0
*/ */
async function isRegistered(shortcut: string): Promise<boolean> { async function isRegistered(shortcut: string): Promise<boolean> {
return await invoke("plugin:globalShortcut|is_registered", { return await window.__TAURI_INVOKE__("plugin:globalShortcut|is_registered", {
shortcut, shortcut,
}); });
} }
@ -96,7 +103,7 @@ async function isRegistered(shortcut: string): Promise<boolean> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function unregister(shortcut: string): Promise<void> { async function unregister(shortcut: string): Promise<void> {
return await invoke("plugin:globalShortcut|unregister", { return await window.__TAURI_INVOKE__("plugin:globalShortcut|unregister", {
shortcut, shortcut,
}); });
} }
@ -112,7 +119,7 @@ async function unregister(shortcut: string): Promise<void> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function unregisterAll(): Promise<void> { async function unregisterAll(): Promise<void> {
return await invoke("plugin:globalShortcut|unregister_all"); return await window.__TAURI_INVOKE__("plugin:globalShortcut|unregister_all");
} }
export { register, registerAll, isRegistered, unregister, unregisterAll }; export { register, registerAll, isRegistered, unregister, unregisterAll };

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_GLOBALSHORTCUT__=function(_){"use strict";return _.isRegistered=async function(_){return await window.__TAURI_INVOKE__("plugin:globalShortcut|is_registered",{shortcut:_})},_.register=async function(_,t){return await window.__TAURI_INVOKE__("plugin:globalShortcut|register",{shortcut:_,handler:window.__TAURI__.transformCallback(t)})},_.registerAll=async function(_,t){return await window.__TAURI_INVOKE__("plugin:globalShortcut|register_all",{shortcuts:_,handler:window.__TAURI__.transformCallback(t)})},_.unregister=async function(_){return await window.__TAURI_INVOKE__("plugin:globalShortcut|unregister",{shortcut:_})},_.unregisterAll=async function(){return await window.__TAURI_INVOKE__("plugin:globalShortcut|unregister_all")},_}({});Object.defineProperty(window.__TAURI__,"globalShortcut",{value:__TAURI_GLOBALSHORTCUT__})}

@ -283,6 +283,7 @@ impl Builder {
pub fn build<R: Runtime>(self) -> TauriPlugin<R> { pub fn build<R: Runtime>(self) -> TauriPlugin<R> {
let handler = self.handler; let handler = self.handler;
PluginBuilder::new("globalShortcut") PluginBuilder::new("globalShortcut")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
register, register,
register_all, register_all,

@ -24,7 +24,11 @@
* @module * @module
*/ */
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
/** /**
* @since 1.0.0 * @since 1.0.0
@ -297,7 +301,7 @@ class Client {
* ``` * ```
*/ */
async drop(): Promise<void> { async drop(): Promise<void> {
return invoke("plugin:http|drop_client", { return window.__TAURI_INVOKE__("plugin:http|drop_client", {
client: this.id, client: this.id,
}); });
} }
@ -320,30 +324,32 @@ class Client {
if (jsonResponse) { if (jsonResponse) {
options.responseType = ResponseType.Text; options.responseType = ResponseType.Text;
} }
return invoke<IResponse<T>>("plugin:http|request", { return window
clientId: this.id, .__TAURI_INVOKE__<IResponse<T>>("plugin:http|request", {
options, clientId: this.id,
}).then((res) => { options,
const response = new Response(res); })
if (jsonResponse) { .then((res) => {
/* eslint-disable */ const response = new Response(res);
try { if (jsonResponse) {
response.data = JSON.parse(response.data as string); /* eslint-disable */
} catch (e) { try {
if (response.ok && (response.data as unknown as string) === "") { response.data = JSON.parse(response.data as string);
response.data = {} as T; } catch (e) {
} else if (response.ok) { if (response.ok && (response.data as unknown as string) === "") {
throw Error( response.data = {} as T;
`Failed to parse response \`${response.data}\` as JSON: ${e}; } 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.` try setting the \`responseType\` option to \`ResponseType.Text\` or \`ResponseType.Binary\` if the API does not return a JSON response.`
); );
}
} }
/* eslint-enable */
return response;
} }
/* eslint-enable */
return response; return response;
} });
return response;
});
} }
/** /**
@ -478,9 +484,11 @@ class Client {
* @since 1.0.0 * @since 1.0.0
*/ */
async function getClient(options?: ClientOptions): Promise<Client> { async function getClient(options?: ClientOptions): Promise<Client> {
return invoke<number>("plugin:http|create_client", { return window
options, .__TAURI_INVOKE__<number>("plugin:http|create_client", {
}).then((id) => new Client(id)); options,
})
.then((id) => new Client(id));
} }
/** @internal */ /** @internal */

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_HTTP__=function(e){"use strict";var t;e.ResponseType=void 0,(t=e.ResponseType||(e.ResponseType={}))[t.JSON=1]="JSON",t[t.Text=2]="Text",t[t.Binary=3]="Binary";class r{constructor(e,t){this.type=e,this.payload=t}static form(e){const t={},s=(e,r)=>{if(null!==r){let s;s="string"==typeof r?r:r instanceof Uint8Array||Array.isArray(r)?Array.from(r):r instanceof File?{file:r.name,mime:r.type,fileName:r.name}:"string"==typeof r.file?{file:r.file,mime:r.mime,fileName:r.fileName}:{file:Array.from(r.file),mime:r.mime,fileName:r.fileName},t[String(e)]=s}};if(e instanceof FormData)for(const[t,r]of e)s(t,r);else for(const[t,r]of Object.entries(e))s(t,r);return new r("Form",t)}static json(e){return new r("Json",e)}static text(e){return new r("Text",e)}static bytes(e){return new r("Bytes",Array.from(e instanceof ArrayBuffer?new Uint8Array(e):e))}}class s{constructor(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}}class n{constructor(e){this.id=e}async drop(){return window.__TAURI_INVOKE__("plugin:http|drop_client",{client:this.id})}async request(t){const r=!t.responseType||t.responseType===e.ResponseType.JSON;return r&&(t.responseType=e.ResponseType.Text),window.__TAURI_INVOKE__("plugin:http|request",{clientId:this.id,options:t}).then((e=>{const t=new s(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 \`${t.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 t}return t}))}async get(e,t){return this.request({method:"GET",url:e,...t})}async post(e,t,r){return this.request({method:"POST",url:e,body:t,...r})}async put(e,t,r){return this.request({method:"PUT",url:e,body:t,...r})}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 i(e){return window.__TAURI_INVOKE__("plugin:http|create_client",{options:e}).then((e=>new n(e)))}let o=null;return e.Body=r,e.Client=n,e.Response=s,e.fetch=async function(e,t){var r;return null===o&&(o=await i()),o.request({url:e,method:null!==(r=null==t?void 0:t.method)&&void 0!==r?r:"GET",...t})},e.getClient=i,e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_HTTP__})}

@ -41,6 +41,7 @@ impl<R: Runtime, T: Manager<R>> HttpExt<R> for T {
pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> { pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> {
Builder::<R, Option<Config>>::new("http") Builder::<R, Option<Config>>::new("http")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
commands::create_client, commands::create_client,
commands::drop_client, commands::drop_client,

@ -2,9 +2,14 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri";
import { listen, UnlistenFn } from "@tauri-apps/api/event"; import { listen, UnlistenFn } from "@tauri-apps/api/event";
declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
export type LogOptions = { export type LogOptions = {
file?: string; file?: string;
line?: number; line?: number;
@ -61,7 +66,7 @@ async function log(
location = "webview::unknown"; location = "webview::unknown";
} }
await invoke("plugin:log|log", { await window.__TAURI_INVOKE__("plugin:log|log", {
level, level,
message, message,
location, location,

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_LOG__=function(e){"use strict";var n=Object.defineProperty,t=(e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})},r=(e,n,t)=>{if(!n.has(e))throw TypeError("Cannot "+t)},a=(e,n,t)=>(r(e,n,"read from private field"),t?t.call(e):n.get(e)),i=(e,n,t,a)=>(r(e,n,"write to private field"),a?a.call(e,t):n.set(e,t),t);function o(e,n=!1){let t=window.crypto.getRandomValues(new Uint32Array(1))[0],r=`_${t}`;return Object.defineProperty(window,r,{value:t=>(n&&Reflect.deleteProperty(window,r),e?.(t)),writable:!1,configurable:!0}),t}t({},{Channel:()=>c,PluginListener:()=>s,addPluginListener:()=>u,convertFileSrc:()=>_,invoke:()=>d,transformCallback:()=>o});var l,c=class{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,((e,n,t)=>{if(n.has(e))throw TypeError("Cannot add the same private member more than once");n instanceof WeakSet?n.add(e):n.set(e,t)})(this,l,(()=>{})),this.id=o((e=>{a(this,l).call(this,e)}))}set onmessage(e){i(this,l,e)}get onmessage(){return a(this,l)}toJSON(){return`__CHANNEL__:${this.id}`}};l=new WeakMap;var s=class{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}};async function u(e,n,t){let r=new c;return r.onmessage=t,d(`plugin:${e}|register_listener`,{event:n,handler:r}).then((()=>new s(e,n,r.id)))}async function d(e,n={}){return new Promise(((t,r)=>{let a=o((e=>{t(e),Reflect.deleteProperty(window,`_${i}`)}),!0),i=o((e=>{r(e),Reflect.deleteProperty(window,`_${a}`)}),!0);window.__TAURI_IPC__({cmd:e,callback:a,error:i,...n})}))}function _(e,n="asset"){let t=encodeURIComponent(e);return navigator.userAgent.includes("Windows")?`https://${n}.localhost/${t}`:`${n}://localhost/${t}`}async function w(e,n){await d("plugin:event|unlisten",{event:e,eventId:n})}async function f(e,n,t){return d("plugin:event|listen",{event:e,windowLabel:n,handler:o(t)}).then((n=>async()=>w(e,n)))}t({},{TauriEvent:()=>h,emit:()=>y,listen:()=>E,once:()=>I});var v,g,h=((v=h||{}).WINDOW_RESIZED="tauri://resize",v.WINDOW_MOVED="tauri://move",v.WINDOW_CLOSE_REQUESTED="tauri://close-requested",v.WINDOW_CREATED="tauri://window-created",v.WINDOW_DESTROYED="tauri://destroyed",v.WINDOW_FOCUS="tauri://focus",v.WINDOW_BLUR="tauri://blur",v.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",v.WINDOW_THEME_CHANGED="tauri://theme-changed",v.WINDOW_FILE_DROP="tauri://file-drop",v.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",v.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",v.MENU="tauri://menu",v);async function E(e,n){return f(e,null,n)}async function I(e,n){return async function(e,n,t){return f(e,n,(n=>{t(n),w(e,n.id).catch((()=>{}))}))}(e,null,n)}async function y(e,n){return async function(e,n,t){await d("plugin:event|emit",{event:e,windowLabel:n,payload:t})}(e,void 0,n)}async function p(e,n,t){var r,a;const i=null===(r=(new Error).stack)||void 0===r?void 0:r.split("\n").map((e=>e.split("@"))),o=null==i?void 0:i.filter((([e,n])=>e.length>0&&"[native code]"!==n)),{file:l,line:c,...s}=null!=t?t:{};let u=null===(a=null==o?void 0:o[0])||void 0===a?void 0:a.filter((e=>e.length>0)).join("@");"Error"===u&&(u="webview::unknown"),await window.__TAURI_INVOKE__("plugin:log|log",{level:e,message:n,location:u,file:l,line:c,keyValues:s})}return function(e){e[e.Trace=1]="Trace",e[e.Debug=2]="Debug",e[e.Info=3]="Info",e[e.Warn=4]="Warn",e[e.Error=5]="Error"}(g||(g={})),e.attachConsole=async function(){return await E("log://log",(e=>{const n=e.payload,t=n.message.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,"");switch(n.level){case g.Trace:console.log(t);break;case g.Debug:console.debug(t);break;case g.Info:console.info(t);break;case g.Warn:console.warn(t);break;case g.Error:console.error(t);break;default:throw new Error(`unknown log level ${n.level}`)}}))},e.debug=async function(e,n){await p(g.Debug,e,n)},e.error=async function(e,n){await p(g.Error,e,n)},e.info=async function(e,n){await p(g.Info,e,n)},e.trace=async function(e,n){await p(g.Trace,e,n)},e.warn=async function(e,n){await p(g.Warn,e,n)},e}({});Object.defineProperty(window.__TAURI__,"log",{value:__TAURI_LOG__})}

@ -389,6 +389,7 @@ impl Builder {
pub fn build<R: Runtime>(mut self) -> TauriPlugin<R> { pub fn build<R: Runtime>(mut self) -> TauriPlugin<R> {
plugin::Builder::new("log") plugin::Builder::new("log")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![log]) .invoke_handler(tauri::generate_handler![log])
.setup(move |app_handle, _api| { .setup(move |app_handle, _api| {
let app_name = &app_handle.package_info().name; let app_name = &app_handle.package_info().name;

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_NOTIFICATION__=function(n){"use strict";var e=Object.defineProperty,i=(n,e,i)=>{if(!e.has(n))throw TypeError("Cannot "+i)},t=(n,e,t)=>(i(n,e,"read from private field"),t?t.call(n):e.get(n)),o=(n,e,t,o)=>(i(n,e,"write to private field"),o?o.call(n,t):e.set(n,t),t);function r(n,e=!1){let i=window.crypto.getRandomValues(new Uint32Array(1))[0],t=`_${i}`;return Object.defineProperty(window,t,{value:i=>(e&&Reflect.deleteProperty(window,t),n?.(i)),writable:!1,configurable:!0}),i}((n,i)=>{for(var t in i)e(n,t,{get:i[t],enumerable:!0})})({},{Channel:()=>a,PluginListener:()=>f,addPluginListener:()=>d,convertFileSrc:()=>p,invoke:()=>_,transformCallback:()=>r});var c,a=class{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,((n,e,i)=>{if(e.has(n))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(n):e.set(n,i)})(this,c,(()=>{})),this.id=r((n=>{t(this,c).call(this,n)}))}set onmessage(n){o(this,c,n)}get onmessage(){return t(this,c)}toJSON(){return`__CHANNEL__:${this.id}`}};c=new WeakMap;var s,l,u,f=class{constructor(n,e,i){this.plugin=n,this.event=e,this.channelId=i}async unregister(){return _(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}};async function d(n,e,i){let t=new a;return t.onmessage=i,_(`plugin:${n}|register_listener`,{event:e,handler:t}).then((()=>new f(n,e,t.id)))}async function _(n,e={}){return new Promise(((i,t)=>{let o=r((n=>{i(n),Reflect.deleteProperty(window,`_${c}`)}),!0),c=r((n=>{t(n),Reflect.deleteProperty(window,`_${o}`)}),!0);window.__TAURI_IPC__({cmd:n,callback:o,error:c,...e})}))}function p(n,e="asset"){let i=encodeURIComponent(n);return navigator.userAgent.includes("Windows")?`https://${e}.localhost/${i}`:`${e}://localhost/${i}`}return function(n){n.Year="Year",n.Month="Month",n.TwoWeeks="TwoWeeks",n.Week="Week",n.Day="Day",n.Hour="Hour",n.Minute="Minute",n.Second="Second"}(s||(s={})),n.Importance=void 0,(l=n.Importance||(n.Importance={}))[l.None=0]="None",l[l.Min=1]="Min",l[l.Low=2]="Low",l[l.Default=3]="Default",l[l.High=4]="High",n.Visibility=void 0,(u=n.Visibility||(n.Visibility={}))[u.Secret=-1]="Secret",u[u.Private=0]="Private",u[u.Public=1]="Public",n.active=async function(){return _("plugin:notification|get_active")},n.cancel=async function(n){return _("plugin:notification|cancel",{notifications:n})},n.cancelAll=async function(){return _("plugin:notification|cancel")},n.channels=async function(){return _("plugin:notification|getActive")},n.createChannel=async function(n){return _("plugin:notification|create_channel",{...n})},n.isPermissionGranted=async function(){return"default"!==window.Notification.permission?Promise.resolve("granted"===window.Notification.permission):_("plugin:notification|is_permission_granted")},n.onAction=async function(n){return d("notification","actionPerformed",n)},n.onNotificationReceived=async function(n){return d("notification","notification",n)},n.pending=async function(){return _("plugin:notification|get_pending")},n.registerActionTypes=async function(n){return _("plugin:notification|register_action_types",{types:n})},n.removeActive=async function(n){return _("plugin:notification|remove_active",{notifications:n})},n.removeAllActive=async function(){return _("plugin:notification|remove_active")},n.removeChannel=async function(n){return _("plugin:notification|delete_channel",{id:n})},n.requestPermission=async function(){return window.Notification.requestPermission()},n.sendNotification=function(n){"string"==typeof n?new window.Notification(n):new window.Notification(n.title,n)},n}({});Object.defineProperty(window.__TAURI__,"notification",{value:__TAURI_NOTIFICATION__})}

@ -212,13 +212,15 @@ impl<R: Runtime, T: Manager<R>> crate::NotificationExt<R> for T {
/// Initializes the plugin. /// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
let mut init_script = include_str!("init.js").to_string();
init_script.push_str(include_str!("api-iife.js"));
Builder::new("notification") Builder::new("notification")
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
commands::notify, commands::notify,
commands::request_permission, commands::request_permission,
commands::is_permission_granted commands::is_permission_granted
]) ])
.js_init_script(include_str!("init.js").into()) .js_init_script(init_script)
.setup(|app, api| { .setup(|app, api| {
#[cfg(mobile)] #[cfg(mobile)]
let notification = mobile::init(app, api)?; let notification = mobile::init(app, api)?;

@ -8,7 +8,11 @@
* @module * @module
*/ */
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
type Platform = type Platform =
| "linux" | "linux"
@ -63,7 +67,7 @@ const EOL = isWindows() ? "\r\n" : "\n";
* *
*/ */
async function platform(): Promise<Platform> { async function platform(): Promise<Platform> {
return invoke("plugin:os|platform"); return window.__TAURI_INVOKE__("plugin:os|platform");
} }
/** /**
@ -77,7 +81,7 @@ async function platform(): Promise<Platform> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function version(): Promise<string> { async function version(): Promise<string> {
return invoke("plugin:os|version"); return window.__TAURI_INVOKE__("plugin:os|version");
} }
/** /**
@ -91,7 +95,7 @@ async function version(): Promise<string> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function type(): Promise<OsType> { async function type(): Promise<OsType> {
return invoke("plugin:os|kind"); return window.__TAURI_INVOKE__("plugin:os|kind");
} }
/** /**
@ -106,7 +110,7 @@ async function type(): Promise<OsType> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function arch(): Promise<Arch> { async function arch(): Promise<Arch> {
return invoke("plugin:os|arch"); return window.__TAURI_INVOKE__("plugin:os|arch");
} }
/** /**
@ -120,7 +124,7 @@ async function arch(): Promise<Arch> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function tempdir(): Promise<string> { async function tempdir(): Promise<string> {
return invoke("plugin:os|tempdir"); return window.__TAURI_INVOKE__("plugin:os|tempdir");
} }
export { EOL, platform, version, type, arch, tempdir }; export { EOL, platform, version, type, arch, tempdir };

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_OS__=function(n){"use strict";const _=navigator.appVersion.includes("Win")?"\r\n":"\n";return n.EOL=_,n.arch=async function(){return window.__TAURI_INVOKE__("plugin:os|arch")},n.platform=async function(){return window.__TAURI_INVOKE__("plugin:os|platform")},n.tempdir=async function(){return window.__TAURI_INVOKE__("plugin:os|tempdir")},n.type=async function(){return window.__TAURI_INVOKE__("plugin:os|kind")},n.version=async function(){return window.__TAURI_INVOKE__("plugin:os|version")},n}({});Object.defineProperty(window.__TAURI__,"os",{value:__TAURI_OS__})}

@ -70,6 +70,7 @@ pub fn tempdir() -> PathBuf {
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("os") Builder::new("os")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
commands::platform, commands::platform,
commands::version, commands::version,

@ -3,7 +3,11 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
/** /**
* Well known window positions. * Well known window positions.
@ -33,7 +37,7 @@ export enum Position {
* @param to The {@link Position} to move to. * @param to The {@link Position} to move to.
*/ */
export async function moveWindow(to: Position): Promise<void> { export async function moveWindow(to: Position): Promise<void> {
await invoke("plugin:positioner|move_window", { await window.__TAURI_INVOKE__("plugin:positioner|move_window", {
position: to, position: to,
}); });
} }

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_POSITIONER__=function(t){"use strict";var o;return t.Position=void 0,(o=t.Position||(t.Position={}))[o.TopLeft=0]="TopLeft",o[o.TopRight=1]="TopRight",o[o.BottomLeft=2]="BottomLeft",o[o.BottomRight=3]="BottomRight",o[o.TopCenter=4]="TopCenter",o[o.BottomCenter=5]="BottomCenter",o[o.LeftCenter=6]="LeftCenter",o[o.RightCenter=7]="RightCenter",o[o.Center=8]="Center",o[o.TrayLeft=9]="TrayLeft",o[o.TrayBottomLeft=10]="TrayBottomLeft",o[o.TrayRight=11]="TrayRight",o[o.TrayBottomRight=12]="TrayBottomRight",o[o.TrayCenter=13]="TrayCenter",o[o.TrayBottomCenter=14]="TrayBottomCenter",t.moveWindow=async function(t){await window.__TAURI_INVOKE__("plugin:positioner|move_window",{position:t})},t}({});Object.defineProperty(window.__TAURI__,"positioner",{value:__TAURI_POSITIONER__})}

@ -62,8 +62,9 @@ async fn move_window<R: Runtime>(window: tauri::Window<R>, position: Position) -
/// The Tauri plugin that exposes [`WindowExt::move_window`] to the webview. /// The Tauri plugin that exposes [`WindowExt::move_window`] to the webview.
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
let plugin = let plugin = plugin::Builder::new("positioner")
plugin::Builder::new("positioner").invoke_handler(tauri::generate_handler![move_window]); .js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![move_window]);
#[cfg(feature = "system-tray")] #[cfg(feature = "system-tray")]
let plugin = plugin.setup(|app_handle, _api| { let plugin = plugin.setup(|app_handle, _api| {

@ -7,7 +7,11 @@
* @module * @module
*/ */
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
/** /**
* Exits immediately with the given `exitCode`. * Exits immediately with the given `exitCode`.
@ -23,7 +27,7 @@ import { invoke } from "@tauri-apps/api/tauri";
* @since 1.0.0 * @since 1.0.0
*/ */
async function exit(code = 0): Promise<void> { async function exit(code = 0): Promise<void> {
return invoke("plugin:process|exit", { code }); return window.__TAURI_INVOKE__("plugin:process|exit", { code });
} }
/** /**
@ -39,7 +43,7 @@ async function exit(code = 0): Promise<void> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function relaunch(): Promise<void> { async function relaunch(): Promise<void> {
return invoke("plugin:process|restart"); return window.__TAURI_INVOKE__("plugin:process|restart");
} }
export { exit, relaunch }; export { exit, relaunch };

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_PROCESS__=function(_){"use strict";return _.exit=async function(_=0){return window.__TAURI_INVOKE__("plugin:process|exit",{code:_})},_.relaunch=async function(){return window.__TAURI_INVOKE__("plugin:process|restart")},_}({});Object.defineProperty(window.__TAURI__,"process",{value:__TAURI_PROCESS__})}

@ -11,6 +11,7 @@ mod commands;
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("process") Builder::new("process")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![commands::exit, commands::restart]) .invoke_handler(tauri::generate_handler![commands::exit, commands::restart])
.build() .build()
} }

@ -62,7 +62,14 @@
* @module * @module
*/ */
import { invoke, transformCallback } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
__TAURI__: {
transformCallback: <T>(cb: (payload: T) => void) => number;
};
}
}
/** /**
* @since 1.0.0 * @since 1.0.0
@ -119,11 +126,11 @@ async function execute<O extends IOPayload>(
Object.freeze(args); Object.freeze(args);
} }
return invoke<number>("plugin:shell|execute", { return window.__TAURI_INVOKE__<number>("plugin:shell|execute", {
program, program,
args, args,
options, options,
onEventFn: transformCallback(onEvent), onEventFn: window.__TAURI__.transformCallback(onEvent),
}); });
} }
@ -345,7 +352,7 @@ class Child {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async write(data: IOPayload): Promise<void> { async write(data: IOPayload): Promise<void> {
return invoke("plugin:shell|stdin_write", { return window.__TAURI_INVOKE__("plugin:shell|stdin_write", {
pid: this.pid, pid: this.pid,
// correctly serialize Uint8Arrays // correctly serialize Uint8Arrays
buffer: typeof data === "string" ? data : Array.from(data), buffer: typeof data === "string" ? data : Array.from(data),
@ -358,7 +365,7 @@ class Child {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async kill(): Promise<void> { async kill(): Promise<void> {
return invoke("plugin:shell|kill", { return window.__TAURI_INVOKE__("plugin:shell|kill", {
cmd: "killChild", cmd: "killChild",
pid: this.pid, pid: this.pid,
}); });
@ -629,7 +636,7 @@ type CommandEvent<O extends IOPayload> =
* @since 1.0.0 * @since 1.0.0
*/ */
async function open(path: string, openWith?: string): Promise<void> { async function open(path: string, openWith?: string): Promise<void> {
return invoke("plugin:shell|open", { return window.__TAURI_INVOKE__("plugin:shell|open", {
path, path,
with: openWith, with: openWith,
}); });

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_SHELL__=function(e){"use strict";class t{constructor(){this.eventListeners=Object.create(null)}addListener(e,t){return this.on(e,t)}removeListener(e,t){return this.off(e,t)}on(e,t){return e in this.eventListeners?this.eventListeners[e].push(t):this.eventListeners[e]=[t],this}once(e,t){const s=n=>{this.removeListener(e,s),t(n)};return this.addListener(e,s)}off(e,t){return e in this.eventListeners&&(this.eventListeners[e]=this.eventListeners[e].filter((e=>e!==t))),this}removeAllListeners(e){return e?delete this.eventListeners[e]:this.eventListeners=Object.create(null),this}emit(e,t){if(e in this.eventListeners){const s=this.eventListeners[e];for(const e of s)e(t);return!0}return!1}listenerCount(e){return e in this.eventListeners?this.eventListeners[e].length:0}prependListener(e,t){return e in this.eventListeners?this.eventListeners[e].unshift(t):this.eventListeners[e]=[t],this}prependOnceListener(e,t){const s=n=>{this.removeListener(e,s),t(n)};return this.prependListener(e,s)}}class s{constructor(e){this.pid=e}async write(e){return window.__TAURI_INVOKE__("plugin:shell|stdin_write",{pid:this.pid,buffer:"string"==typeof e?e:Array.from(e)})}async kill(){return window.__TAURI_INVOKE__("plugin:shell|kill",{cmd:"killChild",pid:this.pid})}}class n extends t{constructor(e,s=[],n){super(),this.stdout=new t,this.stderr=new t,this.program=e,this.args="string"==typeof s?[s]:s,this.options=null!=n?n:{}}static create(e,t=[],s){return new n(e,t,s)}static sidecar(e,t=[],s){const r=new n(e,t,s);return r.options.sidecar=!0,r}async spawn(){return async function(e,t,s=[],n){return"object"==typeof s&&Object.freeze(s),window.__TAURI_INVOKE__("plugin:shell|execute",{program:t,args:s,options:n,onEventFn:window.__TAURI__.transformCallback(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 s(e)))}async execute(){return new Promise(((e,t)=>{this.on("error",t);const s=[],n=[];this.stdout.on("data",(e=>{s.push(e)})),this.stderr.on("data",(e=>{n.push(e)})),this.on("close",(t=>{e({code:t.code,signal:t.signal,stdout:this.collectOutput(s),stderr:this.collectOutput(n)})})),this.spawn().catch(t)}))}collectOutput(e){return"raw"===this.options.encoding?e.reduce(((e,t)=>new Uint8Array([...e,...t,10])),new Uint8Array):e.join("\n")}}return e.Child=s,e.Command=n,e.EventEmitter=t,e.open=async function(e,t){return window.__TAURI_INVOKE__("plugin:shell|open",{path:e,with:t})},e}({});Object.defineProperty(window.__TAURI__,"shell",{value:__TAURI_SHELL__})}

@ -67,8 +67,11 @@ impl<R: Runtime, T: Manager<R>> ShellExt<R> for T {
} }
pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> { pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> {
let mut init_script = include_str!("init.js").to_string();
init_script.push_str(include_str!("api-iife.js"));
Builder::<R, Option<Config>>::new("shell") Builder::<R, Option<Config>>::new("shell")
.js_init_script(include_str!("init.js").to_string()) .js_init_script(init_script)
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
commands::execute, commands::execute,
commands::stdin_write, commands::stdin_write,

@ -2,7 +2,11 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
export interface QueryResult { export interface QueryResult {
/** The number of rows affected by the query. */ /** The number of rows affected by the query. */
@ -46,7 +50,7 @@ export default class Database {
* ``` * ```
*/ */
static async load(path: string): Promise<Database> { static async load(path: string): Promise<Database> {
const _path = await invoke<string>("plugin:sql|load", { const _path = await window.__TAURI_INVOKE__<string>("plugin:sql|load", {
db: path, db: path,
}); });
@ -87,14 +91,13 @@ export default class Database {
* ``` * ```
*/ */
async execute(query: string, bindValues?: unknown[]): Promise<QueryResult> { async execute(query: string, bindValues?: unknown[]): Promise<QueryResult> {
const [rowsAffected, lastInsertId] = await invoke<[number, number]>( const [rowsAffected, lastInsertId] = await window.__TAURI_INVOKE__<
"plugin:sql|execute", [number, number]
{ >("plugin:sql|execute", {
db: this.path, db: this.path,
query, query,
values: bindValues ?? [], values: bindValues ?? [],
} });
);
return { return {
lastInsertId, lastInsertId,
@ -115,7 +118,7 @@ export default class Database {
* ``` * ```
*/ */
async select<T>(query: string, bindValues?: unknown[]): Promise<T> { async select<T>(query: string, bindValues?: unknown[]): Promise<T> {
const result = await invoke<T>("plugin:sql|select", { const result = await window.__TAURI_INVOKE__<T>("plugin:sql|select", {
db: this.path, db: this.path,
query, query,
values: bindValues ?? [], values: bindValues ?? [],
@ -136,7 +139,7 @@ export default class Database {
* @param db - Optionally state the name of a database if you are managing more than one. Otherwise, all database pools will be in scope. * @param db - Optionally state the name of a database if you are managing more than one. Otherwise, all database pools will be in scope.
*/ */
async close(db?: string): Promise<boolean> { async close(db?: string): Promise<boolean> {
const success = await invoke<boolean>("plugin:sql|close", { const success = await window.__TAURI_INVOKE__<boolean>("plugin:sql|close", {
db, db,
}); });
return success; return success;

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_SQL__=function(){"use strict";class _{constructor(_){this.path=_}static async load(t){const e=await window.__TAURI_INVOKE__("plugin:sql|load",{db:t});return new _(e)}static get(t){return new _(t)}async execute(_,t){const[e,n]=await window.__TAURI_INVOKE__("plugin:sql|execute",{db:this.path,query:_,values:null!=t?t:[]});return{lastInsertId:n,rowsAffected:e}}async select(_,t){return await window.__TAURI_INVOKE__("plugin:sql|select",{db:this.path,query:_,values:null!=t?t:[]})}async close(_){return await window.__TAURI_INVOKE__("plugin:sql|close",{db:_})}}return _}();Object.defineProperty(window.__TAURI__,"sql",{value:__TAURI_SQL__})}

@ -280,6 +280,7 @@ impl Builder {
pub fn build<R: Runtime>(mut self) -> TauriPlugin<R, Option<PluginConfig>> { pub fn build<R: Runtime>(mut self) -> TauriPlugin<R, Option<PluginConfig>> {
PluginBuilder::<R, Option<PluginConfig>>::new("sql") PluginBuilder::<R, Option<PluginConfig>>::new("sql")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![load, execute, select, close]) .invoke_handler(tauri::generate_handler![load, execute, select, close])
.setup(|app, api| { .setup(|app, api| {
let config = api.config().clone().unwrap_or_default(); let config = api.config().clone().unwrap_or_default();

@ -2,9 +2,14 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri";
import { listen, UnlistenFn } from "@tauri-apps/api/event"; import { listen, UnlistenFn } from "@tauri-apps/api/event";
declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
interface ChangePayload<T> { interface ChangePayload<T> {
path: string; path: string;
key: string; key: string;
@ -28,7 +33,7 @@ export class Store {
* @returns * @returns
*/ */
async set(key: string, value: unknown): Promise<void> { async set(key: string, value: unknown): Promise<void> {
return await invoke("plugin:store|set", { return await window.__TAURI_INVOKE__("plugin:store|set", {
path: this.path, path: this.path,
key, key,
value, value,
@ -42,7 +47,7 @@ export class Store {
* @returns * @returns
*/ */
async get<T>(key: string): Promise<T | null> { async get<T>(key: string): Promise<T | null> {
return await invoke("plugin:store|get", { return await window.__TAURI_INVOKE__("plugin:store|get", {
path: this.path, path: this.path,
key, key,
}); });
@ -55,7 +60,7 @@ export class Store {
* @returns * @returns
*/ */
async has(key: string): Promise<boolean> { async has(key: string): Promise<boolean> {
return await invoke("plugin:store|has", { return await window.__TAURI_INVOKE__("plugin:store|has", {
path: this.path, path: this.path,
key, key,
}); });
@ -68,7 +73,7 @@ export class Store {
* @returns * @returns
*/ */
async delete(key: string): Promise<boolean> { async delete(key: string): Promise<boolean> {
return await invoke("plugin:store|delete", { return await window.__TAURI_INVOKE__("plugin:store|delete", {
path: this.path, path: this.path,
key, key,
}); });
@ -81,7 +86,7 @@ export class Store {
* @returns * @returns
*/ */
async clear(): Promise<void> { async clear(): Promise<void> {
return await invoke("plugin:store|clear", { return await window.__TAURI_INVOKE__("plugin:store|clear", {
path: this.path, path: this.path,
}); });
} }
@ -93,7 +98,7 @@ export class Store {
* @returns * @returns
*/ */
async reset(): Promise<void> { async reset(): Promise<void> {
return await invoke("plugin:store|reset", { return await window.__TAURI_INVOKE__("plugin:store|reset", {
path: this.path, path: this.path,
}); });
} }
@ -104,7 +109,7 @@ export class Store {
* @returns * @returns
*/ */
async keys(): Promise<string[]> { async keys(): Promise<string[]> {
return await invoke("plugin:store|keys", { return await window.__TAURI_INVOKE__("plugin:store|keys", {
path: this.path, path: this.path,
}); });
} }
@ -115,7 +120,7 @@ export class Store {
* @returns * @returns
*/ */
async values<T>(): Promise<T[]> { async values<T>(): Promise<T[]> {
return await invoke("plugin:store|values", { return await window.__TAURI_INVOKE__("plugin:store|values", {
path: this.path, path: this.path,
}); });
} }
@ -126,7 +131,7 @@ export class Store {
* @returns * @returns
*/ */
async entries<T>(): Promise<Array<[key: string, value: T]>> { async entries<T>(): Promise<Array<[key: string, value: T]>> {
return await invoke("plugin:store|entries", { return await window.__TAURI_INVOKE__("plugin:store|entries", {
path: this.path, path: this.path,
}); });
} }
@ -137,7 +142,7 @@ export class Store {
* @returns * @returns
*/ */
async length(): Promise<number> { async length(): Promise<number> {
return await invoke("plugin:store|length", { return await window.__TAURI_INVOKE__("plugin:store|length", {
path: this.path, path: this.path,
}); });
} }
@ -151,7 +156,7 @@ export class Store {
* @returns * @returns
*/ */
async load(): Promise<void> { async load(): Promise<void> {
return await invoke("plugin:store|load", { return await window.__TAURI_INVOKE__("plugin:store|load", {
path: this.path, path: this.path,
}); });
} }
@ -164,7 +169,7 @@ export class Store {
* @returns * @returns
*/ */
async save(): Promise<void> { async save(): Promise<void> {
return await invoke("plugin:store|save", { return await window.__TAURI_INVOKE__("plugin:store|save", {
path: this.path, path: this.path,
}); });
} }

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_STORE__=function(e){"use strict";var t=Object.defineProperty,n=(e,n)=>{for(var a in n)t(e,a,{get:n[a],enumerable:!0})},a=(e,t,n)=>{if(!t.has(e))throw TypeError("Cannot "+n)},r=(e,t,n)=>(a(e,t,"read from private field"),n?n.call(e):t.get(e)),i=(e,t,n,r)=>(a(e,t,"write to private field"),r?r.call(e,n):t.set(e,n),n);function s(e,t=!1){let n=window.crypto.getRandomValues(new Uint32Array(1))[0],a=`_${n}`;return Object.defineProperty(window,a,{value:n=>(t&&Reflect.deleteProperty(window,a),e?.(n)),writable:!1,configurable:!0}),n}n({},{Channel:()=>o,PluginListener:()=>l,addPluginListener:()=>u,convertFileSrc:()=>h,invoke:()=>c,transformCallback:()=>s});var _,o=class{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,((e,t,n)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,n)})(this,_,(()=>{})),this.id=s((e=>{r(this,_).call(this,e)}))}set onmessage(e){i(this,_,e)}get onmessage(){return r(this,_)}toJSON(){return`__CHANNEL__:${this.id}`}};_=new WeakMap;var l=class{constructor(e,t,n){this.plugin=e,this.event=t,this.channelId=n}async unregister(){return c(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}};async function u(e,t,n){let a=new o;return a.onmessage=n,c(`plugin:${e}|register_listener`,{event:t,handler:a}).then((()=>new l(e,t,a.id)))}async function c(e,t={}){return new Promise(((n,a)=>{let r=s((e=>{n(e),Reflect.deleteProperty(window,`_${i}`)}),!0),i=s((e=>{a(e),Reflect.deleteProperty(window,`_${r}`)}),!0);window.__TAURI_IPC__({cmd:e,callback:r,error:i,...t})}))}function h(e,t="asset"){let n=encodeURIComponent(e);return navigator.userAgent.includes("Windows")?`https://${t}.localhost/${n}`:`${t}://localhost/${n}`}async function d(e,t){await c("plugin:event|unlisten",{event:e,eventId:t})}async function p(e,t,n){return c("plugin:event|listen",{event:e,windowLabel:t,handler:s(n)}).then((t=>async()=>d(e,t)))}n({},{TauriEvent:()=>y,emit:()=>E,listen:()=>I,once:()=>g});var w,y=((w=y||{}).WINDOW_RESIZED="tauri://resize",w.WINDOW_MOVED="tauri://move",w.WINDOW_CLOSE_REQUESTED="tauri://close-requested",w.WINDOW_CREATED="tauri://window-created",w.WINDOW_DESTROYED="tauri://destroyed",w.WINDOW_FOCUS="tauri://focus",w.WINDOW_BLUR="tauri://blur",w.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",w.WINDOW_THEME_CHANGED="tauri://theme-changed",w.WINDOW_FILE_DROP="tauri://file-drop",w.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",w.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",w.MENU="tauri://menu",w);async function I(e,t){return p(e,null,t)}async function g(e,t){return async function(e,t,n){return p(e,t,(t=>{n(t),d(e,t.id).catch((()=>{}))}))}(e,null,t)}async function E(e,t){return async function(e,t,n){await c("plugin:event|emit",{event:e,windowLabel:t,payload:n})}(e,void 0,t)}return e.Store=class{constructor(e){this.path=e}async set(e,t){return await window.__TAURI_INVOKE__("plugin:store|set",{path:this.path,key:e,value:t})}async get(e){return await window.__TAURI_INVOKE__("plugin:store|get",{path:this.path,key:e})}async has(e){return await window.__TAURI_INVOKE__("plugin:store|has",{path:this.path,key:e})}async delete(e){return await window.__TAURI_INVOKE__("plugin:store|delete",{path:this.path,key:e})}async clear(){return await window.__TAURI_INVOKE__("plugin:store|clear",{path:this.path})}async reset(){return await window.__TAURI_INVOKE__("plugin:store|reset",{path:this.path})}async keys(){return await window.__TAURI_INVOKE__("plugin:store|keys",{path:this.path})}async values(){return await window.__TAURI_INVOKE__("plugin:store|values",{path:this.path})}async entries(){return await window.__TAURI_INVOKE__("plugin:store|entries",{path:this.path})}async length(){return await window.__TAURI_INVOKE__("plugin:store|length",{path:this.path})}async load(){return await window.__TAURI_INVOKE__("plugin:store|load",{path:this.path})}async save(){return await window.__TAURI_INVOKE__("plugin:store|save",{path:this.path})}async onKeyChange(e,t){return await I("store://change",(n=>{n.payload.path===this.path&&n.payload.key===e&&t(n.payload.value)}))}async onChange(e){return await I("store://change",(t=>{t.payload.path===this.path&&e(t.payload.key,t.payload.value)}))}},e}({});Object.defineProperty(window.__TAURI__,"store",{value:__TAURI_STORE__})}

@ -278,6 +278,7 @@ impl<R: Runtime> Builder<R> {
/// ``` /// ```
pub fn build(mut self) -> TauriPlugin<R> { pub fn build(mut self) -> TauriPlugin<R> {
plugin::Builder::new("store") plugin::Builder::new("store")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
set, get, has, delete, clear, reset, keys, values, length, entries, load, save set, get, has, delete, clear, reset, keys, values, length, entries, load, save
]) ])

@ -2,7 +2,11 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
type BytesDto = string | number[]; type BytesDto = string | number[];
export type ClientPath = export type ClientPath =
@ -131,16 +135,18 @@ class ProcedureExecutor {
outputLocation: Location, outputLocation: Location,
sizeBytes?: number sizeBytes?: number
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await invoke<number[]>("plugin:stronghold|execute_procedure", { return await window
...this.procedureArgs, .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
procedure: { ...this.procedureArgs,
type: "SLIP10Generate", procedure: {
payload: { type: "SLIP10Generate",
output: outputLocation, payload: {
sizeBytes, output: outputLocation,
sizeBytes,
},
}, },
}, })
}).then((n) => Uint8Array.from(n)); .then((n) => Uint8Array.from(n));
} }
/** /**
@ -158,20 +164,22 @@ class ProcedureExecutor {
sourceLocation: Location, sourceLocation: Location,
outputLocation: Location outputLocation: Location
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await invoke<number[]>("plugin:stronghold|execute_procedure", { return await window
...this.procedureArgs, .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
procedure: { ...this.procedureArgs,
type: "SLIP10Derive", procedure: {
payload: { type: "SLIP10Derive",
chain, payload: {
input: { chain,
type: source, input: {
payload: sourceLocation, type: source,
payload: sourceLocation,
},
output: outputLocation,
}, },
output: outputLocation,
}, },
}, })
}).then((n) => Uint8Array.from(n)); .then((n) => Uint8Array.from(n));
} }
/** /**
@ -187,17 +195,19 @@ class ProcedureExecutor {
outputLocation: Location, outputLocation: Location,
passphrase?: string passphrase?: string
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await invoke<number[]>("plugin:stronghold|execute_procedure", { return await window
...this.procedureArgs, .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
procedure: { ...this.procedureArgs,
type: "BIP39Recover", procedure: {
payload: { type: "BIP39Recover",
mnemonic, payload: {
passphrase, mnemonic,
output: outputLocation, passphrase,
output: outputLocation,
},
}, },
}, })
}).then((n) => Uint8Array.from(n)); .then((n) => Uint8Array.from(n));
} }
/** /**
@ -211,16 +221,18 @@ class ProcedureExecutor {
outputLocation: Location, outputLocation: Location,
passphrase?: string passphrase?: string
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await invoke<number[]>("plugin:stronghold|execute_procedure", { return await window
...this.procedureArgs, .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
procedure: { ...this.procedureArgs,
type: "BIP39Generate", procedure: {
payload: { type: "BIP39Generate",
output: outputLocation, payload: {
passphrase, output: outputLocation,
passphrase,
},
}, },
}, })
}).then((n) => Uint8Array.from(n)); .then((n) => Uint8Array.from(n));
} }
/** /**
@ -229,16 +241,18 @@ class ProcedureExecutor {
* @returns A promise resolving to the public key hex string. * @returns A promise resolving to the public key hex string.
*/ */
async getEd25519PublicKey(privateKeyLocation: Location): Promise<Uint8Array> { async getEd25519PublicKey(privateKeyLocation: Location): Promise<Uint8Array> {
return await invoke<number[]>("plugin:stronghold|execute_procedure", { return await window
...this.procedureArgs, .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
procedure: { ...this.procedureArgs,
type: "PublicKey", procedure: {
payload: { type: "PublicKey",
type: "Ed25519", payload: {
privateKey: privateKeyLocation, type: "Ed25519",
privateKey: privateKeyLocation,
},
}, },
}, })
}).then((n) => Uint8Array.from(n)); .then((n) => Uint8Array.from(n));
} }
/** /**
@ -251,16 +265,18 @@ class ProcedureExecutor {
privateKeyLocation: Location, privateKeyLocation: Location,
msg: string msg: string
): Promise<Uint8Array> { ): Promise<Uint8Array> {
return await invoke<number[]>("plugin:stronghold|execute_procedure", { return await window
...this.procedureArgs, .__TAURI_INVOKE__<number[]>("plugin:stronghold|execute_procedure", {
procedure: { ...this.procedureArgs,
type: "Ed25519Sign", procedure: {
payload: { type: "Ed25519Sign",
privateKey: privateKeyLocation, payload: {
msg, privateKey: privateKeyLocation,
msg,
},
}, },
}, })
}).then((n) => Uint8Array.from(n)); .then((n) => Uint8Array.from(n));
} }
} }
@ -298,11 +314,13 @@ export class Store {
} }
async get(key: StoreKey): Promise<Uint8Array> { async get(key: StoreKey): Promise<Uint8Array> {
return await invoke<number[]>("plugin:stronghold|get_store_record", { return await window
snapshotPath: this.path, .__TAURI_INVOKE__<number[]>("plugin:stronghold|get_store_record", {
client: this.client, snapshotPath: this.path,
key: toBytesDto(key), client: this.client,
}).then((v) => Uint8Array.from(v)); key: toBytesDto(key),
})
.then((v) => Uint8Array.from(v));
} }
async insert( async insert(
@ -310,24 +328,29 @@ export class Store {
value: number[], value: number[],
lifetime?: Duration lifetime?: Duration
): Promise<void> { ): Promise<void> {
return await invoke("plugin:stronghold|save_store_record", { return await window.__TAURI_INVOKE__(
snapshotPath: this.path, "plugin:stronghold|save_store_record",
client: this.client,
key: toBytesDto(key),
value,
lifetime,
});
}
async remove(key: StoreKey): Promise<Uint8Array | null> {
return await invoke<number[] | null>(
"plugin:stronghold|remove_store_record",
{ {
snapshotPath: this.path, snapshotPath: this.path,
client: this.client, client: this.client,
key: toBytesDto(key), key: toBytesDto(key),
value,
lifetime,
} }
).then((v) => (v != null ? Uint8Array.from(v) : null)); );
}
async remove(key: StoreKey): Promise<Uint8Array | null> {
return await window
.__TAURI_INVOKE__<number[] | null>(
"plugin:stronghold|remove_store_record",
{
snapshotPath: this.path,
client: this.client,
key: toBytesDto(key),
}
)
.then((v) => (v != null ? Uint8Array.from(v) : null));
} }
} }
@ -362,7 +385,7 @@ export class Vault extends ProcedureExecutor {
* @returns * @returns
*/ */
async insert(recordPath: RecordPath, secret: number[]): Promise<void> { async insert(recordPath: RecordPath, secret: number[]): Promise<void> {
return await invoke("plugin:stronghold|save_secret", { return await window.__TAURI_INVOKE__("plugin:stronghold|save_secret", {
snapshotPath: this.path, snapshotPath: this.path,
client: this.client, client: this.client,
vault: this.name, vault: this.name,
@ -378,7 +401,7 @@ export class Vault extends ProcedureExecutor {
* @returns * @returns
*/ */
async remove(location: Location): Promise<void> { async remove(location: Location): Promise<void> {
return await invoke("plugin:stronghold|remove_secret", { return await window.__TAURI_INVOKE__("plugin:stronghold|remove_secret", {
snapshotPath: this.path, snapshotPath: this.path,
client: this.client, client: this.client,
vault: this.name, vault: this.name,
@ -410,7 +433,7 @@ export class Stronghold {
* @returns * @returns
*/ */
private async reload(password: string): Promise<void> { private async reload(password: string): Promise<void> {
return await invoke("plugin:stronghold|initialize", { return await window.__TAURI_INVOKE__("plugin:stronghold|initialize", {
snapshotPath: this.path, snapshotPath: this.path,
password, password,
}); });
@ -420,23 +443,27 @@ export class Stronghold {
* Remove this instance from the cache. * Remove this instance from the cache.
*/ */
async unload(): Promise<void> { async unload(): Promise<void> {
return await invoke("plugin:stronghold|destroy", { return await window.__TAURI_INVOKE__("plugin:stronghold|destroy", {
snapshotPath: this.path, snapshotPath: this.path,
}); });
} }
async loadClient(client: ClientPath): Promise<Client> { async loadClient(client: ClientPath): Promise<Client> {
return await invoke("plugin:stronghold|load_client", { return await window
snapshotPath: this.path, .__TAURI_INVOKE__("plugin:stronghold|load_client", {
client: toBytesDto(client), snapshotPath: this.path,
}).then(() => new Client(this.path, client)); client: toBytesDto(client),
})
.then(() => new Client(this.path, client));
} }
async createClient(client: ClientPath): Promise<Client> { async createClient(client: ClientPath): Promise<Client> {
return await invoke("plugin:stronghold|create_client", { return await window
snapshotPath: this.path, .__TAURI_INVOKE__("plugin:stronghold|create_client", {
client: toBytesDto(client), snapshotPath: this.path,
}).then(() => new Client(this.path, client)); client: toBytesDto(client),
})
.then(() => new Client(this.path, client));
} }
/** /**
@ -444,7 +471,7 @@ export class Stronghold {
* @returns * @returns
*/ */
async save(): Promise<void> { async save(): Promise<void> {
return await invoke("plugin:stronghold|save", { return await window.__TAURI_INVOKE__("plugin:stronghold|save", {
snapshotPath: this.path, snapshotPath: this.path,
}); });
} }

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_STRONGHOLD__=function(t){"use strict";function e(t){return"string"==typeof t?t:Array.from(t instanceof ArrayBuffer?new Uint8Array(t):t)}class r{constructor(t,e){this.type=t,this.payload=e}static generic(t,n){return new r("Generic",{vault:e(t),record:e(n)})}static counter(t,n){return new r("Counter",{vault:e(t),counter:n})}}class n{constructor(t){this.procedureArgs=t}async generateSLIP10Seed(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"SLIP10Generate",payload:{output:t,sizeBytes:e}}}).then((t=>Uint8Array.from(t)))}async deriveSLIP10(t,e,r,n){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"SLIP10Derive",payload:{chain:t,input:{type:e,payload:r},output:n}}}).then((t=>Uint8Array.from(t)))}async recoverBIP39(t,e,r){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"BIP39Recover",payload:{mnemonic:t,passphrase:r,output:e}}}).then((t=>Uint8Array.from(t)))}async generateBIP39(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"BIP39Generate",payload:{output:t,passphrase:e}}}).then((t=>Uint8Array.from(t)))}async getEd25519PublicKey(t){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"PublicKey",payload:{type:"Ed25519",privateKey:t}}}).then((t=>Uint8Array.from(t)))}async signEd25519(t,e){return await window.__TAURI_INVOKE__("plugin:stronghold|execute_procedure",{...this.procedureArgs,procedure:{type:"Ed25519Sign",payload:{privateKey:t,msg:e}}}).then((t=>Uint8Array.from(t)))}}class a{constructor(t,r){this.path=t,this.name=e(r)}getVault(t){return new s(this.path,this.name,e(t))}getStore(){return new i(this.path,this.name)}}class i{constructor(t,e){this.path=t,this.client=e}async get(t){return await window.__TAURI_INVOKE__("plugin:stronghold|get_store_record",{snapshotPath:this.path,client:this.client,key:e(t)}).then((t=>Uint8Array.from(t)))}async insert(t,r,n){return await window.__TAURI_INVOKE__("plugin:stronghold|save_store_record",{snapshotPath:this.path,client:this.client,key:e(t),value:r,lifetime:n})}async remove(t){return await window.__TAURI_INVOKE__("plugin:stronghold|remove_store_record",{snapshotPath:this.path,client:this.client,key:e(t)}).then((t=>null!=t?Uint8Array.from(t):null))}}class s extends n{constructor(t,r,n){super({snapshotPath:t,client:r,vault:n}),this.path=t,this.client=e(r),this.name=e(n)}async insert(t,r){return await window.__TAURI_INVOKE__("plugin:stronghold|save_secret",{snapshotPath:this.path,client:this.client,vault:this.name,recordPath:e(t),secret:r})}async remove(t){return await window.__TAURI_INVOKE__("plugin:stronghold|remove_secret",{snapshotPath:this.path,client:this.client,vault:this.name,location:t})}}return t.Client=a,t.Location=r,t.Store=i,t.Stronghold=class{constructor(t,e){this.path=t,this.reload(e)}async reload(t){return await window.__TAURI_INVOKE__("plugin:stronghold|initialize",{snapshotPath:this.path,password:t})}async unload(){return await window.__TAURI_INVOKE__("plugin:stronghold|destroy",{snapshotPath:this.path})}async loadClient(t){return await window.__TAURI_INVOKE__("plugin:stronghold|load_client",{snapshotPath:this.path,client:e(t)}).then((()=>new a(this.path,t)))}async createClient(t){return await window.__TAURI_INVOKE__("plugin:stronghold|create_client",{snapshotPath:this.path,client:e(t)}).then((()=>new a(this.path,t)))}async save(){return await window.__TAURI_INVOKE__("plugin:stronghold|save",{snapshotPath:this.path})}},t.Vault=s,t}({});Object.defineProperty(window.__TAURI__,"stronghold",{value:__TAURI_STRONGHOLD__})}

@ -413,6 +413,7 @@ impl Builder {
let password_hash_function = self.password_hash_function; let password_hash_function = self.password_hash_function;
PluginBuilder::new("stronghold") PluginBuilder::new("stronghold")
.js_init_script(include_str!("api-iife.js").to_string())
.setup(move |app, _api| { .setup(move |app, _api| {
app.manage(StrongholdCollection::default()); app.manage(StrongholdCollection::default());
app.manage(PasswordHashFunction(password_hash_function)); app.manage(PasswordHashFunction(password_hash_function));

@ -46,7 +46,9 @@ class Update {
if (onEvent != null) { if (onEvent != null) {
channel.onmessage = onEvent; channel.onmessage = onEvent;
} }
return invoke("plugin:updater|download_and_install", { onEvent: channel }); return invoke("plugin:updater|download_and_install", {
onEvent: channel,
});
} }
} }

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_UPDATER__=function(e){"use strict";var n=Object.defineProperty,t=(e,n,t)=>{if(!n.has(e))throw TypeError("Cannot "+t)},r=(e,n,r)=>(t(e,n,"read from private field"),r?r.call(e):n.get(e)),i=(e,n,r,i)=>(t(e,n,"write to private field"),i?i.call(e,r):n.set(e,r),r);function a(e,n=!1){let t=window.crypto.getRandomValues(new Uint32Array(1))[0],r=`_${t}`;return Object.defineProperty(window,r,{value:t=>(n&&Reflect.deleteProperty(window,r),e?.(t)),writable:!1,configurable:!0}),t}((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})({},{Channel:()=>s,PluginListener:()=>l,addPluginListener:()=>c,convertFileSrc:()=>u,invoke:()=>d,transformCallback:()=>a});var o,s=class{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,((e,n,t)=>{if(n.has(e))throw TypeError("Cannot add the same private member more than once");n instanceof WeakSet?n.add(e):n.set(e,t)})(this,o,(()=>{})),this.id=a((e=>{r(this,o).call(this,e)}))}set onmessage(e){i(this,o,e)}get onmessage(){return r(this,o)}toJSON(){return`__CHANNEL__:${this.id}`}};o=new WeakMap;var l=class{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}};async function c(e,n,t){let r=new s;return r.onmessage=t,d(`plugin:${e}|register_listener`,{event:n,handler:r}).then((()=>new l(e,n,r.id)))}async function d(e,n={}){return new Promise(((t,r)=>{let i=a((e=>{t(e),Reflect.deleteProperty(window,`_${o}`)}),!0),o=a((e=>{r(e),Reflect.deleteProperty(window,`_${i}`)}),!0);window.__TAURI_IPC__({cmd:e,callback:i,error:o,...n})}))}function u(e,n="asset"){let t=encodeURIComponent(e);return navigator.userAgent.includes("Windows")?`https://${n}.localhost/${t}`:`${n}://localhost/${t}`}class _{constructor(e){this.response=e}async downloadAndInstall(e){const n=new s;return null!=e&&(n.onmessage=e),d("plugin:updater|download_and_install",{onEvent:n})}}return e.Update=_,e.check=async function(e){return d("plugin:updater|check",{...e}).then((e=>new _(e)))},e}({});Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_UPDATER__})}

@ -82,6 +82,7 @@ impl Builder {
let target = self.target; let target = self.target;
let installer_args = self.installer_args; let installer_args = self.installer_args;
PluginBuilder::<R, Config>::new("updater") PluginBuilder::<R, Config>::new("updater")
.js_init_script(include_str!("api-iife.js").to_string())
.setup(move |app, api| { .setup(move |app, api| {
let mut config = api.config().clone(); let mut config = api.config().clone();
if let Some(installer_args) = installer_args { if let Some(installer_args) = installer_args {

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_UPLOAD__=function(e){"use strict";var n=Object.defineProperty,t=(e,n,t)=>{if(!n.has(e))throw TypeError("Cannot "+t)},r=(e,n,r)=>(t(e,n,"read from private field"),r?r.call(e):n.get(e)),o=(e,n,r,o)=>(t(e,n,"write to private field"),o?o.call(e,r):n.set(e,r),r);function a(e,n=!1){let t=window.crypto.getRandomValues(new Uint32Array(1))[0],r=`_${t}`;return Object.defineProperty(window,r,{value:t=>(n&&Reflect.deleteProperty(window,r),e?.(t)),writable:!1,configurable:!0}),t}((e,t)=>{for(var r in t)n(e,r,{get:t[r],enumerable:!0})})({},{Channel:()=>l,PluginListener:()=>s,addPluginListener:()=>d,convertFileSrc:()=>u,invoke:()=>c,transformCallback:()=>a});var i,l=class{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,((e,n,t)=>{if(n.has(e))throw TypeError("Cannot add the same private member more than once");n instanceof WeakSet?n.add(e):n.set(e,t)})(this,i,(()=>{})),this.id=a((e=>{r(this,i).call(this,e)}))}set onmessage(e){o(this,i,e)}get onmessage(){return r(this,i)}toJSON(){return`__CHANNEL__:${this.id}`}};i=new WeakMap;var s=class{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return c(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}};async function d(e,n,t){let r=new l;return r.onmessage=t,c(`plugin:${e}|register_listener`,{event:n,handler:r}).then((()=>new s(e,n,r.id)))}async function c(e,n={}){return new Promise(((t,r)=>{let o=a((e=>{t(e),Reflect.deleteProperty(window,`_${i}`)}),!0),i=a((e=>{r(e),Reflect.deleteProperty(window,`_${o}`)}),!0);window.__TAURI_IPC__({cmd:e,callback:o,error:i,...n})}))}function u(e,n="asset"){let t=encodeURIComponent(e);return navigator.userAgent.includes("Windows")?`https://${n}.localhost/${t}`:`${n}://localhost/${t}`}async function _(e,n,t,r){const o=new Uint32Array(1);window.crypto.getRandomValues(o);const a=o[0],i=new l;null!=t&&(i.onmessage=t),await c("plugin:upload|upload",{id:a,url:e,filePath:n,headers:null!=r?r:{},onProgress:i})}return e.default=_,e.download=async function(e,n,t,r){const o=new Uint32Array(1);window.crypto.getRandomValues(o);const a=o[0],i=new l;null!=t&&(i.onmessage=t),await c("plugin:upload|download",{id:a,url:e,filePath:n,headers:null!=r?r:{},onProgress:i})},e.upload=_,Object.defineProperty(e,"__esModule",{value:!0}),e}({});Object.defineProperty(window.__TAURI__,"upload",{value:__TAURI_UPLOAD__})}

@ -115,6 +115,7 @@ fn file_to_body<R: Runtime>(channel: Channel<R>, file: File) -> reqwest::Body {
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
PluginBuilder::new("upload") PluginBuilder::new("upload")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![download, upload]) .invoke_handler(tauri::generate_handler![download, upload])
.build() .build()
} }

@ -2,7 +2,14 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke, transformCallback } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
__TAURI__: {
transformCallback: <T>(cb: (payload: T) => void) => number;
};
}
}
export interface MessageKind<T, D> { export interface MessageKind<T, D> {
type: T; type: T;
@ -36,11 +43,13 @@ export default class WebSocket {
listeners.forEach((l) => l(message)); listeners.forEach((l) => l(message));
}; };
return await invoke<number>("plugin:websocket|connect", { return await window
url, .__TAURI_INVOKE__<number>("plugin:websocket|connect", {
callbackFunction: transformCallback(handler), url,
options, callbackFunction: window.__TAURI__.transformCallback(handler),
}).then((id) => new WebSocket(id, listeners)); options,
})
.then((id) => new WebSocket(id, listeners));
} }
addListener(cb: (arg: Message) => void): void { addListener(cb: (arg: Message) => void): void {
@ -60,7 +69,7 @@ export default class WebSocket {
"invalid `message` type, expected a `{ type: string, data: any }` object, a string or a numeric array" "invalid `message` type, expected a `{ type: string, data: any }` object, a string or a numeric array"
); );
} }
return await invoke("plugin:websocket|send", { return await window.__TAURI_INVOKE__("plugin:websocket|send", {
id: this.id, id: this.id,
message: m, message: m,
}); });

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_WEBSOCKET__=function(){"use strict";class e{constructor(e,t){this.id=e,this.listeners=t}static async connect(t,n){const i=[];return await window.__TAURI_INVOKE__("plugin:websocket|connect",{url:t,callbackFunction:window.__TAURI__.transformCallback((e=>{i.forEach((t=>t(e)))})),options:n}).then((t=>new e(t,i)))}addListener(e){this.listeners.push(e)}async send(e){let t;if("string"==typeof e)t={type:"Text",data:e};else if("object"==typeof e&&"type"in e)t=e;else{if(!Array.isArray(e))throw new Error("invalid `message` type, expected a `{ type: string, data: any }` object, a string or a numeric array");t={type:"Binary",data:e}}return await window.__TAURI_INVOKE__("plugin:websocket|send",{id:this.id,message:t})}async disconnect(){return await this.send({type:"Close",data:{code:1e3,reason:"Disconnected by client"}})}}return e}();Object.defineProperty(window.__TAURI__,"websocket",{value:__TAURI_WEBSOCKET__})}

@ -165,6 +165,7 @@ async fn send(
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
PluginBuilder::new("websocket") PluginBuilder::new("websocket")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![connect, send]) .invoke_handler(tauri::generate_handler![connect, send])
.setup(|app, _api| { .setup(|app, _api| {
app.manage(ConnectionManager::default()); app.manage(ConnectionManager::default());

@ -2,7 +2,11 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
interface WindowDef { interface WindowDef {
label: string; label: string;
@ -31,14 +35,17 @@ export enum StateFlags {
* Save the state of all open windows to disk. * Save the state of all open windows to disk.
*/ */
async function saveWindowState(flags: StateFlags) { async function saveWindowState(flags: StateFlags) {
invoke("plugin:window-state|save_window_state", { flags }); window.__TAURI_INVOKE__("plugin:window-state|save_window_state", { flags });
} }
/** /**
* Restore the state for the specified window from disk. * Restore the state for the specified window from disk.
*/ */
async function restoreState(label: string, flags: StateFlags) { async function restoreState(label: string, flags: StateFlags) {
invoke("plugin:window-state|restore_state", { label, flags }); window.__TAURI_INVOKE__("plugin:window-state|restore_state", {
label,
flags,
});
} }
/** /**

@ -0,0 +1 @@
if("__TAURI__"in window){var __TAURI_WINDOWSTATE__=function(_){"use strict";var t;async function e(_,t){window.__TAURI_INVOKE__("plugin:window-state|restore_state",{label:_,flags:t})}return _.StateFlags=void 0,(t=_.StateFlags||(_.StateFlags={}))[t.SIZE=1]="SIZE",t[t.POSITION=2]="POSITION",t[t.MAXIMIZED=4]="MAXIMIZED",t[t.VISIBLE=8]="VISIBLE",t[t.DECORATIONS=16]="DECORATIONS",t[t.FULLSCREEN=32]="FULLSCREEN",t[t.ALL=63]="ALL",_.restoreState=e,_.restoreStateCurrent=async function(_){e(window.__TAURI_METADATA__.__currentWindow.label,_)},_.saveWindowState=async function(_){window.__TAURI_INVOKE__("plugin:window-state|save_window_state",{flags:_})},_}({});Object.defineProperty(window.__TAURI__,"windowState",{value:__TAURI_WINDOWSTATE__})}

@ -282,6 +282,7 @@ impl Builder {
pub fn build<R: Runtime>(self) -> TauriPlugin<R> { pub fn build<R: Runtime>(self) -> TauriPlugin<R> {
let flags = self.state_flags; let flags = self.state_flags;
PluginBuilder::new("window-state") PluginBuilder::new("window-state")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
cmd::save_window_state, cmd::save_window_state,
cmd::restore_state cmd::restore_state

@ -2,7 +2,14 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { invoke, transformCallback } from "@tauri-apps/api/tauri"; declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
__TAURI__: {
transformCallback: <T>(cb: (payload: T) => void) => number;
};
}
}
export interface Event<T> { export interface Event<T> {
/** Event name */ /** Event name */
@ -28,7 +35,7 @@ export type UnlistenFn = () => void;
* @returns * @returns
*/ */
async function _unlisten(event: string, eventId: number): Promise<void> { async function _unlisten(event: string, eventId: number): Promise<void> {
await invoke("plugin:event|unlisten", { await window.__TAURI_INVOKE__("plugin:event|unlisten", {
event, event,
eventId, eventId,
}); });
@ -47,7 +54,7 @@ async function emit(
windowLabel?: string, windowLabel?: string,
payload?: unknown payload?: unknown
): Promise<void> { ): Promise<void> {
await invoke("plugin:event|emit", { await window.__TAURI_INVOKE__("plugin:event|emit", {
event, event,
windowLabel, windowLabel,
payload, payload,
@ -66,13 +73,15 @@ async function listen<T>(
windowLabel: string | null, windowLabel: string | null,
handler: EventCallback<T> handler: EventCallback<T>
): Promise<UnlistenFn> { ): Promise<UnlistenFn> {
return invoke<number>("plugin:event|listen", { return window
event, .__TAURI_INVOKE__<number>("plugin:event|listen", {
windowLabel, event,
handler: transformCallback(handler), windowLabel,
}).then((eventId) => { handler: window.__TAURI__.transformCallback(handler),
return async () => _unlisten(event, eventId); })
}); .then((eventId) => {
return async () => _unlisten(event, eventId);
});
} }
/** /**

@ -16,7 +16,6 @@
* @module * @module
*/ */
import { invoke } from "@tauri-apps/api/tauri";
import type { import type {
Event, Event,
EventName, EventName,
@ -27,6 +26,12 @@ import { TauriEvent } from "@tauri-apps/api/event";
// TODO: use from @tauri-apps/api v2 // TODO: use from @tauri-apps/api v2
import { emit, listen, once } from "./event"; import { emit, listen, once } from "./event";
declare global {
interface Window {
__TAURI_INVOKE__: <T>(cmd: string, args?: unknown) => Promise<T>;
}
}
type Theme = "light" | "dark"; type Theme = "light" | "dark";
type TitleBarStyle = "visible" | "transparent" | "overlay"; type TitleBarStyle = "visible" | "transparent" | "overlay";
@ -403,7 +408,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns The window's monitor scale factor. * @returns The window's monitor scale factor.
* */ * */
async scaleFactor(): Promise<number> { async scaleFactor(): Promise<number> {
return invoke("plugin:window|scale_factor", { return window.__TAURI_INVOKE__("plugin:window|scale_factor", {
label: this.label, label: this.label,
}); });
} }
@ -419,9 +424,14 @@ class WindowManager extends WebviewWindowHandle {
* @returns The window's inner position. * @returns The window's inner position.
* */ * */
async innerPosition(): Promise<PhysicalPosition> { async innerPosition(): Promise<PhysicalPosition> {
return invoke<{ x: number; y: number }>("plugin:window|inner_position", { return window
label: this.label, .__TAURI_INVOKE__<{ x: number; y: number }>(
}).then(({ x, y }) => new PhysicalPosition(x, y)); "plugin:window|inner_position",
{
label: this.label,
}
)
.then(({ x, y }) => new PhysicalPosition(x, y));
} }
/** /**
@ -435,9 +445,14 @@ class WindowManager extends WebviewWindowHandle {
* @returns The window's outer position. * @returns The window's outer position.
* */ * */
async outerPosition(): Promise<PhysicalPosition> { async outerPosition(): Promise<PhysicalPosition> {
return invoke<{ x: number; y: number }>("plugin:window|outer_position", { return window
label: this.label, .__TAURI_INVOKE__<{ x: number; y: number }>(
}).then(({ x, y }) => new PhysicalPosition(x, y)); "plugin:window|outer_position",
{
label: this.label,
}
)
.then(({ x, y }) => new PhysicalPosition(x, y));
} }
/** /**
@ -452,12 +467,14 @@ class WindowManager extends WebviewWindowHandle {
* @returns The window's inner size. * @returns The window's inner size.
*/ */
async innerSize(): Promise<PhysicalSize> { async innerSize(): Promise<PhysicalSize> {
return invoke<{ width: number; height: number }>( return window
"plugin:window|inner_size", .__TAURI_INVOKE__<{ width: number; height: number }>(
{ "plugin:window|inner_size",
label: this.label, {
} label: this.label,
).then(({ width, height }) => new PhysicalSize(width, height)); }
)
.then(({ width, height }) => new PhysicalSize(width, height));
} }
/** /**
@ -472,12 +489,14 @@ class WindowManager extends WebviewWindowHandle {
* @returns The window's outer size. * @returns The window's outer size.
*/ */
async outerSize(): Promise<PhysicalSize> { async outerSize(): Promise<PhysicalSize> {
return invoke<{ width: number; height: number }>( return window
"plugin:window|outer_size", .__TAURI_INVOKE__<{ width: number; height: number }>(
{ "plugin:window|outer_size",
label: this.label, {
} label: this.label,
).then(({ width, height }) => new PhysicalSize(width, height)); }
)
.then(({ width, height }) => new PhysicalSize(width, height));
} }
/** /**
@ -491,7 +510,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns Whether the window is in fullscreen mode or not. * @returns Whether the window is in fullscreen mode or not.
* */ * */
async isFullscreen(): Promise<boolean> { async isFullscreen(): Promise<boolean> {
return invoke("plugin:window|is_fullscreen", { return window.__TAURI_INVOKE__("plugin:window|is_fullscreen", {
label: this.label, label: this.label,
}); });
} }
@ -507,7 +526,7 @@ class WindowManager extends WebviewWindowHandle {
* @since 1.3.0 * @since 1.3.0
* */ * */
async isMinimized(): Promise<boolean> { async isMinimized(): Promise<boolean> {
return invoke("plugin:window|is_minimized", { return window.__TAURI_INVOKE__("plugin:window|is_minimized", {
label: this.label, label: this.label,
}); });
} }
@ -523,7 +542,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns Whether the window is maximized or not. * @returns Whether the window is maximized or not.
* */ * */
async isMaximized(): Promise<boolean> { async isMaximized(): Promise<boolean> {
return invoke("plugin:window|is_maximized", { return window.__TAURI_INVOKE__("plugin:window|is_maximized", {
label: this.label, label: this.label,
}); });
} }
@ -539,7 +558,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns Whether the window is decorated or not. * @returns Whether the window is decorated or not.
* */ * */
async isDecorated(): Promise<boolean> { async isDecorated(): Promise<boolean> {
return invoke("plugin:window|is_decorated", { return window.__TAURI_INVOKE__("plugin:window|is_decorated", {
label: this.label, label: this.label,
}); });
} }
@ -555,7 +574,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns Whether the window is resizable or not. * @returns Whether the window is resizable or not.
* */ * */
async isResizable(): Promise<boolean> { async isResizable(): Promise<boolean> {
return invoke("plugin:window|is_resizable", { return window.__TAURI_INVOKE__("plugin:window|is_resizable", {
label: this.label, label: this.label,
}); });
} }
@ -571,7 +590,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns Whether the window is visible or not. * @returns Whether the window is visible or not.
* */ * */
async isVisible(): Promise<boolean> { async isVisible(): Promise<boolean> {
return invoke("plugin:window|is_visible", { return window.__TAURI_INVOKE__("plugin:window|is_visible", {
label: this.label, label: this.label,
}); });
} }
@ -587,7 +606,7 @@ class WindowManager extends WebviewWindowHandle {
* @since 1.3.0 * @since 1.3.0
* */ * */
async title(): Promise<string> { async title(): Promise<string> {
return invoke("plugin:window|title", { return window.__TAURI_INVOKE__("plugin:window|title", {
label: this.label, label: this.label,
}); });
} }
@ -608,7 +627,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns The window theme. * @returns The window theme.
* */ * */
async theme(): Promise<Theme | null> { async theme(): Promise<Theme | null> {
return invoke("plugin:window|theme", { return window.__TAURI_INVOKE__("plugin:window|theme", {
label: this.label, label: this.label,
}); });
} }
@ -627,7 +646,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async center(): Promise<void> { async center(): Promise<void> {
return invoke("plugin:window|center", { return window.__TAURI_INVOKE__("plugin:window|center", {
label: this.label, label: this.label,
}); });
} }
@ -665,7 +684,7 @@ class WindowManager extends WebviewWindowHandle {
} }
} }
return invoke("plugin:window|request_user_attention", { return window.__TAURI_INVOKE__("plugin:window|request_user_attention", {
label: this.label, label: this.label,
value: requestType_, value: requestType_,
}); });
@ -683,7 +702,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setResizable(resizable: boolean): Promise<void> { async setResizable(resizable: boolean): Promise<void> {
return invoke("plugin:window|set_resizable", { return window.__TAURI_INVOKE__("plugin:window|set_resizable", {
label: this.label, label: this.label,
value: resizable, value: resizable,
}); });
@ -701,7 +720,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setTitle(title: string): Promise<void> { async setTitle(title: string): Promise<void> {
return invoke("plugin:window|set_title", { return window.__TAURI_INVOKE__("plugin:window|set_title", {
label: this.label, label: this.label,
value: title, value: title,
}); });
@ -718,7 +737,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async maximize(): Promise<void> { async maximize(): Promise<void> {
return invoke("plugin:window|maximize", { return window.__TAURI_INVOKE__("plugin:window|maximize", {
label: this.label, label: this.label,
}); });
} }
@ -734,7 +753,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async unmaximize(): Promise<void> { async unmaximize(): Promise<void> {
return invoke("plugin:window|unmaximize", { return window.__TAURI_INVOKE__("plugin:window|unmaximize", {
label: this.label, label: this.label,
}); });
} }
@ -750,7 +769,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async toggleMaximize(): Promise<void> { async toggleMaximize(): Promise<void> {
return invoke("plugin:window|toggle_maximize", { return window.__TAURI_INVOKE__("plugin:window|toggle_maximize", {
label: this.label, label: this.label,
}); });
} }
@ -766,7 +785,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async minimize(): Promise<void> { async minimize(): Promise<void> {
return invoke("plugin:window|minimize", { return window.__TAURI_INVOKE__("plugin:window|minimize", {
label: this.label, label: this.label,
}); });
} }
@ -782,7 +801,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async unminimize(): Promise<void> { async unminimize(): Promise<void> {
return invoke("plugin:window|unminimize", { return window.__TAURI_INVOKE__("plugin:window|unminimize", {
label: this.label, label: this.label,
}); });
} }
@ -798,7 +817,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async show(): Promise<void> { async show(): Promise<void> {
return invoke("plugin:window|show", { return window.__TAURI_INVOKE__("plugin:window|show", {
label: this.label, label: this.label,
}); });
} }
@ -814,7 +833,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async hide(): Promise<void> { async hide(): Promise<void> {
return invoke("plugin:window|hide", { return window.__TAURI_INVOKE__("plugin:window|hide", {
label: this.label, label: this.label,
}); });
} }
@ -830,7 +849,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async close(): Promise<void> { async close(): Promise<void> {
return invoke("plugin:window|close", { return window.__TAURI_INVOKE__("plugin:window|close", {
label: this.label, label: this.label,
}); });
} }
@ -847,7 +866,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setDecorations(decorations: boolean): Promise<void> { async setDecorations(decorations: boolean): Promise<void> {
return invoke("plugin:window|set_decorations", { return window.__TAURI_INVOKE__("plugin:window|set_decorations", {
label: this.label, label: this.label,
value: decorations, value: decorations,
}); });
@ -875,7 +894,7 @@ class WindowManager extends WebviewWindowHandle {
* @since 2.0 * @since 2.0
*/ */
async setShadow(enable: boolean): Promise<void> { async setShadow(enable: boolean): Promise<void> {
return invoke("plugin:window|set_shadow", { return window.__TAURI_INVOKE__("plugin:window|set_shadow", {
label: this.label, label: this.label,
value: enable, value: enable,
}); });
@ -893,7 +912,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setAlwaysOnTop(alwaysOnTop: boolean): Promise<void> { async setAlwaysOnTop(alwaysOnTop: boolean): Promise<void> {
return invoke("plugin:window|set_always_on_top", { return window.__TAURI_INVOKE__("plugin:window|set_always_on_top", {
label: this.label, label: this.label,
value: alwaysOnTop, value: alwaysOnTop,
}); });
@ -912,7 +931,7 @@ class WindowManager extends WebviewWindowHandle {
* @since 1.2.0 * @since 1.2.0
*/ */
async setContentProtected(protected_: boolean): Promise<void> { async setContentProtected(protected_: boolean): Promise<void> {
return invoke("plugin:window|set_content_protected", { return window.__TAURI_INVOKE__("plugin:window|set_content_protected", {
label: this.label, label: this.label,
value: protected_, value: protected_,
}); });
@ -936,7 +955,7 @@ class WindowManager extends WebviewWindowHandle {
); );
} }
return invoke("plugin:window|set_size", { return window.__TAURI_INVOKE__("plugin:window|set_size", {
label: this.label, label: this.label,
value: { value: {
type: size.type, type: size.type,
@ -968,7 +987,7 @@ class WindowManager extends WebviewWindowHandle {
); );
} }
return invoke("plugin:window|set_min_size", { return window.__TAURI_INVOKE__("plugin:window|set_min_size", {
label: this.label, label: this.label,
value: size value: size
? { ? {
@ -1002,7 +1021,7 @@ class WindowManager extends WebviewWindowHandle {
); );
} }
return invoke("plugin:window|set_max_size", { return window.__TAURI_INVOKE__("plugin:window|set_max_size", {
label: this.label, label: this.label,
value: size value: size
? { ? {
@ -1039,7 +1058,7 @@ class WindowManager extends WebviewWindowHandle {
); );
} }
return invoke("plugin:window|set_position", { return window.__TAURI_INVOKE__("plugin:window|set_position", {
label: this.label, label: this.label,
value: { value: {
type: position.type, type: position.type,
@ -1063,7 +1082,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setFullscreen(fullscreen: boolean): Promise<void> { async setFullscreen(fullscreen: boolean): Promise<void> {
return invoke("plugin:window|set_fullscreen", { return window.__TAURI_INVOKE__("plugin:window|set_fullscreen", {
label: this.label, label: this.label,
value: fullscreen, value: fullscreen,
}); });
@ -1080,7 +1099,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setFocus(): Promise<void> { async setFocus(): Promise<void> {
return invoke("plugin:window|set_focus", { return window.__TAURI_INVOKE__("plugin:window|set_focus", {
label: this.label, label: this.label,
}); });
} }
@ -1104,7 +1123,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setIcon(icon: string | Uint8Array): Promise<void> { async setIcon(icon: string | Uint8Array): Promise<void> {
return invoke("plugin:window|set_icon", { return window.__TAURI_INVOKE__("plugin:window|set_icon", {
label: this.label, label: this.label,
value: typeof icon === "string" ? icon : Array.from(icon), value: typeof icon === "string" ? icon : Array.from(icon),
}); });
@ -1126,7 +1145,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setSkipTaskbar(skip: boolean): Promise<void> { async setSkipTaskbar(skip: boolean): Promise<void> {
return invoke("plugin:window|set_skip_taskbar", { return window.__TAURI_INVOKE__("plugin:window|set_skip_taskbar", {
label: this.label, label: this.label,
value: skip, value: skip,
}); });
@ -1152,7 +1171,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setCursorGrab(grab: boolean): Promise<void> { async setCursorGrab(grab: boolean): Promise<void> {
return invoke("plugin:window|set_cursor_grab", { return window.__TAURI_INVOKE__("plugin:window|set_cursor_grab", {
label: this.label, label: this.label,
value: grab, value: grab,
}); });
@ -1176,7 +1195,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setCursorVisible(visible: boolean): Promise<void> { async setCursorVisible(visible: boolean): Promise<void> {
return invoke("plugin:window|set_cursor_visible", { return window.__TAURI_INVOKE__("plugin:window|set_cursor_visible", {
label: this.label, label: this.label,
value: visible, value: visible,
}); });
@ -1194,7 +1213,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setCursorIcon(icon: CursorIcon): Promise<void> { async setCursorIcon(icon: CursorIcon): Promise<void> {
return invoke("plugin:window|set_cursor_icon", { return window.__TAURI_INVOKE__("plugin:window|set_cursor_icon", {
label: this.label, label: this.label,
value: icon, value: icon,
}); });
@ -1223,7 +1242,7 @@ class WindowManager extends WebviewWindowHandle {
); );
} }
return invoke("plugin:window|set_cursor_position", { return window.__TAURI_INVOKE__("plugin:window|set_cursor_position", {
label: this.label, label: this.label,
value: { value: {
type: position.type, type: position.type,
@ -1248,7 +1267,7 @@ class WindowManager extends WebviewWindowHandle {
* @returns A promise indicating the success or failure of the operation. * @returns A promise indicating the success or failure of the operation.
*/ */
async setIgnoreCursorEvents(ignore: boolean): Promise<void> { async setIgnoreCursorEvents(ignore: boolean): Promise<void> {
return invoke("plugin:window|set_ignore_cursor_events", { return window.__TAURI_INVOKE__("plugin:window|set_ignore_cursor_events", {
label: this.label, label: this.label,
value: ignore, value: ignore,
}); });
@ -1265,7 +1284,7 @@ class WindowManager extends WebviewWindowHandle {
* @return A promise indicating the success or failure of the operation. * @return A promise indicating the success or failure of the operation.
*/ */
async startDragging(): Promise<void> { async startDragging(): Promise<void> {
return invoke("plugin:window|start_dragging", { return window.__TAURI_INVOKE__("plugin:window|start_dragging", {
label: this.label, label: this.label,
}); });
} }
@ -1622,12 +1641,13 @@ class WebviewWindow extends WindowManager {
super(label); super(label);
// @ts-expect-error `skip` is not a public API so it is not defined in WindowOptions // @ts-expect-error `skip` is not a public API so it is not defined in WindowOptions
if (!options?.skip) { if (!options?.skip) {
invoke("plugin:window|create", { window
options: { .__TAURI_INVOKE__("plugin:window|create", {
...options, options: {
label, ...options,
}, label,
}) },
})
.then(async () => this.emit("tauri://created")) .then(async () => this.emit("tauri://created"))
.catch(async (e: string) => this.emit("tauri://error", e)); .catch(async (e: string) => this.emit("tauri://error", e));
} }
@ -1813,9 +1833,9 @@ function mapPhysicalSize(m: PhysicalSize): PhysicalSize {
* @since 1.0.0 * @since 1.0.0
*/ */
async function currentMonitor(): Promise<Monitor | null> { async function currentMonitor(): Promise<Monitor | null> {
return invoke<Monitor | null>("plugin:window|current_monitor").then( return window
mapMonitor .__TAURI_INVOKE__<Monitor | null>("plugin:window|current_monitor")
); .then(mapMonitor);
} }
/** /**
@ -1830,9 +1850,9 @@ async function currentMonitor(): Promise<Monitor | null> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function primaryMonitor(): Promise<Monitor | null> { async function primaryMonitor(): Promise<Monitor | null> {
return invoke<Monitor | null>("plugin:window|primary_monitor").then( return window
mapMonitor .__TAURI_INVOKE__<Monitor | null>("plugin:window|primary_monitor")
); .then(mapMonitor);
} }
/** /**
@ -1846,9 +1866,9 @@ async function primaryMonitor(): Promise<Monitor | null> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function availableMonitors(): Promise<Monitor[]> { async function availableMonitors(): Promise<Monitor[]> {
return invoke<Monitor[]>("plugin:window|available_monitors").then( return window
(ms) => ms.map(mapMonitor) as Monitor[] .__TAURI_INVOKE__<Monitor[]>("plugin:window|available_monitors")
); .then((ms) => ms.map(mapMonitor) as Monitor[]);
} }
export { export {

File diff suppressed because one or more lines are too long

@ -11,18 +11,20 @@ use tauri::{
mod desktop_commands; mod desktop_commands;
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
let mut init_js = String::new(); let mut init_script = String::new();
// window.print works on Linux/Windows; need to use the API on macOS // window.print works on Linux/Windows; need to use the API on macOS
#[cfg(any(target_os = "macos", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "ios"))]
{ {
init_js.push_str(include_str!("./scripts/print.js")); init_script.push_str(include_str!("./scripts/print.js"));
} }
init_js.push_str(include_str!("./scripts/drag.js")); init_script.push_str(include_str!("./scripts/drag.js"));
#[cfg(any(debug_assertions, feature = "devtools"))] #[cfg(any(debug_assertions, feature = "devtools"))]
init_js.push_str(include_str!("./scripts/toggle-devtools.js")); init_script.push_str(include_str!("./scripts/toggle-devtools.js"));
init_script.push_str(include_str!("api-iife.js"));
Builder::new("window") Builder::new("window")
.js_init_script(init_js) .js_init_script(init_script)
.invoke_handler(|invoke| { .invoke_handler(|invoke| {
#[cfg(desktop)] #[cfg(desktop)]
{ {

@ -6,7 +6,7 @@ import { builtinModules } from "module";
import typescript from "@rollup/plugin-typescript"; import typescript from "@rollup/plugin-typescript";
import resolve from "@rollup/plugin-node-resolve"; import resolve from "@rollup/plugin-node-resolve";
// import terser from "@rollup/plugin-terser"; import terser from "@rollup/plugin-terser";
/** /**
* Create a base rollup config * Create a base rollup config
@ -15,6 +15,10 @@ import resolve from "@rollup/plugin-node-resolve";
* @returns {import('rollup').RollupOptions} * @returns {import('rollup').RollupOptions}
*/ */
export function createConfig({ input = "index.ts", pkg, external = [] }) { export function createConfig({ input = "index.ts", pkg, external = [] }) {
const pluginJsName = pkg.name
.replace("@tauri-apps/plugin-", "")
.replace(/-./g, (x) => x[1].toUpperCase());
const iifeVarName = `__TAURI_${pluginJsName.toUpperCase()}__`;
return [ return [
{ {
input, input,
@ -51,5 +55,28 @@ export function createConfig({ input = "index.ts", pkg, external = [] }) {
typescript({ sourceMap: true }), typescript({ sourceMap: true }),
], ],
}, },
{
input,
output: {
file: "src/api-iife.js",
format: "iife",
name: iifeVarName,
// IIFE is in the format `var ${iifeVarName} = (() => {})()`
// we check if __TAURI__ exists and inject the API object
banner: "if ('__TAURI__' in window) {",
// the last `}` closes the if in the banner
footer: `Object.defineProperty(window.__TAURI__, '${pluginJsName}', { value: ${iifeVarName} }) }`,
},
// and var is not guaranteed to assign to the global `window` object so we make sure to assign it
plugins: [
resolve(),
typescript({
sourceMap: false,
declaration: false,
declarationDir: undefined,
}),
terser(),
],
},
]; ];
} }

@ -39,6 +39,7 @@ impl<R: Runtime, T: Manager<R>> crate::{{ plugin_name_pascal_case }}Ext<R> for T
/// Initializes the plugin. /// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R> { pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("{{ plugin_name }}") Builder::new("{{ plugin_name }}")
.js_init_script(include_str!("api-iife.js").to_string())
.invoke_handler(tauri::generate_handler![commands::execute]) .invoke_handler(tauri::generate_handler![commands::execute])
.setup(|app, api| { .setup(|app, api| {
#[cfg(mobile)] #[cfg(mobile)]

Loading…
Cancel
Save