Skip to content

Instantly share code, notes, and snippets.

@bramblex
Created September 11, 2018 02:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bramblex/2e788275c87fe8999778c5de92b49eb0 to your computer and use it in GitHub Desktop.
Save bramblex/2e788275c87fe8999778c5de92b49eb0 to your computer and use it in GitHub Desktop.
const { template } = require('./template')
function setEnv(env, paris) {
for (const [name, value] of Object.entries(paris)) {
let get
if (typeof value === 'string') {
const { dependencies, tplFunc } = template(value)
if (dependencies) {
get = () => {
const values = {}
for (const dep of dependencies) {
if (dep === name) {
const parentEnv = getParentEnv(env)
const value = parentEnv ? parentEnv[dep] : undefined
values[dep] = value === undefined ? `{{ ${dep} }}` : value
} else {
const value = env[dep]
values[dep] = value === undefined ? `{{ ${dep} }}` : value
}
}
return tplFunc(values)
}
} else {
get = () => value
}
} else if (typeof value === 'function') {
const func = value
get = () => func(env)
} else {
get = () => value
}
Object.defineProperty(env, name, { get, enumerable: true, configurable: true })
}
}
function showEnv(env) {
const result = {}
for (const name in env) {
result[name] = env[name]
}
return result
}
function getParentEnv(env) {
return Object.getPrototypeOf(env)
}
function createEnv(parentEnv = null, pairs = null) {
const env = Object.create(parentEnv)
if (pairs) setEnv(env, pairs)
return env
}
module.exports = {
createEnv,
setEnv,
showEnv,
getParentEnv
}
const defaultRe = /\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/
function template(tpl, re = defaultRe) {
const matched = tpl.match(new RegExp(re, 'g'))
if (!matched) {
return { dependencies: null, tpl, tplFunc: () => tpl }
} else {
const tmp = {}
for (const token of matched) {
const [, name] = re.exec(token)
tmp[name] = true
}
const dependencies = [...Object.keys(tmp)]
const tplFunc = new Function('env', 'return' + JSON.stringify(tpl).replace(re, '" + env.$1 + "'))
return { dependencies, tpl, tplFunc }
}
}
module.exports = { template }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment