"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 { fileURLToPath } from "url";
import watch from "@cnakazawa/watch";
import wrench from "wrench";
const DIRNAME = p.dirname(fileURLToPath(import.meta.url));
/**
* 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 };