UNPKG

@uiengine/core

Version:

Create, document and evolve your design system collaboratively.

112 lines (94 loc) 3.67 kB
const R = require('ramda') const { UiengineInputError, StringUtil: { hasContent }, PageUtil: { isDocumentationPage, isIndexPage, pageIdForComponentId, pageIdToPath, pagePathForComponentId, parentIdForPageId } } = require('@uiengine/util') const assocNavigation = (navigation, entry) => R.assoc(entry.id, entry, navigation) const dataForPageId = (state, id) => { const { pages, components } = state // page const page = pages[id] const availableComponentIds = components ? Object.keys(components) : [] const componentIds = page.componentIds || [] const componentPageIds = R.map(componentId => { if (availableComponentIds.includes(componentId)) { return pageIdForComponentId(id, componentId) } else { throw new UiengineInputError([ `Component "${componentId}" does not exist, but was inserted on page "${id}".`, 'Here is a list of available components:', availableComponentIds.map(id => `- ${id}`).join('\n') ]) } }, componentIds) const childIds = page.childIds.concat(componentPageIds) const relations = dataForRelations(pages, id, childIds) const data = R.mergeRight(relations, { id, itemId: id, isStructural: isDocumentationPage(page.type) && !hasContent(page.content), path: isIndexPage(id) ? '/' : `/${page.path}/`, type: page.type, title: page.title, keywords: (page.keywords || []).concat(page.tags || []) }) if (!data.isStructural) delete data.isStructural if (page.collapsed) data.collapsed = true if (data.keywords.length === 0) delete data.keywords // component childpages const componentData = R.partial(dataForComponentId, [state, page]) const componentsData = R.map(componentData, componentIds) return [data, ...componentsData] } const dataForComponentId = (state, parent, id) => { const { components, pages } = state const component = components[id] const pageId = pageIdForComponentId(parent.id, component.id) const pagePath = pagePathForComponentId(parent.path, component.id) const relations = dataForRelations(pages, pageId, []) const variantTags = R.uniq(R.flatten(R.pluck('tags', component.variants))) const data = R.mergeRight(relations, { id: pageId, itemId: id, path: `/${pagePath}/`, type: component.type, title: component.title, keywords: (component.keywords || []).concat(component.tags || []).concat(variantTags) }) if (data.keywords.length === 0) delete data.keywords return data } const dataForRelations = (pages, id, childIds) => { let siblings = [] const data = {} const pageIds = Object.keys(pages) const parentId = parentIdForPageId(pageIds, id) const parent = pages[parentId] if (parent) { const parentPrefix = pageIdToPath(parent.id) const parentComponentPageIds = R.map(componentId => `${parentPrefix}/${componentId}`, parent.componentIds || []) siblings = (parent.childIds || []).concat(parentComponentPageIds) } const indexInSiblings = R.indexOf(id, siblings) if (indexInSiblings > 0) data.prevSiblingId = siblings[indexInSiblings - 1] if (indexInSiblings < siblings.length - 1) data.nextSiblingId = siblings[indexInSiblings + 1] if (childIds.length) data.childIds = childIds if (parentId) data.parentId = parentId return data } async function fetch (state) { const ids = Object.keys(state.pages) const data = R.partial(dataForPageId, [state]) const navigationData = R.chain(data, ids) const navigation = R.reduce(assocNavigation, {}, navigationData) return navigation } async function fetchForPageId (state, id) { return dataForPageId(state, id) } module.exports = { fetch, fetchForPageId }