conextra
Version:
Conextra for Web Development. Helps create a SPWA (Single-page Progressive Web Application).
315 lines (254 loc) • 11.2 kB
JavaScript
/** Copyright (c) Manuel Lõhmus (MIT License) */
'use script';
var conextra_version = require('../package.json').version,
configSets = require("config-sets"),
{ addUser } = require('ws-user'),
{ exec } = require('child_process'),
fs = require('fs'),
path = require('path'),
package = {
name: 'conextra_power',
version: '1.0.0',
main: 'node node_modules/conextra/index.js',
scripts: {
start: 'node node_modules/conextra/index.js',
test: 'echo "Error: no test specified" && exit',
},
license: 'UNLICENSED',
author: '',
dependencies: { conextra: '^1.0.0-beta.1' }
},
{ help, version, init, cwd, add_user, debug } = configSets.arg_options();
configSets.isSaveChanges = false;
//debug = true;
//pDebug('arg_options:', { help, debug, name, cwd });
if (help || (!help && !version && !init && !cwd && !add_user && !debug)) {
console.log(`
conextra [OPTION1=VALUE1] [OPTION2=VALUE2] ...
The following options are supported:
--help Display this help
--version Display version information
--init Create new project - example: --init=projectOfConextra
--cwd <string> Current working directory - Default process.cwd()
--add_user <string> Add user to conextra system - example: --add_user=admin@localhost:password:username
--debug Print debug messages
`);
return process.exit(0);
}
(async function main() {
try {
// Display version information
if (version) {
console.log('Conextra version: ' + conextra_version);
return process.exit(0);
}
// Set current working directory
if (cwd) {
pDebug('Set current working directory:', cwd);
// If cwd is relative path, resolve it to absolute path
if (!path.isAbsolute(cwd)) {
pDebug('CWD is relative path:', cwd);
cwd = path.resolve(process.cwd(), cwd || '');
}
// Check if cwd exists
if (!fs.existsSync(cwd)) {
console.error('CWD does not exist:', cwd);
console.error('Please check the path and try again!');
return process.exit(1);
}
// Check if cwd is a directory
if (!fs.lstatSync(cwd).isDirectory()) {
console.error('CWD is not a directory:', cwd);
console.error('Please check the path and try again!');
return process.exit(1);
}
// Change current working directory
pDebug('CWD is absolute path:', cwd);
process.chdir(cwd);
}
else {
cwd = process.cwd();
}
// Project of Conextra is initialized
var isConextraInstalled = fs.existsSync(path.join(cwd, 'node_modules', 'conextra'));
// Install conextra if it is not installed
if (init !== undefined) {
pDebug('Creating new project:', init);
if (isConextraInstalled) {
console.error('Project already exists!');
return process.exit(1);
}
// Check if init is a empty string
if (init === true) { init = path.basename(cwd); }
// Cange package name to project name
package.name = init;
// Create project directory
if (!cwd.endsWith(init)) {
pDebug('reate project directory:', init)
cwd = path.join(cwd, init);
makeDirIfNotExists(cwd);
process.chdir(cwd);
}
// Create package.json
pDebug('Create package.json');
fs.writeFileSync('package.json', JSON.stringify(package, null, 4));
// Create config-sets.json
pDebug('Create config-sets.json');
fs.writeFileSync('config-sets.json', JSON.stringify(getConfigSetsContent(), null, 4));
// Install conextra
pDebug('Install project dependencies');
await execCommandPromise('npm install');
// Move conextra public files to project public directory.
pDebug('Move conextra public files to project public directory.');
fs.renameSync(
path.join(cwd, 'node_modules', 'conextra', 'public'),
path.join(cwd, 'public')
);
// Move conextra init_server.js to project root directory.
pDebug('Move conextra init_server.js to project root directory.');
fs.renameSync(
path.join(cwd, 'node_modules', 'conextra', 'init_server.js'),
path.join(cwd, 'init_server.js')
);
console.log(`New project initialized: ${cwd}`);
console.log(`Navigate to the project directory: ${cwd}`);
console.log(`Run 'npm start' to start the project`);
//quick-start.html, list-of-modules.html
console.log(`Open in browser, take a closer look http://localhost/pages/quick-start.html`);
return process.exit(0);
}
// Add user to conextra system
if (add_user) {
// Current working directory is set to conextra project directory
var isConextraInstalled = fs.existsSync(path.join(cwd, 'node_modules', 'conextra'));
if (!isConextraInstalled) {
console.error('Wrong working directory!');
console.error('Current working directory is not conextra project directory!');
console.error('Please run this command in the conextra project directory!');
console.error('Or use --init option to initialize new project!');
console.error('Example: conextra --init=projectOfConextra');
console.error('Or use --cwd option to set the current working directory!');
console.error('Example: conextra --cwd=/path/to/conextra/project --add_user=admin@localhost:password:username');
return process.exit(1);
}
pDebug(`Add user to conextra system`);
var [email, password, username] = add_user.split(':'),
msg = addUser(email, password, username);
console.log(msg);
return process.exit(msg.includes('Error') ? 1 : 0);
}
}
catch (err) {
pError(err);
console.error('Something went wrong!');
return process.exit(1);
}
// for debugging
//setTimeout(() => { debugger; }, 10000);
})();
function makeDirIfNotExists(dir) {
if (!fs.existsSync(dir)) {
console.log(`Creating directory: ${dir}`);
fs.mkdirSync(dir, { recursive: true });
}
}
function execCommandPromise(command) {
return new Promise((resolve, reject) => {
console.log(`Executing command: ${command}`);
var child = exec(command, (err) => {
if (err) { reject(err); }
else { resolve(); }
});
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
});
}
function getConfigSetsContent() {
return {
"isProduction": true,
"production": {
"web-cluster": {
"isDebug": false,
"parallelism": "auto 1"
},
"tiny-https-server": {
"isDebug": false,
"host": "0.0.0.0",
"port": 80,
"exclusive": false,
"logDir": "data/log/tiny-https-server",
"directory_index": "index.html",
"primary_domain": {
"document_root": "./public/www",
"service_worker_version": "1",
"service_worker_version_update": true,
"is_new_service_worker_reload_browser": true,
"precache_urls": [
"/node_modules/bootstrap@5/dist/css/bootstrap.min.css",
"/node_modules/bootstrap@5/dist/js/bootstrap.bundle.min.js",
"/node_modules/data-context-binding@2",
"/node_modules/data-context@2",
"/node_modules/tiny-https-server",
"/node_modules/url-fragment-extender@2",
"/node_modules/ws-user"
],
"headers": {
"default": {
"server": "tiny-https-server"
}
},
"sitemap_update": true
},
"subdomains": {},
"cache_control": {
"fileTypes": {
"webp": "max-age=2592000",
"bmp": "max-age=2592000",
"jpeg": "max-age=2592000",
"jpg": "max-age=2592000",
"png": "max-age=2592000",
"svg": "max-age=2592000",
"pdf": "max-age=2592000",
"woff2": "max-age=2592000",
"woff": "max-age=2592000",
"image/svg+xml": "max-age=2592000",
"html": "max-age=86400",
"css": "max-age=86400",
"js": "max-age=86400"
}
},
"pathToBlacklistFile": "data/log/tiny-https-server/blacklist.json",
"bad_path_validation_regex_patterns": [
".php$|.asmx$"
],
"contact_email": "default@localhost",
"pathToCert": "/etc/letsencrypt/live/yourdomain.com/fullchain.pem",
"pathToPrivkey": "/etc/letsencrypt/live/yourdomain.com/privkey.pem"
},
"ws-link": {
"isDebug": false,
"pathToResourseMap": "data/resourse_map.json",
"pathToDataDir": "data"
},
"ws-user": {
"isDebug": false,
"pathToFrontendErrors": "data/log/frontend_errors.log",
"pathToLoggedUsers": "data/logged_users.json",
"pathToUsersDir": "data/users"
},
"nodemailer": {
"isDebug": false,
"domain_account": "localhost",
"auth": {
"user": "*user*@localhost",
"pass": ""
}
}
},
"development": {}
};
}
// Debugging
function pDebug(msg) { if (debug) { console.log(`[ DEBUG ] 'conextra' `, ...arguments); } }
function pError(msg) { if (debug) { console.error(`[ ERROR ] 'conextra' `, ...arguments); } }