diff --git a/.eslintrc.json b/.eslintrc.json
index 895b737..b66130c 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,44 +1,45 @@
-{
- "parserOptions": {
- "ecmaVersion": 9
- },
- "extends": "google",
- "rules": {
+{
+ "parserOptions": {
+ "ecmaVersion": 9
+ },
+ "extends": "google",
+ "rules": {
"no-unused-vars": 0,
"no-tabs": 0,
"one-var": 0,
+ "linebreak-style": 0,
"brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
- "max-len": 0,
- "no-multiple-empty-lines": ["error", { "max": 1, "maxBOF": 1 }],
- "padded-blocks": 0,
- "curly": 0,
- "object-curly-spacing": ["error", "always"],
- "block-spacing": ["error", "always"],
- "array-bracket-spacing": ["error", "always"],
- "prefer-template": 2,
- "new-cap": 0,
- "guard-for-in": 0,
- "indent": [
- "error", "tab", {
- "CallExpression": {
- "arguments": 1
- },
- "FunctionDeclaration": {
- "body": 1,
- "parameters": 2
- },
- "FunctionExpression": {
- "body": 1,
- "parameters": 2
- },
- "MemberExpression": 2,
- "ObjectExpression": 1,
- "SwitchCase": 1,
- "ignoredNodes": [
- "ConditionalExpression",
- "VariableDeclarator"
- ]
- }
- ]
- }
-}
+ "max-len": 0,
+ "no-multiple-empty-lines": ["error", { "max": 1, "maxBOF": 1 }],
+ "padded-blocks": 0,
+ "curly": 0,
+ "object-curly-spacing": ["error", "always"],
+ "block-spacing": ["error", "always"],
+ "array-bracket-spacing": ["error", "always"],
+ "prefer-template": 2,
+ "new-cap": 0,
+ "guard-for-in": 0,
+ "indent": [
+ "error", "tab", {
+ "CallExpression": {
+ "arguments": 1
+ },
+ "FunctionDeclaration": {
+ "body": 1,
+ "parameters": 2
+ },
+ "FunctionExpression": {
+ "body": 1,
+ "parameters": 2
+ },
+ "MemberExpression": 2,
+ "ObjectExpression": 1,
+ "SwitchCase": 1,
+ "ignoredNodes": [
+ "ConditionalExpression",
+ "VariableDeclarator"
+ ]
+ }
+ ]
+ }
+}
diff --git a/local-server.js b/local-server.js
index 4f88d6b..bb8ef80 100644
--- a/local-server.js
+++ b/local-server.js
@@ -1,90 +1,94 @@
-const htmlFiles = [
- 'header',
- 'main',
- 'dashboard/dashboard',
- 'my-addresses/my-addresses',
- 'new-address/new-address',
- 'send/send',
- 'transactions/transactions',
- 'footer',
- 'welcome/welcome',
- 'restore/restore',
- 'create-wallet/create-wallet',
- 'set-password/set-password',
- 'login/login',
-];
-
+const htmlFiles = [
+ 'header',
+ 'main',
+ 'dashboard/dashboard',
+ 'my-addresses/my-addresses',
+ 'new-address/new-address',
+ 'send/send',
+ 'transactions/transactions',
+ 'footer',
+ 'welcome/welcome',
+ 'restore/restore',
+ 'create-wallet/create-wallet',
+ 'set-password/set-password',
+ 'login/login',
+];
+
let workDir = '/src/';
if (process.env.DIST_FOLDER) workDir = `/${process.env.DIST_FOLDER}/`;
const express = require('express');
const app = express();
const fs = require('fs');
+const packageConfig = require('./package.json').config || {};
+
+process.env.IP = process.env.IP || packageConfig.IP;
+process.env.PORT = process.env.PORT || packageConfig.PORT;
if ( ! process.env.IP || ! process.env.PORT) {
console.error('Need to specify IP and PORT environments (example: IP=192.168.23.42 PORT=80 node local-server.js) !');
- process.exit();
-}
-
-let server;
-if (process.env.PORT !== '443') server = require('http').createServer(app);
-else server = require('https').createServer({
- pfx: fs.readFileSync(`${__dirname}/localhost.pfx`),
- passphrase: '12345',
-}, app);
-
-server.listen(process.env.PORT, process.env.IP, () => {
- const address = server.address().address;
- console.log(`Server running at http${process.env.PORT === '443' ? 's' : ''}://${address === '127.0.0.1' ? 'localhost' : address}:${server.address().port} from ${workDir}`);
-});
-
-app.use(express.static(__dirname + workDir));
-
-if (workDir === '/src/') {
- const path = require('path');
-
- const templateJs = (file) => { return ``; };
- const templateCss = (file) => { return ``; };
-
- let pathJsFiles = ``;
- let pathCssFiles = ``;
-
- const generatePathFiles = async (filePath = '') => {
- const fullFilePath = workDir + filePath;
- let files;
- try {
- files = fs.readdirSync(path.join(__dirname, fullFilePath));
- }
- catch (err) {
- return console.error(`unable read files ${fullFilePath}:`, err);
- }
- for await (const file of files) {
- const fileExt = path.extname(file).substr(1);
- if (fileExt === 'js') pathJsFiles += templateJs(file);
- else if (fileExt === 'css') pathCssFiles += templateCss(file);
- else if ( ! fileExt) {
- app.use(express.static(__dirname + fullFilePath + file));
- generatePathFiles(filePath + file);
- }
- }
- };
-
- (async () => {
- await generatePathFiles('../lib/');
- await generatePathFiles();
- })();
-
- app.use(express.static(`${__dirname}/public/`));
- app.use(express.static(`${__dirname}/lib/`));
-
- app.get('/', (req, res) => {
- let outputStr = '';
- outputStr += pathCssFiles;
- htmlFiles.forEach((htmlFile) => {
- outputStr += fs.readFileSync(`${__dirname + workDir + htmlFile}.html`);
- });
- outputStr += pathJsFiles;
- res.setHeader('Content-Type', 'text/html');
- res.send(outputStr);
- });
-}
+ process.exit();
+}
+
+let server;
+if (process.env.PORT !== '443') server = require('http').createServer(app);
+else server = require('https').createServer({
+ pfx: fs.readFileSync(`${__dirname}/localhost.pfx`),
+ passphrase: '12345',
+}, app);
+
+server.listen(process.env.PORT, process.env.IP, () => {
+ const address = server.address().address;
+ console.log(`Server running at http${process.env.PORT === '443' ? 's' : ''}://${address === '127.0.0.1' ? 'localhost' : address}:${server.address().port} from ${workDir}`);
+});
+
+app.use(express.static(__dirname + workDir));
+
+if (workDir === '/src/') {
+ const path = require('path');
+
+ const templateJs = (file) => { return ``; };
+ const templateCss = (file) => { return ``; };
+
+ let pathJsFiles = ``;
+ let pathCssFiles = ``;
+
+ const generatePathFiles = async (filePath = '') => {
+ const fullFilePath = workDir + filePath;
+ let files;
+ try {
+ files = fs.readdirSync(path.join(__dirname, fullFilePath));
+ }
+ catch (err) {
+ return console.error(`unable read files ${fullFilePath}:`, err);
+ }
+ for await (const file of files) {
+ const fileExt = path.extname(file).substr(1);
+ if (fileExt === 'js') pathJsFiles += templateJs(file);
+ else if (fileExt === 'css') pathCssFiles += templateCss(file);
+ else if ( ! fileExt) {
+ app.use(express.static(__dirname + fullFilePath + file));
+ generatePathFiles(filePath + file);
+ }
+ }
+ };
+
+ (async () => {
+ await generatePathFiles('../lib/');
+ await generatePathFiles();
+ })();
+
+ app.use(express.static(`${__dirname}/public/`));
+ app.use(express.static(`${__dirname}/lib/`));
+
+ app.get('/', (req, res) => {
+ let outputStr = '';
+ outputStr += pathCssFiles;
+ htmlFiles.forEach((htmlFile) => {
+ outputStr += fs.readFileSync(`${__dirname + workDir + htmlFile}.html`);
+ });
+ outputStr += pathJsFiles;
+ res.setHeader('Content-Type', 'text/html');
+ res.send(outputStr);
+ });
+}
diff --git a/package.json b/package.json
index 5bc89e4..ff14c64 100644
--- a/package.json
+++ b/package.json
@@ -1,40 +1,40 @@
-{
- "name": "bitgesell-wallet",
- "version": "0.9.5",
- "description": "Bitgesell Wallet JS",
- "homepage": "https://app.bglwallet.io",
- "bugs": "https://github.com/epexa/bitgesell-wallet/issues",
- "license": "Proprietary",
- "author": "epexa",
- "main": "local-server.js",
- "repository": "epexa/bitgesell-wallet",
- "config": {
- "IP": "127.0.0.1",
- "PORT": "80",
- "DIST_FOLDER": "../bitgesell-wallet-dist"
- },
+{
+ "name": "bitgesell-wallet",
+ "version": "0.9.5",
+ "description": "Bitgesell Wallet JS",
+ "homepage": "https://app.bglwallet.io",
+ "bugs": "https://github.com/epexa/bitgesell-wallet/issues",
+ "license": "Proprietary",
+ "author": "epexa",
+ "main": "local-server.js",
+ "repository": "epexa/bitgesell-wallet",
+ "config": {
+ "IP": "127.0.0.1",
+ "PORT": "80",
+ "DIST_FOLDER": "../bitgesell-wallet-dist"
+ },
"scripts": {
- "test": "eslint 'src/*.js'",
- "local-server": "IP=$npm_package_config_IP PORT=$npm_package_config_PORT node local-server.js",
+ "test": "eslint src/*.js",
+ "local-server": "node local-server.js",
"start": "npm test && npm run local-server",
- "build": "./build.sh $npm_package_config_DIST_FOLDER",
- "dist-start": "npm run build && DIST_FOLDER=$npm_package_config_DIST_FOLDER npm run local-server"
- },
- "husky": {
- "hooks": {
- "pre-commit": "npm test"
- }
+ "build": "npm test && node scripts/build.js",
+ "dist-start": "npm run build && node scripts/dist-server.js"
},
- "devDependencies": {
- "@babel/cli": "^7.2.3",
- "@babel/core": "^7.4.0",
- "@babel/preset-env": "^7.4.2",
- "clean-css-cli": "^4.2.1",
- "eslint": "^5.15.3",
- "eslint-config-google": "^0.12.0",
- "express": "^4.16.4",
- "html-minifier": "^3.5.21",
- "husky": "^2.3.0",
- "uglify-js": "^3.5.2"
- }
-}
+ "husky": {
+ "hooks": {
+ "pre-commit": "npm test"
+ }
+ },
+ "devDependencies": {
+ "@babel/cli": "^7.2.3",
+ "@babel/core": "^7.4.0",
+ "@babel/preset-env": "^7.4.2",
+ "clean-css-cli": "^4.2.1",
+ "eslint": "^5.15.3",
+ "eslint-config-google": "^0.12.0",
+ "express": "^4.16.4",
+ "html-minifier": "^3.5.21",
+ "husky": "^2.3.0",
+ "uglify-js": "^3.5.2"
+ }
+}
diff --git a/scripts/build.js b/scripts/build.js
new file mode 100644
index 0000000..69338f5
--- /dev/null
+++ b/scripts/build.js
@@ -0,0 +1,127 @@
+const fs = require('fs');
+const path = require('path');
+const { execFileSync } = require('child_process');
+
+const rootDir = path.resolve(__dirname, '..');
+const packageConfig = require('../package.json').config || {};
+const distFolder = path.resolve(
+ rootDir,
+ process.argv[2] ||
+ process.env.DIST_FOLDER ||
+ process.env.npm_package_config_DIST_FOLDER ||
+ packageConfig.DIST_FOLDER ||
+ '../bitgesell-wallet-dist',
+);
+
+const packageBin = (packageName, binName) => {
+ const packagePath = require.resolve(`${packageName}/package.json`);
+ const packageJson = require(packagePath);
+ const binConfig = packageJson.bin;
+ const binPath = typeof binConfig === 'string' ? binConfig : binConfig[binName];
+ return path.join(path.dirname(packagePath), binPath);
+};
+
+const bins = {
+ babel: packageBin('@babel/cli', 'babel'),
+ uglifyjs: packageBin('uglify-js', 'uglifyjs'),
+ 'html-minifier': packageBin('html-minifier', 'html-minifier'),
+ cleancss: packageBin('clean-css-cli', 'cleancss'),
+};
+
+const run = (name, args) => {
+ execFileSync(process.execPath, [ bins[name], ...args ], {
+ cwd: rootDir,
+ stdio: 'inherit',
+ });
+};
+
+const copyRecursive = (from, to) => {
+ fs.mkdirSync(to, { recursive: true });
+ for (const entry of fs.readdirSync(from, { withFileTypes: true })) {
+ const source = path.join(from, entry.name);
+ const target = path.join(to, entry.name);
+ if (entry.isDirectory()) copyRecursive(source, target);
+ else fs.copyFileSync(source, target);
+ }
+};
+
+const src = (...parts) => path.join(rootDir, ...parts);
+const dist = (...parts) => path.join(distFolder, ...parts);
+
+fs.mkdirSync(distFolder, { recursive: true });
+copyRecursive(src('public'), distFolder);
+
+const appJs = dist('app.js');
+run('babel', [
+ src('src', 'utils.js'),
+ src('src', 'api.js'),
+ src('src', 'app.js'),
+ src('src', 'login', 'login.js'),
+ src('src', 'welcome', 'welcome.js'),
+ src('src', 'create-wallet', 'create-wallet.js'),
+ src('src', 'set-password', 'set-password.js'),
+ src('src', 'restore', 'restore.js'),
+ src('src', 'my-addresses', 'my-addresses.js'),
+ src('src', 'new-address', 'new-address.js'),
+ src('src', 'transactions', 'transactions.js'),
+ src('src', 'dashboard', 'dashboard.js'),
+ src('src', 'send', 'send.js'),
+ '-o',
+ appJs,
+]);
+
+run('uglifyjs', [
+ src('lib', '1-jquery.slim.min.js'),
+ src('lib', '2-jquery.dataTables.min.js'),
+ src('lib', '3-dataTables.bootstrap4.min.js'),
+ src('lib', '4-dataTables.responsive.min.js'),
+ src('lib', '5-responsive.bootstrap.min.js'),
+ src('lib', 'bootstrap-native.min.js'),
+ src('lib', 'sweetalert2.min.js'),
+ src('lib', 'qrcode.js'),
+ src('lib', 'satoshi-bitcoin.js'),
+ src('lib', 'aes4js.min.js'),
+ src('lib', 'dayjs.min.js'),
+ appJs,
+ '-c',
+ 'drop_console=true,toplevel=true',
+ '-m',
+ 'toplevel=true',
+ '-o',
+ dist('app.min.js'),
+]);
+
+fs.unlinkSync(appJs);
+
+run('html-minifier', [
+ '--collapse-whitespace',
+ '--remove-comments',
+ src('src', 'header.html'),
+ src('src', 'main.html'),
+ src('src', 'my-addresses', 'my-addresses.html'),
+ src('src', 'new-address', 'new-address.html'),
+ src('src', 'transactions', 'transactions.html'),
+ src('src', 'dashboard', 'dashboard.html'),
+ src('src', 'send', 'send.html'),
+ src('src', 'footer.html'),
+ src('src', 'welcome', 'welcome.html'),
+ src('src', 'create-wallet', 'create-wallet.html'),
+ src('src', 'restore', 'restore.html'),
+ src('src', 'set-password', 'set-password.html'),
+ src('src', 'login', 'login.html'),
+ '-o',
+ dist('index.html'),
+]);
+
+run('cleancss', [
+ src('lib', 'sweetalert2.min.css'),
+ src('lib', 'dataTables.bootstrap4.min.css'),
+ src('lib', 'responsive.bootstrap4.min.css'),
+ src('lib', 'icomoon.css'),
+ src('src', 'custom.css'),
+ '-o',
+ dist('custom.min.css'),
+ '--skip-rebase',
+]);
+
+console.log(`Built wallet assets in ${distFolder}`);
diff --git a/scripts/dist-server.js b/scripts/dist-server.js
new file mode 100644
index 0000000..34b4569
--- /dev/null
+++ b/scripts/dist-server.js
@@ -0,0 +1,5 @@
+const packageConfig = require('../package.json').config || {};
+
+process.env.DIST_FOLDER = process.env.DIST_FOLDER || packageConfig.DIST_FOLDER;
+
+require('../local-server');