Run formatter on new plugins

pull/340/head^2
FabianLars 2 years ago
parent d0be006776
commit b730c34923
No known key found for this signature in database
GPG Key ID: 3B12BC1DEBF61125

@ -8,7 +8,7 @@
* @module * @module
*/ */
import { invoke } from '@tauri-apps/api/tauri'; import { invoke } from "@tauri-apps/api/tauri";
/** /**
* @since 1.0.0 * @since 1.0.0
@ -19,32 +19,32 @@ interface ArgMatch {
* boolean if flag * boolean if flag
* string[] or null if takes multiple values * string[] or null if takes multiple values
*/ */
value: string | boolean | string[] | null value: string | boolean | string[] | null;
/** /**
* Number of occurrences * Number of occurrences
*/ */
occurrences: number occurrences: number;
} }
/** /**
* @since 1.0.0 * @since 1.0.0
*/ */
interface SubcommandMatch { interface SubcommandMatch {
name: string name: string;
matches: CliMatches matches: CliMatches;
} }
/** /**
* @since 1.0.0 * @since 1.0.0
*/ */
interface CliMatches { interface CliMatches {
args: Record<string, ArgMatch> args: Record<string, ArgMatch>;
subcommand: SubcommandMatch | null subcommand: SubcommandMatch | null;
} }
/** /**
* Parse the arguments provided to the current process and get the matches using the configuration defined [`tauri.cli`](https://tauri.app/v1/api/config/#tauriconfig.cli) in `tauri.conf.json` * Parse the arguments provided to the current process and get the matches using the configuration defined [`tauri.cli`](https://tauri.app/v1/api/config/#tauriconfig.cli) in `tauri.conf.json`
* *
* @example * @example
* ```typescript * ```typescript
* import { getMatches } from 'tauri-plugin-cli-api'; * import { getMatches } from 'tauri-plugin-cli-api';
@ -64,9 +64,9 @@ 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 invoke("plugin:cli|cli_matches");
} }
export type { ArgMatch, SubcommandMatch, CliMatches } export type { ArgMatch, SubcommandMatch, CliMatches };
export { getMatches } export { getMatches };

@ -24,14 +24,14 @@
* @module * @module
*/ */
import { invoke } from '@tauri-apps/api/tauri' import { invoke } from "@tauri-apps/api/tauri";
interface Clip<K, T> { interface Clip<K, T> {
kind: K kind: K;
options: T options: T;
} }
type ClipResponse = Clip<'PlainText', string> type ClipResponse = Clip<"PlainText", string>;
/** /**
* Writes plain text to the clipboard. * Writes plain text to the clipboard.
@ -46,16 +46,19 @@ type ClipResponse = Clip<'PlainText', string>
* *
* @since 1.0.0. * @since 1.0.0.
*/ */
async function writeText(text: string, opts?: { label?: string }): Promise<void> { async function writeText(
return invoke('plugin:clipboard|write', { text: string,
opts?: { label?: string }
): Promise<void> {
return invoke("plugin:clipboard|write", {
data: { data: {
kind: 'PlainText', kind: "PlainText",
options: { options: {
label: opts?.label, label: opts?.label,
text text,
} },
} },
}) });
} }
/** /**
@ -68,8 +71,8 @@ async function writeText(text: string, opts?: { label?: string }): Promise<void>
* @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 invoke("plugin:clipboard|read");
return kind.options return kind.options;
} }
export { writeText, readText } export { writeText, readText };

@ -29,4 +29,4 @@
"dependencies": { "dependencies": {
"@tauri-apps/api": "^1.2.0" "@tauri-apps/api": "^1.2.0"
} }
} }

@ -19,4 +19,4 @@
"svelte": "^3.49.0", "svelte": "^3.49.0",
"vite": "^3.0.2" "vite": "^3.0.2"
} }
} }

@ -1,116 +1,116 @@
{ {
"images" : [ "images": [
{ {
"size" : "20x20", "size": "20x20",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "AppIcon-20x20@2x.png", "filename": "AppIcon-20x20@2x.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "20x20", "size": "20x20",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "AppIcon-20x20@3x.png", "filename": "AppIcon-20x20@3x.png",
"scale" : "3x" "scale": "3x"
}, },
{ {
"size" : "29x29", "size": "29x29",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "AppIcon-29x29@2x-1.png", "filename": "AppIcon-29x29@2x-1.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "29x29", "size": "29x29",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "AppIcon-29x29@3x.png", "filename": "AppIcon-29x29@3x.png",
"scale" : "3x" "scale": "3x"
}, },
{ {
"size" : "40x40", "size": "40x40",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "AppIcon-40x40@2x.png", "filename": "AppIcon-40x40@2x.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "40x40", "size": "40x40",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "AppIcon-40x40@3x.png", "filename": "AppIcon-40x40@3x.png",
"scale" : "3x" "scale": "3x"
}, },
{ {
"size" : "60x60", "size": "60x60",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "AppIcon-60x60@2x.png", "filename": "AppIcon-60x60@2x.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "60x60", "size": "60x60",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "AppIcon-60x60@3x.png", "filename": "AppIcon-60x60@3x.png",
"scale" : "3x" "scale": "3x"
}, },
{ {
"size" : "20x20", "size": "20x20",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-20x20@1x.png", "filename": "AppIcon-20x20@1x.png",
"scale" : "1x" "scale": "1x"
}, },
{ {
"size" : "20x20", "size": "20x20",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-20x20@2x-1.png", "filename": "AppIcon-20x20@2x-1.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "29x29", "size": "29x29",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-29x29@1x.png", "filename": "AppIcon-29x29@1x.png",
"scale" : "1x" "scale": "1x"
}, },
{ {
"size" : "29x29", "size": "29x29",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-29x29@2x.png", "filename": "AppIcon-29x29@2x.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "40x40", "size": "40x40",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-40x40@1x.png", "filename": "AppIcon-40x40@1x.png",
"scale" : "1x" "scale": "1x"
}, },
{ {
"size" : "40x40", "size": "40x40",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-40x40@2x-1.png", "filename": "AppIcon-40x40@2x-1.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "76x76", "size": "76x76",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-76x76@1x.png", "filename": "AppIcon-76x76@1x.png",
"scale" : "1x" "scale": "1x"
}, },
{ {
"size" : "76x76", "size": "76x76",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-76x76@2x.png", "filename": "AppIcon-76x76@2x.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "83.5x83.5", "size": "83.5x83.5",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "AppIcon-83.5x83.5@2x.png", "filename": "AppIcon-83.5x83.5@2x.png",
"scale" : "2x" "scale": "2x"
}, },
{ {
"size" : "1024x1024", "size": "1024x1024",
"idiom" : "ios-marketing", "idiom": "ios-marketing",
"filename" : "AppIcon-512@2x.png", "filename": "AppIcon-512@2x.png",
"scale" : "1x" "scale": "1x"
} }
], ],
"info" : { "info": {
"version" : 1, "version": 1,
"author" : "xcode" "author": "xcode"
} }
} }

@ -1,6 +1,6 @@
{ {
"info" : { "info": {
"version" : 1, "version": 1,
"author" : "xcode" "author": "xcode"
} }
} }

@ -60,7 +60,7 @@ targets:
base: base:
ENABLE_BITCODE: false ENABLE_BITCODE: false
ARCHS: [arm64, arm64-sim] ARCHS: [arm64, arm64-sim]
VALID_ARCHS: arm64 arm64-sim VALID_ARCHS: arm64 arm64-sim
LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64-sim]: $(inherited) $(PROJECT_DIR)/Externals/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) LIBRARY_SEARCH_PATHS[arch=arm64-sim]: $(inherited) $(PROJECT_DIR)/Externals/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
@ -82,4 +82,4 @@ targets:
basedOnDependencyAnalysis: false basedOnDependencyAnalysis: false
outputFiles: outputFiles:
- $(SRCROOT)/target/aarch64-apple-ios/${CONFIGURATION}/deps/libapp.a - $(SRCROOT)/target/aarch64-apple-ios/${CONFIGURATION}/deps/libapp.a
- $(SRCROOT)/target/x86_64-apple-ios/${CONFIGURATION}/deps/libapp.a - $(SRCROOT)/target/x86_64-apple-ios/${CONFIGURATION}/deps/libapp.a

@ -4,7 +4,11 @@ import { internalIpV4 } from "internal-ip";
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig(async () => { export default defineConfig(async () => {
const host = process.env.TAURI_PLATFORM === 'android' || process.env.TAURI_PLATFORM === 'ios' ? (await internalIpV4()) : 'localhost' const host =
process.env.TAURI_PLATFORM === "android" ||
process.env.TAURI_PLATFORM === "ios"
? await internalIpV4()
: "localhost";
return { return {
plugins: [svelte()], plugins: [svelte()],
@ -13,17 +17,17 @@ export default defineConfig(async () => {
clearScreen: false, clearScreen: false,
// tauri expects a fixed port, fail if that port is not available // tauri expects a fixed port, fail if that port is not available
server: { server: {
host: '0.0.0.0', host: "0.0.0.0",
port: 5173, port: 5173,
strictPort: true, strictPort: true,
hmr: { hmr: {
protocol: 'ws', protocol: "ws",
host, host,
port: 5183 port: 5183,
}, },
fs: { fs: {
allow: ['.', '../../tooling/api/dist'] allow: [".", "../../tooling/api/dist"],
} },
}, },
// to make use of `TAURI_DEBUG` and other env variables // to make use of `TAURI_DEBUG` and other env variables
// https://tauri.studio/v1/api/config#buildconfig.beforedevcommand // https://tauri.studio/v1/api/config#buildconfig.beforedevcommand
@ -36,5 +40,5 @@ export default defineConfig(async () => {
// produce sourcemaps for debug builds // produce sourcemaps for debug builds
sourcemap: !!process.env.TAURI_DEBUG, sourcemap: !!process.env.TAURI_DEBUG,
}, },
} };
}); });

@ -2,18 +2,18 @@
// 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 { invoke } from "@tauri-apps/api/tauri";
interface FileResponse { interface FileResponse {
base64Data?: string base64Data?: string;
duration?: number duration?: number;
height?: number height?: number;
width?: number width?: number;
mimeType?: string mimeType?: string;
modifiedAt?: number modifiedAt?: number;
name?: string name?: string;
path: string path: string;
size: number size: number;
} }
/** /**
@ -23,7 +23,7 @@ interface FileResponse {
*/ */
interface DialogFilter { interface DialogFilter {
/** Filter name. */ /** Filter name. */
name: string name: string;
/** /**
* Extensions to filter, without a `.` prefix. * Extensions to filter, without a `.` prefix.
* @example * @example
@ -31,7 +31,7 @@ interface DialogFilter {
* extensions: ['svg', 'png'] * extensions: ['svg', 'png']
* ``` * ```
*/ */
extensions: string[] extensions: string[];
} }
/** /**
@ -41,20 +41,20 @@ interface DialogFilter {
*/ */
interface OpenDialogOptions { interface OpenDialogOptions {
/** The title of the dialog window. */ /** The title of the dialog window. */
title?: string title?: string;
/** The filters of the dialog. */ /** The filters of the dialog. */
filters?: DialogFilter[] filters?: DialogFilter[];
/** Initial directory or file path. */ /** Initial directory or file path. */
defaultPath?: string defaultPath?: string;
/** Whether the dialog allows multiple selection or not. */ /** Whether the dialog allows multiple selection or not. */
multiple?: boolean multiple?: boolean;
/** Whether the dialog is a directory selection or not. */ /** Whether the dialog is a directory selection or not. */
directory?: boolean directory?: boolean;
/** /**
* If `directory` is true, indicates that it will be read recursively later. * If `directory` is true, indicates that it will be read recursively later.
* Defines whether subdirectories will be allowed on the scope or not. * Defines whether subdirectories will be allowed on the scope or not.
*/ */
recursive?: boolean recursive?: boolean;
} }
/** /**
@ -64,15 +64,15 @@ interface OpenDialogOptions {
*/ */
interface SaveDialogOptions { interface SaveDialogOptions {
/** The title of the dialog window. */ /** The title of the dialog window. */
title?: string title?: string;
/** The filters of the dialog. */ /** The filters of the dialog. */
filters?: DialogFilter[] filters?: DialogFilter[];
/** /**
* Initial directory or file path. * Initial directory or file path.
* If it's a directory path, the dialog interface will change to that folder. * If it's a directory path, the dialog interface will change to that folder.
* If it's not an existing directory, the file name will be set to the dialog's file name input and the dialog will be set to the parent folder. * If it's not an existing directory, the file name will be set to the dialog's file name input and the dialog will be set to the parent folder.
*/ */
defaultPath?: string defaultPath?: string;
} }
/** /**
@ -80,36 +80,36 @@ interface SaveDialogOptions {
*/ */
interface MessageDialogOptions { interface MessageDialogOptions {
/** The title of the dialog. Defaults to the app name. */ /** The title of the dialog. Defaults to the app name. */
title?: string title?: string;
/** The type of the dialog. Defaults to `info`. */ /** The type of the dialog. Defaults to `info`. */
type?: 'info' | 'warning' | 'error' type?: "info" | "warning" | "error";
/** The label of the confirm button. */ /** The label of the confirm button. */
okLabel?: string okLabel?: string;
} }
interface ConfirmDialogOptions { interface ConfirmDialogOptions {
/** The title of the dialog. Defaults to the app name. */ /** The title of the dialog. Defaults to the app name. */
title?: string title?: string;
/** The type of the dialog. Defaults to `info`. */ /** The type of the dialog. Defaults to `info`. */
type?: 'info' | 'warning' | 'error' type?: "info" | "warning" | "error";
/** The label of the confirm button. */ /** The label of the confirm button. */
okLabel?: string okLabel?: string;
/** The label of the cancel button. */ /** The label of the cancel button. */
cancelLabel?: string cancelLabel?: string;
} }
async function open( async function open(
options?: OpenDialogOptions & { multiple?: false, directory?: false } options?: OpenDialogOptions & { multiple?: false; directory?: false }
): Promise<null | FileResponse> ): Promise<null | FileResponse>;
async function open( async function open(
options?: OpenDialogOptions & { multiple?: true, directory?: false } options?: OpenDialogOptions & { multiple?: true; directory?: false }
): Promise<null | FileResponse[]> ): Promise<null | FileResponse[]>;
async function open( async function open(
options?: OpenDialogOptions & { multiple?: false, directory?: true } options?: OpenDialogOptions & { multiple?: false; directory?: true }
): Promise<null | string> ): Promise<null | string>;
async function open( async function open(
options?: OpenDialogOptions & { multiple?: true, directory?: true } options?: OpenDialogOptions & { multiple?: true; directory?: true }
): Promise<null | string[]> ): Promise<null | string[]>;
/** /**
* Open a file/directory selection dialog. * Open a file/directory selection dialog.
* *
@ -165,11 +165,11 @@ async function open(
async function open( async function open(
options: OpenDialogOptions = {} options: OpenDialogOptions = {}
): Promise<null | string | string[] | FileResponse | FileResponse[]> { ): Promise<null | string | string[] | FileResponse | FileResponse[]> {
if (typeof options === 'object') { if (typeof options === "object") {
Object.freeze(options) Object.freeze(options);
} }
return invoke('plugin:dialog|open', { options }) return invoke("plugin:dialog|open", { options });
} }
/** /**
@ -197,11 +197,11 @@ async function open(
* @since 1.0.0 * @since 1.0.0
*/ */
async function save(options: SaveDialogOptions = {}): Promise<string | null> { async function save(options: SaveDialogOptions = {}): Promise<string | null> {
if (typeof options === 'object') { if (typeof options === "object") {
Object.freeze(options) Object.freeze(options);
} }
return invoke('plugin:dialog|save', { options }) return invoke("plugin:dialog|save", { options });
} }
/** /**
@ -225,13 +225,13 @@ async function message(
message: string, message: string,
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 invoke("plugin:dialog|message", {
message: message.toString(), message: message.toString(),
title: opts?.title?.toString(), title: opts?.title?.toString(),
type_: opts?.type, type_: opts?.type,
okButtonLabel: opts?.okLabel?.toString() okButtonLabel: opts?.okLabel?.toString(),
}) });
} }
/** /**
@ -254,14 +254,14 @@ async function ask(
message: string, message: string,
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 invoke("plugin:dialog|ask", {
message: message.toString(), message: message.toString(),
title: opts?.title?.toString(), title: opts?.title?.toString(),
type_: opts?.type, type_: opts?.type,
okButtonLabel: opts?.okLabel?.toString() ?? 'Yes', okButtonLabel: opts?.okLabel?.toString() ?? "Yes",
cancelButtonLabel: opts?.cancelLabel?.toString() ?? 'No', cancelButtonLabel: opts?.cancelLabel?.toString() ?? "No",
}) });
} }
/** /**
@ -284,14 +284,14 @@ async function confirm(
message: string, message: string,
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 invoke("plugin:dialog|confirm", {
message: message.toString(), message: message.toString(),
title: opts?.title?.toString(), title: opts?.title?.toString(),
type_: opts?.type, type_: opts?.type,
okButtonLabel: opts?.okLabel?.toString() ?? 'Ok', okButtonLabel: opts?.okLabel?.toString() ?? "Ok",
cancelButtonLabel: opts?.cancelLabel?.toString() ?? 'Cancel', cancelButtonLabel: opts?.cancelLabel?.toString() ?? "Cancel",
}) });
} }
export type { export type {
@ -299,7 +299,7 @@ export type {
OpenDialogOptions, OpenDialogOptions,
SaveDialogOptions, SaveDialogOptions,
MessageDialogOptions, MessageDialogOptions,
ConfirmDialogOptions ConfirmDialogOptions,
} };
export { open, save, message, ask, confirm } export { open, save, message, ask, confirm };

@ -210,14 +210,14 @@ enum BaseDirectory {
Font, Font,
Home, Home,
Runtime, Runtime,
Template Template,
} }
/** /**
* @since 1.0.0 * @since 1.0.0
*/ */
interface FsOptions { interface FsOptions {
dir?: BaseDirectory dir?: BaseDirectory;
// note that adding fields here needs a change in the writeBinaryFile check // note that adding fields here needs a change in the writeBinaryFile check
} }
@ -225,8 +225,8 @@ interface FsOptions {
* @since 1.0.0 * @since 1.0.0
*/ */
interface FsDirOptions { interface FsDirOptions {
dir?: BaseDirectory dir?: BaseDirectory;
recursive?: boolean recursive?: boolean;
} }
/** /**
@ -236,12 +236,12 @@ interface FsDirOptions {
*/ */
interface FsTextFileOption { interface FsTextFileOption {
/** Path to the file to write. */ /** Path to the file to write. */
path: string path: string;
/** The UTF-8 string to write to the file. */ /** The UTF-8 string to write to the file. */
contents: string contents: string;
} }
type BinaryFileContents = Iterable<number> | ArrayLike<number> | ArrayBuffer type BinaryFileContents = Iterable<number> | ArrayLike<number> | ArrayBuffer;
/** /**
* Options object used to write a binary data to a file. * Options object used to write a binary data to a file.
@ -250,23 +250,23 @@ type BinaryFileContents = Iterable<number> | ArrayLike<number> | ArrayBuffer
*/ */
interface FsBinaryFileOption { interface FsBinaryFileOption {
/** Path to the file to write. */ /** Path to the file to write. */
path: string path: string;
/** The byte array contents. */ /** The byte array contents. */
contents: BinaryFileContents contents: BinaryFileContents;
} }
/** /**
* @since 1.0.0 * @since 1.0.0
*/ */
interface FileEntry { interface FileEntry {
path: string path: string;
/** /**
* Name of the directory/file * Name of the directory/file
* can be null if the path terminates with `..` * can be null if the path terminates with `..`
*/ */
name?: string name?: string;
/** Children of this entry if it's a directory; null otherwise */ /** Children of this entry if it's a directory; null otherwise */
children?: FileEntry[] children?: FileEntry[];
} }
/** /**
@ -286,8 +286,8 @@ async function readTextFile(
): Promise<string> { ): Promise<string> {
return await invoke("plugin:fs|read_text_file", { return await invoke("plugin:fs|read_text_file", {
path: filePath, path: filePath,
options options,
}) });
} }
/** /**
@ -307,10 +307,10 @@ async function readBinaryFile(
): Promise<Uint8Array> { ): Promise<Uint8Array> {
const arr = await invoke<number[]>("plugin:fs|read_file", { const arr = await invoke<number[]>("plugin:fs|read_file", {
path: filePath, path: filePath,
options options,
}) });
return Uint8Array.from(arr) return Uint8Array.from(arr);
} }
/** /**
@ -328,7 +328,7 @@ async function writeTextFile(
path: string, path: string,
contents: string, contents: string,
options?: FsOptions options?: FsOptions
): Promise<void> ): Promise<void>;
/** /**
* Writes a UTF-8 text file. * Writes a UTF-8 text file.
@ -345,7 +345,7 @@ async function writeTextFile(
async function writeTextFile( async function writeTextFile(
file: FsTextFileOption, file: FsTextFileOption,
options?: FsOptions options?: FsOptions
): Promise<void> ): Promise<void>;
/** /**
* Writes a UTF-8 text file. * Writes a UTF-8 text file.
@ -359,33 +359,33 @@ async function writeTextFile(
contents?: string | FsOptions, contents?: string | FsOptions,
options?: FsOptions options?: FsOptions
): Promise<void> { ): Promise<void> {
if (typeof options === 'object') { if (typeof options === "object") {
Object.freeze(options) Object.freeze(options);
} }
if (typeof path === 'object') { if (typeof path === "object") {
Object.freeze(path) Object.freeze(path);
} }
const file: FsTextFileOption = { path: '', contents: '' } const file: FsTextFileOption = { path: "", contents: "" };
let fileOptions: FsOptions | undefined = options let fileOptions: FsOptions | undefined = options;
if (typeof path === 'string') { if (typeof path === "string") {
file.path = path file.path = path;
} else { } else {
file.path = path.path file.path = path.path;
file.contents = path.contents file.contents = path.contents;
} }
if (typeof contents === 'string') { if (typeof contents === "string") {
file.contents = contents ?? '' file.contents = contents ?? "";
} else { } else {
fileOptions = contents fileOptions = contents;
} }
return await invoke("plugin:fs|write_file", { return await 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,
}) });
} }
/** /**
@ -406,7 +406,7 @@ async function writeBinaryFile(
path: string, path: string,
contents: BinaryFileContents, contents: BinaryFileContents,
options?: FsOptions options?: FsOptions
): Promise<void> ): Promise<void>;
/** /**
* Writes a byte array content to a file. * Writes a byte array content to a file.
@ -426,7 +426,7 @@ async function writeBinaryFile(
async function writeBinaryFile( async function writeBinaryFile(
file: FsBinaryFileOption, file: FsBinaryFileOption,
options?: FsOptions options?: FsOptions
): Promise<void> ): Promise<void>;
/** /**
* Writes a byte array content to a file. * Writes a byte array content to a file.
@ -440,27 +440,27 @@ async function writeBinaryFile(
contents?: BinaryFileContents | FsOptions, contents?: BinaryFileContents | FsOptions,
options?: FsOptions options?: FsOptions
): Promise<void> { ): Promise<void> {
if (typeof options === 'object') { if (typeof options === "object") {
Object.freeze(options) Object.freeze(options);
} }
if (typeof path === 'object') { if (typeof path === "object") {
Object.freeze(path) Object.freeze(path);
} }
const file: FsBinaryFileOption = { path: '', contents: [] } const file: FsBinaryFileOption = { path: "", contents: [] };
let fileOptions: FsOptions | undefined = options let fileOptions: FsOptions | undefined = options;
if (typeof path === 'string') { if (typeof path === "string") {
file.path = path file.path = path;
} else { } else {
file.path = path.path file.path = path.path;
file.contents = path.contents file.contents = path.contents;
} }
if (contents && 'dir' in contents) { if (contents && "dir" in contents) {
fileOptions = contents fileOptions = contents;
} else if (typeof path === 'string') { } else if (typeof path === "string") {
// @ts-expect-error in this case `contents` is always a BinaryFileContents // @ts-expect-error in this case `contents` is always a BinaryFileContents
file.contents = contents ?? [] file.contents = contents ?? [];
} }
return await invoke("plugin:fs|write_binary_file", { return await invoke("plugin:fs|write_binary_file", {
@ -470,8 +470,8 @@ async function writeBinaryFile(
? new Uint8Array(file.contents) ? new Uint8Array(file.contents)
: file.contents : file.contents
), ),
options: fileOptions options: fileOptions,
}) });
} }
/** /**
@ -500,8 +500,8 @@ async function readDir(
): Promise<FileEntry[]> { ): Promise<FileEntry[]> {
return await invoke("plugin:fs|read_dir", { return await invoke("plugin:fs|read_dir", {
path: dir, path: dir,
options options,
}) });
} }
/** /**
@ -525,8 +525,8 @@ async function createDir(
): Promise<void> { ): Promise<void> {
return await invoke("plugin:fs|create_dir", { return await invoke("plugin:fs|create_dir", {
path: dir, path: dir,
options options,
}) });
} }
/** /**
@ -549,8 +549,8 @@ async function removeDir(
): Promise<void> { ): Promise<void> {
return await invoke("plugin:fs|remove_dir", { return await invoke("plugin:fs|remove_dir", {
path: dir, path: dir,
options options,
}) });
} }
/** /**
@ -574,8 +574,8 @@ async function copyFile(
return await invoke("plugin:fs|copy_file", { return await invoke("plugin:fs|copy_file", {
source, source,
destination, destination,
options options,
}) });
} }
/** /**
@ -597,8 +597,8 @@ async function removeFile(
): Promise<void> { ): Promise<void> {
return await invoke("plugin:fs|remove_file", { return await invoke("plugin:fs|remove_file", {
path: file, path: file,
options options,
}) });
} }
/** /**
@ -622,9 +622,8 @@ async function renameFile(
return await invoke("plugin:fs|rename_file", { return await invoke("plugin:fs|rename_file", {
oldPath, oldPath,
newPath, newPath,
options options,
});
})
} }
/** /**
@ -644,7 +643,7 @@ async function exists(path: string): Promise<boolean> {
/** /**
* Returns the metadata for the given path. * Returns the metadata for the given path.
* *
* @since 1.0.0 * @since 1.0.0
*/ */
async function metadata(path: string): Promise<Metadata> { async function metadata(path: string): Promise<Metadata> {
@ -670,7 +669,7 @@ export type {
FileEntry, FileEntry,
Permissions, Permissions,
Metadata, Metadata,
} };
export { export {
BaseDirectory, BaseDirectory,
@ -687,5 +686,5 @@ export {
removeFile, removeFile,
renameFile, renameFile,
exists, exists,
metadata metadata,
} };

@ -21,9 +21,9 @@
* @module * @module
*/ */
import { invoke, transformCallback } from '@tauri-apps/api/tauri' import { invoke, transformCallback } from "@tauri-apps/api/tauri";
export type ShortcutHandler = (shortcut: string) => void export type ShortcutHandler = (shortcut: string) => void;
/** /**
* Register a global shortcut. * Register a global shortcut.
@ -44,10 +44,10 @@ async function register(
shortcut: string, shortcut: string,
handler: ShortcutHandler handler: ShortcutHandler
): Promise<void> { ): Promise<void> {
return await invoke('plugin:globalShortcut|register', { return await invoke("plugin:globalShortcut|register", {
shortcut, shortcut,
handler: transformCallback(handler) handler: transformCallback(handler),
}) });
} }
/** /**
@ -69,15 +69,15 @@ async function registerAll(
shortcuts: string[], shortcuts: string[],
handler: ShortcutHandler handler: ShortcutHandler
): Promise<void> { ): Promise<void> {
return await invoke('plugin:globalShortcut|register_all', { return await invoke("plugin:globalShortcut|register_all", {
shortcuts, shortcuts,
handler: transformCallback(handler) handler: transformCallback(handler),
}) });
} }
/** /**
* Determines whether the given shortcut is registered by this application or not. * Determines whether the given shortcut is registered by this application or not.
* *
* If the shortcut is registered by another application, it will still return `false`. * If the shortcut is registered by another application, it will still return `false`.
* *
* @example * @example
@ -91,9 +91,9 @@ 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 invoke("plugin:globalShortcut|is_registered", {
shortcut shortcut,
}) });
} }
/** /**
@ -109,9 +109,9 @@ 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 invoke("plugin:globalShortcut|unregister", {
shortcut shortcut,
}) });
} }
/** /**
@ -125,7 +125,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 invoke("plugin:globalShortcut|unregister_all");
} }
export { register, registerAll, isRegistered, unregister, unregisterAll } export { register, registerAll, isRegistered, unregister, unregisterAll };

@ -41,14 +41,14 @@
* @module * @module
*/ */
import { invoke } from '@tauri-apps/api/tauri' import { invoke } from "@tauri-apps/api/tauri";
/** /**
* @since 1.0.0 * @since 1.0.0
*/ */
interface Duration { interface Duration {
secs: number secs: number;
nanos: number nanos: number;
} }
/** /**
@ -59,8 +59,8 @@ interface ClientOptions {
* Defines the maximum number of redirects the client should follow. * Defines the maximum number of redirects the client should follow.
* If set to 0, no redirects will be followed. * If set to 0, no redirects will be followed.
*/ */
maxRedirections?: number maxRedirections?: number;
connectTimeout?: number | Duration connectTimeout?: number | Duration;
} }
/** /**
@ -69,19 +69,19 @@ interface ClientOptions {
enum ResponseType { enum ResponseType {
JSON = 1, JSON = 1,
Text = 2, Text = 2,
Binary = 3 Binary = 3,
} }
/** /**
* @since 1.0.0 * @since 1.0.0
*/ */
interface FilePart<T> { interface FilePart<T> {
file: string | T file: string | T;
mime?: string mime?: string;
fileName?: string fileName?: string;
} }
type Part = string | Uint8Array | FilePart<Uint8Array> type Part = string | Uint8Array | FilePart<Uint8Array>;
/** /**
* The body object to be used on POST and PUT requests. * The body object to be used on POST and PUT requests.
@ -89,13 +89,13 @@ type Part = string | Uint8Array | FilePart<Uint8Array>
* @since 1.0.0 * @since 1.0.0
*/ */
class Body { class Body {
type: string type: string;
payload: unknown payload: unknown;
/** @ignore */ /** @ignore */
private constructor(type: string, payload: unknown) { private constructor(type: string, payload: unknown) {
this.type = type this.type = type;
this.payload = payload this.payload = payload;
} }
/** /**
@ -130,39 +130,39 @@ class Body {
* @returns The body object ready to be used on the POST and PUT requests. * @returns The body object ready to be used on the POST and PUT requests.
*/ */
static form(data: Record<string, Part> | FormData): Body { static form(data: Record<string, Part> | FormData): Body {
const form: Record<string, string | number[] | FilePart<number[]>> = {} const form: Record<string, string | number[] | FilePart<number[]>> = {};
const append = ( const append = (
key: string, key: string,
v: string | Uint8Array | FilePart<Uint8Array> | File v: string | Uint8Array | FilePart<Uint8Array> | File
): void => { ): void => {
if (v !== null) { if (v !== null) {
let r let r;
if (typeof v === 'string') { if (typeof v === "string") {
r = v r = v;
} else if (v instanceof Uint8Array || Array.isArray(v)) { } else if (v instanceof Uint8Array || Array.isArray(v)) {
r = Array.from(v) r = Array.from(v);
} else if (v instanceof File) { } else if (v instanceof File) {
r = { file: v.name, mime: v.type, fileName: v.name } r = { file: v.name, mime: v.type, fileName: v.name };
} else if (typeof v.file === 'string') { } else if (typeof v.file === "string") {
r = { file: v.file, mime: v.mime, fileName: v.fileName } r = { file: v.file, mime: v.mime, fileName: v.fileName };
} else { } else {
r = { file: Array.from(v.file), mime: v.mime, fileName: v.fileName } r = { file: Array.from(v.file), mime: v.mime, fileName: v.fileName };
} }
form[String(key)] = r form[String(key)] = r;
} }
} };
if (data instanceof FormData) { if (data instanceof FormData) {
for (const [key, value] of data) { for (const [key, value] of data) {
append(key, value) append(key, value);
} }
} else { } else {
for (const [key, value] of Object.entries(data)) { for (const [key, value] of Object.entries(data)) {
append(key, value) append(key, value);
} }
} }
return new Body('Form', form) return new Body("Form", form);
} }
/** /**
@ -181,7 +181,7 @@ class Body {
* @returns The body object ready to be used on the POST and PUT requests. * @returns The body object ready to be used on the POST and PUT requests.
*/ */
static json<K extends string | number | symbol, V>(data: Record<K, V>): Body { static json<K extends string | number | symbol, V>(data: Record<K, V>): Body {
return new Body('Json', data) return new Body("Json", data);
} }
/** /**
@ -197,7 +197,7 @@ class Body {
* @returns The body object ready to be used on the POST and PUT requests. * @returns The body object ready to be used on the POST and PUT requests.
*/ */
static text(value: string): Body { static text(value: string): Body {
return new Body('Text', value) return new Body("Text", value);
} }
/** /**
@ -217,23 +217,23 @@ class Body {
): Body { ): Body {
// stringifying Uint8Array doesn't return an array of numbers, so we create one here // stringifying Uint8Array doesn't return an array of numbers, so we create one here
return new Body( return new Body(
'Bytes', "Bytes",
Array.from(bytes instanceof ArrayBuffer ? new Uint8Array(bytes) : bytes) Array.from(bytes instanceof ArrayBuffer ? new Uint8Array(bytes) : bytes)
) );
} }
} }
/** The request HTTP verb. */ /** The request HTTP verb. */
type HttpVerb = type HttpVerb =
| 'GET' | "GET"
| 'POST' | "POST"
| 'PUT' | "PUT"
| 'DELETE' | "DELETE"
| 'PATCH' | "PATCH"
| 'HEAD' | "HEAD"
| 'OPTIONS' | "OPTIONS"
| 'CONNECT' | "CONNECT"
| 'TRACE' | "TRACE";
/** /**
* Options object sent to the backend. * Options object sent to the backend.
@ -241,27 +241,27 @@ type HttpVerb =
* @since 1.0.0 * @since 1.0.0
*/ */
interface HttpOptions { interface HttpOptions {
method: HttpVerb method: HttpVerb;
url: string url: string;
headers?: Record<string, unknown> headers?: Record<string, unknown>;
query?: Record<string, unknown> query?: Record<string, unknown>;
body?: Body body?: Body;
timeout?: number | Duration timeout?: number | Duration;
responseType?: ResponseType responseType?: ResponseType;
} }
/** Request options. */ /** Request options. */
type RequestOptions = Omit<HttpOptions, 'method' | 'url'> type RequestOptions = Omit<HttpOptions, "method" | "url">;
/** Options for the `fetch` API. */ /** Options for the `fetch` API. */
type FetchOptions = Omit<HttpOptions, 'url'> type FetchOptions = Omit<HttpOptions, "url">;
/** @ignore */ /** @ignore */
interface IResponse<T> { interface IResponse<T> {
url: string url: string;
status: number status: number;
headers: Record<string, string> headers: Record<string, string>;
rawHeaders: Record<string, string[]> rawHeaders: Record<string, string[]>;
data: T data: T;
} }
/** /**
@ -271,26 +271,26 @@ interface IResponse<T> {
* */ * */
class Response<T> { class Response<T> {
/** The request URL. */ /** The request URL. */
url: string url: string;
/** The response status code. */ /** The response status code. */
status: number status: number;
/** A boolean indicating whether the response was successful (status in the range 200299) or not. */ /** A boolean indicating whether the response was successful (status in the range 200299) or not. */
ok: boolean ok: boolean;
/** The response headers. */ /** The response headers. */
headers: Record<string, string> headers: Record<string, string>;
/** The response raw headers. */ /** The response raw headers. */
rawHeaders: Record<string, string[]> rawHeaders: Record<string, string[]>;
/** The response data. */ /** The response data. */
data: T data: T;
/** @ignore */ /** @ignore */
constructor(response: IResponse<T>) { constructor(response: IResponse<T>) {
this.url = response.url this.url = response.url;
this.status = response.status this.status = response.status;
this.ok = this.status >= 200 && this.status < 300 this.ok = this.status >= 200 && this.status < 300;
this.headers = response.headers this.headers = response.headers;
this.rawHeaders = response.rawHeaders this.rawHeaders = response.rawHeaders;
this.data = response.data this.data = response.data;
} }
} }
@ -298,10 +298,10 @@ class Response<T> {
* @since 1.0.0 * @since 1.0.0
*/ */
class Client { class Client {
id: number id: number;
/** @ignore */ /** @ignore */
constructor(id: number) { constructor(id: number) {
this.id = id this.id = id;
} }
/** /**
@ -314,9 +314,9 @@ class Client {
* ``` * ```
*/ */
async drop(): Promise<void> { async drop(): Promise<void> {
return invoke('plugin:http|drop_client', { return invoke("plugin:http|drop_client", {
client: this.id client: this.id,
}) });
} }
/** /**
@ -333,34 +333,34 @@ class Client {
*/ */
async request<T>(options: HttpOptions): Promise<Response<T>> { async request<T>(options: HttpOptions): Promise<Response<T>> {
const jsonResponse = const jsonResponse =
!options.responseType || options.responseType === ResponseType.JSON !options.responseType || options.responseType === ResponseType.JSON;
if (jsonResponse) { if (jsonResponse) {
options.responseType = ResponseType.Text options.responseType = ResponseType.Text;
} }
return invoke<IResponse<T>>('plugin:http|request', { return invoke<IResponse<T>>("plugin:http|request", {
clientId: this.id, clientId: this.id,
options options,
}).then((res) => { }).then((res) => {
const response = new Response(res) const response = new Response(res);
if (jsonResponse) { if (jsonResponse) {
/* eslint-disable */ /* eslint-disable */
try { try {
response.data = JSON.parse(response.data as string) response.data = JSON.parse(response.data as string);
} catch (e) { } catch (e) {
if (response.ok && (response.data as unknown as string) === '') { if (response.ok && (response.data as unknown as string) === "") {
response.data = {} as T response.data = {} as T;
} else if (response.ok) { } else if (response.ok) {
throw Error( throw Error(
`Failed to parse response \`${response.data}\` as JSON: ${e}; `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 */ /* eslint-enable */
return response return response;
} }
return response return response;
}) });
} }
/** /**
@ -378,10 +378,10 @@ class Client {
*/ */
async get<T>(url: string, options?: RequestOptions): Promise<Response<T>> { async get<T>(url: string, options?: RequestOptions): Promise<Response<T>> {
return this.request({ return this.request({
method: 'GET', method: "GET",
url, url,
...options ...options,
}) });
} }
/** /**
@ -406,11 +406,11 @@ class Client {
options?: RequestOptions options?: RequestOptions
): Promise<Response<T>> { ): Promise<Response<T>> {
return this.request({ return this.request({
method: 'POST', method: "POST",
url, url,
body, body,
...options ...options,
}) });
} }
/** /**
@ -436,11 +436,11 @@ class Client {
options?: RequestOptions options?: RequestOptions
): Promise<Response<T>> { ): Promise<Response<T>> {
return this.request({ return this.request({
method: 'PUT', method: "PUT",
url, url,
body, body,
...options ...options,
}) });
} }
/** /**
@ -456,10 +456,10 @@ class Client {
*/ */
async patch<T>(url: string, options?: RequestOptions): Promise<Response<T>> { async patch<T>(url: string, options?: RequestOptions): Promise<Response<T>> {
return this.request({ return this.request({
method: 'PATCH', method: "PATCH",
url, url,
...options ...options,
}) });
} }
/** /**
@ -473,10 +473,10 @@ class Client {
*/ */
async delete<T>(url: string, options?: RequestOptions): Promise<Response<T>> { async delete<T>(url: string, options?: RequestOptions): Promise<Response<T>> {
return this.request({ return this.request({
method: 'DELETE', method: "DELETE",
url, url,
...options ...options,
}) });
} }
} }
@ -495,13 +495,13 @@ 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 invoke<number>("plugin:http|create_client", {
options options,
}).then((id) => new Client(id)) }).then((id) => new Client(id));
} }
/** @internal */ /** @internal */
let defaultClient: Client | null = null let defaultClient: Client | null = null;
/** /**
* Perform an HTTP request using the default client. * Perform an HTTP request using the default client.
@ -519,13 +519,13 @@ async function fetch<T>(
options?: FetchOptions options?: FetchOptions
): Promise<Response<T>> { ): Promise<Response<T>> {
if (defaultClient === null) { if (defaultClient === null) {
defaultClient = await getClient() defaultClient = await getClient();
} }
return defaultClient.request({ return defaultClient.request({
url, url,
method: options?.method ?? 'GET', method: options?.method ?? "GET",
...options ...options,
}) });
} }
export type { export type {
@ -535,7 +535,15 @@ export type {
HttpVerb, HttpVerb,
HttpOptions, HttpOptions,
RequestOptions, RequestOptions,
FetchOptions FetchOptions,
} };
export { getClient, fetch, Body, Client, Response, ResponseType, type FilePart } export {
getClient,
fetch,
Body,
Client,
Response,
ResponseType,
type FilePart,
};

@ -24,7 +24,7 @@
* @module * @module
*/ */
import { invoke } from '@tauri-apps/api/tauri' import { invoke } from "@tauri-apps/api/tauri";
/** /**
* Options to send a notification. * Options to send a notification.
@ -33,15 +33,15 @@ import { invoke } from '@tauri-apps/api/tauri'
*/ */
interface Options { interface Options {
/** Notification title. */ /** Notification title. */
title: string title: string;
/** Optional notification body. */ /** Optional notification body. */
body?: string body?: string;
/** Optional notification icon. */ /** Optional notification icon. */
icon?: string icon?: string;
} }
/** Possible permission values. */ /** Possible permission values. */
type Permission = 'granted' | 'denied' | 'default' type Permission = "granted" | "denied" | "default";
/** /**
* Checks if the permission to send notifications is granted. * Checks if the permission to send notifications is granted.
@ -54,10 +54,10 @@ type Permission = 'granted' | 'denied' | 'default'
* @since 1.0.0 * @since 1.0.0
*/ */
async function isPermissionGranted(): Promise<boolean> { async function isPermissionGranted(): Promise<boolean> {
if (window.Notification.permission !== 'default') { if (window.Notification.permission !== "default") {
return Promise.resolve(window.Notification.permission === 'granted') return Promise.resolve(window.Notification.permission === "granted");
} }
return invoke('plugin:notification|is_permission_granted') return invoke("plugin:notification|is_permission_granted");
} }
/** /**
@ -77,7 +77,7 @@ async function isPermissionGranted(): Promise<boolean> {
* @since 1.0.0 * @since 1.0.0
*/ */
async function requestPermission(): Promise<Permission> { async function requestPermission(): Promise<Permission> {
return window.Notification.requestPermission() return window.Notification.requestPermission();
} }
/** /**
@ -99,15 +99,15 @@ async function requestPermission(): Promise<Permission> {
* @since 1.0.0 * @since 1.0.0
*/ */
function sendNotification(options: Options | string): void { function sendNotification(options: Options | string): void {
if (typeof options === 'string') { if (typeof options === "string") {
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new window.Notification(options) new window.Notification(options);
} else { } else {
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new window.Notification(options.title, options) new window.Notification(options.title, options);
} }
} }
export type { Options, Permission } export type { Options, Permission };
export { sendNotification, requestPermission, isPermissionGranted } export { sendNotification, requestPermission, isPermissionGranted };

@ -1,71 +1,71 @@
(function () { (function () {
let permissionSettable = false let permissionSettable = false;
let permissionValue = 'default' let permissionValue = "default";
function isPermissionGranted() { function isPermissionGranted() {
if (window.Notification.permission !== 'default') { if (window.Notification.permission !== "default") {
return Promise.resolve(window.Notification.permission === 'granted') return Promise.resolve(window.Notification.permission === "granted");
} }
return __TAURI__.invoke('plugin:notification|is_permission_granted') return __TAURI__.invoke("plugin:notification|is_permission_granted");
} }
function setNotificationPermission(value) { function setNotificationPermission(value) {
permissionSettable = true permissionSettable = true;
// @ts-expect-error we can actually set this value on the webview // @ts-expect-error we can actually set this value on the webview
window.Notification.permission = value window.Notification.permission = value;
permissionSettable = false permissionSettable = false;
} }
function requestPermission() { function requestPermission() {
return __TAURI__.invoke('plugin:notification|request_permission') return __TAURI__
.invoke("plugin:notification|request_permission")
.then(function (permission) { .then(function (permission) {
setNotificationPermission(permission) setNotificationPermission(permission);
return permission return permission;
}) });
} }
function sendNotification(options) { function sendNotification(options) {
if (typeof options === 'object') { if (typeof options === "object") {
Object.freeze(options) Object.freeze(options);
} }
return __TAURI__.invoke('plugin:notification|notify', { return __TAURI__.invoke("plugin:notification|notify", {
options: typeof options === 'string' options:
? { typeof options === "string"
title: options ? {
} title: options,
: options }
}) : options,
});
} }
// @ts-expect-error unfortunately we can't implement the whole type, so we overwrite it with our own version // @ts-expect-error unfortunately we can't implement the whole type, so we overwrite it with our own version
window.Notification = function (title, options) { window.Notification = function (title, options) {
const opts = options || {} const opts = options || {};
sendNotification( sendNotification(Object.assign(opts, { title }));
Object.assign(opts, { title }) };
)
}
window.Notification.requestPermission = requestPermission window.Notification.requestPermission = requestPermission;
Object.defineProperty(window.Notification, 'permission', { Object.defineProperty(window.Notification, "permission", {
enumerable: true, enumerable: true,
get: function () { get: function () {
return permissionValue return permissionValue;
}, },
set: function (v) { set: function (v) {
if (!permissionSettable) { if (!permissionSettable) {
throw new Error('Readonly property') throw new Error("Readonly property");
} }
permissionValue = v permissionValue = v;
} },
}) });
isPermissionGranted().then(function (response) { isPermissionGranted().then(function (response) {
if (response === null) { if (response === null) {
setNotificationPermission('default') setNotificationPermission("default");
} else { } else {
setNotificationPermission(response ? 'granted' : 'denied') setNotificationPermission(response ? "granted" : "denied");
} }
}) });
})() })();

@ -75,27 +75,27 @@
* @module * @module
*/ */
import { invoke, transformCallback } from '@tauri-apps/api/tauri' import { invoke, transformCallback } from "@tauri-apps/api/tauri";
/** /**
* @since 1.0.0 * @since 1.0.0
*/ */
interface SpawnOptions { interface SpawnOptions {
/** Current working directory. */ /** Current working directory. */
cwd?: string cwd?: string;
/** Environment variables. set to `null` to clear the process env. */ /** Environment variables. set to `null` to clear the process env. */
env?: Record<string, string> env?: Record<string, string>;
/** /**
* Character encoding for stdout/stderr * Character encoding for stdout/stderr
* *
* @since 1.1.0 * @since 1.1.0
* */ * */
encoding?: string encoding?: string;
} }
/** @ignore */ /** @ignore */
interface InternalSpawnOptions extends SpawnOptions { interface InternalSpawnOptions extends SpawnOptions {
sidecar?: boolean sidecar?: boolean;
} }
/** /**
@ -103,13 +103,13 @@ interface InternalSpawnOptions extends SpawnOptions {
*/ */
interface ChildProcess<O extends IOPayload> { interface ChildProcess<O extends IOPayload> {
/** Exit code of the process. `null` if the process was terminated by a signal on Unix. */ /** Exit code of the process. `null` if the process was terminated by a signal on Unix. */
code: number | null code: number | null;
/** If the process was terminated by a signal, represents that signal. */ /** If the process was terminated by a signal, represents that signal. */
signal: number | null signal: number | null;
/** The data that the process wrote to `stdout`. */ /** The data that the process wrote to `stdout`. */
stdout: O stdout: O;
/** The data that the process wrote to `stderr`. */ /** The data that the process wrote to `stderr`. */
stderr: O stderr: O;
} }
/** /**
@ -128,16 +128,16 @@ async function execute<O extends IOPayload>(
args: string | string[] = [], args: string | string[] = [],
options?: InternalSpawnOptions options?: InternalSpawnOptions
): Promise<number> { ): Promise<number> {
if (typeof args === 'object') { if (typeof args === "object") {
Object.freeze(args) Object.freeze(args);
} }
return invoke<number>('plugin:shell|execute', { return invoke<number>("plugin:shell|execute", {
program, program,
args, args,
options, options,
onEventFn: transformCallback(onEvent) onEventFn: transformCallback(onEvent),
}) });
} }
/** /**
@ -147,7 +147,7 @@ class EventEmitter<E extends Record<string, any>> {
/** @ignore */ /** @ignore */
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
private eventListeners: Record<keyof E, Array<(arg: any) => void>> = private eventListeners: Record<keyof E, Array<(arg: any) => void>> =
Object.create(null) Object.create(null);
/** /**
* Alias for `emitter.on(eventName, listener)`. * Alias for `emitter.on(eventName, listener)`.
@ -158,7 +158,7 @@ class EventEmitter<E extends Record<string, any>> {
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void
): this { ): this {
return this.on(eventName, listener) return this.on(eventName, listener);
} }
/** /**
@ -170,7 +170,7 @@ class EventEmitter<E extends Record<string, any>> {
eventName: N, eventName: N,
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void
): this { ): this {
return this.off(eventName, listener) return this.off(eventName, listener);
} }
/** /**
@ -189,12 +189,12 @@ class EventEmitter<E extends Record<string, any>> {
): this { ): this {
if (eventName in this.eventListeners) { if (eventName in this.eventListeners) {
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
this.eventListeners[eventName].push(listener) this.eventListeners[eventName].push(listener);
} else { } else {
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
this.eventListeners[eventName] = [listener] this.eventListeners[eventName] = [listener];
} }
return this return this;
} }
/** /**
@ -210,11 +210,11 @@ class EventEmitter<E extends Record<string, any>> {
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void
): this { ): this {
const wrapper = (arg: E[typeof eventName]): void => { const wrapper = (arg: E[typeof eventName]): void => {
this.removeListener(eventName, wrapper) this.removeListener(eventName, wrapper);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
listener(arg) listener(arg);
} };
return this.addListener(eventName, wrapper) return this.addListener(eventName, wrapper);
} }
/** /**
@ -231,9 +231,9 @@ class EventEmitter<E extends Record<string, any>> {
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
this.eventListeners[eventName] = this.eventListeners[eventName].filter( this.eventListeners[eventName] = this.eventListeners[eventName].filter(
(l) => l !== listener (l) => l !== listener
) );
} }
return this return this;
} }
/** /**
@ -246,12 +246,12 @@ class EventEmitter<E extends Record<string, any>> {
removeAllListeners<N extends keyof E>(event?: N): this { removeAllListeners<N extends keyof E>(event?: N): this {
if (event) { if (event) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete,security/detect-object-injection // eslint-disable-next-line @typescript-eslint/no-dynamic-delete,security/detect-object-injection
delete this.eventListeners[event] delete this.eventListeners[event];
} else { } else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this.eventListeners = Object.create(null) this.eventListeners = Object.create(null);
} }
return this return this;
} }
/** /**
@ -264,12 +264,12 @@ class EventEmitter<E extends Record<string, any>> {
emit<N extends keyof E>(eventName: N, arg: E[typeof eventName]): boolean { emit<N extends keyof E>(eventName: N, arg: E[typeof eventName]): boolean {
if (eventName in this.eventListeners) { if (eventName in this.eventListeners) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,security/detect-object-injection // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,security/detect-object-injection
const listeners = this.eventListeners[eventName] const listeners = this.eventListeners[eventName];
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
for (const listener of listeners) listener(arg) for (const listener of listeners) listener(arg);
return true return true;
} }
return false return false;
} }
/** /**
@ -280,8 +280,8 @@ class EventEmitter<E extends Record<string, any>> {
listenerCount<N extends keyof E>(eventName: N): number { listenerCount<N extends keyof E>(eventName: N): number {
if (eventName in this.eventListeners) if (eventName in this.eventListeners)
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
return this.eventListeners[eventName].length return this.eventListeners[eventName].length;
return 0 return 0;
} }
/** /**
@ -300,12 +300,12 @@ class EventEmitter<E extends Record<string, any>> {
): this { ): this {
if (eventName in this.eventListeners) { if (eventName in this.eventListeners) {
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
this.eventListeners[eventName].unshift(listener) this.eventListeners[eventName].unshift(listener);
} else { } else {
// eslint-disable-next-line security/detect-object-injection // eslint-disable-next-line security/detect-object-injection
this.eventListeners[eventName] = [listener] this.eventListeners[eventName] = [listener];
} }
return this return this;
} }
/** /**
@ -321,11 +321,11 @@ class EventEmitter<E extends Record<string, any>> {
listener: (arg: E[typeof eventName]) => void listener: (arg: E[typeof eventName]) => void
): this { ): this {
const wrapper = (arg: any): void => { const wrapper = (arg: any): void => {
this.removeListener(eventName, wrapper) this.removeListener(eventName, wrapper);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
listener(arg) listener(arg);
} };
return this.prependListener(eventName, wrapper) return this.prependListener(eventName, wrapper);
} }
} }
@ -334,10 +334,10 @@ class EventEmitter<E extends Record<string, any>> {
*/ */
class Child { class Child {
/** The child process `pid`. */ /** The child process `pid`. */
pid: number pid: number;
constructor(pid: number) { constructor(pid: number) {
this.pid = pid this.pid = pid;
} }
/** /**
@ -356,11 +356,11 @@ 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 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),
}) });
} }
/** /**
@ -369,20 +369,20 @@ 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 invoke("plugin:shell|kill", {
cmd: 'killChild', cmd: "killChild",
pid: this.pid pid: this.pid,
}) });
} }
} }
interface CommandEvents { interface CommandEvents {
close: TerminatedPayload close: TerminatedPayload;
error: string error: string;
} }
interface OutputEvents<O extends IOPayload> { interface OutputEvents<O extends IOPayload> {
data: O data: O;
} }
/** /**
@ -408,15 +408,15 @@ interface OutputEvents<O extends IOPayload> {
*/ */
class Command<O extends IOPayload> extends EventEmitter<CommandEvents> { class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
/** @ignore Program to execute. */ /** @ignore Program to execute. */
private readonly program: string private readonly program: string;
/** @ignore Program arguments */ /** @ignore Program arguments */
private readonly args: string[] private readonly args: string[];
/** @ignore Spawn options. */ /** @ignore Spawn options. */
private readonly options: InternalSpawnOptions private readonly options: InternalSpawnOptions;
/** Event emitter for the `stdout`. Emits the `data` event. */ /** Event emitter for the `stdout`. Emits the `data` event. */
readonly stdout = new EventEmitter<OutputEvents<O>>() readonly stdout = new EventEmitter<OutputEvents<O>>();
/** Event emitter for the `stderr`. Emits the `data` event. */ /** Event emitter for the `stderr`. Emits the `data` event. */
readonly stderr = new EventEmitter<OutputEvents<O>>() readonly stderr = new EventEmitter<OutputEvents<O>>();
/** /**
* @ignore * @ignore
@ -432,23 +432,23 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
args: string | string[] = [], args: string | string[] = [],
options?: SpawnOptions options?: SpawnOptions
) { ) {
super() super();
this.program = program this.program = program;
this.args = typeof args === 'string' ? [args] : args this.args = typeof args === "string" ? [args] : args;
this.options = options ?? {} this.options = options ?? {};
} }
static create(program: string, args?: string | string[]): Command<string> static create(program: string, args?: string | string[]): Command<string>;
static create( static create(
program: string, program: string,
args?: string | string[], args?: string | string[],
options?: SpawnOptions & { encoding: 'raw' } options?: SpawnOptions & { encoding: "raw" }
): Command<Uint8Array> ): Command<Uint8Array>;
static create( static create(
program: string, program: string,
args?: string | string[], args?: string | string[],
options?: SpawnOptions options?: SpawnOptions
): Command<string> ): Command<string>;
/** /**
* Creates a command to execute the given program. * Creates a command to execute the given program.
@ -467,20 +467,20 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
args: string | string[] = [], args: string | string[] = [],
options?: SpawnOptions options?: SpawnOptions
): Command<O> { ): Command<O> {
return new Command(program, args, options) return new Command(program, args, options);
} }
static sidecar(program: string, args?: string | string[]): Command<string> static sidecar(program: string, args?: string | string[]): Command<string>;
static sidecar( static sidecar(
program: string, program: string,
args?: string | string[], args?: string | string[],
options?: SpawnOptions & { encoding: 'raw' } options?: SpawnOptions & { encoding: "raw" }
): Command<Uint8Array> ): Command<Uint8Array>;
static sidecar( static sidecar(
program: string, program: string,
args?: string | string[], args?: string | string[],
options?: SpawnOptions options?: SpawnOptions
): Command<string> ): Command<string>;
/** /**
* Creates a command to execute the given sidecar program. * Creates a command to execute the given sidecar program.
@ -499,9 +499,9 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
args: string | string[] = [], args: string | string[] = [],
options?: SpawnOptions options?: SpawnOptions
): Command<O> { ): Command<O> {
const instance = new Command<O>(program, args, options) const instance = new Command<O>(program, args, options);
instance.options.sidecar = true instance.options.sidecar = true;
return instance return instance;
} }
/** /**
@ -513,24 +513,24 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
return execute<O>( return execute<O>(
(event) => { (event) => {
switch (event.event) { switch (event.event) {
case 'Error': case "Error":
this.emit('error', event.payload) this.emit("error", event.payload);
break break;
case 'Terminated': case "Terminated":
this.emit('close', event.payload) this.emit("close", event.payload);
break break;
case 'Stdout': case "Stdout":
this.stdout.emit('data', event.payload) this.stdout.emit("data", event.payload);
break break;
case 'Stderr': case "Stderr":
this.stderr.emit('data', event.payload) this.stderr.emit("data", event.payload);
break break;
} }
}, },
this.program, this.program,
this.args, this.args,
this.options this.options
).then((pid) => new Child(pid)) ).then((pid) => new Child(pid));
} }
/** /**
@ -549,38 +549,38 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
*/ */
async execute(): Promise<ChildProcess<O>> { async execute(): Promise<ChildProcess<O>> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.on('error', reject) this.on("error", reject);
const stdout: O[] = [] const stdout: O[] = [];
const stderr: O[] = [] const stderr: O[] = [];
this.stdout.on('data', (line: O) => { this.stdout.on("data", (line: O) => {
stdout.push(line) stdout.push(line);
}) });
this.stderr.on('data', (line: O) => { this.stderr.on("data", (line: O) => {
stderr.push(line) stderr.push(line);
}) });
this.on('close', (payload: TerminatedPayload) => { this.on("close", (payload: TerminatedPayload) => {
resolve({ resolve({
code: payload.code, code: payload.code,
signal: payload.signal, signal: payload.signal,
stdout: this.collectOutput(stdout) as O, stdout: this.collectOutput(stdout) as O,
stderr: this.collectOutput(stderr) as O stderr: this.collectOutput(stderr) as O,
}) });
}) });
this.spawn().catch(reject) this.spawn().catch(reject);
}) });
} }
/** @ignore */ /** @ignore */
private collectOutput(events: O[]): string | Uint8Array { private collectOutput(events: O[]): string | Uint8Array {
if (this.options.encoding === 'raw') { if (this.options.encoding === "raw") {
return events.reduce<Uint8Array>((p, c) => { return events.reduce<Uint8Array>((p, c) => {
return new Uint8Array([...p, ...(c as Uint8Array), 10]) return new Uint8Array([...p, ...(c as Uint8Array), 10]);
}, new Uint8Array()) }, new Uint8Array());
} else { } else {
return events.join('\n') return events.join("\n");
} }
} }
} }
@ -589,8 +589,8 @@ class Command<O extends IOPayload> extends EventEmitter<CommandEvents> {
* Describes the event message received from the command. * Describes the event message received from the command.
*/ */
interface Event<T, V> { interface Event<T, V> {
event: T event: T;
payload: V payload: V;
} }
/** /**
@ -598,20 +598,20 @@ interface Event<T, V> {
*/ */
interface TerminatedPayload { interface TerminatedPayload {
/** Exit code of the process. `null` if the process was terminated by a signal on Unix. */ /** Exit code of the process. `null` if the process was terminated by a signal on Unix. */
code: number | null code: number | null;
/** If the process was terminated by a signal, represents that signal. */ /** If the process was terminated by a signal, represents that signal. */
signal: number | null signal: number | null;
} }
/** Event payload type */ /** Event payload type */
type IOPayload = string | Uint8Array type IOPayload = string | Uint8Array;
/** Events emitted by the child process. */ /** Events emitted by the child process. */
type CommandEvent<O extends IOPayload> = type CommandEvent<O extends IOPayload> =
| Event<'Stdout', O> | Event<"Stdout", O>
| Event<'Stderr', O> | Event<"Stderr", O>
| Event<'Terminated', TerminatedPayload> | Event<"Terminated", TerminatedPayload>
| Event<'Error', string> | Event<"Error", string>;
/** /**
* Opens a path or URL with the system's default app, * Opens a path or URL with the system's default app,
@ -640,18 +640,18 @@ 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 invoke("plugin:shell|open", {
path, path,
with: openWith with: openWith,
}) });
} }
export { Command, Child, EventEmitter, open } export { Command, Child, EventEmitter, open };
export type { export type {
IOPayload, IOPayload,
CommandEvents, CommandEvents,
TerminatedPayload, TerminatedPayload,
OutputEvents, OutputEvents,
ChildProcess, ChildProcess,
SpawnOptions SpawnOptions,
} };

@ -29,4 +29,4 @@
"dependencies": { "dependencies": {
"@tauri-apps/api": "^1.2.0" "@tauri-apps/api": "^1.2.0"
} }
} }

@ -1,20 +1,20 @@
{ {
"compilerOptions": { "compilerOptions": {
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"esModuleInterop": true, "esModuleInterop": true,
"lib": ["ES2019", "ES2020.Promise", "ES2020.String", "DOM", "DOM.Iterable"], "lib": ["ES2019", "ES2020.Promise", "ES2020.String", "DOM", "DOM.Iterable"],
"module": "ESNext", "module": "ESNext",
"moduleResolution": "node", "moduleResolution": "node",
"noEmit": true, "noEmit": true,
"noEmitOnError": false, "noEmitOnError": false,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"pretty": true, "pretty": true,
"sourceMap": true, "sourceMap": true,
"strict": true, "strict": true,
"target": "ES2019", "target": "ES2019",
"declaration": true, "declaration": true,
"declarationDir": "./" "declarationDir": "./"
}, },
"exclude": ["dist-js", "node_modules", "test/types"] "exclude": ["dist-js", "node_modules", "test/types"]
} }

Loading…
Cancel
Save