UNPKG

hikarujs

Version:

A static site generator that generates routes based on directories naturally.

78 lines (72 loc) 2.22 kB
/** * @module helper */ import {isObject, checkType, getFullDocPath} from "./utils.js"; /** * @description Context helper. * This is used to register properties to context of all decorated files, if you * only need to register properties to context of a specific layout, you could * do that while registering decorator. */ class Helper { /** * @param {Logger} logger * @return {Helper} */ constructor(logger) { this.logger = logger; // Using Array because they need to be called in sequence, so user's custom // handlers will be called after internal handlers. this._ = []; } /** * @callback helpCallback * @description The returned object will be merged with context while * decorating with templates. * @param {Site} site * @param {File} file * @return {Object} */ /** * @description Register a helper function. * @param {String} name * @param {helpCallback} fn * @param {String} [layout=null] If you want to run this helper * function on a specific layout, pass it here as a filter. */ register(name, fn, layout = null) { checkType(name, "name", "String"); checkType(fn, "fn", "Function"); checkType(layout, "layout", "String", "null"); this._.push({name, fn, layout}); } /** * @description Run all helper functions and gather context. * @param {Site} site * @param {File} file * @return {Promise<Object>} */ async getContext(site, file) { // Decorator uses layout to select template, so files without layout cannot // be decorated and have no context. if (file["layout"] == null) { return {}; } const all = await Promise.all(this._.filter(({name, fn, layout}) => { return layout == null || layout === file["layout"]; }).map(({name, fn, layout}) => { this.logger.debug(`Hikaru is running helper of \`${ this.logger.blue(name) }\` for \`${ this.logger.cyan(getFullDocPath(file)) }\`...`); return fn(site, file); })); return all.filter((cur) => { return cur != null && isObject(cur); }).reduce((acc, cur, idx, src) => { return Object.assign(acc, cur); }, {}); } } export default Helper;