mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-02-06 13:57:16 +00:00
Co-authored-by: Quentin Goinaud <armaldio@gmail.com> Co-authored-by: Lucas Fernandes Nogueira <lucasfernandesnog@gmail.com> Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
parent
14cddd404c
commit
2681ad361b
5
.changes/ts-api.md
Normal file
5
.changes/ts-api.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri.js": minor
|
||||
---
|
||||
|
||||
Create UMD, ESM and CJS artifacts for the JavaScript API entry point from TS source using rollup.
|
||||
6
.changes/window-tauri.md
Normal file
6
.changes/window-tauri.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri.js": minor
|
||||
---
|
||||
|
||||
Renaming `window.tauri` to `window.__TAURI__`, closing #435.
|
||||
The `__TAURI__` object now follows the TypeScript API structure (e.g. `window.__TAURI__.readTextFile` is now `window.__TAURI__.fs.readTextFile`).
|
||||
2
.github/workflows/build-smoke-tests.yml
vendored
2
.github/workflows/build-smoke-tests.yml
vendored
@ -87,7 +87,7 @@ jobs:
|
||||
- name: install cli deps via yarn
|
||||
working-directory: ./cli/tauri.js
|
||||
run: yarn
|
||||
- name: build cli
|
||||
- name: build cli & api
|
||||
working-directory: ./cli/tauri.js
|
||||
run: yarn build
|
||||
- name: cache node modules
|
||||
|
||||
1
cli/deno
Submodule
1
cli/deno
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 55fd9104fa4da3b7afb96a16bb1ed8378b028a5a
|
||||
3
cli/tauri.js/.gitignore
vendored
3
cli/tauri.js/.gitignore
vendored
@ -63,6 +63,9 @@ debug.log
|
||||
package-lock.json
|
||||
.vscode/settings.json
|
||||
|
||||
#api
|
||||
api/*
|
||||
|
||||
# Tauri output
|
||||
bundle.json
|
||||
config.json
|
||||
|
||||
23
cli/tauri.js/api-src/bundle.ts
Normal file
23
cli/tauri.js/api-src/bundle.ts
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
import 'regenerator-runtime/runtime'
|
||||
import * as cli from './cli'
|
||||
import * as dialog from './dialog'
|
||||
import * as event from './event'
|
||||
import * as fs from './fs'
|
||||
import http from './http'
|
||||
import * as process from './process'
|
||||
import * as tauri from './tauri'
|
||||
import * as window from './window'
|
||||
import * as notification from './notification'
|
||||
|
||||
export {
|
||||
cli,
|
||||
dialog,
|
||||
event,
|
||||
fs,
|
||||
http,
|
||||
process,
|
||||
tauri,
|
||||
window,
|
||||
notification
|
||||
}
|
||||
15
cli/tauri.js/api-src/cli.ts
Normal file
15
cli/tauri.js/api-src/cli.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { CliMatches } from './types/cli'
|
||||
import { promisified } from './tauri'
|
||||
|
||||
/**
|
||||
* gets the CLI matches
|
||||
*/
|
||||
async function getMatches(): Promise<CliMatches> {
|
||||
return await promisified<CliMatches>({
|
||||
cmd: 'cliMatches'
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
getMatches
|
||||
}
|
||||
47
cli/tauri.js/api-src/dialog.ts
Normal file
47
cli/tauri.js/api-src/dialog.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { OpenDialogOptions, SaveDialogOptions } from './types/dialog'
|
||||
import { promisified } from './tauri'
|
||||
|
||||
/**
|
||||
* @name openDialog
|
||||
* @description Open a file/directory selection dialog
|
||||
* @param [options]
|
||||
* @param [options.filter]
|
||||
* @param [options.defaultPath]
|
||||
* @param [options.multiple=false]
|
||||
* @param [options.directory=false]
|
||||
* @returns promise resolving to the select path(s)
|
||||
*/
|
||||
async function open(options: OpenDialogOptions = {}): Promise<String | String[]> {
|
||||
if (typeof options === 'object') {
|
||||
Object.freeze(options)
|
||||
}
|
||||
|
||||
return await promisified({
|
||||
cmd: 'openDialog',
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @name save
|
||||
* @description Open a file/directory save dialog
|
||||
* @param [options]
|
||||
* @param [options.filter]
|
||||
* @param [options.defaultPath]
|
||||
* @returns promise resolving to the select path
|
||||
*/
|
||||
async function save(options: SaveDialogOptions = {}): Promise<String> {
|
||||
if (typeof options === 'object') {
|
||||
Object.freeze(options)
|
||||
}
|
||||
|
||||
return await promisified({
|
||||
cmd: 'saveDialog',
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
open,
|
||||
save
|
||||
}
|
||||
36
cli/tauri.js/api-src/event.ts
Normal file
36
cli/tauri.js/api-src/event.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { invoke, transformCallback } from './tauri'
|
||||
import { EventCallback } from './types/event'
|
||||
|
||||
/**
|
||||
* listen to an event from the backend
|
||||
*
|
||||
* @param event the event name
|
||||
* @param handler the event handler callback
|
||||
*/
|
||||
function listen(event: string, handler: EventCallback, once = false): void {
|
||||
invoke({
|
||||
cmd: 'listen',
|
||||
event,
|
||||
handler: transformCallback(handler, once),
|
||||
once
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* emits an event to the backend
|
||||
*
|
||||
* @param event the event name
|
||||
* @param [payload] the event payload
|
||||
*/
|
||||
function emit(event: string, payload?: string): void {
|
||||
invoke({
|
||||
cmd: 'emit',
|
||||
event,
|
||||
payload
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
listen,
|
||||
emit
|
||||
}
|
||||
239
cli/tauri.js/api-src/fs.ts
Normal file
239
cli/tauri.js/api-src/fs.ts
Normal file
@ -0,0 +1,239 @@
|
||||
import { promisified } from './tauri'
|
||||
import { BaseDirectory, FsOptions, FsTextFileOption, FsBinaryFileOption, FileEntry } from './types/fs'
|
||||
|
||||
/**
|
||||
* reads a file as text
|
||||
*
|
||||
* @param filePath path to the file
|
||||
* @param [options] configuration object
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function readTextFile(filePath: string, options: FsOptions = {}): Promise<string> {
|
||||
return await promisified({
|
||||
cmd: 'readTextFile',
|
||||
path: filePath,
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* reads a file as binary
|
||||
*
|
||||
* @param filePath path to the file
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<int[]>}
|
||||
*/
|
||||
async function readBinaryFile(filePath: string, options: FsOptions = {}): Promise<string> {
|
||||
return await promisified({
|
||||
cmd: 'readBinaryFile',
|
||||
path: filePath,
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* writes a text file
|
||||
*
|
||||
* @param file
|
||||
* @param file.path path of the file
|
||||
* @param file.contents contents of the file
|
||||
* @param [options] configuration object
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function writeFile(file: FsTextFileOption, options: FsOptions = {}): Promise<void> {
|
||||
if (typeof options === 'object') {
|
||||
Object.freeze(options)
|
||||
}
|
||||
if (typeof file === 'object') {
|
||||
Object.freeze(file)
|
||||
}
|
||||
|
||||
return await promisified({
|
||||
cmd: 'writeFile',
|
||||
file: file.path,
|
||||
contents: file.contents,
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
const CHUNK_SIZE = 65536
|
||||
|
||||
/**
|
||||
* convert an Uint8Array to ascii string
|
||||
*
|
||||
* @param arr
|
||||
* @return ASCII string
|
||||
*/
|
||||
function uint8ArrayToString(arr: Uint8Array): string {
|
||||
if (arr.length < CHUNK_SIZE) {
|
||||
return String.fromCharCode.apply(null, Array.from(arr))
|
||||
}
|
||||
|
||||
let result = ''
|
||||
const arrLen = arr.length
|
||||
for (let i = 0; i < arrLen; i++) {
|
||||
const chunk = arr.subarray(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE)
|
||||
result += String.fromCharCode.apply(null, Array.from(chunk))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* convert an ArrayBuffer to base64 encoded string
|
||||
*
|
||||
* @param buffer
|
||||
* @return base64 encoded string
|
||||
*/
|
||||
function arrayBufferToBase64(buffer: ArrayBuffer): string {
|
||||
const str = uint8ArrayToString(new Uint8Array(buffer))
|
||||
return btoa(str)
|
||||
}
|
||||
|
||||
/**
|
||||
* writes a binary file
|
||||
*
|
||||
* @param file
|
||||
* @param file.path path of the file
|
||||
* @param file.contents contents of the file
|
||||
* @param [options] configuration object
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function writeBinaryFile(file: FsBinaryFileOption, options: FsOptions = {}): Promise<void> {
|
||||
if (typeof options === 'object') {
|
||||
Object.freeze(options)
|
||||
}
|
||||
if (typeof file === 'object') {
|
||||
Object.freeze(file)
|
||||
}
|
||||
|
||||
return await promisified({
|
||||
cmd: 'writeFile',
|
||||
file: file.path,
|
||||
contents: arrayBufferToBase64(file.contents),
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* list directory files
|
||||
*
|
||||
* @param dir path to the directory to read
|
||||
* @param [options] configuration object
|
||||
* @param [options.recursive] whether to list dirs recursively or not
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function readDir(dir: string, options: FsOptions = {}): Promise<FileEntry[]> {
|
||||
return await promisified({
|
||||
cmd: 'readDir',
|
||||
path: dir,
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a directory
|
||||
* If one of the path's parent components doesn't exist
|
||||
* and the `recursive` option isn't set to true, it will be rejected
|
||||
*
|
||||
* @param dir path to the directory to create
|
||||
* @param [options] configuration object
|
||||
* @param [options.recursive] whether to create the directory's parent components or not
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function createDir(dir: string, options: FsOptions = {}): Promise<void> {
|
||||
return await promisified({
|
||||
cmd: 'createDir',
|
||||
path: dir,
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a directory
|
||||
* If the directory is not empty and the `recursive` option isn't set to true, it will be rejected
|
||||
*
|
||||
* @param dir path to the directory to remove
|
||||
* @param [options] configuration object
|
||||
* @param [options.recursive] whether to remove all of the directory's content or not
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function removeDir(dir: string, options: FsOptions = {}): Promise<void> {
|
||||
return await promisified({
|
||||
cmd: 'removeDir',
|
||||
path: dir,
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy file
|
||||
*
|
||||
* @param source
|
||||
* @param destination
|
||||
* @param [options] configuration object
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function copyFile(source: string, destination: string, options: FsOptions = {}): Promise<void> {
|
||||
return await promisified({
|
||||
cmd: 'copyFile',
|
||||
source,
|
||||
destination,
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a file
|
||||
*
|
||||
* @param file path to the file to remove
|
||||
* @param [options] configuration object
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function removeFile(file: string, options: FsOptions = {}): Promise<void> {
|
||||
return await promisified({
|
||||
cmd: 'removeFile',
|
||||
path: file,
|
||||
options: options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a file
|
||||
*
|
||||
* @param oldPath
|
||||
* @param newPath
|
||||
* @param [options] configuration object
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function renameFile(oldPath: string, newPath: string, options: FsOptions = {}): Promise<void> {
|
||||
return await promisified({
|
||||
cmd: 'renameFile',
|
||||
oldPath,
|
||||
newPath,
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
BaseDirectory as Dir,
|
||||
readTextFile,
|
||||
readBinaryFile,
|
||||
writeFile,
|
||||
writeBinaryFile,
|
||||
readDir,
|
||||
createDir,
|
||||
removeDir,
|
||||
copyFile,
|
||||
removeFile,
|
||||
renameFile
|
||||
}
|
||||
111
cli/tauri.js/api-src/http.ts
Normal file
111
cli/tauri.js/api-src/http.ts
Normal file
@ -0,0 +1,111 @@
|
||||
import { promisified } from './tauri'
|
||||
import { HttpOptions, Body, BodyType, ResponseType, PartialOptions } from './types/http'
|
||||
|
||||
/**
|
||||
* makes a HTTP request
|
||||
*
|
||||
* @param options request options
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function request<T>(options: HttpOptions): Promise<T> {
|
||||
return await promisified({
|
||||
cmd: 'httpRequest',
|
||||
options: options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a GET request
|
||||
*
|
||||
* @param url request URL
|
||||
* @param options request options
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function get<T>(url: string, options: PartialOptions): Promise<T> {
|
||||
return await request({
|
||||
method: 'GET',
|
||||
url,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a POST request
|
||||
*
|
||||
* @param url request URL
|
||||
* @param body request body
|
||||
* @param options request options
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function post<T>(url: string, body: Body, options: PartialOptions): Promise<T> {
|
||||
return await request({
|
||||
method: 'POST',
|
||||
url,
|
||||
body,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a PUT request
|
||||
*
|
||||
* @param url request URL
|
||||
* @param body request body
|
||||
* @param options request options
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function put<T>(url: string, body: Body, options: PartialOptions): Promise<T> {
|
||||
return await request({
|
||||
method: 'PUT',
|
||||
url,
|
||||
body,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a PATCH request
|
||||
*
|
||||
* @param url request URL
|
||||
* @param options request options
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function patch<T>(url: string, options: PartialOptions): Promise<T> {
|
||||
return await request({
|
||||
method: 'PATCH',
|
||||
url,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a DELETE request
|
||||
*
|
||||
* @param url request URL
|
||||
* @param options request options
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function deleteRequest<T>(url: string, options: PartialOptions): Promise<T> {
|
||||
return await request({
|
||||
method: 'DELETE',
|
||||
url,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
request,
|
||||
get,
|
||||
post,
|
||||
put,
|
||||
patch,
|
||||
delete: deleteRequest,
|
||||
ResponseType,
|
||||
BodyType
|
||||
}
|
||||
2
cli/tauri.js/api-src/index.ts
Normal file
2
cli/tauri.js/api-src/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
import * as api from './bundle'
|
||||
export default api
|
||||
84
cli/tauri.js/api-src/notification.ts
Normal file
84
cli/tauri.js/api-src/notification.ts
Normal file
@ -0,0 +1,84 @@
|
||||
import { Options, PartialOptions, Permission } from './types/notification'
|
||||
import { promisified } from './tauri'
|
||||
|
||||
let permissionSettable = false
|
||||
let permissionValue = 'default'
|
||||
function setNotificationPermission(value: Permission): void {
|
||||
permissionSettable = true
|
||||
// @ts-expect-error
|
||||
window.Notification.permission = value
|
||||
permissionSettable = false
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
window.Notification = (title: string, options?: PartialOptions) => {
|
||||
sendNotification({
|
||||
title,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
window.Notification.requestPermission = requestPermission
|
||||
|
||||
Object.defineProperty(window.Notification, 'permission', {
|
||||
enumerable: true,
|
||||
get: () => permissionValue,
|
||||
set(v: Permission) {
|
||||
if (!permissionSettable) {
|
||||
throw new Error('Readonly property')
|
||||
}
|
||||
permissionValue = v
|
||||
}
|
||||
})
|
||||
|
||||
isPermissionGranted()
|
||||
.then(response => {
|
||||
if (response === null) {
|
||||
setNotificationPermission('default')
|
||||
} else {
|
||||
setNotificationPermission(response ? 'granted' : 'denied')
|
||||
}
|
||||
})
|
||||
.catch(err => { throw err })
|
||||
|
||||
async function isPermissionGranted(): Promise<boolean | null> {
|
||||
if (window.Notification.permission !== 'default') {
|
||||
return await Promise.resolve(window.Notification.permission === 'granted')
|
||||
}
|
||||
return await promisified({
|
||||
cmd: 'isNotificationPermissionGranted'
|
||||
})
|
||||
}
|
||||
|
||||
async function requestPermission(): Promise<Permission> {
|
||||
return await promisified<Permission>({
|
||||
cmd: 'requestNotificationPermission'
|
||||
}).then(permission => {
|
||||
setNotificationPermission(permission)
|
||||
return permission
|
||||
})
|
||||
}
|
||||
|
||||
function sendNotification(options: Options | string): void {
|
||||
if (typeof options === 'object') {
|
||||
Object.freeze(options)
|
||||
}
|
||||
|
||||
isPermissionGranted()
|
||||
.then(permission => {
|
||||
if (permission) {
|
||||
return promisified({
|
||||
cmd: 'notification',
|
||||
options: typeof options === 'string' ? {
|
||||
body: options
|
||||
} : options
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(err => { throw err })
|
||||
}
|
||||
|
||||
export {
|
||||
sendNotification,
|
||||
isPermissionGranted
|
||||
}
|
||||
24
cli/tauri.js/api-src/process.ts
Normal file
24
cli/tauri.js/api-src/process.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { promisified } from './tauri'
|
||||
|
||||
/**
|
||||
* spawns a process
|
||||
*
|
||||
* @param command the name of the cmd to execute e.g. 'mkdir' or 'node'
|
||||
* @param [args] command args
|
||||
* @return promise resolving to the stdout text
|
||||
*/
|
||||
async function execute(command: string, args?: string | string[]): Promise<string> {
|
||||
if (typeof args === 'object') {
|
||||
Object.freeze(args)
|
||||
}
|
||||
|
||||
return await promisified({
|
||||
cmd: 'execute',
|
||||
command,
|
||||
args: typeof args === 'string' ? [args] : args
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
execute
|
||||
}
|
||||
53
cli/tauri.js/api-src/tauri.ts
Normal file
53
cli/tauri.js/api-src/tauri.ts
Normal file
@ -0,0 +1,53 @@
|
||||
declare global {
|
||||
interface External {
|
||||
invoke: (command: string) => void
|
||||
}
|
||||
}
|
||||
|
||||
function s4(): string {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1)
|
||||
}
|
||||
|
||||
function uid(): string {
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4()
|
||||
}
|
||||
|
||||
function invoke(args: any): void {
|
||||
window.external.invoke(typeof args === 'object' ? JSON.stringify(args) : args)
|
||||
}
|
||||
|
||||
function transformCallback(callback?: (response: any) => void, once = false): string {
|
||||
const identifier = uid()
|
||||
|
||||
Object.defineProperty(window, identifier, {
|
||||
value: (result: any) => {
|
||||
if (once) {
|
||||
Reflect.deleteProperty(window, identifier)
|
||||
}
|
||||
|
||||
return callback?.(result)
|
||||
},
|
||||
writable: false
|
||||
})
|
||||
|
||||
return identifier
|
||||
}
|
||||
|
||||
async function promisified<T>(args: any): Promise<T> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
invoke({
|
||||
callback: transformCallback(resolve),
|
||||
error: transformCallback(reject),
|
||||
...args
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
invoke,
|
||||
transformCallback,
|
||||
promisified
|
||||
}
|
||||
17
cli/tauri.js/api-src/tsconfig.json
Normal file
17
cli/tauri.js/api-src/tsconfig.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"strict": true,
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"types": ["@types"]
|
||||
},
|
||||
},
|
||||
"include": ["./"]
|
||||
}
|
||||
22
cli/tauri.js/api-src/types/cli.ts
Normal file
22
cli/tauri.js/api-src/types/cli.ts
Normal file
@ -0,0 +1,22 @@
|
||||
export interface ArgMatch {
|
||||
/**
|
||||
* string if takes value
|
||||
* boolean if flag
|
||||
* string[] or null if takes multiple values
|
||||
*/
|
||||
value: string | boolean | string[] | null
|
||||
/**
|
||||
* number of occurrences
|
||||
*/
|
||||
occurrences: number
|
||||
}
|
||||
|
||||
export interface SubcommandMatch {
|
||||
name: string
|
||||
matches: CliMatches
|
||||
}
|
||||
|
||||
export interface CliMatches {
|
||||
args: { [name: string]: ArgMatch }
|
||||
subcommand: SubcommandMatch | null
|
||||
}
|
||||
8
cli/tauri.js/api-src/types/dialog.ts
Normal file
8
cli/tauri.js/api-src/types/dialog.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export interface OpenDialogOptions {
|
||||
filter?: string
|
||||
defaultPath?: string
|
||||
multiple?: boolean
|
||||
directory?: boolean
|
||||
}
|
||||
|
||||
export type SaveDialogOptions = Pick<OpenDialogOptions, 'filter' | 'defaultPath'>
|
||||
6
cli/tauri.js/api-src/types/event.ts
Normal file
6
cli/tauri.js/api-src/types/event.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export interface Event {
|
||||
type: string
|
||||
payload: unknown
|
||||
}
|
||||
|
||||
export type EventCallback = (event: Event) => void
|
||||
41
cli/tauri.js/api-src/types/fs.ts
Normal file
41
cli/tauri.js/api-src/types/fs.ts
Normal file
@ -0,0 +1,41 @@
|
||||
export enum BaseDirectory {
|
||||
Audio = 1,
|
||||
Cache,
|
||||
Config,
|
||||
Data,
|
||||
LocalData,
|
||||
Desktop,
|
||||
Document,
|
||||
Download,
|
||||
Executable,
|
||||
Font,
|
||||
Home,
|
||||
Picture,
|
||||
Public,
|
||||
Runtime,
|
||||
Template,
|
||||
Video,
|
||||
Resource,
|
||||
App,
|
||||
}
|
||||
|
||||
export interface FsOptions {
|
||||
dir?: BaseDirectory
|
||||
}
|
||||
|
||||
export interface FsTextFileOption {
|
||||
path: string
|
||||
contents: string
|
||||
}
|
||||
|
||||
export interface FsBinaryFileOption {
|
||||
path: string
|
||||
contents: ArrayBuffer
|
||||
}
|
||||
|
||||
export interface FileEntry {
|
||||
path: string
|
||||
// TODO why not camelCase ?
|
||||
is_dir: boolean
|
||||
name: string
|
||||
}
|
||||
33
cli/tauri.js/api-src/types/http.ts
Normal file
33
cli/tauri.js/api-src/types/http.ts
Normal file
@ -0,0 +1,33 @@
|
||||
export enum ResponseType {
|
||||
JSON = 1,
|
||||
Text = 2,
|
||||
Binary = 3
|
||||
}
|
||||
|
||||
export enum BodyType {
|
||||
Form = 1,
|
||||
File = 2,
|
||||
Auto = 3
|
||||
}
|
||||
|
||||
export type Body = object | string | BinaryType
|
||||
|
||||
export type HttpVerb = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE'
|
||||
|
||||
export interface HttpOptions {
|
||||
method: HttpVerb
|
||||
url: string
|
||||
headers?: Record<string, any>
|
||||
propertys?: Record<string, any>
|
||||
body?: Body
|
||||
followRedirects: boolean
|
||||
maxRedirections: boolean
|
||||
connectTimeout: number
|
||||
readTimeout: number
|
||||
timeout: number
|
||||
allowCompression: boolean
|
||||
responseType?: ResponseType
|
||||
bodyType: BodyType
|
||||
}
|
||||
|
||||
export type PartialOptions = Omit<HttpOptions, 'method' | 'url'>
|
||||
8
cli/tauri.js/api-src/types/notification.ts
Normal file
8
cli/tauri.js/api-src/types/notification.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export interface Options {
|
||||
title?: string
|
||||
body?: string
|
||||
icon?: string
|
||||
}
|
||||
|
||||
export type PartialOptions = Omit<Options, 'title'>
|
||||
export type Permission = 'granted' | 'denied' | 'default'
|
||||
30
cli/tauri.js/api-src/window.ts
Normal file
30
cli/tauri.js/api-src/window.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { invoke } from './tauri'
|
||||
|
||||
/**
|
||||
* sets the window title
|
||||
*
|
||||
* @param title the new title
|
||||
*/
|
||||
function setTitle(title: string): void {
|
||||
invoke({
|
||||
cmd: 'setTitle',
|
||||
title
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* opens an URL on the user default browser
|
||||
*
|
||||
* @param url the URL to open
|
||||
*/
|
||||
function open(url: string): void {
|
||||
invoke({
|
||||
cmd: 'open',
|
||||
uri: url
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
setTitle,
|
||||
open
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import tauri from './tauri'
|
||||
|
||||
/**
|
||||
* gets the CLI matches
|
||||
*/
|
||||
function getMatches() {
|
||||
return tauri.cliMatches()
|
||||
}
|
||||
|
||||
export {
|
||||
getMatches
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
import tauri from './tauri'
|
||||
|
||||
/**
|
||||
* @name openDialog
|
||||
* @description Open a file/directory selection dialog
|
||||
* @param {Object} [options]
|
||||
* @param {String} [options.filter]
|
||||
* @param {String} [options.defaultPath]
|
||||
* @param {Boolean} [options.multiple=false]
|
||||
* @param {Boolean} [options.directory=false]
|
||||
* @returns {Promise<String|String[]>} promise resolving to the select path(s)
|
||||
*/
|
||||
function open (options = {}) {
|
||||
return tauri.openDialog(options)
|
||||
}
|
||||
|
||||
/**
|
||||
* @name save
|
||||
* @description Open a file/directory save dialog
|
||||
* @param {Object} [options]
|
||||
* @param {String} [options.filter]
|
||||
* @param {String} [options.defaultPath]
|
||||
* @returns {Promise<String>} promise resolving to the select path
|
||||
*/
|
||||
function save (options = {}) {
|
||||
return tauri.saveDialog(options)
|
||||
}
|
||||
|
||||
export {
|
||||
open,
|
||||
save
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
import tauri from './tauri'
|
||||
|
||||
/**
|
||||
* The event handler callback
|
||||
* @callback EventCallback
|
||||
* @param {Object} event
|
||||
* @param {String} event.type
|
||||
* @param {any} [event.payload]
|
||||
*/
|
||||
|
||||
/**
|
||||
* listen to an event from the backend
|
||||
*
|
||||
* @param {String} event the event name
|
||||
* @param {EventCallback} handler the event handler callback
|
||||
*/
|
||||
function listen (event, handler) {
|
||||
tauri.listen(event, handler)
|
||||
}
|
||||
|
||||
/**
|
||||
* emits an event to the backend
|
||||
*
|
||||
* @param {String} event the event name
|
||||
* @param {String} [payload] the event payload
|
||||
*/
|
||||
function emit (event, payload) {
|
||||
tauri.emit(event, payload)
|
||||
}
|
||||
|
||||
export {
|
||||
listen,
|
||||
emit
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* @typedef {number} BaseDirectory
|
||||
*/
|
||||
/**
|
||||
* @enum {BaseDirectory}
|
||||
*/
|
||||
const Dir = {
|
||||
Audio: 1,
|
||||
Cache: 2,
|
||||
Config: 3,
|
||||
Data: 4,
|
||||
LocalData: 5,
|
||||
Desktop: 6,
|
||||
Document: 7,
|
||||
Download: 8,
|
||||
Executable: 9,
|
||||
Font: 10,
|
||||
Home: 11,
|
||||
Picture: 12,
|
||||
Public: 13,
|
||||
Runtime: 14,
|
||||
Template: 15,
|
||||
Video: 16,
|
||||
Resource: 17,
|
||||
App: 18
|
||||
}
|
||||
|
||||
export {
|
||||
Dir
|
||||
}
|
||||
@ -1,191 +0,0 @@
|
||||
import tauri from '../tauri'
|
||||
import { Dir } from './dir'
|
||||
|
||||
/**
|
||||
* reads a file as text
|
||||
*
|
||||
* @param {String} filePath path to the file
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
function readTextFile (filePath, options = {}) {
|
||||
return tauri.readTextFile(filePath, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* reads a file as binary
|
||||
*
|
||||
* @param {String} filePath path to the file
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<int[]>}
|
||||
*/
|
||||
function readBinaryFile (filePath, options = {}) {
|
||||
return tauri.readBinaryFile(filePath, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* writes a text file
|
||||
*
|
||||
* @param {Object} file
|
||||
* @param {String} file.path path of the file
|
||||
* @param {String} file.contents contents of the file
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function writeFile (file, options = {}) {
|
||||
return tauri.writeFile(file, options)
|
||||
}
|
||||
|
||||
const CHUNK_SIZE = 65536;
|
||||
|
||||
/**
|
||||
* convert an Uint8Array to ascii string
|
||||
*
|
||||
* @param {Uint8Array} arr
|
||||
* @return {String}
|
||||
*/
|
||||
function uint8ArrayToString(arr) {
|
||||
if (arr.length < CHUNK_SIZE) {
|
||||
return String.fromCharCode.apply(null, arr)
|
||||
}
|
||||
|
||||
let result = ''
|
||||
const arrLen = arr.length
|
||||
for (let i = 0; i < arrLen; i++) {
|
||||
const chunk = arr.subarray(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE)
|
||||
result += String.fromCharCode.apply(null, chunk)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* convert an ArrayBuffer to base64 encoded string
|
||||
*
|
||||
* @param {ArrayBuffer} buffer
|
||||
* @return {String}
|
||||
*/
|
||||
function arrayBufferToBase64(buffer) {
|
||||
const str = uint8ArrayToString(new Uint8Array(buffer))
|
||||
return btoa(str)
|
||||
}
|
||||
|
||||
/**
|
||||
* writes a binary file
|
||||
*
|
||||
* @param {Object} file
|
||||
* @param {String} file.path path of the file
|
||||
* @param {ArrayBuffer} file.contents contents of the file
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function writeBinaryFile(file, options = {}) {
|
||||
return tauri.writeBinaryFile({
|
||||
...file,
|
||||
contents: arrayBufferToBase64(file.contents)
|
||||
}, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} FileEntry
|
||||
* @property {String} path
|
||||
* @property {Boolean} is_dir
|
||||
* @property {String} name
|
||||
*/
|
||||
|
||||
/**
|
||||
* list directory files
|
||||
*
|
||||
* @param {String} dir path to the directory to read
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {Boolean} [options.recursive] whether to list dirs recursively or not
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<FileEntry[]>}
|
||||
*/
|
||||
function readDir (dir, options = {}) {
|
||||
return tauri.readDir(dir, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a directory
|
||||
* If one of the path's parent components doesn't exist
|
||||
* and the `recursive` option isn't set to true, it will be rejected
|
||||
*
|
||||
* @param {String} dir path to the directory to create
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {Boolean} [options.recursive] whether to create the directory's parent components or not
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function createDir (dir, options = {}) {
|
||||
return tauri.createDir(dir, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a directory
|
||||
* If the directory is not empty and the `recursive` option isn't set to true, it will be rejected
|
||||
*
|
||||
* @param {String} dir path to the directory to remove
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {Boolean} [options.recursive] whether to remove all of the directory's content or not
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function removeDir (dir, options = {}) {
|
||||
return tauri.removeDir(dir, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy file
|
||||
*
|
||||
* @param {string} source
|
||||
* @param {string} destination
|
||||
* @param {object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function copyFile (source, destination, options = {}) {
|
||||
return tauri.copyFile(source, destination, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a file
|
||||
*
|
||||
* @param {String} file path to the file to remove
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function removeFile (file, options = {}) {
|
||||
return tauri.removeFile(file, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a file
|
||||
*
|
||||
* @param {String} oldPath
|
||||
* @param {String} newPath
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function renameFile (oldPath, newPath, options = {}) {
|
||||
return tauri.renameFile(oldPath, newPath, options)
|
||||
}
|
||||
|
||||
export {
|
||||
Dir,
|
||||
readTextFile,
|
||||
readBinaryFile,
|
||||
writeFile,
|
||||
writeBinaryFile,
|
||||
readDir,
|
||||
createDir,
|
||||
removeDir,
|
||||
copyFile,
|
||||
removeFile,
|
||||
renameFile
|
||||
}
|
||||
@ -1,160 +0,0 @@
|
||||
import tauri from './tauri'
|
||||
|
||||
/**
|
||||
* @typedef {number} ResponseType
|
||||
*/
|
||||
/**
|
||||
* @enum {ResponseType}
|
||||
*/
|
||||
const ResponseType = {
|
||||
JSON: 1,
|
||||
Text: 2,
|
||||
Binary: 3
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {number} BodyType
|
||||
*/
|
||||
/**
|
||||
* @enum {BodyType}
|
||||
*/
|
||||
const BodyType = {
|
||||
Form: 1,
|
||||
File: 2,
|
||||
Auto: 3
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} HttpOptions
|
||||
* @property {String} options.method GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT or TRACE
|
||||
* @property {String} options.url the request URL
|
||||
* @property {Object} [options.headers] the request headers
|
||||
* @property {Object} [options.propertys] the request query propertys
|
||||
* @property {Object|String|Binary} [options.body] the request body
|
||||
* @property {Boolean} followRedirects whether to follow redirects or not
|
||||
* @property {Number} maxRedirections max number of redirections
|
||||
* @property {Number} connectTimeout request connect timeout
|
||||
* @property {Number} readTimeout request read timeout
|
||||
* @property {Number} timeout request timeout
|
||||
* @property {Boolean} allowCompression
|
||||
* @property {ResponseType} [responseType=1] response type
|
||||
* @property {BodyType} [bodyType=3] body type
|
||||
*/
|
||||
|
||||
/**
|
||||
* makes a HTTP request
|
||||
*
|
||||
* @param {HttpOptions} options request options
|
||||
*
|
||||
* @return {Promise<any>} promise resolving to the response
|
||||
*/
|
||||
function request (options) {
|
||||
return tauri.httpRequest(options)
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a GET request
|
||||
*
|
||||
* @param {String} url request URL
|
||||
* @param {String|Object|Binary} body request body
|
||||
* @param {HttpOptions} options request options
|
||||
*
|
||||
* @return {Promise<any>} promise resolving to the response
|
||||
*/
|
||||
function get (url, options = {}) {
|
||||
return request({
|
||||
method: 'GET',
|
||||
url,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a POST request
|
||||
*
|
||||
* @param {String} url request URL
|
||||
* @param {String|Object|Binary} body request body
|
||||
* @param {HttpOptions} options request options
|
||||
*
|
||||
* @return {Promise<any>} promise resolving to the response
|
||||
*/
|
||||
function post (url, body = void 0, options = {}) {
|
||||
return request({
|
||||
method: 'POST',
|
||||
url,
|
||||
body,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a PUT request
|
||||
*
|
||||
* @param {String} url request URL
|
||||
* @param {String|Object|Binary} body request body
|
||||
* @param {HttpOptions} options request options
|
||||
*
|
||||
* @return {Promise<any>} promise resolving to the response
|
||||
*/
|
||||
function put (url, body = void 0, options = {}) {
|
||||
return request({
|
||||
method: 'PUT',
|
||||
url,
|
||||
body,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a PATCH request
|
||||
*
|
||||
* @param {String} url request URL
|
||||
* @param {HttpOptions} options request options
|
||||
*
|
||||
* @return {Promise<any>} promise resolving to the response
|
||||
*/
|
||||
function patch (url, options = {}) {
|
||||
return request({
|
||||
method: 'PATCH',
|
||||
url,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a DELETE request
|
||||
*
|
||||
* @param {String} url request URL
|
||||
* @param {HttpOptions} options request options
|
||||
*
|
||||
* @return {Promise<any>} promise resolving to the response
|
||||
*/
|
||||
function deleteRequest (url, options = {}) {
|
||||
return request({
|
||||
method: 'DELETE',
|
||||
url,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
request,
|
||||
get,
|
||||
post,
|
||||
put,
|
||||
patch,
|
||||
deleteRequest,
|
||||
ResponseType,
|
||||
BodyType
|
||||
}
|
||||
|
||||
export default {
|
||||
request,
|
||||
get,
|
||||
post,
|
||||
put,
|
||||
patch,
|
||||
delete: deleteRequest,
|
||||
ResponseType,
|
||||
BodyType
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
import tauri from './tauri'
|
||||
|
||||
export default tauri
|
||||
@ -1,16 +0,0 @@
|
||||
import tauri from './tauri'
|
||||
|
||||
/**
|
||||
* spawns a process
|
||||
*
|
||||
* @param {String} command the name of the cmd to execute e.g. 'mkdir' or 'node'
|
||||
* @param {(String[]|String)} [args] command args
|
||||
* @return {Promise<String>} promise resolving to the stdout text
|
||||
*/
|
||||
function execute (command, args) {
|
||||
return tauri.execute(command, args)
|
||||
}
|
||||
|
||||
export {
|
||||
execute
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
export default window.tauri
|
||||
@ -1,24 +0,0 @@
|
||||
import tauri from './tauri'
|
||||
|
||||
/**
|
||||
* sets the window title
|
||||
*
|
||||
* @param {String} title the new title
|
||||
*/
|
||||
function setTitle (title) {
|
||||
tauri.setTitle(title)
|
||||
}
|
||||
|
||||
/**
|
||||
* opens an URL on the user default browser
|
||||
*
|
||||
* @param {String} url the URL to open
|
||||
*/
|
||||
function open (url) {
|
||||
tauri.open(url)
|
||||
}
|
||||
|
||||
export {
|
||||
setTitle,
|
||||
open
|
||||
}
|
||||
@ -10,13 +10,15 @@
|
||||
"url": "https://opencollective.com/tauri"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --progress",
|
||||
"build": "rollup -c --silent && webpack --progress",
|
||||
"build:webpack": "webpack --progress",
|
||||
"build:api": "rollup -c",
|
||||
"build-release": "yarn build --display none --progress false",
|
||||
"test": "jest --runInBand --no-cache --testPathIgnorePatterns=\"(build|dev)\"",
|
||||
"pretest": "yarn build",
|
||||
"prepublishOnly": "yarn build-release",
|
||||
"test:local": "jest --runInBand",
|
||||
"lint": "eslint --ext ts ./src/**/*.ts",
|
||||
"lint": "eslint --ext ts ./src/**/*.ts ./api-src/**/*.ts",
|
||||
"lint-fix": "eslint --fix --ext ts ./src/**/*.ts",
|
||||
"lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn",
|
||||
"build:tauri[rust]": "cd ../tauri && TAURI_DIST_DIR=../../test/fixture/dist TAURI_DIR=../test/fixture cargo publish --dry-run --allow-dirty"
|
||||
@ -72,6 +74,12 @@
|
||||
"@babel/core": "7.10.3",
|
||||
"@babel/preset-env": "7.10.3",
|
||||
"@babel/preset-typescript": "7.10.1",
|
||||
"@rollup/plugin-babel": "^5.0.3",
|
||||
"@rollup/plugin-commonjs": "13.0.0",
|
||||
"@rollup/plugin-json": "4.1.0",
|
||||
"@rollup/plugin-node-resolve": "8.0.1",
|
||||
"@rollup/plugin-sucrase": "^3.0.2",
|
||||
"@rollup/plugin-typescript": "4.1.2",
|
||||
"@types/cross-spawn": "6.0.2",
|
||||
"@types/fs-extra": "9.0.1",
|
||||
"@types/http-proxy": "1.17.4",
|
||||
@ -102,8 +110,12 @@
|
||||
"lockfile-lint": "4.3.7",
|
||||
"promise": "8.1.0",
|
||||
"raw-loader": "4.0.1",
|
||||
"rollup": "2.17.1",
|
||||
"rollup-plugin-terser": "6.1.0",
|
||||
"rollup-plugin-typescript2": "0.27.1",
|
||||
"toml-loader": "1.0.0",
|
||||
"ts-loader": "7.0.5",
|
||||
"tslib": "2.0.0",
|
||||
"typescript": "3.9.5",
|
||||
"webpack": "4.43.0",
|
||||
"webpack-cli": "3.3.12",
|
||||
|
||||
98
cli/tauri.js/rollup.config.js
Normal file
98
cli/tauri.js/rollup.config.js
Normal file
@ -0,0 +1,98 @@
|
||||
// rollup.config.js
|
||||
import { terser } from 'rollup-plugin-terser'
|
||||
import resolve from '@rollup/plugin-node-resolve'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import sucrase from '@rollup/plugin-sucrase'
|
||||
import { getBabelOutputPlugin } from '@rollup/plugin-babel'
|
||||
import pkg from './package.json'
|
||||
|
||||
export default [{
|
||||
input: {
|
||||
'fs': './api-src/fs.ts',
|
||||
'dialog': './api-src/dialog.ts',
|
||||
'event': './api-src/event.ts',
|
||||
'http': './api-src/http.ts',
|
||||
'index': './api-src/index.ts',
|
||||
'process': './api-src/process.ts',
|
||||
'tauri': './api-src/tauri.ts',
|
||||
'window': './api-src/window.ts',
|
||||
},
|
||||
treeshake: true,
|
||||
perf: true,
|
||||
output: [
|
||||
{
|
||||
dir: 'api/', // if you want to consume in node but want it tiny
|
||||
entryFileNames: '[name].js',
|
||||
format: 'cjs',
|
||||
plugins: [ terser() ],
|
||||
exports: 'named',
|
||||
globals: {}
|
||||
},
|
||||
{
|
||||
dir: 'api/esm/', // if you will be transpiling and minifying yourself
|
||||
entryFileNames: '[name].js',
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
exports: 'named',
|
||||
globals: {}
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
commonjs({}),
|
||||
sucrase({
|
||||
exclude: ['node_modules'],
|
||||
transforms: ['typescript']
|
||||
}),
|
||||
resolve({
|
||||
// pass custom options to the resolve plugin
|
||||
customResolveOptions: {
|
||||
moduleDirectory: 'node_modules'
|
||||
}
|
||||
})
|
||||
],
|
||||
external: [
|
||||
...Object.keys(pkg.dependencies || {}),
|
||||
...Object.keys(pkg.peerDependencies || {})
|
||||
],
|
||||
watch: {
|
||||
chokidar: true,
|
||||
include: 'api-src/**',
|
||||
exclude: 'node_modules/**'
|
||||
}
|
||||
},
|
||||
{
|
||||
input: {
|
||||
'bundle': './api-src/bundle.ts'
|
||||
},
|
||||
output: [{
|
||||
name: '__TAURI__',
|
||||
dir: 'api/', // if it needs to run in the browser
|
||||
entryFileNames: 'tauri.bundle.umd.js',
|
||||
format: 'umd',
|
||||
plugins: [
|
||||
getBabelOutputPlugin({
|
||||
presets: [['@babel/preset-env', { modules: 'umd' }]],
|
||||
allowAllFormats: true
|
||||
}),
|
||||
terser()
|
||||
],
|
||||
globals: {
|
||||
}
|
||||
}],
|
||||
plugins: [
|
||||
sucrase({
|
||||
exclude: ['node_modules'],
|
||||
transforms: ['typescript']
|
||||
}),
|
||||
resolve({
|
||||
// pass custom options to the resolve plugin
|
||||
customResolveOptions: {
|
||||
moduleDirectory: 'node_modules'
|
||||
}
|
||||
})
|
||||
],
|
||||
external: [
|
||||
...Object.keys(pkg.dependencies || {}),
|
||||
...Object.keys(pkg.peerDependencies || {})
|
||||
]
|
||||
}]
|
||||
@ -1,14 +0,0 @@
|
||||
import { ensureDirSync, writeFileSync } from 'fs-extra'
|
||||
import { template } from 'lodash'
|
||||
import path from 'path'
|
||||
import { TauriConfig } from './types/config'
|
||||
|
||||
export const generate = (outDir: string, cfg: TauriConfig): void => {
|
||||
// this MUST be from the templates repo
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-var-requires
|
||||
const apiTemplate = require('../templates/tauri.js').default
|
||||
const compiledApi = template(apiTemplate)
|
||||
|
||||
ensureDirSync(outDir)
|
||||
writeFileSync(path.join(outDir, 'tauri.js'), compiledApi(cfg), 'utf-8')
|
||||
}
|
||||
@ -9,7 +9,6 @@ import http from 'http'
|
||||
import * as net from 'net'
|
||||
import os from 'os'
|
||||
import { findClosestOpenPort } from './helpers/net'
|
||||
import * as entry from './entry'
|
||||
import { tauriDir, appDir } from './helpers/app-paths'
|
||||
import logger from './helpers/logger'
|
||||
import onShutdown from './helpers/on-shutdown'
|
||||
@ -75,8 +74,6 @@ class Runner {
|
||||
this.__whitelistApi(cfg, cargoManifest)
|
||||
this.__rewriteManifest(cargoManifest as unknown as toml.JsonMap)
|
||||
|
||||
entry.generate(tauriDir, cfg)
|
||||
|
||||
const runningDevServer = devPath.startsWith('http')
|
||||
|
||||
let inlinedAssets: string[] = []
|
||||
@ -94,13 +91,13 @@ class Runner {
|
||||
selfHandleResponse: true
|
||||
})
|
||||
|
||||
proxy.on('proxyRes', function(proxyRes: http.IncomingMessage, req: http.IncomingMessage, res: http.ServerResponse) {
|
||||
proxy.on('proxyRes', function (proxyRes: http.IncomingMessage, req: http.IncomingMessage, res: http.ServerResponse) {
|
||||
if (req.url === '/') {
|
||||
const body: Uint8Array[] = []
|
||||
proxyRes.on('data', function(chunk: Uint8Array) {
|
||||
proxyRes.on('data', function (chunk: Uint8Array) {
|
||||
body.push(chunk)
|
||||
})
|
||||
proxyRes.on('end', function() {
|
||||
proxyRes.on('end', function () {
|
||||
const bodyStr = body.join('')
|
||||
const indexDir = os.tmpdir()
|
||||
writeFileSync(path.join(indexDir, 'index.html'), bodyStr)
|
||||
@ -227,8 +224,6 @@ class Runner {
|
||||
this.__whitelistApi(cfg, cargoManifest as unknown as CargoManifest)
|
||||
this.__rewriteManifest(cargoManifest)
|
||||
|
||||
entry.generate(tauriDir, cfg)
|
||||
|
||||
const inlinedAssets = (await this.__parseHtml(cfg, cfg.build.distDir)).inlinedAssets
|
||||
process.env.TAURI_INLINED_ASSSTS = inlinedAssets.join('|')
|
||||
|
||||
@ -307,9 +302,17 @@ class Runner {
|
||||
}
|
||||
|
||||
const tauriScript = document.createElement('script')
|
||||
tauriScript.text = readFileSync(path.join(tauriDir, 'tauri.js')).toString()
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
|
||||
tauriScript.text = require('../templates/tauri.js').default
|
||||
document.head.insertBefore(tauriScript, document.head.firstChild)
|
||||
|
||||
if (cfg.build.withGlobalTauri) {
|
||||
const tauriUmdScript = document.createElement('script')
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
|
||||
tauriUmdScript.text = require('../api/tauri.bundle.umd').default
|
||||
document.head.insertBefore(tauriUmdScript, document.head.firstChild)
|
||||
}
|
||||
|
||||
const csp = cfg.tauri.security.csp
|
||||
if (csp) {
|
||||
const cspTag = document.createElement('meta')
|
||||
@ -501,7 +504,7 @@ class Runner {
|
||||
}
|
||||
|
||||
if (cfg.tauri.cli) {
|
||||
tomlFeatures.push('cli')
|
||||
tomlFeatures.push('cli')
|
||||
}
|
||||
|
||||
if (typeof manifest.dependencies.tauri === 'string') {
|
||||
|
||||
@ -37,6 +37,7 @@ export interface TauriConfig {
|
||||
devPath: string
|
||||
beforeDevCommand?: string
|
||||
beforeBuildCommand?: string
|
||||
withGlobalTauri?: boolean
|
||||
}
|
||||
ctx: {
|
||||
prod?: boolean
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
(function () {
|
||||
function loadAsset(path, type) {
|
||||
if (path) {
|
||||
window.tauri.loadAsset(path, type)
|
||||
window.__TAURI__.loadAsset(path, type)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,5 @@ WixTools
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
tauri.js
|
||||
config.json
|
||||
bundle.json
|
||||
|
||||
@ -1,385 +0,0 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* * THIS FILE IS GENERATED AUTOMATICALLY.
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Please whitelist these API functions in tauri.conf.json
|
||||
*
|
||||
**/
|
||||
|
||||
// open <a href="..."> links with the Tauri API
|
||||
|
||||
/**
|
||||
* @module tauri
|
||||
* @description This API interface makes powerful interactions available
|
||||
* to be run on client side applications. They are opt-in features, and
|
||||
* must be enabled in tauri.conf.json
|
||||
*
|
||||
* Each binding MUST provide these interfaces in order to be compliant,
|
||||
* and also whitelist them based upon the developer's settings.
|
||||
*/
|
||||
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1)
|
||||
}
|
||||
|
||||
const uid = function () {
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4()
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name __whitelistWarning
|
||||
* @description Present a stylish warning to the developer that their API
|
||||
* call has not been whitelisted in tauri.conf.json
|
||||
* @param {String} func - function name to warn
|
||||
* @private
|
||||
*/
|
||||
const __whitelistWarning = function (func) {
|
||||
console.warn('%c[Tauri] Danger \ntauri.' + func + ' not whitelisted 💣\n%c\nAdd to tauri.conf.json: \n\ntauri: \n whitelist: { \n ' + func + ': true \n\nReference: https://github.com/tauri-apps/tauri/wiki' + func , 'background: red; color: white; font-weight: 800; padding: 2px; font-size:1.5em', ' ')
|
||||
}
|
||||
<% } %>
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name __reject
|
||||
* @description is a private promise used to deflect un-whitelisted tauri API calls
|
||||
* Its only purpose is to maintain thenable structure in client code without
|
||||
* breaking the application
|
||||
* * @type {Promise<any>}
|
||||
* @private
|
||||
*/
|
||||
<% } %>
|
||||
const __reject = new Promise((reject) => { reject })
|
||||
|
||||
window.tauri = {
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name invoke
|
||||
* @description Calls a Tauri Core feature, such as setTitle
|
||||
* @param {Object} args
|
||||
*/
|
||||
<% } %>
|
||||
invoke (args) {
|
||||
Object.freeze(args)
|
||||
window.external.invoke(JSON.stringify(args))
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name listen
|
||||
* @description Add an event listener to Tauri backend
|
||||
* @param {String} event
|
||||
* @param {Function} handler
|
||||
* @param {Boolean} once
|
||||
*/
|
||||
<% } %>
|
||||
listen (event, handler, once = false) {
|
||||
this.invoke({
|
||||
cmd: 'listen',
|
||||
event,
|
||||
handler: this.transformCallback(handler, once),
|
||||
once
|
||||
})
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name emit
|
||||
* @description Emits an evt to the Tauri back end
|
||||
* @param {String} evt
|
||||
* @param {Object} payload
|
||||
*/
|
||||
<% } %>
|
||||
emit (evt, payload) {
|
||||
this.invoke({
|
||||
cmd: 'emit',
|
||||
event: evt,
|
||||
payload
|
||||
})
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name transformCallback
|
||||
* @description Registers a callback with a uid
|
||||
* @param {Function} callback
|
||||
* @param {Boolean} once
|
||||
* @returns {*}
|
||||
*/
|
||||
<% } %>
|
||||
transformCallback (callback, once = true) {
|
||||
const identifier = Object.freeze(uid())
|
||||
window[identifier] = (result) => {
|
||||
if (once) {
|
||||
delete window[identifier]
|
||||
}
|
||||
return callback && callback(result)
|
||||
}
|
||||
return identifier
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name promisified
|
||||
* @description Turns a request into a chainable promise
|
||||
* @param {Object} args
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
<% } %>
|
||||
promisified (args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.invoke({
|
||||
callback: this.transformCallback(resolve),
|
||||
error: this.transformCallback(reject),
|
||||
...args
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name readTextFile
|
||||
* @description Accesses a non-binary file on the user's filesystem
|
||||
* and returns the content. Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
readTextFile (path) {
|
||||
<% if (tauri.whitelist.readTextFile === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(path)
|
||||
return this.promisified({ cmd: 'readTextFile', path })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('readTextFile')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name readBinaryFile
|
||||
* @description Accesses a binary file on the user's filesystem
|
||||
* and returns the content. Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
readBinaryFile (path) {
|
||||
<% if (tauri.whitelist.readBinaryFile === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(path)
|
||||
return this.promisified({ cmd: 'readBinaryFile', path })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('readBinaryFile')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name writeFile
|
||||
* @description Write a file to the Local Filesystem.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {Object} cfg
|
||||
* @param {String} cfg.file
|
||||
* @param {String|Binary} cfg.contents
|
||||
*/
|
||||
<% } %>
|
||||
writeFile (cfg) {
|
||||
<% if (tauri.whitelist.writeFile === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(cfg)
|
||||
this.invoke({ cmd: 'writeFile', file: cfg.file, contents: cfg.contents })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('writeFile')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name writeBinaryFile
|
||||
* @description Write a binary file to the Local Filesystem.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {Object} cfg
|
||||
* @param {String} cfg.file
|
||||
* @param {String|Binary} cfg.contents
|
||||
*/
|
||||
<% } %>
|
||||
writeBinaryFile (cfg) {
|
||||
<% if (tauri.whitelist.writeBinaryFile === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(cfg)
|
||||
this.invoke({ cmd: 'writeBinaryFile', file: cfg.file, contents: cfg.contents })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('writeBinaryFile')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name listFiles
|
||||
* @description Get the files in a path.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
listFiles (path) {
|
||||
<% if (tauri.whitelist.listFiles === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(path)
|
||||
return this.promisified({ cmd: 'listFiles', path })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('listFiles')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name listDirs
|
||||
* @description Get the directories in a path.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
listDirs (path) {
|
||||
<% if (tauri.whitelist.listDirs === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(path)
|
||||
return this.promisified({ cmd: 'listDirs', path })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('listDirs')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name setTitle
|
||||
* @description Set the application's title
|
||||
* @param {String} title
|
||||
*/
|
||||
<% } %>
|
||||
setTitle (title) {
|
||||
<% if (tauri.whitelist.setTitle === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(title)
|
||||
this.invoke({ cmd: 'setTitle', title })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('setTitle')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name open
|
||||
* @description Open an URI
|
||||
* @param {String} uri
|
||||
*/
|
||||
<% } %>
|
||||
open (uri) {
|
||||
<% if (tauri.whitelist.open === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(uri)
|
||||
this.invoke({ cmd: 'open', uri })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('open')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name execute
|
||||
* @description Execute a program with arguments.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} command
|
||||
* @param {String|Array} args
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
execute (command, args) {
|
||||
<% if (tauri.whitelist.execute === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(command)
|
||||
if (typeof args === 'string' || typeof args === 'object') {
|
||||
Object.freeze(args)
|
||||
}
|
||||
return this.promisified({ cmd: 'execute', command, args: typeof (args) === 'string' ? [args] : args })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('execute')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name bridge
|
||||
* @description Securely pass a message to the backend.
|
||||
* @example
|
||||
* this.$q.tauri.bridge('QBP/1/ping/client-1', 'pingback')
|
||||
* @param {String} command - a compressed, slash-delimited and
|
||||
* versioned API call to the backend.
|
||||
* @param {String|Object}payload
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
bridge (command, payload) {
|
||||
<% if (tauri.whitelist.bridge === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(command)
|
||||
if (typeof payload === 'string' || typeof payload === 'object') {
|
||||
Object.freeze(payload)
|
||||
}
|
||||
return this.promisified({ cmd: 'bridge', command, payload: typeof (payload) === 'object' ? [payload] : payload })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('bridge')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name setup
|
||||
* @description Inform Rust that the webview has initialized and is
|
||||
* ready for communication
|
||||
*/
|
||||
<% } %>
|
||||
setup () {
|
||||
document.querySelector('body').addEventListener('click', function (e) {
|
||||
let target = e.target
|
||||
while (target != null) {
|
||||
if (target.matches ? target.matches('a') : target.msMatchesSelector('a')) {
|
||||
tauri.open(target.href)
|
||||
break
|
||||
}
|
||||
target = target.parentElement
|
||||
}
|
||||
}, true)
|
||||
|
||||
tauri.invoke({
|
||||
cmd: 'init'
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,23 +1,3 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* * THIS FILE IS GENERATED AUTOMATICALLY.
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Please whitelist these API functions in tauri.conf.json
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
* @module tauri
|
||||
* @description This API interface makes powerful interactions available
|
||||
* to be run on client side applications. They are opt-in features, and
|
||||
* must be enabled in tauri.conf.json
|
||||
*
|
||||
* Each binding MUST provide these interfaces in order to be compliant,
|
||||
* and also whitelist them based upon the developer's settings.
|
||||
*/
|
||||
|
||||
// polyfills
|
||||
if (!String.prototype.startsWith) {
|
||||
String.prototype.startsWith = function (searchString, position) {
|
||||
@ -27,7 +7,6 @@ if (!String.prototype.startsWith) {
|
||||
}
|
||||
|
||||
// makes the window.external.invoke API available after window.location.href changes
|
||||
|
||||
switch (navigator.platform) {
|
||||
case "Macintosh":
|
||||
case "MacPPC":
|
||||
@ -63,765 +42,99 @@ switch (navigator.platform) {
|
||||
s4() + '-' + s4() + s4() + s4()
|
||||
}
|
||||
|
||||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
|
||||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
/**
|
||||
* @typedef {number} BaseDirectory
|
||||
*/
|
||||
/**
|
||||
* @enum {BaseDirectory}
|
||||
*/
|
||||
var Dir = {
|
||||
Audio: 1,
|
||||
Cache: 2,
|
||||
Config: 3,
|
||||
Data: 4,
|
||||
LocalData: 5,
|
||||
Desktop: 6,
|
||||
Document: 7,
|
||||
Download: 8,
|
||||
Executable: 9,
|
||||
Font: 10,
|
||||
Home: 11,
|
||||
Picture: 12,
|
||||
Public: 13,
|
||||
Runtime: 14,
|
||||
Template: 15,
|
||||
Video: 16,
|
||||
Resource: 17,
|
||||
App: 18
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
function camelToKebab (string) {
|
||||
return string.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase()
|
||||
}
|
||||
/**
|
||||
* @name return __whitelistWarning
|
||||
* @description Present a stylish warning to the developer that their API
|
||||
* call has not been whitelisted in tauri.conf.json
|
||||
* @param {String} func - function name to warn
|
||||
* @private
|
||||
*/
|
||||
var __whitelistWarning = function (func) {
|
||||
console.warn('%c[Tauri] Danger \ntauri.' + func + ' not whitelisted 💣\n%c\nAdd to tauri.conf.json: \n\ntauri: \n whitelist: { \n ' + camelToKebab(func) + ': true \n\nReference: https://github.com/tauri-apps/tauri/wiki' + func, 'background: red; color: white; font-weight: 800; padding: 2px; font-size:1.5em', ' ')
|
||||
return __reject()
|
||||
}
|
||||
<% } %>
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name __reject
|
||||
* @description generates a promise used to deflect un-whitelisted tauri API calls
|
||||
* Its only purpose is to maintain thenable structure in client code without
|
||||
* breaking the application
|
||||
* * @type {Promise<any>}
|
||||
* @private
|
||||
*/
|
||||
<% } %>
|
||||
var __reject = function () {
|
||||
return new Promise(function (_, reject) {
|
||||
reject();
|
||||
});
|
||||
}
|
||||
|
||||
window.tauri = {
|
||||
Dir: Dir,
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name invoke
|
||||
* @description Calls a Tauri Core feature, such as setTitle
|
||||
* @param {Object} args
|
||||
*/
|
||||
<% } %>
|
||||
invoke: function invoke(args) {
|
||||
window.external.invoke(JSON.stringify(args));
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name listen
|
||||
* @description Add an event listener to Tauri backend
|
||||
* @param {String} event
|
||||
* @param {Function} handler
|
||||
* @param {Boolean} once
|
||||
*/
|
||||
<% } %>
|
||||
listen: function listen(event, handler) {
|
||||
<% if (tauri.whitelist.event === true || tauri.whitelist.all === true) { %>
|
||||
var once = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
||||
this.invoke({
|
||||
cmd: 'listen',
|
||||
event: event,
|
||||
handler: window.tauri.transformCallback(handler, once),
|
||||
once: once
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('event')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name emit
|
||||
* @description Emits an evt to the Tauri back end
|
||||
* @param {String} evt
|
||||
* @param {Object} payload
|
||||
*/
|
||||
<% } %>
|
||||
emit: function emit(evt, payload) {
|
||||
<% if (tauri.whitelist.event === true || tauri.whitelist.all === true) { %>
|
||||
this.invoke({
|
||||
cmd: 'emit',
|
||||
event: evt,
|
||||
payload: payload
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('event')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name transformCallback
|
||||
* @description Registers a callback with a uid
|
||||
* @param {Function} callback
|
||||
* @param {Boolean} once
|
||||
* @returns {*}
|
||||
*/
|
||||
<% } %>
|
||||
transformCallback: function transformCallback(callback) {
|
||||
var once = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||
var identifier = uid();
|
||||
|
||||
window[identifier] = function (result) {
|
||||
if (once) {
|
||||
delete window[identifier];
|
||||
}
|
||||
|
||||
return callback && callback(result);
|
||||
};
|
||||
|
||||
return identifier;
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name promisified
|
||||
* @description Turns a request into a chainable promise
|
||||
* @param {Object} args
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
<% } %>
|
||||
promisified: function promisified(args) {
|
||||
var _this = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
_this.invoke(_objectSpread({
|
||||
callback: _this.transformCallback(resolve),
|
||||
error: _this.transformCallback(reject)
|
||||
}, args));
|
||||
function ownKeys(object, enumerableOnly) {
|
||||
var keys = Object.keys(object);
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
var symbols = Object.getOwnPropertySymbols(object);
|
||||
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
||||
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
||||
});
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name readTextFile
|
||||
* @description Accesses a non-binary file on the user's filesystem
|
||||
* and returns the content. Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
readTextFile: function readTextFile(path, options) {
|
||||
<% if (tauri.whitelist.readTextFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'readTextFile',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('readTextFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name readBinaryFile
|
||||
* @description Accesses a binary file on the user's filesystem
|
||||
* and returns the content. Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
readBinaryFile: function readBinaryFile(path, options) {
|
||||
<% if (tauri.whitelist.readBinaryFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'readBinaryFile',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('readBinaryFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name writeFile
|
||||
* @description Write a file to the Local Filesystem.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {Object} cfg
|
||||
* @param {String} cfg.file
|
||||
* @param {String|Binary} cfg.contents
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
*/
|
||||
<% } %>
|
||||
writeFile: function writeFile(cfg, options) {
|
||||
<% if (tauri.whitelist.writeFile === true || tauri.whitelist.all === true) { %>
|
||||
if (_typeof(cfg) === 'object') {
|
||||
Object.freeze(cfg);
|
||||
}
|
||||
return this.promisified({
|
||||
cmd: 'writeFile',
|
||||
file: cfg.file,
|
||||
contents: cfg.contents,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('writeFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name writeBinaryFile
|
||||
* @description Write a binary file to the Local Filesystem.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {Object} cfg
|
||||
* @param {String} cfg.file
|
||||
* @param {String|Binary} cfg.contents
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
*/
|
||||
<% } %>
|
||||
writeBinaryFile: function writeBinaryFile(cfg, options) {
|
||||
<% if (tauri.whitelist.writeBinaryFile === true || tauri.whitelist.all === true) { %>
|
||||
if (_typeof(cfg) === 'object') {
|
||||
Object.freeze(cfg);
|
||||
}
|
||||
return this.promisified({
|
||||
cmd: 'writeBinaryFile',
|
||||
file: cfg.file,
|
||||
contents: cfg.contents,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('writeBinaryFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name readDir
|
||||
* @description Reads a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
readDir: function readDir(path, options) {
|
||||
<% if (tauri.whitelist.readDir === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'readDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('readDir')
|
||||
<% } %>
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name createDir
|
||||
* @description Creates a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
createDir: function createDir(path, options) {
|
||||
<% if (tauri.whitelist.createDir === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'createDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('createDir')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name removeDir
|
||||
* @description Removes a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
removeDir: function removeDir(path, options) {
|
||||
<% if (tauri.whitelist.removeDir === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'removeDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('removeDir')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name copyFile
|
||||
* @description Copy file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} source
|
||||
* @param {String} destination
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
copyFile: function copyFile(source, destination, options) {
|
||||
<% if (tauri.whitelist.copyFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'copyFile',
|
||||
source: source,
|
||||
destination: destination,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('copyFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name removeFile
|
||||
* @description Removes a file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
removeFile: function removeFile(path, options) {
|
||||
<% if (tauri.whitelist.removeFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'removeFile',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('removeFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name renameFile
|
||||
* @description Renames a file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
renameFile: function renameFile(oldPath, newPath, options) {
|
||||
<% if (tauri.whitelist.renameFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'renameFile',
|
||||
oldPath: oldPath,
|
||||
newPath: newPath,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('renameFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name setTitle
|
||||
* @description Set the application's title
|
||||
* @param {String} title
|
||||
*/
|
||||
<% } %>
|
||||
setTitle: function setTitle(title) {
|
||||
<% if (tauri.whitelist.setTitle === true || tauri.whitelist.all === true) { %>
|
||||
this.invoke({
|
||||
cmd: 'setTitle',
|
||||
title: title
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('setTitle')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name open
|
||||
* @description Open an URI
|
||||
* @param {String} uri
|
||||
*/
|
||||
<% } %>
|
||||
open: function open(uri) {
|
||||
<% if (tauri.whitelist.open === true || tauri.whitelist.all === true) { %>
|
||||
this.invoke({
|
||||
cmd: 'open',
|
||||
uri: uri
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('open')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name execute
|
||||
* @description Execute a program with arguments.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} command
|
||||
* @param {String|Array} args
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
execute: function execute(command, args) {
|
||||
<% if (tauri.whitelist.execute === true || tauri.whitelist.all === true) { %>
|
||||
|
||||
if (_typeof(args) === 'object') {
|
||||
Object.freeze(args);
|
||||
}
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'execute',
|
||||
command: command,
|
||||
args: typeof args === 'string' ? [args] : args
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('execute')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name openDialog
|
||||
* @description Open a file/directory selection dialog
|
||||
* @param {String} [options]
|
||||
* @param {String} [options.filter]
|
||||
* @param {String} [options.defaultPath]
|
||||
* @param {Boolean} [options.multiple=false]
|
||||
* @param {Boolean} [options.directory=false]
|
||||
* @returns {Promise<String|String[]>} promise resolving to the select path(s)
|
||||
*/
|
||||
<% } %>
|
||||
openDialog: function openDialog(options) {
|
||||
<% if (tauri.whitelist.openDialog === true || tauri.whitelist.all === true) { %>
|
||||
var opts = options || {}
|
||||
if (_typeof(options) === 'object') {
|
||||
opts.default_path = opts.defaultPath
|
||||
Object.freeze(options);
|
||||
}
|
||||
return this.promisified({
|
||||
cmd: 'openDialog',
|
||||
options: opts
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('openDialog')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name saveDialog
|
||||
* @description Open a file/directory save dialog
|
||||
* @param {String} [options]
|
||||
* @param {String} [options.filter]
|
||||
* @param {String} [options.defaultPath]
|
||||
* @returns {Promise<String>} promise resolving to the select path
|
||||
*/
|
||||
<% } %>
|
||||
saveDialog: function saveDialog(options) {
|
||||
<% if (tauri.whitelist.saveDialog === true || tauri.whitelist.all === true) { %>
|
||||
var opts = options || {}
|
||||
if (_typeof(options) === 'object') {
|
||||
opts.default_path = opts.defaultPath
|
||||
Object.freeze(options);
|
||||
}
|
||||
return this.promisified({
|
||||
cmd: 'saveDialog',
|
||||
options: opts
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('saveDialog')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name httpRequest
|
||||
* @description Makes an HTTP request
|
||||
* @param {Object} options
|
||||
* @param {String} options.method GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT or TRACE
|
||||
* @param {String} options.url the request URL
|
||||
* @param {Object} [options.headers] the request headers
|
||||
* @param {Object} [options.params] the request query params
|
||||
* @param {Object|String|Binary} [options.body] the request body
|
||||
* @param {Boolean} followRedirects whether to follow redirects or not
|
||||
* @param {Number} maxRedirections max number of redirections
|
||||
* @param {Number} connectTimeout request connect timeout
|
||||
* @param {Number} readTimeout request read timeout
|
||||
* @param {Number} timeout request timeout
|
||||
* @param {Boolean} allowCompression
|
||||
* @param {Number} [responseType=1] 1 - JSON, 2 - Text, 3 - Binary
|
||||
* @param {Number} [bodyType=3] 1 - Form, 2 - File, 3 - Auto
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
<% } %>
|
||||
httpRequest: function httpRequest(options) {
|
||||
<% if (tauri.whitelist.readBinaryFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'httpRequest',
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('httpRequest')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name notification
|
||||
* @description Display a desktop notification
|
||||
* @param {Object|String} options the notifications options if an object, otherwise its body
|
||||
* @param {String} [options.summary] the notification's summary
|
||||
* @param {String} options.body the notification's body
|
||||
* @param {String} [options.icon] the notifications's icon
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
notification: function notification(options) {
|
||||
<% if (tauri.whitelist.notification === true || tauri.whitelist.all === true) { %>
|
||||
|
||||
if (_typeof(options) === 'object') {
|
||||
Object.freeze(options);
|
||||
}
|
||||
|
||||
return window.tauri.isNotificationPermissionGranted()
|
||||
.then(function (permission) {
|
||||
if (permission) {
|
||||
return window.tauri.promisified({
|
||||
cmd: 'notification',
|
||||
options: typeof options === 'string' ? {
|
||||
body: options
|
||||
} : options
|
||||
});
|
||||
}
|
||||
})
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('notification')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
isNotificationPermissionGranted: function isNotificationPermissionGranted() {
|
||||
<% if (tauri.whitelist.notification === true || tauri.whitelist.all === true) { %>
|
||||
if (window.Notification.permission !== 'default' && window.Notification.permission !== 'loading') {
|
||||
return Promise.resolve(window.Notification.permission === 'granted')
|
||||
}
|
||||
return window.tauri.promisified({
|
||||
cmd: 'isNotificationPermissionGranted'
|
||||
})
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('notification')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
requestNotificationPermission: function requestNotificationPermission() {
|
||||
<% if (tauri.whitelist.notification === true || tauri.whitelist.all === true) { %>
|
||||
return window.tauri.promisified({
|
||||
cmd: 'requestNotificationPermission'
|
||||
}).then(function (state) {
|
||||
setNotificationPermission(state)
|
||||
return state
|
||||
})
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('notification')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
loadAsset: function loadAsset(assetName, assetType) {
|
||||
return this.promisified({
|
||||
cmd: 'loadAsset',
|
||||
asset: assetName,
|
||||
assetType: assetType || 'unknown'
|
||||
})
|
||||
},
|
||||
|
||||
cliMatches: function () {
|
||||
<% if (tauri.cli) { %>
|
||||
return this.promisified({
|
||||
cmd: 'cliMatches'
|
||||
})
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
console.error('You must add the CLI args configuration under tauri.conf.json > tauri > cli')
|
||||
return __reject()
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
|
||||
keys.push.apply(keys, symbols);
|
||||
}
|
||||
};
|
||||
return keys;
|
||||
}
|
||||
|
||||
<% if (tauri.whitelist.notification === true || tauri.whitelist.all === true) { %>
|
||||
var notificationPermissionSettable = false
|
||||
var notificationPermission = 'default'
|
||||
function setNotificationPermission(value) {
|
||||
notificationPermissionSettable = true
|
||||
window.Notification.permission = value
|
||||
notificationPermissionSettable = false
|
||||
}
|
||||
|
||||
window.Notification = function (title, options) {
|
||||
if (options === void 0) {
|
||||
options = {}
|
||||
function _objectSpread(target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i] != null ? arguments[i] : {};
|
||||
if (i % 2) {
|
||||
ownKeys(source, true).forEach(function (key) {
|
||||
_defineProperty(target, key, source[key]);
|
||||
});
|
||||
} else if (Object.getOwnPropertyDescriptors) {
|
||||
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
||||
} else {
|
||||
ownKeys(source).forEach(function (key) {
|
||||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
||||
});
|
||||
}
|
||||
options.title = title
|
||||
window.tauri.notification(options)
|
||||
}
|
||||
window.Notification.requestPermission = window.tauri.requestNotificationPermission
|
||||
return target;
|
||||
}
|
||||
|
||||
Object.defineProperty(window.Notification, 'permission', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return notificationPermission
|
||||
},
|
||||
set: function(v) {
|
||||
if (!notificationPermissionSettable) {
|
||||
throw new Error("Readonly property")
|
||||
}
|
||||
notificationPermission = v
|
||||
function _defineProperty(obj, key, value) {
|
||||
if (key in obj) {
|
||||
Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
} else {
|
||||
obj[key] = value;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (!window.__TAURI__) {
|
||||
window.__TAURI__ = {}
|
||||
}
|
||||
window.__TAURI__.invoke = function invoke(args) {
|
||||
window.external.invoke(JSON.stringify(args))
|
||||
}
|
||||
|
||||
window.__TAURI__.transformCallback = function transformCallback(callback) {
|
||||
var once = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false
|
||||
var identifier = uid()
|
||||
|
||||
window[identifier] = function (result) {
|
||||
if (once) {
|
||||
delete window[identifier]
|
||||
}
|
||||
});
|
||||
|
||||
setNotificationPermission('loading')
|
||||
window.tauri.isNotificationPermissionGranted()
|
||||
.then(function (response) {
|
||||
if (response === null) {
|
||||
setNotificationPermission('default')
|
||||
} else {
|
||||
setNotificationPermission(response ? 'granted' : 'denied')
|
||||
}
|
||||
})
|
||||
<% } %>
|
||||
return callback && callback(result)
|
||||
}
|
||||
|
||||
return identifier;
|
||||
}
|
||||
|
||||
window.__TAURI__.promisified = function promisified(args) {
|
||||
var _this = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
_this.invoke(_objectSpread({
|
||||
callback: _this.transformCallback(resolve),
|
||||
error: _this.transformCallback(reject)
|
||||
}, args))
|
||||
})
|
||||
}
|
||||
|
||||
window.__TAURI__.loadAsset = function loadAsset(assetName, assetType) {
|
||||
return this.promisified({
|
||||
cmd: 'loadAsset',
|
||||
asset: assetName,
|
||||
assetType: assetType || 'unknown'
|
||||
})
|
||||
}
|
||||
|
||||
// init tauri API
|
||||
try {
|
||||
window.tauri.invoke({
|
||||
window.__TAURI__.invoke({
|
||||
cmd: 'init'
|
||||
})
|
||||
} catch (e) {
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
window.tauri.invoke({
|
||||
window.__TAURI__.invoke({
|
||||
cmd: 'init'
|
||||
})
|
||||
}, true)
|
||||
@ -831,7 +144,7 @@ switch (navigator.platform) {
|
||||
var target = e.target
|
||||
while (target != null) {
|
||||
if (target.matches ? target.matches('img') : target.msMatchesSelector('img')) {
|
||||
window.tauri.loadAsset(target.src, 'image')
|
||||
window.__TAURI__.loadAsset(target.src, 'image')
|
||||
.then(function (img) {
|
||||
target.src = img
|
||||
})
|
||||
@ -848,7 +161,10 @@ switch (navigator.platform) {
|
||||
while (target != null) {
|
||||
if (target.matches ? target.matches('a') : target.msMatchesSelector('a')) {
|
||||
if (target.href && target.href.startsWith('http') && target.target === '_blank') {
|
||||
window.tauri.open(target.href)
|
||||
window.__TAURI__.invoke({
|
||||
cmd: 'open',
|
||||
uri: target.href
|
||||
})
|
||||
e.preventDefault()
|
||||
}
|
||||
break
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
function callBackEnd (route, args) {
|
||||
function callBackEnd(route, args) {
|
||||
console.log(route)
|
||||
console.log(args)
|
||||
var xhr = new XMLHttpRequest()
|
||||
@ -17,15 +18,15 @@
|
||||
xhr.send(JSON.stringify(args))
|
||||
}
|
||||
|
||||
function reply (args) {
|
||||
function reply(args) {
|
||||
return callBackEnd('reply', args)
|
||||
}
|
||||
|
||||
function sendError (error) {
|
||||
function sendError(error) {
|
||||
return callBackEnd('error', error)
|
||||
}
|
||||
|
||||
function testFs (dir) {
|
||||
function testFs(dir) {
|
||||
var contents = 'TAURI E2E TEST FILE'
|
||||
var commandSuffix = (dir ? 'WithDir' : '')
|
||||
|
||||
@ -33,37 +34,54 @@
|
||||
dir: dir || null
|
||||
}
|
||||
|
||||
return window.tauri.writeFile({
|
||||
return window.__TAURI__.fs.writeFile({
|
||||
file: 'tauri-test.txt',
|
||||
contents: contents
|
||||
}, options).then(function (res) {
|
||||
reply({ cmd: 'writeFile' + commandSuffix })
|
||||
return window.tauri.readTextFile('tauri-test.txt', options).then(function (res) {
|
||||
reply({
|
||||
cmd: 'writeFile' + commandSuffix
|
||||
})
|
||||
return window.__TAURI__.fs.readTextFile('tauri-test.txt', options).then(function (res) {
|
||||
if (res === contents) {
|
||||
reply({ cmd: 'readFile' + commandSuffix })
|
||||
reply({
|
||||
cmd: 'readFile' + commandSuffix
|
||||
})
|
||||
|
||||
return window.tauri.readDir('.', options).then(res => {
|
||||
reply({ cmd: 'readDir' + commandSuffix })
|
||||
|
||||
return window.tauri.copyFile('tauri-test.txt', 'tauri-test-copy.txt', options)
|
||||
return window.__TAURI__.fs.readDir('.', options).then(res => {
|
||||
reply({
|
||||
cmd: 'readDir' + commandSuffix
|
||||
})
|
||||
|
||||
return window.__TAURI__.fs.copyFile('tauri-test.txt', 'tauri-test-copy.txt', options)
|
||||
.then(function (res) {
|
||||
reply({ cmd: 'copyFile' + commandSuffix })
|
||||
reply({
|
||||
cmd: 'copyFile' + commandSuffix
|
||||
})
|
||||
|
||||
return window.tauri.createDir('tauri-test-dir', options).then(function (res) {
|
||||
reply({ cmd: 'createDir' + commandSuffix })
|
||||
return window.tauri.removeDir('tauri-test-dir', options).then(function (res) {
|
||||
reply({ cmd: 'removeDir' + commandSuffix })
|
||||
return window.__TAURI__.fs.createDir('tauri-test-dir', options).then(function (res) {
|
||||
reply({
|
||||
cmd: 'createDir' + commandSuffix
|
||||
})
|
||||
}).then(function (res) {
|
||||
return window.tauri.renameFile('tauri-test.txt', 'tauri.testt.txt', options).then(function (res) {
|
||||
reply({ cmd: 'renameFile' + commandSuffix })
|
||||
return Promise.all([
|
||||
window.tauri.removeFile('tauri.testt.txt', options),
|
||||
window.tauri.removeFile('tauri-test-copy.txt', options)
|
||||
]).then(function (res) {
|
||||
reply({ cmd: 'removeFile' + commandSuffix })
|
||||
return window.__TAURI__.fs.removeDir('tauri-test-dir', options).then(function (res) {
|
||||
reply({
|
||||
cmd: 'removeDir' + commandSuffix
|
||||
})
|
||||
})
|
||||
}).then(function (res) {
|
||||
return window.__TAURI__.fs.renameFile('tauri-test.txt', 'tauri.testt.txt', options)
|
||||
.then(function (res) {
|
||||
reply({
|
||||
cmd: 'renameFile' + commandSuffix
|
||||
})
|
||||
return Promise.all([
|
||||
window.__TAURI__.fs.removeFile('tauri.testt.txt', options),
|
||||
window.__TAURI__.fs.removeFile('tauri-test-copy.txt', options)
|
||||
]).then(function (res) {
|
||||
reply({
|
||||
cmd: 'removeFile' + commandSuffix
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -74,21 +92,26 @@
|
||||
}).catch(sendError)
|
||||
}
|
||||
|
||||
window.tauri.listen('reply', function (res) {
|
||||
reply({ cmd: 'listen' })
|
||||
window.__TAURI__.event.listen('reply', function (res) {
|
||||
reply({
|
||||
cmd: 'listen'
|
||||
})
|
||||
})
|
||||
window.onTauriInit = function () {
|
||||
window.tauri.emit('hello')
|
||||
window.__TAURI__.event.emit('hello')
|
||||
}
|
||||
|
||||
testFs(null).then(function () {
|
||||
testFs(window.tauri.Dir.Config)
|
||||
testFs(window.__TAURI__.fs.Dir.Config)
|
||||
})
|
||||
|
||||
setTimeout(function () {
|
||||
window.tauri.invoke({ cmd: 'exit' })
|
||||
window.__TAURI__.invoke({
|
||||
cmd: 'exit'
|
||||
})
|
||||
}, 15000)
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
"paths": {
|
||||
"types": ["src/types"]
|
||||
},
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src"]
|
||||
"include": ["src", "api-src"]
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ module.exports = {
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /templates[\\/](tauri|mutation-observer)\.js/,
|
||||
test: /(templates|api)[\\/].+\.js/,
|
||||
use: 'raw-loader'
|
||||
},
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.1":
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.1", "@babel/code-frame@^7.8.3":
|
||||
version "7.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.1.tgz#d5481c5095daa1c57e16e54c6f9198443afb49ff"
|
||||
integrity sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==
|
||||
@ -208,7 +208,7 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.10.1"
|
||||
|
||||
"@babel/helper-module-imports@^7.10.1":
|
||||
"@babel/helper-module-imports@^7.10.1", "@babel/helper-module-imports@^7.7.4":
|
||||
version "7.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz#dd331bd45bccc566ce77004e9d05fe17add13876"
|
||||
integrity sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==
|
||||
@ -1189,6 +1189,72 @@
|
||||
"@nodelib/fs.scandir" "2.1.3"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@rollup/plugin-babel@^5.0.3":
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.0.3.tgz#8d416865b0da79faf14e07c8d233abe0eac0753d"
|
||||
integrity sha512-NlaPf4E6YFxeOCbqc+A2PTkB1BSy3rfKu6EJuQ1MGhMHpTVvMqKi6Rf0DlwtnEsTNK9LueUgsGEgp5Occ4KDVA==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.7.4"
|
||||
"@rollup/pluginutils" "^3.0.8"
|
||||
|
||||
"@rollup/plugin-commonjs@13.0.0":
|
||||
version "13.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-13.0.0.tgz#8a1d684ba6848afe8b9e3d85649d4b2f6f7217ec"
|
||||
integrity sha512-Anxc3qgkAi7peAyesTqGYidG5GRim9jtg8xhmykNaZkImtvjA7Wsqep08D2mYsqw1IF7rA3lYfciLgzUSgRoqw==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.0.8"
|
||||
commondir "^1.0.1"
|
||||
estree-walker "^1.0.1"
|
||||
glob "^7.1.2"
|
||||
is-reference "^1.1.2"
|
||||
magic-string "^0.25.2"
|
||||
resolve "^1.11.0"
|
||||
|
||||
"@rollup/plugin-json@4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3"
|
||||
integrity sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.0.8"
|
||||
|
||||
"@rollup/plugin-node-resolve@8.0.1":
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-8.0.1.tgz#364b5938808ee6b5164dea5ef7291be3f7395199"
|
||||
integrity sha512-KIeAmueDDaYMqMBnUngLVVZhURwxA12nq/YB6nGm5/JpVyOMwI1fCVU3oL/dAnnLBG7oiPXntO5LHOiMrfNXCA==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.0.8"
|
||||
"@types/resolve" "0.0.8"
|
||||
builtin-modules "^3.1.0"
|
||||
deep-freeze "^0.0.1"
|
||||
deepmerge "^4.2.2"
|
||||
is-module "^1.0.0"
|
||||
resolve "^1.14.2"
|
||||
|
||||
"@rollup/plugin-sucrase@^3.0.2":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-sucrase/-/plugin-sucrase-3.0.2.tgz#681cacef67a0328a903e5f431f461d73899b545b"
|
||||
integrity sha512-6fglZKerNRlGN7MJLuUX9fFpOT/md4mqje5pC1gltJAdFo++5NqTfPmcJ9sgXSytwqAK6jiwnUQwbBovieaEzw==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.0.1"
|
||||
sucrase "^3.10.1"
|
||||
|
||||
"@rollup/plugin-typescript@4.1.2":
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-4.1.2.tgz#6f910430276ae3e53a47a12ad65820627e7b6ad9"
|
||||
integrity sha512-+7UlGat/99e2JbmGNnIauxwEhYLwrL7adO/tSJxUN57xrrS3Ps+ZzYpLCDGPZJ57j+ZJTZLLN89KXW9JMEB+jg==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.0.1"
|
||||
resolve "^1.14.1"
|
||||
|
||||
"@rollup/pluginutils@^3.0.1", "@rollup/pluginutils@^3.0.8":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
|
||||
integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==
|
||||
dependencies:
|
||||
"@types/estree" "0.0.39"
|
||||
estree-walker "^1.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@sindresorhus/is@^0.14.0":
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
|
||||
@ -1314,6 +1380,16 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
|
||||
|
||||
"@types/estree@0.0.39":
|
||||
version "0.0.39"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
||||
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
||||
|
||||
"@types/estree@0.0.44":
|
||||
version "0.0.44"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.44.tgz#980cc5a29a3ef3bea6ff1f7d021047d7ea575e21"
|
||||
integrity sha512-iaIVzr+w2ZJ5HkidlZ3EJM8VTZb2MJLCjw3V+505yVts0gRC4UMvjw0d1HPtGqI/HQC/KdsYtayfzl+AXY2R8g==
|
||||
|
||||
"@types/events@*":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
||||
@ -1447,6 +1523,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
|
||||
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
|
||||
|
||||
"@types/resolve@0.0.8":
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
|
||||
integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/sharp@0.25.0":
|
||||
version "0.25.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.25.0.tgz#e21501779b110e26f33cec7fb1969e49e0cdc3c0"
|
||||
@ -1879,6 +1962,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.2.1:
|
||||
"@types/color-name" "^1.1.1"
|
||||
color-convert "^2.0.1"
|
||||
|
||||
any-promise@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
|
||||
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
|
||||
|
||||
anymatch@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
|
||||
@ -2439,6 +2527,11 @@ buffer@^5.2.1, buffer@^5.5.0:
|
||||
base64-js "^1.0.2"
|
||||
ieee754 "^1.1.4"
|
||||
|
||||
builtin-modules@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484"
|
||||
integrity sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==
|
||||
|
||||
builtin-status-codes@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
|
||||
@ -2845,6 +2938,11 @@ commander@^2.20.0, commander@~2.20.3:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
commander@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
|
||||
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
|
||||
|
||||
commander@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
|
||||
@ -3292,6 +3390,11 @@ deep-extend@^0.6.0:
|
||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
||||
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
||||
|
||||
deep-freeze@^0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/deep-freeze/-/deep-freeze-0.0.1.tgz#3a0b0005de18672819dfd38cd31f91179c893e84"
|
||||
integrity sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=
|
||||
|
||||
deep-is@^0.1.3, deep-is@~0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
@ -3897,6 +4000,11 @@ estraverse@^5.1.0:
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642"
|
||||
integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==
|
||||
|
||||
estree-walker@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
|
||||
integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
@ -4247,6 +4355,15 @@ find-cache-dir@^2.1.0:
|
||||
make-dir "^2.0.0"
|
||||
pkg-dir "^3.0.0"
|
||||
|
||||
find-cache-dir@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880"
|
||||
integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==
|
||||
dependencies:
|
||||
commondir "^1.0.1"
|
||||
make-dir "^3.0.2"
|
||||
pkg-dir "^4.1.0"
|
||||
|
||||
find-up@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
|
||||
@ -4362,6 +4479,15 @@ fs-constants@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||
|
||||
fs-extra@8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs-extra@9.0.1:
|
||||
version "9.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc"
|
||||
@ -4522,7 +4648,7 @@ glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0:
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
|
||||
glob@7.1.6, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
@ -5237,6 +5363,11 @@ is-installed-globally@^0.3.1:
|
||||
global-dirs "^2.0.1"
|
||||
is-path-inside "^3.0.1"
|
||||
|
||||
is-module@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
|
||||
integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
|
||||
|
||||
is-natural-number@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"
|
||||
@ -5301,6 +5432,13 @@ is-potential-custom-element-name@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397"
|
||||
integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c=
|
||||
|
||||
is-reference@^1.1.2:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.0.tgz#d938b0cf85a0df09849417b274f02fb509293599"
|
||||
integrity sha512-ZVxq+5TkOx6GQdnoMm2aRdCKADdcrOWXLGzGT+vIA8DMpqEJaRk5AL1bS80zJ2bjHunVmjdzfCt0e4BymIEqKQ==
|
||||
dependencies:
|
||||
"@types/estree" "0.0.44"
|
||||
|
||||
is-regex@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
|
||||
@ -5932,6 +6070,13 @@ json5@^2.1.2:
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179"
|
||||
@ -6315,6 +6460,13 @@ lru-cache@^5.1.1:
|
||||
dependencies:
|
||||
yallist "^3.0.2"
|
||||
|
||||
magic-string@^0.25.2:
|
||||
version "0.25.7"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
|
||||
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
|
||||
dependencies:
|
||||
sourcemap-codec "^1.4.4"
|
||||
|
||||
make-dir@^1.0.0, make-dir@^1.2.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
|
||||
@ -6330,7 +6482,7 @@ make-dir@^2.0.0:
|
||||
pify "^4.0.1"
|
||||
semver "^5.6.0"
|
||||
|
||||
make-dir@^3.0.0:
|
||||
make-dir@^3.0.0, make-dir@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
|
||||
integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
|
||||
@ -6594,6 +6746,20 @@ ms@2.1.2, ms@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
mute-stream@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
|
||||
|
||||
mz@^2.7.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
|
||||
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
object-assign "^4.0.1"
|
||||
thenify-all "^1.0.0"
|
||||
|
||||
nan@^2.12.1:
|
||||
version "2.14.1"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
|
||||
@ -7237,7 +7403,7 @@ performance-now@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
|
||||
picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1, picomatch@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
||||
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
|
||||
@ -7290,7 +7456,7 @@ pkg-dir@^3.0.0:
|
||||
dependencies:
|
||||
find-up "^3.0.0"
|
||||
|
||||
pkg-dir@^4.2.0:
|
||||
pkg-dir@^4.1.0, pkg-dir@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
|
||||
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
|
||||
@ -7537,7 +7703,7 @@ querystring@0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
|
||||
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
|
||||
@ -7884,7 +8050,14 @@ resolve-url@^0.2.1:
|
||||
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
||||
|
||||
resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2:
|
||||
resolve@1.15.1:
|
||||
version "1.15.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
|
||||
integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
|
||||
dependencies:
|
||||
path-parse "^1.0.6"
|
||||
|
||||
resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.13.1, resolve@^1.14.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.3.2:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
|
||||
integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
|
||||
@ -7945,6 +8118,34 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
rollup-plugin-terser@6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-6.1.0.tgz#071866585aea104bfbb9dd1019ac523e63c81e45"
|
||||
integrity sha512-4fB3M9nuoWxrwm39habpd4hvrbrde2W2GG4zEGPQg1YITNkM3Tqur5jSuXlWNzbv/2aMLJ+dZJaySc3GCD8oDw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.8.3"
|
||||
jest-worker "^26.0.0"
|
||||
serialize-javascript "^3.0.0"
|
||||
terser "^4.7.0"
|
||||
|
||||
rollup-plugin-typescript2@0.27.1:
|
||||
version "0.27.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.27.1.tgz#4f27193408a8f040139eed3e3db7b0c7f3668200"
|
||||
integrity sha512-RJl77Bbj1EunAQDC3dK/O2HWuSUX3oJbRGzyLoS5o9W4Hs1Nix3Gavqj1Lzs5Y6Ff4H2xXfmZ1WWUQCYocSbzQ==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^3.0.8"
|
||||
find-cache-dir "^3.3.1"
|
||||
fs-extra "8.1.0"
|
||||
resolve "1.15.1"
|
||||
tslib "1.11.2"
|
||||
|
||||
rollup@2.17.1:
|
||||
version "2.17.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.17.1.tgz#d01a27c1b76e42efe2cd786609589f6332e81aa6"
|
||||
integrity sha512-lVrtCXJ+08Eapa0SfApLmRNWNWm2FsYFnLPIJZJvZz2uI2Gv+dfPyu1zgF7KKF/HYFJDvjxbdCbI8lUVMnG7Sg==
|
||||
optionalDependencies:
|
||||
fsevents "~2.1.2"
|
||||
|
||||
rsvp@^4.8.4:
|
||||
version "4.8.5"
|
||||
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734"
|
||||
@ -8092,6 +8293,13 @@ serialize-javascript@^2.1.2:
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
|
||||
integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==
|
||||
|
||||
serialize-javascript@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea"
|
||||
integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==
|
||||
dependencies:
|
||||
randombytes "^2.1.0"
|
||||
|
||||
set-blocking@^2.0.0, set-blocking@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
@ -8331,6 +8539,11 @@ source-map@^0.7.3:
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
||||
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
||||
|
||||
sourcemap-codec@^1.4.4:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
||||
|
||||
spdx-correct@^3.0.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
||||
@ -8653,6 +8866,25 @@ strip-outer@^1.0.0:
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.2"
|
||||
|
||||
sucrase@^3.10.1:
|
||||
version "3.15.0"
|
||||
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.15.0.tgz#78596a78be7264a65b52ed8d873883413ef0220c"
|
||||
integrity sha512-05TJOUfMgckH7wKqfk/1p4G6q16nIeW/GHQwD44vkT0mQMqqzgfHCwkX3whNmwyOo7nVF0jDLwVu/qOBTtsscw==
|
||||
dependencies:
|
||||
commander "^4.0.0"
|
||||
glob "7.1.6"
|
||||
lines-and-columns "^1.1.6"
|
||||
mz "^2.7.0"
|
||||
pirates "^4.0.1"
|
||||
ts-interface-checker "^0.1.9"
|
||||
|
||||
supports-color@6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
|
||||
integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
@ -8822,6 +9054,15 @@ terser@^4.1.2:
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.12"
|
||||
|
||||
terser@^4.7.0:
|
||||
version "4.8.0"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
|
||||
integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==
|
||||
dependencies:
|
||||
commander "^2.20.0"
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.12"
|
||||
|
||||
test-exclude@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
|
||||
@ -8843,6 +9084,20 @@ then-fs@^2.0.0:
|
||||
dependencies:
|
||||
promise ">=3.2 <8"
|
||||
|
||||
thenify-all@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
|
||||
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
|
||||
dependencies:
|
||||
thenify ">= 3.1.0 < 4"
|
||||
|
||||
"thenify@>= 3.1.0 < 4":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
|
||||
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
|
||||
throat@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
|
||||
@ -8978,6 +9233,11 @@ trim-repeated@^1.0.0:
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.2"
|
||||
|
||||
ts-interface-checker@^0.1.9:
|
||||
version "0.1.11"
|
||||
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.11.tgz#07e7eddb08212f83fef12c253d0cefa8c70fe1bc"
|
||||
integrity sha512-Jx6cFBiuCQrRl3CgoIOamIE/toZ8jQJbIlsLGpkBiUpCEUyFcyZ2pvjP8kSXIcz8V5v/murgm/5EfIQapUmh6A==
|
||||
|
||||
ts-loader@7.0.5:
|
||||
version "7.0.5"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-7.0.5.tgz#789338fb01cb5dc0a33c54e50558b34a73c9c4c5"
|
||||
@ -8999,6 +9259,16 @@ tsconfig-paths@^3.9.0:
|
||||
minimist "^1.2.0"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@1.11.2:
|
||||
version "1.11.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.2.tgz#9c79d83272c9a7aaf166f73915c9667ecdde3cc9"
|
||||
integrity sha512-tTSkux6IGPnUGUd1XAZHcpu85MOkIl5zX49pO+jfsie3eP0B6pyhOlLXm3cAC6T7s+euSDDUUV+Acop5WmtkVg==
|
||||
|
||||
tslib@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.0.tgz#18d13fc2dce04051e20f074cc8387fd8089ce4f3"
|
||||
integrity sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==
|
||||
|
||||
tslib@^1.8.1, tslib@^1.9.0:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
|
||||
@ -9148,6 +9418,11 @@ unique-string@^2.0.0:
|
||||
dependencies:
|
||||
crypto-random-string "^2.0.0"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
|
||||
universalify@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
|
||||
|
||||
@ -58,9 +58,9 @@ if ((Test-Path $dist_path -PathType Any) -Or (Test-Path $src_path -PathType Any)
|
||||
cargo install --path cli\tauri-bundler --force
|
||||
cargo install cargo-web
|
||||
|
||||
# install the tauri Node CLI.
|
||||
# install the tauri Node CLI and transpile the TS version of the API.
|
||||
cd cli\tauri.js
|
||||
yarn; yarn build
|
||||
yarn; yarn build;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ tauri-api = { version = "0.6", path = "../tauri-api" }
|
||||
|
||||
[build-dependencies]
|
||||
tauri_includedir_codegen = "0.6.0"
|
||||
cfg_aliases = "0.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = "0.10.0"
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use cfg_aliases::cfg_aliases;
|
||||
|
||||
#[cfg(any(feature = "embedded-server", feature = "no-server"))]
|
||||
use std::{
|
||||
env,
|
||||
@ -72,4 +74,48 @@ fn shared() {
|
||||
tauri_path.push("tauri.conf.json");
|
||||
println!("cargo:rerun-if-changed={:?}", tauri_path);
|
||||
}
|
||||
|
||||
cfg_aliases! {
|
||||
embedded_server: { feature = "embedded-server" },
|
||||
no_server: { feature = "no-server" },
|
||||
assets: { any(feature = "embedded-server", feature = "no-server") },
|
||||
dev: { not(any(feature = "embedded-server", feature = "no-server")) },
|
||||
|
||||
all_api: { feature = "all-api" },
|
||||
|
||||
// fs
|
||||
read_text_file: { any(all_api, feature = "read-text-file") },
|
||||
read_binary_file: { any(all_api, feature = "read-binary-file") },
|
||||
write_file: { any(all_api, feature = "write-file") },
|
||||
write_binary_file: { any(all_api, feature = "write-binary-file") },
|
||||
read_dir: { any(all_api, feature = "read-dir") },
|
||||
copy_file: { any(all_api, feature = "copy-file") },
|
||||
create_dir: { any(all_api, feature = "create_dir") },
|
||||
remove_dir: { any(all_api, feature = "remove-dir") },
|
||||
remove_file: { any(all_api, feature = "remove-file") },
|
||||
rename_file: { any(all_api, feature = "rename-file") },
|
||||
|
||||
// window
|
||||
set_title: { any(all_api, feature = "set-title") },
|
||||
open: { any(all_api, feature = "open") },
|
||||
|
||||
// process
|
||||
execute: { any(all_api, feature = "execute") },
|
||||
|
||||
// event
|
||||
event: { any(all_api, feature = "event") },
|
||||
|
||||
// dialog
|
||||
open_dialog: { any(all_api, feature = "open-dialog") },
|
||||
save_dialog: { any(all_api, feature = "save-dialog") },
|
||||
|
||||
// http
|
||||
http_request: { any(all_api, feature = "http-request") },
|
||||
|
||||
// cli
|
||||
cli: { feature = "cli" },
|
||||
|
||||
// notification
|
||||
notification: { any(all_api, feature = "notification") },
|
||||
}
|
||||
}
|
||||
|
||||
2
tauri/examples/communication/dist/cli.js
vendored
2
tauri/examples/communication/dist/cli.js
vendored
@ -1,5 +1,5 @@
|
||||
document.getElementById('cli-matches').addEventListener('click', function () {
|
||||
window.tauri.cliMatches()
|
||||
window.__TAURI__.cli.getMatches()
|
||||
.then(registerResponse)
|
||||
.catch(registerResponse)
|
||||
})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
document.getElementById('log').addEventListener('click', function () {
|
||||
window.tauri.invoke({
|
||||
window.__TAURI__.invoke({
|
||||
cmd: 'logOperation',
|
||||
event: 'tauri-click',
|
||||
payload: 'this payload is optional because we used Option in Rust'
|
||||
@ -7,7 +7,7 @@ document.getElementById('log').addEventListener('click', function () {
|
||||
})
|
||||
|
||||
document.getElementById('request').addEventListener('click', function () {
|
||||
window.tauri.promisified({
|
||||
window.__TAURI__.promisified({
|
||||
cmd: 'performRequest',
|
||||
endpoint: 'dummy endpoint arg',
|
||||
body: {
|
||||
@ -18,6 +18,5 @@ document.getElementById('request').addEventListener('click', function () {
|
||||
})
|
||||
|
||||
document.getElementById('event').addEventListener('click', function () {
|
||||
window.tauri.emit('js-event', 'this is the payload string')
|
||||
window.__TAURI__.event.emit('js-event', 'this is the payload string')
|
||||
})
|
||||
|
||||
|
||||
6
tauri/examples/communication/dist/dialog.js
vendored
6
tauri/examples/communication/dist/dialog.js
vendored
@ -4,7 +4,7 @@ var multipleInput = document.getElementById('dialog-multiple')
|
||||
var directoryInput = document.getElementById('dialog-directory')
|
||||
|
||||
document.getElementById('open-dialog').addEventListener('click', function () {
|
||||
window.tauri.openDialog({
|
||||
window.__TAURI__.dialog.open({
|
||||
defaultPath: defaultPathInput.value || null,
|
||||
filter: filterInput.value || null,
|
||||
multiple: multipleInput.checked,
|
||||
@ -13,7 +13,7 @@ document.getElementById('open-dialog').addEventListener('click', function () {
|
||||
console.log(res)
|
||||
var pathToRead = res
|
||||
var isFile = pathToRead.match(/\S+\.\S+$/g)
|
||||
window.tauri.readBinaryFile(pathToRead).then(function (response) {
|
||||
window.__TAURI__.fs.readBinaryFile(pathToRead).then(function (response) {
|
||||
if (isFile) {
|
||||
if (pathToRead.includes('.png') || pathToRead.includes('.jpg')) {
|
||||
arrayBufferToBase64(new Uint8Array(response), function (base64) {
|
||||
@ -31,7 +31,7 @@ document.getElementById('open-dialog').addEventListener('click', function () {
|
||||
})
|
||||
|
||||
document.getElementById('save-dialog').addEventListener('click', function () {
|
||||
window.tauri.saveDialog({
|
||||
window.__TAURI__.dialog.save({
|
||||
defaultPath: defaultPathInput.value || null,
|
||||
filter: filterInput.value || null
|
||||
}).then(registerResponse).catch(registerResponse)
|
||||
|
||||
11
tauri/examples/communication/dist/fs.js
vendored
11
tauri/examples/communication/dist/fs.js
vendored
@ -1,5 +1,6 @@
|
||||
var dirSelect = document.getElementById('dir')
|
||||
function getDir () {
|
||||
|
||||
function getDir() {
|
||||
return dirSelect.value ? parseInt(dir.value) : null
|
||||
}
|
||||
|
||||
@ -23,8 +24,10 @@ addClickEnterHandler(
|
||||
function () {
|
||||
var pathToRead = pathInput.value
|
||||
var isFile = pathToRead.match(/\S+\.\S+$/g)
|
||||
var opts = { dir: getDir() }
|
||||
var promise = isFile ? window.tauri.readBinaryFile(pathToRead, opts) : window.tauri.readDir(pathToRead, opts)
|
||||
var opts = {
|
||||
dir: getDir()
|
||||
}
|
||||
var promise = isFile ? window.__TAURI__.fs.readBinaryFile(pathToRead, opts) : window.__TAURI__.fs.readDir(pathToRead, opts)
|
||||
promise.then(function (response) {
|
||||
if (isFile) {
|
||||
if (pathToRead.includes('.png') || pathToRead.includes('.jpg')) {
|
||||
@ -38,7 +41,7 @@ addClickEnterHandler(
|
||||
var fileInput = document.getElementById('file-response')
|
||||
fileInput.value = value
|
||||
document.getElementById('file-save').addEventListener('click', function () {
|
||||
window.tauri.writeFile({
|
||||
window.__TAURI__.fs.writeFile({
|
||||
file: pathToRead,
|
||||
contents: fileInput.value
|
||||
}, {
|
||||
|
||||
4
tauri/examples/communication/dist/http.js
vendored
4
tauri/examples/communication/dist/http.js
vendored
@ -19,5 +19,5 @@ document.getElementById('make-request').addEventListener('click', function () {
|
||||
}
|
||||
options.body = body
|
||||
|
||||
window.tauri.httpRequest(options).then(registerResponse).catch(registerResponse)
|
||||
})
|
||||
window.__TAURI__.http.request(options).then(registerResponse).catch(registerResponse)
|
||||
})
|
||||
|
||||
18
tauri/examples/communication/dist/index.html
vendored
18
tauri/examples/communication/dist/index.html
vendored
@ -284,21 +284,23 @@
|
||||
})
|
||||
}
|
||||
|
||||
window.tauri.listen('rust-event', function (res) {
|
||||
window.__TAURI__.event.listen('rust-event', function (res) {
|
||||
document.getElementById('response').innerHTML = JSON.stringify(res)
|
||||
})
|
||||
|
||||
document.querySelector('.logo').addEventListener('click', function () {
|
||||
window.tauri.open('https://tauri.studio/')
|
||||
window.__TAURI__.window.open('https://tauri.studio/')
|
||||
})
|
||||
|
||||
var dirSelect = document.getElementById('dir')
|
||||
for (var key in window.tauri.Dir) {
|
||||
var value = window.tauri.Dir[key]
|
||||
var opt = document.createElement("option")
|
||||
opt.value = value
|
||||
opt.innerHTML = key
|
||||
dirSelect.appendChild(opt)
|
||||
for (var key in window.__TAURI__.fs.Dir) {
|
||||
if (isNaN(parseInt(key))) {
|
||||
var value = window.__TAURI__.fs.Dir[key]
|
||||
var opt = document.createElement("option")
|
||||
opt.value = value
|
||||
opt.innerHTML = key
|
||||
dirSelect.appendChild(opt)
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
723
tauri/examples/communication/dist/index.tauri.html
vendored
723
tauri/examples/communication/dist/index.tauri.html
vendored
File diff suppressed because one or more lines are too long
4
tauri/examples/communication/dist/window.js
vendored
4
tauri/examples/communication/dist/window.js
vendored
@ -4,7 +4,7 @@ addClickEnterHandler(
|
||||
document.getElementById('open-url'),
|
||||
urlInput,
|
||||
function () {
|
||||
window.tauri.open(urlInput.value)
|
||||
window.__TAURI__.window.open(urlInput.value)
|
||||
}
|
||||
)
|
||||
|
||||
@ -14,6 +14,6 @@ addClickEnterHandler(
|
||||
document.getElementById('set-title'),
|
||||
titleInput,
|
||||
function () {
|
||||
window.tauri.setTitle(titleInput.value)
|
||||
window.__TAURI__.window.setTitle(titleInput.value)
|
||||
}
|
||||
)
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
{
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
"devPath": "../dist"
|
||||
"devPath": "../dist",
|
||||
"withGlobalTauri": true
|
||||
},
|
||||
"ctx": {},
|
||||
"tauri": {
|
||||
|
||||
@ -1,732 +0,0 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* * THIS FILE IS GENERATED AUTOMATICALLY.
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Please whitelist these API functions in tauri.conf.json
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
* @module tauri
|
||||
* @description This API interface makes powerful interactions available
|
||||
* to be run on client side applications. They are opt-in features, and
|
||||
* must be enabled in tauri.conf.json
|
||||
*
|
||||
* Each binding MUST provide these interfaces in order to be compliant,
|
||||
* and also whitelist them based upon the developer's settings.
|
||||
*/
|
||||
|
||||
// polyfills
|
||||
if (!String.prototype.startsWith) {
|
||||
String.prototype.startsWith = function (searchString, position) {
|
||||
position = position || 0
|
||||
return this.substr(position, searchString.length) === searchString
|
||||
}
|
||||
}
|
||||
|
||||
// makes the window.external.invoke API available after window.location.href changes
|
||||
|
||||
switch (navigator.platform) {
|
||||
case "Macintosh":
|
||||
case "MacPPC":
|
||||
case "MacIntel":
|
||||
case "Mac68K":
|
||||
window.external = this
|
||||
invoke = function (x) {
|
||||
webkit.messageHandlers.invoke.postMessage(x);
|
||||
}
|
||||
break;
|
||||
case "Windows":
|
||||
case "WinCE":
|
||||
case "Win32":
|
||||
case "Win64":
|
||||
break;
|
||||
default:
|
||||
window.external = this
|
||||
invoke = function (x) {
|
||||
window.webkit.messageHandlers.external.postMessage(x);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
(function () {
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1)
|
||||
}
|
||||
|
||||
var uid = function () {
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4()
|
||||
}
|
||||
|
||||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
|
||||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
/**
|
||||
* @typedef {number} BaseDirectory
|
||||
*/
|
||||
/**
|
||||
* @enum {BaseDirectory}
|
||||
*/
|
||||
var Dir = {
|
||||
Audio: 1,
|
||||
Cache: 2,
|
||||
Config: 3,
|
||||
Data: 4,
|
||||
LocalData: 5,
|
||||
Desktop: 6,
|
||||
Document: 7,
|
||||
Download: 8,
|
||||
Executable: 9,
|
||||
Font: 10,
|
||||
Home: 11,
|
||||
Picture: 12,
|
||||
Public: 13,
|
||||
Runtime: 14,
|
||||
Template: 15,
|
||||
Video: 16,
|
||||
Resource: 17,
|
||||
App: 18
|
||||
}
|
||||
|
||||
|
||||
function camelToKebab (string) {
|
||||
return string.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase()
|
||||
}
|
||||
/**
|
||||
* @name return __whitelistWarning
|
||||
* @description Present a stylish warning to the developer that their API
|
||||
* call has not been whitelisted in tauri.conf.json
|
||||
* @param {String} func - function name to warn
|
||||
* @private
|
||||
*/
|
||||
var __whitelistWarning = function (func) {
|
||||
console.warn('%c[Tauri] Danger \ntauri.' + func + ' not whitelisted 💣\n%c\nAdd to tauri.conf.json: \n\ntauri: \n whitelist: { \n ' + camelToKebab(func) + ': true \n\nReference: https://github.com/tauri-apps/tauri/wiki' + func, 'background: red; color: white; font-weight: 800; padding: 2px; font-size:1.5em', ' ')
|
||||
return __reject()
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @name __reject
|
||||
* @description generates a promise used to deflect un-whitelisted tauri API calls
|
||||
* Its only purpose is to maintain thenable structure in client code without
|
||||
* breaking the application
|
||||
* * @type {Promise<any>}
|
||||
* @private
|
||||
*/
|
||||
|
||||
var __reject = function () {
|
||||
return new Promise(function (_, reject) {
|
||||
reject();
|
||||
});
|
||||
}
|
||||
|
||||
window.tauri = {
|
||||
Dir: Dir,
|
||||
|
||||
/**
|
||||
* @name invoke
|
||||
* @description Calls a Tauri Core feature, such as setTitle
|
||||
* @param {Object} args
|
||||
*/
|
||||
|
||||
invoke: function invoke(args) {
|
||||
window.external.invoke(JSON.stringify(args));
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name listen
|
||||
* @description Add an event listener to Tauri backend
|
||||
* @param {String} event
|
||||
* @param {Function} handler
|
||||
* @param {Boolean} once
|
||||
*/
|
||||
|
||||
listen: function listen(event, handler) {
|
||||
|
||||
var once = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
||||
this.invoke({
|
||||
cmd: 'listen',
|
||||
event: event,
|
||||
handler: window.tauri.transformCallback(handler, once),
|
||||
once: once
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name emit
|
||||
* @description Emits an evt to the Tauri back end
|
||||
* @param {String} evt
|
||||
* @param {Object} payload
|
||||
*/
|
||||
|
||||
emit: function emit(evt, payload) {
|
||||
|
||||
this.invoke({
|
||||
cmd: 'emit',
|
||||
event: evt,
|
||||
payload: payload
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name transformCallback
|
||||
* @description Registers a callback with a uid
|
||||
* @param {Function} callback
|
||||
* @param {Boolean} once
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
transformCallback: function transformCallback(callback) {
|
||||
var once = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||
var identifier = uid();
|
||||
|
||||
window[identifier] = function (result) {
|
||||
if (once) {
|
||||
delete window[identifier];
|
||||
}
|
||||
|
||||
return callback && callback(result);
|
||||
};
|
||||
|
||||
return identifier;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name promisified
|
||||
* @description Turns a request into a chainable promise
|
||||
* @param {Object} args
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
|
||||
promisified: function promisified(args) {
|
||||
var _this = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
_this.invoke(_objectSpread({
|
||||
callback: _this.transformCallback(resolve),
|
||||
error: _this.transformCallback(reject)
|
||||
}, args));
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name readTextFile
|
||||
* @description Accesses a non-binary file on the user's filesystem
|
||||
* and returns the content. Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
readTextFile: function readTextFile(path, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'readTextFile',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name readBinaryFile
|
||||
* @description Accesses a binary file on the user's filesystem
|
||||
* and returns the content. Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
readBinaryFile: function readBinaryFile(path, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'readBinaryFile',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name writeFile
|
||||
* @description Write a file to the Local Filesystem.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {Object} cfg
|
||||
* @param {String} cfg.file
|
||||
* @param {String|Binary} cfg.contents
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
*/
|
||||
|
||||
writeFile: function writeFile(cfg, options) {
|
||||
|
||||
if (_typeof(cfg) === 'object') {
|
||||
Object.freeze(cfg);
|
||||
}
|
||||
return this.promisified({
|
||||
cmd: 'writeFile',
|
||||
file: cfg.file,
|
||||
contents: cfg.contents,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name readDir
|
||||
* @description Reads a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
readDir: function readDir(path, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'readDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name createDir
|
||||
* @description Creates a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
createDir: function createDir(path, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'createDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name removeDir
|
||||
* @description Removes a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
removeDir: function removeDir(path, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'removeDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name copyFile
|
||||
* @description Copy file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} source
|
||||
* @param {String} destination
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
copyFile: function copyFile(source, destination, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'copyFile',
|
||||
source: source,
|
||||
destination: destination,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name removeFile
|
||||
* @description Removes a file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
removeFile: function removeFile(path, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'removeFile',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name renameFile
|
||||
* @description Renames a file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
renameFile: function renameFile(oldPath, newPath, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'renameFile',
|
||||
oldPath: oldPath,
|
||||
newPath: newPath,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name setTitle
|
||||
* @description Set the application's title
|
||||
* @param {String} title
|
||||
*/
|
||||
|
||||
setTitle: function setTitle(title) {
|
||||
|
||||
this.invoke({
|
||||
cmd: 'setTitle',
|
||||
title: title
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name open
|
||||
* @description Open an URI
|
||||
* @param {String} uri
|
||||
*/
|
||||
|
||||
open: function open(uri) {
|
||||
|
||||
this.invoke({
|
||||
cmd: 'open',
|
||||
uri: uri
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name execute
|
||||
* @description Execute a program with arguments.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} command
|
||||
* @param {String|Array} args
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
execute: function execute(command, args) {
|
||||
|
||||
|
||||
if (_typeof(args) === 'object') {
|
||||
Object.freeze(args);
|
||||
}
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'execute',
|
||||
command: command,
|
||||
args: typeof args === 'string' ? [args] : args
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name openDialog
|
||||
* @description Open a file/directory selection dialog
|
||||
* @param {String} [options]
|
||||
* @param {String} [options.filter]
|
||||
* @param {String} [options.defaultPath]
|
||||
* @param {Boolean} [options.multiple=false]
|
||||
* @param {Boolean} [options.directory=false]
|
||||
* @returns {Promise<String|String[]>} promise resolving to the select path(s)
|
||||
*/
|
||||
|
||||
openDialog: function openDialog(options) {
|
||||
|
||||
var opts = options || {}
|
||||
if (_typeof(options) === 'object') {
|
||||
opts.default_path = opts.defaultPath
|
||||
Object.freeze(options);
|
||||
}
|
||||
return this.promisified({
|
||||
cmd: 'openDialog',
|
||||
options: opts
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name saveDialog
|
||||
* @description Open a file/directory save dialog
|
||||
* @param {String} [options]
|
||||
* @param {String} [options.filter]
|
||||
* @param {String} [options.defaultPath]
|
||||
* @returns {Promise<String>} promise resolving to the select path
|
||||
*/
|
||||
|
||||
saveDialog: function saveDialog(options) {
|
||||
|
||||
var opts = options || {}
|
||||
if (_typeof(options) === 'object') {
|
||||
opts.default_path = opts.defaultPath
|
||||
Object.freeze(options);
|
||||
}
|
||||
return this.promisified({
|
||||
cmd: 'saveDialog',
|
||||
options: opts
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name httpRequest
|
||||
* @description Makes an HTTP request
|
||||
* @param {Object} options
|
||||
* @param {String} options.method GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT or TRACE
|
||||
* @param {String} options.url the request URL
|
||||
* @param {Object} [options.headers] the request headers
|
||||
* @param {Object} [options.params] the request query params
|
||||
* @param {Object|String|Binary} [options.body] the request body
|
||||
* @param {Boolean} followRedirects whether to follow redirects or not
|
||||
* @param {Number} maxRedirections max number of redirections
|
||||
* @param {Number} connectTimeout request connect timeout
|
||||
* @param {Number} readTimeout request read timeout
|
||||
* @param {Number} timeout request timeout
|
||||
* @param {Boolean} allowCompression
|
||||
* @param {Number} [responseType=1] 1 - JSON, 2 - Text, 3 - Binary
|
||||
* @param {Number} [bodyType=3] 1 - Form, 2 - File, 3 - Auto
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
|
||||
httpRequest: function httpRequest(options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'httpRequest',
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* @name notification
|
||||
* @description Display a desktop notification
|
||||
* @param {Object|String} options the notifications options if an object, otherwise its body
|
||||
* @param {String} [options.summary] the notification's summary
|
||||
* @param {String} options.body the notification's body
|
||||
* @param {String} [options.icon] the notifications's icon
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
notification: function notification(options) {
|
||||
|
||||
|
||||
if (_typeof(options) === 'object') {
|
||||
Object.freeze(options);
|
||||
}
|
||||
|
||||
return window.tauri.isNotificationPermissionGranted()
|
||||
.then(function (permission) {
|
||||
if (permission) {
|
||||
return window.tauri.promisified({
|
||||
cmd: 'notification',
|
||||
options: typeof options === 'string' ? {
|
||||
body: options
|
||||
} : options
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
isNotificationPermissionGranted: function isNotificationPermissionGranted() {
|
||||
|
||||
if (window.Notification.permission !== 'default' && window.Notification.permission !== 'loading') {
|
||||
return Promise.resolve(window.Notification.permission === 'granted')
|
||||
}
|
||||
return window.tauri.promisified({
|
||||
cmd: 'isNotificationPermissionGranted'
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
requestNotificationPermission: function requestNotificationPermission() {
|
||||
|
||||
return window.tauri.promisified({
|
||||
cmd: 'requestNotificationPermission'
|
||||
}).then(function (state) {
|
||||
setNotificationPermission(state)
|
||||
return state
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
loadAsset: function loadAsset(assetName, assetType) {
|
||||
return this.promisified({
|
||||
cmd: 'loadAsset',
|
||||
asset: assetName,
|
||||
assetType: assetType || 'unknown'
|
||||
})
|
||||
},
|
||||
|
||||
cliMatches: function () {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'cliMatches'
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var notificationPermissionSettable = false
|
||||
var notificationPermission = 'default'
|
||||
function setNotificationPermission(value) {
|
||||
notificationPermissionSettable = true
|
||||
window.Notification.permission = value
|
||||
notificationPermissionSettable = false
|
||||
}
|
||||
|
||||
window.Notification = function (title, options) {
|
||||
if (options === void 0) {
|
||||
options = {}
|
||||
}
|
||||
options.title = title
|
||||
window.tauri.notification(options)
|
||||
}
|
||||
window.Notification.requestPermission = window.tauri.requestNotificationPermission
|
||||
|
||||
Object.defineProperty(window.Notification, 'permission', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return notificationPermission
|
||||
},
|
||||
set: function(v) {
|
||||
if (!notificationPermissionSettable) {
|
||||
throw new Error("Readonly property")
|
||||
}
|
||||
notificationPermission = v
|
||||
}
|
||||
});
|
||||
|
||||
setNotificationPermission('loading')
|
||||
window.tauri.isNotificationPermissionGranted()
|
||||
.then(function (response) {
|
||||
if (response === null) {
|
||||
setNotificationPermission('default')
|
||||
} else {
|
||||
setNotificationPermission(response ? 'granted' : 'denied')
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
// init tauri API
|
||||
try {
|
||||
window.tauri.invoke({
|
||||
cmd: 'init'
|
||||
})
|
||||
} catch (e) {
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
window.tauri.invoke({
|
||||
cmd: 'init'
|
||||
})
|
||||
}, true)
|
||||
}
|
||||
|
||||
document.addEventListener('error', function (e) {
|
||||
var target = e.target
|
||||
while (target != null) {
|
||||
if (target.matches ? target.matches('img') : target.msMatchesSelector('img')) {
|
||||
window.tauri.loadAsset(target.src, 'image')
|
||||
.then(function (img) {
|
||||
target.src = img
|
||||
})
|
||||
break
|
||||
}
|
||||
target = target.parentElement
|
||||
}
|
||||
}, true)
|
||||
|
||||
// open <a href="..."> links with the Tauri API
|
||||
function __openLinks() {
|
||||
document.querySelector('body').addEventListener('click', function (e) {
|
||||
var target = e.target
|
||||
while (target != null) {
|
||||
if (target.matches ? target.matches('a') : target.msMatchesSelector('a')) {
|
||||
if (target.href && target.href.startsWith('http') && target.target === '_blank') {
|
||||
window.tauri.open(target.href)
|
||||
e.preventDefault()
|
||||
}
|
||||
break
|
||||
}
|
||||
target = target.parentElement
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
|
||||
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||
__openLinks()
|
||||
} else {
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
__openLinks()
|
||||
}, true)
|
||||
}
|
||||
})()
|
||||
@ -10,7 +10,7 @@ use std::{
|
||||
use web_view::{builder, Content, WebView};
|
||||
|
||||
use super::App;
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
use crate::api::tcp::{get_available_port, port_is_available};
|
||||
use tauri_api::config::get;
|
||||
|
||||
@ -20,7 +20,7 @@ pub(crate) fn run(application: &mut App) -> crate::Result<()> {
|
||||
let main_content = setup_content()?;
|
||||
|
||||
// setup the server url for the embedded-server
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
let server_url = {
|
||||
if let Content::Url(ref url) = &main_content {
|
||||
String::from(url)
|
||||
@ -46,7 +46,7 @@ pub(crate) fn run(application: &mut App) -> crate::Result<()> {
|
||||
)?;
|
||||
|
||||
// spawn the embedded server on our server url
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
spawn_server(server_url.to_string())?;
|
||||
|
||||
// spin up the updater process
|
||||
@ -60,7 +60,7 @@ pub(crate) fn run(application: &mut App) -> crate::Result<()> {
|
||||
}
|
||||
|
||||
// setup content for dev-server
|
||||
#[cfg(not(any(feature = "embedded-server", feature = "no-server")))]
|
||||
#[cfg(dev)]
|
||||
fn setup_content() -> crate::Result<Content<String>> {
|
||||
let config = get()?;
|
||||
if config.build.dev_path.starts_with("http") {
|
||||
@ -79,7 +79,7 @@ fn setup_content() -> crate::Result<Content<String>> {
|
||||
}
|
||||
|
||||
// setup content for embedded server
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
fn setup_content() -> crate::Result<Content<String>> {
|
||||
let (port, valid) = setup_port()?;
|
||||
let url = (if valid {
|
||||
@ -93,14 +93,14 @@ fn setup_content() -> crate::Result<Content<String>> {
|
||||
}
|
||||
|
||||
// setup content for no-server
|
||||
#[cfg(feature = "no-server")]
|
||||
#[cfg(no_server)]
|
||||
fn setup_content() -> crate::Result<Content<String>> {
|
||||
let html = include_str!(concat!(env!("OUT_DIR"), "/index.tauri.html"));
|
||||
Ok(Content::Html(html.to_string()))
|
||||
}
|
||||
|
||||
// get the port for the embedded server
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
fn setup_port() -> crate::Result<(String, bool)> {
|
||||
let config = get()?;
|
||||
if config.tauri.embedded_server.port == "random" {
|
||||
@ -120,7 +120,7 @@ fn setup_port() -> crate::Result<(String, bool)> {
|
||||
}
|
||||
|
||||
// setup the server url for embedded server
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
fn setup_server_url(port: String) -> crate::Result<String> {
|
||||
let config = get()?;
|
||||
let mut url = format!("{}:{}", config.tauri.embedded_server.host, port);
|
||||
@ -131,7 +131,7 @@ fn setup_server_url(port: String) -> crate::Result<String> {
|
||||
}
|
||||
|
||||
// spawn the embedded server
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
fn spawn_server(server_url: String) -> crate::Result<()> {
|
||||
spawn(move || {
|
||||
let server = tiny_http::Server::http(
|
||||
@ -294,13 +294,13 @@ mod test {
|
||||
env::set_current_dir(tauri_dir).expect("failed to change cwd");
|
||||
let res = super::setup_content();
|
||||
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
match res {
|
||||
Ok(Content::Url(u)) => assert!(u.contains("http://")),
|
||||
_ => assert!(false),
|
||||
}
|
||||
|
||||
#[cfg(feature = "no-server")]
|
||||
#[cfg(no_server)]
|
||||
match res {
|
||||
Ok(Content::Html(s)) => {
|
||||
let dist_dir = match option_env!("TAURI_DIST_DIR") {
|
||||
@ -319,7 +319,7 @@ mod test {
|
||||
_ => assert!(false),
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "embedded-server", feature = "no-server")))]
|
||||
#[cfg(dev)]
|
||||
match res {
|
||||
Ok(Content::Url(dp)) => assert_eq!(dp, config.build.dev_path),
|
||||
Ok(Content::Html(s)) => {
|
||||
@ -334,7 +334,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
#[test]
|
||||
fn check_setup_port() {
|
||||
let res = super::setup_port();
|
||||
@ -346,7 +346,7 @@ mod test {
|
||||
|
||||
proptest! {
|
||||
#![proptest_config(ProptestConfig::with_cases(10000))]
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
#[test]
|
||||
fn check_server_url(port in (any::<u32>().prop_map(|v| v.to_string()))) {
|
||||
let p = port.clone();
|
||||
|
||||
@ -1,11 +1,24 @@
|
||||
mod cmd;
|
||||
mod dialog;
|
||||
#[allow(unused_imports)]
|
||||
mod file_system;
|
||||
mod http;
|
||||
mod init;
|
||||
mod salt;
|
||||
|
||||
#[cfg(any(feature = "embedded-server", feature = "no-server"))]
|
||||
use std::path::PathBuf;
|
||||
use init::init;
|
||||
|
||||
#[cfg(assets)]
|
||||
mod asset;
|
||||
#[cfg(open)]
|
||||
mod browser;
|
||||
#[cfg(any(open_dialog, save_dialog))]
|
||||
mod dialog;
|
||||
#[cfg(event)]
|
||||
mod event;
|
||||
#[cfg(http_request)]
|
||||
mod http;
|
||||
#[cfg(notification)]
|
||||
mod notification;
|
||||
|
||||
use web_view::WebView;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
@ -24,25 +37,28 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
|
||||
event_init = event_init
|
||||
))?;
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "read-text-file"))]
|
||||
ReadTextFile {
|
||||
path,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(read_text_file)]
|
||||
file_system::read_text_file(webview, path, options, callback, error);
|
||||
#[cfg(not(read_text_file))]
|
||||
whitelist_error(webview, error, "readTextFile");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "read-binary-file"))]
|
||||
ReadBinaryFile {
|
||||
path,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(read_binary_file)]
|
||||
file_system::read_binary_file(webview, path, options, callback, error);
|
||||
#[cfg(not(read_binary_file))]
|
||||
whitelist_error(webview, error, "readBinaryFile");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "write-file"))]
|
||||
WriteFile {
|
||||
file,
|
||||
contents,
|
||||
@ -50,9 +66,11 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(write_file)]
|
||||
file_system::write_file(webview, file, contents, options, callback, error);
|
||||
#[cfg(not(write_file))]
|
||||
whitelist_error(webview, error, "writeFile");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "write-binary-file"))]
|
||||
WriteBinaryFile {
|
||||
file,
|
||||
contents,
|
||||
@ -62,16 +80,17 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
|
||||
} => {
|
||||
file_system::write_binary_file(webview, file, contents, options, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "read-dir"))]
|
||||
ReadDir {
|
||||
path,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(read_dir)]
|
||||
file_system::read_dir(webview, path, options, callback, error);
|
||||
#[cfg(not(read_dir))]
|
||||
whitelist_error(webview, error, "readDir");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "copy-file"))]
|
||||
CopyFile {
|
||||
source,
|
||||
destination,
|
||||
@ -79,36 +98,44 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(copy_file)]
|
||||
file_system::copy_file(webview, source, destination, options, callback, error);
|
||||
#[cfg(not(copy_file))]
|
||||
whitelist_error(webview, error, "copyFile");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "create-dir"))]
|
||||
CreateDir {
|
||||
path,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(create_dir)]
|
||||
file_system::create_dir(webview, path, options, callback, error);
|
||||
#[cfg(not(create_dir))]
|
||||
whitelist_error(webview, error, "createDir");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "remove-dir"))]
|
||||
RemoveDir {
|
||||
path,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(remove_dir)]
|
||||
file_system::remove_dir(webview, path, options, callback, error);
|
||||
#[cfg(not(remove_dir))]
|
||||
whitelist_error(webview, error, "removeDir");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "remove-file"))]
|
||||
RemoveFile {
|
||||
path,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(remove_file)]
|
||||
file_system::remove_file(webview, path, options, callback, error);
|
||||
#[cfg(not(remove_file))]
|
||||
whitelist_error(webview, error, "removeFile");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "rename-file"))]
|
||||
RenameFile {
|
||||
old_path,
|
||||
new_path,
|
||||
@ -116,24 +143,33 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(rename_file)]
|
||||
file_system::rename_file(webview, old_path, new_path, options, callback, error);
|
||||
#[cfg(not(rename_file))]
|
||||
whitelist_error(webview, error, "renameFile");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "set-title"))]
|
||||
SetTitle { title } => {
|
||||
#[cfg(set_title)]
|
||||
webview.set_title(&title)?;
|
||||
#[cfg(not(set_title))]
|
||||
throw_whitelist_error(webview, "title");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "execute"))]
|
||||
Execute {
|
||||
command,
|
||||
args,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(execute)]
|
||||
crate::call(webview, command, args, callback, error);
|
||||
#[cfg(not(execute))]
|
||||
throw_whitelist_error(webview, "execute");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "open"))]
|
||||
Open { uri } => {
|
||||
open_fn(uri)?;
|
||||
#[cfg(open)]
|
||||
browser::open(uri);
|
||||
#[cfg(not(open))]
|
||||
throw_whitelist_error(webview, "open");
|
||||
}
|
||||
ValidateSalt {
|
||||
salt,
|
||||
@ -142,304 +178,127 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
|
||||
} => {
|
||||
salt::validate(webview, salt, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "event"))]
|
||||
Listen {
|
||||
event,
|
||||
handler,
|
||||
once,
|
||||
} => {
|
||||
let js_string = listen_fn(event, handler, once)?;
|
||||
webview.eval(&js_string)?;
|
||||
#[cfg(event)]
|
||||
{
|
||||
let js_string = event::listen_fn(event, handler, once)?;
|
||||
webview.eval(&js_string)?;
|
||||
}
|
||||
#[cfg(not(event))]
|
||||
throw_whitelist_error(webview, "event");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "event"))]
|
||||
Emit { event, payload } => {
|
||||
#[cfg(event)]
|
||||
crate::event::on_event(event, payload);
|
||||
#[cfg(not(event))]
|
||||
throw_whitelist_error(webview, "event");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "open-dialog"))]
|
||||
OpenDialog {
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(open_dialog)]
|
||||
dialog::open(webview, options, callback, error);
|
||||
#[cfg(not(open_dialog))]
|
||||
whitelist_error(webview, error, "title");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "save-dialog"))]
|
||||
SaveDialog {
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(save_dialog)]
|
||||
dialog::save(webview, options, callback, error);
|
||||
#[cfg(not(save_dialog))]
|
||||
throw_whitelist_error(webview, "saveDialog");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "http-request"))]
|
||||
HttpRequest {
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
#[cfg(http_request)]
|
||||
http::make_request(webview, *options, callback, error);
|
||||
#[cfg(not(http_request))]
|
||||
whitelist_error(webview, error, "httpRequest");
|
||||
}
|
||||
#[cfg(any(feature = "embedded-server", feature = "no-server"))]
|
||||
#[cfg(assets)]
|
||||
LoadAsset {
|
||||
asset,
|
||||
asset_type,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
load_asset(webview, asset, asset_type, callback, error)?;
|
||||
asset::load(webview, asset, asset_type, callback, error);
|
||||
}
|
||||
CliMatches { callback, error } => {
|
||||
#[cfg(cli)]
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || match crate::cli::get_matches() {
|
||||
Some(matches) => Ok(serde_json::to_string(matches)?),
|
||||
None => Err(anyhow::anyhow!(r#""failed to get matches""#)),
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
#[cfg(not(cli))]
|
||||
whitelist_error(webview, error, "cli");
|
||||
}
|
||||
#[cfg(feature = "cli")]
|
||||
CliMatches { callback, error } => crate::execute_promise(
|
||||
webview,
|
||||
move || match crate::cli::get_matches() {
|
||||
Some(matches) => Ok(serde_json::to_string(matches)?),
|
||||
None => Err(anyhow::anyhow!(r#""failed to get matches""#)),
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
),
|
||||
#[cfg(any(feature = "all-api", feature = "notification"))]
|
||||
Notification {
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
notification(webview, options, callback, error)?;
|
||||
#[cfg(notification)]
|
||||
notification::send(webview, options, callback, error);
|
||||
#[cfg(not(notification))]
|
||||
whitelist_error(webview, error, "notification");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "notification"))]
|
||||
IsNotificationPermissionGranted { callback, error } => {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
let settings = crate::settings::read_settings()?;
|
||||
if let Some(allow_notification) = settings.allow_notification {
|
||||
Ok(allow_notification.to_string())
|
||||
} else {
|
||||
Ok("null".to_string())
|
||||
}
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
#[cfg(notification)]
|
||||
notification::is_permission_granted(webview, callback, error);
|
||||
#[cfg(not(notification))]
|
||||
whitelist_error(webview, error, "notification");
|
||||
}
|
||||
RequestNotificationPermission { callback, error } => {
|
||||
#[cfg(notification)]
|
||||
notification::request_permission(webview, callback, error);
|
||||
#[cfg(not(notification))]
|
||||
whitelist_error(webview, error, "notification");
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "notification"))]
|
||||
RequestNotificationPermission { callback, error } => crate::execute_promise_sync(
|
||||
webview,
|
||||
move || {
|
||||
let mut settings = crate::settings::read_settings()?;
|
||||
let granted = r#""granted""#.to_string();
|
||||
let denied = r#""denied""#.to_string();
|
||||
if let Some(allow_notification) = settings.allow_notification {
|
||||
return Ok(if allow_notification { granted } else { denied });
|
||||
}
|
||||
let answer = tauri_api::dialog::ask(
|
||||
"This app wants to show notifications. Do you allow?",
|
||||
"Permissions",
|
||||
);
|
||||
match answer {
|
||||
tauri_api::dialog::DialogSelection::Yes => {
|
||||
settings.allow_notification = Some(true);
|
||||
crate::settings::write_settings(settings)?;
|
||||
Ok(granted)
|
||||
}
|
||||
tauri_api::dialog::DialogSelection::No => Ok(denied),
|
||||
_ => Ok(r#""default""#.to_string()),
|
||||
}
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init() -> crate::Result<String> {
|
||||
#[cfg(not(any(feature = "all-api", feature = "event")))]
|
||||
return Ok(String::from(""));
|
||||
#[cfg(any(feature = "all-api", feature = "event"))]
|
||||
return Ok(format!(
|
||||
"
|
||||
window['{queue}'] = [];
|
||||
window['{fn}'] = function (payload, salt, ignoreQueue) {{
|
||||
const listeners = (window['{listeners}'] && window['{listeners}'][payload.type]) || []
|
||||
if (!ignoreQueue && listeners.length === 0) {{
|
||||
window['{queue}'].push({{
|
||||
payload: payload,
|
||||
salt: salt
|
||||
}})
|
||||
}}
|
||||
|
||||
if (listeners.length > 0) {{
|
||||
window.tauri.promisified({{
|
||||
cmd: 'validateSalt',
|
||||
salt: salt
|
||||
}}).then(function () {{
|
||||
for (let i = listeners.length - 1; i >= 0; i--) {{
|
||||
const listener = listeners[i]
|
||||
if (listener.once)
|
||||
listeners.splice(i, 1)
|
||||
listener.handler(payload)
|
||||
}}
|
||||
}})
|
||||
}}
|
||||
}}
|
||||
",
|
||||
fn = crate::event::emit_function_name(),
|
||||
queue = crate::event::event_queue_object_name(),
|
||||
listeners = crate::event::event_listeners_object_name()
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "all-api", feature = "open"))]
|
||||
fn open_fn(uri: String) -> crate::Result<()> {
|
||||
crate::spawn(move || {
|
||||
#[cfg(test)]
|
||||
assert!(uri.contains("http://"));
|
||||
|
||||
#[cfg(not(test))]
|
||||
webbrowser::open(&uri).expect("Failed to open webbrowser with uri");
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "all-api", feature = "event"))]
|
||||
fn listen_fn(event: String, handler: String, once: bool) -> crate::Result<String> {
|
||||
Ok(format!(
|
||||
"if (window['{listeners}'] === void 0) {{
|
||||
window['{listeners}'] = {{}}
|
||||
}}
|
||||
if (window['{listeners}']['{evt}'] === void 0) {{
|
||||
window['{listeners}']['{evt}'] = []
|
||||
}}
|
||||
window['{listeners}']['{evt}'].push({{
|
||||
handler: window['{handler}'],
|
||||
once: {once_flag}
|
||||
}});
|
||||
|
||||
for (let i = 0; i < (window['{queue}'] || []).length; i++) {{
|
||||
const e = window['{queue}'][i];
|
||||
window['{emit}'](e.payload, e.salt, true)
|
||||
}}
|
||||
",
|
||||
listeners = crate::event::event_listeners_object_name(),
|
||||
queue = crate::event::event_queue_object_name(),
|
||||
emit = crate::event::emit_function_name(),
|
||||
evt = event,
|
||||
handler = handler,
|
||||
once_flag = if once { "true" } else { "false" }
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "embedded-server", feature = "no-server"))]
|
||||
fn load_asset<T: 'static>(
|
||||
#[allow(dead_code)]
|
||||
fn whitelist_error<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
asset: String,
|
||||
asset_type: String,
|
||||
callback: String,
|
||||
error: String,
|
||||
) -> crate::Result<()> {
|
||||
let handle = webview.handle();
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
let mut path = PathBuf::from(if asset.starts_with('/') {
|
||||
asset.replacen("/", "", 1)
|
||||
} else {
|
||||
asset.clone()
|
||||
});
|
||||
let mut read_asset;
|
||||
loop {
|
||||
read_asset = crate::assets::ASSETS.get(&format!(
|
||||
"{}/{}",
|
||||
option_env!("TAURI_DIST_DIR")
|
||||
.expect("tauri apps should be built with the TAURI_DIST_DIR environment variable"),
|
||||
path.to_string_lossy()
|
||||
));
|
||||
if read_asset.is_err() {
|
||||
match path.iter().next() {
|
||||
Some(component) => {
|
||||
let first_component = component.to_str().expect("failed to read path component");
|
||||
path = PathBuf::from(path.to_string_lossy().replacen(
|
||||
format!("{}/", first_component).as_str(),
|
||||
"",
|
||||
1,
|
||||
));
|
||||
}
|
||||
None => {
|
||||
return Err(anyhow::anyhow!("Asset '{}' not found", asset));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if asset_type == "image" {
|
||||
let ext = if asset.ends_with("gif") {
|
||||
"gif"
|
||||
} else if asset.ends_with("png") {
|
||||
"png"
|
||||
} else {
|
||||
"jpeg"
|
||||
};
|
||||
Ok(format!(
|
||||
r#""data:image/{};base64,{}""#,
|
||||
ext,
|
||||
base64::encode(&read_asset.expect("Failed to read asset type").into_owned())
|
||||
))
|
||||
} else {
|
||||
handle
|
||||
.dispatch(move |_webview| {
|
||||
let asset_bytes = &read_asset.expect("Failed to read asset type").into_owned();
|
||||
let asset_str =
|
||||
&std::str::from_utf8(asset_bytes).expect("failed to convert asset bytes to u8 slice");
|
||||
if asset_type == "stylesheet" {
|
||||
_webview.inject_css(asset_str)
|
||||
} else {
|
||||
_webview.eval(asset_str)
|
||||
}
|
||||
})
|
||||
.map_err(|err| err.into())
|
||||
.map(|_| r#""Asset loaded successfully""#.to_string())
|
||||
}
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
error_fn: String,
|
||||
whitelist_key: &str,
|
||||
) {
|
||||
let reject_code = tauri_api::rpc::format_callback(
|
||||
error_fn,
|
||||
format!(r#""'{}' not whitelisted""#, whitelist_key),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
webview
|
||||
.eval(&reject_code)
|
||||
.expect("failed to eval whitelist error")
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "all-api", feature = "notification"))]
|
||||
fn notification<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
options: cmd::NotificationOptions,
|
||||
callback: String,
|
||||
error: String,
|
||||
) -> crate::Result<()> {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
let mut notification = tauri_api::notification::Notification::new();
|
||||
notification.body(options.body);
|
||||
if let Some(title) = options.title {
|
||||
notification.title(title);
|
||||
}
|
||||
if let Some(icon) = options.icon {
|
||||
notification.icon(icon);
|
||||
}
|
||||
notification
|
||||
.show()
|
||||
.map_err(|e| anyhow::anyhow!(r#""{}""#, e.to_string()))?;
|
||||
Ok("".to_string())
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
Ok(())
|
||||
#[allow(dead_code)]
|
||||
fn throw_whitelist_error<T: 'static>(webview: &mut WebView<'_, T>, whitelist_key: &str) {
|
||||
let reject_code = format!(r#"throw new Error("'{}' not whitelisted")"#, whitelist_key);
|
||||
webview
|
||||
.eval(&reject_code)
|
||||
.expect("failed to eval whitelist error")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -449,16 +308,16 @@ mod test {
|
||||
#[test]
|
||||
// test to see if check init produces a string or not.
|
||||
fn check_init() {
|
||||
if cfg!(not(any(feature = "all-api", feature = "event"))) {
|
||||
if cfg!(not(event)) {
|
||||
let res = super::init();
|
||||
match res {
|
||||
Ok(s) => assert_eq!(s, ""),
|
||||
Err(_) => assert!(false),
|
||||
}
|
||||
} else if cfg!(any(feature = "all-api", feature = "event")) {
|
||||
} else if cfg!(event) {
|
||||
let res = super::init();
|
||||
match res {
|
||||
Ok(s) => assert!(s.contains("window.tauri.promisified")),
|
||||
Ok(s) => assert!(s.contains("window.__TAURI__.promisified")),
|
||||
Err(_) => assert!(false),
|
||||
}
|
||||
}
|
||||
@ -466,10 +325,10 @@ mod test {
|
||||
|
||||
// check the listen_fn for various usecases.
|
||||
proptest! {
|
||||
#[cfg(any(feature = "all-api", feature = "event"))]
|
||||
#[cfg(event)]
|
||||
#[test]
|
||||
fn check_listen_fn(event in "", handler in "", once in proptest::bool::ANY) {
|
||||
let res = super::listen_fn(event, handler, once);
|
||||
let res = super::event::listen_fn(event, handler, once);
|
||||
match res {
|
||||
Ok(_) => assert!(true),
|
||||
Err(_) => assert!(false)
|
||||
@ -479,14 +338,10 @@ mod test {
|
||||
|
||||
// Test the open func to see if proper uris can be opened by the browser.
|
||||
proptest! {
|
||||
#[cfg(any(feature = "all-api", feature = "open"))]
|
||||
#[cfg(open)]
|
||||
#[test]
|
||||
fn check_open(uri in r"(http://)([\\w\\d\\.]+([\\w]{2,6})?)") {
|
||||
let res = super::open_fn(uri);
|
||||
match res {
|
||||
Ok(_) => assert!(true),
|
||||
Err(_) => assert!(false),
|
||||
}
|
||||
super::browser::open(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
79
tauri/src/endpoints/asset.rs
Normal file
79
tauri/src/endpoints/asset.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use std::path::PathBuf;
|
||||
use web_view::WebView;
|
||||
|
||||
pub fn load<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
asset: String,
|
||||
asset_type: String,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
let handle = webview.handle();
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
let mut path = PathBuf::from(if asset.starts_with('/') {
|
||||
asset.replacen("/", "", 1)
|
||||
} else {
|
||||
asset.clone()
|
||||
});
|
||||
let mut read_asset;
|
||||
loop {
|
||||
read_asset = crate::assets::ASSETS.get(&format!(
|
||||
"{}/{}",
|
||||
option_env!("TAURI_DIST_DIR")
|
||||
.expect("tauri apps should be built with the TAURI_DIST_DIR environment variable"),
|
||||
path.to_string_lossy()
|
||||
));
|
||||
if read_asset.is_err() {
|
||||
match path.iter().next() {
|
||||
Some(component) => {
|
||||
let first_component = component.to_str().expect("failed to read path component");
|
||||
path = PathBuf::from(path.to_string_lossy().replacen(
|
||||
format!("{}/", first_component).as_str(),
|
||||
"",
|
||||
1,
|
||||
));
|
||||
}
|
||||
None => {
|
||||
return Err(anyhow::anyhow!("Asset '{}' not found", asset));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if asset_type == "image" {
|
||||
let ext = if asset.ends_with("gif") {
|
||||
"gif"
|
||||
} else if asset.ends_with("png") {
|
||||
"png"
|
||||
} else {
|
||||
"jpeg"
|
||||
};
|
||||
Ok(format!(
|
||||
r#""data:image/{};base64,{}""#,
|
||||
ext,
|
||||
base64::encode(&read_asset.expect("Failed to read asset type").into_owned())
|
||||
))
|
||||
} else {
|
||||
handle
|
||||
.dispatch(move |_webview| {
|
||||
let asset_bytes = &read_asset.expect("Failed to read asset type").into_owned();
|
||||
let asset_str =
|
||||
&std::str::from_utf8(asset_bytes).expect("failed to convert asset bytes to u8 slice");
|
||||
if asset_type == "stylesheet" {
|
||||
_webview.inject_css(asset_str)
|
||||
} else {
|
||||
_webview.eval(asset_str)
|
||||
}
|
||||
})
|
||||
.map_err(|err| err.into())
|
||||
.map(|_| r#""Asset loaded successfully""#.to_string())
|
||||
}
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
10
tauri/src/endpoints/browser.rs
Normal file
10
tauri/src/endpoints/browser.rs
Normal file
@ -0,0 +1,10 @@
|
||||
#[cfg(open)]
|
||||
pub fn open(uri: String) {
|
||||
crate::spawn(move || {
|
||||
#[cfg(test)]
|
||||
assert!(uri.contains("http://"));
|
||||
|
||||
#[cfg(not(test))]
|
||||
webbrowser::open(&uri).expect("Failed to open webbrowser with uri");
|
||||
});
|
||||
}
|
||||
@ -43,21 +43,18 @@ pub struct NotificationOptions {
|
||||
#[serde(tag = "cmd", rename_all = "camelCase")]
|
||||
pub enum Cmd {
|
||||
Init {},
|
||||
#[cfg(any(feature = "all-api", feature = "read-text-file"))]
|
||||
ReadTextFile {
|
||||
path: String,
|
||||
options: Option<FileOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "read-binary-file"))]
|
||||
ReadBinaryFile {
|
||||
path: String,
|
||||
options: Option<FileOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "write-file"))]
|
||||
WriteFile {
|
||||
file: String,
|
||||
contents: String,
|
||||
@ -65,7 +62,6 @@ pub enum Cmd {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "write-binary-file"))]
|
||||
WriteBinaryFile {
|
||||
file: String,
|
||||
contents: String,
|
||||
@ -73,14 +69,12 @@ pub enum Cmd {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "read-dir"))]
|
||||
ReadDir {
|
||||
path: String,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "copy-file"))]
|
||||
CopyFile {
|
||||
source: String,
|
||||
destination: String,
|
||||
@ -88,21 +82,18 @@ pub enum Cmd {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "create-dir"))]
|
||||
CreateDir {
|
||||
path: String,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "remove-dir"))]
|
||||
RemoveDir {
|
||||
path: String,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "remove-file"))]
|
||||
RemoveFile {
|
||||
path: String,
|
||||
options: Option<FileOperationOptions>,
|
||||
@ -110,7 +101,6 @@ pub enum Cmd {
|
||||
error: String,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg(any(feature = "all-api", feature = "rename-file"))]
|
||||
RenameFile {
|
||||
old_path: String,
|
||||
new_path: String,
|
||||
@ -118,18 +108,15 @@ pub enum Cmd {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "set-title"))]
|
||||
SetTitle {
|
||||
title: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "execute"))]
|
||||
Execute {
|
||||
command: String,
|
||||
args: Vec<String>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "open"))]
|
||||
Open {
|
||||
uri: String,
|
||||
},
|
||||
@ -138,30 +125,25 @@ pub enum Cmd {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "event"))]
|
||||
Listen {
|
||||
event: String,
|
||||
handler: String,
|
||||
once: bool,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "event"))]
|
||||
Emit {
|
||||
event: String,
|
||||
payload: Option<String>,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "open-dialog"))]
|
||||
OpenDialog {
|
||||
options: OpenDialogOptions,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "save-dialog"))]
|
||||
SaveDialog {
|
||||
options: SaveDialogOptions,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "http-request"))]
|
||||
HttpRequest {
|
||||
options: Box<HttpRequestOptions>,
|
||||
callback: String,
|
||||
@ -175,23 +157,19 @@ pub enum Cmd {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(feature = "cli")]
|
||||
CliMatches {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "notification"))]
|
||||
Notification {
|
||||
options: NotificationOptions,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "notification"))]
|
||||
RequestNotificationPermission {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "notification"))]
|
||||
IsNotificationPermissionGranted {
|
||||
callback: String,
|
||||
error: String,
|
||||
|
||||
@ -10,6 +10,7 @@ fn map_response(response: Response) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(open_dialog)]
|
||||
pub fn open<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
options: OpenDialogOptions,
|
||||
@ -33,6 +34,7 @@ pub fn open<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(save_dialog)]
|
||||
pub fn save<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
options: SaveDialogOptions,
|
||||
|
||||
27
tauri/src/endpoints/event.rs
Normal file
27
tauri/src/endpoints/event.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#[cfg(event)]
|
||||
pub fn listen_fn(event: String, handler: String, once: bool) -> crate::Result<String> {
|
||||
Ok(format!(
|
||||
"if (window['{listeners}'] === void 0) {{
|
||||
window['{listeners}'] = {{}}
|
||||
}}
|
||||
if (window['{listeners}']['{evt}'] === void 0) {{
|
||||
window['{listeners}']['{evt}'] = []
|
||||
}}
|
||||
window['{listeners}']['{evt}'].push({{
|
||||
handler: window['{handler}'],
|
||||
once: {once_flag}
|
||||
}});
|
||||
|
||||
for (let i = 0; i < (window['{queue}'] || []).length; i++) {{
|
||||
const e = window['{queue}'][i];
|
||||
window['{emit}'](e.payload, e.salt, true)
|
||||
}}
|
||||
",
|
||||
listeners = crate::event::event_listeners_object_name(),
|
||||
queue = crate::event::event_queue_object_name(),
|
||||
emit = crate::event::emit_function_name(),
|
||||
evt = event,
|
||||
handler = handler,
|
||||
once_flag = if once { "true" } else { "false" }
|
||||
))
|
||||
}
|
||||
@ -10,6 +10,7 @@ use std::io::Write;
|
||||
|
||||
use super::cmd::{DirOperationOptions, FileOperationOptions};
|
||||
|
||||
#[cfg(read_dir)]
|
||||
pub fn read_dir<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
@ -38,6 +39,7 @@ pub fn read_dir<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(copy_file)]
|
||||
pub fn copy_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
source: String,
|
||||
@ -65,6 +67,7 @@ pub fn copy_file<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(create_dir)]
|
||||
pub fn create_dir<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
@ -94,6 +97,7 @@ pub fn create_dir<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(remove_dir)]
|
||||
pub fn remove_dir<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
@ -123,6 +127,7 @@ pub fn remove_dir<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(remove_file)]
|
||||
pub fn remove_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
@ -143,6 +148,7 @@ pub fn remove_file<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(rename_file)]
|
||||
pub fn rename_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
old_path: String,
|
||||
@ -170,6 +176,7 @@ pub fn rename_file<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(write_file)]
|
||||
pub fn write_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
file: String,
|
||||
@ -194,6 +201,7 @@ pub fn write_file<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(write_binary_file)]
|
||||
pub fn write_binary_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
file: String,
|
||||
@ -222,6 +230,7 @@ pub fn write_binary_file<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(read_text_file)]
|
||||
pub fn read_text_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
@ -240,6 +249,7 @@ pub fn read_text_file<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(read_binary_file)]
|
||||
pub fn read_binary_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
|
||||
36
tauri/src/endpoints/init.rs
Normal file
36
tauri/src/endpoints/init.rs
Normal file
@ -0,0 +1,36 @@
|
||||
pub fn init() -> crate::Result<String> {
|
||||
#[cfg(not(event))]
|
||||
return Ok(String::from(""));
|
||||
#[cfg(event)]
|
||||
return Ok(format!(
|
||||
"
|
||||
window['{queue}'] = [];
|
||||
window['{fn}'] = function (payload, salt, ignoreQueue) {{
|
||||
const listeners = (window['{listeners}'] && window['{listeners}'][payload.type]) || []
|
||||
if (!ignoreQueue && listeners.length === 0) {{
|
||||
window['{queue}'].push({{
|
||||
payload: payload,
|
||||
salt: salt
|
||||
}})
|
||||
}}
|
||||
|
||||
if (listeners.length > 0) {{
|
||||
window.__TAURI__.promisified({{
|
||||
cmd: 'validateSalt',
|
||||
salt: salt
|
||||
}}).then(function () {{
|
||||
for (let i = listeners.length - 1; i >= 0; i--) {{
|
||||
const listener = listeners[i]
|
||||
if (listener.once)
|
||||
listeners.splice(i, 1)
|
||||
listener.handler(payload)
|
||||
}}
|
||||
}})
|
||||
}}
|
||||
}}
|
||||
",
|
||||
fn = crate::event::emit_function_name(),
|
||||
queue = crate::event::event_queue_object_name(),
|
||||
listeners = crate::event::event_listeners_object_name()
|
||||
));
|
||||
}
|
||||
86
tauri/src/endpoints/notification.rs
Normal file
86
tauri/src/endpoints/notification.rs
Normal file
@ -0,0 +1,86 @@
|
||||
use super::cmd::NotificationOptions;
|
||||
use web_view::WebView;
|
||||
|
||||
pub fn send<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
options: NotificationOptions,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
let mut notification = tauri_api::notification::Notification::new();
|
||||
notification.body(options.body);
|
||||
if let Some(title) = options.title {
|
||||
notification.title(title);
|
||||
}
|
||||
if let Some(icon) = options.icon {
|
||||
notification.icon(icon);
|
||||
}
|
||||
notification
|
||||
.show()
|
||||
.map_err(|e| anyhow::anyhow!(r#""{}""#, e.to_string()))?;
|
||||
Ok("".to_string())
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn is_permission_granted<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
let settings = crate::settings::read_settings()?;
|
||||
if let Some(allow_notification) = settings.allow_notification {
|
||||
Ok(allow_notification.to_string())
|
||||
} else {
|
||||
Ok("null".to_string())
|
||||
}
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn request_permission<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise_sync(
|
||||
webview,
|
||||
move || {
|
||||
let mut settings = crate::settings::read_settings()?;
|
||||
let granted = r#""granted""#.to_string();
|
||||
let denied = r#""denied""#.to_string();
|
||||
if let Some(allow_notification) = settings.allow_notification {
|
||||
return Ok(if allow_notification { granted } else { denied });
|
||||
}
|
||||
let answer = tauri_api::dialog::ask(
|
||||
"This app wants to show notifications. Do you allow?",
|
||||
"Permissions",
|
||||
);
|
||||
match answer {
|
||||
tauri_api::dialog::DialogSelection::Yes => {
|
||||
settings.allow_notification = Some(true);
|
||||
crate::settings::write_settings(settings)?;
|
||||
Ok(granted)
|
||||
}
|
||||
tauri_api::dialog::DialogSelection::No => {
|
||||
settings.allow_notification = Some(false);
|
||||
crate::settings::write_settings(settings)?;
|
||||
Ok(denied)
|
||||
}
|
||||
_ => Ok(r#""default""#.to_string()),
|
||||
}
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
@ -3,14 +3,14 @@
|
||||
windows_subsystem = "windows"
|
||||
)]
|
||||
|
||||
#[cfg(any(feature = "embedded-server", feature = "no-server"))]
|
||||
#[cfg(assets)]
|
||||
pub mod assets;
|
||||
pub mod event;
|
||||
#[cfg(feature = "embedded-server")]
|
||||
#[cfg(embedded_server)]
|
||||
pub mod server;
|
||||
pub mod settings;
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
#[cfg(cli)]
|
||||
pub mod cli;
|
||||
|
||||
mod app;
|
||||
|
||||
@ -8,7 +8,7 @@ use tauri_api::path::{resolve_path, BaseDirectory};
|
||||
|
||||
#[derive(Default, Deserialize, Serialize)]
|
||||
pub struct Settings {
|
||||
#[cfg(any(feature = "all-api", feature = "notification"))]
|
||||
#[cfg(notification)]
|
||||
pub allow_notification: Option<bool>,
|
||||
}
|
||||
|
||||
@ -18,7 +18,10 @@ fn get_settings_path() -> tauri_api::Result<String> {
|
||||
|
||||
pub(crate) fn write_settings(settings: Settings) -> crate::Result<()> {
|
||||
let settings_path = get_settings_path()?;
|
||||
std::fs::create_dir(Path::new(&settings_path).parent().unwrap())?;
|
||||
let settings_folder = Path::new(&settings_path).parent().unwrap();
|
||||
if !settings_folder.exists() {
|
||||
std::fs::create_dir(settings_folder)?;
|
||||
}
|
||||
File::create(settings_path)
|
||||
.map_err(|e| anyhow!(e))
|
||||
.and_then(|mut f| {
|
||||
|
||||
@ -1,219 +0,0 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* * THIS FILE IS GENERATED AUTOMATICALLY.
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Please whitelist these API functions in tauri.conf.json
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
* @module tauri
|
||||
* @description This API interface makes powerful interactions available
|
||||
* to be run on client side applications. They are opt-in features, and
|
||||
* must be enabled in tauri.conf.json
|
||||
*
|
||||
* Each binding MUST provide these interfaces in order to be compliant,
|
||||
* and also whitelist them based upon the developer's settings.
|
||||
*/
|
||||
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1)
|
||||
}
|
||||
|
||||
var uid = function () {
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4()
|
||||
}
|
||||
|
||||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
|
||||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
|
||||
|
||||
|
||||
var __reject = function () {
|
||||
return new Promise(function (_, reject) {
|
||||
reject();
|
||||
});
|
||||
}
|
||||
|
||||
window.tauri = {
|
||||
|
||||
invoke: function invoke(args) {
|
||||
window.external.invoke(JSON.stringify(args));
|
||||
},
|
||||
|
||||
|
||||
listen: function listen(event, handler) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
emit: function emit(evt, payload) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
transformCallback: function transformCallback(callback) {
|
||||
var once = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||
var identifier = Object.freeze(uid());
|
||||
|
||||
window[identifier] = function (result) {
|
||||
if (once) {
|
||||
delete window[identifier];
|
||||
}
|
||||
|
||||
return callback && callback(result);
|
||||
};
|
||||
|
||||
return identifier;
|
||||
},
|
||||
|
||||
|
||||
promisified: function promisified(args) {
|
||||
var _this = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
_this.invoke(_objectSpread({
|
||||
callback: _this.transformCallback(resolve),
|
||||
error: _this.transformCallback(reject)
|
||||
}, args));
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
readTextFile: function readTextFile(path) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
readBinaryFile: function readBinaryFile(path) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
writeFile: function writeFile(cfg) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
listFiles: function listFiles(path) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
listDirs: function listDirs(path) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
setTitle: function setTitle(title) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
open: function open(uri) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
|
||||
execute: function execute(command, args) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
bridge: function bridge(command, payload) {
|
||||
|
||||
|
||||
return __reject()
|
||||
|
||||
},
|
||||
|
||||
loadAsset: function loadAsset(assetName, assetType) {
|
||||
return this.promisified({
|
||||
cmd: 'loadAsset',
|
||||
asset: assetName,
|
||||
asset_type: assetType || 'unknown'
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
// init tauri API
|
||||
try {
|
||||
window.tauri.invoke({
|
||||
cmd: 'init'
|
||||
})
|
||||
} catch (e) {
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
window.tauri.invoke({
|
||||
cmd: 'init'
|
||||
})
|
||||
}, true)
|
||||
}
|
||||
|
||||
document.addEventListener('error', function (e) {
|
||||
var target = e.target
|
||||
while (target != null) {
|
||||
if (target.matches ? target.matches('img') : target.msMatchesSelector('img')) {
|
||||
window.tauri.loadAsset(target.src, 'image')
|
||||
.then(img => {
|
||||
target.src = img
|
||||
})
|
||||
break
|
||||
}
|
||||
target = target.parentElement
|
||||
}
|
||||
}, true)
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
// open <a href="..."> links with the Tauri API
|
||||
document.querySelector('body').addEventListener('click', function (e) {
|
||||
var target = e.target
|
||||
while (target != null) {
|
||||
if (target.matches ? target.matches('a') : target.msMatchesSelector('a')) {
|
||||
window.tauri.open(target.href)
|
||||
break
|
||||
}
|
||||
target = target.parentElement
|
||||
}
|
||||
}, true)
|
||||
}, true)
|
||||
Loading…
Reference in New Issue
Block a user