From 72569e75ee3f59973611b6fce5f1c7376d3d05dd Mon Sep 17 00:00:00 2001 From: amrbashir Date: Wed, 8 May 2024 19:34:09 +0300 Subject: [PATCH 1/4] fix(core/shell): speedup `Command.execute` & fix extra new lines The speed gains comes from running the Command in Rust fully and returning the result in one go instead of using events. The extra new lines was a regression from https://github.com/tauri-apps/tauri/pull/6519 ref: https://github.com/tauri-apps/tauri/issues/7684#issuecomment-2100897383 --- .changes/shell-execute-extra-newline.md | 6 + .changes/shell-execute-performance.md | 7 + core/tauri/scripts/bundle.global.js | 2 +- core/tauri/src/endpoints/shell.rs | 188 +++++++++++++++++------- tooling/api/src/shell.ts | 123 +++++++--------- 5 files changed, 203 insertions(+), 123 deletions(-) create mode 100644 .changes/shell-execute-extra-newline.md create mode 100644 .changes/shell-execute-performance.md diff --git a/.changes/shell-execute-extra-newline.md b/.changes/shell-execute-extra-newline.md new file mode 100644 index 000000000000..0e3dde3e5261 --- /dev/null +++ b/.changes/shell-execute-extra-newline.md @@ -0,0 +1,6 @@ +--- +"@tauri-apps/api": "patch:bug" +--- + +Fix The JS `Command.execute` API from `shell` module including extra new lines. + diff --git a/.changes/shell-execute-performance.md b/.changes/shell-execute-performance.md new file mode 100644 index 000000000000..590726743378 --- /dev/null +++ b/.changes/shell-execute-performance.md @@ -0,0 +1,7 @@ +--- +"tauri": "patch:enhance" +"@tauri-apps/api": "patch:enhance" +--- + +Enhance the speed of The JS `Command.execute` API from `shell` module. + diff --git a/core/tauri/scripts/bundle.global.js b/core/tauri/scripts/bundle.global.js index 3dd498ed05e0..92627ab7eee5 100644 --- a/core/tauri/scripts/bundle.global.js +++ b/core/tauri/scripts/bundle.global.js @@ -1 +1 @@ -var __TAURI_IIFE__=function(e){"use strict";function t(e,t=!1){const a=window.crypto.getRandomValues(new Uint32Array(1))[0],n=`_${a}`;return Object.defineProperty(window,n,{value:a=>(t&&Reflect.deleteProperty(window,n),null==e?void 0:e(a)),writable:!1,configurable:!0}),a}async function a(e,a={}){return new Promise(((n,i)=>{const r=t((e=>{n(e),Reflect.deleteProperty(window,`_${s}`)}),!0),s=t((e=>{i(e),Reflect.deleteProperty(window,`_${r}`)}),!0);window.__TAURI_IPC__({cmd:e,callback:r,error:s,...a})}))}var n=Object.freeze({__proto__:null,convertFileSrc:function(e,t="asset"){return window.__TAURI__.convertFileSrc(e,t)},invoke:a,transformCallback:t});async function i(e){return a("tauri",e)}var r=Object.freeze({__proto__:null,getName:async function(){return i({__tauriModule:"App",message:{cmd:"getAppName"}})},getTauriVersion:async function(){return i({__tauriModule:"App",message:{cmd:"getTauriVersion"}})},getVersion:async function(){return i({__tauriModule:"App",message:{cmd:"getAppVersion"}})},hide:async function(){return i({__tauriModule:"App",message:{cmd:"hide"}})},show:async function(){return i({__tauriModule:"App",message:{cmd:"show"}})}});var s=Object.freeze({__proto__:null,getMatches:async function(){return i({__tauriModule:"Cli",message:{cmd:"cliMatches"}})}});var o=Object.freeze({__proto__:null,readText:async function(){return i({__tauriModule:"Clipboard",message:{cmd:"readText",data:null}})},writeText:async function(e){return i({__tauriModule:"Clipboard",message:{cmd:"writeText",data:e}})}});var l,u=Object.freeze({__proto__:null,ask:async function(e,t){var a,n,r,s,o;const l="string"==typeof t?{title:t}:t;return i({__tauriModule:"Dialog",message:{cmd:"askDialog",message:e.toString(),title:null===(a=null==l?void 0:l.title)||void 0===a?void 0:a.toString(),type:null==l?void 0:l.type,buttonLabels:[null!==(r=null===(n=null==l?void 0:l.okLabel)||void 0===n?void 0:n.toString())&&void 0!==r?r:"Yes",null!==(o=null===(s=null==l?void 0:l.cancelLabel)||void 0===s?void 0:s.toString())&&void 0!==o?o:"No"]}})},confirm:async function(e,t){var a,n,r,s,o;const l="string"==typeof t?{title:t}:t;return i({__tauriModule:"Dialog",message:{cmd:"confirmDialog",message:e.toString(),title:null===(a=null==l?void 0:l.title)||void 0===a?void 0:a.toString(),type:null==l?void 0:l.type,buttonLabels:[null!==(r=null===(n=null==l?void 0:l.okLabel)||void 0===n?void 0:n.toString())&&void 0!==r?r:"Ok",null!==(o=null===(s=null==l?void 0:l.cancelLabel)||void 0===s?void 0:s.toString())&&void 0!==o?o:"Cancel"]}})},message:async function(e,t){var a,n;const r="string"==typeof t?{title:t}:t;return i({__tauriModule:"Dialog",message:{cmd:"messageDialog",message:e.toString(),title:null===(a=null==r?void 0:r.title)||void 0===a?void 0:a.toString(),type:null==r?void 0:r.type,buttonLabel:null===(n=null==r?void 0:r.okLabel)||void 0===n?void 0:n.toString()}})},open:async function(e={}){return"object"==typeof e&&Object.freeze(e),i({__tauriModule:"Dialog",message:{cmd:"openDialog",options:e}})},save:async function(e={}){return"object"==typeof e&&Object.freeze(e),i({__tauriModule:"Dialog",message:{cmd:"saveDialog",options:e}})}});async function c(e,t){return i({__tauriModule:"Event",message:{cmd:"unlisten",event:e,eventId:t}})}async function d(e,t,a){await i({__tauriModule:"Event",message:{cmd:"emit",event:e,windowLabel:t,payload:a}})}async function m(e,a,n){return i({__tauriModule:"Event",message:{cmd:"listen",event:e,windowLabel:a,handler:t(n)}}).then((t=>async()=>c(e,t)))}async function h(e,t,a){return m(e,t,(t=>{a(t),c(e,t.id).catch((()=>{}))}))}async function p(e,t){return m(e,null,t)}async function _(e,t){return h(e,null,t)}async function y(e,t){return d(e,void 0,t)}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_CREATED="tauri://window-created",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_FILE_DROP="tauri://file-drop",e.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",e.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",e.MENU="tauri://menu",e.CHECK_UPDATE="tauri://update",e.UPDATE_AVAILABLE="tauri://update-available",e.INSTALL_UPDATE="tauri://update-install",e.STATUS_UPDATE="tauri://update-status",e.DOWNLOAD_PROGRESS="tauri://update-download-progress"}(l||(l={}));var g,f=Object.freeze({__proto__:null,get TauriEvent(){return l},emit:y,listen:p,once:_});async function b(e,t,a){"object"==typeof a&&Object.freeze(a),"object"==typeof e&&Object.freeze(e);const n={path:"",contents:""};let r=a;return"string"==typeof e?n.path=e:(n.path=e.path,n.contents=e.contents),"string"==typeof t?n.contents=null!=t?t:"":r=t,i({__tauriModule:"Fs",message:{cmd:"writeFile",path:n.path,contents:Array.from((new TextEncoder).encode(n.contents)),options:r}})}!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Desktop=6]="Desktop",e[e.Document=7]="Document",e[e.Download=8]="Download",e[e.Executable=9]="Executable",e[e.Font=10]="Font",e[e.Home=11]="Home",e[e.Picture=12]="Picture",e[e.Public=13]="Public",e[e.Runtime=14]="Runtime",e[e.Template=15]="Template",e[e.Video=16]="Video",e[e.Resource=17]="Resource",e[e.App=18]="App",e[e.Log=19]="Log",e[e.Temp=20]="Temp",e[e.AppConfig=21]="AppConfig",e[e.AppData=22]="AppData",e[e.AppLocalData=23]="AppLocalData",e[e.AppCache=24]="AppCache",e[e.AppLog=25]="AppLog"}(g||(g={}));var w=Object.freeze({__proto__:null,get BaseDirectory(){return g},get Dir(){return g},copyFile:async function(e,t,a={}){return i({__tauriModule:"Fs",message:{cmd:"copyFile",source:e,destination:t,options:a}})},createDir:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"createDir",path:e,options:t}})},exists:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"exists",path:e,options:t}})},readBinaryFile:async function(e,t={}){const a=await i({__tauriModule:"Fs",message:{cmd:"readFile",path:e,options:t}});return Uint8Array.from(a)},readDir:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"readDir",path:e,options:t}})},readTextFile:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"readTextFile",path:e,options:t}})},removeDir:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"removeDir",path:e,options:t}})},removeFile:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"removeFile",path:e,options:t}})},renameFile:async function(e,t,a={}){return i({__tauriModule:"Fs",message:{cmd:"renameFile",oldPath:e,newPath:t,options:a}})},writeBinaryFile:async function(e,t,a){"object"==typeof a&&Object.freeze(a),"object"==typeof e&&Object.freeze(e);const n={path:"",contents:[]};let r=a;return"string"==typeof e?n.path=e:(n.path=e.path,n.contents=e.contents),t&&"dir"in t?r=t:"string"==typeof e&&(n.contents=null!=t?t:[]),i({__tauriModule:"Fs",message:{cmd:"writeFile",path:n.path,contents:Array.from(n.contents instanceof ArrayBuffer?new Uint8Array(n.contents):n.contents),options:r}})},writeFile:b,writeTextFile:b});var v,M=Object.freeze({__proto__:null,isRegistered:async function(e){return i({__tauriModule:"GlobalShortcut",message:{cmd:"isRegistered",shortcut:e}})},register:async function(e,a){return i({__tauriModule:"GlobalShortcut",message:{cmd:"register",shortcut:e,handler:t(a)}})},registerAll:async function(e,a){return i({__tauriModule:"GlobalShortcut",message:{cmd:"registerAll",shortcuts:e,handler:t(a)}})},unregister:async function(e){return i({__tauriModule:"GlobalShortcut",message:{cmd:"unregister",shortcut:e}})},unregisterAll:async function(){return i({__tauriModule:"GlobalShortcut",message:{cmd:"unregisterAll"}})}});!function(e){e[e.JSON=1]="JSON",e[e.Text=2]="Text",e[e.Binary=3]="Binary"}(v||(v={}));class D{constructor(e,t){this.type=e,this.payload=t}static form(e){return new D("Form",e)}static json(e){return new D("Json",e)}static text(e){return new D("Text",e)}static bytes(e){return new D("Bytes",Array.from(e instanceof ArrayBuffer?new Uint8Array(e):e))}}class P{constructor(e){this.url=e.url,this.status=e.status,this.ok=this.status>=200&&this.status<300,this.headers=e.headers,this.rawHeaders=e.rawHeaders,this.data=e.data}}class A{constructor(e){this.id=e}async drop(){return i({__tauriModule:"Http",message:{cmd:"dropClient",client:this.id}})}async request(e){var t;const a=!e.responseType||e.responseType===v.JSON;return a&&(e.responseType=v.Text),"Form"===(null===(t=e.body)||void 0===t?void 0:t.type)&&(e.body.payload=await async function(e){const t={},a=async(e,a)=>{if(null!==a){let n;n="string"==typeof a?a:a instanceof Uint8Array||Array.isArray(a)?Array.from(a):a instanceof File?{file:Array.from(new Uint8Array(await a.arrayBuffer())),mime:a.type,fileName:a.name}:"string"==typeof a.file?{file:a.file,mime:a.mime,fileName:a.fileName}:{file:Array.from(a.file),mime:a.mime,fileName:a.fileName},t[String(e)]=n}};if(e instanceof FormData)for(const[t,n]of e)await a(t,n);else for(const[t,n]of Object.entries(e))await a(t,n);return t}(e.body.payload)),i({__tauriModule:"Http",message:{cmd:"httpRequest",client:this.id,options:e}}).then((e=>{const t=new P(e);if(a){try{t.data=JSON.parse(t.data)}catch(e){if(t.ok&&""===t.data)t.data={};else if(t.ok)throw Error(`Failed to parse response \`${t.data}\` as JSON: ${e};\n try setting the \`responseType\` option to \`ResponseType.Text\` or \`ResponseType.Binary\` if the API does not return a JSON response.`)}return t}return t}))}async get(e,t){return this.request({method:"GET",url:e,...t})}async post(e,t,a){return this.request({method:"POST",url:e,body:t,...a})}async put(e,t,a){return this.request({method:"PUT",url:e,body:t,...a})}async patch(e,t){return this.request({method:"PATCH",url:e,...t})}async delete(e,t){return this.request({method:"DELETE",url:e,...t})}}async function W(e){return i({__tauriModule:"Http",message:{cmd:"createClient",options:e}}).then((e=>new A(e)))}let E=null;var L=Object.freeze({__proto__:null,Body:D,Client:A,Response:P,get ResponseType(){return v},fetch:async function(e,t){var a;return null===E&&(E=await W()),E.request({url:e,method:null!==(a=null==t?void 0:t.method)&&void 0!==a?a:"GET",...t})},getClient:W});var T=Object.freeze({__proto__:null,isPermissionGranted:async function(){return"default"!==window.Notification.permission?Promise.resolve("granted"===window.Notification.permission):i({__tauriModule:"Notification",message:{cmd:"isNotificationPermissionGranted"}})},requestPermission:async function(){return window.Notification.requestPermission()},sendNotification:function(e){"string"==typeof e?new window.Notification(e):new window.Notification(e.title,e)}});function O(){return navigator.appVersion.includes("Win")}async function C(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppConfig}})}async function z(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppLog}})}const S=O()?"\\":"/",F=O()?";":":";var I=Object.freeze({__proto__:null,get BaseDirectory(){return g},appCacheDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppCache}})},appConfigDir:C,appDataDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppData}})},appDir:async function(){return C()},appLocalDataDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppLocalData}})},appLogDir:z,audioDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Audio}})},basename:async function(e,t){return i({__tauriModule:"Path",message:{cmd:"basename",path:e,ext:t}})},cacheDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Cache}})},configDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Config}})},dataDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Data}})},delimiter:F,desktopDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Desktop}})},dirname:async function(e){return i({__tauriModule:"Path",message:{cmd:"dirname",path:e}})},documentDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Document}})},downloadDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Download}})},executableDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Executable}})},extname:async function(e){return i({__tauriModule:"Path",message:{cmd:"extname",path:e}})},fontDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Font}})},homeDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Home}})},isAbsolute:async function(e){return i({__tauriModule:"Path",message:{cmd:"isAbsolute",path:e}})},join:async function(...e){return i({__tauriModule:"Path",message:{cmd:"join",paths:e}})},localDataDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.LocalData}})},logDir:async function(){return z()},normalize:async function(e){return i({__tauriModule:"Path",message:{cmd:"normalize",path:e}})},pictureDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Picture}})},publicDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Public}})},resolve:async function(...e){return i({__tauriModule:"Path",message:{cmd:"resolve",paths:e}})},resolveResource:async function(e){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:e,directory:g.Resource}})},resourceDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Resource}})},runtimeDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Runtime}})},sep:S,templateDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Template}})},videoDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Video}})}});var x=Object.freeze({__proto__:null,exit:async function(e=0){return i({__tauriModule:"Process",message:{cmd:"exit",exitCode:e}})},relaunch:async function(){return i({__tauriModule:"Process",message:{cmd:"relaunch"}})}});class N{constructor(){this.eventListeners=Object.create(null)}addListener(e,t){return this.on(e,t)}removeListener(e,t){return this.off(e,t)}on(e,t){return e in this.eventListeners?this.eventListeners[e].push(t):this.eventListeners[e]=[t],this}once(e,t){const a=(...n)=>{this.removeListener(e,a),t(...n)};return this.addListener(e,a)}off(e,t){return e in this.eventListeners&&(this.eventListeners[e]=this.eventListeners[e].filter((e=>e!==t))),this}removeAllListeners(e){return e?delete this.eventListeners[e]:this.eventListeners=Object.create(null),this}emit(e,...t){if(e in this.eventListeners){const a=this.eventListeners[e];for(const e of a)e(...t);return!0}return!1}listenerCount(e){return e in this.eventListeners?this.eventListeners[e].length:0}prependListener(e,t){return e in this.eventListeners?this.eventListeners[e].unshift(t):this.eventListeners[e]=[t],this}prependOnceListener(e,t){const a=(...n)=>{this.removeListener(e,a),t(...n)};return this.prependListener(e,a)}}class R{constructor(e){this.pid=e}async write(e){return i({__tauriModule:"Shell",message:{cmd:"stdinWrite",pid:this.pid,buffer:"string"==typeof e?e:Array.from(e)}})}async kill(){return i({__tauriModule:"Shell",message:{cmd:"killChild",pid:this.pid}})}}class U extends N{constructor(e,t=[],a){super(),this.stdout=new N,this.stderr=new N,this.program=e,this.args="string"==typeof t?[t]:t,this.options=null!=a?a:{}}static sidecar(e,t=[],a){const n=new U(e,t,a);return n.options.sidecar=!0,n}async spawn(){return async function(e,a,n=[],r){return"object"==typeof n&&Object.freeze(n),i({__tauriModule:"Shell",message:{cmd:"execute",program:a,args:n,options:r,onEventFn:t(e)}})}((e=>{switch(e.event){case"Error":this.emit("error",e.payload);break;case"Terminated":this.emit("close",e.payload);break;case"Stdout":this.stdout.emit("data",e.payload);break;case"Stderr":this.stderr.emit("data",e.payload)}}),this.program,this.args,this.options).then((e=>new R(e)))}async execute(){return new Promise(((e,t)=>{this.on("error",t);const a=[],n=[];this.stdout.on("data",(e=>{a.push(e)})),this.stderr.on("data",(e=>{n.push(e)})),this.on("close",(t=>{e({code:t.code,signal:t.signal,stdout:a.join("\n"),stderr:n.join("\n")})})),this.spawn().catch(t)}))}}var j=Object.freeze({__proto__:null,Child:R,Command:U,EventEmitter:N,open:async function(e,t){return i({__tauriModule:"Shell",message:{cmd:"open",path:e,with:t}})}});async function k(e){return p(l.STATUS_UPDATE,(t=>{e(null==t?void 0:t.payload)}))}var H,V=Object.freeze({__proto__:null,checkUpdate:async function(){let e;function t(){e&&e(),e=void 0}return new Promise(((a,n)=>{_(l.UPDATE_AVAILABLE,(e=>{var n;n=null==e?void 0:e.payload,t(),a({manifest:n,shouldUpdate:!0})})).catch((e=>{throw t(),e})),k((function(e){if(e.error)return t(),void n(e.error);"UPTODATE"===e.status&&(t(),a({shouldUpdate:!1}))})).then((t=>{e=t})).catch((e=>{throw t(),e})),y(l.CHECK_UPDATE).catch((e=>{throw t(),e}))}))},installUpdate:async function(){let e;function t(){e&&e(),e=void 0}return new Promise(((a,n)=>{k((function(e){if(e.error)return t(),void n(e.error);"DONE"===e.status&&(t(),a())})).then((t=>{e=t})).catch((e=>{throw t(),e})),y(l.INSTALL_UPDATE).catch((e=>{throw t(),e}))}))},onUpdaterEvent:k});class B{constructor(e,t){this.type="Logical",this.width=e,this.height=t}}class G{constructor(e,t){this.type="Physical",this.width=e,this.height=t}toLogical(e){return new B(this.width/e,this.height/e)}}class q{constructor(e,t){this.type="Logical",this.x=e,this.y=t}}class J{constructor(e,t){this.type="Physical",this.x=e,this.y=t}toLogical(e){return new q(this.x/e,this.y/e)}}function $(){return window.__TAURI_METADATA__.__windows.map((e=>new X(e.label,{skip:!0})))}!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(H||(H={}));const K=["tauri://created","tauri://error"];class Q{constructor(e){this.label=e,this.listeners=Object.create(null)}async listen(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const a=this.listeners[e];a.splice(a.indexOf(t),1)})):m(e,this.label,t)}async once(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const a=this.listeners[e];a.splice(a.indexOf(t),1)})):h(e,this.label,t)}async emit(e,t){if(K.includes(e)){for(const a of this.listeners[e]||[])a({event:e,id:-1,windowLabel:this.label,payload:t});return Promise.resolve()}return d(e,this.label,t)}_handleTauriEvent(e,t){return!!K.includes(e)&&(e in this.listeners?this.listeners[e].push(t):this.listeners[e]=[t],!0)}}class Y extends Q{async scaleFactor(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"scaleFactor"}}}})}async innerPosition(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"innerPosition"}}}}).then((({x:e,y:t})=>new J(e,t)))}async outerPosition(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"outerPosition"}}}}).then((({x:e,y:t})=>new J(e,t)))}async innerSize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"innerSize"}}}}).then((({width:e,height:t})=>new G(e,t)))}async outerSize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"outerSize"}}}}).then((({width:e,height:t})=>new G(e,t)))}async isFullscreen(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isFullscreen"}}}})}async isMinimized(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMinimized"}}}})}async isMaximized(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMaximized"}}}})}async isFocused(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isFocused"}}}})}async isDecorated(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isDecorated"}}}})}async isResizable(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isResizable"}}}})}async isMaximizable(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMaximizable"}}}})}async isMinimizable(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMinimizable"}}}})}async isClosable(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isClosable"}}}})}async isVisible(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isVisible"}}}})}async title(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"title"}}}})}async theme(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"theme"}}}})}async center(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"center"}}}})}async requestUserAttention(e){let t=null;return e&&(t=e===H.Critical?{type:"Critical"}:{type:"Informational"}),i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"requestUserAttention",payload:t}}}})}async setResizable(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setResizable",payload:e}}}})}async setMaximizable(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMaximizable",payload:e}}}})}async setMinimizable(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMinimizable",payload:e}}}})}async setClosable(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setClosable",payload:e}}}})}async setTitle(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setTitle",payload:e}}}})}async maximize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"maximize"}}}})}async unmaximize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"unmaximize"}}}})}async toggleMaximize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"toggleMaximize"}}}})}async minimize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"minimize"}}}})}async unminimize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"unminimize"}}}})}async show(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"show"}}}})}async hide(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"hide"}}}})}async close(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"close"}}}})}async setDecorations(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setDecorations",payload:e}}}})}async setAlwaysOnTop(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setAlwaysOnTop",payload:e}}}})}async setContentProtected(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setContentProtected",payload:e}}}})}async setSize(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setSize",payload:{type:e.type,data:{width:e.width,height:e.height}}}}}})}async setMinSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMinSize",payload:e?{type:e.type,data:{width:e.width,height:e.height}}:null}}}})}async setMaxSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMaxSize",payload:e?{type:e.type,data:{width:e.width,height:e.height}}:null}}}})}async setPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setPosition",payload:{type:e.type,data:{x:e.x,y:e.y}}}}}})}async setFullscreen(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setFullscreen",payload:e}}}})}async setFocus(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setFocus"}}}})}async setIcon(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setIcon",payload:{icon:"string"==typeof e?e:Array.from(e)}}}}})}async setSkipTaskbar(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setSkipTaskbar",payload:e}}}})}async setCursorGrab(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setCursorGrab",payload:e}}}})}async setCursorVisible(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setCursorVisible",payload:e}}}})}async setCursorIcon(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setCursorIcon",payload:e}}}})}async setCursorPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setCursorPosition",payload:{type:e.type,data:{x:e.x,y:e.y}}}}}})}async setIgnoreCursorEvents(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setIgnoreCursorEvents",payload:e}}}})}async startDragging(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"startDragging"}}}})}async onResized(e){return this.listen(l.WINDOW_RESIZED,(t=>{t.payload=ne(t.payload),e(t)}))}async onMoved(e){return this.listen(l.WINDOW_MOVED,(t=>{t.payload=ae(t.payload),e(t)}))}async onCloseRequested(e){return this.listen(l.WINDOW_CLOSE_REQUESTED,(t=>{const a=new Z(t);Promise.resolve(e(a)).then((()=>{if(!a.isPreventDefault())return this.close()}))}))}async onFocusChanged(e){const t=await this.listen(l.WINDOW_FOCUS,(t=>{e({...t,payload:!0})})),a=await this.listen(l.WINDOW_BLUR,(t=>{e({...t,payload:!1})}));return()=>{t(),a()}}async onScaleChanged(e){return this.listen(l.WINDOW_SCALE_FACTOR_CHANGED,e)}async onMenuClicked(e){return this.listen(l.MENU,e)}async onFileDropEvent(e){const t=await this.listen(l.WINDOW_FILE_DROP,(t=>{e({...t,payload:{type:"drop",paths:t.payload}})})),a=await this.listen(l.WINDOW_FILE_DROP_HOVER,(t=>{e({...t,payload:{type:"hover",paths:t.payload}})})),n=await this.listen(l.WINDOW_FILE_DROP_CANCELLED,(t=>{e({...t,payload:{type:"cancel"}})}));return()=>{t(),a(),n()}}async onThemeChanged(e){return this.listen(l.WINDOW_THEME_CHANGED,e)}}class Z{constructor(e){this._preventDefault=!1,this.event=e.event,this.windowLabel=e.windowLabel,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}class X extends Y{constructor(e,t={}){super(e),(null==t?void 0:t.skip)||i({__tauriModule:"Window",message:{cmd:"createWebview",data:{options:{label:e,...t}}}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static getByLabel(e){return $().some((t=>t.label===e))?new X(e,{skip:!0}):null}static async getFocusedWindow(){for(const e of $())if(await e.isFocused())return e;return null}}let ee;function te(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:ae(e.position),size:ne(e.size)}}function ae(e){return new J(e.x,e.y)}function ne(e){return new G(e.width,e.height)}"__TAURI_METADATA__"in window?ee=new X(window.__TAURI_METADATA__.__currentWindow.label,{skip:!0}):(console.warn('Could not find "window.__TAURI_METADATA__". The "appWindow" value will reference the "main" window label.\nNote that this is not an issue if running this frontend on a browser instead of a Tauri window.'),ee=new X("main",{skip:!0}));var ie=Object.freeze({__proto__:null,CloseRequestedEvent:Z,LogicalPosition:q,LogicalSize:B,PhysicalPosition:J,PhysicalSize:G,get UserAttentionType(){return H},WebviewWindow:X,WebviewWindowHandle:Q,WindowManager:Y,get appWindow(){return ee},availableMonitors:async function(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"availableMonitors"}}}}).then((e=>e.map(te)))},currentMonitor:async function(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"currentMonitor"}}}}).then(te)},getAll:$,getCurrent:function(){return new X(window.__TAURI_METADATA__.__currentWindow.label,{skip:!0})},primaryMonitor:async function(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"primaryMonitor"}}}}).then(te)}});const re=O()?"\r\n":"\n";var se=Object.freeze({__proto__:null,EOL:re,arch:async function(){return i({__tauriModule:"Os",message:{cmd:"arch"}})},locale:async function(){return i({__tauriModule:"Os",message:{cmd:"locale"}})},platform:async function(){return i({__tauriModule:"Os",message:{cmd:"platform"}})},tempdir:async function(){return i({__tauriModule:"Os",message:{cmd:"tempdir"}})},type:async function(){return i({__tauriModule:"Os",message:{cmd:"osType"}})},version:async function(){return i({__tauriModule:"Os",message:{cmd:"version"}})}});const oe=a;return e.app=r,e.cli=s,e.clipboard=o,e.dialog=u,e.event=f,e.fs=w,e.globalShortcut=M,e.http=L,e.invoke=oe,e.notification=T,e.os=se,e.path=I,e.process=x,e.shell=j,e.tauri=n,e.updater=V,e.window=ie,e}({});window.__TAURI__=__TAURI_IIFE__; +var __TAURI_IIFE__=function(e){"use strict";function t(e,t=!1){const a=window.crypto.getRandomValues(new Uint32Array(1))[0],n=`_${a}`;return Object.defineProperty(window,n,{value:a=>(t&&Reflect.deleteProperty(window,n),null==e?void 0:e(a)),writable:!1,configurable:!0}),a}async function a(e,a={}){return new Promise(((n,i)=>{const r=t((e=>{n(e),Reflect.deleteProperty(window,`_${s}`)}),!0),s=t((e=>{i(e),Reflect.deleteProperty(window,`_${r}`)}),!0);window.__TAURI_IPC__({cmd:e,callback:r,error:s,...a})}))}var n=Object.freeze({__proto__:null,convertFileSrc:function(e,t="asset"){return window.__TAURI__.convertFileSrc(e,t)},invoke:a,transformCallback:t});async function i(e){return a("tauri",e)}var r=Object.freeze({__proto__:null,getName:async function(){return i({__tauriModule:"App",message:{cmd:"getAppName"}})},getTauriVersion:async function(){return i({__tauriModule:"App",message:{cmd:"getTauriVersion"}})},getVersion:async function(){return i({__tauriModule:"App",message:{cmd:"getAppVersion"}})},hide:async function(){return i({__tauriModule:"App",message:{cmd:"hide"}})},show:async function(){return i({__tauriModule:"App",message:{cmd:"show"}})}});var s=Object.freeze({__proto__:null,getMatches:async function(){return i({__tauriModule:"Cli",message:{cmd:"cliMatches"}})}});var o=Object.freeze({__proto__:null,readText:async function(){return i({__tauriModule:"Clipboard",message:{cmd:"readText",data:null}})},writeText:async function(e){return i({__tauriModule:"Clipboard",message:{cmd:"writeText",data:e}})}});var l,u=Object.freeze({__proto__:null,ask:async function(e,t){var a,n,r,s,o;const l="string"==typeof t?{title:t}:t;return i({__tauriModule:"Dialog",message:{cmd:"askDialog",message:e.toString(),title:null===(a=null==l?void 0:l.title)||void 0===a?void 0:a.toString(),type:null==l?void 0:l.type,buttonLabels:[null!==(r=null===(n=null==l?void 0:l.okLabel)||void 0===n?void 0:n.toString())&&void 0!==r?r:"Yes",null!==(o=null===(s=null==l?void 0:l.cancelLabel)||void 0===s?void 0:s.toString())&&void 0!==o?o:"No"]}})},confirm:async function(e,t){var a,n,r,s,o;const l="string"==typeof t?{title:t}:t;return i({__tauriModule:"Dialog",message:{cmd:"confirmDialog",message:e.toString(),title:null===(a=null==l?void 0:l.title)||void 0===a?void 0:a.toString(),type:null==l?void 0:l.type,buttonLabels:[null!==(r=null===(n=null==l?void 0:l.okLabel)||void 0===n?void 0:n.toString())&&void 0!==r?r:"Ok",null!==(o=null===(s=null==l?void 0:l.cancelLabel)||void 0===s?void 0:s.toString())&&void 0!==o?o:"Cancel"]}})},message:async function(e,t){var a,n;const r="string"==typeof t?{title:t}:t;return i({__tauriModule:"Dialog",message:{cmd:"messageDialog",message:e.toString(),title:null===(a=null==r?void 0:r.title)||void 0===a?void 0:a.toString(),type:null==r?void 0:r.type,buttonLabel:null===(n=null==r?void 0:r.okLabel)||void 0===n?void 0:n.toString()}})},open:async function(e={}){return"object"==typeof e&&Object.freeze(e),i({__tauriModule:"Dialog",message:{cmd:"openDialog",options:e}})},save:async function(e={}){return"object"==typeof e&&Object.freeze(e),i({__tauriModule:"Dialog",message:{cmd:"saveDialog",options:e}})}});async function c(e,t){return i({__tauriModule:"Event",message:{cmd:"unlisten",event:e,eventId:t}})}async function d(e,t,a){await i({__tauriModule:"Event",message:{cmd:"emit",event:e,windowLabel:t,payload:a}})}async function m(e,a,n){return i({__tauriModule:"Event",message:{cmd:"listen",event:e,windowLabel:a,handler:t(n)}}).then((t=>async()=>c(e,t)))}async function h(e,t,a){return m(e,t,(t=>{a(t),c(e,t.id).catch((()=>{}))}))}async function p(e,t){return m(e,null,t)}async function _(e,t){return h(e,null,t)}async function y(e,t){return d(e,void 0,t)}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_CREATED="tauri://window-created",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_FILE_DROP="tauri://file-drop",e.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",e.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",e.MENU="tauri://menu",e.CHECK_UPDATE="tauri://update",e.UPDATE_AVAILABLE="tauri://update-available",e.INSTALL_UPDATE="tauri://update-install",e.STATUS_UPDATE="tauri://update-status",e.DOWNLOAD_PROGRESS="tauri://update-download-progress"}(l||(l={}));var g,f=Object.freeze({__proto__:null,get TauriEvent(){return l},emit:y,listen:p,once:_});async function b(e,t,a){"object"==typeof a&&Object.freeze(a),"object"==typeof e&&Object.freeze(e);const n={path:"",contents:""};let r=a;return"string"==typeof e?n.path=e:(n.path=e.path,n.contents=e.contents),"string"==typeof t?n.contents=null!=t?t:"":r=t,i({__tauriModule:"Fs",message:{cmd:"writeFile",path:n.path,contents:Array.from((new TextEncoder).encode(n.contents)),options:r}})}!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Desktop=6]="Desktop",e[e.Document=7]="Document",e[e.Download=8]="Download",e[e.Executable=9]="Executable",e[e.Font=10]="Font",e[e.Home=11]="Home",e[e.Picture=12]="Picture",e[e.Public=13]="Public",e[e.Runtime=14]="Runtime",e[e.Template=15]="Template",e[e.Video=16]="Video",e[e.Resource=17]="Resource",e[e.App=18]="App",e[e.Log=19]="Log",e[e.Temp=20]="Temp",e[e.AppConfig=21]="AppConfig",e[e.AppData=22]="AppData",e[e.AppLocalData=23]="AppLocalData",e[e.AppCache=24]="AppCache",e[e.AppLog=25]="AppLog"}(g||(g={}));var w=Object.freeze({__proto__:null,get BaseDirectory(){return g},get Dir(){return g},copyFile:async function(e,t,a={}){return i({__tauriModule:"Fs",message:{cmd:"copyFile",source:e,destination:t,options:a}})},createDir:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"createDir",path:e,options:t}})},exists:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"exists",path:e,options:t}})},readBinaryFile:async function(e,t={}){const a=await i({__tauriModule:"Fs",message:{cmd:"readFile",path:e,options:t}});return Uint8Array.from(a)},readDir:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"readDir",path:e,options:t}})},readTextFile:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"readTextFile",path:e,options:t}})},removeDir:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"removeDir",path:e,options:t}})},removeFile:async function(e,t={}){return i({__tauriModule:"Fs",message:{cmd:"removeFile",path:e,options:t}})},renameFile:async function(e,t,a={}){return i({__tauriModule:"Fs",message:{cmd:"renameFile",oldPath:e,newPath:t,options:a}})},writeBinaryFile:async function(e,t,a){"object"==typeof a&&Object.freeze(a),"object"==typeof e&&Object.freeze(e);const n={path:"",contents:[]};let r=a;return"string"==typeof e?n.path=e:(n.path=e.path,n.contents=e.contents),t&&"dir"in t?r=t:"string"==typeof e&&(n.contents=null!=t?t:[]),i({__tauriModule:"Fs",message:{cmd:"writeFile",path:n.path,contents:Array.from(n.contents instanceof ArrayBuffer?new Uint8Array(n.contents):n.contents),options:r}})},writeFile:b,writeTextFile:b});var v,M=Object.freeze({__proto__:null,isRegistered:async function(e){return i({__tauriModule:"GlobalShortcut",message:{cmd:"isRegistered",shortcut:e}})},register:async function(e,a){return i({__tauriModule:"GlobalShortcut",message:{cmd:"register",shortcut:e,handler:t(a)}})},registerAll:async function(e,a){return i({__tauriModule:"GlobalShortcut",message:{cmd:"registerAll",shortcuts:e,handler:t(a)}})},unregister:async function(e){return i({__tauriModule:"GlobalShortcut",message:{cmd:"unregister",shortcut:e}})},unregisterAll:async function(){return i({__tauriModule:"GlobalShortcut",message:{cmd:"unregisterAll"}})}});!function(e){e[e.JSON=1]="JSON",e[e.Text=2]="Text",e[e.Binary=3]="Binary"}(v||(v={}));class D{constructor(e,t){this.type=e,this.payload=t}static form(e){return new D("Form",e)}static json(e){return new D("Json",e)}static text(e){return new D("Text",e)}static bytes(e){return new D("Bytes",Array.from(e instanceof ArrayBuffer?new Uint8Array(e):e))}}class P{constructor(e){this.url=e.url,this.status=e.status,this.ok=this.status>=200&&this.status<300,this.headers=e.headers,this.rawHeaders=e.rawHeaders,this.data=e.data}}class A{constructor(e){this.id=e}async drop(){return i({__tauriModule:"Http",message:{cmd:"dropClient",client:this.id}})}async request(e){var t;const a=!e.responseType||e.responseType===v.JSON;return a&&(e.responseType=v.Text),"Form"===(null===(t=e.body)||void 0===t?void 0:t.type)&&(e.body.payload=await async function(e){const t={},a=async(e,a)=>{if(null!==a){let n;n="string"==typeof a?a:a instanceof Uint8Array||Array.isArray(a)?Array.from(a):a instanceof File?{file:Array.from(new Uint8Array(await a.arrayBuffer())),mime:a.type,fileName:a.name}:"string"==typeof a.file?{file:a.file,mime:a.mime,fileName:a.fileName}:{file:Array.from(a.file),mime:a.mime,fileName:a.fileName},t[String(e)]=n}};if(e instanceof FormData)for(const[t,n]of e)await a(t,n);else for(const[t,n]of Object.entries(e))await a(t,n);return t}(e.body.payload)),i({__tauriModule:"Http",message:{cmd:"httpRequest",client:this.id,options:e}}).then((e=>{const t=new P(e);if(a){try{t.data=JSON.parse(t.data)}catch(e){if(t.ok&&""===t.data)t.data={};else if(t.ok)throw Error(`Failed to parse response \`${t.data}\` as JSON: ${e};\n try setting the \`responseType\` option to \`ResponseType.Text\` or \`ResponseType.Binary\` if the API does not return a JSON response.`)}return t}return t}))}async get(e,t){return this.request({method:"GET",url:e,...t})}async post(e,t,a){return this.request({method:"POST",url:e,body:t,...a})}async put(e,t,a){return this.request({method:"PUT",url:e,body:t,...a})}async patch(e,t){return this.request({method:"PATCH",url:e,...t})}async delete(e,t){return this.request({method:"DELETE",url:e,...t})}}async function W(e){return i({__tauriModule:"Http",message:{cmd:"createClient",options:e}}).then((e=>new A(e)))}let E=null;var L=Object.freeze({__proto__:null,Body:D,Client:A,Response:P,get ResponseType(){return v},fetch:async function(e,t){var a;return null===E&&(E=await W()),E.request({url:e,method:null!==(a=null==t?void 0:t.method)&&void 0!==a?a:"GET",...t})},getClient:W});var O=Object.freeze({__proto__:null,isPermissionGranted:async function(){return"default"!==window.Notification.permission?Promise.resolve("granted"===window.Notification.permission):i({__tauriModule:"Notification",message:{cmd:"isNotificationPermissionGranted"}})},requestPermission:async function(){return window.Notification.requestPermission()},sendNotification:function(e){"string"==typeof e?new window.Notification(e):new window.Notification(e.title,e)}});function T(){return navigator.appVersion.includes("Win")}async function C(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppConfig}})}async function z(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppLog}})}const S=T()?"\\":"/",F=T()?";":":";var I=Object.freeze({__proto__:null,get BaseDirectory(){return g},appCacheDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppCache}})},appConfigDir:C,appDataDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppData}})},appDir:async function(){return C()},appLocalDataDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.AppLocalData}})},appLogDir:z,audioDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Audio}})},basename:async function(e,t){return i({__tauriModule:"Path",message:{cmd:"basename",path:e,ext:t}})},cacheDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Cache}})},configDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Config}})},dataDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Data}})},delimiter:F,desktopDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Desktop}})},dirname:async function(e){return i({__tauriModule:"Path",message:{cmd:"dirname",path:e}})},documentDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Document}})},downloadDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Download}})},executableDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Executable}})},extname:async function(e){return i({__tauriModule:"Path",message:{cmd:"extname",path:e}})},fontDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Font}})},homeDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Home}})},isAbsolute:async function(e){return i({__tauriModule:"Path",message:{cmd:"isAbsolute",path:e}})},join:async function(...e){return i({__tauriModule:"Path",message:{cmd:"join",paths:e}})},localDataDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.LocalData}})},logDir:async function(){return z()},normalize:async function(e){return i({__tauriModule:"Path",message:{cmd:"normalize",path:e}})},pictureDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Picture}})},publicDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Public}})},resolve:async function(...e){return i({__tauriModule:"Path",message:{cmd:"resolve",paths:e}})},resolveResource:async function(e){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:e,directory:g.Resource}})},resourceDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Resource}})},runtimeDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Runtime}})},sep:S,templateDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Template}})},videoDir:async function(){return i({__tauriModule:"Path",message:{cmd:"resolvePath",path:"",directory:g.Video}})}});var x=Object.freeze({__proto__:null,exit:async function(e=0){return i({__tauriModule:"Process",message:{cmd:"exit",exitCode:e}})},relaunch:async function(){return i({__tauriModule:"Process",message:{cmd:"relaunch"}})}});class N{constructor(){this.eventListeners=Object.create(null)}addListener(e,t){return this.on(e,t)}removeListener(e,t){return this.off(e,t)}on(e,t){return e in this.eventListeners?this.eventListeners[e].push(t):this.eventListeners[e]=[t],this}once(e,t){const a=(...n)=>{this.removeListener(e,a),t(...n)};return this.addListener(e,a)}off(e,t){return e in this.eventListeners&&(this.eventListeners[e]=this.eventListeners[e].filter((e=>e!==t))),this}removeAllListeners(e){return e?delete this.eventListeners[e]:this.eventListeners=Object.create(null),this}emit(e,...t){if(e in this.eventListeners){const a=this.eventListeners[e];for(const e of a)e(...t);return!0}return!1}listenerCount(e){return e in this.eventListeners?this.eventListeners[e].length:0}prependListener(e,t){return e in this.eventListeners?this.eventListeners[e].unshift(t):this.eventListeners[e]=[t],this}prependOnceListener(e,t){const a=(...n)=>{this.removeListener(e,a),t(...n)};return this.prependListener(e,a)}}class R{constructor(e){this.pid=e}async write(e){return i({__tauriModule:"Shell",message:{cmd:"stdinWrite",pid:this.pid,buffer:"string"==typeof e?e:Array.from(e)}})}async kill(){return i({__tauriModule:"Shell",message:{cmd:"killChild",pid:this.pid}})}}class U extends N{constructor(e,t=[],a){super(),this.stdout=new N,this.stderr=new N,this.program=e,this.args="string"==typeof t?[t]:t,this.options=null!=a?a:{}}static sidecar(e,t=[],a){const n=new U(e,t,a);return n.options.sidecar=!0,n}async spawn(){const e=this.program,a=this.args,n=this.options;"object"==typeof a&&Object.freeze(a);return i({__tauriModule:"Shell",message:{cmd:"execute",program:e,args:a,options:n,onEventFn:t((e=>{switch(e.event){case"Error":this.emit("error",e.payload);break;case"Terminated":this.emit("close",e.payload);break;case"Stdout":this.stdout.emit("data",e.payload);break;case"Stderr":this.stderr.emit("data",e.payload)}}))}}).then((e=>new R(e)))}async execute(){const e=this.program,t=this.args,a=this.options;return"object"==typeof t&&Object.freeze(t),i({__tauriModule:"Shell",message:{cmd:"executeAndReturn",program:e,args:t,options:a}})}}var j=Object.freeze({__proto__:null,Child:R,Command:U,EventEmitter:N,open:async function(e,t){return i({__tauriModule:"Shell",message:{cmd:"open",path:e,with:t}})}});async function k(e){return p(l.STATUS_UPDATE,(t=>{e(null==t?void 0:t.payload)}))}var H,V=Object.freeze({__proto__:null,checkUpdate:async function(){let e;function t(){e&&e(),e=void 0}return new Promise(((a,n)=>{_(l.UPDATE_AVAILABLE,(e=>{var n;n=null==e?void 0:e.payload,t(),a({manifest:n,shouldUpdate:!0})})).catch((e=>{throw t(),e})),k((function(e){if(e.error)return t(),void n(e.error);"UPTODATE"===e.status&&(t(),a({shouldUpdate:!1}))})).then((t=>{e=t})).catch((e=>{throw t(),e})),y(l.CHECK_UPDATE).catch((e=>{throw t(),e}))}))},installUpdate:async function(){let e;function t(){e&&e(),e=void 0}return new Promise(((a,n)=>{k((function(e){if(e.error)return t(),void n(e.error);"DONE"===e.status&&(t(),a())})).then((t=>{e=t})).catch((e=>{throw t(),e})),y(l.INSTALL_UPDATE).catch((e=>{throw t(),e}))}))},onUpdaterEvent:k});class B{constructor(e,t){this.type="Logical",this.width=e,this.height=t}}class G{constructor(e,t){this.type="Physical",this.width=e,this.height=t}toLogical(e){return new B(this.width/e,this.height/e)}}class q{constructor(e,t){this.type="Logical",this.x=e,this.y=t}}class J{constructor(e,t){this.type="Physical",this.x=e,this.y=t}toLogical(e){return new q(this.x/e,this.y/e)}}function $(){return window.__TAURI_METADATA__.__windows.map((e=>new X(e.label,{skip:!0})))}!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(H||(H={}));const K=["tauri://created","tauri://error"];class Q{constructor(e){this.label=e,this.listeners=Object.create(null)}async listen(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const a=this.listeners[e];a.splice(a.indexOf(t),1)})):m(e,this.label,t)}async once(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const a=this.listeners[e];a.splice(a.indexOf(t),1)})):h(e,this.label,t)}async emit(e,t){if(K.includes(e)){for(const a of this.listeners[e]||[])a({event:e,id:-1,windowLabel:this.label,payload:t});return Promise.resolve()}return d(e,this.label,t)}_handleTauriEvent(e,t){return!!K.includes(e)&&(e in this.listeners?this.listeners[e].push(t):this.listeners[e]=[t],!0)}}class Y extends Q{async scaleFactor(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"scaleFactor"}}}})}async innerPosition(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"innerPosition"}}}}).then((({x:e,y:t})=>new J(e,t)))}async outerPosition(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"outerPosition"}}}}).then((({x:e,y:t})=>new J(e,t)))}async innerSize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"innerSize"}}}}).then((({width:e,height:t})=>new G(e,t)))}async outerSize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"outerSize"}}}}).then((({width:e,height:t})=>new G(e,t)))}async isFullscreen(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isFullscreen"}}}})}async isMinimized(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMinimized"}}}})}async isMaximized(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMaximized"}}}})}async isFocused(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isFocused"}}}})}async isDecorated(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isDecorated"}}}})}async isResizable(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isResizable"}}}})}async isMaximizable(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMaximizable"}}}})}async isMinimizable(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isMinimizable"}}}})}async isClosable(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isClosable"}}}})}async isVisible(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"isVisible"}}}})}async title(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"title"}}}})}async theme(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"theme"}}}})}async center(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"center"}}}})}async requestUserAttention(e){let t=null;return e&&(t=e===H.Critical?{type:"Critical"}:{type:"Informational"}),i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"requestUserAttention",payload:t}}}})}async setResizable(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setResizable",payload:e}}}})}async setMaximizable(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMaximizable",payload:e}}}})}async setMinimizable(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMinimizable",payload:e}}}})}async setClosable(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setClosable",payload:e}}}})}async setTitle(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setTitle",payload:e}}}})}async maximize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"maximize"}}}})}async unmaximize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"unmaximize"}}}})}async toggleMaximize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"toggleMaximize"}}}})}async minimize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"minimize"}}}})}async unminimize(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"unminimize"}}}})}async show(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"show"}}}})}async hide(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"hide"}}}})}async close(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"close"}}}})}async setDecorations(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setDecorations",payload:e}}}})}async setAlwaysOnTop(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setAlwaysOnTop",payload:e}}}})}async setContentProtected(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setContentProtected",payload:e}}}})}async setSize(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setSize",payload:{type:e.type,data:{width:e.width,height:e.height}}}}}})}async setMinSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMinSize",payload:e?{type:e.type,data:{width:e.width,height:e.height}}:null}}}})}async setMaxSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setMaxSize",payload:e?{type:e.type,data:{width:e.width,height:e.height}}:null}}}})}async setPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setPosition",payload:{type:e.type,data:{x:e.x,y:e.y}}}}}})}async setFullscreen(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setFullscreen",payload:e}}}})}async setFocus(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setFocus"}}}})}async setIcon(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setIcon",payload:{icon:"string"==typeof e?e:Array.from(e)}}}}})}async setSkipTaskbar(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setSkipTaskbar",payload:e}}}})}async setCursorGrab(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setCursorGrab",payload:e}}}})}async setCursorVisible(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setCursorVisible",payload:e}}}})}async setCursorIcon(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setCursorIcon",payload:e}}}})}async setCursorPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setCursorPosition",payload:{type:e.type,data:{x:e.x,y:e.y}}}}}})}async setIgnoreCursorEvents(e){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"setIgnoreCursorEvents",payload:e}}}})}async startDragging(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{label:this.label,cmd:{type:"startDragging"}}}})}async onResized(e){return this.listen(l.WINDOW_RESIZED,(t=>{t.payload=ne(t.payload),e(t)}))}async onMoved(e){return this.listen(l.WINDOW_MOVED,(t=>{t.payload=ae(t.payload),e(t)}))}async onCloseRequested(e){return this.listen(l.WINDOW_CLOSE_REQUESTED,(t=>{const a=new Z(t);Promise.resolve(e(a)).then((()=>{if(!a.isPreventDefault())return this.close()}))}))}async onFocusChanged(e){const t=await this.listen(l.WINDOW_FOCUS,(t=>{e({...t,payload:!0})})),a=await this.listen(l.WINDOW_BLUR,(t=>{e({...t,payload:!1})}));return()=>{t(),a()}}async onScaleChanged(e){return this.listen(l.WINDOW_SCALE_FACTOR_CHANGED,e)}async onMenuClicked(e){return this.listen(l.MENU,e)}async onFileDropEvent(e){const t=await this.listen(l.WINDOW_FILE_DROP,(t=>{e({...t,payload:{type:"drop",paths:t.payload}})})),a=await this.listen(l.WINDOW_FILE_DROP_HOVER,(t=>{e({...t,payload:{type:"hover",paths:t.payload}})})),n=await this.listen(l.WINDOW_FILE_DROP_CANCELLED,(t=>{e({...t,payload:{type:"cancel"}})}));return()=>{t(),a(),n()}}async onThemeChanged(e){return this.listen(l.WINDOW_THEME_CHANGED,e)}}class Z{constructor(e){this._preventDefault=!1,this.event=e.event,this.windowLabel=e.windowLabel,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}class X extends Y{constructor(e,t={}){super(e),(null==t?void 0:t.skip)||i({__tauriModule:"Window",message:{cmd:"createWebview",data:{options:{label:e,...t}}}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static getByLabel(e){return $().some((t=>t.label===e))?new X(e,{skip:!0}):null}static async getFocusedWindow(){for(const e of $())if(await e.isFocused())return e;return null}}let ee;function te(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:ae(e.position),size:ne(e.size)}}function ae(e){return new J(e.x,e.y)}function ne(e){return new G(e.width,e.height)}"__TAURI_METADATA__"in window?ee=new X(window.__TAURI_METADATA__.__currentWindow.label,{skip:!0}):(console.warn('Could not find "window.__TAURI_METADATA__". The "appWindow" value will reference the "main" window label.\nNote that this is not an issue if running this frontend on a browser instead of a Tauri window.'),ee=new X("main",{skip:!0}));var ie=Object.freeze({__proto__:null,CloseRequestedEvent:Z,LogicalPosition:q,LogicalSize:B,PhysicalPosition:J,PhysicalSize:G,get UserAttentionType(){return H},WebviewWindow:X,WebviewWindowHandle:Q,WindowManager:Y,get appWindow(){return ee},availableMonitors:async function(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"availableMonitors"}}}}).then((e=>e.map(te)))},currentMonitor:async function(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"currentMonitor"}}}}).then(te)},getAll:$,getCurrent:function(){return new X(window.__TAURI_METADATA__.__currentWindow.label,{skip:!0})},primaryMonitor:async function(){return i({__tauriModule:"Window",message:{cmd:"manage",data:{cmd:{type:"primaryMonitor"}}}}).then(te)}});const re=T()?"\r\n":"\n";var se=Object.freeze({__proto__:null,EOL:re,arch:async function(){return i({__tauriModule:"Os",message:{cmd:"arch"}})},locale:async function(){return i({__tauriModule:"Os",message:{cmd:"locale"}})},platform:async function(){return i({__tauriModule:"Os",message:{cmd:"platform"}})},tempdir:async function(){return i({__tauriModule:"Os",message:{cmd:"tempdir"}})},type:async function(){return i({__tauriModule:"Os",message:{cmd:"osType"}})},version:async function(){return i({__tauriModule:"Os",message:{cmd:"version"}})}});const oe=a;return e.app=r,e.cli=s,e.clipboard=o,e.dialog=u,e.event=f,e.fs=w,e.globalShortcut=M,e.http=L,e.invoke=oe,e.notification=O,e.os=se,e.path=I,e.process=x,e.shell=j,e.tauri=n,e.updater=V,e.window=ie,e}({});window.__TAURI__=__TAURI_IIFE__; diff --git a/core/tauri/src/endpoints/shell.rs b/core/tauri/src/endpoints/shell.rs index daf0d47b161e..931f4cef51c7 100644 --- a/core/tauri/src/endpoints/shell.rs +++ b/core/tauri/src/endpoints/shell.rs @@ -8,7 +8,7 @@ use super::InvokeContext; use crate::{api::ipc::CallbackFn, Runtime}; #[cfg(shell_scope)] use crate::{Manager, Scopes}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use tauri_macros::{command_enum, module_command_handler, CommandModule}; #[cfg(shell_scope)] @@ -63,6 +63,15 @@ pub struct CommandOptions { #[derive(Deserialize, CommandModule)] #[serde(tag = "cmd", rename_all = "camelCase")] pub enum Cmd { + /// The execute and return script API. + #[cmd(shell_script, "shell > execute or shell > sidecar")] + #[serde(rename_all = "camelCase")] + ExecuteAndReturn { + program: String, + args: ExecuteArgs, + #[serde(default)] + options: CommandOptions, + }, /// The execute script API. #[cmd(shell_script, "shell > execute or shell > sidecar")] #[serde(rename_all = "camelCase")] @@ -81,7 +90,73 @@ pub enum Cmd { Open { path: String, with: Option }, } +#[derive(Serialize)] +#[cfg(any(shell_execute, shell_sidecar))] +struct ChildProcessReturn { + code: Option, + signal: Option, + stdout: String, + stderr: String, +} + impl Cmd { + #[module_command_handler(shell_script)] + #[allow(unused_variables)] + fn execute_and_return( + context: InvokeContext, + program: String, + args: ExecuteArgs, + options: CommandOptions, + ) -> super::Result { + let mut command = prepare_cmd(&context, &program, args, &options)?; + + #[cfg(any(shell_execute, shell_sidecar))] + { + if let Some(cwd) = options.cwd { + command = command.current_dir(cwd); + } + if let Some(env) = options.env { + command = command.envs(env); + } else { + command = command.env_clear(); + } + + let encoding = if let Some(encoding) = options.encoding { + if let Some(encoding) = crate::api::process::Encoding::for_label(encoding.as_bytes()) { + Some(encoding) + } else { + return Err(anyhow::anyhow!(format!("unknown encoding {encoding}"))); + } + } else { + None + }; + + let mut command: std::process::Command = command.into(); + let output = command.output()?; + + let (stdout, stderr) = match encoding { + Some(encoding) => ( + encoding.decode_with_bom_removal(&output.stdout).0.into(), + encoding.decode_with_bom_removal(&output.stderr).0.into(), + ), + None => ( + String::from_utf8(output.stdout)?, + String::from_utf8(output.stderr)?, + ), + }; + + Ok(ChildProcessReturn { + code: output.status.code(), + #[cfg(windows)] + signal: None, + #[cfg(unix)] + signal: output.status.signal(), + stdout, + stderr, + }) + } + } + #[module_command_handler(shell_script)] #[allow(unused_variables)] fn execute( @@ -91,55 +166,11 @@ impl Cmd { on_event_fn: CallbackFn, options: CommandOptions, ) -> super::Result { - let mut command = if options.sidecar { - #[cfg(not(shell_sidecar))] - return Err(crate::Error::ApiNotAllowlisted("shell > sidecar".to_string()).into_anyhow()); - #[cfg(shell_sidecar)] - { - let program = PathBuf::from(program); - let program_as_string = program.display().to_string(); - let program_no_ext_as_string = program.with_extension("").display().to_string(); - let configured_sidecar = context - .config - .tauri - .bundle - .external_bin - .as_ref() - .map(|bins| { - bins - .iter() - .find(|b| b == &&program_as_string || b == &&program_no_ext_as_string) - }) - .unwrap_or_default(); - if let Some(sidecar) = configured_sidecar { - context - .window - .state::() - .shell - .prepare_sidecar(&program.to_string_lossy(), sidecar, args) - .map_err(crate::error::into_anyhow)? - } else { - return Err(crate::Error::SidecarNotAllowed(program).into_anyhow()); - } - } - } else { - #[cfg(not(shell_execute))] - return Err(crate::Error::ApiNotAllowlisted("shell > execute".to_string()).into_anyhow()); - #[cfg(shell_execute)] - match context - .window - .state::() - .shell - .prepare(&program, args) - { - Ok(cmd) => cmd, - Err(e) => { - #[cfg(debug_assertions)] - eprintln!("{e}"); - return Err(crate::Error::ProgramNotAllowed(PathBuf::from(program)).into_anyhow()); - } - } - }; + use std::future::Future; + use std::pin::Pin; + + let mut command = prepare_cmd(&context, &program, args, &options)?; + #[cfg(any(shell_execute, shell_sidecar))] { if let Some(cwd) = options.cwd { @@ -226,6 +257,63 @@ impl Cmd { } } +fn prepare_cmd( + context: &InvokeContext, + program: &String, + args: ExecuteArgs, + options: &CommandOptions, +) -> super::Result { + if options.sidecar { + #[cfg(not(shell_sidecar))] + return Err(crate::Error::ApiNotAllowlisted("shell > sidecar".to_string()).into_anyhow()); + #[cfg(shell_sidecar)] + { + let program = PathBuf::from(program); + let program_as_string = program.display().to_string(); + let program_no_ext_as_string = program.with_extension("").display().to_string(); + let configured_sidecar = context + .config + .tauri + .bundle + .external_bin + .as_ref() + .map(|bins| { + bins + .iter() + .find(|b| b == &&program_as_string || b == &&program_no_ext_as_string) + }) + .unwrap_or_default(); + if let Some(sidecar) = configured_sidecar { + context + .window + .state::() + .shell + .prepare_sidecar(&program.to_string_lossy(), sidecar, args) + .map_err(crate::error::into_anyhow) + } else { + return Err(crate::Error::SidecarNotAllowed(program).into_anyhow()); + } + } + } else { + #[cfg(not(shell_execute))] + return Err(crate::Error::ApiNotAllowlisted("shell > execute".to_string()).into_anyhow()); + #[cfg(shell_execute)] + match context + .window + .state::() + .shell + .prepare(&program, args) + { + Ok(cmd) => Ok(cmd), + Err(e) => { + #[cfg(debug_assertions)] + eprintln!("{e}"); + return Err(crate::Error::ProgramNotAllowed(PathBuf::from(program)).into_anyhow()); + } + } + } +} + #[cfg(test)] mod tests { use super::{Buffer, ChildId, CommandOptions, ExecuteArgs}; diff --git a/tooling/api/src/shell.ts b/tooling/api/src/shell.ts index 51c55fce20ee..5c0e71f9a863 100644 --- a/tooling/api/src/shell.ts +++ b/tooling/api/src/shell.ts @@ -115,38 +115,6 @@ interface ChildProcess { stderr: string } -/** - * Spawns a process. - * - * @ignore - * @param program The name of the scoped command. - * @param onEvent Event handler. - * @param args Program arguments. - * @param options Configuration for the process spawn. - * @returns A promise resolving to the process id. - */ -async function execute( - onEvent: (event: CommandEvent) => void, - program: string, - args: string | string[] = [], - options?: InternalSpawnOptions -): Promise { - if (typeof args === 'object') { - Object.freeze(args) - } - - return invokeTauriCommand({ - __tauriModule: 'Shell', - message: { - cmd: 'execute', - program, - args, - options, - onEventFn: transformCallback(onEvent) - } - }) -} - /** * @since 1.0.0 */ @@ -449,27 +417,41 @@ class Command extends EventEmitter<'close' | 'error'> { * @returns A promise resolving to the child process handle. */ async spawn(): Promise { - return execute( - (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 - } - }, - this.program, - this.args, - this.options - ).then((pid) => new Child(pid)) + const program = this.program + const args = this.args + const options = this.options + + if (typeof args === 'object') { + Object.freeze(args) + } + + const onEvent = (event: CommandEvent) => { + 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 + } + } + + return invokeTauriCommand({ + __tauriModule: 'Shell', + message: { + cmd: 'execute', + program, + args, + options, + onEventFn: transformCallback(onEvent) + } + }).then((pid) => new Child(pid)) } /** @@ -487,25 +469,22 @@ class Command extends EventEmitter<'close' | 'error'> { * @returns A promise resolving to the child process output. */ async execute(): Promise { - return new Promise((resolve, reject) => { - this.on('error', reject) - const stdout: string[] = [] - const stderr: string[] = [] - this.stdout.on('data', (line: string) => { - stdout.push(line) - }) - this.stderr.on('data', (line: string) => { - stderr.push(line) - }) - this.on('close', (payload: TerminatedPayload) => { - resolve({ - code: payload.code, - signal: payload.signal, - stdout: stdout.join('\n'), - stderr: stderr.join('\n') - }) - }) - this.spawn().catch(reject) + const program = this.program + const args = this.args + const options = this.options + + if (typeof args === 'object') { + Object.freeze(args) + } + + return invokeTauriCommand({ + __tauriModule: 'Shell', + message: { + cmd: 'executeAndReturn', + program, + args, + options + } }) } } From be2da3a9709c69948c3fcbf623a6f815e2836efa Mon Sep 17 00:00:00 2001 From: amrbashir Date: Wed, 8 May 2024 19:46:38 +0300 Subject: [PATCH 2/4] fix unix build --- core/tauri/src/endpoints/shell.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/tauri/src/endpoints/shell.rs b/core/tauri/src/endpoints/shell.rs index 931f4cef51c7..b270a6f03dac 100644 --- a/core/tauri/src/endpoints/shell.rs +++ b/core/tauri/src/endpoints/shell.rs @@ -145,6 +145,9 @@ impl Cmd { ), }; + #[cfg(unix)] + use std::os::unix::process::ExitStatusExt; + Ok(ChildProcessReturn { code: output.status.code(), #[cfg(windows)] From 906c4cc7ff1fd16aedd5a417474cb64e95424651 Mon Sep 17 00:00:00 2001 From: amrbashir Date: Wed, 8 May 2024 20:08:16 +0300 Subject: [PATCH 3/4] clippy --- core/tauri/src/endpoints/shell.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/tauri/src/endpoints/shell.rs b/core/tauri/src/endpoints/shell.rs index b270a6f03dac..788a3810af1f 100644 --- a/core/tauri/src/endpoints/shell.rs +++ b/core/tauri/src/endpoints/shell.rs @@ -294,7 +294,7 @@ fn prepare_cmd( .prepare_sidecar(&program.to_string_lossy(), sidecar, args) .map_err(crate::error::into_anyhow) } else { - return Err(crate::Error::SidecarNotAllowed(program).into_anyhow()); + Err(crate::Error::SidecarNotAllowed(program).into_anyhow()) } } } else { @@ -305,13 +305,13 @@ fn prepare_cmd( .window .state::() .shell - .prepare(&program, args) + .prepare(program, args) { Ok(cmd) => Ok(cmd), Err(e) => { #[cfg(debug_assertions)] eprintln!("{e}"); - return Err(crate::Error::ProgramNotAllowed(PathBuf::from(program)).into_anyhow()); + Err(crate::Error::ProgramNotAllowed(PathBuf::from(program)).into_anyhow()) } } } From 0658f9f2d191faafadc92ea84e03c9449af0aebb Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Thu, 9 May 2024 10:48:02 -0300 Subject: [PATCH 4/4] cleanup --- core/tauri/src/endpoints/shell.rs | 152 +++++++++++++----------------- 1 file changed, 66 insertions(+), 86 deletions(-) diff --git a/core/tauri/src/endpoints/shell.rs b/core/tauri/src/endpoints/shell.rs index 788a3810af1f..90d8db63e444 100644 --- a/core/tauri/src/endpoints/shell.rs +++ b/core/tauri/src/endpoints/shell.rs @@ -101,67 +101,47 @@ struct ChildProcessReturn { impl Cmd { #[module_command_handler(shell_script)] - #[allow(unused_variables)] fn execute_and_return( context: InvokeContext, program: String, args: ExecuteArgs, options: CommandOptions, ) -> super::Result { - let mut command = prepare_cmd(&context, &program, args, &options)?; - - #[cfg(any(shell_execute, shell_sidecar))] - { - if let Some(cwd) = options.cwd { - command = command.current_dir(cwd); - } - if let Some(env) = options.env { - command = command.envs(env); - } else { - command = command.env_clear(); - } - - let encoding = if let Some(encoding) = options.encoding { - if let Some(encoding) = crate::api::process::Encoding::for_label(encoding.as_bytes()) { - Some(encoding) - } else { - return Err(anyhow::anyhow!(format!("unknown encoding {encoding}"))); - } - } else { - None - }; - - let mut command: std::process::Command = command.into(); - let output = command.output()?; - - let (stdout, stderr) = match encoding { - Some(encoding) => ( - encoding.decode_with_bom_removal(&output.stdout).0.into(), - encoding.decode_with_bom_removal(&output.stderr).0.into(), - ), - None => ( - String::from_utf8(output.stdout)?, - String::from_utf8(output.stderr)?, - ), - }; - + let encoding = options + .encoding + .as_ref() + .and_then(|encoding| crate::api::process::Encoding::for_label(encoding.as_bytes())); + let command = prepare_cmd(&context, &program, args, options)?; + + let mut command: std::process::Command = command.into(); + let output = command.output()?; + + let (stdout, stderr) = match encoding { + Some(encoding) => ( + encoding.decode_with_bom_removal(&output.stdout).0.into(), + encoding.decode_with_bom_removal(&output.stderr).0.into(), + ), + None => ( + String::from_utf8(output.stdout)?, + String::from_utf8(output.stderr)?, + ), + }; + + #[cfg(unix)] + use std::os::unix::process::ExitStatusExt; + + Ok(ChildProcessReturn { + code: output.status.code(), + #[cfg(windows)] + signal: None, #[cfg(unix)] - use std::os::unix::process::ExitStatusExt; - - Ok(ChildProcessReturn { - code: output.status.code(), - #[cfg(windows)] - signal: None, - #[cfg(unix)] - signal: output.status.signal(), - stdout, - stderr, - }) - } + signal: output.status.signal(), + stdout, + stderr, + }) } #[module_command_handler(shell_script)] - #[allow(unused_variables)] fn execute( context: InvokeContext, program: String, @@ -172,44 +152,26 @@ impl Cmd { use std::future::Future; use std::pin::Pin; - let mut command = prepare_cmd(&context, &program, args, &options)?; + let command = prepare_cmd(&context, &program, args, options)?; - #[cfg(any(shell_execute, shell_sidecar))] - { - if let Some(cwd) = options.cwd { - command = command.current_dir(cwd); - } - if let Some(env) = options.env { - command = command.envs(env); - } else { - command = command.env_clear(); - } - if let Some(encoding) = options.encoding { - if let Some(encoding) = crate::api::process::Encoding::for_label(encoding.as_bytes()) { - command = command.encoding(encoding); - } else { - return Err(anyhow::anyhow!(format!("unknown encoding {encoding}"))); - } - } - let (mut rx, child) = command.spawn()?; - - let pid = child.pid(); - command_child_store().lock().unwrap().insert(pid, child); + let (mut rx, child) = command.spawn()?; - crate::async_runtime::spawn(async move { - while let Some(event) = rx.recv().await { - if matches!(event, crate::api::process::CommandEvent::Terminated(_)) { - command_child_store().lock().unwrap().remove(&pid); - } - let js = crate::api::ipc::format_callback(on_event_fn, &event) - .expect("unable to serialize CommandEvent"); + let pid = child.pid(); + command_child_store().lock().unwrap().insert(pid, child); - let _ = context.window.eval(js.as_str()); + crate::async_runtime::spawn(async move { + while let Some(event) = rx.recv().await { + if matches!(event, crate::api::process::CommandEvent::Terminated(_)) { + command_child_store().lock().unwrap().remove(&pid); } - }); + let js = crate::api::ipc::format_callback(on_event_fn, &event) + .expect("unable to serialize CommandEvent"); - Ok(pid) - } + let _ = context.window.eval(js.as_str()); + } + }); + + Ok(pid) } #[module_command_handler(shell_script)] @@ -264,9 +226,9 @@ fn prepare_cmd( context: &InvokeContext, program: &String, args: ExecuteArgs, - options: &CommandOptions, + options: CommandOptions, ) -> super::Result { - if options.sidecar { + let mut command = if options.sidecar { #[cfg(not(shell_sidecar))] return Err(crate::Error::ApiNotAllowlisted("shell > sidecar".to_string()).into_anyhow()); #[cfg(shell_sidecar)] @@ -314,7 +276,25 @@ fn prepare_cmd( Err(crate::Error::ProgramNotAllowed(PathBuf::from(program)).into_anyhow()) } } + }?; + + if let Some(cwd) = options.cwd { + command = command.current_dir(cwd); + } + if let Some(env) = options.env { + command = command.envs(env); + } else { + command = command.env_clear(); } + if let Some(encoding) = &options.encoding { + if let Some(encoding) = crate::api::process::Encoding::for_label(encoding.as_bytes()) { + command = command.encoding(encoding); + } else { + return Err(anyhow::anyhow!(format!("unknown encoding {encoding}"))); + } + } + + Ok(command) } #[cfg(test)]