@handfish/hygen
Version:
The scalable code generator that saves you time.
89 lines (82 loc) • 2.34 kB
text/typescript
import { RenderedAction, RunnerConfig } from './types'
import fs from 'fs-extra'
import ejs from 'ejs'
import fm from 'front-matter'
import path from 'path'
import walk from 'ignore-walk'
import context from './context'
// for some reason lodash/fp takes 90ms to load.
// inline what we use here with the regular lodash.
const map = f => arr => arr.map(f)
const filter = f => arr => arr.filter(f)
const ignores = [
'prompt.js',
'index.js',
'prompt.ts',
'index.ts',
'.hygenignore',
'.DS_Store',
'.Spotlight-V100',
'.Trashes',
'ehthumbs.db',
'Thumbs.db',
]
const renderTemplate = (tmpl, locals, config) =>
typeof tmpl === 'string' ? ejs.render(tmpl, context(locals, config)) : tmpl
async function getFiles(dir) {
const files = walk
.sync({ path: dir, ignoreFiles: ['.hygenignore'] })
.map(f => path.join(dir, f))
return files
}
const render = async (
args: any,
config: RunnerConfig,
): Promise<RenderedAction[]> =>
getFiles(args.actionfolder)
.then(things => things.sort((a, b) => a.localeCompare(b))) // TODO: add a test to verify this sort
.then(filter(f => !ignores.find(ig => f.endsWith(ig)))) // TODO: add a
// test for ignoring prompt.js and index.js
.then(
filter(file =>
args.subaction
? file.replace(args.actionfolder, '').match(args.subaction)
: true,
),
)
.then(
map(file =>
fs.readFile(file).then(text => ({ file, text: text.toString() })),
),
)
.then(_ => Promise.all(_))
.then(
map(({ file, text }) => {
if(config.debug) console.debug('Pre-formatting file:', file)
return { file, ...fm(text, { allowUnsafe: true }) }
}),
)
.then(
map(({ file, attributes, body }) => {
const renderedAttrs = Object.entries(attributes).reduce(
(obj, [key, value]) => {
return {
...obj,
[key]: renderTemplate(value, args, config),
}
},
{},
)
if(config.debug) console.debug('Rendering file:', file)
return {
file,
attributes: renderedAttrs,
body: renderTemplate(
body,
{ ...args, attributes: renderedAttrs },
config,
),
}
}),
)
export default render