diff --git a/.github/workflows/js-lint.yml b/.github/workflows/js-lint.yml index a7ddf4aa5..5528c4120 100644 --- a/.github/workflows/js-lint.yml +++ b/.github/workflows/js-lint.yml @@ -9,6 +9,8 @@ on: paths: - '.github/workflows/js-lint.yml' - 'tooling/cli.js/**' + - 'tooling/api/**' + - 'tooling/create-tauri-app/**' jobs: eslint-check: @@ -18,12 +20,32 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '12' - - name: install deps via yarn + - name: install cli.js deps via yarn working-directory: ./tooling/cli.js/ run: yarn - - name: run eslint + - name: run cli.js lint working-directory: ./tooling/cli.js/ run: yarn lint - - name: run prettier + - name: run cli.js format working-directory: ./tooling/cli.js/ run: yarn format:check + + - name: install api deps via yarn + working-directory: ./tooling/api/ + run: yarn + - name: run api lint + working-directory: ./tooling/api/ + run: yarn lint + - name: run api format + working-directory: ./tooling/api/ + run: yarn format:check + + - name: install create-tauri-app deps via yarn + working-directory: ./tooling/create-tauri-app/ + run: yarn + - name: run create-tauri-app lint + working-directory: ./tooling/create-tauri-app/ + run: yarn lint + - name: run create-tauri-app format + working-directory: ./tooling/create-tauri-app/ + run: yarn format:check diff --git a/.husky/pre-commit b/.husky/pre-commit index f0fdbcd6a..e38b205ae 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -9,6 +9,11 @@ cd tooling/api yarn format yarn lint-fix + cd ../cli.js yarn format yarn lint-fix + +cd ../create-tauri-app +yarn format +yarn lint-fix diff --git a/tooling/create-tauri-app/.eslintrc.js b/tooling/create-tauri-app/.eslintrc.js new file mode 100644 index 000000000..24b1e39d2 --- /dev/null +++ b/tooling/create-tauri-app/.eslintrc.js @@ -0,0 +1,55 @@ +module.exports = { + root: true, + + env: { + node: true, + jest: true + }, + + parser: '@typescript-eslint/parser', + + extends: [ + 'standard-with-typescript', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:lodash-template/recommended', + // TODO: make this work with typescript + // 'plugin:node/recommended' + 'prettier' + ], + + plugins: ['@typescript-eslint', 'node', 'security'], + + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + }, + + globals: { + __statics: true, + process: true + }, + + // add your custom rules here + rules: { + // allow console.log during development only + 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', + // allow debugger during development only + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'no-process-exit': 'off', + 'security/detect-non-literal-fs-filename': 'warn', + 'security/detect-unsafe-regex': 'error', + 'security/detect-buffer-noassert': 'error', + 'security/detect-child-process': 'warn', + 'security/detect-disable-mustache-escape': 'error', + 'security/detect-eval-with-expression': 'error', + 'security/detect-no-csrf-before-method-override': 'error', + 'security/detect-non-literal-regexp': 'error', + 'security/detect-non-literal-require': 'warn', + 'security/detect-object-injection': 'warn', + 'security/detect-possible-timing-attacks': 'error', + 'security/detect-pseudoRandomBytes': 'error', + 'space-before-function-paren': 'off', + '@typescript-eslint/default-param-last': 'off', + '@typescript-eslint/strict-boolean-expressions': 0 + } +} diff --git a/tooling/create-tauri-app/.prettierrc.js b/tooling/create-tauri-app/.prettierrc.js new file mode 100644 index 000000000..2be2f9327 --- /dev/null +++ b/tooling/create-tauri-app/.prettierrc.js @@ -0,0 +1,5 @@ +module.exports = { + singleQuote: true, + semi: false, + trailingComma: 'none' +} diff --git a/tooling/create-tauri-app/bin/create-tauri-app.js b/tooling/create-tauri-app/bin/create-tauri-app.js index 007e9a041..16fb0de9b 100755 --- a/tooling/create-tauri-app/bin/create-tauri-app.js +++ b/tooling/create-tauri-app/bin/create-tauri-app.js @@ -3,9 +3,9 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -const parseArgs = require("minimist"); -const inquirer = require("inquirer"); -const { resolve, join } = require("path"); +const parseArgs = require('minimist') +const inquirer = require('inquirer') +const { resolve, join } = require('path') const { recipeShortNames, recipeDescriptiveNames, @@ -14,8 +14,8 @@ const { install, checkPackageManager, shell, - addTauriScript, -} = require("../dist/"); + addTauriScript +} = require('../dist/') /** * @type {object} @@ -35,41 +35,41 @@ const { const createTauriApp = async (cliArgs) => { const argv = parseArgs(cliArgs, { alias: { - h: "help", - v: "version", - f: "force", - l: "log", - m: "manager", - d: "directory", - b: "binary", - t: "tauri-path", - A: "app-name", - W: "window-title", - D: "dist-dir", - P: "dev-path", - r: "recipe", + h: 'help', + v: 'version', + f: 'force', + l: 'log', + m: 'manager', + d: 'directory', + b: 'binary', + t: 'tauri-path', + A: 'app-name', + W: 'window-title', + D: 'dist-dir', + P: 'dev-path', + r: 'recipe' }, - boolean: ["h", "l", "ci"], - }); + boolean: ['h', 'l', 'ci'] + }) if (argv.help) { - printUsage(); - return 0; + printUsage() + return 0 } if (argv.v) { - console.log(require("../package.json").version); - return false; // do this for node consumers and tests + console.log(require('../package.json').version) + return false // do this for node consumers and tests } if (argv.ci) { - return runInit(argv); + return runInit(argv) } else { return getOptionsInteractive(argv).then((responses) => runInit(argv, responses) - ); + ) } -}; +} function printUsage() { console.log(` @@ -91,146 +91,146 @@ function printUsage() { --dist-dir, -D Web assets location, relative to /src-tauri --dev-path, -P Url of your dev server --recipe, -r Add UI framework recipe. None by default. - Supported recipes: [${recipeShortNames.join("|")}] - `); + Supported recipes: [${recipeShortNames.join('|')}] + `) } const getOptionsInteractive = (argv) => { - let defaultAppName = argv.A || "tauri-app"; + let defaultAppName = argv.A || 'tauri-app' return inquirer .prompt([ { - type: "input", - name: "appName", - message: "What is your app name?", + type: 'input', + name: 'appName', + message: 'What is your app name?', default: defaultAppName, - when: !argv.A, + when: !argv.A }, { - type: "input", - name: "tauri.window.title", - message: "What should the window title be?", - default: "Tauri App", - when: () => !argv.W, + type: 'input', + name: 'tauri.window.title', + message: 'What should the window title be?', + default: 'Tauri App', + when: () => !argv.W }, { - type: "list", - name: "recipeName", - message: "Would you like to add a UI recipe?", + type: 'list', + name: 'recipeName', + message: 'Would you like to add a UI recipe?', choices: recipeDescriptiveNames, - default: "No recipe", - when: () => !argv.r, - }, + default: 'No recipe', + when: () => !argv.r + } ]) .catch((error) => { if (error.isTtyError) { // Prompt couldn't be rendered in the current environment console.log( - "It appears your terminal does not support interactive prompts. Using default values." - ); - runInit(); + 'It appears your terminal does not support interactive prompts. Using default values.' + ) + runInit() } else { // Something else went wrong - console.error("An unknown error occurred:", error); + console.error('An unknown error occurred:', error) } - }); -}; + }) +} async function runInit(argv, config = {}) { const { appName, recipeName, tauri: { - window: { title }, - }, - } = config; + window: { title } + } + } = config // this little fun snippet pulled from vite determines the package manager the script was run from - const packageManager = /yarn/.test(process.env.npm_execpath) ? "yarn" : "npm"; + const packageManager = /yarn/.test(process.env.npm_execpath) ? 'yarn' : 'npm' - let recipe; + let recipe if (recipeName !== undefined) { - recipe = recipeByDescriptiveName(recipeName); + recipe = recipeByDescriptiveName(recipeName) } else if (argv.r) { - recipe = recipeByShortName(argv.r); + recipe = recipeByShortName(argv.r) } let buildConfig = { distDir: argv.D, - devPath: argv.P, - }; - - if (recipe !== undefined) { - buildConfig = recipe.configUpdate({ buildConfig, packageManager }); + devPath: argv.P } - const directory = argv.d || process.cwd(); + if (recipe !== undefined) { + buildConfig = recipe.configUpdate({ buildConfig, packageManager }) + } + + const directory = argv.d || process.cwd() const cfg = { ...buildConfig, appName: appName || argv.A, - windowTitle: title || argv.w, - }; + windowTitle: title || argv.w + } // note that our app directory is reliant on the appName and // generally there are issues if the path has spaces (see Windows) // future TODO prevent app names with spaces or escape here? - const appDirectory = join(directory, cfg.appName); + const appDirectory = join(directory, cfg.appName) // this throws an error if we can't run the package manager they requested - await checkPackageManager({ cwd: directory, packageManager }); + await checkPackageManager({ cwd: directory, packageManager }) if (recipe.preInit) { - console.log("===== running initial command(s) ====="); - await recipe.preInit({ cwd: directory, cfg, packageManager }); + console.log('===== running initial command(s) =====') + await recipe.preInit({ cwd: directory, cfg, packageManager }) } const initArgs = [ - ["--app-name", cfg.appName], - ["--window-title", cfg.windowTitle], - ["--dist-dir", cfg.distDir], - ["--dev-path", cfg.devPath], + ['--app-name', cfg.appName], + ['--window-title', cfg.windowTitle], + ['--dist-dir', cfg.distDir], + ['--dev-path', cfg.devPath] ].reduce((final, argSet) => { if (argSet[1]) { - return final.concat(argSet); + return final.concat(argSet) } else { - return final; + return final } - }, []); + }, []) // Vue CLI plugin automatically runs these - if (recipe.shortName !== "vuecli") { - console.log("===== installing any additional needed deps ====="); + if (recipe.shortName !== 'vuecli') { + console.log('===== installing any additional needed deps =====') await install({ appDir: appDirectory, dependencies: recipe.extraNpmDependencies, - devDependencies: ["@tauri-apps/cli", ...recipe.extraNpmDevDependencies], - packageManager, - }); + devDependencies: ['@tauri-apps/cli', ...recipe.extraNpmDevDependencies], + packageManager + }) - console.log("===== running tauri init ====="); - addTauriScript(appDirectory); + console.log('===== running tauri init =====') + addTauriScript(appDirectory) - const binary = !argv.b ? packageManager : resolve(appDirectory, argv.b); + const binary = !argv.b ? packageManager : resolve(appDirectory, argv.b) const runTauriArgs = - packageManager === "npm" && !argv.b - ? ["run", "tauri", "--", "init"] - : ["tauri", "init"]; + packageManager === 'npm' && !argv.b + ? ['run', 'tauri', '--', 'init'] + : ['tauri', 'init'] await shell(binary, [...runTauriArgs, ...initArgs], { - cwd: appDirectory, - }); + cwd: appDirectory + }) } if (recipe.postInit) { - console.log("===== running final command(s) ====="); + console.log('===== running final command(s) =====') await recipe.postInit({ cwd: appDirectory, cfg, - packageManager, - }); + packageManager + }) } } createTauriApp(process.argv.slice(2)).catch((err) => { - console.error(err); -}); + console.error(err) +}) diff --git a/tooling/create-tauri-app/package.json b/tooling/create-tauri-app/package.json index da687d75e..717e6b4a9 100644 --- a/tooling/create-tauri-app/package.json +++ b/tooling/create-tauri-app/package.json @@ -24,7 +24,12 @@ "scripts": { "create-tauri-app": "create-tauri-app", "build": "rollup --config", - "prepublishOnly": "yarn build" + "prepublishOnly": "yarn build", + "lint": "eslint --ext ts \"./src/**/*.ts\"", + "lint-fix": "eslint --fix --ext ts \"./src/**/*.ts\"", + "lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts npm yarn", + "format": "prettier --write --end-of-line=auto \"./**/*.{js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore", + "format:check": "prettier --check --end-of-line=auto \"./**/*.{js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore" }, "dependencies": { "execa": "^5.0.0", @@ -33,15 +38,25 @@ "scaffe": "1.0.0" }, "devDependencies": { - "@rollup/plugin-commonjs": "^18.0.0", - "@rollup/plugin-node-resolve": "^11.2.1", - "@rollup/plugin-typescript": "^8.2.1", + "@rollup/plugin-commonjs": "18.0.0", + "@rollup/plugin-node-resolve": "11.2.1", + "@rollup/plugin-typescript": "8.2.1", + "@typescript-eslint/eslint-plugin": "4.22.0", + "@typescript-eslint/parser": "4.22.0", "@types/cross-spawn": "6.0.2", "@types/inquirer": "7.3.1", "@types/semver": "7.3.4", - "prettier": "^2.2.1", - "rollup": "^2.45.1", - "tslib": "^2.2.0", + "eslint": "7.24.0", + "eslint-config-prettier": "8.2.0", + "eslint-config-standard-with-typescript": "20.0.0", + "eslint-plugin-import": "2.22.1", + "eslint-plugin-lodash-template": "0.19.0", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-promise": "5.1.0", + "eslint-plugin-security": "1.4.0", + "prettier": "2.2.1", + "rollup": "2.45.1", + "tslib": "2.2.0", "typescript": "4.2.4" } } diff --git a/tooling/create-tauri-app/rollup.config.js b/tooling/create-tauri-app/rollup.config.js index 9885b1eb8..b308bda8a 100644 --- a/tooling/create-tauri-app/rollup.config.js +++ b/tooling/create-tauri-app/rollup.config.js @@ -1,27 +1,27 @@ -import typescript from "@rollup/plugin-typescript"; -import commonjs from "@rollup/plugin-commonjs"; -import pkg from "./package.json"; +import typescript from '@rollup/plugin-typescript' +import commonjs from '@rollup/plugin-commonjs' +import pkg from './package.json' export default { treeshake: true, perf: true, - input: "src/index.ts", + input: 'src/index.ts', output: { - dir: "dist", - format: "cjs", - entryFileNames: "[name].js", - exports: "named", + dir: 'dist', + format: 'cjs', + entryFileNames: '[name].js', + exports: 'named' }, - plugins: [typescript(), commonjs({ extensions: [".js"] })], + plugins: [typescript(), commonjs({ extensions: ['.js'] })], external: [ - "fs", - "path", + 'fs', + 'path', ...Object.keys(pkg.dependencies || {}), - ...Object.keys(pkg.peerDependencies || {}), + ...Object.keys(pkg.peerDependencies || {}) ], watch: { chokidar: true, - include: "src/**", - exclude: "node_modules/**", - }, -}; + include: 'src/**', + exclude: 'node_modules/**' + } +} diff --git a/tooling/create-tauri-app/src/dependency-manager.ts b/tooling/create-tauri-app/src/dependency-manager.ts index 734c0fba1..c671f6c8c 100644 --- a/tooling/create-tauri-app/src/dependency-manager.ts +++ b/tooling/create-tauri-app/src/dependency-manager.ts @@ -2,46 +2,46 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { ManagementType, Result } from "./types/deps"; -import { shell } from "./shell"; +import { ManagementType, Result } from './types/deps' +import { shell } from './shell' -export type PackageManager = "npm" | "yarn"; +export type PackageManager = 'npm' | 'yarn' export async function install({ appDir, dependencies, devDependencies, - packageManager, + packageManager }: { - appDir: string; - dependencies: string[]; - devDependencies: string[]; - packageManager: PackageManager; + appDir: string + dependencies: string[] + devDependencies: string[] + packageManager: PackageManager }): Promise { - const result: Result = new Map(); - await installNpmDevPackage(devDependencies, packageManager, appDir); - result.set(ManagementType.Install, devDependencies); + const result: Result = new Map() + await installNpmDevPackage(devDependencies, packageManager, appDir) + result.set(ManagementType.Install, devDependencies) - await installNpmPackage(dependencies, packageManager, appDir); - result.set(ManagementType.Install, dependencies); + await installNpmPackage(dependencies, packageManager, appDir) + result.set(ManagementType.Install, dependencies) - return result; + return result } export async function checkPackageManager({ cwd, - packageManager, + packageManager }: { - cwd: string; - packageManager: PackageManager; + cwd: string + packageManager: PackageManager }): Promise { try { - await shell(packageManager, ["--version"], { stdio: "pipe", cwd }); - return true; + await shell(packageManager, ['--version'], { stdio: 'pipe', cwd }) + return true } catch (error) { throw new Error( `Must have ${packageManager} installed to manage dependencies. Is either in your PATH? We tried running in ${cwd}` - ); + ) } } @@ -50,16 +50,16 @@ async function installNpmPackage( packageManager: PackageManager, appDir: string ): Promise { - if (packageNames.length === 0) return; - console.log(`Installing ${packageNames.join(", ")}...`); - if (packageManager === "yarn") { - await shell("yarn", ["add", packageNames.join(" ")], { - cwd: appDir, - }); + if (packageNames.length === 0) return + console.log(`Installing ${packageNames.join(', ')}...`) + if (packageManager === 'yarn') { + await shell('yarn', ['add', packageNames.join(' ')], { + cwd: appDir + }) } else { - await shell("npm", ["install", packageNames.join(" ")], { - cwd: appDir, - }); + await shell('npm', ['install', packageNames.join(' ')], { + cwd: appDir + }) } } @@ -68,23 +68,23 @@ async function installNpmDevPackage( packageManager: PackageManager, appDir: string ): Promise { - if (packageNames.length === 0) return; - console.log(`Installing ${packageNames.join(", ")}...`); - if (packageManager === "yarn") { + if (packageNames.length === 0) return + console.log(`Installing ${packageNames.join(', ')}...`) + if (packageManager === 'yarn') { await shell( - "yarn", - ["add", "--dev", "--ignore-scripts", packageNames.join(" ")], + 'yarn', + ['add', '--dev', '--ignore-scripts', packageNames.join(' ')], { - cwd: appDir, + cwd: appDir } - ); + ) } else { await shell( - "npm", - ["install", "--save-dev", "--ignore-scripts", packageNames.join(" ")], + 'npm', + ['install', '--save-dev', '--ignore-scripts', packageNames.join(' ')], { - cwd: appDir, + cwd: appDir } - ); + ) } } diff --git a/tooling/create-tauri-app/src/helpers/add-tauri-script.ts b/tooling/create-tauri-app/src/helpers/add-tauri-script.ts index 39355c9d1..24e14eb1c 100644 --- a/tooling/create-tauri-app/src/helpers/add-tauri-script.ts +++ b/tooling/create-tauri-app/src/helpers/add-tauri-script.ts @@ -2,25 +2,25 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { readFileSync, writeFileSync } from "fs"; -import { join } from "path"; +import { readFileSync, writeFileSync } from 'fs' +import { join } from 'path' -export async function addTauriScript(appDirectory: string) { - const pkgPath = join(appDirectory, "package.json"); - const pkgString = readFileSync(pkgPath, "utf8"); +export function addTauriScript(appDirectory: string): void { + const pkgPath = join(appDirectory, 'package.json') + const pkgString = readFileSync(pkgPath, 'utf8') const pkg = JSON.parse(pkgString) as { scripts: { - tauri: string; - }; - }; + tauri: string + } + } const outputPkg = { ...pkg, scripts: { ...pkg.scripts, - tauri: "tauri", - }, - }; + tauri: 'tauri' + } + } - writeFileSync(pkgPath, JSON.stringify(outputPkg, undefined, 2)); + writeFileSync(pkgPath, JSON.stringify(outputPkg, undefined, 2)) } diff --git a/tooling/create-tauri-app/src/index.ts b/tooling/create-tauri-app/src/index.ts index b45647383..2e0537926 100644 --- a/tooling/create-tauri-app/src/index.ts +++ b/tooling/create-tauri-app/src/index.ts @@ -2,62 +2,62 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { TauriBuildConfig } from "./types/config"; -import { reactjs, reactts } from "./recipes/react"; -import { vuecli } from "./recipes/vue-cli"; -import { vanillajs } from "./recipes/vanilla"; -import { vite } from "./recipes/vite"; +import { TauriBuildConfig } from './types/config' +import { reactjs, reactts } from './recipes/react' +import { vuecli } from './recipes/vue-cli' +import { vanillajs } from './recipes/vanilla' +import { vite } from './recipes/vite' +import { PackageManager } from './dependency-manager' -export { shell } from "./shell"; -export { install, checkPackageManager } from "./dependency-manager"; -export { addTauriScript } from "./helpers/add-tauri-script"; -import { PackageManager } from "./dependency-manager"; +export { shell } from './shell' +export { install, checkPackageManager } from './dependency-manager' +export { addTauriScript } from './helpers/add-tauri-script' export interface Recipe { - descriptiveName: string; - shortName: string; + descriptiveName: string + shortName: string configUpdate?: ({ cfg, - packageManager, + packageManager }: { - cfg: TauriBuildConfig; - packageManager: PackageManager; - }) => TauriBuildConfig; - extraNpmDependencies: string[]; - extraNpmDevDependencies: string[]; + cfg: TauriBuildConfig + packageManager: PackageManager + }) => TauriBuildConfig + extraNpmDependencies: string[] + extraNpmDevDependencies: string[] preInit?: ({ cwd, cfg, - packageManager, + packageManager }: { - cwd: string; - cfg: TauriBuildConfig; - packageManager: PackageManager; - }) => Promise; + cwd: string + cfg: TauriBuildConfig + packageManager: PackageManager + }) => Promise postInit?: ({ cwd, cfg, - packageManager, + packageManager }: { - cwd: string; - cfg: TauriBuildConfig; - packageManager: PackageManager; - }) => Promise; + cwd: string + cfg: TauriBuildConfig + packageManager: PackageManager + }) => Promise } -export const allRecipes: Recipe[] = [vanillajs, reactjs, reactts, vite, vuecli]; +export const allRecipes: Recipe[] = [vanillajs, reactjs, reactts, vite, vuecli] export const recipeNames: Array<[string, string]> = allRecipes.map((r) => [ r.shortName, - r.descriptiveName, -]); + r.descriptiveName +]) -export const recipeByShortName = (name: string) => - allRecipes.find((r) => r.shortName === name); +export const recipeByShortName = (name: string): Recipe | undefined => + allRecipes.find((r) => r.shortName === name) -export const recipeByDescriptiveName = (name: string) => - allRecipes.find((r) => r.descriptiveName === name); +export const recipeByDescriptiveName = (name: string): Recipe | undefined => + allRecipes.find((r) => r.descriptiveName === name) -export const recipeShortNames = allRecipes.map((r) => r.shortName); +export const recipeShortNames = allRecipes.map((r) => r.shortName) -export const recipeDescriptiveNames = allRecipes.map((r) => r.descriptiveName); +export const recipeDescriptiveNames = allRecipes.map((r) => r.descriptiveName) diff --git a/tooling/create-tauri-app/src/recipes/react.ts b/tooling/create-tauri-app/src/recipes/react.ts index a24acf5bc..6b3cfa4f7 100644 --- a/tooling/create-tauri-app/src/recipes/react.ts +++ b/tooling/create-tauri-app/src/recipes/react.ts @@ -2,104 +2,107 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { Recipe } from ".."; -import { join } from "path"; -//@ts-ignore -import scaffe from "scaffe"; -import { shell } from "../shell"; +import { Recipe } from '..' +import { join } from 'path' +// @ts-expect-error +import scaffe from 'scaffe' +import { shell } from '../shell' const afterCra = async ( cwd: string, appName: string, typescript: boolean = false -) => { +): Promise => { const templateDir = join( __dirname, - `../src/templates/react/${typescript ? "react-ts" : "react"}` - ); + `../src/templates/react/${typescript ? 'react-ts' : 'react'}` + ) try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call await scaffe.generate(templateDir, join(cwd, appName), { - overwrite: true, - }); + overwrite: true + }) } catch (err) { - console.log(err); + console.log(err) } -}; +} const reactjs: Recipe = { - descriptiveName: "React.js", - shortName: "reactjs", + descriptiveName: 'React.js', + shortName: 'reactjs', configUpdate: ({ cfg, packageManager }) => ({ ...cfg, distDir: `../build`, - devPath: "http://localhost:3000", - beforeDevCommand: `${packageManager === "yarn" ? "yarn" : "npm run"} start`, + devPath: 'http://localhost:3000', + beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`, beforeBuildCommand: `${ - packageManager === "yarn" ? "yarn" : "npm run" - } build`, + packageManager === 'yarn' ? 'yarn' : 'npm run' + } build` }), extraNpmDevDependencies: [], extraNpmDependencies: [], preInit: async ({ cwd, cfg, packageManager }) => { // CRA creates the folder for you - if (packageManager === "yarn") { - await shell("yarn", ["create", "react-app", `${cfg.appName}`], { - cwd, - }); + if (packageManager === 'yarn') { + await shell('yarn', ['create', 'react-app', `${cfg.appName}`], { + cwd + }) } else { - await shell("npx", ["create-react-app", `${cfg.appName}`, "--use-npm"], { - cwd, - }); + await shell('npx', ['create-react-app', `${cfg.appName}`, '--use-npm'], { + cwd + }) } - await afterCra(cwd, cfg.appName); + await afterCra(cwd, cfg.appName) }, postInit: async ({ packageManager }) => { console.log(` Your installation completed. - To start, run ${packageManager === "yarn" ? "yarn" : "npm run"} tauri dev - `); - }, -}; + To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri dev + `) + return await Promise.resolve() + } +} const reactts: Recipe = { ...reactjs, - descriptiveName: "React with Typescript", - shortName: "reactts", + descriptiveName: 'React with Typescript', + shortName: 'reactts', extraNpmDependencies: [], preInit: async ({ cwd, cfg, packageManager }) => { // CRA creates the folder for you - if (packageManager === "yarn") { + if (packageManager === 'yarn') { await shell( - "yarn", - ["create", "react-app", "--template", "typescript", `${cfg.appName}`], + 'yarn', + ['create', 'react-app', '--template', 'typescript', `${cfg.appName}`], { - cwd, + cwd } - ); + ) } else { await shell( - "npx", + 'npx', [ - "create-react-app", + 'create-react-app', `${cfg.appName}`, - "--use-npm", - "--template", - "typescript", + '--use-npm', + '--template', + 'typescript' ], { - cwd, + cwd } - ); + ) } - await afterCra(cwd, cfg.appName, true); + await afterCra(cwd, cfg.appName, true) }, postInit: async ({ packageManager }) => { console.log(` Your installation completed. - To start, run ${packageManager === "yarn" ? "yarn" : "npm run"} tauri dev - `); - }, -}; + To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri dev + `) + return await Promise.resolve() + } +} -export { reactjs, reactts }; +export { reactjs, reactts } diff --git a/tooling/create-tauri-app/src/recipes/vanilla.ts b/tooling/create-tauri-app/src/recipes/vanilla.ts index 2e17fb197..f7cb0d20e 100644 --- a/tooling/create-tauri-app/src/recipes/vanilla.ts +++ b/tooling/create-tauri-app/src/recipes/vanilla.ts @@ -2,49 +2,50 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { Recipe } from ".."; -import { join } from "path"; -//@ts-ignore -import scaffe from "scaffe"; +import { Recipe } from '..' +import { join } from 'path' +// @ts-expect-error +import scaffe from 'scaffe' export const vanillajs: Recipe = { - descriptiveName: "Vanilla.js", - shortName: "vanillajs", + descriptiveName: 'Vanilla.js', + shortName: 'vanillajs', configUpdate: ({ cfg, packageManager }) => ({ ...cfg, distDir: `../dist`, devPath: `../dist`, - beforeDevCommand: `${packageManager === "yarn" ? "yarn" : "npm run"} start`, + beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`, beforeBuildCommand: `${ - packageManager === "yarn" ? "yarn" : "npm run" - } build`, + packageManager === 'yarn' ? 'yarn' : 'npm run' + } build` }), extraNpmDevDependencies: [], extraNpmDependencies: [], preInit: async ({ cwd, cfg }) => { - const { appName } = cfg; - const templateDir = join(__dirname, "../src/templates/vanilla"); + const { appName } = cfg + const templateDir = join(__dirname, '../src/templates/vanilla') const variables = { - name: appName, - }; + name: appName + } try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call await scaffe.generate(templateDir, join(cwd, appName), { overwrite: true, - variables, - }); + variables + }) } catch (err) { - console.log(err); + console.log(err) } }, postInit: async ({ cfg, packageManager }) => { const setApp = - packageManager === "npm" + packageManager === 'npm' ? ` set tauri script once $ npm set-script tauri tauri ` - : ""; + : '' console.log(` change directory: @@ -54,9 +55,10 @@ install dependencies: $ ${packageManager} install run the app: - $ ${packageManager === "yarn" ? "yarn" : "npm run"} tauri ${ - packageManager === "npm" ? "-- " : "" + $ ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri ${ + packageManager === 'npm' ? '-- ' : '' }dev - `); - }, -}; + `) + return await Promise.resolve() + } +} diff --git a/tooling/create-tauri-app/src/recipes/vite.ts b/tooling/create-tauri-app/src/recipes/vite.ts index 3314b639e..86d977507 100644 --- a/tooling/create-tauri-app/src/recipes/vite.ts +++ b/tooling/create-tauri-app/src/recipes/vite.ts @@ -2,98 +2,105 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { Recipe } from ".."; -import { join } from "path"; -import { readdirSync } from "fs"; -//@ts-ignore -import scaffe from "scaffe"; -import { shell } from "../shell"; -import inquirer from "inquirer"; +import { Recipe } from '..' +import { join } from 'path' +import { readdirSync } from 'fs' +// @ts-expect-error +import scaffe from 'scaffe' +import { shell } from '../shell' +import inquirer from 'inquirer' -const afterViteCA = async (cwd: string, appName: string, template: string) => { - const templateDir = join(__dirname, `../src/templates/vite/${template}`); +const afterViteCA = async ( + cwd: string, + appName: string, + template: string +): Promise => { + const templateDir = join(__dirname, `../src/templates/vite/${template}`) try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call await scaffe.generate(templateDir, join(cwd, appName), { - overwrite: true, - }); + overwrite: true + }) } catch (err) { - console.log(err); + console.log(err) } -}; +} const vite: Recipe = { - descriptiveName: "Vite backed recipe", - shortName: "vite", + descriptiveName: 'Vite backed recipe', + shortName: 'vite', configUpdate: ({ cfg, packageManager }) => ({ ...cfg, distDir: `../dist`, - devPath: "http://localhost:3000", - beforeDevCommand: `${packageManager === "yarn" ? "yarn" : "npm run"} start`, + devPath: 'http://localhost:3000', + beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`, beforeBuildCommand: `${ - packageManager === "yarn" ? "yarn" : "npm run" - } build`, + packageManager === 'yarn' ? 'yarn' : 'npm run' + } build` }), extraNpmDevDependencies: [], extraNpmDependencies: [], preInit: async ({ cwd, cfg, packageManager }) => { try { - const { template } = await inquirer.prompt([ + const { template } = (await inquirer.prompt([ { - type: "list", - name: "template", - message: "Which vite template would you like to use?", - choices: readdirSync(join(__dirname, "../src/templates/vite")), - default: "vue", - }, - ]); + type: 'list', + name: 'template', + message: 'Which vite template would you like to use?', + choices: readdirSync(join(__dirname, '../src/templates/vite')), + default: 'vue' + } + ])) as { template: string } // Vite creates the folder for you - if (packageManager === "yarn") { + if (packageManager === 'yarn') { await shell( - "yarn", + 'yarn', [ - "create", - "@vitejs/app", + 'create', + '@vitejs/app', `${cfg.appName}`, - "--template", - `${template}`, + '--template', + `${template}` ], { - cwd, + cwd } - ); + ) } else { await shell( - "npx", - ["@vitejs/create-app", `${cfg.appName}`, "--template", `${template}`], + 'npx', + ['@vitejs/create-app', `${cfg.appName}`, '--template', `${template}`], { - cwd, + cwd } - ); + ) } - await afterViteCA(cwd, cfg.appName, template); + await afterViteCA(cwd, cfg.appName, template) } catch (error) { - if (error.isTtyError) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (error?.isTtyError) { // Prompt couldn't be rendered in the current environment console.log( - "It appears your terminal does not support interactive prompts. Using default values." - ); + 'It appears your terminal does not support interactive prompts. Using default values.' + ) } else { // Something else went wrong - console.error("An unknown error occurred:", error); + console.error('An unknown error occurred:', error) } } }, postInit: async ({ packageManager }) => { console.log(` Your installation completed. - To start, run ${packageManager === "yarn" ? "yarn" : "npm run"} tauri ${ - packageManager === "npm" ? "--" : "" + To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri ${ + packageManager === 'npm' ? '--' : '' } dev - `); - }, -}; + `) + return await Promise.resolve() + } +} -export { vite }; +export { vite } diff --git a/tooling/create-tauri-app/src/recipes/vue-cli.ts b/tooling/create-tauri-app/src/recipes/vue-cli.ts index 6162adbec..1d69a917d 100644 --- a/tooling/create-tauri-app/src/recipes/vue-cli.ts +++ b/tooling/create-tauri-app/src/recipes/vue-cli.ts @@ -2,43 +2,44 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { Recipe } from ".."; -import { join } from "path"; -import { shell } from "../shell"; +import { Recipe } from '..' +import { join } from 'path' +import { shell } from '../shell' const completeLogMsg = ` Your installation completed. To start, run yarn tauri:serve -`; +` const vuecli: Recipe = { - descriptiveName: "Vue CLI", - shortName: "vuecli", + descriptiveName: 'Vue CLI', + shortName: 'vuecli', extraNpmDevDependencies: [], extraNpmDependencies: [], configUpdate: ({ cfg }) => cfg, preInit: async ({ cwd, cfg }) => { // Vue CLI creates the folder for you - await shell("npx", ["@vue/cli", "create", `${cfg.appName}`], { cwd }); + await shell('npx', ['@vue/cli', 'create', `${cfg.appName}`], { cwd }) await shell( - "npx", + 'npx', [ - "@vue/cli", - "add", - "tauri", - "--appName", + '@vue/cli', + 'add', + 'tauri', + '--appName', `${cfg.appName}`, - "--windowTitle", - `${cfg.windowTitle}`, + '--windowTitle', + `${cfg.windowTitle}` ], { - cwd: join(cwd, cfg.appName), + cwd: join(cwd, cfg.appName) } - ); + ) }, postInit: async () => { - console.log(completeLogMsg); - }, -}; + console.log(completeLogMsg) + return await Promise.resolve() + } +} -export { vuecli }; +export { vuecli } diff --git a/tooling/create-tauri-app/src/shell.ts b/tooling/create-tauri-app/src/shell.ts index e3a2e7c01..0473e994e 100644 --- a/tooling/create-tauri-app/src/shell.ts +++ b/tooling/create-tauri-app/src/shell.ts @@ -2,35 +2,35 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import execa from "execa"; +import execa from 'execa' export const shell = async ( command: string, args?: string[], options?: execa.Options, log: boolean = false -) => { +): Promise => { try { if (options && options.shell === true) { - const stringCommand = [command, ...(!args ? [] : args)].join(" "); - if (log) console.log(`[running]: ${stringCommand}`); + const stringCommand = [command, ...(!args ? [] : args)].join(' ') + if (log) console.log(`[running]: ${stringCommand}`) return await execa(stringCommand, { - stdio: "inherit", + stdio: 'inherit', cwd: process.cwd(), env: process.env, - ...options, - }); + ...options + }) } else { - if (log) console.log(`[running]: ${command}`); + if (log) console.log(`[running]: ${command}`) return await execa(command, args, { - stdio: "inherit", + stdio: 'inherit', cwd: process.cwd(), env: process.env, - ...options, - }); + ...options + }) } } catch (error) { - console.error("Error with command: %s", command); - throw new Error(error); + console.error('Error with command: %s', command) + throw new Error(error) } -}; +} diff --git a/tooling/create-tauri-app/src/templates/react/react-ts/src/App.tsx b/tooling/create-tauri-app/src/templates/react/react-ts/src/App.tsx index 36ba28f00..2236bfbb8 100644 --- a/tooling/create-tauri-app/src/templates/react/react-ts/src/App.tsx +++ b/tooling/create-tauri-app/src/templates/react/react-ts/src/App.tsx @@ -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 ( @@ -34,7 +34,7 @@ function App() {

- ); + ) } -export default App; +export default App diff --git a/tooling/create-tauri-app/src/templates/react/react/src/App.js b/tooling/create-tauri-app/src/templates/react/react/src/App.js index 36ba28f00..2236bfbb8 100644 --- a/tooling/create-tauri-app/src/templates/react/react/src/App.js +++ b/tooling/create-tauri-app/src/templates/react/react/src/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 ( @@ -34,7 +34,7 @@ function App() {

- ); + ) } -export default App; +export default App diff --git a/tooling/create-tauri-app/src/types/config.ts b/tooling/create-tauri-app/src/types/config.ts index f7dd3803a..2795d7d60 100644 --- a/tooling/create-tauri-app/src/types/config.ts +++ b/tooling/create-tauri-app/src/types/config.ts @@ -3,24 +3,24 @@ // SPDX-License-Identifier: MIT export interface TauriBuildConfig { - appName: string; - windowTitle: string; + appName: string + windowTitle: string /** * the path to the app's dist dir * this path must contain your index.html file */ - distDir: string; + distDir: string /** * the app's dev server URL, or the path to the directory containing an index.html to open */ - devPath: string; + devPath: string /** * a shell command to run before `tauri dev` kicks in */ - beforeDevCommand?: string; + beforeDevCommand?: string /** * a shell command to run before `tauri build` kicks in */ - beforeBuildCommand?: string; - withGlobalTauri?: boolean; + beforeBuildCommand?: string + withGlobalTauri?: boolean } diff --git a/tooling/create-tauri-app/src/types/deps.ts b/tooling/create-tauri-app/src/types/deps.ts index 6cf06569f..15a525bae 100644 --- a/tooling/create-tauri-app/src/types/deps.ts +++ b/tooling/create-tauri-app/src/types/deps.ts @@ -5,7 +5,7 @@ export enum ManagementType { Install, InstallDev, - Update, + Update } -export type Result = Map; +export type Result = Map