Refactor, units, tests
This commit is contained in:
parent
519c34bc60
commit
cd90705ba1
24 changed files with 1221 additions and 1222 deletions
71
src/prepare.js
Normal file
71
src/prepare.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
const u = require('./utils')
|
||||
const a = require('./assert')
|
||||
|
||||
const unnest = exports.unnest = (config) => {
|
||||
if (a.type(config)() !== 'object') return config
|
||||
const result = {}
|
||||
for (const [key, val] of Object.entries(config)) {
|
||||
u.deep(result, key, unnest(val))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const _extend = exports._extend = (to, from) => {
|
||||
const to_type = a.type(to)()
|
||||
const from_type = a.type(from)()
|
||||
if (from === undefined || from === null) return to
|
||||
if (from === '!!unset') return undefined
|
||||
if (to_type != from_type) return from
|
||||
if (from_type == 'object') {
|
||||
const res = u.deepcopy(to)
|
||||
for (const key of Object.keys(from)) {
|
||||
res[key] = _extend(to[key], from[key])
|
||||
if (res[key] === undefined) delete res[key]
|
||||
}
|
||||
return res
|
||||
} else if (from_type == 'array') {
|
||||
const res = u.deepcopy(to)
|
||||
for (const [i, val] of from.entries()) {
|
||||
res[i] = _extend(res[i], val)
|
||||
}
|
||||
return res
|
||||
} else return from
|
||||
}
|
||||
|
||||
const extend = exports.extend = (...args) => {
|
||||
let res = args[0]
|
||||
for (const arg of args) {
|
||||
if (res == arg) continue
|
||||
res = _extend(res, arg)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
const _inherit = exports._inherit = (config, root, breadcrumbs) => {
|
||||
if (a.type(config)() !== 'object') return config
|
||||
const result = {}
|
||||
for (const [key, val] of Object.entries(config)) {
|
||||
breadcrumbs.push(key)
|
||||
let newval = _inherit(val, root, breadcrumbs)
|
||||
if (newval && newval.extends !== undefined) {
|
||||
let candidates = [newval.extends]
|
||||
const list = [newval]
|
||||
while (candidates.length) {
|
||||
const path = candidates.shift()
|
||||
const other = u.deepcopy(u.deep(root, path))
|
||||
a.assert(other, `"${path}" (reached from "${breadcrumbs.join('.')}.${key}.extends") does not name a valid target!`)
|
||||
let parents = other.extends || []
|
||||
if (a.type(parents)() !== 'array') parents = [parents]
|
||||
candidates = candidates.concat(parents)
|
||||
list.unshift(other)
|
||||
}
|
||||
newval = extend.apply(this, list)
|
||||
delete newval.extends
|
||||
}
|
||||
result[key] = newval
|
||||
breadcrumbs.pop()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const inherit = exports.inherit = (config) => _inherit(config, config, [])
|
Loading…
Add table
Add a link
Reference in a new issue