UNPKG

jschemer

Version:

A Node.js library to generate documentation for JSON Schemas

149 lines (126 loc) 3.85 kB
const handlebars = require(`handlebars`); const markdown = require(`./markdown`); const path = require(`path`); const { readFile } = require(`fs`).promises; /** * A list of JSON Schema annotation and meta keywords * @type {Array} */ const metaKeys = [ `$comment`, `$id`, `$schema`, `description`, `default`, `examples`, `readOnly`, `writeOnly`, ]; /** * A Handlebars helper to check whether an item is an array * @param {Any} item The item to check * @param {Object} options Handlebars options * @return {String} */ function isArray(item, options) { return Array.isArray(item) ? options.fn(this) : options.inverse(this); } /** * A Handlebars helper to check whether an item is a boolean * @param {Any} item The item to check * @param {Object} options Handlebars options * @return {String} */ function isBoolean(item, options) { return typeof item === `boolean` ? options.fn(this) : options.inverse(this); } /** * A Handlebars helper to check whether an item is defined * @param {Any} item The item to check * @param {Object} options Handlebars options * @return {String} */ function isDefined(item, options) { return typeof item === `undefined` ? options.inverse(this) : options.fn(this); } /** * A Handlebars helper to check whether an item is a string * @param {Any} item The item to check * @param {Object} options Handlebars options * @return {Boolean} */ function isString(item, options) { return typeof item === `string` ? options.fn(this) : options.inverse(this); } /** * A Handlebars helper to check whether an item is equal to the value true * @param {Any} item The item to check * @param {Object} options Handlebars options * @return {String} */ function isTrue(item, options) { const isDefinitelyTrue = item === true || ( typeof item === `object` && item.constructor === Boolean && item.valueOf() === true ); return isDefinitelyTrue ? options.fn(this) : options.inverse(this); } /** * A Handlebars helper to check whether a schema is an empty schema * @param {Object} schema The schema to check * @param {Object} options Handlebars options * @return {Boolean} */ function emptySchema(schema, options) { const isEmptySchema = Object.keys(schema) .filter(key => !metaKeys.includes(key)) .length === 0; return isEmptySchema ? options.fn(this) : options.inverse(this); } /** * A Handlebars helper that JSON stringifies an object * @param {Any} data The JavaScript object to stringify * @return {String} Returns a JSON string */ function json(data) { return JSON.stringify(data, null, 2); } /** * A Markdown helper for Handlebars * @param {String} text The Markdown text to render as HTML * @param {String} [inline] If set to `inline`, the Markdown text is rendered inline * @return {String} Returns an HTML string */ function md(text, inline) { if (!text) return ``; const method = inline === `inline` ? `renderInline` : `render`; return new handlebars.SafeString(markdown[method](text)); } // Register helpers handlebars.registerHelper({ emptySchema, isArray, isBoolean, isDefined, isString, isTrue, json, md, }); /** * This method loads each of the jschemer Handlebars partials and registers them to the Handlebars instance * @return {Promise} */ handlebars.registerPartials = async () => { const navPartialPath = path.join(__dirname, `../../components/nav/nav.hbs`); const navPartial = await readFile(navPartialPath, `utf8`); const schemaPartialPath = path.join(__dirname, `../../components/schema/schema.hbs`); const schemaPartial = await readFile(schemaPartialPath, `utf8`); handlebars.registerPartial({ nav: navPartial, schema: schemaPartial, }); }; module.exports = handlebars;