1
0
Fork 0
mirror of synced 2024-07-02 13:01:09 +12:00
budibase/packages/server/utilities/builder/buildPage.js
Michael Shanks 4089b52c53
Client Api - New state binding method (#105)
* new binding...
- state manager
- one store per screen
- not passing

* client lib binding - tests passing

* binding fully working again post stateManager

* bugfix with button component

* Control flow ("code") now working, tests passing

* Events List now reading from component definition

* fix to button.svelte - missing props._children
2020-02-18 12:29:38 +00:00

165 lines
4.3 KiB
JavaScript

const { appPackageFolder } = require("../createAppPackage")
const { componentLibraryInfo } = require("./componentLibraryInfo")
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")
const deleteCodeMeta = require("./deleteCodeMeta")
module.exports = async (config, appname, pageName, pkg) => {
const appPath = appPackageFolder(config, appname)
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)
}
const rootPath = (config, appname) =>
config.useAppRootPath ? `/${appname}` : ""
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
)
}
const buildIndexHtml = async (config, appname, pageName, appPath, pkg) => {
const appPublicPath = publicPath(appPath, pageName)
const appRootPath = rootPath(config, appname)
const stylesheetUrl = s =>
s.indexOf("http://") === 0 || s.indexOf("https://") === 0
? s
: `/${rootPath(config, appname)}/${s}`
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,
}
const indexHtmlTemplate = await readFile(
resolve(__dirname, "index.template.html"),
"utf8"
)
const indexHtmlPath = join(appPublicPath, "index.html")
const indexHtml = sqrl.Render(indexHtmlTemplate, templateObj)
await writeFile(indexHtmlPath, indexHtml, { flag: "w+" })
}
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
}
if (shouldCopy) {
await copyFile(source, destPath, constants.COPYFILE_FICLONE)
}
}
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_DEFINITION##'] = ${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
}
if (pkg.page._screens) {
delete pkg.page._screens
}
deleteCodeMeta(pkg.page.props)
await writeJSON(pageFile, pkg.page, {
spaces: 2,
})
}