const fs = require('fs') const path = require('path') const { Filter, orderBy, reduce } = require('@helpers/siteomat-query') const PageFactory = require('./../factories/page.js') const BlocksQuery = require('./../queries/blocks.js') /** * Pages - search, filter and find pages * * @author Björn Hase * @license http://opensource.org/licenses/MIT The MIT License * @link https://gitea.node001.net/HerrHase/siteomat-webpack-plugin.git * */ class Pages { /** * * * @param {string} dirPath * */ constructor(dirPath) { // constants this.FILE_EXTENSION = '.md' this.FILE_INDEX = 'index' this.DIRECTORY_BLOCKS = '_blocks' // default options for find this._options = { parent: '', deep: -1 } this._dirPath = dirPath this._results = [] } /** * find pages * * @param {Object} [options={}] * @return {array} * */ find(options = {}) { this._results = [] this._count = 0 options = Object.assign({}, this._options, options) if (options.filter) { this._filter = new Filter(options.filter) } this._findFiles(this._dirPath, options) // if (options.orderBy && options.orderBy.length > 0) { this.results = orderBy(options.orderBy, this._results) } if (options.limit || options.offset) { this._results = reduce(options, this._results) } return this._results } /** * find files * * @param {[type]} dirPath [description] * @param {Object} [parameters={}] [description] * @param {Object} [options={}] [description] * @return {[type]} * */ _findFiles(dirPath, options) { // getting all files const files = fs.readdirSync(dirPath + options.parent, { withFileTypes: true }) files.forEach((file) => { // skip for file that is not markdown if (file.isFile() && path.extname(file.name) !== this.FILE_EXTENSION ) { return; } // skip for file that is index but not root if (file.isFile() && file.name === (this.FILE_INDEX + this.FILE_EXTENSION) && options.parent !== '') { return; } // skip for directory that contains partials if (file.isDirectory() && file.name === this.DIRECTORY_BLOCKS) { return; } // if directory going deep if (file.isDirectory() && (options.deep > 0 || options.deep === -1)) { if (options.deep > 0) { options.deep-- } const childrenOptions = Object.assign({}, options, { 'parent': options.parent + '/' + file.name }) this._findFiles(dirPath, childrenOptions) } // get file const content = this._getFile(file, dirPath + options.parent) // skip if empty if (!content) { return; } // check if const blocks = this._getBlocks(dirPath + options.parent + '/' + file.name) // create page object and add to page const page = new PageFactory(file, options.parent, content, blocks) // check for filters and skip if (this._filter && !this._filter.validate(page.get())) { return; } this._results.push(page.get()) }) } /** * * * @param {string} dirPath * @return {array} * */ _getBlocks(dirPath) { const blocksQuery = new BlocksQuery(dirPath) return blocksQuery.find() } /** * get file content * * @param {string} slug * @param {string} sourcePath * @return {mixed} * */ _getFile(file, dirPath) { // file let result = null // path of file, first try with slug let filePath = dirPath + '/' + file.name if (fs.existsSync(filePath) && file.isFile()) { result = fs.readFileSync(filePath, 'utf8') } else { filePath = dirPath + '/' + file.name + '/' + this.FILE_INDEX + this.FILE_EXTENSION if (fs.existsSync(filePath)) { result = fs.readFileSync(filePath, 'utf8') } } return result } } module.exports = Pages