mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-01-31 00:35:19 +01:00
feat(tauri) initial work for the CLI (#20)
* feat(tauri) initial work for the CLI * feat(build) read dist path from env * feat(tauri) proton.js entry * feat(tauri) threeshake fs * feat(injector) check if tauri dir exists * feat(injector) don't show success message if dir exists * chore(injector) cleanup fs imports
This commit is contained in:
committed by
GitHub
parent
4c2c9d00b9
commit
a0f410dcff
@@ -3,11 +3,8 @@ extern crate includedir_codegen;
|
||||
use includedir_codegen::Compression;
|
||||
use std::env;
|
||||
|
||||
static CARGOENV: &str = "cargo:rustc-env=";
|
||||
|
||||
fn main() {
|
||||
let dist_path = format!("{}/../../../../{}", env::var("OUT_DIR").unwrap(), "compiled-web");
|
||||
println!("{}TAURI_DIST_DIR={}", CARGOENV, dist_path);
|
||||
let dist_path = env::var("TAURI_DIST_DIR").unwrap();
|
||||
includedir_codegen::start("ASSETS")
|
||||
.dir(dist_path, Compression::None)
|
||||
.build("data.rs")
|
||||
|
||||
337
lib/tauri.js
Normal file
337
lib/tauri.js
Normal file
@@ -0,0 +1,337 @@
|
||||
<%
|
||||
if (typeof(confName) === 'undefined') {
|
||||
confName = 'quasar.conf.js'
|
||||
}
|
||||
%>
|
||||
/**
|
||||
* THIS FILE IS GENERATED AUTOMATICALLY.
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Please whitelist these API functions in <% confName %>
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
* @module tauri
|
||||
* @description This API interface makes powerful interactions available
|
||||
* to be run on client side applications. They are opt-in features, and
|
||||
* must be enabled in <% confName %>
|
||||
*
|
||||
* Each binding MUST provide these interfaces in order to be compliant,
|
||||
* and also whitelist them based upon the developer's settings.
|
||||
*/
|
||||
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1)
|
||||
}
|
||||
|
||||
const uid = function () {
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4()
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name __whitelistWarning
|
||||
* @description Present a stylish warning to the developer that their API
|
||||
* call has not been whitelisted in <% confName %>
|
||||
* @param {String} func - function name to warn
|
||||
* @private
|
||||
*/
|
||||
const __whitelistWarning = function (func) {
|
||||
console.warn('%c[Tauri] Danger \ntauri.' + func + ' not whitelisted 💣\n%c\nAdd to <% confName %>: \n\ntauri: \n whitelist: { \n ' + func + ': true \n\nReference: https://quasar.dev/quasar-cli/creating-tauri-apps/api#' + func , 'background: red; color: white; font-weight: 800; padding: 2px; font-size:1.5em', ' ')
|
||||
}
|
||||
<% } %>
|
||||
|
||||
/**
|
||||
* @name __reject
|
||||
* @description is a private promise used to deflect un-whitelisted tauri API calls
|
||||
* Its only purpose is to maintain thenable structure in client code without
|
||||
* breaking the application
|
||||
* * @type {Promise<any>}
|
||||
* @private
|
||||
*/
|
||||
const __reject = new Promise((reject) => { reject })
|
||||
|
||||
export default class Tauri {
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name invoke
|
||||
* @description Calls a Quasar Core feature, such as setTitle
|
||||
* @param {Object} args
|
||||
*/
|
||||
<% } %>
|
||||
static invoke (args) {
|
||||
Object.freeze(args)
|
||||
external.invoke(JSON.stringify(args))
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name addEventListener
|
||||
* @description Add an event listener to Tauri back end
|
||||
* @param {String} event
|
||||
* @param {Function} handler
|
||||
* @param {Boolean} once
|
||||
*/
|
||||
<% } %>
|
||||
static addEventListener(event, handler, once = false) {
|
||||
this.invoke({
|
||||
cmd: 'addEventListener',
|
||||
event,
|
||||
handler: this.transformCallback(handler, once),
|
||||
once
|
||||
})
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name emit
|
||||
* @description Emits an event to the Tauri back end
|
||||
* @param {String} event
|
||||
* @param {Object} payload
|
||||
*/
|
||||
<% } %>
|
||||
static emit(event, payload) {
|
||||
this.invoke({
|
||||
cmd: 'emit',
|
||||
event,
|
||||
payload
|
||||
})
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name transformCallback
|
||||
* @description Registers a callback with a uid
|
||||
* @param {Function} callback
|
||||
* @param {Boolean} once
|
||||
* @returns {*}
|
||||
*/
|
||||
<% } %>
|
||||
static transformCallback (callback, once = true) {
|
||||
const identifier = Object.freeze(uid())
|
||||
window[identifier] = (result) => {
|
||||
if (once) {
|
||||
delete window[identifier]
|
||||
}
|
||||
return callback && callback(result)
|
||||
}
|
||||
return identifier
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name promisified
|
||||
* @description Turns a request into a chainable promise
|
||||
* @param {Object} args
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
<% } %>
|
||||
static promisified (args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.invoke({
|
||||
callback: this.transformCallback(resolve),
|
||||
error: this.transformCallback(reject),
|
||||
...args
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name readTextFile
|
||||
* @description Accesses a non-binary file on the user's filesystem
|
||||
* and returns the content. Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
static readTextFile (path) {
|
||||
<% if (tauri.whitelist.readTextFile === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(path)
|
||||
return this.promisified({ cmd: 'readTextFile', path })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('readTextFile')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name readBinaryFile
|
||||
* @description Accesses a binary file on the user's filesystem
|
||||
* and returns the content. Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
static readBinaryFile (path) {
|
||||
<% if (tauri.whitelist.readBinaryFile === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(path)
|
||||
return this.promisified({ cmd: 'readBinaryFile', path })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('readBinaryFile')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name writeFile
|
||||
* @description Write a file to the Local Filesystem.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {Object} cfg
|
||||
* @param {String} cfg.file
|
||||
* @param {String|Binary} cfg.contents
|
||||
*/
|
||||
<% } %>
|
||||
static writeFile (cfg) {
|
||||
Object.freeze(cfg)
|
||||
<% if (tauri.whitelist.writeFile === true || tauri.whitelist.all === true) { %>
|
||||
this.invoke({ cmd: 'writeFile', file: cfg.file, contents: cfg.contents })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('writeFile')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %> }
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name listFiles
|
||||
* @description Get the files in a path.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
static listFiles (path) {
|
||||
<% if (tauri.whitelist.listFiles === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(path)
|
||||
return this.promisified({ cmd: 'listFiles', path })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('listFiles')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name listDirs
|
||||
* @description Get the directories in a path.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
static listDirs (path) {
|
||||
<% if (tauri.whitelist.listDirs === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(path)
|
||||
return this.promisified({ cmd: 'listDirs', path })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('listDirs')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name setTitle
|
||||
* @description Set the application's title
|
||||
* @param {String} title
|
||||
*/
|
||||
<% } %>
|
||||
static setTitle (title) {
|
||||
<% if (tauri.whitelist.setTitle === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(title)
|
||||
this.invoke({ cmd: 'setTitle', title })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('setTitle')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name open
|
||||
* @description Open an URI
|
||||
* @param {String} uri
|
||||
*/
|
||||
<% } %>
|
||||
static open (uri) {
|
||||
<% if (tauri.whitelist.open === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(uri)
|
||||
this.invoke({ cmd: 'open', uri })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('open')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name execute
|
||||
* @description Execute a program with arguments.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} command
|
||||
* @param {String|Array} args
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
static execute (command, args) {
|
||||
<% if (tauri.whitelist.execute === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(command)
|
||||
if (typeof args === 'string' || typeof args === 'object') {
|
||||
Object.freeze(args)
|
||||
}
|
||||
return this.promisified({ cmd: 'execute', command, args: typeof (args) === 'string' ? [args] : args })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('execute')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
}
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name bridge
|
||||
* @description Securely pass a message to the backend.
|
||||
* @example
|
||||
* this.$q.tauri.bridge('QBP/1/ping/client-1', 'pingback')
|
||||
* @param {String} command - a compressed, slash-delimited and
|
||||
* versioned API call to the backend.
|
||||
* @param {String|Object}payload
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
static bridge (command, payload) {
|
||||
<% if (tauri.whitelist.bridge === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(command)
|
||||
if (typeof payload === 'string' || typeof payload === 'object') {
|
||||
Object.freeze(payload)
|
||||
}
|
||||
return this.promisified({ cmd: 'bridge', command, payload: typeof (payload) === 'object' ? [payload] : payload })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('bridge')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
}
|
||||
}
|
||||
18
package.json
18
package.json
@@ -2,7 +2,10 @@
|
||||
"name": "@quasar/tauri",
|
||||
"version": "1.0.0-alpha.1",
|
||||
"description": "Multi-binding collection of libraries and templates for building Tauri",
|
||||
"main": "templates/index.js",
|
||||
"main": "tauri/lib.js",
|
||||
"bin": {
|
||||
"tauri": "tauri/bin/tauri.js"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
@@ -23,5 +26,18 @@
|
||||
"node": ">= 10.16.0",
|
||||
"npm": ">= 6.6.0",
|
||||
"yarn": ">= 1.17.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iarna/toml": "^2.2.3",
|
||||
"chalk": "^2.4.2",
|
||||
"chokidar": "^3.0.2",
|
||||
"cross-spawn": "^6.0.5",
|
||||
"fast-glob": "^3.0.4",
|
||||
"fs-extra": "^8.1.0",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.template": "^4.5.0",
|
||||
"minimist": "^1.2.0",
|
||||
"ms": "^2.1.2",
|
||||
"webpack-merge": "^4.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
42
tauri/bin/tauri-build.js
Normal file
42
tauri/bin/tauri-build.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const
|
||||
parseArgs = require('minimist'),
|
||||
{ writeFileSync } = require('fs-extra'),
|
||||
path = require('path')
|
||||
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
h: 'help',
|
||||
d: 'debug'
|
||||
},
|
||||
boolean: ['h', 'd']
|
||||
})
|
||||
|
||||
if (argv.help) {
|
||||
console.log(`
|
||||
Description
|
||||
Tauri build.
|
||||
Usage
|
||||
$ tauri build
|
||||
Options
|
||||
--help, -h Displays this message
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const appPaths = require('../helpers/app-paths'),
|
||||
Runner = require('../runner'),
|
||||
Injector = require('../injector'),
|
||||
tauri = new Runner(appPaths),
|
||||
injector = new Injector(appPaths),
|
||||
tauriConfig = require('../helpers/tauri-config')({
|
||||
ctx: {
|
||||
debug: argv.debug
|
||||
}
|
||||
})
|
||||
const {bundle, ...cfg} = tauriConfig.tauri,
|
||||
cfgDir = injector.configDir()
|
||||
writeFileSync(path.join(cfgDir, 'config.json'), JSON.stringify(cfg))
|
||||
writeFileSync(path.join(cfgDir, 'bundle.json'), JSON.stringify(bundle))
|
||||
|
||||
require('../helpers/generator')(tauriConfig)
|
||||
tauri.build(tauriConfig)
|
||||
44
tauri/bin/tauri-dev.js
Normal file
44
tauri/bin/tauri-dev.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const
|
||||
parseArgs = require('minimist'),
|
||||
path = require('path'),
|
||||
{ writeFileSync } = require('fs-extra')
|
||||
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
h: 'help'
|
||||
},
|
||||
boolean: ['h']
|
||||
})
|
||||
|
||||
if (argv.help) {
|
||||
console.log(`
|
||||
Description
|
||||
Tauri dev.
|
||||
Usage
|
||||
$ tauri dev
|
||||
Options
|
||||
--help, -h Displays this message
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const appPaths = require('../helpers/app-paths'),
|
||||
Runner = require('../runner'),
|
||||
Injector = require('../injector'),
|
||||
tauri = new Runner(appPaths),
|
||||
injector = new Injector(appPaths),
|
||||
tauriConfig = require('../helpers/tauri-config')({
|
||||
ctx: {
|
||||
debug: true
|
||||
}
|
||||
})
|
||||
|
||||
const { bundle, ...cfg } = tauriConfig.tauri,
|
||||
cfgDir = injector.configDir()
|
||||
|
||||
writeFileSync(path.join(cfgDir, 'config.json'), JSON.stringify(cfg))
|
||||
writeFileSync(path.join(cfgDir, 'bundle.json'), JSON.stringify(bundle))
|
||||
|
||||
require('../helpers/generator')(tauriConfig)
|
||||
|
||||
tauri.run(tauriConfig)
|
||||
29
tauri/bin/tauri-init.js
Normal file
29
tauri/bin/tauri-init.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const
|
||||
parseArgs = require('minimist'),
|
||||
appPaths = require('../helpers/app-paths'),
|
||||
log = require('../helpers/logger')('app:tauri')
|
||||
|
||||
const argv = parseArgs(process.argv.slice(2), {
|
||||
alias: {
|
||||
h: 'help'
|
||||
},
|
||||
boolean: ['h']
|
||||
})
|
||||
|
||||
if (argv.help) {
|
||||
console.log(`
|
||||
Description
|
||||
Inits the Tauri template.
|
||||
Usage
|
||||
$ tauri init
|
||||
Options
|
||||
--help, -h Displays this message
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const Injector = require('../injector'),
|
||||
injector = new Injector(appPaths)
|
||||
if (injector.injectTemplate()) {
|
||||
log('Tauri template successfully installed')
|
||||
}
|
||||
22
tauri/bin/tauri.js
Executable file
22
tauri/bin/tauri.js
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const cmds = ['init', 'dev', 'build', 'help']
|
||||
|
||||
const cmd = process.argv[2]
|
||||
if (!cmd || cmd === '-h' || cmd === '--help' || cmd === 'help') {
|
||||
console.log(`
|
||||
Description
|
||||
Tauri CLI.
|
||||
Usage
|
||||
$ tauri ${cmds.join('|')}
|
||||
Options
|
||||
--help, -h Displays this message
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
if (cmds.includes(cmd)) {
|
||||
process.argv.splice(2, 1)
|
||||
require(`./tauri-${cmd}`)
|
||||
} else {
|
||||
console.log(`Invalid command ${cmd}. Use one of ${cmds.join(',')}.`)
|
||||
}
|
||||
38
tauri/helpers/app-paths.js
Normal file
38
tauri/helpers/app-paths.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const
|
||||
{ existsSync } = require('fs'),
|
||||
path = require('path'),
|
||||
resolve = path.resolve,
|
||||
join = path.join
|
||||
|
||||
function getAppDir() {
|
||||
let dir = process.cwd()
|
||||
|
||||
while (dir.length && dir[dir.length - 1] !== path.sep) {
|
||||
if (existsSync(join(dir, 'tauri.conf.js'))) {
|
||||
return dir
|
||||
}
|
||||
|
||||
dir = path.normalize(join(dir, '..'))
|
||||
}
|
||||
|
||||
const
|
||||
logger = require('./logger')
|
||||
warn = logger('app:paths', 'red')
|
||||
|
||||
warn(`⚠️ Error. This command must be executed inside a Tauri project folder.`)
|
||||
warn()
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const appDir = getAppDir(),
|
||||
tauriDir = resolve(appDir, 'src-tauri')
|
||||
|
||||
module.exports = {
|
||||
appDir,
|
||||
tauriDir,
|
||||
|
||||
resolve: {
|
||||
app: dir => join(appDir, dir),
|
||||
tauri: dir => join(tauriDir, dir)
|
||||
}
|
||||
}
|
||||
13
tauri/helpers/generator.js
Normal file
13
tauri/helpers/generator.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const compileTemplate = require('lodash.template'),
|
||||
{ readFileSync, writeFileSync } = require('fs'),
|
||||
appPaths = require('./app-paths'),
|
||||
path = require('path')
|
||||
|
||||
module.exports = cfg => {
|
||||
const apiTemplate = readFileSync(path.resolve(__dirname, '../../lib/tauri.js'), 'utf-8')
|
||||
const apiContent = compileTemplate(apiTemplate)({
|
||||
...cfg,
|
||||
confName: 'tauri.conf.js'
|
||||
})
|
||||
writeFileSync(appPaths.resolve.tauri('tauri.js'), apiContent, 'utf-8')
|
||||
}
|
||||
21
tauri/helpers/logger.js
Normal file
21
tauri/helpers/logger.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const
|
||||
ms = require('ms'),
|
||||
chalk = require('chalk')
|
||||
|
||||
let prevTime
|
||||
|
||||
module.exports = function (banner, color = 'green') {
|
||||
return function (msg) {
|
||||
const
|
||||
curr = +new Date(),
|
||||
diff = curr - (prevTime || curr)
|
||||
|
||||
prevTime = curr
|
||||
|
||||
if (msg) {
|
||||
console.log(` ${chalk[color](banner)} ${msg} ${chalk.green(`+${ms(diff)}`)}`)
|
||||
} else {
|
||||
console.log()
|
||||
}
|
||||
}
|
||||
}
|
||||
15
tauri/helpers/on-shutdown.js
Normal file
15
tauri/helpers/on-shutdown.js
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = function (fn) {
|
||||
const cleanup = () => {
|
||||
try {
|
||||
fn()
|
||||
} finally {
|
||||
process.exit()
|
||||
}
|
||||
}
|
||||
|
||||
process.on('exit', cleanup)
|
||||
process.on('SIGINT', cleanup)
|
||||
process.on('SIGTERM', cleanup)
|
||||
process.on('SIGHUP', cleanup)
|
||||
process.on('SIGBREAK', cleanup)
|
||||
}
|
||||
62
tauri/helpers/spawn.js
Normal file
62
tauri/helpers/spawn.js
Normal file
@@ -0,0 +1,62 @@
|
||||
const
|
||||
logger = require('./logger'),
|
||||
log = logger('app:spawn'),
|
||||
warn = logger('app:spawn', 'red'),
|
||||
crossSpawn = require('cross-spawn')
|
||||
|
||||
/*
|
||||
Returns pid, takes onClose
|
||||
*/
|
||||
module.exports.spawn = function (cmd, params, cwd, onClose) {
|
||||
log(`Running "${cmd} ${params.join(' ')}"`)
|
||||
log()
|
||||
|
||||
const runner = crossSpawn(
|
||||
cmd,
|
||||
params, {
|
||||
stdio: 'inherit',
|
||||
stdout: 'inherit',
|
||||
stderr: 'inherit',
|
||||
cwd
|
||||
}
|
||||
)
|
||||
|
||||
runner.on('close', code => {
|
||||
log()
|
||||
if (code) {
|
||||
log(`Command "${cmd}" failed with exit code: ${code}`)
|
||||
}
|
||||
|
||||
onClose && onClose(code)
|
||||
})
|
||||
|
||||
return runner.pid
|
||||
}
|
||||
|
||||
/*
|
||||
Returns nothing, takes onFail
|
||||
*/
|
||||
module.exports.spawnSync = function (cmd, params, cwd, onFail) {
|
||||
log(`[sync] Running "${cmd} ${params.join(' ')}"`)
|
||||
log()
|
||||
|
||||
const runner = crossSpawn.sync(
|
||||
cmd,
|
||||
params, {
|
||||
stdio: 'inherit',
|
||||
stdout: 'inherit',
|
||||
stderr: 'inherit',
|
||||
cwd
|
||||
}
|
||||
)
|
||||
|
||||
if (runner.status || runner.error) {
|
||||
warn()
|
||||
warn(`⚠️ Command "${cmd}" failed with exit code: ${runner.status}`)
|
||||
if (runner.status === null) {
|
||||
warn(`⚠️ Please globally install "${cmd}"`)
|
||||
}
|
||||
onFail && onFail()
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
29
tauri/helpers/tauri-config.js
Normal file
29
tauri/helpers/tauri-config.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const appPaths = require('./app-paths'),
|
||||
merge = require('webpack-merge')
|
||||
|
||||
module.exports = cfg => {
|
||||
const tauriConf = require(appPaths.resolve.app('tauri.conf.js'))(cfg.ctx)
|
||||
const config = merge({
|
||||
build: {},
|
||||
ctx: {},
|
||||
tauri: {
|
||||
embeddedServer: {
|
||||
active: true
|
||||
},
|
||||
bundle: {
|
||||
active: true
|
||||
},
|
||||
whitelist: {},
|
||||
window: {
|
||||
title: require(appPaths.resolve.app('package.json')).productName
|
||||
},
|
||||
security: {
|
||||
csp: 'default-src data: filesystem: ws: http: https: \'unsafe-eval\' \'unsafe-inline\''
|
||||
}
|
||||
}
|
||||
}, tauriConf, cfg)
|
||||
|
||||
process.env.TAURI_DIST_DIR = appPaths.resolve.app(config.build.distDir)
|
||||
|
||||
return config
|
||||
}
|
||||
41
tauri/injector.js
Normal file
41
tauri/injector.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const { copySync, renameSync, existsSync, mkdirSync } = require('fs-extra'),
|
||||
path = require('path')
|
||||
|
||||
class TauriInjector {
|
||||
constructor(appPaths) {
|
||||
this.appPaths = appPaths
|
||||
}
|
||||
|
||||
configDir() {
|
||||
return path.resolve(__dirname, '..')
|
||||
}
|
||||
|
||||
injectTemplate() {
|
||||
if (existsSync(this.appPaths.tauriDir)) {
|
||||
console.log(`Tauri dir (${this.appPaths.tauriDir}) not empty.`)
|
||||
return false
|
||||
}
|
||||
mkdirSync(this.appPaths.tauriDir)
|
||||
copySync(path.resolve(__dirname, '../templates/rust'), this.appPaths.tauriDir)
|
||||
const files = require('fast-glob').sync(['**/_*'], {
|
||||
cwd: this.appPaths.tauriDir
|
||||
})
|
||||
for (const rawPath of files) {
|
||||
const targetRelativePath = rawPath.split('/').map(name => {
|
||||
// dotfiles are ignored when published to npm, therefore in templates
|
||||
// we need to use underscore instead (e.g. "_gitignore")
|
||||
if (name.charAt(0) === '_' && name.charAt(1) !== '_') {
|
||||
return `.${name.slice(1)}`
|
||||
}
|
||||
if (name.charAt(0) === '_' && name.charAt(1) === '_') {
|
||||
return `${name.slice(1)}`
|
||||
}
|
||||
return name
|
||||
}).join('/')
|
||||
renameSync(this.appPaths.resolve.tauri(rawPath), this.appPaths.resolve.tauri(targetRelativePath))
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TauriInjector
|
||||
9
tauri/lib.js
Normal file
9
tauri/lib.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const TauriRunner = require('./runner'),
|
||||
TauriInjector = require('./injector'),
|
||||
path = require('path')
|
||||
|
||||
module.exports = {
|
||||
runner: TauriRunner,
|
||||
injector: TauriInjector,
|
||||
apiTemplatePath: path.resolve(__dirname, '../lib/tauri.js')
|
||||
}
|
||||
189
tauri/runner.js
Normal file
189
tauri/runner.js
Normal file
@@ -0,0 +1,189 @@
|
||||
const
|
||||
chokidar = require('chokidar'),
|
||||
debounce = require('lodash.debounce')
|
||||
|
||||
const
|
||||
{ spawn } = require('./helpers/spawn'),
|
||||
log = require('./helpers/logger')('app:tauri')
|
||||
onShutdown = require('./helpers/on-shutdown'),
|
||||
{ readFileSync, writeFileSync } = require('fs-extra')
|
||||
|
||||
class TauriRunner {
|
||||
constructor(appPaths) {
|
||||
this.appPaths = appPaths
|
||||
this.pid = 0
|
||||
this.tauriWatcher = null
|
||||
|
||||
onShutdown(() => {
|
||||
this.stop()
|
||||
})
|
||||
}
|
||||
|
||||
async run(cfg) {
|
||||
const
|
||||
url = cfg.build.APP_URL
|
||||
|
||||
if (this.pid) {
|
||||
if (this.url !== url) {
|
||||
await this.stop()
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
this.__manipulateToml(toml => {
|
||||
this.__whitelistApi(cfg, toml)
|
||||
})
|
||||
|
||||
this.url = url
|
||||
|
||||
const args = ['--url', url]
|
||||
|
||||
const startDevTauri = () => {
|
||||
return this.__runCargoCommand({
|
||||
cargoArgs: ['run', '--features', 'dev'],
|
||||
extraArgs: args
|
||||
})
|
||||
}
|
||||
|
||||
// Start watching for tauri app changes
|
||||
this.tauriWatcher = chokidar
|
||||
.watch([
|
||||
this.appPaths.resolve.tauri('src'),
|
||||
this.appPaths.resolve.tauri('Cargo.toml'),
|
||||
this.appPaths.resolve.tauri('build.rs')
|
||||
], {
|
||||
watchers: {
|
||||
chokidar: {
|
||||
ignoreInitial: true
|
||||
}
|
||||
}
|
||||
})
|
||||
.on('change', debounce(async () => {
|
||||
await this.__stopCargo()
|
||||
startDevTauri()
|
||||
}, 1000))
|
||||
|
||||
return startDevTauri()
|
||||
}
|
||||
|
||||
async build(cfg) {
|
||||
this.__manipulateToml(toml => {
|
||||
this.__whitelistApi(cfg, toml)
|
||||
})
|
||||
|
||||
const features = []
|
||||
if (cfg.tauri.embeddedServer.active) {
|
||||
features.push('embedded-server')
|
||||
}
|
||||
|
||||
const buildFn = target => this.__runCargoCommand({
|
||||
cargoArgs: [cfg.tauri.bundle.active ? 'tauri-bundle' : 'build']
|
||||
.concat(features.length ? ['--features', ...features] : [])
|
||||
.concat(cfg.ctx.debug ? [] : ['--release'])
|
||||
.concat(target ? ['--target', target] : [])
|
||||
})
|
||||
|
||||
if (cfg.ctx.debug || !cfg.ctx.targetName) {
|
||||
// on debug mode or if not arget specified,
|
||||
// build only for the current platform
|
||||
return buildFn()
|
||||
}
|
||||
|
||||
const targets = cfg.ctx.target.split(',')
|
||||
|
||||
for (const target of targets) {
|
||||
await buildFn(target)
|
||||
}
|
||||
}
|
||||
|
||||
stop() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.tauriWatcher && this.tauriWatcher.close()
|
||||
this.__stopCargo().then(resolve)
|
||||
})
|
||||
}
|
||||
|
||||
__runCargoCommand({
|
||||
cargoArgs,
|
||||
extraArgs
|
||||
}) {
|
||||
return new Promise(resolve => {
|
||||
this.pid = spawn(
|
||||
'cargo',
|
||||
|
||||
extraArgs ?
|
||||
cargoArgs.concat(['--']).concat(extraArgs) :
|
||||
cargoArgs,
|
||||
|
||||
this.appPaths.tauriDir,
|
||||
|
||||
code => {
|
||||
if (code) {
|
||||
warn()
|
||||
warn(`⚠️ [FAIL] Cargo CLI has failed`)
|
||||
warn()
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (this.killPromise) {
|
||||
this.killPromise()
|
||||
this.killPromise = null
|
||||
} else { // else it wasn't killed by us
|
||||
warn()
|
||||
warn('Cargo process was killed. Exiting...')
|
||||
warn()
|
||||
process.exit(0)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
__stopCargo() {
|
||||
const pid = this.pid
|
||||
|
||||
if (!pid) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
log('Shutting down tauri process...')
|
||||
this.pid = 0
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.killPromise = resolve
|
||||
process.kill(pid)
|
||||
})
|
||||
}
|
||||
|
||||
__manipulateToml(callback) {
|
||||
const toml = require('@iarna/toml'),
|
||||
tomlPath = this.appPaths.resolve.tauri('Cargo.toml'),
|
||||
tomlFile = readFileSync(tomlPath),
|
||||
tomlContents = toml.parse(tomlFile)
|
||||
|
||||
callback(tomlContents)
|
||||
|
||||
const output = toml.stringify(tomlContents)
|
||||
writeFileSync(tomlPath, output)
|
||||
}
|
||||
|
||||
__whitelistApi(cfg, tomlContents) {
|
||||
if (!tomlContents.dependencies.tauri.features) {
|
||||
tomlContents.dependencies.tauri.features = []
|
||||
}
|
||||
|
||||
if (cfg.tauri.whitelist.all) {
|
||||
if (!tomlContents.dependencies.tauri.features.includes('all-api')) {
|
||||
tomlContents.dependencies.tauri.features.push('all-api')
|
||||
}
|
||||
} else {
|
||||
const whitelist = Object.keys(cfg.tauri.whitelist).filter(w => cfg.tauri.whitelist[w] === true)
|
||||
tomlContents.dependencies.tauri.features = whitelist.concat(tomlContents.dependencies.tauri.features.filter(f => f !== 'api' && cfg.tauri.whitelist[f] !== true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TauriRunner
|
||||
@@ -7,4 +7,6 @@
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
**/*.rs.bk
|
||||
|
||||
tauri.js
|
||||
341
yarn.lock
Normal file
341
yarn.lock
Normal file
@@ -0,0 +1,341 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@iarna/toml@^2.2.3":
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.3.tgz#f060bf6eaafae4d56a7dac618980838b0696e2ab"
|
||||
integrity sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz#7fa8fed654939e1a39753d286b48b4836d00e0eb"
|
||||
integrity sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==
|
||||
dependencies:
|
||||
"@nodelib/fs.stat" "2.0.1"
|
||||
run-parallel "^1.1.9"
|
||||
|
||||
"@nodelib/fs.stat@2.0.1", "@nodelib/fs.stat@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz#814f71b1167390cfcb6a6b3d9cdeb0951a192c14"
|
||||
integrity sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==
|
||||
|
||||
"@nodelib/fs.walk@^1.2.1":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz#6a6450c5e17012abd81450eb74949a4d970d2807"
|
||||
integrity sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==
|
||||
dependencies:
|
||||
"@nodelib/fs.scandir" "2.1.1"
|
||||
fastq "^1.6.0"
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
anymatch@^3.0.1:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.0.3.tgz#2fb624fe0e84bccab00afee3d0006ed310f22f09"
|
||||
integrity sha512-c6IvoeBECQlMVuYUjSwimnhmztImpErfxJzWZhIQinIvQWoGOnB0dLIgifbPHQt5heS6mNlaZG16f06H3C8t1g==
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
|
||||
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
|
||||
|
||||
braces@^3.0.1, braces@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
chalk@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chokidar@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.2.tgz#0d1cd6d04eb2df0327446188cd13736a3367d681"
|
||||
integrity sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==
|
||||
dependencies:
|
||||
anymatch "^3.0.1"
|
||||
braces "^3.0.2"
|
||||
glob-parent "^5.0.0"
|
||||
is-binary-path "^2.1.0"
|
||||
is-glob "^4.0.1"
|
||||
normalize-path "^3.0.0"
|
||||
readdirp "^3.1.1"
|
||||
optionalDependencies:
|
||||
fsevents "^2.0.6"
|
||||
|
||||
color-convert@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
dependencies:
|
||||
color-name "1.1.3"
|
||||
|
||||
color-name@1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
cross-spawn@^6.0.5:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
dependencies:
|
||||
nice-try "^1.0.4"
|
||||
path-key "^2.0.1"
|
||||
semver "^5.5.0"
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
fast-glob@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.0.4.tgz#d484a41005cb6faeb399b951fd1bd70ddaebb602"
|
||||
integrity sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==
|
||||
dependencies:
|
||||
"@nodelib/fs.stat" "^2.0.1"
|
||||
"@nodelib/fs.walk" "^1.2.1"
|
||||
glob-parent "^5.0.0"
|
||||
is-glob "^4.0.1"
|
||||
merge2 "^1.2.3"
|
||||
micromatch "^4.0.2"
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2"
|
||||
integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==
|
||||
dependencies:
|
||||
reusify "^1.0.0"
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
fs-extra@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fsevents@^2.0.6:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a"
|
||||
integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==
|
||||
|
||||
glob-parent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954"
|
||||
integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
|
||||
integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
is-binary-path@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||
|
||||
is-glob@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
||||
integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-number@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
lodash._reinterpolate@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
|
||||
|
||||
lodash.debounce@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
|
||||
|
||||
lodash.template@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
|
||||
integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
|
||||
dependencies:
|
||||
lodash._reinterpolate "^3.0.0"
|
||||
lodash.templatesettings "^4.0.0"
|
||||
|
||||
lodash.templatesettings@^4.0.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33"
|
||||
integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==
|
||||
dependencies:
|
||||
lodash._reinterpolate "^3.0.0"
|
||||
|
||||
lodash@^4.17.5:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
||||
merge2@^1.2.3:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.4.tgz#c9269589e6885a60cf80605d9522d4b67ca646e3"
|
||||
integrity sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A==
|
||||
|
||||
micromatch@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
|
||||
integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
|
||||
dependencies:
|
||||
braces "^3.0.1"
|
||||
picomatch "^2.0.5"
|
||||
|
||||
minimist@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
|
||||
|
||||
ms@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
normalize-path@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
path-key@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
||||
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.0.5:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6"
|
||||
integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==
|
||||
|
||||
readdirp@^3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.1.2.tgz#fa85d2d14d4289920e4671dead96431add2ee78a"
|
||||
integrity sha512-8rhl0xs2cxfVsqzreYCvs8EwBfn/DhVdqtoLmw19uI3SC5avYX9teCurlErfpPXGmYtMHReGaP2RsLnFvz/lnw==
|
||||
dependencies:
|
||||
picomatch "^2.0.4"
|
||||
|
||||
reusify@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||
|
||||
run-parallel@^1.1.9:
|
||||
version "1.1.9"
|
||||
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
|
||||
integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
|
||||
|
||||
semver@^5.5.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
|
||||
dependencies:
|
||||
shebang-regex "^1.0.0"
|
||||
|
||||
shebang-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
|
||||
webpack-merge@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.1.tgz#5e923cf802ea2ace4fd5af1d3247368a633489b4"
|
||||
integrity sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==
|
||||
dependencies:
|
||||
lodash "^4.17.5"
|
||||
|
||||
which@^1.2.9:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
||||
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
Reference in New Issue
Block a user