const fs = require('fs') const path = require('path') const { SitemapStream, streamToPromise } = require('sitemap') const { Readable } = require('stream') const logger = require('./logger')() /* * This class will output any files in the assets folder * Eg. `./assets/{foldername}/{filename}` * * You can also create a function that will output html * On the client side the `main.js` will use `innerHTML = {output}` */ class ReadFile { constructor(x) { try { this.object = { baseUrl: x.baseUrl, mime: '', main: '', types: x.mime, layouts: { header: fs.readFileSync('./views/layouts/header.html', 'utf-8'), loading: fs.readFileSync('./views/layouts/loading.html', 'utf-8'), footer: fs.readFileSync('./views/layouts/footer.html', 'utf-8') } } for (const key in this.object.layouts) {this.object.layouts[key] = this.#RemoveSpaces(this.object.layouts[key])} } catch(err) { logger.Error(err) } } GetMain(x) { const data = { header: ` ${x.hasOwnProperty('title') ? x.title : 'Undefined'} ${this.object.layouts.loading}
`, footer: `
` } return this.#RemoveSpaces(data.header + data.footer) } async Create(x) { try { return this.#SetData({data: x, mime: this.object.types}) } catch(err) { try { return await x.then(output => { return this.#SetData({data: output, mime: this.object.types}) }) } catch (err) { logger.Error(`${err.code}: Failed to create HTML`) } } } async Sitemap(x) { const object = { keys: x.keys, links: [], remove: ['/', '/blog'], stream: new SitemapStream({hostname: x.url}) } Array.from(object.remove).forEach(url => { object.keys.splice(object.keys.indexOf(url), 1) object.links.push({url: url, changefreq: 'daily', priority: 1}) }) object.keys.forEach(link => object.links.push({url: link, changefreq: 'weekly', priority: 0.8})) return streamToPromise(Readable.from(object.links).pipe(object.stream)).then(data => {return data.toString()}) } NotFound() { return fs.readFileSync('./views/layouts/404.html', 'utf-8') } GetFile(x) { const path = x.split('/') const object = { file: fs.createReadStream(`./assets/${path[1]}/${path[2]}`).on('error', (err) => { logger.Error(err) return null }), mime: this.#GetFileType(path).then(output => {return output}) } if (object.file) {return object} else {return null} } GetFavicon() { const object = { file: fs.createReadStream('./favicon/favicon.ico').on('error', (err) => { logger.Error(`${err.code}: Failed to get 'favicon.ico'`) return null }), mime: this.#GetFileType('favicon.ico') } if (object.file) {return object} else {return null} } GetRobots() { const object = { file: fs.createReadStream('./assets/robots/robots.txt').on('error', (err) => { logger.Error(`${err.code}: Failed to get 'robots.txt'`) return null }), mime: this.#GetFileType('robots.txt') } if (object.file) {return object} else {return null} } CreateBlog(x) { const data = { start: `
`, body: x, end: `
` } return this.#SetData(data) } #SetData(x) { const object = JSON.parse(JSON.stringify(this.object)) object.mime = x.mime.html delete object.types object.layouts.data = this.#RemoveSpaces(x.data) return object } #RemoveSpaces(x) {return x.replace(/^(\n)\s+/gm, '$1')} async #GetFileType(x) {return this.object.types[path.extname(`./assets/${x[1]}/${x[2]}`).slice(1)] || 'text/plain'} } module.exports = ReadFile