@uiengine/core
Version:
Create, document and evolve your design system collaboratively.
121 lines (95 loc) • 3.35 kB
JavaScript
const {
UiengineInputError,
ComponentUtil: { componentFilePathToId },
DebugUtil: { debug3 },
FileUtil: { extension }
} = require('@uiengine/util')
const getModule = ({ config: { adapters } }, ext, filePath) => {
const { module } = adapters[ext] || {}
if (!module) {
throw new UiengineInputError(`Cannot handle ${filePath}: No "${ext}" adapter configured.`)
}
try {
return require(module)
} catch (err) {
throw new UiengineInputError(`Cannot load "${ext}" adapter.`, err)
}
}
const getOptions = (state, ext, additional = {}) => {
const { config: { adapters, target, themes, source: { base, components, templates }, ui: { base: uiBase } } } = state
const themeIds = themes.map(theme => theme.id)
const { options } = adapters[ext]
return Object.assign({}, options, additional, { ext, base, components, templates, target, themeIds, uiBase })
}
async function setup (state) {
debug3(state, 'Connector.setup():start')
const { config: { adapters } } = state
const exts = Object.keys(adapters || {})
const tasks = []
exts.forEach(ext => {
const { setup: setupFn } = getModule(state, ext)
if (typeof setupFn === 'function') {
const options = getOptions(state, ext)
tasks.push(setupFn(options))
}
})
await Promise.all(tasks)
debug3(state, 'Connector.setup():end')
}
async function registerComponentFile (state, filePath) {
const { config: { adapters, source: { components } } } = state
const ext = extension(filePath)
const adapter = adapters[ext]
if (adapter) {
const { registerComponentFile: registerFn } = getModule(state, ext, filePath)
if (typeof registerFn === 'function') {
const options = getOptions(state, ext)
const data = await registerFn(options, filePath)
if (data) {
const id = componentFilePathToId(components, filePath)
return { id, filePath, data }
}
}
}
}
async function render (state, templatePath, data = {}, themeId, identifier) {
const ext = extension(templatePath)
const { render: renderFn } = getModule(state, ext, templatePath)
if (typeof renderFn === 'function') {
const options = getOptions(state, ext, { themeId })
const renderId = `${themeId}/${identifier}`
const rendered = await renderFn(options, templatePath, data, renderId)
return typeof rendered === 'string' ? { rendered } : rendered
} else {
throw new UiengineInputError(`The "${ext}" adapter does not support rendering.`)
}
}
async function filesForComponent (state, ext, componentName) {
const { filesForComponent: filesFn } = getModule(state, ext)
const options = getOptions(state, ext)
const fnExists = typeof filesFn === 'function'
if (fnExists && !options.skipScaffold) {
const files = await filesFn(options, componentName)
return files
} else {
return []
}
}
async function filesForVariant (state, ext, componentName, variantName) {
const { filesForVariant: filesFn } = getModule(state, ext)
const options = getOptions(state, ext)
const fnExists = typeof filesFn === 'function'
if (fnExists && !options.skipScaffold) {
const files = await filesFn(options, componentName, variantName)
return files
} else {
return []
}
}
module.exports = {
setup,
render,
registerComponentFile,
filesForComponent,
filesForVariant
}