budibase/packages/server/utilities/builder/buildPage.js

158 lines
4.2 KiB
JavaScript
Raw Normal View History

const { appPackageFolder } = require("../createAppPackage")
const { componentLibraryInfo } = require("./componentLibraryInfo")
2019-09-06 14:04:23 +02:00
const {
stat,
ensureDir,
pathExists,
constants,
copyFile,
writeFile,
readFile,
writeJSON,
} = require("fs-extra")
const { join, resolve, dirname } = require("path")
const sqrl = require("squirrelly")
const { convertCssToFiles } = require("./convertCssToFiles")
const publicPath = require("./publicPath")
2019-09-06 14:04:23 +02:00
module.exports = async (config, appname, pageName, pkg) => {
const appPath = appPackageFolder(config, appname)
2020-02-11 17:36:16 +01:00
pkg.screens = pkg.screens || []
await convertCssToFiles(publicPath(appPath, pageName), pkg)
await buildIndexHtml(config, appname, pageName, appPath, pkg)
await buildFrontendAppDefinition(config, appname, pageName, pkg, appPath)
await copyClientLib(appPath, pageName)
await savePageJson(appPath, pageName, pkg)
2019-09-06 14:04:23 +02:00
}
const rootPath = (config, appname) =>
config.useAppRootPath ? `/${appname}` : ""
2019-09-06 14:04:23 +02:00
2019-09-07 07:50:35 +02:00
const copyClientLib = async (appPath, pageName) => {
const sourcepath = require.resolve("@budibase/client")
const destPath = join(publicPath(appPath, pageName), "budibase-client.js")
await copyFile(sourcepath, destPath, constants.COPYFILE_FICLONE)
await copyFile(
sourcepath + ".map",
destPath + ".map",
constants.COPYFILE_FICLONE
)
2019-09-06 14:04:23 +02:00
}
const buildIndexHtml = async (config, appname, pageName, appPath, pkg) => {
const appPublicPath = publicPath(appPath, pageName)
const appRootPath = rootPath(config, appname)
2019-09-06 14:04:23 +02:00
const stylesheetUrl = s =>
s.indexOf("http://") === 0 || s.indexOf("https://") === 0
? s
: `/${rootPath(config, appname)}/${s}`
2019-09-06 14:04:23 +02:00
const templateObj = {
title: pkg.page.title || "Budibase App",
favicon: `${appRootPath}/${pkg.page.favicon || "/_shared/favicon.png"}`,
stylesheets: (pkg.page.stylesheets || []).map(stylesheetUrl),
screenStyles: pkg.screens.filter(s => s._css).map(s => s._css),
pageStyle: pkg.page._css,
appRootPath,
}
2019-09-06 14:04:23 +02:00
const indexHtmlTemplate = await readFile(
resolve(__dirname, "index.template.html"),
"utf8"
)
2019-09-06 14:04:23 +02:00
const indexHtmlPath = join(appPublicPath, "index.html")
2019-09-06 14:04:23 +02:00
const indexHtml = sqrl.Render(indexHtmlTemplate, templateObj)
2019-09-09 06:24:14 +02:00
await writeFile(indexHtmlPath, indexHtml, { flag: "w+" })
2019-09-06 14:04:23 +02:00
}
const buildFrontendAppDefinition = async (config, appname, pageName, pkg) => {
const appPath = appPackageFolder(config, appname)
const appPublicPath = publicPath(appPath, pageName)
const appRootPath = rootPath(config, appname)
const componentLibraries = []
for (let lib of pkg.page.componentLibraries) {
const info = await componentLibraryInfo(appPath, lib)
const libFile = info.components._lib || "index.js"
const source = join(info.libDir, libFile)
const moduleDir = join(
appPublicPath,
"lib",
info.libDir.replace(appPath, "")
)
const destPath = join(moduleDir, libFile)
await ensureDir(dirname(destPath))
componentLibraries.push({
importPath: destPath.replace(appPublicPath, "").replace(/\\/g, "/"),
libName: lib,
})
let shouldCopy = !(await pathExists(destPath))
if (!shouldCopy) {
const destStat = await stat(destPath)
const sourceStat = await stat(source)
shouldCopy = destStat.ctimeMs !== sourceStat.ctimeMs
2019-09-06 14:04:23 +02:00
}
if (shouldCopy) {
await copyFile(source, destPath, constants.COPYFILE_FICLONE)
2019-09-07 07:50:35 +02:00
}
}
const filename = join(appPublicPath, "clientFrontendDefinition.js")
if (pkg.page._css) {
delete pkg.page._css
}
for (let screen of pkg.screens) {
if (screen._css) {
delete pkg.page._css
}
}
const clientUiDefinition = JSON.stringify({
componentLibraries: componentLibraries,
appRootPath: appRootPath,
page: pkg.page,
screens: pkg.screens,
})
await writeFile(
filename,
`window['##BUDIBASE_FRONTEND_DEINITION##'] = ${clientUiDefinition};
window['##BUDIBASE_FRONTEND_FUNCTIONS##'] = ${pkg.uiFunctions}`
)
}
const savePageJson = async (appPath, pageName, pkg) => {
const pageFile = join(appPath, "pages", pageName, "page.json")
if (pkg.page._css) {
delete pkg.page._css
}
if (pkg.page.name) {
delete pkg.page.name
}
await writeJSON(pageFile, pkg.page, {
spaces: 2,
})
}