Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Object.keys(components).forEach((componentKey) => {
const component = components[componentKey]
// values coming from the input UIDL
const { fileName, componentClassName } = component.outputOptions || {
fileName: '',
componentClassName: '',
}
const defaultComponentName = 'AppComponent'
const friendlyName = StringUtils.removeIllegalCharacters(component.name) || defaultComponentName
const friendlyFileName = fileName || StringUtils.camelCaseToDashCase(friendlyName) // ex: primary-button
const friendlyComponentName =
componentClassName || StringUtils.dashCaseToUpperCamelCase(friendlyName) // ex: PrimaryButton
const folderPath = UIDLUtils.getComponentFolderPath(component)
const {
customComponentFileName,
customStyleFileName,
customTemplateFileName,
} = componentStrategyOptions
// If the component has its own folder, name is 'index' or an override from the strategy.
// In this case, the file name (dash converted) is used as the folder name
if (componentStrategyOptions.createFolderForEachComponent) {
component.outputOptions = {
componentClassName: friendlyComponentName,
fileName: (customComponentFileName && customComponentFileName(friendlyFileName)) || 'index',
styleFileName: (customStyleFileName && customStyleFileName(friendlyFileName)) || 'style',
templateFileName:
export const extractPageOptions = (
routeDefinitions: UIDLStateDefinition,
routeName: string,
useFileNameForNavigation = false
): UIDLPageOptions => {
const isHomePage = routeDefinitions.defaultValue === routeName
const pageDefinitions = routeDefinitions.values || []
const pageDefinition = pageDefinitions.find((stateDef) => stateDef.value === routeName)
// If no meta object is defined, the stateName is used
const defaultPageName = 'AppPage'
const friendlyStateName = StringUtils.removeIllegalCharacters(routeName) || defaultPageName // remove space, leading numbers, etc.
const friendlyComponentName = StringUtils.dashCaseToUpperCamelCase(friendlyStateName) // component name in UpperCamelCase
const friendlyFileName = StringUtils.camelCaseToDashCase(friendlyStateName) // file name in dash-case
let pageOptions: UIDLPageOptions = {
// default values extracted from state name
fileName: friendlyFileName,
componentName: friendlyComponentName,
navLink: '/' + (isHomePage ? '' : friendlyFileName),
}
if (pageDefinition && pageDefinition.pageOptions) {
// The pageDefinition values have precedence, defaults are fallbacks
pageOptions = {
...pageOptions,
...pageDefinition.pageOptions,
}
}
UIDLUtils.traverseElements(node, (element) => {
let { style } = element
const { key, elementType } = element
if (style && Object.keys(style).length > 0) {
const root = jsxNodesLookup[key]
let className = StringUtils.dashCaseToUpperCamelCase(key)
// Styled components might create an element that clashes with native element (Text, View, Image, etc.)
if (
illegalComponentNames.includes(className) ||
StringUtils.dashCaseToUpperCamelCase(key) === name ||
Object.keys(dependencies).includes(className)
) {
className = `Styled${className}`
}
const timesReferred = countPropReferences(style, 0)
if (componentLibrary === 'reactnative') {
style = UIDLUtils.cleanupNestedStyles(style)
}
const { elementType, name, key, children, attrs, dependency, events, selfClosing } = node.content
const tagName = elementType || 'component'
const safeTagName =
dependency && dependency.type === 'local'
? templateSyntax.customElementTagName(tagName)
: tagName
const htmlNode = createHTMLNode(safeTagName)
if (dependency && templateSyntax.dependencyHandling === 'import') {
if (dependency.type !== 'local') {
// library and package dependencies are assumed to be safe
dependencies[tagName] = { ...dependency }
} else {
// local dependencies can be renamed based on their safety (eg: Header/header, Form/form)
const safeImportName = StringUtils.dashCaseToUpperCamelCase(safeTagName)
dependencies[safeImportName] = { ...dependency }
}
}
if (attrs) {
Object.keys(attrs).forEach((attrKey) => {
const attrValue = attrs[attrKey]
handleAttribute(htmlNode, name, attrKey, attrValue, params, templateSyntax, node)
})
}
if (events) {
Object.keys(events).forEach((eventKey) =>
handleEvent(htmlNode, name, eventKey, events[eventKey], params, templateSyntax)
)
}
const generateElementNode: NodeToLitHTML = (node, params) => {
const { dependencies } = params
const { elementType, dependency, children, attrs } = node.content
const tagName = elementType || 'component'
let attributes = ''
if (dependency) {
if (dependency.type !== 'local') {
// library and package dependencies are assumed to be safe
dependencies[tagName] = { ...dependency }
} else {
// local dependencies can be renamed based on their safety (eg: Header/header, Form/form)
const safeImportName = StringUtils.dashCaseToUpperCamelCase(tagName)
dependencies[safeImportName] = { ...dependency }
}
}
let childTags: string = ''
if (children && children.length > 0) {
children.forEach((child) => {
const childTag = generateNode(child, params)
childTags = `${childTags} ${childTag}`
})
}
if (attrs) {
Object.keys(attrs).forEach((attribute) => {
const { type, content } = attrs[attribute]
UIDLUtils.traverseElements(node, (element) => {
let { style } = element
const { key, elementType } = element
if (style && Object.keys(style).length > 0) {
const root = jsxNodesLookup[key]
let className = StringUtils.dashCaseToUpperCamelCase(key)
// Styled components might create an element that clashes with native element (Text, View, Image, etc.)
if (
illegalComponentNames.includes(className) ||
StringUtils.dashCaseToUpperCamelCase(key) === name ||
Object.keys(dependencies).includes(className)
) {
className = `Styled${className}`
}
const timesReferred = countPropReferences(style, 0)
if (componentLibrary === 'reactnative') {
style = UIDLUtils.cleanupNestedStyles(style)
}
jssStyleMap[className] = UIDLUtils.transformDynamicStyles(
style,
(styleValue, attribute) => {
if (styleValue.content.referenceType === 'prop') {
const dashCaseAttribute = StringUtils.dashCaseToCamelCase(attribute)
t.identifier('loadChildren'),
t.arrowFunctionExpression(
[],
t.callExpression(
t.memberExpression(
t.callExpression(t.identifier('import'), [
t.stringLiteral(`./pages/${fileName}/${fileName}.module`),
]),
t.identifier('then')
),
[
t.arrowFunctionExpression(
[t.identifier('m')],
t.memberExpression(
t.identifier('m'),
t.identifier(`${StringUtils.dashCaseToUpperCamelCase(fileName)}Module`)
)
),
]
)
)
),
])
})
const isPropEvent = statement && statement.type === 'propCall' && statement.calls
if (isPropEvent) {
const eventEmitter = templateSyntax.eventEmmitter(statement.calls)
hastUtils.addAttributeToNode(htmlNode, eventHandlerKey, eventEmitter)
} else {
hastUtils.addAttributeToNode(
htmlNode,
eventHandlerKey,
statement.newState === '$toggle'
? `${statement.modifies} = !${statement.modifies}`
: `${statement.modifies} = ${statement.newState}`
)
}
} else {
const methodName = `handle${StringUtils.dashCaseToUpperCamelCase(
elementName
)}${StringUtils.dashCaseToUpperCamelCase(eventKey)}`
const eventNameBiding = templateSyntax.eventHandlersBindingMode
? templateSyntax.eventHandlersBindingMode(methodName)
: methodName
methodsObject[methodName] = eventHandlerStatements
hastUtils.addAttributeToNode(htmlNode, eventHandlerKey, eventNameBiding)
}
}
export const createPageModule = async (
pageUIDL: ComponentUIDL,
strategy: ProjectStrategy,
options: GeneratorOptions
) => {
pageUIDL.outputOptions = pageUIDL.outputOptions || {}
pageUIDL.outputOptions.moduleName = `${StringUtils.dashCaseToUpperCamelCase(
pageUIDL.outputOptions.folderPath[0]
)}Module`
return strategy.pages.moduleGenerator.generateComponent(pageUIDL, options)
}