diff --git a/.changes/prettier-taurijs.md b/.changes/prettier-taurijs.md new file mode 100644 index 000000000..42d70b1d0 --- /dev/null +++ b/.changes/prettier-taurijs.md @@ -0,0 +1,5 @@ +--- +"tauri.js": patch +--- + +Format all code with prettier. This technically should only affect code styles, but noting for posterity. diff --git a/.github/workflows/js-lint.yml b/.github/workflows/js-lint.yml index 1e363c537..d65972ed5 100644 --- a/.github/workflows/js-lint.yml +++ b/.github/workflows/js-lint.yml @@ -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 diff --git a/cli/deno b/cli/deno new file mode 160000 index 000000000..55fd9104f --- /dev/null +++ b/cli/deno @@ -0,0 +1 @@ +Subproject commit 55fd9104fa4da3b7afb96a16bb1ed8378b028a5a diff --git a/cli/tauri.js/.eslintrc.js b/cli/tauri.js/.eslintrc.js index 3c531f83f..3f0a5dbf0 100644 --- a/cli/tauri.js/.eslintrc.js +++ b/cli/tauri.js/.eslintrc.js @@ -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 } } diff --git a/cli/tauri.js/.prettierrc.js b/cli/tauri.js/.prettierrc.js new file mode 100644 index 000000000..2be2f9327 --- /dev/null +++ b/cli/tauri.js/.prettierrc.js @@ -0,0 +1,5 @@ +module.exports = { + singleQuote: true, + semi: false, + trailingComma: 'none' +} diff --git a/cli/tauri.js/api-src/bundle.ts b/cli/tauri.js/api-src/bundle.ts index 627abd45c..824481bc9 100644 --- a/cli/tauri.js/api-src/bundle.ts +++ b/cli/tauri.js/api-src/bundle.ts @@ -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 } diff --git a/cli/tauri.js/api-src/cli.ts b/cli/tauri.js/api-src/cli.ts index b513f1ff1..af72bfae9 100644 --- a/cli/tauri.js/api-src/cli.ts +++ b/cli/tauri.js/api-src/cli.ts @@ -32,6 +32,4 @@ async function getMatches(): Promise { }) } -export { - getMatches -} +export { getMatches } diff --git a/cli/tauri.js/api-src/dialog.ts b/cli/tauri.js/api-src/dialog.ts index d365de28b..3dee01cef 100644 --- a/cli/tauri.js/api-src/dialog.ts +++ b/cli/tauri.js/api-src/dialog.ts @@ -7,7 +7,10 @@ export interface OpenDialogOptions { directory?: boolean } -export type SaveDialogOptions = Pick +export type SaveDialogOptions = Pick< + OpenDialogOptions, + 'filter' | 'defaultPath' +> /** * @name openDialog @@ -51,7 +54,4 @@ async function save(options: SaveDialogOptions = {}): Promise { }) } -export { - open, - save -} +export { open, save } diff --git a/cli/tauri.js/api-src/event.ts b/cli/tauri.js/api-src/event.ts index d9a3a1a8c..b395507d8 100644 --- a/cli/tauri.js/api-src/event.ts +++ b/cli/tauri.js/api-src/event.ts @@ -13,7 +13,11 @@ export type EventCallback = (event: Event) => void * @param event the event name * @param handler the event handler callback */ -function listen(event: string, handler: EventCallback, once = false): void { +function listen( + event: string, + handler: EventCallback, + once = false +): void { invoke({ cmd: 'listen', event, @@ -36,7 +40,4 @@ function emit(event: string, payload?: string): void { }) } -export { - listen, - emit -} +export { listen, emit } diff --git a/cli/tauri.js/api-src/fs.ts b/cli/tauri.js/api-src/fs.ts index 27cb91d54..3251c4fbc 100644 --- a/cli/tauri.js/api-src/fs.ts +++ b/cli/tauri.js/api-src/fs.ts @@ -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 { +async function writeFile( + file: FsTextFileOption, + options: FsOptions = {} +): Promise { 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 { +async function writeBinaryFile( + file: FsBinaryFileOption, + options: FsOptions = {} +): Promise { 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 { +async function readDir( + dir: string, + options: FsOptions = {} +): Promise { return await promisified({ cmd: 'readDir', path: dir, @@ -230,7 +239,11 @@ async function removeDir(dir: string, options: FsOptions = {}): Promise { * @param [options.dir] base directory * @return */ -async function copyFile(source: string, destination: string, options: FsOptions = {}): Promise { +async function copyFile( + source: string, + destination: string, + options: FsOptions = {} +): Promise { 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 { +async function removeFile( + file: string, + options: FsOptions = {} +): Promise { return await promisified({ cmd: 'removeFile', path: file, @@ -264,7 +280,11 @@ async function removeFile(file: string, options: FsOptions = {}): Promise * @param [options.dir] base directory * @return */ -async function renameFile(oldPath: string, newPath: string, options: FsOptions = {}): Promise { +async function renameFile( + oldPath: string, + newPath: string, + options: FsOptions = {} +): Promise { return await promisified({ cmd: 'renameFile', oldPath, diff --git a/cli/tauri.js/api-src/http.ts b/cli/tauri.js/api-src/http.ts index 9527f1491..92d681273 100644 --- a/cli/tauri.js/api-src/http.ts +++ b/cli/tauri.js/api-src/http.ts @@ -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(url: string, options: PartialOptions): Promise { * * @return promise resolving to the response */ -async function post(url: string, body: Body, options: PartialOptions): Promise { +async function post( + url: string, + body: Body, + options: PartialOptions +): Promise { return await request({ method: 'POST', url, @@ -91,7 +104,11 @@ async function post(url: string, body: Body, options: PartialOptions): Promis * * @return promise resolving to the response */ -async function put(url: string, body: Body, options: PartialOptions): Promise { +async function put( + url: string, + body: Body, + options: PartialOptions +): Promise { return await request({ method: 'PUT', url, @@ -124,7 +141,10 @@ async function patch(url: string, options: PartialOptions): Promise { * * @return promise resolving to the response */ -async function deleteRequest(url: string, options: PartialOptions): Promise { +async function deleteRequest( + url: string, + options: PartialOptions +): Promise { return await request({ method: 'DELETE', url, diff --git a/cli/tauri.js/api-src/notification.ts b/cli/tauri.js/api-src/notification.ts index 517f55083..cb56caecc 100644 --- a/cli/tauri.js/api-src/notification.ts +++ b/cli/tauri.js/api-src/notification.ts @@ -32,8 +32,4 @@ function sendNotification(options: Options | string): void { } } -export { - sendNotification, - requestPermission, - isPermissionGranted -} +export { sendNotification, requestPermission, isPermissionGranted } diff --git a/cli/tauri.js/api-src/process.ts b/cli/tauri.js/api-src/process.ts index 38d0f29ca..14b7f69f6 100644 --- a/cli/tauri.js/api-src/process.ts +++ b/cli/tauri.js/api-src/process.ts @@ -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 { +async function execute( + command: string, + args?: string | string[] +): Promise { if (typeof args === 'object') { Object.freeze(args) } @@ -19,6 +22,4 @@ async function execute(command: string, args?: string | string[]): Promise 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(args: any): Promise { 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(args: any): Promise { }) } -export { - invoke, - transformCallback, - promisified -} +export { invoke, transformCallback, promisified } diff --git a/cli/tauri.js/api-src/window.ts b/cli/tauri.js/api-src/window.ts index a46833e3d..9428bf07a 100644 --- a/cli/tauri.js/api-src/window.ts +++ b/cli/tauri.js/api-src/window.ts @@ -24,7 +24,4 @@ function open(url: string): void { }) } -export { - setTitle, - open -} +export { setTitle, open } diff --git a/cli/tauri.js/babel.config.js b/cli/tauri.js/babel.config.js index 75a3c465d..454f6976a 100644 --- a/cli/tauri.js/babel.config.js +++ b/cli/tauri.js/babel.config.js @@ -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' ] -}; +} diff --git a/cli/tauri.js/bin/tauri-build.js b/cli/tauri.js/bin/tauri-build.js index 893b94f14..ccdec4d23 100644 --- a/cli/tauri.js/bin/tauri-build.js +++ b/cli/tauri.js/bin/tauri-build.js @@ -25,7 +25,7 @@ if (argv.help) { process.exit(0) } -async function run () { +async function run() { const build = require('../dist/api/build') await build({ diff --git a/cli/tauri.js/bin/tauri-create.js b/cli/tauri.js/bin/tauri-create.js index 6b7e75037..4fabe3acd 100644 --- a/cli/tauri.js/bin/tauri-create.js +++ b/cli/tauri.js/bin/tauri-create.js @@ -2,11 +2,11 @@ const parseArgs = require('minimist') const inquirer = require('inquirer') const { resolve } = require('path') const { merge } = require('lodash') -const { - recipeShortNames, - recipeDescriptiveNames, - recipeByDescriptiveName, - recipeByShortName +const { + recipeShortNames, + recipeDescriptiveNames, + recipeByDescriptiveName, + recipeByShortName } = require('../dist/api/recipes') /** @@ -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 "/src-tauri" folder that will be created?', + message: + 'Where are your web assets (HTML/CSS/JS) located, relative to the "/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) { @@ -168,7 +172,7 @@ async function runInit(argv, config = {}) { } const directory = argv.d || process.cwd() - + init({ directory, force: argv.f || null, @@ -184,18 +188,16 @@ async function runInit(argv, config = {}) { } }) }) - - const { - installDependencies - } = require('../dist/api/dependency-manager') + + const { installDependencies } = require('../dist/api/dependency-manager') await installDependencies() - + if (recipe !== undefined) { const { installRecipeDependencies, runRecipePostConfig } = require('../dist/api/recipes/install') - + await installRecipeDependencies(recipe, directory) await runRecipePostConfig(recipe, directory) } diff --git a/cli/tauri.js/bin/tauri-dev.js b/cli/tauri.js/bin/tauri-dev.js index b350da305..988364548 100644 --- a/cli/tauri.js/bin/tauri-dev.js +++ b/cli/tauri.js/bin/tauri-dev.js @@ -20,7 +20,7 @@ if (argv.help) { process.exit(0) } -async function run () { +async function run() { const dev = require('../dist/api/dev') await dev({ diff --git a/cli/tauri.js/bin/tauri-icon.js b/cli/tauri.js/bin/tauri-icon.js index 35f425251..51a49455c 100644 --- a/cli/tauri.js/bin/tauri-icon.js +++ b/cli/tauri.js/bin/tauri-icon.js @@ -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) + }) diff --git a/cli/tauri.js/bin/tauri-init.js b/cli/tauri.js/bin/tauri-init.js index 32614e3e5..a959f32c4 100644 --- a/cli/tauri.js/bin/tauri-init.js +++ b/cli/tauri.js/bin/tauri-init.js @@ -2,9 +2,9 @@ const parseArgs = require('minimist') const tauriCreate = require('./tauri-create') /** - * init is an alias for create -r none, same as + * init is an alias for create -r none, same as * creating a fresh tauri project with no UI recipe applied. - * + * * @type {object} * @property {boolean} h * @property {boolean} help @@ -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 diff --git a/cli/tauri.js/bin/tauri.js b/cli/tauri.js/bin/tauri.js index 66ec903d4..fb3ccc0ea 100755 --- a/cli/tauri.js/bin/tauri.js +++ b/cli/tauri.js/bin/tauri.js @@ -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. diff --git a/cli/tauri.js/build/type-validators.js b/cli/tauri.js/build/type-validators.js index b6590c37a..560054e80 100644 --- a/cli/tauri.js/build/type-validators.js +++ b/cli/tauri.js/build/type-validators.js @@ -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'` + ) + ) + } } -}) +) diff --git a/cli/tauri.js/jest.config.js b/cli/tauri.js/jest.config.js index 0c2d8f085..91143cebf 100644 --- a/cli/tauri.js/jest.config.js +++ b/cli/tauri.js/jest.config.js @@ -38,8 +38,9 @@ module.exports = { '^test/(.*)$': '/test/$1', '../../package.json': '/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' } } diff --git a/cli/tauri.js/package.json b/cli/tauri.js/package.json index ee0986167..b7ed95280 100644 --- a/cli/tauri.js/package.json +++ b/cli/tauri.js/package.json @@ -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" + } } diff --git a/cli/tauri.js/rollup.config.js b/cli/tauri.js/rollup.config.js index 3550d4c7a..edc4ffd12 100644 --- a/cli/tauri.js/rollup.config.js +++ b/cli/tauri.js/rollup.config.js @@ -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 || {}) + ] + } +] diff --git a/cli/tauri.js/src/api/dependency-manager/cargo-commands.ts b/cli/tauri.js/src/api/dependency-manager/cargo-commands.ts index c08ec4825..ed70eba7e 100644 --- a/cli/tauri.js/src/api/dependency-manager/cargo-commands.ts +++ b/cli/tauri.js/src/api/dependency-manager/cargo-commands.ts @@ -9,7 +9,9 @@ const log = logger('dependency:cargo-commands') const dependencies = ['tauri-bundler'] -async function manageDependencies(managementType: ManagementType): Promise { +async function manageDependencies( + managementType: ManagementType +): Promise { const installedDeps = [] const updatedDeps = [] @@ -22,12 +24,16 @@ async function manageDependencies(managementType: ManagementType): Promise { return await manageDependencies(ManagementType.Update) } -export { - install, - update -} +export { install, update } diff --git a/cli/tauri.js/src/api/dependency-manager/cargo-crates.ts b/cli/tauri.js/src/api/dependency-manager/cargo-crates.ts index eecc61d43..23581943e 100644 --- a/cli/tauri.js/src/api/dependency-manager/cargo-crates.ts +++ b/cli/tauri.js/src/api/dependency-manager/cargo-crates.ts @@ -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(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 { +async function manageDependencies( + managementType: ManagementType +): Promise { const installedDeps = [] const updatedDeps = [] const result: Result = new Map() @@ -43,12 +49,17 @@ async function manageDependencies(managementType: ManagementType): Promise(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((initialValue, dep) => [...initialValue, '-p', dep], [])], tauriDir) + spawnSync( + 'cargo', + [ + 'update', + '--aggressive', + ...updatedDeps.reduce( + (initialValue, dep) => [...initialValue, '-p', dep], + [] + ) + ], + tauriDir + ) } result.set(ManagementType.Install, installedDeps) @@ -102,7 +133,4 @@ async function update(): Promise { return await manageDependencies(ManagementType.Update) } -export { - install, - update -} +export { install, update } diff --git a/cli/tauri.js/src/api/dependency-manager/npm-packages.ts b/cli/tauri.js/src/api/dependency-manager/npm-packages.ts index 767c832f9..a0f284989 100644 --- a/cli/tauri.js/src/api/dependency-manager/npm-packages.ts +++ b/cli/tauri.js/src/api/dependency-manager/npm-packages.ts @@ -14,7 +14,10 @@ import { existsSync } from 'fs' const log = logger('dependency:npm-packages') -async function manageDependencies(managementType: ManagementType, dependencies: string[]): Promise { +async function manageDependencies( + managementType: ManagementType, + dependencies: string[] +): Promise { 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 { return await manageDependencies(ManagementType.Update, dependencies) } -export { - install, - installThese, - installTheseDev, - update -} +export { install, installThese, installTheseDev, update } diff --git a/cli/tauri.js/src/api/dependency-manager/rust.ts b/cli/tauri.js/src/api/dependency-manager/rust.ts index 8547bb27d..72187aa76 100644 --- a/cli/tauri.js/src/api/dependency-manager/rust.ts +++ b/cli/tauri.js/src/api/dependency-manager/rust.ts @@ -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 { 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 } diff --git a/cli/tauri.js/src/api/dependency-manager/util.ts b/cli/tauri.js/src/api/dependency-manager/util.ts index 9a7c7f8a7..ae3e719ce 100644 --- a/cli/tauri.js/src/api/dependency-manager/util.ts +++ b/cli/tauri.js/src/api/dependency-manager/util.ts @@ -23,13 +23,21 @@ async function getCrateLatestVersion(crateName: string): Promise { } 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 { +async function getNpmPackageVersion( + packageName: string +): Promise { 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) diff --git a/cli/tauri.js/src/api/dev.ts b/cli/tauri.js/src/api/dev.ts index d2cb5865e..0b817263a 100644 --- a/cli/tauri.js/src/api/dev.ts +++ b/cli/tauri.js/src/api/dev.ts @@ -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) } } diff --git a/cli/tauri.js/src/api/info.ts b/cli/tauri.js/src/api/info.ts index 65e95f07d..31e7b70eb 100644 --- a/cli/tauri.js/src/api/info.ts +++ b/cli/tauri.js/src/api/info.ts @@ -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 { 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(filepath: string): T | null { +function readTomlFile( + 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 { const lockPath = path.join(tauriDir, 'Cargo.lock') const lock = readTomlFile(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(manifestPath) @@ -123,7 +138,9 @@ async function printAppInfo(tauriDir: string): Promise { } 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 { const manifestPath = path.resolve(tauriDir, tauri.path, 'Cargo.toml') const manifestContent = readTomlFile(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 { 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 { 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 { 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 { ? 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', diff --git a/cli/tauri.js/src/api/init.ts b/cli/tauri.js/src/api/init.ts index 0759a25e1..d36301583 100644 --- a/cli/tauri.js/src/api/init.ts +++ b/cli/tauri.js/src/api/init.ts @@ -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 } diff --git a/cli/tauri.js/src/api/recipes/index.ts b/cli/tauri.js/src/api/recipes/index.ts index f4a38d476..903762d91 100644 --- a/cli/tauri.js/src/api/recipes/index.ts +++ b/cli/tauri.js/src/api/recipes/index.ts @@ -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 +) diff --git a/cli/tauri.js/src/api/recipes/install.ts b/cli/tauri.js/src/api/recipes/install.ts index ca423af30..4e9644d8c 100644 --- a/cli/tauri.js/src/api/recipes/install.ts +++ b/cli/tauri.js/src/api/recipes/install.ts @@ -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 { +export async function installRecipeDependencies( + recipe: Recipe +): Promise { 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 { +export async function runRecipePostConfig( + recipe: Recipe, + cwd: string +): Promise { const log = logger('recipe:postconfig') log(`Running post configuration for ${recipe.descriptiveName}`) diff --git a/cli/tauri.js/src/api/recipes/react.ts b/cli/tauri.js/src/api/recipes/react.ts index d2485dbf7..c5f004b9a 100644 --- a/cli/tauri.js/src/api/recipes/react.ts +++ b/cli/tauri.js/src/api/recipes/react.ts @@ -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 } diff --git a/cli/tauri.js/src/api/tauricon.ts b/cli/tauri.js/src/api/tauricon.ts index 9e36d2458..9171b5f82 100644 --- a/cli/tauri.js/src/api/tauricon.ts +++ b/cli/tauri.js/src/api/tauricon.ts @@ -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 { +const exists = async function (file: string | Buffer): Promise { 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 { 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 diff --git a/cli/tauri.js/src/helpers/app-paths.ts b/cli/tauri.js/src/helpers/app-paths.ts index 5d9c382c6..74e4a007a 100644 --- a/cli/tauri.js/src/helpers/app-paths.ts +++ b/cli/tauri.js/src/helpers/app-paths.ts @@ -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) } diff --git a/cli/tauri.js/src/helpers/copy-templates.ts b/cli/tauri.js/src/helpers/copy-templates.ts index 6da4d9e2a..ae2eec7e1 100644 --- a/cli/tauri.js/src/helpers/copy-templates.ts +++ b/cli/tauri.js/src/helpers/copy-templates.ts @@ -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) !== '_') { diff --git a/cli/tauri.js/src/helpers/net.ts b/cli/tauri.js/src/helpers/net.ts index 905e780d8..474927f55 100644 --- a/cli/tauri.js/src/helpers/net.ts +++ b/cli/tauri.js/src/helpers/net.ts @@ -2,22 +2,25 @@ import net from 'net' -async function findClosestOpenPort(port: number, host: string): Promise { - 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 { + 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 { 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 { } }) .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 { }) } -export { - findClosestOpenPort, - isPortAvailable -} +export { findClosestOpenPort, isPortAvailable } diff --git a/cli/tauri.js/src/helpers/spawn.ts b/cli/tauri.js/src/helpers/spawn.ts index d6598e793..ba04f9894 100644 --- a/cli/tauri.js/src/helpers/spawn.ts +++ b/cli/tauri.js/src/helpers/spawn.ts @@ -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 diff --git a/cli/tauri.js/src/helpers/tauri-config.ts b/cli/tauri.js/src/helpers/tauri-config.ts index 5bece5246..c9ccb0fac 100644 --- a/cli/tauri.js/src/helpers/tauri-config.ts +++ b/cli/tauri.js/src/helpers/tauri-config.ts @@ -18,8 +18,12 @@ const getTauriConfig = (cfg: Partial): 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 => { 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 => { ) 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 => { // 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' + ) } } diff --git a/cli/tauri.js/src/runner.ts b/cli/tauri.js/src/runner.ts index 155a10756..5ddc81bf1 100644 --- a/cli/tauri.js/src/runner.ts +++ b/cli/tauri.js/src/runner.ts @@ -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)) } diff --git a/cli/tauri.js/src/template/defaultConfig.ts b/cli/tauri.js/src/template/defaultConfig.ts index 8e923551d..91c1de100 100644 --- a/cli/tauri.js/src/template/defaultConfig.ts +++ b/cli/tauri.js/src/template/defaultConfig.ts @@ -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 diff --git a/cli/tauri.js/src/template/index.ts b/cli/tauri.js/src/template/index.ts index 30a947bc9..2667b52ee 100644 --- a/cli/tauri.js/src/template/index.ts +++ b/cli/tauri.js/src/template/index.ts @@ -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 } diff --git a/cli/tauri.js/src/types/cargo.ts b/cli/tauri.js/src/types/cargo.ts index ea9d68548..16999fa8e 100644 --- a/cli/tauri.js/src/types/cargo.ts +++ b/cli/tauri.js/src/types/cargo.ts @@ -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 diff --git a/cli/tauri.js/src/types/config.schema.json b/cli/tauri.js/src/types/config.schema.json index f6942d247..98718392b 100644 --- a/cli/tauri.js/src/types/config.schema.json +++ b/cli/tauri.js/src/types/config.schema.json @@ -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" -} \ No newline at end of file +} diff --git a/cli/tauri.js/src/types/config.validator.ts b/cli/tauri.js/src/types/config.validator.ts index 278126fa4..fbd598157 100644 --- a/cli/tauri.js/src/types/config.validator.ts +++ b/cli/tauri.js/src/types/config.validator.ts @@ -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 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 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 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 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 = ((data: unknown) => data is T) & Pick -export const isTauriConfig = ajv.compile(TauriConfigSchema) as ValidateFunction; + required: ['build', 'ctx', 'tauri'], + type: 'object' +} +export type ValidateFunction = ((data: unknown) => data is T) & + Pick +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) + ) } } diff --git a/cli/tauri.js/templates/recipes/react/App.js b/cli/tauri.js/templates/recipes/react/App.js index 0ac2b6b63..2236bfbb8 100644 --- a/cli/tauri.js/templates/recipes/react/App.js +++ b/cli/tauri.js/templates/recipes/react/App.js @@ -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 logo @@ -34,7 +34,7 @@ function App() {

- ); + ) } -export default App; +export default App diff --git a/cli/tauri.js/templates/tauri.js b/cli/tauri.js/templates/tauri.js index 3f605a79f..ffb541a92 100644 --- a/cli/tauri.js/templates/tauri.js +++ b/cli/tauri.js/templates/tauri.js @@ -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 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 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__({ diff --git a/cli/tauri.js/test/jest/__tests__/build.spec.js b/cli/tauri.js/test/jest/__tests__/build.spec.js index 76eb9bfec..f0a32cf50 100644 --- a/cli/tauri.js/test/jest/__tests__/build.spec.js +++ b/cli/tauri.js/test/jest/__tests__/build.spec.js @@ -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, diff --git a/cli/tauri.js/test/jest/__tests__/dev.spec.js b/cli/tauri.js/test/jest/__tests__/dev.spec.js index 5187785e1..64a7c4075 100644 --- a/cli/tauri.js/test/jest/__tests__/dev.spec.js +++ b/cli/tauri.js/test/jest/__tests__/dev.spec.js @@ -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) diff --git a/cli/tauri.js/test/jest/__tests__/tauri.spec.js b/cli/tauri.js/test/jest/__tests__/tauri.spec.js index 412bbe3b1..1ef522764 100644 --- a/cli/tauri.js/test/jest/__tests__/tauri.spec.js +++ b/cli/tauri.js/test/jest/__tests__/tauri.spec.js @@ -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 () => { diff --git a/cli/tauri.js/test/jest/__tests__/tauricon.spec.js b/cli/tauri.js/test/jest/__tests__/tauricon.spec.js index 100bffca4..5fe77fea3 100644 --- a/cli/tauri.js/test/jest/__tests__/tauricon.spec.js +++ b/cli/tauri.js/test/jest/__tests__/tauricon.spec.js @@ -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) }) diff --git a/cli/tauri.js/test/jest/__tests__/template.spec.js b/cli/tauri.js/test/jest/__tests__/template.spec.js index e933e8377..6e4ae427e 100644 --- a/cli/tauri.js/test/jest/__tests__/template.spec.js +++ b/cli/tauri.js/test/jest/__tests__/template.spec.js @@ -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 () => { diff --git a/cli/tauri.js/test/jest/fixtures/app-test-setup.js b/cli/tauri.js/test/jest/fixtures/app-test-setup.js index 0e18a4c69..b8fc25be9 100644 --- a/cli/tauri.js/test/jest/fixtures/app-test-setup.js +++ b/cli/tauri.js/test/jest/fixtures/app-test-setup.js @@ -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') { diff --git a/cli/tauri.js/test/jest/fixtures/app/dist/index.html b/cli/tauri.js/test/jest/fixtures/app/dist/index.html index 8ff07736e..7e4f0df64 100644 --- a/cli/tauri.js/test/jest/fixtures/app/dist/index.html +++ b/cli/tauri.js/test/jest/fixtures/app/dist/index.html @@ -1,117 +1,145 @@ - - - - + setTimeout(function () { + window.__TAURI__.invoke({ + cmd: 'exit' + }) + }, 15000) + + diff --git a/cli/tauri.js/test/jest/fixtures/app/index.js b/cli/tauri.js/test/jest/fixtures/app/index.js index 05d17c7ae..c930b879f 100644 --- a/cli/tauri.js/test/jest/fixtures/app/index.js +++ b/cli/tauri.js/test/jest/fixtures/app/index.js @@ -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 ) diff --git a/cli/tauri.js/test/jest/fixtures/app/package.json b/cli/tauri.js/test/jest/fixtures/app/package.json index 4003bbb26..dba216389 100644 --- a/cli/tauri.js/test/jest/fixtures/app/package.json +++ b/cli/tauri.js/test/jest/fixtures/app/package.json @@ -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" + } } diff --git a/cli/tauri.js/test/jest/fixtures/app/src-tauri/tauri.conf.json b/cli/tauri.js/test/jest/fixtures/app/src-tauri/tauri.conf.json index 4a6485f10..1595fc58c 100644 --- a/cli/tauri.js/test/jest/fixtures/app/src-tauri/tauri.conf.json +++ b/cli/tauri.js/test/jest/fixtures/app/src-tauri/tauri.conf.json @@ -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": { diff --git a/cli/tauri.js/test/jest/raw-loader-transformer.js b/cli/tauri.js/test/jest/raw-loader-transformer.js index 23cc28bfc..d64cef701 100644 --- a/cli/tauri.js/test/jest/raw-loader-transformer.js +++ b/cli/tauri.js/test/jest/raw-loader-transformer.js @@ -1,3 +1,3 @@ module.exports = { - process: content => `module.exports = {default: ${JSON.stringify(content)}}` + process: (content) => `module.exports = {default: ${JSON.stringify(content)}}` } diff --git a/cli/tauri.js/tsconfig.json b/cli/tauri.js/tsconfig.json index cac982c5f..5cafb0018 100644 --- a/cli/tauri.js/tsconfig.json +++ b/cli/tauri.js/tsconfig.json @@ -11,7 +11,7 @@ "baseUrl": ".", "paths": { "types": ["src/types"] - }, + } }, "include": ["src", "api-src"] } diff --git a/cli/tauri.js/webpack.config.js b/cli/tauri.js/webpack.config.js index a5bdfa25b..b01f38511 100644 --- a/cli/tauri.js/webpack.config.js +++ b/cli/tauri.js/webpack.config.js @@ -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') } diff --git a/cli/tauri.js/yarn.lock b/cli/tauri.js/yarn.lock index 5213f56ce..29534fad6 100644 --- a/cli/tauri.js/yarn.lock +++ b/cli/tauri.js/yarn.lock @@ -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" diff --git a/package.json b/package.json index fca0416f1..dea07adc8 100644 --- a/package.json +++ b/package.json @@ -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" } }