diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 1b0b469..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/.tauri diff --git a/Cargo.toml b/Cargo.toml index bd5d1bd..d226fa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,11 +10,11 @@ repository = { workspace = true } links = "tauri-plugin-shell" [package.metadata.docs.rs] -rustc-args = [ "--cfg", "docsrs" ] -rustdoc-args = [ "--cfg", "docsrs" ] +rustc-args = ["--cfg", "docsrs"] +rustdoc-args = ["--cfg", "docsrs"] [build-dependencies] -tauri-plugin = { workspace = true, features = [ "build" ] } +tauri-plugin = { workspace = true, features = ["build"] } schemars = { workspace = true } serde = { workspace = true } diff --git a/README.md b/README.md index 2881f2c..2513764 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ fn main() { Afterwards all the plugin's APIs are available through the JavaScript guest bindings: ```javascript -import { Command } from "@tauri-apps/plugin-shell"; -Command.create("git", ["commit", "-m", "the commit message"]); +import { Command } from '@tauri-apps/plugin-shell' +Command.create('git', ['commit', '-m', 'the commit message']) ``` ## Contributing diff --git a/SECURITY.md b/SECURITY.md index 67d831f..4f09bba 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -20,4 +20,4 @@ We prefer to receive reports in English. Please disclose a vulnerability or security relevant issue here: [https://github.com/tauri-apps/plugins-workspace/security/advisories/new](https://github.com/tauri-apps/plugins-workspace/security/advisories/new). -Alternatively, you can also contact us by email via [security@tauri.app](mailto:security@tauri.app). \ No newline at end of file +Alternatively, you can also contact us by email via [security@tauri.app](mailto:security@tauri.app). diff --git a/dist-js/index.cjs b/dist-js/index.cjs index fe101f2..bb3ff92 100644 --- a/dist-js/index.cjs +++ b/dist-js/index.cjs @@ -252,9 +252,9 @@ class Child { * @since 2.0.0 */ async write(data) { - await core.invoke("plugin:shell|stdin_write", { + await core.invoke('plugin:shell|stdin_write', { pid: this.pid, - buffer: data, + buffer: data }); } /** @@ -265,9 +265,9 @@ class Child { * @since 2.0.0 */ async kill() { - await core.invoke("plugin:shell|kill", { - cmd: "killChild", - pid: this.pid, + await core.invoke('plugin:shell|kill', { + cmd: 'killChild', + pid: this.pid }); } } @@ -309,7 +309,7 @@ class Command extends EventEmitter { /** Event emitter for the `stderr`. Emits the `data` event. */ this.stderr = new EventEmitter(); this.program = program; - this.args = typeof args === "string" ? [args] : args; + this.args = typeof args === 'string' ? [args] : args; this.options = options ?? {}; } /** @@ -355,31 +355,31 @@ class Command extends EventEmitter { const program = this.program; const args = this.args; const options = this.options; - if (typeof args === "object") { + if (typeof args === 'object') { Object.freeze(args); } const onEvent = new core.Channel(); onEvent.onmessage = (event) => { switch (event.event) { - case "Error": - this.emit("error", event.payload); + case 'Error': + this.emit('error', event.payload); break; - case "Terminated": - this.emit("close", event.payload); + case 'Terminated': + this.emit('close', event.payload); break; - case "Stdout": - this.stdout.emit("data", event.payload); + case 'Stdout': + this.stdout.emit('data', event.payload); break; - case "Stderr": - this.stderr.emit("data", event.payload); + case 'Stderr': + this.stderr.emit('data', event.payload); break; } }; - return await core.invoke("plugin:shell|spawn", { + return await core.invoke('plugin:shell|spawn', { program, args, options, - onEvent, + onEvent }).then((pid) => new Child(pid)); } /** @@ -402,13 +402,13 @@ class Command extends EventEmitter { const program = this.program; const args = this.args; const options = this.options; - if (typeof args === "object") { + if (typeof args === 'object') { Object.freeze(args); } - return await core.invoke("plugin:shell|execute", { + return await core.invoke('plugin:shell|execute', { program, args, - options, + options }); } } @@ -439,9 +439,9 @@ class Command extends EventEmitter { * @since 2.0.0 */ async function open(path, openWith) { - await core.invoke("plugin:shell|open", { + await core.invoke('plugin:shell|open', { path, - with: openWith, + with: openWith }); } diff --git a/dist-js/index.d.ts b/dist-js/index.d.ts index 0eff079..8a45448 100644 --- a/dist-js/index.d.ts +++ b/dist-js/index.d.ts @@ -201,12 +201,12 @@ declare class Command extends EventEmitter { private constructor(); static create(program: string, args?: string | string[]): Command; static create(program: string, args?: string | string[], options?: SpawnOptions & { - encoding: "raw"; + encoding: 'raw'; }): Command; static create(program: string, args?: string | string[], options?: SpawnOptions): Command; static sidecar(program: string, args?: string | string[]): Command; static sidecar(program: string, args?: string | string[], options?: SpawnOptions & { - encoding: "raw"; + encoding: 'raw'; }): Command; static sidecar(program: string, args?: string | string[], options?: SpawnOptions): Command; /** @@ -274,4 +274,4 @@ type IOPayload = string | Uint8Array; */ declare function open(path: string, openWith?: string): Promise; export { Command, Child, EventEmitter, open }; -export type { IOPayload, CommandEvents, TerminatedPayload, OutputEvents, ChildProcess, SpawnOptions, }; +export type { IOPayload, CommandEvents, TerminatedPayload, OutputEvents, ChildProcess, SpawnOptions }; diff --git a/dist-js/index.js b/dist-js/index.js index e5a38f2..bcbe0c1 100644 --- a/dist-js/index.js +++ b/dist-js/index.js @@ -250,9 +250,9 @@ class Child { * @since 2.0.0 */ async write(data) { - await invoke("plugin:shell|stdin_write", { + await invoke('plugin:shell|stdin_write', { pid: this.pid, - buffer: data, + buffer: data }); } /** @@ -263,9 +263,9 @@ class Child { * @since 2.0.0 */ async kill() { - await invoke("plugin:shell|kill", { - cmd: "killChild", - pid: this.pid, + await invoke('plugin:shell|kill', { + cmd: 'killChild', + pid: this.pid }); } } @@ -307,7 +307,7 @@ class Command extends EventEmitter { /** Event emitter for the `stderr`. Emits the `data` event. */ this.stderr = new EventEmitter(); this.program = program; - this.args = typeof args === "string" ? [args] : args; + this.args = typeof args === 'string' ? [args] : args; this.options = options ?? {}; } /** @@ -353,31 +353,31 @@ class Command extends EventEmitter { const program = this.program; const args = this.args; const options = this.options; - if (typeof args === "object") { + if (typeof args === 'object') { Object.freeze(args); } const onEvent = new Channel(); onEvent.onmessage = (event) => { switch (event.event) { - case "Error": - this.emit("error", event.payload); + case 'Error': + this.emit('error', event.payload); break; - case "Terminated": - this.emit("close", event.payload); + case 'Terminated': + this.emit('close', event.payload); break; - case "Stdout": - this.stdout.emit("data", event.payload); + case 'Stdout': + this.stdout.emit('data', event.payload); break; - case "Stderr": - this.stderr.emit("data", event.payload); + case 'Stderr': + this.stderr.emit('data', event.payload); break; } }; - return await invoke("plugin:shell|spawn", { + return await invoke('plugin:shell|spawn', { program, args, options, - onEvent, + onEvent }).then((pid) => new Child(pid)); } /** @@ -400,13 +400,13 @@ class Command extends EventEmitter { const program = this.program; const args = this.args; const options = this.options; - if (typeof args === "object") { + if (typeof args === 'object') { Object.freeze(args); } - return await invoke("plugin:shell|execute", { + return await invoke('plugin:shell|execute', { program, args, - options, + options }); } } @@ -437,9 +437,9 @@ class Command extends EventEmitter { * @since 2.0.0 */ async function open(path, openWith) { - await invoke("plugin:shell|open", { + await invoke('plugin:shell|open', { path, - with: openWith, + with: openWith }); } diff --git a/guest-js/index.ts b/guest-js/index.ts index ad90aeb..1ed2ac5 100644 --- a/guest-js/index.ts +++ b/guest-js/index.ts @@ -63,27 +63,27 @@ * @module */ -import { invoke, Channel } from "@tauri-apps/api/core"; +import { invoke, Channel } from '@tauri-apps/api/core' /** * @since 2.0.0 */ interface SpawnOptions { /** Current working directory. */ - cwd?: string; + cwd?: string /** Environment variables. set to `null` to clear the process env. */ - env?: Record; + env?: Record /** * Character encoding for stdout/stderr * * @since 2.0.0 * */ - encoding?: string; + encoding?: string } /** @ignore */ interface InternalSpawnOptions extends SpawnOptions { - sidecar?: boolean; + sidecar?: boolean } /** @@ -91,13 +91,13 @@ interface InternalSpawnOptions extends SpawnOptions { */ interface ChildProcess { /** 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. */ - signal: number | null; + signal: number | null /** The data that the process wrote to `stdout`. */ - stdout: O; + stdout: O /** The data that the process wrote to `stderr`. */ - stderr: O; + stderr: O } /** @@ -108,7 +108,7 @@ class EventEmitter> { /** @ignore */ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any private eventListeners: Record void>> = - Object.create(null); + Object.create(null) /** * Alias for `emitter.on(eventName, listener)`. @@ -117,9 +117,9 @@ class EventEmitter> { */ addListener( eventName: N, - listener: (arg: E[typeof eventName]) => void, + listener: (arg: E[typeof eventName]) => void ): this { - return this.on(eventName, listener); + return this.on(eventName, listener) } /** @@ -129,9 +129,9 @@ class EventEmitter> { */ removeListener( eventName: N, - listener: (arg: E[typeof eventName]) => void, + listener: (arg: E[typeof eventName]) => void ): this { - return this.off(eventName, listener); + return this.off(eventName, listener) } /** @@ -146,16 +146,16 @@ class EventEmitter> { */ on( eventName: N, - listener: (arg: E[typeof eventName]) => void, + listener: (arg: E[typeof eventName]) => void ): this { if (eventName in this.eventListeners) { // eslint-disable-next-line security/detect-object-injection - this.eventListeners[eventName].push(listener); + this.eventListeners[eventName].push(listener) } else { // eslint-disable-next-line security/detect-object-injection - this.eventListeners[eventName] = [listener]; + this.eventListeners[eventName] = [listener] } - return this; + return this } /** @@ -168,13 +168,13 @@ class EventEmitter> { */ once( eventName: N, - listener: (arg: E[typeof eventName]) => void, + listener: (arg: E[typeof eventName]) => void ): this { const wrapper = (arg: E[typeof eventName]): void => { - this.removeListener(eventName, wrapper); - listener(arg); - }; - return this.addListener(eventName, wrapper); + this.removeListener(eventName, wrapper) + listener(arg) + } + return this.addListener(eventName, wrapper) } /** @@ -185,15 +185,15 @@ class EventEmitter> { */ off( eventName: N, - listener: (arg: E[typeof eventName]) => void, + listener: (arg: E[typeof eventName]) => void ): this { if (eventName in this.eventListeners) { // eslint-disable-next-line security/detect-object-injection this.eventListeners[eventName] = this.eventListeners[eventName].filter( - (l) => l !== listener, - ); + (l) => l !== listener + ) } - return this; + return this } /** @@ -206,12 +206,12 @@ class EventEmitter> { removeAllListeners(event?: N): this { if (event) { // eslint-disable-next-line security/detect-object-injection - delete this.eventListeners[event]; + delete this.eventListeners[event] } else { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - this.eventListeners = Object.create(null); + this.eventListeners = Object.create(null) } - return this; + return this } /** @@ -226,11 +226,11 @@ class EventEmitter> { emit(eventName: N, arg: E[typeof eventName]): boolean { if (eventName in this.eventListeners) { // eslint-disable-next-line security/detect-object-injection - const listeners = this.eventListeners[eventName]; - for (const listener of listeners) listener(arg); - return true; + const listeners = this.eventListeners[eventName] + for (const listener of listeners) listener(arg) + return true } - return false; + return false } /** @@ -241,8 +241,8 @@ class EventEmitter> { listenerCount(eventName: N): number { if (eventName in this.eventListeners) // eslint-disable-next-line security/detect-object-injection - return this.eventListeners[eventName].length; - return 0; + return this.eventListeners[eventName].length + return 0 } /** @@ -257,16 +257,16 @@ class EventEmitter> { */ prependListener( eventName: N, - listener: (arg: E[typeof eventName]) => void, + listener: (arg: E[typeof eventName]) => void ): this { if (eventName in this.eventListeners) { // eslint-disable-next-line security/detect-object-injection - this.eventListeners[eventName].unshift(listener); + this.eventListeners[eventName].unshift(listener) } else { // eslint-disable-next-line security/detect-object-injection - this.eventListeners[eventName] = [listener]; + this.eventListeners[eventName] = [listener] } - return this; + return this } /** @@ -279,15 +279,15 @@ class EventEmitter> { */ prependOnceListener( eventName: N, - listener: (arg: E[typeof eventName]) => void, + listener: (arg: E[typeof eventName]) => void ): this { // eslint-disable-next-line @typescript-eslint/no-explicit-any const wrapper = (arg: any): void => { - this.removeListener(eventName, wrapper); + this.removeListener(eventName, wrapper) // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - listener(arg); - }; - return this.prependListener(eventName, wrapper); + listener(arg) + } + return this.prependListener(eventName, wrapper) } } @@ -296,10 +296,10 @@ class EventEmitter> { */ class Child { /** The child process `pid`. */ - pid: number; + pid: number constructor(pid: number) { - this.pid = pid; + this.pid = pid } /** @@ -320,10 +320,10 @@ class Child { * @since 2.0.0 */ async write(data: IOPayload | number[]): Promise { - await invoke("plugin:shell|stdin_write", { + await invoke('plugin:shell|stdin_write', { pid: this.pid, - buffer: data, - }); + buffer: data + }) } /** @@ -334,20 +334,20 @@ class Child { * @since 2.0.0 */ async kill(): Promise { - await invoke("plugin:shell|kill", { - cmd: "killChild", - pid: this.pid, - }); + await invoke('plugin:shell|kill', { + cmd: 'killChild', + pid: this.pid + }) } } interface CommandEvents { - close: TerminatedPayload; - error: string; + close: TerminatedPayload + error: string } interface OutputEvents { - data: O; + data: O } /** @@ -373,15 +373,15 @@ interface OutputEvents { */ class Command extends EventEmitter { /** @ignore Program to execute. */ - private readonly program: string; + private readonly program: string /** @ignore Program arguments */ - private readonly args: string[]; + private readonly args: string[] /** @ignore Spawn options. */ - private readonly options: InternalSpawnOptions; + private readonly options: InternalSpawnOptions /** Event emitter for the `stdout`. Emits the `data` event. */ - readonly stdout = new EventEmitter>(); + readonly stdout = new EventEmitter>() /** Event emitter for the `stderr`. Emits the `data` event. */ - readonly stderr = new EventEmitter>(); + readonly stderr = new EventEmitter>() /** * @ignore @@ -395,25 +395,25 @@ class Command extends EventEmitter { private constructor( program: string, args: string | string[] = [], - options?: SpawnOptions, + options?: SpawnOptions ) { - super(); - this.program = program; - this.args = typeof args === "string" ? [args] : args; - this.options = options ?? {}; + super() + this.program = program + this.args = typeof args === 'string' ? [args] : args + this.options = options ?? {} } - static create(program: string, args?: string | string[]): Command; + static create(program: string, args?: string | string[]): Command static create( program: string, args?: string | string[], - options?: SpawnOptions & { encoding: "raw" }, - ): Command; + options?: SpawnOptions & { encoding: 'raw' } + ): Command static create( program: string, args?: string | string[], - options?: SpawnOptions, - ): Command; + options?: SpawnOptions + ): Command /** * Creates a command to execute the given program. @@ -430,22 +430,22 @@ class Command extends EventEmitter { static create( program: string, args: string | string[] = [], - options?: SpawnOptions, + options?: SpawnOptions ): Command { - return new Command(program, args, options); + return new Command(program, args, options) } - static sidecar(program: string, args?: string | string[]): Command; + static sidecar(program: string, args?: string | string[]): Command static sidecar( program: string, args?: string | string[], - options?: SpawnOptions & { encoding: "raw" }, - ): Command; + options?: SpawnOptions & { encoding: 'raw' } + ): Command static sidecar( program: string, args?: string | string[], - options?: SpawnOptions, - ): Command; + options?: SpawnOptions + ): Command /** * Creates a command to execute the given sidecar program. @@ -462,11 +462,11 @@ class Command extends EventEmitter { static sidecar( program: string, args: string | string[] = [], - options?: SpawnOptions, + options?: SpawnOptions ): Command { - const instance = new Command(program, args, options); - instance.options.sidecar = true; - return instance; + const instance = new Command(program, args, options) + instance.options.sidecar = true + return instance } /** @@ -477,38 +477,38 @@ class Command extends EventEmitter { * @since 2.0.0 */ async spawn(): Promise { - const program = this.program; - const args = this.args; - const options = this.options; + const program = this.program + const args = this.args + const options = this.options - if (typeof args === "object") { - Object.freeze(args); + if (typeof args === 'object') { + Object.freeze(args) } - const onEvent = new Channel>(); + const onEvent = new Channel>() onEvent.onmessage = (event) => { switch (event.event) { - case "Error": - this.emit("error", event.payload); - break; - case "Terminated": - this.emit("close", event.payload); - break; - case "Stdout": - this.stdout.emit("data", event.payload); - break; - case "Stderr": - this.stderr.emit("data", event.payload); - break; + case 'Error': + this.emit('error', event.payload) + break + case 'Terminated': + this.emit('close', event.payload) + break + case 'Stdout': + this.stdout.emit('data', event.payload) + break + case 'Stderr': + this.stderr.emit('data', event.payload) + break } - }; + } - return await invoke("plugin:shell|spawn", { + return await invoke('plugin:shell|spawn', { program, args, options, - onEvent, - }).then((pid) => new Child(pid)); + onEvent + }).then((pid) => new Child(pid)) } /** @@ -528,19 +528,19 @@ class Command extends EventEmitter { * @since 2.0.0 */ async execute(): Promise> { - const program = this.program; - const args = this.args; - const options = this.options; + const program = this.program + const args = this.args + const options = this.options - if (typeof args === "object") { - Object.freeze(args); + if (typeof args === 'object') { + Object.freeze(args) } - return await invoke>("plugin:shell|execute", { + return await invoke>('plugin:shell|execute', { program, args, - options, - }); + options + }) } } @@ -548,8 +548,8 @@ class Command extends EventEmitter { * Describes the event message received from the command. */ interface Event { - event: T; - payload: V; + event: T + payload: V } /** @@ -557,20 +557,20 @@ interface Event { */ interface TerminatedPayload { /** 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. */ - signal: number | null; + signal: number | null } /** Event payload type */ -type IOPayload = string | Uint8Array; +type IOPayload = string | Uint8Array /** Events emitted by the child process. */ type CommandEvent = - | Event<"Stdout", O> - | Event<"Stderr", O> - | Event<"Terminated", TerminatedPayload> - | Event<"Error", string>; + | Event<'Stdout', O> + | Event<'Stderr', O> + | Event<'Terminated', TerminatedPayload> + | Event<'Error', string> /** * Opens a path or URL with the system's default app, @@ -599,18 +599,18 @@ type CommandEvent = * @since 2.0.0 */ async function open(path: string, openWith?: string): Promise { - await invoke("plugin:shell|open", { + await invoke('plugin:shell|open', { path, - with: openWith, - }); + with: openWith + }) } -export { Command, Child, EventEmitter, open }; +export { Command, Child, EventEmitter, open } export type { IOPayload, CommandEvents, TerminatedPayload, OutputEvents, ChildProcess, - SpawnOptions, -}; + SpawnOptions +} diff --git a/guest-js/init.ts b/guest-js/init.ts index 895d586..58d0001 100644 --- a/guest-js/init.ts +++ b/guest-js/init.ts @@ -2,39 +2,39 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { invoke } from "@tauri-apps/api/core"; +import { invoke } from '@tauri-apps/api/core' // open links with the API function openLinks(): void { - document.querySelector("body")?.addEventListener("click", function (e) { - let target: HTMLElement | null = e.target as HTMLElement; + document.querySelector('body')?.addEventListener('click', function (e) { + let target: HTMLElement | null = e.target as HTMLElement while (target) { - if (target.matches("a")) { - const t = target as HTMLAnchorElement; + if (target.matches('a')) { + const t = target as HTMLAnchorElement if ( - t.href !== "" && - ["http://", "https://", "mailto:", "tel:"].some((v) => - t.href.startsWith(v), + t.href !== '' && + ['http://', 'https://', 'mailto:', 'tel:'].some((v) => + t.href.startsWith(v) ) && - t.target === "_blank" + t.target === '_blank' ) { - void invoke("plugin:shell|open", { - path: t.href, - }); - e.preventDefault(); + void invoke('plugin:shell|open', { + path: t.href + }) + e.preventDefault() } - break; + break } - target = target.parentElement; + target = target.parentElement } - }); + }) } if ( - document.readyState === "complete" || - document.readyState === "interactive" + document.readyState === 'complete' || + document.readyState === 'interactive' ) { - openLinks(); + openLinks() } else { - window.addEventListener("DOMContentLoaded", openLinks, true); + window.addEventListener('DOMContentLoaded', openLinks, true) } diff --git a/permissions/default.toml b/permissions/default.toml index 4f17daa..4569b05 100644 --- a/permissions/default.toml +++ b/permissions/default.toml @@ -12,6 +12,4 @@ scope pre-configured. It will allow opening `http(s)://`, `tel:` and `mailto:` links. """ -permissions = [ - "allow-open", -] +permissions = ["allow-open"] diff --git a/rollup.config.js b/rollup.config.js index 0aed70d..a7dbd4f 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -2,21 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { createConfig } from "../../shared/rollup.config.js"; -import { nodeResolve } from "@rollup/plugin-node-resolve"; -import typescript from "@rollup/plugin-typescript"; -import terser from "@rollup/plugin-terser"; +import { createConfig } from '../../shared/rollup.config.js' +import { nodeResolve } from '@rollup/plugin-node-resolve' +import typescript from '@rollup/plugin-typescript' +import terser from '@rollup/plugin-terser' export default createConfig({ additionalConfigs: { - input: "guest-js/init.ts", + input: 'guest-js/init.ts', output: { - file: "src/init-iife.js", - format: "iife", + file: 'src/init-iife.js', + format: 'iife' }, plugins: [typescript(), terser(), nodeResolve()], onwarn: (warning) => { - throw Object.assign(new Error(), warning); - }, - }, -}); + throw Object.assign(new Error(), warning) + } + } +})