New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

create-tauri-app

Package Overview
Dependencies
Maintainers
2
Versions
144
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

create-tauri-app - npm Package Compare versions

Comparing version 1.0.0-beta-rc.4 to 1.0.0-rc.0

src/templates/dominator/_.gitignore

228

bin/create-tauri-app.js

@@ -6,232 +6,6 @@ #!/usr/bin/env node

const parseArgs = require('minimist')
const inquirer = require('inquirer')
const { resolve, join } = require('path')
const {
recipeShortNames,
recipeDescriptiveNames,
recipeByDescriptiveName,
recipeByShortName,
install,
checkPackageManager,
shell,
addTauriScript
} = require('../dist/')
const { createTauriApp } = require('../dist/')
/**
* @type {object}
* @property {boolean} h
* @property {boolean} help
* @property {boolean} v
* @property {boolean} version
* @property {string|boolean} f
* @property {string|boolean} force
* @property {boolean} l
* @property {boolean} log
* @property {boolean} d
* @property {boolean} directory
* @property {string} r
* @property {string} recipe
*/
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'
},
boolean: ['h', 'l', 'ci']
})
if (argv.help) {
printUsage()
return 0
}
if (argv.v) {
console.log(require('../package.json').version)
return false // do this for node consumers and tests
}
if (argv.ci) {
return runInit(argv)
} else {
return getOptionsInteractive(argv).then((responses) =>
runInit(argv, responses)
)
}
}
function printUsage() {
console.log(`
Description
Starts a new tauri app from a "recipe" or pre-built template.
Usage
$ yarn create tauri-app <app-name> # npm create-tauri-app <app-name>
Options
--help, -h Displays this message
-v, --version Displays the Tauri CLI version
--ci Skip prompts
--force, -f Force init to overwrite [conf|template|all]
--log, -l Logging [boolean]
--manager, -d Set package manager to use [npm|yarn]
--directory, -d Set target directory for init
--binary, -b Optional path to a tauri binary from which to run init
--app-name, -A Name of your Tauri application
--window-title, -W Window title of your Tauri application
--dist-dir, -D Web assets location, relative to <project-dir>/src-tauri
--dev-path, -P Url of your dev server
--recipe, -r Add UI framework recipe. None by default.
Supported recipes: [${recipeShortNames.join('|')}]
`)
}
const getOptionsInteractive = (argv) => {
let defaultAppName = argv.A || 'tauri-app'
return inquirer
.prompt([
{
type: 'input',
name: 'appName',
message: 'What is your app name?',
default: defaultAppName,
when: !argv.A
},
{
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?',
choices: recipeDescriptiveNames,
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()
} else {
// Something else went wrong
console.error('An unknown error occurred:', error)
}
})
}
async function runInit(argv, config = {}) {
const {
appName,
recipeName,
tauri: {
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'
let recipe
if (recipeName !== undefined) {
recipe = recipeByDescriptiveName(recipeName)
} else if (argv.r) {
recipe = recipeByShortName(argv.r)
}
let buildConfig = {
distDir: argv.D,
devPath: argv.P
}
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
}
// 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)
// this throws an error if we can't run the package manager they requested
await checkPackageManager({ cwd: directory, packageManager })
if (recipe.preInit) {
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]
].reduce((final, argSet) => {
if (argSet[1]) {
return final.concat(argSet)
} else {
return final
}
}, [])
// Vue CLI plugin automatically runs these
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
})
console.log('===== running tauri init =====')
addTauriScript(appDirectory)
const binary = !argv.b ? packageManager : resolve(appDirectory, argv.b)
const runTauriArgs =
packageManager === 'npm' && !argv.b
? ['run', 'tauri', '--', 'init']
: ['tauri', 'init']
await shell(binary, [...runTauriArgs, ...initArgs], {
cwd: appDirectory
})
}
if (recipe.postInit) {
console.log('===== running final command(s) =====')
await recipe.postInit({
cwd: appDirectory,
cfg,
packageManager
})
}
}
createTauriApp(process.argv.slice(2)).catch((err) => {
console.error(err)
})
# Changelog
## \[1.0.0-rc.0]
- Add empty description to Cargo.toml in dominator recipe.
- [97edb3ac](https://www.github.com/tauri-apps/tauri/commit/97edb3ac49d59c5c95ad8486c17b3c333f4f86a2) Fix: [#2508](https://www.github.com/tauri-apps/tauri/pull/2508). Update dominator recipe description. ([#2514](https://www.github.com/tauri-apps/tauri/pull/2514)) on 2021-08-24
- `create-tauri-app` should now be fully compatiable with CI environments.
- [f5e77ff4](https://www.github.com/tauri-apps/tauri/commit/f5e77ff48f00e14476f95cce257d091377ba987c) refactor(cta): use `commander` instead of `minimst` ([#2551](https://www.github.com/tauri-apps/tauri/pull/2551)) on 2022-01-01
- Stop react recipe from opening in browser by default.
- [ea51504e](https://www.github.com/tauri-apps/tauri/commit/ea51504e3a57eedc28e40573fbcc899b8a5c358c) fix(cta): stop react recipe from opening in browser, closes [#2793](https://www.github.com/tauri-apps/tauri/pull/2793) ([#2988](https://www.github.com/tauri-apps/tauri/pull/2988)) on 2021-11-30
- Add SolidJS recipe using the official template.
- [71ea86a4](https://www.github.com/tauri-apps/tauri/commit/71ea86a443f2585fa98edd79f2361bd85b380f0c) feat(cta): add SolidJS recipe ([#2619](https://www.github.com/tauri-apps/tauri/pull/2619)) on 2021-09-22
## \[1.0.0-beta.4]
- [`pnpm`](https://pnpm.io) package manager is now officially supported, either run `pnpx create-tauri-app` or explicitly specifiy it `npx create-tauri-app --manager pnpm`.
- [235e0f67](https://www.github.com/tauri-apps/tauri/commit/235e0f6785b87dc83cc6ebb6f5b022a82fa18eec) feat(CTA): add official support for `pnpm` package manager ([#2348](https://www.github.com/tauri-apps/tauri/pull/2348)) on 2021-08-06
- `create-tauri-app` will prompt users to install `@tauri-apps/api` npm package.
- [c0f42ad0](https://www.github.com/tauri-apps/tauri/commit/c0f42ad0e3d30623b83cfcd692eb1bcb4c4391a2) feat(cta): prompt users to install `@tauri-apps/api` package ([#2251](https://www.github.com/tauri-apps/tauri/pull/2251)) on 2021-07-29
- Add Svelte recipe using the official template.
- [151c3157](https://www.github.com/tauri-apps/tauri/commit/151c3157bef28c267592ebdf717e4ff66a5b27e1) Add svelte recipe to create-tauri-app ([#2276](https://www.github.com/tauri-apps/tauri/pull/2276)) ([#2279](https://www.github.com/tauri-apps/tauri/pull/2279)) on 2021-07-22
- Adjust check for `dev` mode and switch CTA test to a script runner. The script gives us more control and better output into any failures.
- [c410e034](https://www.github.com/tauri-apps/tauri/commit/c410e034f74d0624c8465b1f30bb7af58eb98b34) convert jest tests to child_process run script ([#2308](https://www.github.com/tauri-apps/tauri/pull/2308)) on 2021-08-08
- Update vite recipe to use the new vite npm [package](https://github.com/vitejs/vite/tree/main/packages/create-vite).
- [718d9513](https://www.github.com/tauri-apps/tauri/commit/718d9513ce8013594a21c7fedb2dcb3dcd7bbad8) refactor(cta): update `vite` recipe to use their new npm package ([#2220](https://www.github.com/tauri-apps/tauri/pull/2220)) on 2021-07-29
## \[1.0.0-beta.3]
- Added Angular CLI recipe.
- [489fad55](https://www.github.com/tauri-apps/tauri/commit/489fad55242b3489c7c551fdfdd031ebad2d9b9c) Angular create tauri app \[[#1934](https://www.github.com/tauri-apps/tauri/pull/1934)] ([#2203](https://www.github.com/tauri-apps/tauri/pull/2203)) on 2021-07-14
## \[1.0.0-beta.2]
- Fixes the `beforeDevCommand` on vite recipe.
- [3c21ddc7](https://www.github.com/tauri-apps/tauri/commit/3c21ddc73cd7ab8141b730ceade46fc2dfadd996) fix(cta): use correct `beforeDevCommand` for vite recipe ([#1931](https://www.github.com/tauri-apps/tauri/pull/1931)) on 2021-06-01
## \[1.0.0-beta.1]
- Work around bugs between esbuild and npm by installing directly at the end of the sequence. Also default to using the latest on all of the installs instead of npx's cache.
- [8a164d0](https://www.github.com/tauri-apps/tauri/commit/8a164d0a1f8eb69bdcec7ae4362d26b2f3c7ff55) fix: CTA cache and vite build ([#1806](https://www.github.com/tauri-apps/tauri/pull/1806)) on 2021-05-12
## \[1.0.0-beta.0]
- Explicitly install deps after a vite recipe.
- [397b7af](https://www.github.com/tauri-apps/tauri/commit/397b7af395a213bf826aa52398467b7b3352b666) chore: CTA defaults in CI mode ([#1671](https://www.github.com/tauri-apps/tauri/pull/1671)) on 2021-05-05
- Shift everything out of the `bin` and into `.ts` so we can apply Typescript types.
- [c3acbd6](https://www.github.com/tauri-apps/tauri/commit/c3acbd68ec169188c782cbaf7d100d80b3a4f39a) chore: shift CTA from bin to .ts ([#1651](https://www.github.com/tauri-apps/tauri/pull/1651)) on 2021-04-29
- We setup an e2e type test suite for CTA. It is mostly an internal change, but should help with stability moving forward.
- [af6411d](https://www.github.com/tauri-apps/tauri/commit/af6411d5f8c9fd1c3d9b4f3c2d79e8f1bd0efbf2) feat: setup testing for CTA ([#1615](https://www.github.com/tauri-apps/tauri/pull/1615)) on 2021-04-27
- Add support for all vite templates
- [cea3ba9](https://www.github.com/tauri-apps/tauri/commit/cea3ba9f97de9d0181a84ad085a852517bd33a65) feat(cta): add support for all vite templates ([#1670](https://www.github.com/tauri-apps/tauri/pull/1670)) on 2021-05-07
- Add a welcome prompt to let the user know about the process and links to more info including prerequisite setup steps. Also add links to each of the templates to give the user more context what they are getting into.
- [ea28d01](https://www.github.com/tauri-apps/tauri/commit/ea28d0169168953e11416231e50b08061413a27e) create-tauri-app welcome prompt and recipes links ([#1748](https://www.github.com/tauri-apps/tauri/pull/1748)) on 2021-05-09
## \[1.0.0-beta-rc.4]

@@ -4,0 +56,0 @@

@@ -5,2 +5,6 @@ 'use strict';

var inquirer = require('inquirer');
var commander = require('commander');
var chalk = require('chalk');
var os = require('os');
var path = require('path');

@@ -10,9 +14,8 @@ var scaffe = require('scaffe');

var fs = require('fs');
var inquirer = require('inquirer');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var inquirer__default = /*#__PURE__*/_interopDefaultLegacy(inquirer);
var scaffe__default = /*#__PURE__*/_interopDefaultLegacy(scaffe);
var execa__default = /*#__PURE__*/_interopDefaultLegacy(execa);
var inquirer__default = /*#__PURE__*/_interopDefaultLegacy(inquirer);

@@ -48,6 +51,6 @@ /*! *****************************************************************************

if (options && options.shell === true) {
const stringCommand = [command, ...(!args ? [] : args)].join(' ');
const stringCommand = [command, ...(args !== null && args !== void 0 ? args : [])].join(' ');
if (log)
console.log(`[running]: ${stringCommand}`);
return yield execa__default['default'](stringCommand, Object.assign({ stdio: 'inherit', cwd: process.cwd(), env: process.env }, options));
return yield execa__default["default"](stringCommand, Object.assign({ stdio: 'inherit', cwd: process.cwd(), env: process.env }, options));
}

@@ -57,3 +60,3 @@ else {

console.log(`[running]: ${command}`);
return yield execa__default['default'](command, args, Object.assign({ stdio: 'inherit', cwd: process.cwd(), env: process.env }, options));
return yield execa__default["default"](command, args, Object.assign({ stdio: 'inherit', cwd: process.cwd(), env: process.env }, options));
}

@@ -67,3 +70,27 @@ }

function emptyDir(dir) {
if (!fs.existsSync(dir))
return;
for (const file of fs.readdirSync(dir)) {
const abs = path.resolve(dir, file);
// baseline is Node 12 so can't use rmSync :(
if (fs.lstatSync(abs).isDirectory()) {
emptyDir(abs);
fs.rmdirSync(abs);
}
else {
fs.unlinkSync(abs);
}
}
}
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
function updatePackageJson(f, cwd = process.cwd()) {
const pkgPath = path.join(cwd, 'package.json');
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
const output = f(pkg);
fs.writeFileSync(pkgPath, JSON.stringify(output, undefined, 2));
}
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
const afterCra = (cwd, appName, typescript = false) => __awaiter(void 0, void 0, void 0, function* () {

@@ -73,5 +100,9 @@ const templateDir = path.join(__dirname, `../src/templates/react/${typescript ? 'react-ts' : 'react'}`);

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
yield scaffe__default['default'].generate(templateDir, path.join(cwd, appName), {
yield scaffe__default["default"].generate(templateDir, path.join(cwd, appName), {
overwrite: true
});
updatePackageJson((pkg) => {
var _a;
return Object.assign(Object.assign({}, pkg), { scripts: Object.assign(Object.assign({}, pkg.scripts), { start: `${'cross-env BROWSER=none '}${(_a = pkg.scripts) === null || _a === void 0 ? void 0 : _a.start}` }) });
}, path.join(cwd, appName));
}

@@ -82,64 +113,86 @@ catch (err) {

});
const reactjs = {
descriptiveName: 'React.js',
shortName: 'reactjs',
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../build`, devPath: 'http://localhost:3000', beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`, beforeBuildCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} build` })),
extraNpmDevDependencies: [],
const cra = {
descriptiveName: {
name: 'create-react-app (https://create-react-app.dev/)',
value: 'create-react-app'
},
shortName: 'cra',
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../build`, devPath: 'http://localhost:3000', beforeDevCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} start`, beforeBuildCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} build` })),
extraNpmDevDependencies: ['cross-env'],
extraNpmDependencies: [],
preInit: ({ cwd, cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
// CRA creates the folder for you
if (packageManager === 'yarn') {
yield shell('yarn', ['create', 'react-app', `${cfg.appName}`], {
cwd
});
extraQuestions: ({ ci }) => {
return [
{
type: 'list',
name: 'template',
message: 'Which create-react-app template would you like to use?',
choices: [
{ name: 'create-react-app (JavaScript)', value: 'cra.js' },
{ name: 'create-react-app (Typescript)', value: 'cra.ts' }
],
default: 'cra.js',
loop: false,
when: !ci
}
];
},
preInit: ({ cwd, cfg, packageManager, answers, ci }) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const template = (_a = answers === null || answers === void 0 ? void 0 : answers.template) !== null && _a !== void 0 ? _a : 'cra.js';
switch (packageManager) {
case 'yarn':
yield shell('yarn', [
ci ? '--non-interactive' : '',
'create',
'react-app',
...(template === 'cra.ts' ? ['--template', 'typescript'] : []),
`${cfg.appName}`
], {
cwd
});
break;
case 'npm':
case 'pnpm':
yield shell('npx', [
ci ? '--yes' : '',
'create-react-app@latest',
...(template === 'cra.ts' ? ['--template', 'typescript'] : []),
`${cfg.appName}`,
'--use-npm'
], {
cwd
});
// create-react-app doesn't support pnpm, so we remove `node_modules` and any lock files then install them again using pnpm
if (packageManager === 'pnpm') {
const npmLock = path.join(cwd, cfg.appName, 'package-lock.json');
const yarnLock = path.join(cwd, cfg.appName, 'yarn.lock');
const nodeModules = path.join(cwd, cfg.appName, 'node_modules');
if (fs.existsSync(npmLock))
fs.unlinkSync(npmLock);
if (fs.existsSync(yarnLock))
fs.unlinkSync(yarnLock);
emptyDir(nodeModules);
yield shell('pnpm', ['install'], { cwd: path.join(cwd, cfg.appName) });
}
break;
}
else {
yield shell('npx', ['create-react-app', `${cfg.appName}`, '--use-npm'], {
cwd
});
}
yield afterCra(cwd, cfg.appName);
yield afterCra(cwd, cfg.appName, template === 'cra.ts');
}),
postInit: ({ packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
postInit: ({ packageManager, cfg }) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`
Your installation completed.
To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri dev
`);
$ cd ${cfg.appName}
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev
`);
return yield Promise.resolve();
})
};
const reactts = Object.assign(Object.assign({}, reactjs), { descriptiveName: 'React with Typescript', shortName: 'reactts', extraNpmDependencies: [], preInit: ({ cwd, cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
// CRA creates the folder for you
if (packageManager === 'yarn') {
yield shell('yarn', ['create', 'react-app', '--template', 'typescript', `${cfg.appName}`], {
cwd
});
}
else {
yield shell('npx', [
'create-react-app',
`${cfg.appName}`,
'--use-npm',
'--template',
'typescript'
], {
cwd
});
}
yield afterCra(cwd, cfg.appName, true);
}), postInit: ({ packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`
Your installation completed.
To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri dev
`);
return yield Promise.resolve();
}) });
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
const completeLogMsg = `
Your installation completed.
To start, run yarn tauri:serve
`;
const vuecli = {
descriptiveName: 'Vue CLI',
descriptiveName: {
name: 'Vue CLI (https://cli.vuejs.org/)',
value: 'vue-cli'
},
shortName: 'vuecli',

@@ -149,6 +202,14 @@ extraNpmDevDependencies: [],

configUpdate: ({ cfg }) => cfg,
preInit: ({ cwd, cfg }) => __awaiter(void 0, void 0, void 0, function* () {
// Vue CLI creates the folder for you
yield shell('npx', ['@vue/cli', 'create', `${cfg.appName}`], { cwd });
preInit: ({ cwd, cfg, ci, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
yield shell('npx', [
ci ? '--yes' : '',
'@vue/cli@latest',
'create',
`${cfg.appName}`,
'--packageManager',
packageManager,
ci ? '--default' : ''
], { cwd });
yield shell('npx', [
ci ? '--yes' : '',
'@vue/cli',

@@ -165,4 +226,9 @@ 'add',

}),
postInit: () => __awaiter(void 0, void 0, void 0, function* () {
console.log(completeLogMsg);
postInit: ({ cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`
Your installation completed.
$ cd ${cfg.appName}
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri:serve
`);
return yield Promise.resolve();

@@ -174,5 +240,8 @@ })

const vanillajs = {
descriptiveName: 'Vanilla.js',
descriptiveName: {
name: 'Vanilla.js (html, css, and js without the bundlers)',
value: 'Vanilla.js'
},
shortName: 'vanillajs',
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../dist`, devPath: `../dist`, beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`, beforeBuildCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} build` })),
configUpdate: ({ cfg }) => (Object.assign(Object.assign({}, cfg), { distDir: `../dist`, devPath: `../dist`, beforeDevCommand: '', beforeBuildCommand: '' })),
extraNpmDevDependencies: [],

@@ -188,3 +257,3 @@ extraNpmDependencies: [],

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
yield scaffe__default['default'].generate(templateDir, path.join(cwd, appName), {
yield scaffe__default["default"].generate(templateDir, path.join(cwd, appName), {
overwrite: true,

@@ -199,18 +268,9 @@ variables

postInit: ({ cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
const setApp = packageManager === 'npm'
? `
set tauri script once
$ npm set-script tauri tauri
`
: '';
console.log(`
change directory:
$ cd ${cfg.appName}
${setApp}
install dependencies:
$ ${packageManager} install
Your installation completed.
run the app:
$ ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri ${packageManager === 'npm' ? '-- ' : ''}dev
`);
$ cd ${cfg.appName}
$ ${packageManager} install
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev
`);
return yield Promise.resolve();

@@ -221,36 +281,46 @@ })

// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
const afterViteCA = (cwd, appName, template) => __awaiter(void 0, void 0, void 0, function* () {
const templateDir = path.join(__dirname, `../src/templates/vite/${template}`);
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
yield scaffe__default['default'].generate(templateDir, path.join(cwd, appName), {
overwrite: true
});
}
catch (err) {
console.log(err);
}
});
const vite = {
descriptiveName: 'Vite backed recipe',
descriptiveName: {
name: 'create-vite (vanilla, vue, react, svelte, preact, lit) (https://vitejs.dev/guide/#scaffolding-your-first-vite-project)',
value: 'create-vite'
},
shortName: 'vite',
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../dist`, devPath: 'http://localhost:3000', beforeDevCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} start`, beforeBuildCommand: `${packageManager === 'yarn' ? 'yarn' : 'npm run'} build` })),
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../dist`, devPath: 'http://localhost:3000', beforeDevCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} dev`, beforeBuildCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} build` })),
extraNpmDevDependencies: [],
extraNpmDependencies: [],
preInit: ({ cwd, cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
try {
const { template } = (yield inquirer__default['default'].prompt([
{
type: 'list',
name: 'template',
message: 'Which vite template would you like to use?',
choices: fs.readdirSync(path.join(__dirname, '../src/templates/vite')),
default: 'vue'
}
]));
// Vite creates the folder for you
if (packageManager === 'yarn') {
extraQuestions: ({ ci }) => {
return [
{
type: 'list',
name: 'template',
message: 'Which vite template would you like to use?',
choices: [
'vanilla',
'vanilla-ts',
'vue',
'vue-ts',
'react',
'react-ts',
'preact',
'preact-ts',
'lit-element',
'lit-element-ts',
'svelte',
'svelte-ts'
],
default: 'vue',
loop: false,
when: !ci
}
];
},
preInit: ({ cwd, cfg, packageManager, answers, ci }) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const template = (_a = answers === null || answers === void 0 ? void 0 : answers.template) !== null && _a !== void 0 ? _a : 'vue';
switch (packageManager) {
case 'yarn':
yield shell('yarn', [
ci ? '--non-interactive' : '',
'create',
'@vitejs/app',
'vite',
`${cfg.appName}`,

@@ -262,27 +332,307 @@ '--template',

});
}
else {
yield shell('npx', ['@vitejs/create-app', `${cfg.appName}`, '--template', `${template}`], {
break;
case 'npm':
yield shell('npx', [
ci ? '--yes' : '',
'create-vite@latest',
`${cfg.appName}`,
'--template',
`${template}`
], {
cwd
});
break;
case 'pnpm':
yield shell('pnpm', ['create', 'vite', `${cfg.appName}`, '--template', `${template}`], {
cwd
});
break;
}
}),
postInit: ({ cwd, packageManager, cfg }) => __awaiter(void 0, void 0, void 0, function* () {
// we don't have a consistent way to rebuild and
// esbuild has hit all the bugs and struggles to install on the postinstall
yield shell('node', ['./node_modules/esbuild/install.js'], { cwd });
switch (packageManager) {
case 'pnpm':
case 'yarn':
yield shell(packageManager, ['build'], { cwd });
break;
case 'npm':
yield shell('npm', ['run', 'build'], { cwd });
break;
}
console.log(`
Your installation completed.
$ cd ${cfg.appName}
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev
`);
return yield Promise.resolve();
})
};
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
const dominator = {
descriptiveName: {
name: 'Dominator (https://crates.io/crates/dominator/)',
value: 'Dominator'
},
shortName: 'dominator',
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../dist`, devPath: 'http://localhost:10001/', beforeDevCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} start`, beforeBuildCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} build` })),
extraNpmDevDependencies: [],
extraNpmDependencies: [],
preInit: ({ cwd, cfg }) => __awaiter(void 0, void 0, void 0, function* () {
const { appName, windowTitle } = cfg;
const templateDir = path.join(__dirname, '../src/templates/dominator');
const variables = {
name: appName,
title: windowTitle
};
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
yield scaffe__default["default"].generate(templateDir, path.join(cwd, appName), {
overwrite: true,
variables
});
}
catch (err) {
console.log(err);
}
}),
postInit: ({ cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`
Your installation completed.
$ cd ${cfg.appName}
$ ${packageManager} install
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev
`);
return yield Promise.resolve();
})
};
const addAdditionalPackage = (packageManager, cwd, appName, packageName) => __awaiter(void 0, void 0, void 0, function* () {
const ngCommand = ['ng', 'add', packageName, '--skip-confirmation'];
switch (packageManager) {
case 'pnpm':
case 'yarn':
yield shell(packageManager, ngCommand, {
cwd: path.join(cwd, appName)
});
break;
case 'npm':
yield shell('npm', ['run', ...ngCommand], {
cwd: path.join(cwd, appName)
});
break;
}
});
const ngcli = {
descriptiveName: {
name: 'Angular CLI (https://angular.io/cli)',
value: 'ng-cli'
},
shortName: 'ngcli',
extraNpmDependencies: [],
extraNpmDevDependencies: [],
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../dist/${cfg.appName}`, devPath: 'http://localhost:4200', beforeDevCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} start`, beforeBuildCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} build` })),
extraQuestions: ({ ci }) => {
return [
{
type: 'confirm',
name: 'material',
message: 'Add Angular Material (https://material.angular.io/)?',
when: !ci
},
{
type: 'confirm',
name: 'eslint',
message: 'Add Angular ESLint (https://github.com/angular-eslint/angular-eslint)?',
when: !ci
}
yield afterViteCA(cwd, cfg.appName, template);
];
},
preInit: ({ cwd, cfg, answers, packageManager, ci }) => __awaiter(void 0, void 0, void 0, function* () {
yield shell('npx', [
ci ? '--yes' : '',
'-p',
'@angular/cli',
'ng',
'new',
`${cfg.appName}`,
`--package-manager=${packageManager}`
], {
cwd
});
if (answers === null || answers === void 0 ? void 0 : answers.material) {
yield addAdditionalPackage(packageManager, cwd, cfg.appName, '@angular/material');
}
catch (error) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (error === null || error === void 0 ? void 0 : 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.');
if (answers === null || answers === void 0 ? void 0 : answers.eslint) {
yield addAdditionalPackage(packageManager, cwd, cfg.appName, '@angular-eslint/schematics');
}
}),
postInit: ({ packageManager, cfg }) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`
Your installation completed.
$ cd ${cfg.appName}
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev
`);
return yield Promise.resolve();
})
};
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
const svelte = {
descriptiveName: {
name: 'Svelte (https://github.com/sveltejs/template)',
value: 'svelte'
},
shortName: 'svelte',
extraNpmDevDependencies: [],
extraNpmDependencies: [],
extraQuestions: ({ ci }) => {
return [
{
type: 'confirm',
name: 'typescript',
message: 'Enable Typescript?',
default: true,
loop: false,
when: !ci
}
else {
// Something else went wrong
console.error('An unknown error occurred:', error);
];
},
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../public`, devPath: 'http://localhost:8080', beforeDevCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} dev`, beforeBuildCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} build` })),
preInit: ({ cwd, cfg, answers, ci }) => __awaiter(void 0, void 0, void 0, function* () {
let typescript = false;
if (answers) {
typescript = !!answers.typescript;
}
yield shell('npx', [ci ? '--yes' : '', 'degit', 'sveltejs/template', `${cfg.appName}`], {
cwd
});
if (typescript) {
yield shell('node', ['scripts/setupTypeScript.js'], {
cwd: path.join(cwd, cfg.appName)
});
}
}),
postInit: ({ cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`
Your installation completed.
$ cd ${cfg.appName}
$ ${packageManager} install
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev
`);
return yield Promise.resolve();
})
};
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
const solid = {
descriptiveName: {
name: 'Solid (https://github.com/solidjs/templates)',
value: 'solid'
},
shortName: 'solid',
extraNpmDevDependencies: [],
extraNpmDependencies: [],
extraQuestions: ({ ci }) => {
return [
{
type: 'list',
name: 'template',
message: 'Which Solid template would you like to use?',
choices: [
'js',
'ts-bootstrap',
'ts-minimal',
'ts-router',
'ts-windicss',
'ts'
],
default: 'ts',
loop: false,
when: !ci
}
];
},
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../public`, devPath: 'http://localhost:3000', beforeDevCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} dev`, beforeBuildCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} build` })),
preInit: ({ cwd, cfg, answers, ci }) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
yield shell('npx', [
ci ? '--yes' : '',
'degit',
`solidjs/templates/${(_a = answers === null || answers === void 0 ? void 0 : answers.template) !== null && _a !== void 0 ? _a : 'js'}`,
cfg.appName
], { cwd });
}),
postInit: ({ cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`
Your installation completed.
$ cd ${cfg.appName}
$ ${packageManager} install
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev
`);
return yield Promise.resolve();
})
};
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
const cljs = {
descriptiveName: {
name: 'ClojureScript (https://github.com/filipesilva/create-cljs-app)',
value: 'cljs'
},
shortName: 'cljs',
extraNpmDevDependencies: [],
extraNpmDependencies: [],
configUpdate: ({ cfg, packageManager }) => (Object.assign(Object.assign({}, cfg), { distDir: `../public`, devPath: 'http://localhost:3000', beforeDevCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} start`, beforeBuildCommand: `${packageManager === 'npm' ? 'npm run' : packageManager} build` })),
preInit: ({ cwd, cfg, packageManager, ci }) => __awaiter(void 0, void 0, void 0, function* () {
const npmLock = path.join(cwd, cfg.appName, 'package-lock.json');
const yarnLock = path.join(cwd, cfg.appName, 'yarn.lock');
const nodeModules = path.join(cwd, cfg.appName, 'node_modules');
switch (packageManager) {
case 'yarn':
yield shell('yarn', ['create', 'cljs-app', `${cfg.appName}`], {
cwd
});
// `create-cljs-app` has both a `package-lock.json` and a `yarn.lock`
// so it is better to remove conflicting lock files and install fresh node_modules
if (fs.existsSync(npmLock))
fs.unlinkSync(npmLock);
emptyDir(nodeModules);
yield shell('yarn', ['install'], { cwd: path.join(cwd, cfg.appName) });
break;
case 'npm':
yield shell('npx', [ci ? '--yes' : '', 'create-cljs-app@latest', `${cfg.appName}`], {
cwd
});
if (fs.existsSync(yarnLock))
fs.unlinkSync(yarnLock);
emptyDir(nodeModules);
yield shell('npm', ['install'], { cwd: path.join(cwd, cfg.appName) });
break;
case 'pnpm':
yield shell('npx', [ci ? '--yes' : '', 'create-cljs-app@latest', `${cfg.appName}`], {
cwd
});
if (fs.existsSync(npmLock))
fs.unlinkSync(npmLock);
emptyDir(nodeModules);
yield shell('pnpm', ['install'], { cwd: path.join(cwd, cfg.appName) });
break;
}
}),
postInit: ({ packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
postInit: ({ cfg, packageManager }) => __awaiter(void 0, void 0, void 0, function* () {
console.log(`
Your installation completed.
To start, run ${packageManager === 'yarn' ? 'yarn' : 'npm run'} tauri ${packageManager === 'npm' ? '--' : ''} dev
`);
$ cd ${cfg.appName}
$ ${packageManager === 'npm' ? 'npm run' : packageManager} tauri dev
`);
return yield Promise.resolve();

@@ -326,15 +676,19 @@ })

return __awaiter(this, void 0, void 0, function* () {
if (packageNames.length === 0)
return;
console.log(`Installing ${packageNames.join(', ')}...`);
if (packageManager === 'yarn') {
yield shell('yarn', ['add', packageNames.join(' ')], {
cwd: appDir
});
const packages = packageNames.filter((p) => p !== '');
if (packages.length !== 0) {
console.log(`- Installing ${packages.join(', ')}...`);
switch (packageManager) {
case 'pnpm':
case 'yarn':
yield shell(packageManager, ['add', packageNames.join(' ')], {
cwd: appDir
});
break;
case 'npm':
yield shell('npm', ['install', packageNames.join(' ')], {
cwd: appDir
});
break;
}
}
else {
yield shell('npm', ['install', packageNames.join(' ')], {
cwd: appDir
});
}
});

@@ -344,15 +698,19 @@ }

return __awaiter(this, void 0, void 0, function* () {
if (packageNames.length === 0)
return;
console.log(`Installing ${packageNames.join(', ')}...`);
if (packageManager === 'yarn') {
yield shell('yarn', ['add', '--dev', '--ignore-scripts', packageNames.join(' ')], {
cwd: appDir
});
const packages = packageNames.filter((p) => p !== '');
if (packages.length !== 0) {
console.log(`- Installing ${packages.join(', ')}...`);
switch (packageManager) {
case 'pnpm':
case 'yarn':
yield shell(packageManager, ['add', '-D', '--ignore-scripts', packageNames.join(' ')], {
cwd: appDir
});
break;
case 'npm':
yield shell('npm', ['install', '--save-dev', '--ignore-scripts', packageNames.join(' ')], {
cwd: appDir
});
break;
}
}
else {
yield shell('npm', ['install', '--save-dev', '--ignore-scripts', packageNames.join(' ')], {
cwd: appDir
});
}
});

@@ -362,30 +720,285 @@ }

// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
function addTauriScript(appDirectory) {
const pkgPath = path.join(appDirectory, 'package.json');
const pkgString = fs.readFileSync(pkgPath, 'utf8');
const pkg = JSON.parse(pkgString);
const outputPkg = Object.assign(Object.assign({}, pkg), { scripts: Object.assign(Object.assign({}, pkg.scripts), { tauri: 'tauri' }) });
fs.writeFileSync(pkgPath, JSON.stringify(outputPkg, undefined, 2));
function updateTauriConf(f, cwd = process.cwd()) {
const tauriConfPath = path.join(cwd, 'src-tauri', 'tauri.conf.json');
const tauriConf = JSON.parse(fs.readFileSync(tauriConfPath, 'utf8'));
const output = f(tauriConf);
fs.writeFileSync(tauriConfPath, JSON.stringify(output, undefined, 2));
}
function pkgManagerFromUserAgent(userAgent) {
if (!userAgent)
return undefined;
const pkgSpec = userAgent.split(' ')[0];
const pkgSpecArr = pkgSpec.split('/');
return {
name: pkgSpecArr[0],
version: pkgSpecArr[1]
};
}
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
const allRecipes = [vanillajs, reactjs, reactts, vite, vuecli];
const recipeNames = allRecipes.map((r) => [
r.shortName,
r.descriptiveName
]);
const recipeByShortName = (name) => allRecipes.find((r) => r.shortName === name);
const recipeByDescriptiveName = (name) => allRecipes.find((r) => r.descriptiveName === name);
const allRecipes = [
vanillajs,
cra,
vite,
vuecli,
ngcli,
svelte,
solid,
dominator,
cljs
];
const recipeShortNames = allRecipes.map((r) => r.shortName);
const recipeDescriptiveNames = allRecipes.map((r) => r.descriptiveName);
const recipeByShortName = (name) => allRecipes.find((r) => r.shortName === name);
const recipeByDescriptiveName = (name) => allRecipes.find((r) => r.descriptiveName.value === name);
const createTauriApp = (cliArgs) => __awaiter(void 0, void 0, void 0, function* () {
commander.program
.description('Bootstrap a new tauri app from a "recipe" or a pre-built template.')
.addOption(commander.createOption('-r, --recipe <recipe>', 'Specify UI framework recipe').choices(recipeShortNames))
.option(' --ci', 'Skip prompts')
.option(' --dev', 'Use local development packages')
.addOption(commander.createOption('-f, --force [option]', 'Force init to overwrite')
.choices(['conf', 'template', 'all'])
.default('all'))
.option('-d, --directory <path>', 'Set target directory for init')
.option('-A, --app-name <name>', 'Name of your Tauri application')
.option('-W, --window-title <title>', 'Title of your Tauri application window')
.option('-D, --dist-dir <path>', 'Web assets location, relative to "<project-dir>/src-tauri/tauri.conf.json"')
.option('-p, --dev-path <path>', 'Url of your dev server')
.addOption(commander.createOption('-m, --manager <package-manager>', 'Set package manager to use').choices(['npm', 'yarn', 'pnpm']))
.addOption(commander.createOption('-b, --binary <path>', 'Use a prebuilt Tauri CLI binary'))
.option('-l, --log', 'Add log messages')
.version(
// eslint-disable-next-line
require('../package.json').version, '-v, --version', 'Displays create-tauri-app version')
.helpOption('-h, --help', 'Displays this message')
.showHelpAfterError('For more information try --help')
.configureHelp({
optionTerm: (option) => chalk.cyan(option.flags),
commandUsage: (command) => chalk.cyan(command.name()) + ' [options]',
commandDescription: (command) => chalk.yellow(command.description())
})
.parse(process.argv);
const argv = commander.program.opts();
return yield runInit(argv);
});
const keypress = (skip) => __awaiter(void 0, void 0, void 0, function* () {
if (skip)
return;
process.stdin.setRawMode(true);
return yield new Promise((resolve, reject) => {
console.log('Press any key to continue...');
process.stdin.once('data', (data) => {
const byteArray = [...data];
if (byteArray.length > 0 && byteArray[0] === 3) {
console.log('^C');
process.exit(1);
}
process.stdin.setRawMode(false);
resolve();
});
});
});
const runInit = (argv) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const setupLink = os.platform() === 'win32'
? 'https://tauri.studio/en/docs/get-started/setup-windows/'
: os.platform() === 'darwin'
? 'https://tauri.studio/en/docs/get-started/setup-macos/'
: 'https://tauri.studio/en/docs/get-started/setup-linux/';
// prettier-ignore
console.log(`
We hope to help you create something special with ${chalk.bold(chalk.yellow('Tauri'))}!
You will have a choice of one of the UI frameworks supported by the greater web tech community.
This tool should get you quickly started. See our docs at ${chalk.cyan('https://tauri.studio/')}
exports.addTauriScript = addTauriScript;
exports.allRecipes = allRecipes;
exports.checkPackageManager = checkPackageManager;
exports.install = install;
exports.recipeByDescriptiveName = recipeByDescriptiveName;
exports.recipeByShortName = recipeByShortName;
exports.recipeDescriptiveNames = recipeDescriptiveNames;
exports.recipeNames = recipeNames;
exports.recipeShortNames = recipeShortNames;
exports.shell = shell;
If you haven't already, please take a moment to setup your system.
You may find the requirements here: ${chalk.cyan(setupLink)}
`);
yield keypress(argv.ci);
const defaults = {
appName: 'tauri-app',
tauri: { window: { title: 'Tauri App' } },
recipeName: 'Vanilla.js',
installApi: true
};
// prompt initial questions
const answers = (yield inquirer__default["default"]
.prompt([
{
type: 'input',
name: 'appName',
message: 'What is your app name?',
default: defaults.appName,
when: !argv.ci && !argv.appName
},
{
type: 'input',
name: 'tauri.window.title',
message: 'What should the window title be?',
default: defaults.tauri.window.title,
when: !argv.ci && !argv.windowTitle
},
{
type: 'list',
name: 'recipeName',
message: 'What UI recipe would you like to add?',
choices: recipeDescriptiveNames,
default: defaults.recipeName,
when: !argv.ci && !argv.recipe
},
{
type: 'confirm',
name: 'installApi',
message: 'Add "@tauri-apps/api" npm package?',
default: true,
when: !argv.ci
}
])
.catch((error) => {
if (error.isTtyError) {
// Prompt couldn't be rendered in the current environment
console.warn('It appears your terminal does not support interactive prompts. Using default values.');
}
else {
// Something else went wrong
console.error('An unknown error occurred:', error);
}
}));
const { appName, recipeName, installApi, tauri: { window: { title } } } = Object.assign(Object.assign({}, defaults), answers);
let recipe;
if (argv.recipe) {
recipe = recipeByShortName(argv.recipe);
}
else if (recipeName !== undefined) {
recipe = recipeByDescriptiveName(recipeName);
}
// throw if recipe is not set
if (!recipe) {
throw new Error('Could not find the recipe specified.');
}
const pkgManagerInfo = pkgManagerFromUserAgent(process.env.npm_config_user_agent);
const packageManager = ((_a = pkgManagerInfo === null || pkgManagerInfo === void 0 ? void 0 : pkgManagerInfo.name) !== null && _a !== void 0 ? _a : 'npm');
const buildConfig = {
distDir: argv.distDir,
devPath: argv.devPath,
appName: argv.appName || appName,
windowTitle: argv.windowTitle || title
};
const directory = argv.directory || process.cwd();
// prompt additional recipe questions
let recipeAnswers;
if (recipe.extraQuestions) {
recipeAnswers = yield inquirer__default["default"]
.prompt(recipe.extraQuestions({
cfg: buildConfig,
packageManager,
ci: argv.ci,
cwd: directory
}))
.catch((error) => {
if (error.isTtyError) {
// Prompt couldn't be rendered in the current environment
console.warn('It appears your terminal does not support interactive prompts. Using default values.');
}
else {
// Something else went wrong
console.error('An unknown error occurred:', error);
}
});
}
let updatedConfig;
if (recipe.configUpdate) {
updatedConfig = recipe.configUpdate({
cfg: buildConfig,
packageManager,
ci: argv.ci,
cwd: directory,
answers: recipeAnswers !== null && recipeAnswers !== void 0 ? recipeAnswers : {}
});
}
const cfg = Object.assign(Object.assign({}, buildConfig), (updatedConfig !== null && updatedConfig !== void 0 ? updatedConfig : {}));
// note that our app directory is reliant on the appName and
// generally there are issues if the path has spaces (see Windows)
// TODO: prevent app names with spaces or escape here?
const appDirectory = path.join(directory, cfg.appName);
// this throws an error if we can't run the package manager they requested
yield checkPackageManager({ cwd: directory, packageManager });
if (recipe.preInit) {
logStep('Running initial command(s)');
yield recipe.preInit({
cwd: directory,
cfg,
packageManager,
ci: argv.ci,
answers: recipeAnswers !== null && recipeAnswers !== void 0 ? recipeAnswers : {}
});
}
const initArgs = [
['--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);
}
else {
return final;
}
}, []);
// TODO: const tauriCLIVersion = !argv.dev ?
// 'latest'
// :`file:${relative(appDirectory, join(__dirname, '../../cli.js'))}`
const tauriCLIVersion = 'latest';
const apiVersion = !argv.dev
? 'latest'
: `file:${path.relative(appDirectory, path.join(__dirname, '../../api/dist'))}`;
// Vue CLI plugin automatically runs these
if (recipe.shortName !== 'vuecli') {
logStep('Installing any additional needed dependencies');
yield install({
appDir: appDirectory,
dependencies: [installApi ? `@tauri-apps/api@${apiVersion}` : ''].concat(recipe.extraNpmDependencies),
devDependencies: [`@tauri-apps/cli@${tauriCLIVersion}`].concat(recipe.extraNpmDevDependencies),
packageManager
});
logStep(`Updating ${chalk.reset(chalk.yellow('"package.json"'))}`);
updatePackageJson((pkg) => {
return Object.assign(Object.assign({}, pkg), { name: appName, scripts: Object.assign(Object.assign({}, pkg.scripts), { tauri: 'tauri' }) });
}, appDirectory);
logStep(`Running ${chalk.reset(chalk.yellow('"tauri init"'))}`);
const binary = !argv.binary
? packageManager
: path.resolve(appDirectory, argv.binary);
// "pnpm" is mostly interchangable with "yarn" but due to this bug https://github.com/pnpm/pnpm/issues/2764
// we need to pass "--" to pnpm or arguments won't be parsed correctly so we treat "pnpm" here like "npm"
const runTauriArgs = packageManager === 'yarn' || argv.binary
? ['tauri', 'init']
: ['run', 'tauri', '--', 'init'];
yield shell(binary, [...runTauriArgs, ...initArgs, '--ci'], {
cwd: appDirectory
});
logStep(`Updating ${chalk.reset(chalk.yellow('"tauri.conf.json"'))}`);
updateTauriConf((tauriConf) => {
return Object.assign(Object.assign({}, tauriConf), { build: Object.assign(Object.assign({}, tauriConf.build), { beforeDevCommand: cfg.beforeDevCommand, beforeBuildCommand: cfg.beforeBuildCommand }) });
}, appDirectory);
}
if (recipe.postInit) {
logStep('Running final command(s)');
yield recipe.postInit({
cwd: appDirectory,
cfg,
packageManager,
ci: argv.ci,
answers: recipeAnswers !== null && recipeAnswers !== void 0 ? recipeAnswers : {}
});
}
});
function logStep(msg) {
const out = `${chalk.green('>>')} ${chalk.bold(chalk.cyan(msg))}`;
console.log(out);
}
exports.createTauriApp = createTauriApp;
{
"name": "create-tauri-app",
"version": "1.0.0-beta-rc.4",
"version": "1.0.0-rc.0",
"description": "Jump right into a Tauri App!",

@@ -15,4 +15,3 @@ "bin": {

"contributors": [
"Tauri Team <team@tauri-apps.org> (https://tauri.studio)",
"Jacob Bolda <me@jacobbolda.com> (https://www.jacobbolda.com)"
"Tauri Programme within The Commons Conservancy"
],

@@ -32,33 +31,38 @@ "main": "bin/create-tauri-app.js",

"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"
"format": "prettier --write --end-of-line=auto \"./**/*.{cjs,js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore",
"format:check": "prettier --check --end-of-line=auto \"./**/*.{cjs,js,jsx,ts,tsx,html,css,json}\" --ignore-path .gitignore",
"test": "node ./test/spawn.test.mjs"
},
"dependencies": {
"execa": "^5.0.0",
"inquirer": "^8.0.0",
"minimist": "^1.2.5",
"scaffe": "1.0.0"
"chalk": "4.1.2",
"commander": "8.3.0",
"execa": "5.1.1",
"inquirer": "8.2.0",
"scaffe": "1.2.0"
},
"devDependencies": {
"@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",
"@effection/process": "2.0.4",
"@rollup/plugin-commonjs": "21.0.1",
"@rollup/plugin-node-resolve": "13.1.3",
"@rollup/plugin-typescript": "8.3.0",
"@types/cross-spawn": "6.0.2",
"@types/inquirer": "7.3.1",
"@types/semver": "7.3.4",
"eslint": "7.24.0",
"eslint-config-prettier": "8.2.0",
"eslint-config-standard-with-typescript": "20.0.0",
"eslint-plugin-import": "2.22.1",
"@types/inquirer": "8.2.0",
"@types/semver": "7.3.9",
"@typescript-eslint/eslint-plugin": "5.11.0",
"@typescript-eslint/parser": "5.11.0",
"effection": "2.0.4",
"eslint": "8.8.0",
"eslint-config-prettier": "8.3.0",
"eslint-config-standard-with-typescript": "21.0.1",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-lodash-template": "0.19.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "5.1.0",
"eslint-plugin-promise": "5.2.0",
"eslint-plugin-security": "1.4.0",
"prettier": "2.2.1",
"rollup": "2.45.1",
"tslib": "2.2.0",
"typescript": "4.2.4"
"prettier": "2.5.1",
"rollup": "2.67.1",
"temp-dir": "2.0.0",
"tslib": "2.3.1",
"typescript": "4.5.5"
}
}
# create-tauri-app
<img align="right" src="https://github.com/tauri-apps/tauri/raw/dev/app-icon.png" height="128" width="128">
[![status](https://img.shields.io/badge/Status-Beta-green.svg)](https://github.com/tauri-apps/tauri)
[![Chat Server](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/SpmNs4S)
[![devto](https://img.shields.io/badge/blog-dev.to-black.svg)](https://dev.to/tauri)
![](https://img.shields.io/github/workflow/status/tauri-apps/tauri/test%20library?label=test%20library
)
[![devto](https://img.shields.io/badge/documentation-site-purple.svg)](https://tauri.studio)
[![https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg](https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg)](https://good-labs.github.io/greater-good-affirmation)
[![support](https://img.shields.io/badge/sponsor-Opencollective-blue.svg)](https://opencollective.com/tauri)
| Component | Version |
| --------- | ------------------------------------------- |
| create-tauri-app | ![](https://img.shields.io/npm/v/create-tauri-app.svg) |
## About Tauri
Tauri is a polyglot and generic system that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. In fact, developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily.
Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the system's webview. They do not ship a runtime, since the final binary is compiled from rust. This makes the reversing of Tauri apps not a trivial task.
## This module
This is a toolkit that will enable engineering teams to rapidly scaffold out a new tauri-apps project using the frontend framework of their choice (as long as it has been configured).
To learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document.
## Usage
Run and answer the prompts to get started with your first Tauri app!

@@ -12,3 +40,2 @@

With npm:
```shell

@@ -19,3 +46,2 @@ npm x create-tauri-app

With yarn:
```shell

@@ -25,4 +51,10 @@ yarn create tauri-app

# Additional Args
## Semver
**tauri** is following [Semantic Versioning 2.0](https://semver.org/).
## Licenses
Code: (c) 2021 - The Tauri Programme within The Commons Conservancy.
TODO
MIT or MIT/Apache 2.0 where applicable.
Logo: CC-BY-NC-ND
- Original Tauri Logo Designs by [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc