"use strict";
import async from 'async';
import bag from 'bagofcli';
import cpr from 'cpr';
import dateformat from 'dateformat';
import Engine from './engine.js';
import fs from 'fs';
import p from 'path';
import watch from '@cnakazawa/watch';
import wrench from 'wrench';
const DIRNAME = p.dirname(import.meta.url).replace('file://', '');
/**
* class AE86
*/
class AE86 {
constructor(opts) {
opts = opts || {};
this.outDir = opts.outDir || 'out';
}
/**
* Create example AE86 project files in current directory.
*
* @param {Function} cb: standard cb(err, result) callback
*/
init(cb) {
cpr.cpr(p.join(DIRNAME, '../examples'), '.', cb);
}
/**
* Generate website based on the templates and params.
*
* @param {Function} cb: standard cb(err, result) callback
*/
generate(cb) {
const self = this;
function _static(cb) {
// copy static files as-is
cpr.cpr('static', self.outDir, cb);
}
function _pages(cb) {
function _params(cb) {
function prepParams(result) {
const params = result.params;
// add website info
params.sitemap = params.sitemap || {};
params.__genId = dateformat('yyyymmddHHMMss');
cb(null, params);
}
// initialise userland params
const paramsFile = p.join(process.cwd(), 'params.js');
if (fs.existsSync(paramsFile)) {
import(paramsFile)
.then(result => prepParams(result))
.catch(err => cb(err));
} else {
cb(null, null);
}
}
const engine = new Engine(),
tasks = {};
['partials', 'layouts', 'pages'].forEach((dir) => {
tasks[dir] = function (cb) {
engine.compile(dir, cb);
};
});
async.parallel(tasks, (err, results) => {
function prepParams(err, result) {
if (err) {
cb(err);
} else {
engine.merge(self.outDir, results, result || {}, cb);
}
}
_params(prepParams);
});
}
async.parallel([_static, _pages], cb);
}
/**
* Watch for any file changes in AE86 project files.
* A change means the project website will automatically be regenerated.
*/
watch() {
const self = this;
function _listener() {
// no callback because the process shouldn't exit
self.generate();
}
function _watch(file) {
watch.watchTree(file, function (f, curr, prev) {
if (typeof f === "object" && prev === null && curr === null) {
bag.logStepItemSuccess('Watching for file changes at %s...', file);
} else if (prev === null) {
bag.logStepItemSuccess('%s was created', file);
_listener();
} else if (curr.nlink === 0) {
bag.logStepItemSuccess('%s was deleted', file);
self.clean();
_listener();
} else {
bag.logStepItemSuccess('%s was modified', file);
_listener();
}
});
}
['static', 'partials', 'layouts', 'pages', 'params.js'].forEach(_watch);
}
/**
* Remove the generated website.
*
* @param {Function} cb: standard cb(err, result) callback
*/
clean(cb) {
wrench.rmdirRecursive(this.outDir, cb);
}
}
export {
AE86 as default
};