UNPKG

1.85 kBJavaScriptView Raw
1const chalk = require('chalk')
2const minimatch = require('minimatch')
3const Metalsmith = require('metalsmith')
4const util = require('./util')
5const hbs = require('./hbs')
6
7/**
8 * Filter by template filters
9 */
10const filter = filters => {
11 return (files, metalsmith, next) => {
12 if (!filters) return next()
13
14 const metadata = metalsmith.metadata()
15
16 const filenames = Object.keys(files)
17
18 Object.keys(filters)
19 .filter(glob => !filters[glob](metadata))
20 .forEach(glob => {
21 const match = minimatch.filter(glob, { dot: true, matchBase: true })
22 filenames.forEach(file => match(file) && delete files[file])
23 })
24
25 next()
26 }
27}
28
29/**
30 * Template render
31 */
32const render = helpers => {
33 helpers && hbs.registerHelper(helpers)
34
35 return (files, metalsmith, next) => {
36 const metadata = metalsmith.metadata()
37 for (const item in files) {
38 let contents = files[item].contents.toString()
39 contents = hbs.render(contents, metadata)
40 files[item].contents = Buffer.from(contents)
41 }
42 next()
43 }
44}
45
46/**
47 * Generate from template
48 * @param {String} src Template path
49 * @param {String} dest Destination path
50 * @param {Object} data User answers
51 * @param {Object} options Template options
52 * @return {Promise} Generate promise
53 */
54module.exports = (src, dest, data, options) => new Promise((resolve, reject) => {
55 const { metadata, template, filters, helpers } = options || {}
56
57 Metalsmith(src)
58 .metadata(Object.assign({}, metadata, data))
59 .use(filter(filters))
60 .use(render(helpers))
61 .source(template || 'template')
62 .destination(dest)
63 .clean(false)
64 .build((err, files) => {
65 if (err) return reject(err)
66 console.log(`\n🎉 "${data.name}" generated into ${chalk.yellow(util.tildify(dest))}`)
67 resolve(files)
68 })
69})