mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-10-26 09:58:16 +03:00
chore: add prettier for js formatting (#937)
* chore: add prettier for js/ts formatting * fix lint-staged to object * test commit * format all * lock file bump * eslint extends prettier This will let us skip rules in eslint that prettier can control. Prettier for styles, eslint for code errors. * add prettier config * roll back to what we had with eslint settings * skip mutation observer * add prettier typescript eslint * run prettier in lint workflow * format:check script * turn off space before function in eslint it is fighting with prettier * fix dir in workflow * remove semis * add api to eslint * shift eslint ignore comment after prettier format * ignore errors that currently exist * build:typevalidators * replace was broken on typevalidator build * try pushing up error * format * try removing working dir from eslint workflow * try node 12 * fix indent in action * bump eslint * fix supposeded error and try another * try breaking eslint * try building in action * adjust action paths again * need dot * remove build * fix(tauri.js/eslint): escape glob * * fix(tauri.js): ignore lint error * Create prettier-taurijs.md Co-authored-by: Noah Klayman <noahklayman@gmail.com>
This commit is contained in:
parent
a949e711e4
commit
6a21965ff3
5
.changes/prettier-taurijs.md
Normal file
5
.changes/prettier-taurijs.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri.js": patch
|
||||
---
|
||||
|
||||
Format all code with prettier. This technically should only affect code styles, but noting for posterity.
|
9
.github/workflows/js-lint.yml
vendored
9
.github/workflows/js-lint.yml
vendored
@ -12,9 +12,14 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '12'
|
||||
- name: install deps via yarn
|
||||
working-directory: ./cli/tauri.js
|
||||
working-directory: ./cli/tauri.js/
|
||||
run: yarn
|
||||
- name: run eslint
|
||||
working-directory: ./cli/tauri.js
|
||||
working-directory: ./cli/tauri.js/
|
||||
run: yarn lint
|
||||
- name: run prettier
|
||||
working-directory: ./cli/tauri.js/
|
||||
run: yarn format:check
|
||||
|
1
cli/deno
Submodule
1
cli/deno
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 55fd9104fa4da3b7afb96a16bb1ed8378b028a5a
|
@ -11,9 +11,11 @@ module.exports = {
|
||||
extends: [
|
||||
'standard-with-typescript',
|
||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||
'plugin:lodash-template/recommended'
|
||||
'plugin:lodash-template/recommended',
|
||||
// TODO: make this work with typescript
|
||||
// 'plugin:node/recommended'
|
||||
'prettier',
|
||||
'prettier/@typescript-eslint'
|
||||
],
|
||||
|
||||
plugins: ['@typescript-eslint', 'node', 'security'],
|
||||
@ -49,14 +51,6 @@ module.exports = {
|
||||
'security/detect-pseudoRandomBytes': 'error',
|
||||
'space-before-function-paren': 'off',
|
||||
'@typescript-eslint/default-param-last': 'off',
|
||||
'@typescript-eslint/strict-boolean-expressions': 0,
|
||||
'@typescript-eslint/space-before-function-paren': [
|
||||
'error',
|
||||
{
|
||||
asyncArrow: 'always',
|
||||
anonymous: 'never',
|
||||
named: 'never'
|
||||
}
|
||||
]
|
||||
'@typescript-eslint/strict-boolean-expressions': 0
|
||||
}
|
||||
}
|
||||
|
5
cli/tauri.js/.prettierrc.js
Normal file
5
cli/tauri.js/.prettierrc.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
singleQuote: true,
|
||||
semi: false,
|
||||
trailingComma: 'none'
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
|
||||
import 'regenerator-runtime/runtime'
|
||||
import * as cli from './cli'
|
||||
import * as dialog from './dialog'
|
||||
@ -10,14 +9,4 @@ 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
|
||||
}
|
||||
export { cli, dialog, event, fs, http, process, tauri, window, notification }
|
||||
|
@ -32,6 +32,4 @@ async function getMatches(): Promise<CliMatches> {
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
getMatches
|
||||
}
|
||||
export { getMatches }
|
||||
|
@ -7,7 +7,10 @@ export interface OpenDialogOptions {
|
||||
directory?: boolean
|
||||
}
|
||||
|
||||
export type SaveDialogOptions = Pick<OpenDialogOptions, 'filter' | 'defaultPath'>
|
||||
export type SaveDialogOptions = Pick<
|
||||
OpenDialogOptions,
|
||||
'filter' | 'defaultPath'
|
||||
>
|
||||
|
||||
/**
|
||||
* @name openDialog
|
||||
@ -51,7 +54,4 @@ async function save(options: SaveDialogOptions = {}): Promise<string> {
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
open,
|
||||
save
|
||||
}
|
||||
export { open, save }
|
||||
|
@ -13,7 +13,11 @@ export type EventCallback<T> = (event: Event<T>) => void
|
||||
* @param event the event name
|
||||
* @param handler the event handler callback
|
||||
*/
|
||||
function listen<T>(event: string, handler: EventCallback<T>, once = false): void {
|
||||
function listen<T>(
|
||||
event: string,
|
||||
handler: EventCallback<T>,
|
||||
once = false
|
||||
): void {
|
||||
invoke({
|
||||
cmd: 'listen',
|
||||
event,
|
||||
@ -36,7 +40,4 @@ function emit(event: string, payload?: string): void {
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
listen,
|
||||
emit
|
||||
}
|
||||
export { listen, emit }
|
||||
|
@ -18,7 +18,7 @@ export enum BaseDirectory {
|
||||
Template,
|
||||
Video,
|
||||
Resource,
|
||||
App,
|
||||
App
|
||||
}
|
||||
|
||||
export interface FsOptions {
|
||||
@ -92,7 +92,10 @@ async function readBinaryFile(
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function writeFile(file: FsTextFileOption, options: FsOptions = {}): Promise<void> {
|
||||
async function writeFile(
|
||||
file: FsTextFileOption,
|
||||
options: FsOptions = {}
|
||||
): Promise<void> {
|
||||
if (typeof options === 'object') {
|
||||
Object.freeze(options)
|
||||
}
|
||||
@ -151,7 +154,10 @@ function arrayBufferToBase64(buffer: ArrayBuffer): string {
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function writeBinaryFile(file: FsBinaryFileOption, options: FsOptions = {}): Promise<void> {
|
||||
async function writeBinaryFile(
|
||||
file: FsBinaryFileOption,
|
||||
options: FsOptions = {}
|
||||
): Promise<void> {
|
||||
if (typeof options === 'object') {
|
||||
Object.freeze(options)
|
||||
}
|
||||
@ -176,7 +182,10 @@ async function writeBinaryFile(file: FsBinaryFileOption, options: FsOptions = {}
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function readDir(dir: string, options: FsOptions = {}): Promise<FileEntry[]> {
|
||||
async function readDir(
|
||||
dir: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<FileEntry[]> {
|
||||
return await promisified({
|
||||
cmd: 'readDir',
|
||||
path: dir,
|
||||
@ -230,7 +239,11 @@ async function removeDir(dir: string, options: FsOptions = {}): Promise<void> {
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function copyFile(source: string, destination: string, options: FsOptions = {}): Promise<void> {
|
||||
async function copyFile(
|
||||
source: string,
|
||||
destination: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<void> {
|
||||
return await promisified({
|
||||
cmd: 'copyFile',
|
||||
source,
|
||||
@ -247,7 +260,10 @@ async function copyFile(source: string, destination: string, options: FsOptions
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function removeFile(file: string, options: FsOptions = {}): Promise<void> {
|
||||
async function removeFile(
|
||||
file: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<void> {
|
||||
return await promisified({
|
||||
cmd: 'removeFile',
|
||||
path: file,
|
||||
@ -264,7 +280,11 @@ async function removeFile(file: string, options: FsOptions = {}): Promise<void>
|
||||
* @param [options.dir] base directory
|
||||
* @return
|
||||
*/
|
||||
async function renameFile(oldPath: string, newPath: string, options: FsOptions = {}): Promise<void> {
|
||||
async function renameFile(
|
||||
oldPath: string,
|
||||
newPath: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<void> {
|
||||
return await promisified({
|
||||
cmd: 'renameFile',
|
||||
oldPath,
|
||||
|
@ -14,7 +14,16 @@ export enum BodyType {
|
||||
|
||||
export type Body = object | string | BinaryType
|
||||
|
||||
export type HttpVerb = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE'
|
||||
export type HttpVerb =
|
||||
| 'GET'
|
||||
| 'POST'
|
||||
| 'PUT'
|
||||
| 'DELETE'
|
||||
| 'PATCH'
|
||||
| 'HEAD'
|
||||
| 'OPTIONS'
|
||||
| 'CONNECT'
|
||||
| 'TRACE'
|
||||
|
||||
export interface HttpOptions {
|
||||
method: HttpVerb
|
||||
@ -73,7 +82,11 @@ async function get<T>(url: string, options: PartialOptions): Promise<T> {
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function post<T>(url: string, body: Body, options: PartialOptions): Promise<T> {
|
||||
async function post<T>(
|
||||
url: string,
|
||||
body: Body,
|
||||
options: PartialOptions
|
||||
): Promise<T> {
|
||||
return await request({
|
||||
method: 'POST',
|
||||
url,
|
||||
@ -91,7 +104,11 @@ async function post<T>(url: string, body: Body, options: PartialOptions): Promis
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function put<T>(url: string, body: Body, options: PartialOptions): Promise<T> {
|
||||
async function put<T>(
|
||||
url: string,
|
||||
body: Body,
|
||||
options: PartialOptions
|
||||
): Promise<T> {
|
||||
return await request({
|
||||
method: 'PUT',
|
||||
url,
|
||||
@ -124,7 +141,10 @@ async function patch<T>(url: string, options: PartialOptions): Promise<T> {
|
||||
*
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async function deleteRequest<T>(url: string, options: PartialOptions): Promise<T> {
|
||||
async function deleteRequest<T>(
|
||||
url: string,
|
||||
options: PartialOptions
|
||||
): Promise<T> {
|
||||
return await request({
|
||||
method: 'DELETE',
|
||||
url,
|
||||
|
@ -32,8 +32,4 @@ function sendNotification(options: Options | string): void {
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
sendNotification,
|
||||
requestPermission,
|
||||
isPermissionGranted
|
||||
}
|
||||
export { sendNotification, requestPermission, isPermissionGranted }
|
||||
|
@ -7,7 +7,10 @@ import { promisified } from './tauri'
|
||||
* @param [args] command args
|
||||
* @return promise resolving to the stdout text
|
||||
*/
|
||||
async function execute(command: string, args?: string | string[]): Promise<string> {
|
||||
async function execute(
|
||||
command: string,
|
||||
args?: string | string[]
|
||||
): Promise<string> {
|
||||
if (typeof args === 'object') {
|
||||
Object.freeze(args)
|
||||
}
|
||||
@ -19,6 +22,4 @@ async function execute(command: string, args?: string | string[]): Promise<strin
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
execute
|
||||
}
|
||||
export { execute }
|
||||
|
@ -11,8 +11,20 @@ function s4(): string {
|
||||
}
|
||||
|
||||
function uid(): string {
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4()
|
||||
return (
|
||||
s4() +
|
||||
s4() +
|
||||
'-' +
|
||||
s4() +
|
||||
'-' +
|
||||
s4() +
|
||||
'-' +
|
||||
s4() +
|
||||
'-' +
|
||||
s4() +
|
||||
s4() +
|
||||
s4()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -24,7 +36,10 @@ function invoke(args: any): void {
|
||||
window.__TAURI_INVOKE_HANDLER__(args)
|
||||
}
|
||||
|
||||
function transformCallback(callback?: (response: any) => void, once = false): string {
|
||||
function transformCallback(
|
||||
callback?: (response: any) => void,
|
||||
once = false
|
||||
): string {
|
||||
const identifier = uid()
|
||||
|
||||
Object.defineProperty(window, identifier, {
|
||||
@ -50,11 +65,11 @@ function transformCallback(callback?: (response: any) => void, once = false): st
|
||||
*/
|
||||
async function promisified<T>(args: any): Promise<T> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
const callback = transformCallback(e => {
|
||||
const callback = transformCallback((e) => {
|
||||
resolve(e)
|
||||
Reflect.deleteProperty(window, error)
|
||||
}, true)
|
||||
const error = transformCallback(e => {
|
||||
const error = transformCallback((e) => {
|
||||
reject(e)
|
||||
Reflect.deleteProperty(window, callback)
|
||||
}, true)
|
||||
@ -67,8 +82,4 @@ async function promisified<T>(args: any): Promise<T> {
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
invoke,
|
||||
transformCallback,
|
||||
promisified
|
||||
}
|
||||
export { invoke, transformCallback, promisified }
|
||||
|
@ -24,7 +24,4 @@ function open(url: string): void {
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
setTitle,
|
||||
open
|
||||
}
|
||||
export { setTitle, open }
|
||||
|
@ -1,11 +1,14 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
['@babel/preset-env', {
|
||||
targets: {
|
||||
node: 'current'
|
||||
},
|
||||
modules: 'commonjs'
|
||||
}],
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: 'current'
|
||||
},
|
||||
modules: 'commonjs'
|
||||
}
|
||||
],
|
||||
'@babel/preset-typescript'
|
||||
]
|
||||
};
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ if (argv.help) {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
async function run () {
|
||||
async function run() {
|
||||
const build = require('../dist/api/build')
|
||||
|
||||
await build({
|
||||
|
@ -47,7 +47,7 @@ function main(cliArgs) {
|
||||
if (argv.ci) {
|
||||
runInit(argv)
|
||||
} else {
|
||||
getOptionsInteractive(argv).then(responses => runInit(argv, responses))
|
||||
getOptionsInteractive(argv).then((responses) => runInit(argv, responses))
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,18 +78,22 @@ const getOptionsInteractive = (argv) => {
|
||||
let defaultAppName = argv.A
|
||||
if (!defaultAppName) {
|
||||
try {
|
||||
const packageJson = JSON.parse(readFileSync(resolve(process.cwd(), 'package.json')).toString())
|
||||
const packageJson = JSON.parse(
|
||||
readFileSync(resolve(process.cwd(), 'package.json')).toString()
|
||||
)
|
||||
defaultAppName = packageJson.displayName || packageJson.name
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return inquirer
|
||||
.prompt([{
|
||||
.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'appName',
|
||||
message: 'What is your app name?',
|
||||
default: defaultAppName
|
||||
}, {
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'tauri.window.title',
|
||||
message: 'What should the window title be?',
|
||||
@ -105,7 +109,7 @@ const getOptionsInteractive = (argv) => {
|
||||
when: () => !argv.r
|
||||
}
|
||||
])
|
||||
.then(answers =>
|
||||
.then((answers) =>
|
||||
inquirer
|
||||
.prompt([
|
||||
{
|
||||
@ -113,19 +117,24 @@ const getOptionsInteractive = (argv) => {
|
||||
name: 'build.devPath',
|
||||
message: 'What is the url of your dev server?',
|
||||
default: 'http://localhost:4000',
|
||||
when: () => !argv.P && !argv.p && answers.recipeName === 'No recipe' || argv.r === 'none'
|
||||
when: () =>
|
||||
(!argv.P && !argv.p && answers.recipeName === 'No recipe') ||
|
||||
argv.r === 'none'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'build.distDir',
|
||||
message: 'Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri" folder that will be created?',
|
||||
message:
|
||||
'Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri" folder that will be created?',
|
||||
default: '../dist',
|
||||
when: () => !argv.D && answers.recipeName === 'No recipe' || argv.r === 'none'
|
||||
when: () =>
|
||||
(!argv.D && answers.recipeName === 'No recipe') ||
|
||||
argv.r === 'none'
|
||||
}
|
||||
])
|
||||
.then(answers2 => ({...answers, ...answers2}))
|
||||
.then((answers2) => ({ ...answers, ...answers2 }))
|
||||
)
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
if (error.isTtyError) {
|
||||
// Prompt couldn't be rendered in the current environment
|
||||
console.log(
|
||||
@ -139,16 +148,11 @@ const getOptionsInteractive = (argv) => {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
async function runInit(argv, config = {}) {
|
||||
const {
|
||||
appName,
|
||||
recipeName,
|
||||
...configOptions
|
||||
} = config
|
||||
const { appName, recipeName, ...configOptions } = config
|
||||
const init = require('../dist/api/init')
|
||||
|
||||
let recipe;
|
||||
let recipe
|
||||
let recipeSelection = 'none'
|
||||
|
||||
if (recipeName !== undefined) {
|
||||
@ -185,9 +189,7 @@ async function runInit(argv, config = {}) {
|
||||
})
|
||||
})
|
||||
|
||||
const {
|
||||
installDependencies
|
||||
} = require('../dist/api/dependency-manager')
|
||||
const { installDependencies } = require('../dist/api/dependency-manager')
|
||||
await installDependencies()
|
||||
|
||||
if (recipe !== undefined) {
|
||||
|
@ -20,7 +20,7 @@ if (argv.help) {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
async function run () {
|
||||
async function run() {
|
||||
const dev = require('../dist/api/dev')
|
||||
|
||||
await dev({
|
||||
|
@ -45,14 +45,13 @@ if (argv.help) {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
tauricon.make(
|
||||
argv.i,
|
||||
argv.t,
|
||||
argv.c || 'optipng'
|
||||
).then(() => {
|
||||
// TODO: use logger module for prettier output
|
||||
console.log('app:tauri (tauricon) Completed')
|
||||
}).catch(e => {
|
||||
// TODO: use logger module for prettier output
|
||||
console.error('app:tauri (icon)', e)
|
||||
})
|
||||
tauricon
|
||||
.make(argv.i, argv.t, argv.c || 'optipng')
|
||||
.then(() => {
|
||||
// TODO: use logger module for prettier output
|
||||
console.log('app:tauri (tauricon) Completed')
|
||||
})
|
||||
.catch((e) => {
|
||||
// TODO: use logger module for prettier output
|
||||
console.error('app:tauri (icon)', e)
|
||||
})
|
||||
|
@ -18,7 +18,7 @@ const tauriCreate = require('./tauri-create')
|
||||
function main(cliArgs) {
|
||||
const argv = parseArgs(cliArgs, {
|
||||
alias: {
|
||||
h: 'help',
|
||||
h: 'help'
|
||||
},
|
||||
boolean: ['h']
|
||||
})
|
||||
@ -32,7 +32,6 @@ function main(cliArgs) {
|
||||
tauriCreate([...cliArgs, '-r', 'none'])
|
||||
}
|
||||
|
||||
|
||||
function printUsage() {
|
||||
console.log(`
|
||||
Description
|
||||
|
@ -10,11 +10,17 @@ const cmd = process.argv[2]
|
||||
* @param {string|array} command
|
||||
*/
|
||||
const tauri = function (command) {
|
||||
if (typeof command === 'object') { // technically we just care about an array
|
||||
if (typeof command === 'object') {
|
||||
// technically we just care about an array
|
||||
command = command[0]
|
||||
}
|
||||
|
||||
if (!command || command === '-h' || command === '--help' || command === 'help') {
|
||||
if (
|
||||
!command ||
|
||||
command === '-h' ||
|
||||
command === '--help' ||
|
||||
command === 'help'
|
||||
) {
|
||||
console.log(`
|
||||
Description
|
||||
This is the Tauri CLI.
|
||||
|
@ -1,16 +1,28 @@
|
||||
const { exec } = require("child_process")
|
||||
const { exec } = require('child_process')
|
||||
const { readFileSync, writeFileSync } = require('fs')
|
||||
const { resolve } = require('path')
|
||||
|
||||
const sourcePath = resolve(__dirname, '../src/types/config.ts')
|
||||
|
||||
exec(`typescript-json-validator --noExtraProps ${sourcePath} TauriConfig`, error => {
|
||||
if (error) {
|
||||
console.error(error.message)
|
||||
process.exit(error.code || 1)
|
||||
} else {
|
||||
const configValidatorPath = resolve(__dirname, '../src/types/config.validator.ts')
|
||||
const configValidator = readFileSync(configValidatorPath).toString()
|
||||
writeFileSync(configValidatorPath, configValidator.replace(`import Ajv = require('ajv');`, `import Ajv from 'ajv';`))
|
||||
exec(
|
||||
`typescript-json-validator --noExtraProps ${sourcePath} TauriConfig`,
|
||||
(error) => {
|
||||
if (error) {
|
||||
console.error(error.message)
|
||||
process.exit(error.code || 1)
|
||||
} else {
|
||||
const configValidatorPath = resolve(
|
||||
__dirname,
|
||||
'../src/types/config.validator.ts'
|
||||
)
|
||||
const configValidator = readFileSync(configValidatorPath).toString()
|
||||
writeFileSync(
|
||||
configValidatorPath,
|
||||
configValidator.replace(
|
||||
`import Ajv = require('ajv')`,
|
||||
`import Ajv from 'ajv'`
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
@ -38,8 +38,9 @@ module.exports = {
|
||||
'^test/(.*)$': '<rootDir>/test/$1',
|
||||
'../../package.json': '<rootDir>/package.json'
|
||||
},
|
||||
"transform": {
|
||||
"templates[\\\\/](tauri|mutation-observer)\.js": "./test/jest/raw-loader-transformer.js",
|
||||
"\\.(js|ts)$": "babel-jest"
|
||||
transform: {
|
||||
'templates[\\\\/](tauri|mutation-observer).js':
|
||||
'./test/jest/raw-loader-transformer.js',
|
||||
'\\.(js|ts)$': 'babel-jest'
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,11 @@
|
||||
"pretest": "yarn build",
|
||||
"prepublishOnly": "yarn build-release",
|
||||
"test:local": "jest --runInBand",
|
||||
"lint": "eslint --ext ts ./src/**/*.ts ./api-src/**/*.ts",
|
||||
"lint-fix": "eslint --fix --ext ts ./src/**/*.ts",
|
||||
"lint": "eslint --ext ts \"./src/**/*.ts\" \"./api-src/**/*.ts\"",
|
||||
"lint-fix": "eslint --fix --ext ts \"./src/**/*.ts\" \"./api-src/**/*.ts\"",
|
||||
"lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn",
|
||||
"format": "prettier --write --end-of-line=auto !./**/mutation-observer.js !./**/config.validator.js \"./**/*.{js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore",
|
||||
"format:check": "prettier --check --end-of-line=auto !./**/mutation-observer.js \"./**/*.{js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore",
|
||||
"build:tauri[rust]": "cd ../tauri && TAURI_DIST_DIR=../../test/fixture/dist TAURI_DIR=../test/fixture cargo publish --dry-run --allow-dirty"
|
||||
},
|
||||
"repository": {
|
||||
@ -96,12 +98,13 @@
|
||||
"@types/semver": "7.3.1",
|
||||
"@types/sharp": "0.25.1",
|
||||
"@types/webpack-merge": "4.1.5",
|
||||
"@typescript-eslint/eslint-plugin": "3.7.0",
|
||||
"@typescript-eslint/parser": "3.7.0",
|
||||
"@typescript-eslint/eslint-plugin": "3.9.1",
|
||||
"@typescript-eslint/parser": "3.9.1",
|
||||
"babel-jest": "26.1.0",
|
||||
"copy-webpack-plugin": "6.0.3",
|
||||
"dotenv": "8.2.0",
|
||||
"eslint": "7.5.0",
|
||||
"eslint": "7.7.0",
|
||||
"eslint-config-prettier": "6.11.0",
|
||||
"eslint-config-standard-with-typescript": "18.0.2",
|
||||
"eslint-plugin-import": "2.22.0",
|
||||
"eslint-plugin-lodash-template": "0.19.0",
|
||||
@ -115,6 +118,7 @@
|
||||
"jest-mock-process": "1.4.0",
|
||||
"lint-staged": "10.2.11",
|
||||
"lockfile-lint": "4.3.7",
|
||||
"prettier": "2.0.5",
|
||||
"promise": "8.1.0",
|
||||
"raw-loader": "4.0.1",
|
||||
"rimraf": "3.0.2",
|
||||
@ -138,7 +142,8 @@
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": [
|
||||
"eslint --fix"
|
||||
]
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx,md,html,css,json}": "prettier --write --end-of-line=auto !./**/mutation-observer.js !./**/config.validator.js \"./**/*.{js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore",
|
||||
"*.{ts,tsx}": "eslint --fix --ext ts ./src/**/*.ts ./api-src/**/*.ts"
|
||||
}
|
||||
}
|
||||
|
@ -7,100 +7,100 @@ import babel, { getBabelOutputPlugin } from '@rollup/plugin-babel'
|
||||
import typescript from '@rollup/plugin-typescript'
|
||||
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',
|
||||
'cli': './api-src/cli.ts',
|
||||
'notification': './api-src/notification.ts',
|
||||
},
|
||||
treeshake: true,
|
||||
perf: true,
|
||||
output: [
|
||||
{
|
||||
dir: 'api/',
|
||||
entryFileNames: '[name].js',
|
||||
format: 'cjs',
|
||||
exports: 'named',
|
||||
globals: {}
|
||||
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',
|
||||
cli: './api-src/cli.ts',
|
||||
notification: './api-src/notification.ts'
|
||||
},
|
||||
{
|
||||
dir: 'api/',
|
||||
entryFileNames: '[name].mjs',
|
||||
format: 'esm',
|
||||
exports: 'named',
|
||||
globals: {}
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
commonjs({}),
|
||||
resolve({
|
||||
// pass custom options to the resolve plugin
|
||||
customResolveOptions: {
|
||||
moduleDirectory: 'node_modules'
|
||||
treeshake: true,
|
||||
perf: true,
|
||||
output: [
|
||||
{
|
||||
dir: 'api/',
|
||||
entryFileNames: '[name].js',
|
||||
format: 'cjs',
|
||||
exports: 'named',
|
||||
globals: {}
|
||||
},
|
||||
{
|
||||
dir: 'api/',
|
||||
entryFileNames: '[name].mjs',
|
||||
format: 'esm',
|
||||
exports: 'named',
|
||||
globals: {}
|
||||
}
|
||||
}),
|
||||
typescript({
|
||||
tsconfig: './tsconfig.api.json'
|
||||
}),
|
||||
babel({
|
||||
configFile: false,
|
||||
presets: [
|
||||
['@babel/preset-env'],
|
||||
['@babel/preset-typescript']
|
||||
]
|
||||
}),
|
||||
terser()
|
||||
],
|
||||
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
|
||||
commonjs({}),
|
||||
resolve({
|
||||
// pass custom options to the resolve plugin
|
||||
customResolveOptions: {
|
||||
moduleDirectory: 'node_modules'
|
||||
}
|
||||
}),
|
||||
typescript({
|
||||
tsconfig: './tsconfig.api.json'
|
||||
}),
|
||||
babel({
|
||||
configFile: false,
|
||||
presets: [['@babel/preset-env'], ['@babel/preset-typescript']]
|
||||
}),
|
||||
terser()
|
||||
],
|
||||
globals: {
|
||||
external: [
|
||||
...Object.keys(pkg.dependencies || {}),
|
||||
...Object.keys(pkg.peerDependencies || {})
|
||||
],
|
||||
watch: {
|
||||
chokidar: true,
|
||||
include: 'api-src/**',
|
||||
exclude: 'node_modules/**'
|
||||
}
|
||||
}],
|
||||
plugins: [
|
||||
sucrase({
|
||||
exclude: ['node_modules'],
|
||||
transforms: ['typescript']
|
||||
}),
|
||||
resolve({
|
||||
// pass custom options to the resolve plugin
|
||||
customResolveOptions: {
|
||||
moduleDirectory: '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: {}
|
||||
}
|
||||
})
|
||||
],
|
||||
external: [
|
||||
...Object.keys(pkg.dependencies || {}),
|
||||
...Object.keys(pkg.peerDependencies || {})
|
||||
]
|
||||
}]
|
||||
],
|
||||
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 || {})
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -9,7 +9,9 @@ const log = logger('dependency:cargo-commands')
|
||||
|
||||
const dependencies = ['tauri-bundler']
|
||||
|
||||
async function manageDependencies(managementType: ManagementType): Promise<Result> {
|
||||
async function manageDependencies(
|
||||
managementType: ManagementType
|
||||
): Promise<Result> {
|
||||
const installedDeps = []
|
||||
const updatedDeps = []
|
||||
|
||||
@ -22,12 +24,16 @@ async function manageDependencies(managementType: ManagementType): Promise<Resul
|
||||
} else if (managementType === ManagementType.Update) {
|
||||
const latestVersion = await getCrateLatestVersion(dependency)
|
||||
if (semverLt(currentVersion, latestVersion)) {
|
||||
const inquired = await inquirer.prompt([{
|
||||
type: 'confirm',
|
||||
name: 'answer',
|
||||
message: `[CARGO COMMANDS] "${dependency}" latest version is ${latestVersion}. Do you want to update?`,
|
||||
default: false
|
||||
}])
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const inquired = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'answer',
|
||||
message: `[CARGO COMMANDS] "${dependency}" latest version is ${latestVersion}. Do you want to update?`,
|
||||
default: false
|
||||
}
|
||||
])
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (inquired.answer) {
|
||||
spawnSync('cargo', ['install', dependency, '--force'])
|
||||
updatedDeps.push(dependency)
|
||||
@ -55,7 +61,4 @@ async function update(): Promise<Result> {
|
||||
return await manageDependencies(ManagementType.Update)
|
||||
}
|
||||
|
||||
export {
|
||||
install,
|
||||
update
|
||||
}
|
||||
export { install, update }
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { spawnSync } from './../../helpers/spawn'
|
||||
import { CargoManifest, CargoManifestDependency, CargoLock } from './../../types/cargo'
|
||||
import {
|
||||
CargoManifest,
|
||||
CargoManifestDependency,
|
||||
CargoLock
|
||||
} from './../../types/cargo'
|
||||
import { ManagementType, Result } from './types'
|
||||
import { getCrateLatestVersion, semverLt } from './util'
|
||||
import logger from '../../helpers/logger'
|
||||
@ -15,7 +19,7 @@ const dependencies = ['tauri']
|
||||
function readToml<T>(tomlPath: string): T | null {
|
||||
if (existsSync(tomlPath)) {
|
||||
const manifest = readFileSync(tomlPath).toString()
|
||||
return toml.parse(manifest) as any as T
|
||||
return (toml.parse(manifest) as any) as T
|
||||
}
|
||||
return null
|
||||
}
|
||||
@ -24,7 +28,9 @@ function dependencyDefinition(version: string): CargoManifestDependency {
|
||||
return { version: version.substring(0, version.lastIndexOf('.')) }
|
||||
}
|
||||
|
||||
async function manageDependencies(managementType: ManagementType): Promise<Result> {
|
||||
async function manageDependencies(
|
||||
managementType: ManagementType
|
||||
): Promise<Result> {
|
||||
const installedDeps = []
|
||||
const updatedDeps = []
|
||||
const result: Result = new Map<ManagementType, string[]>()
|
||||
@ -43,12 +49,17 @@ async function manageDependencies(managementType: ManagementType): Promise<Resul
|
||||
const lock = readToml<CargoLock>(lockPath)
|
||||
|
||||
for (const dependency of dependencies) {
|
||||
const lockPackages = lock ? lock.package.filter(pkg => pkg.name === dependency) : []
|
||||
const lockPackages = lock
|
||||
? lock.package.filter((pkg) => pkg.name === dependency)
|
||||
: []
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
const manifestDep = manifest.dependencies[dependency]
|
||||
const currentVersion = lockPackages.length === 1
|
||||
? lockPackages[0].version
|
||||
: (typeof manifestDep === 'string' ? manifestDep : manifestDep?.version)
|
||||
const currentVersion =
|
||||
lockPackages.length === 1
|
||||
? lockPackages[0].version
|
||||
: typeof manifestDep === 'string'
|
||||
? manifestDep
|
||||
: manifestDep?.version
|
||||
if (currentVersion === undefined) {
|
||||
log(`Installing ${dependency}...`)
|
||||
const latestVersion = await getCrateLatestVersion(dependency)
|
||||
@ -58,16 +69,22 @@ async function manageDependencies(managementType: ManagementType): Promise<Resul
|
||||
} else if (managementType === ManagementType.Update) {
|
||||
const latestVersion = await getCrateLatestVersion(dependency)
|
||||
if (semverLt(currentVersion, latestVersion)) {
|
||||
const inquired = await inquirer.prompt([{
|
||||
type: 'confirm',
|
||||
name: 'answer',
|
||||
message: `[CRATES] "${dependency}" latest version is ${latestVersion}. Do you want to update?`,
|
||||
default: false
|
||||
}])
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
|
||||
const inquired = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'answer',
|
||||
message: `[CRATES] "${dependency}" latest version is ${latestVersion}. Do you want to update?`,
|
||||
default: false
|
||||
}
|
||||
])
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
|
||||
if (inquired.answer) {
|
||||
log(`Updating ${dependency}...`)
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
manifest.dependencies[dependency] = dependencyDefinition(latestVersion)
|
||||
manifest.dependencies[dependency] = dependencyDefinition(
|
||||
latestVersion
|
||||
)
|
||||
updatedDeps.push(dependency)
|
||||
}
|
||||
} else {
|
||||
@ -79,13 +96,27 @@ async function manageDependencies(managementType: ManagementType): Promise<Resul
|
||||
}
|
||||
|
||||
if (installedDeps.length || updatedDeps.length) {
|
||||
writeFileSync(appResolve.tauri('Cargo.toml'), toml.stringify(manifest as any))
|
||||
writeFileSync(
|
||||
appResolve.tauri('Cargo.toml'),
|
||||
toml.stringify(manifest as any)
|
||||
)
|
||||
}
|
||||
if (updatedDeps.length) {
|
||||
if (!existsSync(appResolve.tauri('Cargo.lock'))) {
|
||||
spawnSync('cargo', ['generate-lockfile'], tauriDir)
|
||||
}
|
||||
spawnSync('cargo', ['update', '--aggressive', ...updatedDeps.reduce<string[]>((initialValue, dep) => [...initialValue, '-p', dep], [])], tauriDir)
|
||||
spawnSync(
|
||||
'cargo',
|
||||
[
|
||||
'update',
|
||||
'--aggressive',
|
||||
...updatedDeps.reduce<string[]>(
|
||||
(initialValue, dep) => [...initialValue, '-p', dep],
|
||||
[]
|
||||
)
|
||||
],
|
||||
tauriDir
|
||||
)
|
||||
}
|
||||
|
||||
result.set(ManagementType.Install, installedDeps)
|
||||
@ -102,7 +133,4 @@ async function update(): Promise<Result> {
|
||||
return await manageDependencies(ManagementType.Update)
|
||||
}
|
||||
|
||||
export {
|
||||
install,
|
||||
update
|
||||
}
|
||||
export { install, update }
|
||||
|
@ -14,7 +14,10 @@ import { existsSync } from 'fs'
|
||||
|
||||
const log = logger('dependency:npm-packages')
|
||||
|
||||
async function manageDependencies(managementType: ManagementType, dependencies: string[]): Promise<Result> {
|
||||
async function manageDependencies(
|
||||
managementType: ManagementType,
|
||||
dependencies: string[]
|
||||
): Promise<Result> {
|
||||
const installedDeps = []
|
||||
const updatedDeps = []
|
||||
|
||||
@ -32,12 +35,16 @@ async function manageDependencies(managementType: ManagementType, dependencies:
|
||||
} else if (managementType === ManagementType.Update) {
|
||||
const latestVersion = getNpmLatestVersion(dependency)
|
||||
if (semverLt(currentVersion, latestVersion)) {
|
||||
const inquired = await inquirer.prompt([{
|
||||
type: 'confirm',
|
||||
name: 'answer',
|
||||
message: `[NPM]: "${dependency}" latest version is ${latestVersion}. Do you want to update?`,
|
||||
default: false
|
||||
}])
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
|
||||
const inquired = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'answer',
|
||||
message: `[NPM]: "${dependency}" latest version is ${latestVersion}. Do you want to update?`,
|
||||
default: false
|
||||
}
|
||||
])
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
|
||||
if (inquired.answer) {
|
||||
log(`Updating ${dependency}...`)
|
||||
updateNpmPackage(dependency)
|
||||
@ -77,9 +84,4 @@ async function update(): Promise<Result> {
|
||||
return await manageDependencies(ManagementType.Update, dependencies)
|
||||
}
|
||||
|
||||
export {
|
||||
install,
|
||||
installThese,
|
||||
installTheseDev,
|
||||
update
|
||||
}
|
||||
export { install, installThese, installTheseDev, update }
|
||||
|
@ -9,27 +9,38 @@ import https from 'https'
|
||||
|
||||
const log = logger('dependency:rust')
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async function download(url: string, dest: string): Promise<void> {
|
||||
const file = createWriteStream(dest)
|
||||
return await new Promise((resolve, reject) => {
|
||||
https.get(url, response => {
|
||||
response.pipe(file)
|
||||
file.on('finish', function() {
|
||||
file.close()
|
||||
resolve()
|
||||
https
|
||||
.get(url, (response) => {
|
||||
response.pipe(file)
|
||||
file.on('finish', function () {
|
||||
file.close()
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
.on('error', function (err) {
|
||||
unlinkSync(dest)
|
||||
reject(err.message)
|
||||
})
|
||||
}).on('error', function(err) {
|
||||
unlinkSync(dest)
|
||||
reject(err.message)
|
||||
})
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
function installRustup(): void {
|
||||
if (platform() === 'win32') {
|
||||
return spawnSync('powershell', [resolve(__dirname, '../../scripts/rustup-init.exe')], process.cwd())
|
||||
return spawnSync(
|
||||
'powershell',
|
||||
[resolve(__dirname, '../../scripts/rustup-init.exe')],
|
||||
process.cwd()
|
||||
)
|
||||
}
|
||||
return spawnSync('/bin/sh', [resolve(__dirname, '../../scripts/rustup-init.sh')], process.cwd())
|
||||
return spawnSync(
|
||||
'/bin/sh',
|
||||
[resolve(__dirname, '../../scripts/rustup-init.sh')],
|
||||
process.cwd()
|
||||
)
|
||||
}
|
||||
|
||||
function manageDependencies(managementType: ManagementType): void {
|
||||
@ -51,7 +62,4 @@ function update(): void {
|
||||
return manageDependencies(ManagementType.Update)
|
||||
}
|
||||
|
||||
export {
|
||||
install,
|
||||
update
|
||||
}
|
||||
export { install, update }
|
||||
|
@ -23,13 +23,21 @@ async function getCrateLatestVersion(crateName: string): Promise<string> {
|
||||
}
|
||||
|
||||
function getNpmLatestVersion(packageName: string): string {
|
||||
const child = crossSpawnSync('npm', ['show', packageName, 'version'], { cwd: appDir })
|
||||
const child = crossSpawnSync('npm', ['show', packageName, 'version'], {
|
||||
cwd: appDir
|
||||
})
|
||||
return String(child.output[1]).replace('\n', '')
|
||||
}
|
||||
|
||||
async function getNpmPackageVersion(packageName: string): Promise<string | null> {
|
||||
async function getNpmPackageVersion(
|
||||
packageName: string
|
||||
): Promise<string | null> {
|
||||
return await new Promise((resolve) => {
|
||||
const child = crossSpawnSync('npm', ['list', packageName, 'version', '--depth', '0'], { cwd: appDir })
|
||||
const child = crossSpawnSync(
|
||||
'npm',
|
||||
['list', packageName, 'version', '--depth', '0'],
|
||||
{ cwd: appDir }
|
||||
)
|
||||
const output = String(child.output[1])
|
||||
// eslint-disable-next-line security/detect-non-literal-regexp
|
||||
const matches = new RegExp(packageName + '@(\\S+)', 'g').exec(output)
|
||||
|
@ -17,10 +17,14 @@ interface DevResult {
|
||||
|
||||
module.exports = (config: TauriConfig): DevResult => {
|
||||
if (platform() === 'win32') {
|
||||
const child = spawnSync('powershell', [resolve(__dirname, '../../scripts/is-admin.ps1')])
|
||||
const child = spawnSync('powershell', [
|
||||
resolve(__dirname, '../../scripts/is-admin.ps1')
|
||||
])
|
||||
const response = String(child.output[1]).replace('\n', '').trim()
|
||||
if (response === 'True') {
|
||||
error('Administrator privileges detected. Tauri doesn\'t work when running as admin, see https://github.com/Boscop/web-view/issues/96')
|
||||
error(
|
||||
"Administrator privileges detected. Tauri doesn't work when running as admin, see https://github.com/Boscop/web-view/issues/96"
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import toml from '@tauri-apps/toml'
|
||||
import chalk from 'chalk'
|
||||
import fs from 'fs'
|
||||
@ -11,7 +10,11 @@ import { CargoLock, CargoManifest } from '../types/cargo'
|
||||
import nonWebpackRequire from '../helpers/non-webpack-require'
|
||||
import packageJson from '../../package.json'
|
||||
import getScriptVersion from '../helpers/get-script-version'
|
||||
import { semverLt, getNpmLatestVersion, getCrateLatestVersion } from './dependency-manager/util'
|
||||
import {
|
||||
semverLt,
|
||||
getNpmLatestVersion,
|
||||
getCrateLatestVersion
|
||||
} from './dependency-manager/util'
|
||||
|
||||
async function crateLatestVersion(name: string): Promise<string | undefined> {
|
||||
try {
|
||||
@ -39,7 +42,7 @@ function dirTree(filename: string, recurse = true): DirInfo {
|
||||
if (stats.isDirectory()) {
|
||||
info.type = 'folder'
|
||||
if (recurse) {
|
||||
info.children = fs.readdirSync(filename).map(function(child: string) {
|
||||
info.children = fs.readdirSync(filename).map(function (child: string) {
|
||||
return dirTree(filename + '/' + child, false)
|
||||
})
|
||||
}
|
||||
@ -74,7 +77,7 @@ function printInfo(info: Info): void {
|
||||
const suffix = info.suffix ? ` ${info.suffix}` : ''
|
||||
console.log(
|
||||
`${info.section ? '\n' : ''}${info.key}${
|
||||
info.value === undefined ? '' : ' - ' + info.value
|
||||
info.value === undefined ? '' : ' - ' + info.value
|
||||
}${suffix}`
|
||||
)
|
||||
}
|
||||
@ -87,18 +90,28 @@ interface Version {
|
||||
}
|
||||
|
||||
function printVersion(info: Version): void {
|
||||
const outdated = info.version && info.targetVersion && semverLt(info.version, info.targetVersion)
|
||||
const outdated =
|
||||
info.version &&
|
||||
info.targetVersion &&
|
||||
semverLt(info.version, info.targetVersion)
|
||||
console.log(
|
||||
`${info.section ? '\n' : ''}${info.key}${
|
||||
info.version ? ' - ' + chalk.green(info.version) : chalk.red('Not installed')
|
||||
}` + (outdated && info.targetVersion ? ` (${chalk.red('outdated, latest: ' + info.targetVersion)})` : '')
|
||||
info.version
|
||||
? ' - ' + chalk.green(info.version)
|
||||
: chalk.red('Not installed')
|
||||
}` +
|
||||
(outdated && info.targetVersion
|
||||
? ` (${chalk.red('outdated, latest: ' + info.targetVersion)})`
|
||||
: '')
|
||||
)
|
||||
}
|
||||
|
||||
function readTomlFile<T extends CargoLock | CargoManifest>(filepath: string): T | null {
|
||||
function readTomlFile<T extends CargoLock | CargoManifest>(
|
||||
filepath: string
|
||||
): T | null {
|
||||
try {
|
||||
const file = fs.readFileSync(filepath).toString()
|
||||
return toml.parse(file) as unknown as T
|
||||
return (toml.parse(file) as unknown) as T
|
||||
} catch (_) {
|
||||
return null
|
||||
}
|
||||
@ -109,7 +122,9 @@ async function printAppInfo(tauriDir: string): Promise<void> {
|
||||
|
||||
const lockPath = path.join(tauriDir, 'Cargo.lock')
|
||||
const lock = readTomlFile<CargoLock>(lockPath)
|
||||
const lockPackages = lock ? lock.package.filter(pkg => pkg.name === 'tauri') : []
|
||||
const lockPackages = lock
|
||||
? lock.package.filter((pkg) => pkg.name === 'tauri')
|
||||
: []
|
||||
|
||||
const manifestPath = path.join(tauriDir, 'Cargo.toml')
|
||||
const manifest = readTomlFile<CargoManifest>(manifestPath)
|
||||
@ -123,7 +138,9 @@ async function printAppInfo(tauriDir: string): Promise<void> {
|
||||
} else if (lock && lockPackages.length === 1) {
|
||||
// good lockfile, but no manifest - will cause problems building
|
||||
foundTauriVersions.push(lockPackages[0].version)
|
||||
tauriVersion = `${chalk.green(lockPackages[0].version)} (${chalk.red('no manifest')})`
|
||||
tauriVersion = `${chalk.green(lockPackages[0].version)} (${chalk.red(
|
||||
'no manifest'
|
||||
)})`
|
||||
} else {
|
||||
// we found multiple/none `tauri` packages in the lockfile, or
|
||||
// no manifest. in both cases we want more info on the manifest
|
||||
@ -140,7 +157,9 @@ async function printAppInfo(tauriDir: string): Promise<void> {
|
||||
const manifestPath = path.resolve(tauriDir, tauri.path, 'Cargo.toml')
|
||||
const manifestContent = readTomlFile<CargoManifest>(manifestPath)
|
||||
let pathVersion = manifestContent?.package.version
|
||||
pathVersion = pathVersion ? chalk.yellow(pathVersion) : chalk.red(pathVersion)
|
||||
pathVersion = pathVersion
|
||||
? chalk.yellow(pathVersion)
|
||||
: chalk.red(pathVersion)
|
||||
return `path:${tauri.path} [${pathVersion}]`
|
||||
}
|
||||
} else {
|
||||
@ -151,7 +170,7 @@ async function printAppInfo(tauriDir: string): Promise<void> {
|
||||
|
||||
let lockVersion
|
||||
if (lock && lockPackages.length > 0) {
|
||||
lockVersion = chalk.yellow(lockPackages.map(p => p.version).join(', '))
|
||||
lockVersion = chalk.yellow(lockPackages.map((p) => p.version).join(', '))
|
||||
} else if (lock && lockPackages.length === 0) {
|
||||
lockVersion = chalk.red('unknown lockfile')
|
||||
} else {
|
||||
@ -161,14 +180,20 @@ async function printAppInfo(tauriDir: string): Promise<void> {
|
||||
tauriVersion = `${manifestVersion()} (${chalk.yellow(lockVersion)})`
|
||||
}
|
||||
|
||||
const tauriVersionString = foundTauriVersions.reduce((old, current) => semverLt(old, current) ? current : old, '0.0.0')
|
||||
const tauriVersionString = foundTauriVersions.reduce(
|
||||
(old, current) => (semverLt(old, current) ? current : old),
|
||||
'0.0.0'
|
||||
)
|
||||
const latestTauriCore = await crateLatestVersion('tauri')
|
||||
printInfo({
|
||||
key: ' tauri.rs',
|
||||
value: tauriVersion,
|
||||
suffix: tauriVersionString !== '0.0.0' && latestTauriCore && semverLt(tauriVersionString, latestTauriCore)
|
||||
? `(${chalk.red('outdated, latest: ' + latestTauriCore)})`
|
||||
: undefined
|
||||
suffix:
|
||||
tauriVersionString !== '0.0.0' &&
|
||||
latestTauriCore &&
|
||||
semverLt(tauriVersionString, latestTauriCore)
|
||||
? `(${chalk.red('outdated, latest: ' + latestTauriCore)})`
|
||||
: undefined
|
||||
})
|
||||
|
||||
try {
|
||||
@ -185,8 +210,7 @@ async function printAppInfo(tauriDir: string): Promise<void> {
|
||||
printInfo({ key: ' mode', value: tauriMode(config) })
|
||||
printInfo({
|
||||
key: ' build-type',
|
||||
value:
|
||||
config.tauri.bundle?.active ? 'bundle' : 'build'
|
||||
value: config.tauri.bundle?.active ? 'bundle' : 'build'
|
||||
})
|
||||
printInfo({
|
||||
key: ' CSP',
|
||||
@ -204,7 +228,7 @@ async function printAppInfo(tauriDir: string): Promise<void> {
|
||||
? chalk.green(config.build.devPath)
|
||||
: chalk.red('unset')
|
||||
})
|
||||
} catch (_) { }
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
module.exports = async () => {
|
||||
@ -216,16 +240,28 @@ module.exports = async () => {
|
||||
section: true
|
||||
})
|
||||
if (os.platform() === 'win32') {
|
||||
const { stdout } = spawn('REG', ['QUERY', 'HKEY_CLASSES_root\\AppX3xxs313wwkfjhythsb8q46xdsq8d2cvv\\Application', '/v', 'ApplicationName'])
|
||||
const { stdout } = spawn('REG', [
|
||||
'QUERY',
|
||||
'HKEY_CLASSES_root\\AppX3xxs313wwkfjhythsb8q46xdsq8d2cvv\\Application',
|
||||
'/v',
|
||||
'ApplicationName'
|
||||
])
|
||||
const match = /{(\S+)}/g.exec(stdout.toString())
|
||||
if (match) {
|
||||
const edgeString = match[1]
|
||||
printInfo({ key: 'Microsoft Edge', value: edgeString.split('?')[0].replace('Microsoft.MicrosoftEdge_', '') })
|
||||
printInfo({
|
||||
key: 'Microsoft Edge',
|
||||
value: edgeString.split('?')[0].replace('Microsoft.MicrosoftEdge_', '')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
printInfo({ key: 'Node.js environment', section: true })
|
||||
printVersion({ key: ' Node.js', version: process.version.slice(1), targetVersion: packageJson.engines.node.replace('>= ', '') })
|
||||
printVersion({
|
||||
key: ' Node.js',
|
||||
version: process.version.slice(1),
|
||||
targetVersion: packageJson.engines.node.replace('>= ', '')
|
||||
})
|
||||
printVersion({
|
||||
key: ' tauri.js',
|
||||
version: packageJson.version,
|
||||
@ -235,11 +271,11 @@ module.exports = async () => {
|
||||
printInfo({ key: 'Rust environment', section: true })
|
||||
printInfo({
|
||||
key: ' rustc',
|
||||
value: getVersion('rustc', [], output => output.split(' ')[1])
|
||||
value: getVersion('rustc', [], (output) => output.split(' ')[1])
|
||||
})
|
||||
printInfo({
|
||||
key: ' cargo',
|
||||
value: getVersion('cargo', [], output => output.split(' ')[1])
|
||||
value: getVersion('cargo', [], (output) => output.split(' ')[1])
|
||||
})
|
||||
printVersion({
|
||||
key: ' tauri-bundler',
|
||||
|
@ -26,14 +26,19 @@ module.exports = (args: {
|
||||
)
|
||||
if (args.appName) {
|
||||
const manifestPath = resolve(args.directory, 'src-tauri/Cargo.toml')
|
||||
const cargoManifest = toml.parse(readFileSync(manifestPath).toString()) as unknown as CargoManifest
|
||||
const cargoManifest = (toml.parse(
|
||||
readFileSync(manifestPath).toString()
|
||||
) as unknown) as CargoManifest
|
||||
const binName = kebabCase(args.appName)
|
||||
cargoManifest.package.name = binName
|
||||
cargoManifest.package['default-run'] = binName
|
||||
if (cargoManifest.bin?.length) {
|
||||
cargoManifest.bin[0].name = binName
|
||||
}
|
||||
writeFileSync(manifestPath, toml.stringify(cargoManifest as unknown as JsonMap))
|
||||
writeFileSync(
|
||||
manifestPath,
|
||||
toml.stringify((cargoManifest as unknown) as JsonMap)
|
||||
)
|
||||
}
|
||||
return injectResult
|
||||
}
|
||||
|
@ -20,14 +20,12 @@ const none = {
|
||||
postConfiguration: (cwd: string) => {}
|
||||
}
|
||||
|
||||
export const allRecipes: Recipe[] = [
|
||||
none,
|
||||
reactjs,
|
||||
reactts
|
||||
]
|
||||
export const allRecipes: Recipe[] = [none, reactjs, reactts]
|
||||
|
||||
export const recipeNames: Array<[string, string]> =
|
||||
map(allRecipes, (r: Recipe) => [r.shortName, r.descriptiveName])
|
||||
export const recipeNames: Array<[string, string]> = map(
|
||||
allRecipes,
|
||||
(r: Recipe) => [r.shortName, r.descriptiveName]
|
||||
)
|
||||
|
||||
export const recipeByShortName = (name: string): Recipe | undefined =>
|
||||
find(allRecipes, (r: Recipe) => r.shortName === name)
|
||||
@ -35,6 +33,12 @@ export const recipeByShortName = (name: string): Recipe | undefined =>
|
||||
export const recipeByDescriptiveName = (name: string): Recipe | undefined =>
|
||||
find(allRecipes, (r: Recipe) => r.descriptiveName === name)
|
||||
|
||||
export const recipeShortNames: string[] = map(allRecipes, (r: Recipe) => r.shortName)
|
||||
export const recipeShortNames: string[] = map(
|
||||
allRecipes,
|
||||
(r: Recipe) => r.shortName
|
||||
)
|
||||
|
||||
export const recipeDescriptiveNames: string[] = map(allRecipes, (r: Recipe) => r.descriptiveName)
|
||||
export const recipeDescriptiveNames: string[] = map(
|
||||
allRecipes,
|
||||
(r: Recipe) => r.descriptiveName
|
||||
)
|
||||
|
@ -1,20 +1,33 @@
|
||||
import { installThese, installTheseDev } from '../dependency-manager/npm-packages'
|
||||
import {
|
||||
installThese,
|
||||
installTheseDev
|
||||
} from '../dependency-manager/npm-packages'
|
||||
import { Recipe } from '.'
|
||||
import { Result } from '../dependency-manager/types'
|
||||
import logger from '../../helpers/logger'
|
||||
|
||||
export async function installRecipeDependencies(recipe: Recipe): Promise<Result> {
|
||||
export async function installRecipeDependencies(
|
||||
recipe: Recipe
|
||||
): Promise<Result> {
|
||||
const log = logger('recipe:install')
|
||||
|
||||
log(`Installing dependencies for ${recipe.descriptiveName}`)
|
||||
return await installThese(recipe.extraNpmDependencies).then(async (results) =>
|
||||
await installTheseDev(recipe.extraNpmDevDependencies).then((results2) =>
|
||||
new Map([...Array.from(results.entries()), ...Array.from(results2.entries())])
|
||||
)
|
||||
return await installThese(recipe.extraNpmDependencies).then(
|
||||
async (results) =>
|
||||
await installTheseDev(recipe.extraNpmDevDependencies).then(
|
||||
(results2) =>
|
||||
new Map([
|
||||
...Array.from(results.entries()),
|
||||
...Array.from(results2.entries())
|
||||
])
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export async function runRecipePostConfig(recipe: Recipe, cwd: string): Promise<void> {
|
||||
export async function runRecipePostConfig(
|
||||
recipe: Recipe,
|
||||
cwd: string
|
||||
): Promise<void> {
|
||||
const log = logger('recipe:postconfig')
|
||||
|
||||
log(`Running post configuration for ${recipe.descriptiveName}`)
|
||||
|
@ -45,14 +45,21 @@ const reactts: Recipe = {
|
||||
...reactjs,
|
||||
descriptiveName: 'React with Typescript',
|
||||
shortName: 'reactts',
|
||||
extraNpmDependencies: ['typescript', '@types/node', '@types/react', '@types/react-dom', '@types/jest'],
|
||||
extraNpmDependencies: [
|
||||
'typescript',
|
||||
'@types/node',
|
||||
'@types/react',
|
||||
'@types/react-dom',
|
||||
'@types/jest'
|
||||
],
|
||||
postConfiguration: (cwd: string) => {
|
||||
spawnSync('yarn', ['create-react-app', '--template', 'typescript', uiAppDir], cwd)
|
||||
spawnSync(
|
||||
'yarn',
|
||||
['create-react-app', '--template', 'typescript', uiAppDir],
|
||||
cwd
|
||||
)
|
||||
afterCra()
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
reactjs,
|
||||
reactts
|
||||
}
|
||||
export { reactjs, reactts }
|
||||
|
@ -36,7 +36,7 @@ const warn = logger('app:spawn', chalk.red)
|
||||
let image: boolean | sharp.Sharp = false
|
||||
const spinnerInterval = false
|
||||
|
||||
const exists = async function(file: string | Buffer): Promise<boolean> {
|
||||
const exists = async function (file: string | Buffer): Promise<boolean> {
|
||||
try {
|
||||
await access(file)
|
||||
return true
|
||||
@ -106,11 +106,11 @@ const uniqueFolders = (options: { [index: string]: any }): any[] => {
|
||||
*/
|
||||
const hexToRgb = (
|
||||
hex: string
|
||||
): { r: number, g: number, b: number } | undefined => {
|
||||
): { r: number; g: number; b: number } | undefined => {
|
||||
// https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
|
||||
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
|
||||
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i
|
||||
hex = hex.replace(shorthandRegex, function(
|
||||
hex = hex.replace(shorthandRegex, function (
|
||||
m: string,
|
||||
r: string,
|
||||
g: string,
|
||||
@ -122,10 +122,10 @@ const hexToRgb = (
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
}
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
|
||||
@ -178,14 +178,14 @@ const spinner = (): NodeJS.Timeout => {
|
||||
}
|
||||
|
||||
const tauricon = (exports.tauricon = {
|
||||
validate: async function(src: string, target: string) {
|
||||
validate: async function (src: string, target: string) {
|
||||
await validate(src, target)
|
||||
return typeof image === 'object'
|
||||
},
|
||||
version: function() {
|
||||
version: function () {
|
||||
return version
|
||||
},
|
||||
make: async function(
|
||||
make: async function (
|
||||
src: string = path.resolve(appDir, 'app-icon.png'),
|
||||
target: string = path.resolve(tauriDir, 'icons'),
|
||||
strategy: string,
|
||||
@ -217,7 +217,7 @@ const tauricon = (exports.tauricon = {
|
||||
* @param {string} target - where to drop the images
|
||||
* @param {object} options - js object that defines path and sizes
|
||||
*/
|
||||
build: async function(
|
||||
build: async function (
|
||||
src: string,
|
||||
target: string,
|
||||
// TODO: proper type for options
|
||||
@ -225,7 +225,7 @@ const tauricon = (exports.tauricon = {
|
||||
) {
|
||||
await this.validate(src, target)
|
||||
const sharpSrc = sharp(src) // creates the image object
|
||||
const buildify2 = async function(
|
||||
const buildify2 = async function (
|
||||
pvar: [string, number, number]
|
||||
): Promise<void> {
|
||||
try {
|
||||
@ -288,7 +288,7 @@ const tauricon = (exports.tauricon = {
|
||||
* @param {string} target - where to drop the images
|
||||
* @param {object} options - js object that defines path and sizes
|
||||
*/
|
||||
splash: async function(
|
||||
splash: async function (
|
||||
src: string,
|
||||
splashSrc: string,
|
||||
target: string,
|
||||
@ -349,7 +349,9 @@ const tauricon = (exports.tauricon = {
|
||||
background: { r: rgb.r, g: rgb.g, b: rgb.b, alpha: 1 }
|
||||
})
|
||||
} else {
|
||||
throw new Error(`unknown options.splashscreen_type: ${options.splashscreen_type}`)
|
||||
throw new Error(
|
||||
`unknown options.splashscreen_type: ${options.splashscreen_type}`
|
||||
)
|
||||
}
|
||||
const data = await sharpSrc.toBuffer()
|
||||
|
||||
@ -383,7 +385,7 @@ const tauricon = (exports.tauricon = {
|
||||
* @param {string} strategy - which minify strategy to use
|
||||
* @param {string} mode - singlefile or batch
|
||||
*/
|
||||
minify: async function(
|
||||
minify: async function (
|
||||
target: string,
|
||||
// TODO: proper type for options
|
||||
options: { [index: string]: any },
|
||||
@ -392,13 +394,13 @@ const tauricon = (exports.tauricon = {
|
||||
) {
|
||||
let cmd: Plugin
|
||||
const minify = settings.options.minify
|
||||
if (!minify.available.find(x => x === strategy)) {
|
||||
if (!minify.available.find((x) => x === strategy)) {
|
||||
strategy = minify.type
|
||||
}
|
||||
switch (strategy) {
|
||||
case 'pngquant':
|
||||
// TODO: is minify.pngquantOptions the proper format?
|
||||
cmd = pngquant(minify.pngquantOptions as any as PngQuantOptions)
|
||||
cmd = pngquant((minify.pngquantOptions as any) as PngQuantOptions)
|
||||
break
|
||||
case 'optipng':
|
||||
cmd = optipng(minify.optipngOptions)
|
||||
@ -414,7 +416,7 @@ const tauricon = (exports.tauricon = {
|
||||
await imagemin([pvar[0]], {
|
||||
destination: pvar[1],
|
||||
plugins: [cmd]
|
||||
}).catch(err => {
|
||||
}).catch((err) => {
|
||||
warn(err)
|
||||
})
|
||||
}
|
||||
@ -454,7 +456,7 @@ const tauricon = (exports.tauricon = {
|
||||
* @param {object} options
|
||||
* @param {string} strategy
|
||||
*/
|
||||
icns: async function(
|
||||
icns: async function (
|
||||
src: string,
|
||||
target: string,
|
||||
// TODO: proper type for options
|
||||
|
@ -6,9 +6,7 @@ import chalk from 'chalk'
|
||||
const warn = logger('tauri', chalk.red)
|
||||
|
||||
function resolvePath(basePath: string, dir: string): string {
|
||||
return dir && isAbsolute(dir)
|
||||
? dir
|
||||
: resolve(basePath, dir)
|
||||
return dir && isAbsolute(dir) ? dir : resolve(basePath, dir)
|
||||
}
|
||||
|
||||
const getAppDir = (): string => {
|
||||
@ -24,7 +22,9 @@ const getAppDir = (): string => {
|
||||
dir = normalize(join(dir, '..'))
|
||||
}
|
||||
|
||||
warn('Couldn\'t find recognize the current folder as a part of a Tauri project')
|
||||
warn(
|
||||
"Couldn't find recognize the current folder as a part of a Tauri project"
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ const copyTemplates = ({
|
||||
for (const rawPath of files) {
|
||||
const targetRelativePath = rawPath
|
||||
.split('/')
|
||||
.map(name => {
|
||||
.map((name) => {
|
||||
// dotfiles are ignored when published to npm, therefore in templates
|
||||
// we need to use underscore instead (e.g. "_gitignore")
|
||||
if (name.startsWith('_') && name.charAt(1) !== '_') {
|
||||
|
@ -2,22 +2,25 @@
|
||||
|
||||
import net from 'net'
|
||||
|
||||
async function findClosestOpenPort(port: number, host: string): Promise<number> {
|
||||
return await isPortAvailable(port, host)
|
||||
.then(isAvailable => {
|
||||
if (isAvailable) {
|
||||
return port
|
||||
} else if (port < 65535) {
|
||||
return findClosestOpenPort(port + 1, host)
|
||||
} else {
|
||||
throw new Error('ERROR_NETWORK_PORT_NOT_AVAIL')
|
||||
}
|
||||
})
|
||||
async function findClosestOpenPort(
|
||||
port: number,
|
||||
host: string
|
||||
): Promise<number> {
|
||||
return await isPortAvailable(port, host).then((isAvailable) => {
|
||||
if (isAvailable) {
|
||||
return port
|
||||
} else if (port < 65535) {
|
||||
return findClosestOpenPort(port + 1, host)
|
||||
} else {
|
||||
throw new Error('ERROR_NETWORK_PORT_NOT_AVAIL')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function isPortAvailable(port: number, host: string): Promise<boolean> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
const tester = net.createServer()
|
||||
const tester = net
|
||||
.createServer()
|
||||
.once('error', (err: NodeJS.ErrnoException) => {
|
||||
if (err.code === 'EADDRNOTAVAIL') {
|
||||
reject(new Error('ERROR_NETWORK_ADDRESS_NOT_AVAIL'))
|
||||
@ -28,9 +31,10 @@ async function isPortAvailable(port: number, host: string): Promise<boolean> {
|
||||
}
|
||||
})
|
||||
.once('listening', () => {
|
||||
tester.once('close', () => {
|
||||
resolve(true) // found available host/port
|
||||
})
|
||||
tester
|
||||
.once('close', () => {
|
||||
resolve(true) // found available host/port
|
||||
})
|
||||
.close()
|
||||
})
|
||||
.on('error', (err: any) => {
|
||||
@ -40,7 +44,4 @@ async function isPortAvailable(port: number, host: string): Promise<boolean> {
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
findClosestOpenPort,
|
||||
isPortAvailable
|
||||
}
|
||||
export { findClosestOpenPort, isPortAvailable }
|
||||
|
@ -24,7 +24,7 @@ export const spawn = (
|
||||
env: process.env
|
||||
})
|
||||
|
||||
runner.on('close', code => {
|
||||
runner.on('close', (code) => {
|
||||
log()
|
||||
if (code) {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
|
@ -18,8 +18,12 @@ const getTauriConfig = (cfg: Partial<TauriConfig>): TauriConfig => {
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
const tauriConf = JSON.parse(readFileSync(tauriConfPath).toString()) as TauriConfig
|
||||
const pkg = existsSync(pkgPath) ? nonWebpackRequire(pkgPath) as { productName: string } : null
|
||||
const tauriConf = JSON.parse(
|
||||
readFileSync(tauriConfPath).toString()
|
||||
) as TauriConfig
|
||||
const pkg = existsSync(pkgPath)
|
||||
? (nonWebpackRequire(pkgPath) as { productName: string })
|
||||
: null
|
||||
|
||||
const config = merge(
|
||||
{
|
||||
@ -48,7 +52,8 @@ const getTauriConfig = (cfg: Partial<TauriConfig>): TauriConfig => {
|
||||
title: pkg?.productName ?? 'Tauri App'
|
||||
},
|
||||
security: {
|
||||
csp: "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"
|
||||
csp:
|
||||
"default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"
|
||||
},
|
||||
inliner: {
|
||||
active: true
|
||||
@ -60,15 +65,24 @@ const getTauriConfig = (cfg: Partial<TauriConfig>): TauriConfig => {
|
||||
) as TauriConfig
|
||||
|
||||
if (!isTauriConfig(config)) {
|
||||
const messages = ajv.errorsText(
|
||||
isTauriConfig.errors?.filter(e => e.keyword !== 'if').map(e => {
|
||||
e.dataPath = e.dataPath.replace(/\./g, ' > ')
|
||||
if (e.keyword === 'additionalProperties' && typeof e.message === 'string' && 'additionalProperty' in e.params) {
|
||||
e.message = `has unknown property ${e.params.additionalProperty}`
|
||||
}
|
||||
return e
|
||||
}), { dataVar: 'tauri.conf.json', separator: '\n' }
|
||||
).split('\n')
|
||||
const messages = ajv
|
||||
.errorsText(
|
||||
isTauriConfig.errors
|
||||
?.filter((e) => e.keyword !== 'if')
|
||||
.map((e) => {
|
||||
e.dataPath = e.dataPath.replace(/\./g, ' > ')
|
||||
if (
|
||||
e.keyword === 'additionalProperties' &&
|
||||
typeof e.message === 'string' &&
|
||||
'additionalProperty' in e.params
|
||||
) {
|
||||
e.message = `has unknown property ${e.params.additionalProperty}`
|
||||
}
|
||||
return e
|
||||
}),
|
||||
{ dataVar: 'tauri.conf.json', separator: '\n' }
|
||||
)
|
||||
.split('\n')
|
||||
|
||||
for (const message of messages) {
|
||||
error(message)
|
||||
@ -102,7 +116,9 @@ const getTauriConfig = (cfg: Partial<TauriConfig>): TauriConfig => {
|
||||
// bundle targets
|
||||
if (Array.isArray(config.tauri.bundle.targets)) {
|
||||
if (process.platform !== 'win32') {
|
||||
config.tauri.bundle.targets = config.tauri.bundle.targets.filter(t => t !== 'msi')
|
||||
config.tauri.bundle.targets = config.tauri.bundle.targets.filter(
|
||||
(t) => t !== 'msi'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ class Runner {
|
||||
this.pid = 0
|
||||
this.tauriWatcher = undefined
|
||||
onShutdown(() => {
|
||||
this.stop().catch(e => {
|
||||
this.stop().catch((e) => {
|
||||
throw e
|
||||
})
|
||||
})
|
||||
@ -56,14 +56,18 @@ class Runner {
|
||||
|
||||
if (!this.beforeDevProcess && cfg.build.beforeDevCommand) {
|
||||
log('Running `' + cfg.build.beforeDevCommand + '`')
|
||||
const ls = exec(cfg.build.beforeDevCommand, {
|
||||
cwd: appDir,
|
||||
env: process.env
|
||||
}, error => {
|
||||
if (error) {
|
||||
process.exit(1)
|
||||
const ls = exec(
|
||||
cfg.build.beforeDevCommand,
|
||||
{
|
||||
cwd: appDir,
|
||||
env: process.env
|
||||
},
|
||||
(error) => {
|
||||
if (error) {
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
ls.stderr?.pipe(process.stderr)
|
||||
ls.stdout?.pipe(process.stdout)
|
||||
@ -73,19 +77,23 @@ class Runner {
|
||||
const devTryTimeout = 3000
|
||||
while (!(await isReachable(devPath))) {
|
||||
log('Waiting for your dev server to start...')
|
||||
await new Promise(resolve => setTimeout(resolve, devTryTimeout))
|
||||
await new Promise((resolve) => setTimeout(resolve, devTryTimeout))
|
||||
devTryCount++
|
||||
if (devTryCount === 10) {
|
||||
warn(`Couldn't connect to ${devPath} after ${devTryTimeout * devTryCount / 1000}s. Please make sure that's the URL to your dev server.`)
|
||||
warn(
|
||||
`Couldn't connect to ${devPath} after ${
|
||||
(devTryTimeout * devTryCount) / 1000
|
||||
}s. Please make sure that's the URL to your dev server.`
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const cargoManifest = this.__getManifest() as any as CargoManifest
|
||||
const cargoManifest = (this.__getManifest() as any) as CargoManifest
|
||||
this.__allowlistApi(cfg, cargoManifest)
|
||||
this.__rewriteManifest(cargoManifest as unknown as toml.JsonMap)
|
||||
this.__rewriteManifest((cargoManifest as unknown) as toml.JsonMap)
|
||||
|
||||
const runningDevServer = devPath.startsWith('http')
|
||||
|
||||
@ -104,51 +112,67 @@ class Runner {
|
||||
selfHandleResponse: true
|
||||
})
|
||||
|
||||
proxy.on('proxyRes', (proxyRes: http.IncomingMessage, req: http.IncomingMessage, res: http.ServerResponse) => {
|
||||
if (req.url === '/') {
|
||||
const body: Uint8Array[] = []
|
||||
proxyRes.on('data', (chunk: Uint8Array) => {
|
||||
body.push(chunk)
|
||||
})
|
||||
proxyRes.on('end', () => {
|
||||
const bodyStr = body.join('')
|
||||
const indexDir = os.tmpdir()
|
||||
writeFileSync(path.join(indexDir, 'index.html'), bodyStr)
|
||||
self.__parseHtml(cfg, indexDir, false)
|
||||
.then(({ html }) => {
|
||||
const headers: { [key: string]: string } = {}
|
||||
if (proxyRes.headers['content-type']) {
|
||||
headers['content-type'] = proxyRes.headers['content-type']
|
||||
} else {
|
||||
const charsetMatch = /charset="(\S+)"/g.exec(bodyStr)
|
||||
if (charsetMatch) {
|
||||
headers['content-type'] = `'text/html; charset=${charsetMatch[1]}`
|
||||
proxy.on(
|
||||
'proxyRes',
|
||||
(
|
||||
proxyRes: http.IncomingMessage,
|
||||
req: http.IncomingMessage,
|
||||
res: http.ServerResponse
|
||||
) => {
|
||||
if (req.url === '/') {
|
||||
const body: Uint8Array[] = []
|
||||
proxyRes.on('data', (chunk: Uint8Array) => {
|
||||
body.push(chunk)
|
||||
})
|
||||
proxyRes.on('end', () => {
|
||||
const bodyStr = body.join('')
|
||||
const indexDir = os.tmpdir()
|
||||
writeFileSync(path.join(indexDir, 'index.html'), bodyStr)
|
||||
self
|
||||
.__parseHtml(cfg, indexDir, false)
|
||||
.then(({ html }) => {
|
||||
const headers: { [key: string]: string } = {}
|
||||
if (proxyRes.headers['content-type']) {
|
||||
headers['content-type'] = proxyRes.headers['content-type']
|
||||
} else {
|
||||
const charsetMatch = /charset="(\S+)"/g.exec(bodyStr)
|
||||
if (charsetMatch) {
|
||||
headers[
|
||||
'content-type'
|
||||
] = `'text/html; charset=${charsetMatch[1]}`
|
||||
}
|
||||
}
|
||||
}
|
||||
res.writeHead(200, headers)
|
||||
res.end(html)
|
||||
}).catch(err => {
|
||||
res.writeHead(500, JSON.stringify(err))
|
||||
res.end()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
if (proxyRes.statusCode) {
|
||||
res = res.writeHead(proxyRes.statusCode, proxyRes.headers)
|
||||
res.writeHead(200, headers)
|
||||
res.end(html)
|
||||
})
|
||||
.catch((err) => {
|
||||
res.writeHead(500, JSON.stringify(err))
|
||||
res.end()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
if (proxyRes.statusCode) {
|
||||
res = res.writeHead(proxyRes.statusCode, proxyRes.headers)
|
||||
}
|
||||
|
||||
proxyRes.pipe(res)
|
||||
}
|
||||
|
||||
proxyRes.pipe(res)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
proxy.on('error', (error: Error, _: http.IncomingMessage, res: http.ServerResponse) => {
|
||||
if (error.message?.includes('ECONNREFUSED')) {
|
||||
warn(`Connection refused to ${devUrl.protocol}//${devUrl.host}. Did you start your dev server? Usually that's done with a \`dev\` or \`serve\` NPM script.`)
|
||||
} else {
|
||||
console.error(error)
|
||||
proxy.on(
|
||||
'error',
|
||||
(error: Error, _: http.IncomingMessage, res: http.ServerResponse) => {
|
||||
if (error.message?.includes('ECONNREFUSED')) {
|
||||
warn(
|
||||
`Connection refused to ${devUrl.protocol}//${devUrl.host}. Did you start your dev server? Usually that's done with a \`dev\` or \`serve\` NPM script.`
|
||||
)
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
res.writeHead(500, error.message)
|
||||
}
|
||||
res.writeHead(500, error.message)
|
||||
})
|
||||
)
|
||||
|
||||
const proxyServer = http.createServer((req, res) => {
|
||||
delete req.headers['accept-encoding']
|
||||
@ -158,7 +182,10 @@ class Runner {
|
||||
proxy.ws(req, socket, head)
|
||||
})
|
||||
|
||||
const port = await findClosestOpenPort(parseInt(devUrl.port) + 1, devUrl.hostname)
|
||||
const port = await findClosestOpenPort(
|
||||
parseInt(devUrl.port) + 1,
|
||||
devUrl.hostname
|
||||
)
|
||||
const devServer = proxyServer.listen(port)
|
||||
this.devServer = devServer
|
||||
devPath = `${devUrl.protocol}//localhost:${port}`
|
||||
@ -184,8 +211,14 @@ class Runner {
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||
|
||||
let tauriPaths: string[] = []
|
||||
if (typeof cargoManifest.dependencies.tauri !== 'string' && cargoManifest.dependencies.tauri.path) {
|
||||
const tauriPath = path.resolve(tauriDir, cargoManifest.dependencies.tauri.path)
|
||||
if (
|
||||
typeof cargoManifest.dependencies.tauri !== 'string' &&
|
||||
cargoManifest.dependencies.tauri.path
|
||||
) {
|
||||
const tauriPath = path.resolve(
|
||||
tauriDir,
|
||||
cargoManifest.dependencies.tauri.path
|
||||
)
|
||||
tauriPaths = [
|
||||
tauriPath,
|
||||
`${tauriPath}-api`,
|
||||
@ -207,30 +240,36 @@ class Runner {
|
||||
].concat(runningDevServer ? [] : [devPath]),
|
||||
{
|
||||
ignoreInitial: true,
|
||||
ignored: [runningDevServer ? null : path.join(devPath, 'index.tauri.html')].concat(path.join(tauriDir, 'target'))
|
||||
ignored: [
|
||||
runningDevServer ? null : path.join(devPath, 'index.tauri.html')
|
||||
].concat(path.join(tauriDir, 'target'))
|
||||
}
|
||||
)
|
||||
.on(
|
||||
'change',
|
||||
debounce((changedPath: string) => {
|
||||
if (this.rewritingToml && changedPath.startsWith(path.join(tauriDir, 'Cargo.toml'))) {
|
||||
if (
|
||||
this.rewritingToml &&
|
||||
changedPath.startsWith(path.join(tauriDir, 'Cargo.toml'))
|
||||
) {
|
||||
return
|
||||
}
|
||||
(this.pid ? this.__stopCargo() : Promise.resolve())
|
||||
;(this.pid ? this.__stopCargo() : Promise.resolve())
|
||||
.then(() => {
|
||||
const shouldTriggerRun = changedPath.includes('tauri.conf.json') ||
|
||||
const shouldTriggerRun =
|
||||
changedPath.includes('tauri.conf.json') ||
|
||||
changedPath.startsWith(devPath)
|
||||
if (shouldTriggerRun) {
|
||||
this.run(getTauriConfig({ ctx: cfg.ctx })).catch(e => {
|
||||
this.run(getTauriConfig({ ctx: cfg.ctx })).catch((e) => {
|
||||
throw e
|
||||
})
|
||||
} else {
|
||||
startDevTauri().catch(e => {
|
||||
startDevTauri().catch((e) => {
|
||||
throw e
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
warn(err)
|
||||
process.exit(1)
|
||||
})
|
||||
@ -248,10 +287,11 @@ class Runner {
|
||||
}
|
||||
|
||||
const cargoManifest = this.__getManifest()
|
||||
this.__allowlistApi(cfg, cargoManifest as unknown as CargoManifest)
|
||||
this.__allowlistApi(cfg, (cargoManifest as unknown) as CargoManifest)
|
||||
this.__rewriteManifest(cargoManifest)
|
||||
|
||||
const inlinedAssets = (await this.__parseHtml(cfg, cfg.build.distDir)).inlinedAssets
|
||||
const inlinedAssets = (await this.__parseHtml(cfg, cfg.build.distDir))
|
||||
.inlinedAssets
|
||||
process.env.TAURI_INLINED_ASSETS = inlinedAssets.join('|')
|
||||
|
||||
const features = [
|
||||
@ -264,11 +304,11 @@ class Runner {
|
||||
cfg.tauri.bundle.active ? 'tauri-bundler' : 'build',
|
||||
'--features',
|
||||
...features,
|
||||
...(
|
||||
cfg.tauri.bundle.active && Array.isArray(cfg.tauri.bundle.targets) && cfg.tauri.bundle.targets.length
|
||||
? ['--format'].concat(cfg.tauri.bundle.targets)
|
||||
: []
|
||||
)
|
||||
...(cfg.tauri.bundle.active &&
|
||||
Array.isArray(cfg.tauri.bundle.targets) &&
|
||||
cfg.tauri.bundle.targets.length
|
||||
? ['--format'].concat(cfg.tauri.bundle.targets)
|
||||
: [])
|
||||
]
|
||||
.concat(cfg.ctx.debug ? [] : ['--release'])
|
||||
.concat(cfg.verbose ? ['--verbose'] : [])
|
||||
@ -288,7 +328,11 @@ class Runner {
|
||||
}
|
||||
}
|
||||
|
||||
async __parseHtml(cfg: TauriConfig, indexDir: string, inlinerEnabled = cfg.tauri.inliner.active): Promise<{ inlinedAssets: string[], html: string }> {
|
||||
async __parseHtml(
|
||||
cfg: TauriConfig,
|
||||
indexDir: string,
|
||||
inlinerEnabled = cfg.tauri.inliner.active
|
||||
): Promise<{ inlinedAssets: string[]; html: string }> {
|
||||
const inlinedAssets: string[] = []
|
||||
|
||||
return await new Promise((resolve, reject) => {
|
||||
@ -301,17 +345,29 @@ class Runner {
|
||||
}
|
||||
const originalHtml = readFileSync(indexPath).toString()
|
||||
|
||||
const rewriteHtml = (html: string, interceptor?: (dom: JSDOM) => void): string => {
|
||||
const rewriteHtml = (
|
||||
html: string,
|
||||
interceptor?: (dom: JSDOM) => void
|
||||
): string => {
|
||||
const dom = new JSDOM(html)
|
||||
const document = dom.window.document
|
||||
if (interceptor !== undefined) {
|
||||
interceptor(dom)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
if (!((cfg.ctx.dev && cfg.build.devPath.startsWith('http')) || cfg.tauri.embeddedServer.active)) {
|
||||
if (
|
||||
!(
|
||||
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
||||
(
|
||||
(cfg.ctx.dev && cfg.build.devPath.startsWith('http')) ||
|
||||
cfg.tauri.embeddedServer.active
|
||||
)
|
||||
/* eslint-enable */
|
||||
)
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
|
||||
const mutationObserverTemplate = require('../templates/mutation-observer').default
|
||||
const mutationObserverTemplate = require('../templates/mutation-observer')
|
||||
.default
|
||||
const compiledMutationObserver = template(mutationObserverTemplate)
|
||||
|
||||
const bodyMutationObserverScript = document.createElement('script')
|
||||
@ -319,14 +375,20 @@ class Runner {
|
||||
target: 'body',
|
||||
inlinedAssets: JSON.stringify(inlinedAssets)
|
||||
})
|
||||
document.body.insertBefore(bodyMutationObserverScript, document.body.firstChild)
|
||||
document.body.insertBefore(
|
||||
bodyMutationObserverScript,
|
||||
document.body.firstChild
|
||||
)
|
||||
|
||||
const headMutationObserverScript = document.createElement('script')
|
||||
headMutationObserverScript.text = compiledMutationObserver({
|
||||
target: 'head',
|
||||
inlinedAssets: JSON.stringify(inlinedAssets)
|
||||
})
|
||||
document.head.insertBefore(headMutationObserverScript, document.head.firstChild)
|
||||
document.head.insertBefore(
|
||||
headMutationObserverScript,
|
||||
document.head.firstChild
|
||||
)
|
||||
}
|
||||
|
||||
const tauriScript = document.createElement('script')
|
||||
@ -350,40 +412,47 @@ class Runner {
|
||||
}
|
||||
|
||||
const newHtml = dom.serialize()
|
||||
writeFileSync(
|
||||
path.join(indexDir, 'index.tauri.html'),
|
||||
newHtml
|
||||
)
|
||||
writeFileSync(path.join(indexDir, 'index.tauri.html'), newHtml)
|
||||
return newHtml
|
||||
}
|
||||
|
||||
const domInterceptor = cfg.tauri.embeddedServer.active ? undefined : (dom: JSDOM) => {
|
||||
const document = dom.window.document
|
||||
if (!cfg.ctx.dev) {
|
||||
document.querySelectorAll('link').forEach((link: HTMLLinkElement) => {
|
||||
link.removeAttribute('rel')
|
||||
link.removeAttribute('as')
|
||||
})
|
||||
}
|
||||
}
|
||||
const domInterceptor = cfg.tauri.embeddedServer.active
|
||||
? undefined
|
||||
: (dom: JSDOM) => {
|
||||
const document = dom.window.document
|
||||
if (!cfg.ctx.dev) {
|
||||
document
|
||||
.querySelectorAll('link')
|
||||
.forEach((link: HTMLLinkElement) => {
|
||||
link.removeAttribute('rel')
|
||||
link.removeAttribute('as')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
if ((!cfg.ctx.dev && cfg.tauri.embeddedServer.active) || !inlinerEnabled) {
|
||||
if (
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
(!cfg.ctx.dev && cfg.tauri.embeddedServer.active) ||
|
||||
!inlinerEnabled
|
||||
) {
|
||||
const html = rewriteHtml(originalHtml, domInterceptor)
|
||||
resolve({ inlinedAssets, html })
|
||||
} else {
|
||||
const cwd = process.cwd()
|
||||
process.chdir(indexDir) // the inliner requires this to properly work
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
||||
const inliner = new Inliner({ source: originalHtml }, (err: Error, html: string) => {
|
||||
process.chdir(cwd) // reset CWD
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
const rewrittenHtml = rewriteHtml(html, domInterceptor)
|
||||
resolve({ inlinedAssets, html: rewrittenHtml })
|
||||
const inliner = new Inliner(
|
||||
{ source: originalHtml },
|
||||
(err: Error, html: string) => {
|
||||
process.chdir(cwd) // reset CWD
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
const rewrittenHtml = rewriteHtml(html, domInterceptor)
|
||||
resolve({ inlinedAssets, html: rewrittenHtml })
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
||||
inliner.on('progress', (event: string) => {
|
||||
const match = event.match(/([\S\d]+)\.([\S\d]+)/g)
|
||||
@ -397,9 +466,7 @@ class Runner {
|
||||
return await new Promise((resolve, reject) => {
|
||||
this.devServer?.close()
|
||||
this.tauriWatcher?.close().catch(reject)
|
||||
this.__stopCargo()
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
this.__stopCargo().then(resolve).catch(reject)
|
||||
})
|
||||
}
|
||||
|
||||
@ -445,7 +512,9 @@ class Runner {
|
||||
warn()
|
||||
warn('⚠️ [FAIL] Cargo CLI has failed')
|
||||
warn()
|
||||
reject(new Error('Cargo failed with status code ' + code.toString()))
|
||||
reject(
|
||||
new Error('Cargo failed with status code ' + code.toString())
|
||||
)
|
||||
process.exit(1)
|
||||
} else if (!dev) {
|
||||
resolve()
|
||||
@ -508,22 +577,20 @@ class Runner {
|
||||
}, WATCHER_INTERVAL * 2)
|
||||
}
|
||||
|
||||
__allowlistApi(
|
||||
cfg: TauriConfig,
|
||||
manifest: CargoManifest
|
||||
): void {
|
||||
__allowlistApi(cfg: TauriConfig, manifest: CargoManifest): void {
|
||||
const tomlFeatures = []
|
||||
|
||||
if (cfg.tauri.allowlist.all) {
|
||||
tomlFeatures.push('all-api')
|
||||
} else {
|
||||
const toKebabCase = (value: string): string => {
|
||||
return value.replace(/([a-z])([A-Z])/g, '$1-$2')
|
||||
return value
|
||||
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
||||
.replace(/\s+/g, '-')
|
||||
.toLowerCase()
|
||||
}
|
||||
const allowlist = Object.keys(cfg.tauri.allowlist).filter(
|
||||
w => cfg.tauri.allowlist[String(w)]
|
||||
(w) => cfg.tauri.allowlist[String(w)]
|
||||
)
|
||||
tomlFeatures.push(...allowlist.map(toKebabCase))
|
||||
}
|
||||
|
@ -14,7 +14,13 @@ export default {
|
||||
active: true,
|
||||
targets: 'all', // or an array of targets
|
||||
identifier: 'com.tauri.dev',
|
||||
icon: ['icons/32x32.png', 'icons/128x128.png', 'icons/128x128@2x.png', 'icons/icon.icns', 'icons/icon.ico'],
|
||||
icon: [
|
||||
'icons/32x32.png',
|
||||
'icons/128x128.png',
|
||||
'icons/128x128@2x.png',
|
||||
'icons/icon.icns',
|
||||
'icons/icon.ico'
|
||||
],
|
||||
resources: [],
|
||||
externalBin: [],
|
||||
copyright: '',
|
||||
@ -43,7 +49,8 @@ export default {
|
||||
fullscreen: false
|
||||
},
|
||||
security: {
|
||||
csp: "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"
|
||||
csp:
|
||||
"default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"
|
||||
},
|
||||
inliner: {
|
||||
active: true
|
||||
|
@ -34,7 +34,7 @@ const injectConfFile = (
|
||||
if (!force) return false
|
||||
} else {
|
||||
removeSync(path)
|
||||
Object.keys(defaultConfig).forEach(key => {
|
||||
Object.keys(defaultConfig).forEach((key) => {
|
||||
// Options marked `null` should be removed
|
||||
/* eslint-disable security/detect-object-injection */
|
||||
if ((customConfig as UnknownObject)[key] === null) {
|
||||
@ -45,7 +45,10 @@ const injectConfFile = (
|
||||
}
|
||||
/* eslint-enable security/detect-object-injection */
|
||||
})
|
||||
const finalConf = merge(defaultConfig as any, customConfig as any) as UnknownObject
|
||||
const finalConf = merge(
|
||||
defaultConfig as any,
|
||||
customConfig as any
|
||||
) as UnknownObject
|
||||
|
||||
writeFileSync(path, JSON.stringify(finalConf, undefined, 2))
|
||||
if (logging) log('Successfully wrote tauri.conf.json')
|
||||
@ -64,9 +67,10 @@ Run \`tauri init --force template\` to overwrite.`)
|
||||
}
|
||||
|
||||
const resolveTauriPath = (tauriPath: string): string => {
|
||||
const resolvedPath = tauriPath.startsWith('/') || /^\S:/g.test(tauriPath)
|
||||
? join(tauriPath, 'tauri') // we received a full path as argument
|
||||
: join('..', tauriPath, 'tauri') // we received a relative path
|
||||
const resolvedPath =
|
||||
tauriPath.startsWith('/') || /^\S:/g.test(tauriPath)
|
||||
? join(tauriPath, 'tauri') // we received a full path as argument
|
||||
: join('..', tauriPath, 'tauri') // we received a relative path
|
||||
return resolvedPath.replace(/\\/g, '/')
|
||||
}
|
||||
|
||||
@ -106,7 +110,11 @@ const inject = (
|
||||
injectTemplate(injectPath, { force, logging, tauriPath })
|
||||
}
|
||||
if (type === 'conf' || type === 'all') {
|
||||
injectConfFile(join(injectPath, 'src-tauri'), { force, logging }, customConfig)
|
||||
injectConfFile(
|
||||
join(injectPath, 'src-tauri'),
|
||||
{ force, logging },
|
||||
customConfig
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
export interface CargoManifest {
|
||||
dependencies: { [k: string]: string | CargoManifestDependency }
|
||||
package: { version: string, name: string, 'default-run': string }
|
||||
package: { version: string; name: string; 'default-run': string }
|
||||
bin: Array<{
|
||||
name: string
|
||||
path: string
|
||||
|
@ -1,13 +1,11 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"definitions": {
|
||||
"CliArg": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"description": "A CLI argument definition",
|
||||
"properties": {
|
||||
"conflictsWith": {
|
||||
@ -149,15 +147,12 @@
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"required": ["name"],
|
||||
"type": "object"
|
||||
},
|
||||
"CliConfig": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"description": "describes a CLI configuration",
|
||||
"properties": {
|
||||
"afterHelp": {
|
||||
@ -187,8 +182,7 @@
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/CliConfig"
|
||||
},
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"description": "list of subcommands of this command\n\nsubcommands are effectively sub-apps, because they can contain their own arguments, subcommands, usage, etc.\nthey also function just like the app command, in that they get their own auto generated help and usage",
|
||||
"type": "object"
|
||||
}
|
||||
@ -197,8 +191,7 @@
|
||||
},
|
||||
"TauriBuildConfig": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"properties": {
|
||||
"beforeBuildCommand": {
|
||||
"description": "a shell command to run before `tauri build` kicks in",
|
||||
@ -220,10 +213,7 @@
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"devPath",
|
||||
"distDir"
|
||||
],
|
||||
"required": ["devPath", "distDir"],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
@ -235,8 +225,7 @@
|
||||
},
|
||||
"ctx": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"description": "the context of the current `tauri dev` or `tauri build`",
|
||||
"properties": {
|
||||
"debug": {
|
||||
@ -264,42 +253,34 @@
|
||||
},
|
||||
"plugins": {
|
||||
"additionalProperties": {
|
||||
"additionalProperties": {
|
||||
},
|
||||
"defaultProperties": [
|
||||
],
|
||||
"additionalProperties": {},
|
||||
"defaultProperties": [],
|
||||
"type": "object"
|
||||
},
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"type": "object"
|
||||
},
|
||||
"tauri": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"description": "tauri root configuration object",
|
||||
"properties": {
|
||||
"allowlist": {
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"properties": {
|
||||
"all": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"all"
|
||||
],
|
||||
"required": ["all"],
|
||||
"type": "object"
|
||||
},
|
||||
"bundle": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"description": "tauri bundler configuration",
|
||||
"properties": {
|
||||
"active": {
|
||||
@ -314,8 +295,7 @@
|
||||
},
|
||||
"deb": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"properties": {
|
||||
"depends": {
|
||||
"items": {
|
||||
@ -354,8 +334,7 @@
|
||||
},
|
||||
"osx": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"properties": {
|
||||
"frameworks": {
|
||||
"items": {
|
||||
@ -400,10 +379,7 @@
|
||||
"description": "the bundle targets, currently supports [\"deb\", \"osx\", \"msi\", \"appimage\", \"dmg\"] or \"all\""
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"icon",
|
||||
"identifier"
|
||||
],
|
||||
"required": ["icon", "identifier"],
|
||||
"type": "object"
|
||||
},
|
||||
"cli": {
|
||||
@ -412,8 +388,7 @@
|
||||
},
|
||||
"embeddedServer": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"description": "the embedded server configuration",
|
||||
"properties": {
|
||||
"active": {
|
||||
@ -423,9 +398,7 @@
|
||||
"port": {
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": [
|
||||
"random"
|
||||
],
|
||||
"enum": ["random"],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
@ -439,8 +412,7 @@
|
||||
},
|
||||
"inliner": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"properties": {
|
||||
"active": {
|
||||
"type": "boolean"
|
||||
@ -450,8 +422,7 @@
|
||||
},
|
||||
"security": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"properties": {
|
||||
"csp": {
|
||||
"type": "string"
|
||||
@ -461,8 +432,7 @@
|
||||
},
|
||||
"window": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"defaultProperties": [],
|
||||
"properties": {
|
||||
"fullscreen": {
|
||||
"type": "boolean"
|
||||
@ -480,9 +450,7 @@
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title"
|
||||
],
|
||||
"required": ["title"],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
@ -501,10 +469,6 @@
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"build",
|
||||
"ctx",
|
||||
"tauri"
|
||||
],
|
||||
"required": ["build", "ctx", "tauri"],
|
||||
"type": "object"
|
||||
}
|
@ -1,533 +1,545 @@
|
||||
/* tslint:disable */
|
||||
// generated by typescript-json-validator
|
||||
import {inspect} from 'util';
|
||||
import Ajv from 'ajv';
|
||||
import TauriConfig from './config';
|
||||
export const ajv = new Ajv({"allErrors":true,"coerceTypes":false,"format":"fast","nullable":true,"unicode":true,"uniqueItems":true,"useDefaults":true});
|
||||
import { inspect } from 'util'
|
||||
import Ajv from 'ajv'
|
||||
import TauriConfig from './config'
|
||||
export const ajv = new Ajv({
|
||||
allErrors: true,
|
||||
coerceTypes: false,
|
||||
format: 'fast',
|
||||
nullable: true,
|
||||
unicode: true,
|
||||
uniqueItems: true,
|
||||
useDefaults: true
|
||||
})
|
||||
|
||||
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));
|
||||
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'))
|
||||
|
||||
export {TauriConfig};
|
||||
export { TauriConfig }
|
||||
export const TauriConfigSchema = {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"definitions": {
|
||||
"CliArg": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"description": "A CLI argument definition",
|
||||
"properties": {
|
||||
"conflictsWith": {
|
||||
"description": "sets a conflicting argument by name\ni.e. when using this argument, the following argument can't be present and vice versa",
|
||||
"type": "string"
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
definitions: {
|
||||
CliArg: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
description: 'A CLI argument definition',
|
||||
properties: {
|
||||
conflictsWith: {
|
||||
description:
|
||||
"sets a conflicting argument by name\ni.e. when using this argument, the following argument can't be present and vice versa",
|
||||
type: 'string'
|
||||
},
|
||||
"conflictsWithAll": {
|
||||
"description": "the same as conflictsWith but allows specifying multiple two-way conflicts per argument",
|
||||
"type": "string"
|
||||
conflictsWithAll: {
|
||||
description:
|
||||
'the same as conflictsWith but allows specifying multiple two-way conflicts per argument',
|
||||
type: 'string'
|
||||
},
|
||||
"description": {
|
||||
"description": "the argument description which will be shown on the help information\ntypically, this is a short (one line) description of the arg",
|
||||
"type": "string"
|
||||
description: {
|
||||
description:
|
||||
'the argument description which will be shown on the help information\ntypically, this is a short (one line) description of the arg',
|
||||
type: 'string'
|
||||
},
|
||||
"index": {
|
||||
"description": "The positional argument index, starting at 1.\n\nThe index refers to position according to other positional argument.\nIt does not define position in the argument list as a whole. When utilized with multiple=true,\nonly the last positional argument may be defined as multiple (i.e. the one with the highest index).",
|
||||
"type": "number"
|
||||
index: {
|
||||
description:
|
||||
'The positional argument index, starting at 1.\n\nThe index refers to position according to other positional argument.\nIt does not define position in the argument list as a whole. When utilized with multiple=true,\nonly the last positional argument may be defined as multiple (i.e. the one with the highest index).',
|
||||
type: 'number'
|
||||
},
|
||||
"longDescription": {
|
||||
"description": "the argument long description which will be shown on the help information\ntypically this a more detailed (multi-line) message that describes the argument",
|
||||
"type": "string"
|
||||
longDescription: {
|
||||
description:
|
||||
'the argument long description which will be shown on the help information\ntypically this a more detailed (multi-line) message that describes the argument',
|
||||
type: 'string'
|
||||
},
|
||||
"maxValues": {
|
||||
"description": "specifies the maximum number of values are for this argument.\nfor example, if you had a -f <file> argument where you wanted up to 3 'files' you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values.",
|
||||
"type": "number"
|
||||
maxValues: {
|
||||
description:
|
||||
"specifies the maximum number of values are for this argument.\nfor example, if you had a -f <file> argument where you wanted up to 3 'files' you would set .max_values(3), and this argument would be satisfied if the user provided, 1, 2, or 3 values.",
|
||||
type: 'number'
|
||||
},
|
||||
"minValues": {
|
||||
"description": "specifies the minimum number of values for this argument.\nfor example, if you had a -f <file> argument where you wanted at least 2 'files' you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values.",
|
||||
"type": "number"
|
||||
minValues: {
|
||||
description:
|
||||
"specifies the minimum number of values for this argument.\nfor example, if you had a -f <file> argument where you wanted at least 2 'files' you would set `minValues: 2`, and this argument would be satisfied if the user provided, 2 or more values.",
|
||||
type: 'number'
|
||||
},
|
||||
"multiple": {
|
||||
"description": "specifies that the argument may appear more than once.\nfor flags, this results in the number of occurrences of the flag being recorded. For example -ddd or -d -d -d would count as three occurrences.\nfor options there is a distinct difference in multiple occurrences vs multiple values. For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences.",
|
||||
"type": "boolean"
|
||||
multiple: {
|
||||
description:
|
||||
'specifies that the argument may appear more than once.\nfor flags, this results in the number of occurrences of the flag being recorded. For example -ddd or -d -d -d would count as three occurrences.\nfor options there is a distinct difference in multiple occurrences vs multiple values. For example, --opt val1 val2 is one occurrence, but two values. Whereas --opt val1 --opt val2 is two occurrences.',
|
||||
type: 'boolean'
|
||||
},
|
||||
"multipleOccurrences": {
|
||||
"description": "specifies that the argument may appear more than once.",
|
||||
"type": "boolean"
|
||||
multipleOccurrences: {
|
||||
description: 'specifies that the argument may appear more than once.',
|
||||
type: 'boolean'
|
||||
},
|
||||
"name": {
|
||||
"description": "the unique argument name",
|
||||
"type": "string"
|
||||
name: {
|
||||
description: 'the unique argument name',
|
||||
type: 'string'
|
||||
},
|
||||
"possibleValues": {
|
||||
"description": "specifies a list of possible values for this argument. At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
possibleValues: {
|
||||
description:
|
||||
'specifies a list of possible values for this argument. At runtime, the CLI verifies that only one of the specified values was used, or fails with an error message.',
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"requireEquals": {
|
||||
"description": "requires that options use the --option=val syntax\ni.e. an equals between the option and associated value",
|
||||
"type": "boolean"
|
||||
requireEquals: {
|
||||
description:
|
||||
'requires that options use the --option=val syntax\ni.e. an equals between the option and associated value',
|
||||
type: 'boolean'
|
||||
},
|
||||
"required": {
|
||||
"description": "sets whether or not the argument is required by default\nrequired by default means it is required, when no other conflicting rules have been evaluated\nconflicting rules take precedence over being required.",
|
||||
"type": "boolean"
|
||||
required: {
|
||||
description:
|
||||
'sets whether or not the argument is required by default\nrequired by default means it is required, when no other conflicting rules have been evaluated\nconflicting rules take precedence over being required.',
|
||||
type: 'boolean'
|
||||
},
|
||||
"requiredIf": {
|
||||
"additionalItems": {
|
||||
"anyOf": [
|
||||
requiredIf: {
|
||||
additionalItems: {
|
||||
anyOf: [
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "allows specifying that an argument is required conditionally with the signature [arg: string, value: string]\nthe requirement will only become valid if the `arg`'s value equals `${value}`.",
|
||||
"items": [
|
||||
description:
|
||||
"allows specifying that an argument is required conditionally with the signature [arg: string, value: string]\nthe requirement will only become valid if the `arg`'s value equals `${value}`.",
|
||||
items: [
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"type": "array"
|
||||
minItems: 2,
|
||||
type: 'array'
|
||||
},
|
||||
"requiredUnless": {
|
||||
"description": "sets an arg that override this arg's required setting\ni.e. this arg will be required unless this other argument is present",
|
||||
"type": "string"
|
||||
requiredUnless: {
|
||||
description:
|
||||
"sets an arg that override this arg's required setting\ni.e. this arg will be required unless this other argument is present",
|
||||
type: 'string'
|
||||
},
|
||||
"requiredUnlessAll": {
|
||||
"description": "sets args that override this arg's required setting\ni.e. this arg will be required unless all these other arguments are present",
|
||||
"items": {
|
||||
"type": "string"
|
||||
requiredUnlessAll: {
|
||||
description:
|
||||
"sets args that override this arg's required setting\ni.e. this arg will be required unless all these other arguments are present",
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"requiredUnlessOne": {
|
||||
"description": "sets args that override this arg's required setting\ni.e. this arg will be required unless at least one of these other arguments are present",
|
||||
"items": {
|
||||
"type": "string"
|
||||
requiredUnlessOne: {
|
||||
description:
|
||||
"sets args that override this arg's required setting\ni.e. this arg will be required unless at least one of these other arguments are present",
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"requires": {
|
||||
"description": "sets an argument by name that is required when this one is present\ni.e. when using this argument, the following argument must be present",
|
||||
"type": "string"
|
||||
requires: {
|
||||
description:
|
||||
'sets an argument by name that is required when this one is present\ni.e. when using this argument, the following argument must be present',
|
||||
type: 'string'
|
||||
},
|
||||
"requiresAll": {
|
||||
"description": "sets multiple arguments by names that are required when this one is present\ni.e. when using this argument, the following arguments must be present",
|
||||
"items": {
|
||||
"type": "string"
|
||||
requiresAll: {
|
||||
description:
|
||||
'sets multiple arguments by names that are required when this one is present\ni.e. when using this argument, the following arguments must be present',
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"requiresIf": {
|
||||
"additionalItems": {
|
||||
"anyOf": [
|
||||
requiresIf: {
|
||||
additionalItems: {
|
||||
anyOf: [
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "allows a conditional requirement with the signature [arg: string, value: string]\nthe requirement will only become valid if `arg`'s value equals `${value}`",
|
||||
"items": [
|
||||
description:
|
||||
"allows a conditional requirement with the signature [arg: string, value: string]\nthe requirement will only become valid if `arg`'s value equals `${value}`",
|
||||
items: [
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"type": "array"
|
||||
minItems: 2,
|
||||
type: 'array'
|
||||
},
|
||||
"short": {
|
||||
"description": "the short version of the argument, without the preceding -\nNOTE: Any leading - characters will be stripped, and only the first non - character will be used as the short version",
|
||||
"type": "string"
|
||||
short: {
|
||||
description:
|
||||
'the short version of the argument, without the preceding -\nNOTE: Any leading - characters will be stripped, and only the first non - character will be used as the short version',
|
||||
type: 'string'
|
||||
},
|
||||
"takesValue": {
|
||||
"description": "specifies that the argument takes a value at run time.\nNOTE: values for arguments may be specified in any of the following methods\n- Using a space such as -o value or --option value\n- Using an equals and no space such as -o=value or --option=value\n- Use a short and no space such as -ovalue",
|
||||
"type": "boolean"
|
||||
takesValue: {
|
||||
description:
|
||||
'specifies that the argument takes a value at run time.\nNOTE: values for arguments may be specified in any of the following methods\n- Using a space such as -o value or --option value\n- Using an equals and no space such as -o=value or --option=value\n- Use a short and no space such as -ovalue',
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"type": "object"
|
||||
required: ['name'],
|
||||
type: 'object'
|
||||
},
|
||||
"CliConfig": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"description": "describes a CLI configuration",
|
||||
"properties": {
|
||||
"afterHelp": {
|
||||
"description": "adds additional help information to be displayed in addition to auto-generated help\nthis information is displayed after the auto-generated help information\nthis is often used to describe how to use the arguments, or caveats to be noted.",
|
||||
"type": "string"
|
||||
CliConfig: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
description: 'describes a CLI configuration',
|
||||
properties: {
|
||||
afterHelp: {
|
||||
description:
|
||||
'adds additional help information to be displayed in addition to auto-generated help\nthis information is displayed after the auto-generated help information\nthis is often used to describe how to use the arguments, or caveats to be noted.',
|
||||
type: 'string'
|
||||
},
|
||||
"args": {
|
||||
"description": "list of args for the command",
|
||||
"items": {
|
||||
"$ref": "#/definitions/CliArg"
|
||||
args: {
|
||||
description: 'list of args for the command',
|
||||
items: {
|
||||
$ref: '#/definitions/CliArg'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"beforeHelp": {
|
||||
"description": "adds additional help information to be displayed in addition to auto-generated help\nthis information is displayed before the auto-generated help information.\nthis is often used for header information",
|
||||
"type": "string"
|
||||
beforeHelp: {
|
||||
description:
|
||||
'adds additional help information to be displayed in addition to auto-generated help\nthis information is displayed before the auto-generated help information.\nthis is often used for header information',
|
||||
type: 'string'
|
||||
},
|
||||
"description": {
|
||||
"description": "command description which will be shown on the help information",
|
||||
"type": "string"
|
||||
description: {
|
||||
description:
|
||||
'command description which will be shown on the help information',
|
||||
type: 'string'
|
||||
},
|
||||
"longDescription": {
|
||||
"description": "command long description which will be shown on the help information",
|
||||
"type": "string"
|
||||
longDescription: {
|
||||
description:
|
||||
'command long description which will be shown on the help information',
|
||||
type: 'string'
|
||||
},
|
||||
"subcommands": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/CliConfig"
|
||||
subcommands: {
|
||||
additionalProperties: {
|
||||
$ref: '#/definitions/CliConfig'
|
||||
},
|
||||
"defaultProperties": [
|
||||
],
|
||||
"description": "list of subcommands of this command\n\nsubcommands are effectively sub-apps, because they can contain their own arguments, subcommands, usage, etc.\nthey also function just like the app command, in that they get their own auto generated help and usage",
|
||||
"type": "object"
|
||||
defaultProperties: [],
|
||||
description:
|
||||
'list of subcommands of this command\n\nsubcommands are effectively sub-apps, because they can contain their own arguments, subcommands, usage, etc.\nthey also function just like the app command, in that they get their own auto generated help and usage',
|
||||
type: 'object'
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
type: 'object'
|
||||
},
|
||||
"TauriBuildConfig": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"properties": {
|
||||
"beforeBuildCommand": {
|
||||
"description": "a shell command to run before `tauri build` kicks in",
|
||||
"type": "string"
|
||||
TauriBuildConfig: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
properties: {
|
||||
beforeBuildCommand: {
|
||||
description: 'a shell command to run before `tauri build` kicks in',
|
||||
type: 'string'
|
||||
},
|
||||
"beforeDevCommand": {
|
||||
"description": "a shell command to run before `tauri dev` kicks in",
|
||||
"type": "string"
|
||||
beforeDevCommand: {
|
||||
description: 'a shell command to run before `tauri dev` kicks in',
|
||||
type: 'string'
|
||||
},
|
||||
"devPath": {
|
||||
"description": "the app's dev server URL, or the path to the directory containing an index.html to open",
|
||||
"type": "string"
|
||||
devPath: {
|
||||
description:
|
||||
"the app's dev server URL, or the path to the directory containing an index.html to open",
|
||||
type: 'string'
|
||||
},
|
||||
"distDir": {
|
||||
"description": "the path to the app's dist dir\nthis path must contain your index.html file",
|
||||
"type": "string"
|
||||
distDir: {
|
||||
description:
|
||||
"the path to the app's dist dir\nthis path must contain your index.html file",
|
||||
type: 'string'
|
||||
},
|
||||
"withGlobalTauri": {
|
||||
"type": "boolean"
|
||||
withGlobalTauri: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"devPath",
|
||||
"distDir"
|
||||
],
|
||||
"type": "object"
|
||||
required: ['devPath', 'distDir'],
|
||||
type: 'object'
|
||||
}
|
||||
},
|
||||
"description": "Tauri configuration",
|
||||
"properties": {
|
||||
"build": {
|
||||
"$ref": "#/definitions/TauriBuildConfig",
|
||||
"description": "build/dev configuration"
|
||||
description: 'Tauri configuration',
|
||||
properties: {
|
||||
build: {
|
||||
$ref: '#/definitions/TauriBuildConfig',
|
||||
description: 'build/dev configuration'
|
||||
},
|
||||
"ctx": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"description": "the context of the current `tauri dev` or `tauri build`",
|
||||
"properties": {
|
||||
"debug": {
|
||||
"description": "whether the app should be built on debug mode or not",
|
||||
"type": "boolean"
|
||||
ctx: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
description: 'the context of the current `tauri dev` or `tauri build`',
|
||||
properties: {
|
||||
debug: {
|
||||
description: 'whether the app should be built on debug mode or not',
|
||||
type: 'boolean'
|
||||
},
|
||||
"dev": {
|
||||
"description": "whether we're running on the dev environment or not",
|
||||
"type": "boolean"
|
||||
dev: {
|
||||
description: "whether we're running on the dev environment or not",
|
||||
type: 'boolean'
|
||||
},
|
||||
"exitOnPanic": {
|
||||
"description": "defines we should exit the `tauri dev` process if a Rust code error is found",
|
||||
"type": "boolean"
|
||||
exitOnPanic: {
|
||||
description:
|
||||
'defines we should exit the `tauri dev` process if a Rust code error is found',
|
||||
type: 'boolean'
|
||||
},
|
||||
"prod": {
|
||||
"description": "whether we're building for production or not",
|
||||
"type": "boolean"
|
||||
prod: {
|
||||
description: "whether we're building for production or not",
|
||||
type: 'boolean'
|
||||
},
|
||||
"target": {
|
||||
"description": "the target of the compilation (see `rustup target list`)",
|
||||
"type": "string"
|
||||
target: {
|
||||
description:
|
||||
'the target of the compilation (see `rustup target list`)',
|
||||
type: 'string'
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
type: 'object'
|
||||
},
|
||||
"plugins": {
|
||||
"additionalProperties": {
|
||||
"additionalProperties": {
|
||||
},
|
||||
"defaultProperties": [
|
||||
],
|
||||
"type": "object"
|
||||
plugins: {
|
||||
additionalProperties: {
|
||||
additionalProperties: {},
|
||||
defaultProperties: [],
|
||||
type: 'object'
|
||||
},
|
||||
"defaultProperties": [
|
||||
],
|
||||
"type": "object"
|
||||
defaultProperties: [],
|
||||
type: 'object'
|
||||
},
|
||||
"tauri": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"description": "tauri root configuration object",
|
||||
"properties": {
|
||||
"allowlist": {
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
tauri: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
description: 'tauri root configuration object',
|
||||
properties: {
|
||||
allowlist: {
|
||||
additionalProperties: {
|
||||
type: 'boolean'
|
||||
},
|
||||
"defaultProperties": [
|
||||
],
|
||||
"properties": {
|
||||
"all": {
|
||||
"type": "boolean"
|
||||
defaultProperties: [],
|
||||
properties: {
|
||||
all: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"all"
|
||||
],
|
||||
"type": "object"
|
||||
required: ['all'],
|
||||
type: 'object'
|
||||
},
|
||||
"bundle": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"description": "tauri bundler configuration",
|
||||
"properties": {
|
||||
"active": {
|
||||
"description": "whether we should build your app with tauri-bundler or plain `cargo build`",
|
||||
"type": "boolean"
|
||||
bundle: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
description: 'tauri bundler configuration',
|
||||
properties: {
|
||||
active: {
|
||||
description:
|
||||
'whether we should build your app with tauri-bundler or plain `cargo build`',
|
||||
type: 'boolean'
|
||||
},
|
||||
"category": {
|
||||
"type": "string"
|
||||
category: {
|
||||
type: 'string'
|
||||
},
|
||||
"copyright": {
|
||||
"type": "string"
|
||||
copyright: {
|
||||
type: 'string'
|
||||
},
|
||||
"deb": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"properties": {
|
||||
"depends": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
deb: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
properties: {
|
||||
depends: {
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"useBootstrapper": {
|
||||
"type": "boolean"
|
||||
useBootstrapper: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
type: 'object'
|
||||
},
|
||||
"exceptionDomain": {
|
||||
"type": "string"
|
||||
exceptionDomain: {
|
||||
type: 'string'
|
||||
},
|
||||
"externalBin": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
externalBin: {
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"icon": {
|
||||
"description": "the app's icons",
|
||||
"items": {
|
||||
"type": "string"
|
||||
icon: {
|
||||
description: "the app's icons",
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"identifier": {
|
||||
"description": "the app's identifier",
|
||||
"type": "string"
|
||||
identifier: {
|
||||
description: "the app's identifier",
|
||||
type: 'string'
|
||||
},
|
||||
"longDescription": {
|
||||
"type": "string"
|
||||
longDescription: {
|
||||
type: 'string'
|
||||
},
|
||||
"osx": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"properties": {
|
||||
"frameworks": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
osx: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
properties: {
|
||||
frameworks: {
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"license": {
|
||||
"type": "string"
|
||||
license: {
|
||||
type: 'string'
|
||||
},
|
||||
"minimumSystemVersion": {
|
||||
"type": "string"
|
||||
minimumSystemVersion: {
|
||||
type: 'string'
|
||||
},
|
||||
"useBootstrapper": {
|
||||
"type": "boolean"
|
||||
useBootstrapper: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
type: 'object'
|
||||
},
|
||||
"resources": {
|
||||
"description": "app resources to bundle\neach resource is a path to a file or directory\nglob patterns are supported",
|
||||
"items": {
|
||||
"type": "string"
|
||||
resources: {
|
||||
description:
|
||||
'app resources to bundle\neach resource is a path to a file or directory\nglob patterns are supported',
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
"shortDescription": {
|
||||
"type": "string"
|
||||
shortDescription: {
|
||||
type: 'string'
|
||||
},
|
||||
"targets": {
|
||||
"anyOf": [
|
||||
targets: {
|
||||
anyOf: [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
"type": "array"
|
||||
type: 'array'
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
"description": "the bundle targets, currently supports [\"deb\", \"osx\", \"msi\", \"appimage\", \"dmg\"] or \"all\""
|
||||
description:
|
||||
'the bundle targets, currently supports ["deb", "osx", "msi", "appimage", "dmg"] or "all"'
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"icon",
|
||||
"identifier"
|
||||
],
|
||||
"type": "object"
|
||||
required: ['icon', 'identifier'],
|
||||
type: 'object'
|
||||
},
|
||||
"cli": {
|
||||
"$ref": "#/definitions/CliConfig",
|
||||
"description": "app's CLI definition"
|
||||
cli: {
|
||||
$ref: '#/definitions/CliConfig',
|
||||
description: "app's CLI definition"
|
||||
},
|
||||
"embeddedServer": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"description": "the embedded server configuration",
|
||||
"properties": {
|
||||
"active": {
|
||||
"description": "whether we should use the embedded-server or the no-server mode",
|
||||
"type": "boolean"
|
||||
embeddedServer: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
description: 'the embedded server configuration',
|
||||
properties: {
|
||||
active: {
|
||||
description:
|
||||
'whether we should use the embedded-server or the no-server mode',
|
||||
type: 'boolean'
|
||||
},
|
||||
"port": {
|
||||
"anyOf": [
|
||||
port: {
|
||||
anyOf: [
|
||||
{
|
||||
"enum": [
|
||||
"random"
|
||||
],
|
||||
"type": "string"
|
||||
enum: ['random'],
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
type: 'number'
|
||||
}
|
||||
],
|
||||
"description": "the embedded server port number or the 'random' string to generate one at runtime"
|
||||
description:
|
||||
"the embedded server port number or the 'random' string to generate one at runtime"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
type: 'object'
|
||||
},
|
||||
"inliner": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"properties": {
|
||||
"active": {
|
||||
"type": "boolean"
|
||||
inliner: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
properties: {
|
||||
active: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
type: 'object'
|
||||
},
|
||||
"security": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"properties": {
|
||||
"csp": {
|
||||
"type": "string"
|
||||
security: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
properties: {
|
||||
csp: {
|
||||
type: 'string'
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
type: 'object'
|
||||
},
|
||||
"window": {
|
||||
"additionalProperties": false,
|
||||
"defaultProperties": [
|
||||
],
|
||||
"properties": {
|
||||
"fullscreen": {
|
||||
"type": "boolean"
|
||||
window: {
|
||||
additionalProperties: false,
|
||||
defaultProperties: [],
|
||||
properties: {
|
||||
fullscreen: {
|
||||
type: 'boolean'
|
||||
},
|
||||
"height": {
|
||||
"type": "number"
|
||||
height: {
|
||||
type: 'number'
|
||||
},
|
||||
"resizable": {
|
||||
"type": "boolean"
|
||||
resizable: {
|
||||
type: 'boolean'
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
title: {
|
||||
type: 'string'
|
||||
},
|
||||
"width": {
|
||||
"type": "number"
|
||||
width: {
|
||||
type: 'number'
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title"
|
||||
],
|
||||
"type": "object"
|
||||
required: ['title'],
|
||||
type: 'object'
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"allowlist",
|
||||
"bundle",
|
||||
"embeddedServer",
|
||||
"inliner",
|
||||
"security",
|
||||
"window"
|
||||
required: [
|
||||
'allowlist',
|
||||
'bundle',
|
||||
'embeddedServer',
|
||||
'inliner',
|
||||
'security',
|
||||
'window'
|
||||
],
|
||||
"type": "object"
|
||||
type: 'object'
|
||||
},
|
||||
"verbose": {
|
||||
"description": "Whether or not to enable verbose logging",
|
||||
"type": "boolean"
|
||||
verbose: {
|
||||
description: 'Whether or not to enable verbose logging',
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"build",
|
||||
"ctx",
|
||||
"tauri"
|
||||
],
|
||||
"type": "object"
|
||||
};
|
||||
export type ValidateFunction<T> = ((data: unknown) => data is T) & Pick<Ajv.ValidateFunction, 'errors'>
|
||||
export const isTauriConfig = ajv.compile(TauriConfigSchema) as ValidateFunction<TauriConfig>;
|
||||
required: ['build', 'ctx', 'tauri'],
|
||||
type: 'object'
|
||||
}
|
||||
export type ValidateFunction<T> = ((data: unknown) => data is T) &
|
||||
Pick<Ajv.ValidateFunction, 'errors'>
|
||||
export const isTauriConfig = ajv.compile(TauriConfigSchema) as ValidateFunction<
|
||||
TauriConfig
|
||||
>
|
||||
export default function validate(value: unknown): TauriConfig {
|
||||
if (isTauriConfig(value)) {
|
||||
return value;
|
||||
return value
|
||||
} else {
|
||||
throw new Error(
|
||||
ajv.errorsText(isTauriConfig.errors!.filter((e: any) => e.keyword !== 'if'), {dataVar: 'TauriConfig'}) +
|
||||
'\n\n' +
|
||||
inspect(value),
|
||||
);
|
||||
ajv.errorsText(
|
||||
isTauriConfig.errors!.filter((e: any) => e.keyword !== 'if'),
|
||||
{ dataVar: 'TauriConfig' }
|
||||
) +
|
||||
'\n\n' +
|
||||
inspect(value)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import logo from './logo.svg';
|
||||
import tauriCircles from './tauri.svg';
|
||||
import tauriWord from './wordmark.svg';
|
||||
import './App.css';
|
||||
import React from 'react'
|
||||
import logo from './logo.svg'
|
||||
import tauriCircles from './tauri.svg'
|
||||
import tauriWord from './wordmark.svg'
|
||||
import './App.css'
|
||||
|
||||
function App() {
|
||||
return (
|
||||
@ -17,7 +17,7 @@ function App() {
|
||||
href="https://tauri.studio"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
>
|
||||
Learn Tauri
|
||||
</a>
|
||||
<img src={logo} className="App-logo rotate" alt="logo" />
|
||||
@ -34,7 +34,7 @@ function App() {
|
||||
</p>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
@ -6,7 +6,7 @@ if (!String.prototype.startsWith) {
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
;(function () {
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
@ -14,38 +14,58 @@ if (!String.prototype.startsWith) {
|
||||
}
|
||||
|
||||
var uid = function () {
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4()
|
||||
return (
|
||||
s4() +
|
||||
s4() +
|
||||
'-' +
|
||||
s4() +
|
||||
'-' +
|
||||
s4() +
|
||||
'-' +
|
||||
s4() +
|
||||
'-' +
|
||||
s4() +
|
||||
s4() +
|
||||
s4()
|
||||
)
|
||||
}
|
||||
|
||||
function ownKeys(object, enumerableOnly) {
|
||||
var keys = Object.keys(object);
|
||||
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);
|
||||
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;
|
||||
return keys
|
||||
}
|
||||
|
||||
function _objectSpread(target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i] != null ? arguments[i] : {};
|
||||
var source = arguments[i] != null ? arguments[i] : {}
|
||||
if (i % 2) {
|
||||
ownKeys(source, true).forEach(function (key) {
|
||||
_defineProperty(target, key, source[key]);
|
||||
});
|
||||
_defineProperty(target, key, source[key])
|
||||
})
|
||||
} else if (Object.getOwnPropertyDescriptors) {
|
||||
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
||||
Object.defineProperties(
|
||||
target,
|
||||
Object.getOwnPropertyDescriptors(source)
|
||||
)
|
||||
} else {
|
||||
ownKeys(source).forEach(function (key) {
|
||||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
||||
});
|
||||
Object.defineProperty(
|
||||
target,
|
||||
key,
|
||||
Object.getOwnPropertyDescriptor(source, key)
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
return target;
|
||||
return target
|
||||
}
|
||||
|
||||
function _defineProperty(obj, key, value) {
|
||||
@ -55,18 +75,21 @@ if (!String.prototype.startsWith) {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
})
|
||||
} else {
|
||||
obj[key] = value;
|
||||
obj[key] = value
|
||||
}
|
||||
return obj;
|
||||
return obj
|
||||
}
|
||||
|
||||
if (!window.__TAURI__) {
|
||||
window.__TAURI__ = {}
|
||||
}
|
||||
|
||||
window.__TAURI__.transformCallback = function transformCallback(callback, once) {
|
||||
window.__TAURI__.transformCallback = function transformCallback(
|
||||
callback,
|
||||
once
|
||||
) {
|
||||
var identifier = uid()
|
||||
|
||||
window[identifier] = function (result) {
|
||||
@ -77,7 +100,7 @@ if (!String.prototype.startsWith) {
|
||||
return callback && callback(result)
|
||||
}
|
||||
|
||||
return identifier;
|
||||
return identifier
|
||||
}
|
||||
|
||||
window.__TAURI__.promisified = function promisified(args) {
|
||||
@ -93,10 +116,15 @@ if (!String.prototype.startsWith) {
|
||||
delete window[callback]
|
||||
}, true)
|
||||
|
||||
window.__TAURI_INVOKE_HANDLER__(_objectSpread({
|
||||
callback: callback,
|
||||
error: error
|
||||
}, args))
|
||||
window.__TAURI_INVOKE_HANDLER__(
|
||||
_objectSpread(
|
||||
{
|
||||
callback: callback,
|
||||
error: error
|
||||
},
|
||||
args
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@ -108,46 +136,70 @@ if (!String.prototype.startsWith) {
|
||||
})
|
||||
}
|
||||
|
||||
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) {
|
||||
document.addEventListener(
|
||||
'error',
|
||||
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_INVOKE_HANDLER__({
|
||||
cmd: 'open',
|
||||
uri: target.href
|
||||
})
|
||||
e.preventDefault()
|
||||
}
|
||||
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)
|
||||
},
|
||||
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_INVOKE_HANDLER__({
|
||||
cmd: 'open',
|
||||
uri: target.href
|
||||
})
|
||||
e.preventDefault()
|
||||
}
|
||||
break
|
||||
}
|
||||
target = target.parentElement
|
||||
}
|
||||
},
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||
if (
|
||||
document.readyState === 'complete' ||
|
||||
document.readyState === 'interactive'
|
||||
) {
|
||||
__openLinks()
|
||||
} else {
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
__openLinks()
|
||||
}, true)
|
||||
window.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
function () {
|
||||
__openLinks()
|
||||
},
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
let permissionSettable = false
|
||||
@ -169,12 +221,14 @@ if (!String.prototype.startsWith) {
|
||||
}
|
||||
|
||||
function requestPermission() {
|
||||
return window.__TAURI__.promisified({
|
||||
cmd: 'requestNotificationPermission'
|
||||
}).then(function (permission) {
|
||||
setNotificationPermission(permission)
|
||||
return permission
|
||||
})
|
||||
return window.__TAURI__
|
||||
.promisified({
|
||||
cmd: 'requestNotificationPermission'
|
||||
})
|
||||
.then(function (permission) {
|
||||
setNotificationPermission(permission)
|
||||
return permission
|
||||
})
|
||||
}
|
||||
|
||||
function sendNotification(options) {
|
||||
@ -182,24 +236,28 @@ if (!String.prototype.startsWith) {
|
||||
Object.freeze(options)
|
||||
}
|
||||
|
||||
isPermissionGranted()
|
||||
.then(function (permission) {
|
||||
if (permission) {
|
||||
return window.__TAURI__.promisified({
|
||||
cmd: 'notification',
|
||||
options: typeof options === 'string' ? {
|
||||
title: options
|
||||
} : options
|
||||
})
|
||||
}
|
||||
})
|
||||
isPermissionGranted().then(function (permission) {
|
||||
if (permission) {
|
||||
return window.__TAURI__.promisified({
|
||||
cmd: 'notification',
|
||||
options:
|
||||
typeof options === 'string'
|
||||
? {
|
||||
title: options
|
||||
}
|
||||
: options
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
window.Notification = function (title, options) {
|
||||
var opts = options || {}
|
||||
sendNotification(Object.assign(opts, {
|
||||
title: title
|
||||
}))
|
||||
sendNotification(
|
||||
Object.assign(opts, {
|
||||
title: title
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
window.Notification.requestPermission = requestPermission
|
||||
@ -217,14 +275,13 @@ if (!String.prototype.startsWith) {
|
||||
}
|
||||
})
|
||||
|
||||
isPermissionGranted()
|
||||
.then(function (response) {
|
||||
if (response === null) {
|
||||
setNotificationPermission('default')
|
||||
} else {
|
||||
setNotificationPermission(response ? 'granted' : 'denied')
|
||||
}
|
||||
})
|
||||
isPermissionGranted().then(function (response) {
|
||||
if (response === null) {
|
||||
setNotificationPermission('default')
|
||||
} else {
|
||||
setNotificationPermission(response ? 'granted' : 'denied')
|
||||
}
|
||||
})
|
||||
|
||||
window.alert = function (message) {
|
||||
window.__TAURI_INVOKE_HANDLER__({
|
||||
|
@ -23,10 +23,18 @@ function runBuildTest(tauriConfig) {
|
||||
await result.promise
|
||||
|
||||
const artifactFolder = tauriConfig.ctx.debug ? 'debug' : 'release'
|
||||
const artifactPath = path.resolve(appDir, `src-tauri/target/${artifactFolder}/app`)
|
||||
const artifactPath = path.resolve(
|
||||
appDir,
|
||||
`src-tauri/target/${artifactFolder}/app`
|
||||
)
|
||||
|
||||
const appPid = spawn(
|
||||
process.platform === 'win32' ? `${artifactPath}.exe` : artifactPath.replace(`${artifactFolder}/app`, `${artifactFolder}/./app`),
|
||||
process.platform === 'win32'
|
||||
? `${artifactPath}.exe`
|
||||
: artifactPath.replace(
|
||||
`${artifactFolder}/app`,
|
||||
`${artifactFolder}/./app`
|
||||
),
|
||||
[],
|
||||
null
|
||||
)
|
||||
@ -37,7 +45,9 @@ function runBuildTest(tauriConfig) {
|
||||
try {
|
||||
process.kill(appPid)
|
||||
} catch {}
|
||||
const failedCommands = Object.keys(responses).filter(k => responses[k] === null).join(', ')
|
||||
const failedCommands = Object.keys(responses)
|
||||
.filter((k) => responses[k] === null)
|
||||
.join(', ')
|
||||
reject("App didn't reply to " + failedCommands)
|
||||
})
|
||||
}
|
||||
@ -55,11 +65,11 @@ describe('Tauri Build', () => {
|
||||
}
|
||||
|
||||
it.each`
|
||||
mode | flag
|
||||
${'embedded-server'} | ${'debug'}
|
||||
${'embedded-server'} | ${'release'}
|
||||
${'no-server'} | ${'debug'}
|
||||
${'no-server'} | ${'release'}
|
||||
mode | flag
|
||||
${'embedded-server'} | ${'debug'}
|
||||
${'embedded-server'} | ${'release'}
|
||||
${'no-server'} | ${'debug'}
|
||||
${'no-server'} | ${'release'}
|
||||
`('works with the $mode $flag mode', ({ mode, flag }) => {
|
||||
return runBuildTest({
|
||||
build,
|
||||
|
@ -3,29 +3,29 @@ const fixtureSetup = require('../fixtures/app-test-setup')
|
||||
const distDir = path.resolve(fixtureSetup.fixtureDir, 'app', 'dist')
|
||||
|
||||
function startDevServer() {
|
||||
const http = require('http')
|
||||
const { statSync, createReadStream } = require('fs')
|
||||
const app = http.createServer((req, res) => {
|
||||
if (req.method === 'GET') {
|
||||
if (req.url === '/') {
|
||||
const indexPath = path.join(distDir, 'index.html')
|
||||
const stat = statSync(indexPath)
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/html',
|
||||
'Content-Length': stat.size
|
||||
})
|
||||
createReadStream(indexPath).pipe(res)
|
||||
}
|
||||
const http = require('http')
|
||||
const { statSync, createReadStream } = require('fs')
|
||||
const app = http.createServer((req, res) => {
|
||||
if (req.method === 'GET') {
|
||||
if (req.url === '/') {
|
||||
const indexPath = path.join(distDir, 'index.html')
|
||||
const stat = statSync(indexPath)
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/html',
|
||||
'Content-Length': stat.size
|
||||
})
|
||||
createReadStream(indexPath).pipe(res)
|
||||
}
|
||||
})
|
||||
|
||||
const port = 7001
|
||||
|
||||
const server = app.listen(port)
|
||||
return {
|
||||
server,
|
||||
url: `http://localhost:${port}`
|
||||
}
|
||||
})
|
||||
|
||||
const port = 7001
|
||||
|
||||
const server = app.listen(port)
|
||||
return {
|
||||
server,
|
||||
url: `http://localhost:${port}`
|
||||
}
|
||||
}
|
||||
|
||||
function runDevTest(tauriConfig) {
|
||||
@ -39,7 +39,9 @@ function runDevTest(tauriConfig) {
|
||||
let success = false
|
||||
const checkIntervalId = setInterval(async () => {
|
||||
if (!isRunning(runner.pid) && !success) {
|
||||
const failedCommands = Object.keys(responses).filter(k => responses[k] === null).join(', ')
|
||||
const failedCommands = Object.keys(responses)
|
||||
.filter((k) => responses[k] === null)
|
||||
.join(', ')
|
||||
server.close(() => reject("App didn't reply to " + failedCommands))
|
||||
}
|
||||
}, 2000)
|
||||
|
@ -20,7 +20,9 @@ describe('[CLI] tauri.js', () => {
|
||||
it('will not run an unavailable command', async () => {
|
||||
jest.spyOn(console, 'log')
|
||||
tauri('foo')
|
||||
expect(console.log.mock.calls[0][0].split('.')[0]).toBe('Invalid command foo')
|
||||
expect(console.log.mock.calls[0][0].split('.')[0]).toBe(
|
||||
'Invalid command foo'
|
||||
)
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
@ -28,9 +30,11 @@ describe('[CLI] tauri.js', () => {
|
||||
jest.spyOn(console, 'log')
|
||||
jest.mock('fs')
|
||||
try {
|
||||
tauri('init')
|
||||
tauri('init')
|
||||
} catch {}
|
||||
expect(console.log.mock.calls[0][0].split('.')[0]).toBe('[tauri]: running init')
|
||||
expect(console.log.mock.calls[0][0].split('.')[0]).toBe(
|
||||
'[tauri]: running init'
|
||||
)
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
it('gets you help', async () => {
|
||||
|
@ -11,25 +11,38 @@ describe('[CLI] tauri-icon internals', () => {
|
||||
|
||||
it('will not validate a non-file', async () => {
|
||||
jest.spyOn(process, 'exit').mockImplementation(() => true)
|
||||
await tauricon.validate('test/jest/fixtures/doesnotexist.png', 'test/jest/fixtures/')
|
||||
await tauricon.validate(
|
||||
'test/jest/fixtures/doesnotexist.png',
|
||||
'test/jest/fixtures/'
|
||||
)
|
||||
expect(process.exit.mock.calls[0][0]).toBe(1)
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
it('will not validate a non-png', async () => {
|
||||
jest.spyOn(process, 'exit').mockImplementation(() => true)
|
||||
await tauricon.validate('test/jest/fixtures/notAMeme.jpg', 'test/jest/fixtures/')
|
||||
await tauricon.validate(
|
||||
'test/jest/fixtures/notAMeme.jpg',
|
||||
'test/jest/fixtures/'
|
||||
)
|
||||
expect(process.exit.mock.calls[0][0]).toBe(1)
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
it('can validate an image as PNG', async () => {
|
||||
const valid = await tauricon.validate('test/jest/fixtures/tauri-logo.png', 'test/jest/fixtures/')
|
||||
const valid = await tauricon.validate(
|
||||
'test/jest/fixtures/tauri-logo.png',
|
||||
'test/jest/fixtures/'
|
||||
)
|
||||
expect(valid).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('[CLI] tauri-icon builder', () => {
|
||||
it('will still use default compression if missing compression chosen', async () => {
|
||||
const valid = await tauricon.make('test/jest/fixtures/tauri-logo.png', 'test/jest/tmp/missing', 'missing')
|
||||
const valid = await tauricon.make(
|
||||
'test/jest/fixtures/tauri-logo.png',
|
||||
'test/jest/tmp/missing',
|
||||
'missing'
|
||||
)
|
||||
expect(valid).toBe(true)
|
||||
})
|
||||
})
|
||||
@ -37,7 +50,11 @@ describe('[CLI] tauri-icon builder', () => {
|
||||
describe('[CLI] tauri-icon builder', () => {
|
||||
it('will not validate a non-file', async () => {
|
||||
try {
|
||||
await tauricon.make('test/jest/fixtures/tauri-foo-not-found.png', 'test/jest/tmp/pngquant', 'pngquant')
|
||||
await tauricon.make(
|
||||
'test/jest/fixtures/tauri-foo-not-found.png',
|
||||
'test/jest/tmp/pngquant',
|
||||
'pngquant'
|
||||
)
|
||||
} catch (e) {
|
||||
expect(e.message).toBe('Input file is missing')
|
||||
}
|
||||
@ -46,12 +63,20 @@ describe('[CLI] tauri-icon builder', () => {
|
||||
|
||||
describe('[CLI] tauri-icon builder', () => {
|
||||
it('makes a set of icons with pngquant', async () => {
|
||||
const valid = await tauricon.make('test/jest/fixtures/tauri-logo.png', 'test/jest/tmp/pngquant', 'pngquant')
|
||||
const valid = await tauricon.make(
|
||||
'test/jest/fixtures/tauri-logo.png',
|
||||
'test/jest/tmp/pngquant',
|
||||
'pngquant'
|
||||
)
|
||||
expect(valid).toBe(true)
|
||||
})
|
||||
|
||||
it('makes a set of icons with optipng', async () => {
|
||||
const valid = await tauricon.make('test/jest/fixtures/tauri-logo.png', 'test/jest/tmp/optipng', 'optipng')
|
||||
const valid = await tauricon.make(
|
||||
'test/jest/fixtures/tauri-logo.png',
|
||||
'test/jest/tmp/optipng',
|
||||
'optipng'
|
||||
)
|
||||
expect(valid).toBe(true)
|
||||
})
|
||||
|
||||
|
@ -1,11 +1,6 @@
|
||||
const fixtureSetup = require('../fixtures/app-test-setup')
|
||||
const {
|
||||
resolve
|
||||
} = require('path')
|
||||
const {
|
||||
writeFileSync,
|
||||
readFileSync
|
||||
} = require('fs')
|
||||
const { resolve } = require('path')
|
||||
const { writeFileSync, readFileSync } = require('fs')
|
||||
|
||||
describe('[CLI] tauri.js template', () => {
|
||||
it('init a project and builds it', async () => {
|
||||
|
@ -6,15 +6,13 @@ const mockFixtureDir = path.resolve(__dirname, '../fixtures')
|
||||
module.exports.fixtureDir = mockFixtureDir
|
||||
|
||||
function mockResolvePath(basePath, dir) {
|
||||
return dir && path.isAbsolute(dir) ?
|
||||
dir :
|
||||
path.resolve(basePath, dir)
|
||||
return dir && path.isAbsolute(dir) ? dir : path.resolve(basePath, dir)
|
||||
}
|
||||
|
||||
module.exports.initJest = (mockFixture) => {
|
||||
jest.setTimeout(720000)
|
||||
jest.mock('helpers/non-webpack-require', () => {
|
||||
return path => {
|
||||
return (path) => {
|
||||
const value = require('fs').readFileSync(path).toString()
|
||||
if (path.endsWith('.json')) {
|
||||
return JSON.parse(value)
|
||||
@ -31,8 +29,8 @@ module.exports.initJest = (mockFixture) => {
|
||||
appDir,
|
||||
tauriDir,
|
||||
resolve: {
|
||||
app: dir => mockResolvePath(appDir, dir),
|
||||
tauri: dir => mockResolvePath(tauriDir, dir)
|
||||
app: (dir) => mockResolvePath(appDir, dir),
|
||||
tauri: (dir) => mockResolvePath(tauriDir, dir)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -63,7 +61,7 @@ module.exports.startServer = (onSuccess) => {
|
||||
|
||||
function addResponse(response) {
|
||||
responses[response.cmd] = true
|
||||
if (!Object.values(responses).some(c => c === null)) {
|
||||
if (!Object.values(responses).some((c) => c === null)) {
|
||||
server.close(onSuccess)
|
||||
}
|
||||
}
|
||||
@ -83,7 +81,7 @@ module.exports.startServer = (onSuccess) => {
|
||||
|
||||
if (req.method === 'POST') {
|
||||
let body = ''
|
||||
req.on('data', chunk => {
|
||||
req.on('data', (chunk) => {
|
||||
body += chunk.toString()
|
||||
})
|
||||
if (req.url === '/reply') {
|
||||
|
222
cli/tauri.js/test/jest/fixtures/app/dist/index.html
vendored
222
cli/tauri.js/test/jest/fixtures/app/dist/index.html
vendored
@ -1,117 +1,145 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
function callBackEnd(route, args) {
|
||||
console.log(route)
|
||||
console.log(args)
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.onload = function () {
|
||||
console.log(route, args, 'done', xhr.status)
|
||||
}
|
||||
xhr.onerror = function () {
|
||||
console.log(route, args, 'error with ' + xhr.status)
|
||||
}
|
||||
xhr.open('POST', 'http://localhost:7000/' + route)
|
||||
xhr.setRequestHeader('Content-type', 'application/json')
|
||||
xhr.send(JSON.stringify(args))
|
||||
}
|
||||
|
||||
function reply(args) {
|
||||
return callBackEnd('reply', args)
|
||||
}
|
||||
|
||||
function sendError(error) {
|
||||
return callBackEnd('error', error)
|
||||
}
|
||||
|
||||
function testFs(dir) {
|
||||
var contents = 'TAURI E2E TEST FILE'
|
||||
var commandSuffix = (dir ? 'WithDir' : '')
|
||||
|
||||
var options = {
|
||||
dir: dir || null
|
||||
<body>
|
||||
<script>
|
||||
function callBackEnd(route, args) {
|
||||
console.log(route)
|
||||
console.log(args)
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.onload = function () {
|
||||
console.log(route, args, 'done', xhr.status)
|
||||
}
|
||||
xhr.onerror = function () {
|
||||
console.log(route, args, 'error with ' + xhr.status)
|
||||
}
|
||||
xhr.open('POST', 'http://localhost:7000/' + route)
|
||||
xhr.setRequestHeader('Content-type', 'application/json')
|
||||
xhr.send(JSON.stringify(args))
|
||||
}
|
||||
|
||||
return window.__TAURI__.fs.writeFile({
|
||||
file: 'tauri-test.txt',
|
||||
contents: contents
|
||||
}, options).then(function (res) {
|
||||
reply({
|
||||
cmd: 'writeFile' + commandSuffix
|
||||
})
|
||||
return window.__TAURI__.fs.readTextFile('tauri-test.txt', options).then(function (res) {
|
||||
if (res === contents) {
|
||||
function reply(args) {
|
||||
return callBackEnd('reply', args)
|
||||
}
|
||||
|
||||
function sendError(error) {
|
||||
return callBackEnd('error', error)
|
||||
}
|
||||
|
||||
function testFs(dir) {
|
||||
var contents = 'TAURI E2E TEST FILE'
|
||||
var commandSuffix = dir ? 'WithDir' : ''
|
||||
|
||||
var options = {
|
||||
dir: dir || null
|
||||
}
|
||||
|
||||
return window.__TAURI__.fs
|
||||
.writeFile(
|
||||
{
|
||||
file: 'tauri-test.txt',
|
||||
contents: contents
|
||||
},
|
||||
options
|
||||
)
|
||||
.then(function (res) {
|
||||
reply({
|
||||
cmd: 'readFile' + commandSuffix
|
||||
cmd: 'writeFile' + commandSuffix
|
||||
})
|
||||
|
||||
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) {
|
||||
return window.__TAURI__.fs
|
||||
.readTextFile('tauri-test.txt', options)
|
||||
.then(function (res) {
|
||||
if (res === contents) {
|
||||
reply({
|
||||
cmd: 'copyFile' + commandSuffix
|
||||
cmd: 'readFile' + commandSuffix
|
||||
})
|
||||
|
||||
return window.__TAURI__.fs.createDir('tauri-test-dir', options).then(function (res) {
|
||||
reply({
|
||||
cmd: 'createDir' + commandSuffix
|
||||
})
|
||||
return window.__TAURI__.fs.removeDir('tauri-test-dir', options).then(function (res) {
|
||||
return window.__TAURI__.fs
|
||||
.readDir('.', options)
|
||||
.then((res) => {
|
||||
reply({
|
||||
cmd: 'removeDir' + commandSuffix
|
||||
cmd: 'readDir' + 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) {
|
||||
|
||||
return window.__TAURI__.fs
|
||||
.copyFile(
|
||||
'tauri-test.txt',
|
||||
'tauri-test-copy.txt',
|
||||
options
|
||||
)
|
||||
.then(function (res) {
|
||||
reply({
|
||||
cmd: 'removeFile' + commandSuffix
|
||||
cmd: 'copyFile' + commandSuffix
|
||||
})
|
||||
|
||||
return window.__TAURI__.fs
|
||||
.createDir('tauri-test-dir', options)
|
||||
.then(function (res) {
|
||||
reply({
|
||||
cmd: 'createDir' + 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
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
sendError('expected "' + contents + '" found "' + res + '"')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
sendError('expected "' + contents + '" found "' + res + '"')
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(sendError)
|
||||
}
|
||||
|
||||
window.__TAURI__.event.listen('reply', function (res) {
|
||||
reply({
|
||||
cmd: 'listen'
|
||||
})
|
||||
}).catch(sendError)
|
||||
}
|
||||
|
||||
window.__TAURI__.event.listen('reply', function (res) {
|
||||
reply({
|
||||
cmd: 'listen'
|
||||
})
|
||||
})
|
||||
window.onTauriInit = function () {
|
||||
window.__TAURI__.event.emit('hello')
|
||||
}
|
||||
window.onTauriInit = function () {
|
||||
window.__TAURI__.event.emit('hello')
|
||||
}
|
||||
|
||||
testFs(null).then(function () {
|
||||
testFs(window.__TAURI__.fs.Dir.Config)
|
||||
})
|
||||
|
||||
setTimeout(function () {
|
||||
window.__TAURI__.invoke({
|
||||
cmd: 'exit'
|
||||
testFs(null).then(function () {
|
||||
testFs(window.__TAURI__.fs.Dir.Config)
|
||||
})
|
||||
}, 15000)
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
setTimeout(function () {
|
||||
window.__TAURI__.invoke({
|
||||
cmd: 'exit'
|
||||
})
|
||||
}, 15000)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -14,9 +14,11 @@ app.post('/reply', (req, res) => {
|
||||
exit(0)
|
||||
})
|
||||
|
||||
const server = app.listen(port, () => console.log(`Test listening on port ${port}!`))
|
||||
const server = app.listen(port, () =>
|
||||
console.log(`Test listening on port ${port}!`)
|
||||
)
|
||||
|
||||
const exit = code => {
|
||||
const exit = (code) => {
|
||||
server.close()
|
||||
process.kill(appPid)
|
||||
process.exit(code)
|
||||
@ -42,7 +44,9 @@ build({
|
||||
const spawn = require('../cli/tauri.js/dist/helpers/spawn').spawn
|
||||
const artifactPath = path.resolve(__dirname, 'src-tauri/target/debug/app')
|
||||
appPid = spawn(
|
||||
process.platform === 'win32' ? `${artifactPath}.exe` : artifactPath.replace('debug/app', 'debug/./app'),
|
||||
process.platform === 'win32'
|
||||
? `${artifactPath}.exe`
|
||||
: artifactPath.replace('debug/app', 'debug/./app'),
|
||||
[],
|
||||
null
|
||||
)
|
||||
|
@ -1,22 +1,22 @@
|
||||
{
|
||||
"name": "test",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"tauri:prod": "tauri",
|
||||
"tauri:source": "node ../../../../bin/tauri",
|
||||
"tauri:source:init": "yarn tauri:source init --tauriPath ..",
|
||||
"tauri:prod:init": "yarn tauri:prod init",
|
||||
"tauri:source:dev": "yarn tauri:source dev",
|
||||
"tauri:prod:dev": "yarn tauri:prod dev",
|
||||
"tauri:source:build": "yarn tauri:source build",
|
||||
"tauri:prod:build": "yarn tauri:prod build"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1"
|
||||
}
|
||||
"name": "test",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"tauri:prod": "tauri",
|
||||
"tauri:source": "node ../../../../bin/tauri",
|
||||
"tauri:source:init": "yarn tauri:source init --tauriPath ..",
|
||||
"tauri:prod:init": "yarn tauri:prod init",
|
||||
"tauri:source:dev": "yarn tauri:source dev",
|
||||
"tauri:prod:dev": "yarn tauri:prod dev",
|
||||
"tauri:source:build": "yarn tauri:source build",
|
||||
"tauri:prod:build": "yarn tauri:prod build"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1"
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,13 @@
|
||||
"all": true
|
||||
},
|
||||
"bundle": {
|
||||
"icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"identifier": "fixture.app"
|
||||
},
|
||||
"window": {
|
||||
|
@ -1,3 +1,3 @@
|
||||
module.exports = {
|
||||
process: content => `module.exports = {default: ${JSON.stringify(content)}}`
|
||||
process: (content) => `module.exports = {default: ${JSON.stringify(content)}}`
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"types": ["src/types"]
|
||||
},
|
||||
}
|
||||
},
|
||||
"include": ["src", "api-src"]
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ module.exports = {
|
||||
mode: process.env.NODE_ENV || 'development',
|
||||
devtool: 'source-map',
|
||||
module: {
|
||||
rules: [{
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/
|
||||
@ -47,13 +48,15 @@ module.exports = {
|
||||
target: 'node',
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [{
|
||||
from: './src/types/config.validator.ts',
|
||||
to: '../src/types/config.schema.json',
|
||||
transform(content) {
|
||||
return schemaParser('TauriConfigSchema', content.toString())
|
||||
patterns: [
|
||||
{
|
||||
from: './src/types/config.validator.ts',
|
||||
to: '../src/types/config.schema.json',
|
||||
transform(content) {
|
||||
return schemaParser('TauriConfigSchema', content.toString())
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
})
|
||||
]
|
||||
}
|
||||
@ -74,5 +77,5 @@ function schemaParser(schemaName, content) {
|
||||
}
|
||||
}
|
||||
|
||||
return output.join("\n")
|
||||
return output.join('\n')
|
||||
}
|
||||
|
@ -1562,12 +1562,12 @@
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@3.7.0":
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.7.0.tgz#0f91aa3c83d019591719e597fbdb73a59595a263"
|
||||
integrity sha512-4OEcPON3QIx0ntsuiuFP/TkldmBGXf0uKxPQlGtS/W2F3ndYm8Vgdpj/woPJkzUc65gd3iR+qi3K8SDQP/obFg==
|
||||
"@typescript-eslint/eslint-plugin@3.9.1":
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.1.tgz#8cf27b6227d12d66dd8dc1f1a4b04d1daad51c2e"
|
||||
integrity sha512-XIr+Mfv7i4paEdBf0JFdIl9/tVxyj+rlilWIfZ97Be0lZ7hPvUbS5iHt9Glc8kRI53dsr0PcAEudbf8rO2wGgg==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "3.7.0"
|
||||
"@typescript-eslint/experimental-utils" "3.9.1"
|
||||
debug "^4.1.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
regexpp "^3.0.0"
|
||||
@ -1585,26 +1585,26 @@
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
|
||||
"@typescript-eslint/experimental-utils@3.7.0":
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.7.0.tgz#0ee21f6c48b2b30c63211da23827725078d5169a"
|
||||
integrity sha512-xpfXXAfZqhhqs5RPQBfAFrWDHoNxD5+sVB5A46TF58Bq1hRfVROrWHcQHHUM9aCBdy9+cwATcvCbRg8aIRbaHQ==
|
||||
"@typescript-eslint/experimental-utils@3.9.1":
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.1.tgz#b140b2dc7a7554a44f8a86fb6fe7cbfe57ca059e"
|
||||
integrity sha512-lkiZ8iBBaYoyEKhCkkw4SAeatXyBq9Ece5bZXdLe1LWBUwTszGbmbiqmQbwWA8cSYDnjWXp9eDbXpf9Sn0hLAg==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/types" "3.7.0"
|
||||
"@typescript-eslint/typescript-estree" "3.7.0"
|
||||
"@typescript-eslint/types" "3.9.1"
|
||||
"@typescript-eslint/typescript-estree" "3.9.1"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
|
||||
"@typescript-eslint/parser@3.7.0":
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.7.0.tgz#3e9cd9df9ea644536feb6e5acdb8279ecff96ce9"
|
||||
integrity sha512-2LZauVUt7jAWkcIW7djUc3kyW+fSarNEuM3RF2JdLHR9BfX/nDEnyA4/uWz0wseoWVZbDXDF7iF9Jc342flNqQ==
|
||||
"@typescript-eslint/parser@3.9.1":
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.9.1.tgz#ab7983abaea0ae138ff5671c7c7739d8a191b181"
|
||||
integrity sha512-y5QvPFUn4Vl4qM40lI+pNWhTcOWtpZAJ8pOEQ21fTTW4xTJkRplMjMRje7LYTXqVKKX9GJhcyweMz2+W1J5bMg==
|
||||
dependencies:
|
||||
"@types/eslint-visitor-keys" "^1.0.0"
|
||||
"@typescript-eslint/experimental-utils" "3.7.0"
|
||||
"@typescript-eslint/types" "3.7.0"
|
||||
"@typescript-eslint/typescript-estree" "3.7.0"
|
||||
"@typescript-eslint/experimental-utils" "3.9.1"
|
||||
"@typescript-eslint/types" "3.9.1"
|
||||
"@typescript-eslint/typescript-estree" "3.9.1"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
"@typescript-eslint/parser@^3.0.1":
|
||||
@ -1623,10 +1623,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.6.1.tgz#87600fe79a1874235d3cc1cf5c7e1a12eea69eee"
|
||||
integrity sha512-NPxd5yXG63gx57WDTW1rp0cF3XlNuuFFB5G+Kc48zZ+51ZnQn9yjDEsjTPQ+aWM+V+Z0I4kuTFKjKvgcT1F7xQ==
|
||||
|
||||
"@typescript-eslint/types@3.7.0":
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.7.0.tgz#09897fab0cb95479c01166b10b2c03c224821077"
|
||||
integrity sha512-reCaK+hyKkKF+itoylAnLzFeNYAEktB0XVfSQvf0gcVgpz1l49Lt6Vo9x4MVCCxiDydA0iLAjTF/ODH0pbfnpg==
|
||||
"@typescript-eslint/types@3.9.1":
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.9.1.tgz#b2a6eaac843cf2f2777b3f2464fb1fbce5111416"
|
||||
integrity sha512-15JcTlNQE1BsYy5NBhctnEhEoctjXOjOK+Q+rk8ugC+WXU9rAcS2BYhoh6X4rOaXJEpIYDl+p7ix+A5U0BqPTw==
|
||||
|
||||
"@typescript-eslint/typescript-estree@3.6.1":
|
||||
version "3.6.1"
|
||||
@ -1642,13 +1642,13 @@
|
||||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/typescript-estree@3.7.0":
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.0.tgz#66872e6da120caa4b64e6b4ca5c8702afc74738d"
|
||||
integrity sha512-xr5oobkYRebejlACGr1TJ0Z/r0a2/HUf0SXqPvlgUMwiMqOCu/J+/Dr9U3T0IxpE5oLFSkqMx1FE/dKaZ8KsOQ==
|
||||
"@typescript-eslint/typescript-estree@3.9.1":
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.1.tgz#fd81cada74bc8a7f3a2345b00897acb087935779"
|
||||
integrity sha512-IqM0gfGxOmIKPhiHW/iyAEXwSVqMmR2wJ9uXHNdFpqVvPaQ3dWg302vW127sBpAiqM9SfHhyS40NKLsoMpN2KA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "3.7.0"
|
||||
"@typescript-eslint/visitor-keys" "3.7.0"
|
||||
"@typescript-eslint/types" "3.9.1"
|
||||
"@typescript-eslint/visitor-keys" "3.9.1"
|
||||
debug "^4.1.1"
|
||||
glob "^7.1.6"
|
||||
is-glob "^4.0.1"
|
||||
@ -1663,10 +1663,10 @@
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@3.7.0":
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.0.tgz#ac0417d382a136e4571a0b0dcfe52088cb628177"
|
||||
integrity sha512-k5PiZdB4vklUpUX4NBncn5RBKty8G3ihTY+hqJsCdMuD0v4jofI5xuqwnVcWxfv6iTm2P/dfEa2wMUnsUY8ODw==
|
||||
"@typescript-eslint/visitor-keys@3.9.1":
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.1.tgz#92af3747cdb71509199a8f7a4f00b41d636551d1"
|
||||
integrity sha512-zxdtUjeoSh+prCpogswMwVUJfEFmCOjdzK9rpNjNBfm6EyPt99x3RrJoBOGZO23FCt0WPKUCOL5mb/9D5LjdwQ==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
@ -3835,6 +3835,13 @@ escodegen@^1.14.1:
|
||||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
eslint-config-prettier@6.11.0:
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1"
|
||||
integrity sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==
|
||||
dependencies:
|
||||
get-stdin "^6.0.0"
|
||||
|
||||
eslint-config-standard-with-typescript@18.0.2:
|
||||
version "18.0.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-18.0.2.tgz#eb02d5358b17fe083c6f993ff829492c8f96b18f"
|
||||
@ -3956,10 +3963,10 @@ eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
|
||||
integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
|
||||
|
||||
eslint@7.5.0:
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.5.0.tgz#9ecbfad62216d223b82ac9ffea7ef3444671d135"
|
||||
integrity sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q==
|
||||
eslint@7.7.0:
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.7.0.tgz#18beba51411927c4b64da0a8ceadefe4030d6073"
|
||||
integrity sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
ajv "^6.10.0"
|
||||
@ -4620,6 +4627,11 @@ get-stdin@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
|
||||
integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
|
||||
|
||||
get-stdin@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b"
|
||||
integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==
|
||||
|
||||
get-stream@3.0.0, get-stream@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
|
||||
@ -7698,6 +7710,11 @@ prepend-http@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-3.0.1.tgz#3e724d58fd5867465b300bb9615009fa2f8ee3b6"
|
||||
integrity sha512-BLxfZh+m6UiAiCPZFJ4+vYoL7NrRs5XgCTRrjseATAggXhdZKKxn+JUNmuVYWY23bDHgaEHodxw8mnmtVEDtHw==
|
||||
|
||||
prettier@2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
|
||||
integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==
|
||||
|
||||
pretty-format@^26.1.0:
|
||||
version "26.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.1.0.tgz#272b9cd1f1a924ab5d443dc224899d7a65cb96ec"
|
||||
|
@ -8,7 +8,11 @@
|
||||
"url": "https://github.com/tauri-apps/tauri.git",
|
||||
"directory": "cli/tauri.js"
|
||||
},
|
||||
"scripts": {
|
||||
"format": "prettier --write --end-of-line=auto \"./**/*.{js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore"
|
||||
},
|
||||
"devDependencies": {
|
||||
"covector": "^0.2.6"
|
||||
"covector": "^0.2.6",
|
||||
"prettier": "^2.0.5"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user