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

133 lines
4.1 KiB
JavaScript
Raw Normal View History

2019-09-06 14:04:23 +02:00
const {
appPackageFolder
} = require("../createAppPackage");
const { componentLibraryInfo } = require("./componentLibraryInfo");
const {
stat, ensureDir, pathExists,
constants, copyFile, writeFile,
readFile
} = require("fs-extra");
2019-09-11 07:08:39 +02:00
const { join, resolve, dirname } = require("path");
2019-09-06 14:04:23 +02:00
const sqrl = require('squirrelly');
2019-09-07 07:50:35 +02:00
module.exports = async (config, appname, pages, appdefinition) => {
2019-09-06 14:04:23 +02:00
const appPath = appPackageFolder(config, appname);
await buildClientAppDefinition(
config, appname,
2019-09-09 06:24:14 +02:00
appdefinition,
2019-09-07 07:50:35 +02:00
appPath, pages, "main");
await buildClientAppDefinition(
config, appname,
2019-09-09 06:24:14 +02:00
appdefinition,
2019-09-07 07:50:35 +02:00
appPath, pages, "unauthenticated")
2019-09-06 14:04:23 +02:00
await buildIndexHtml(
config, appname, appPath,
2019-09-07 07:50:35 +02:00
pages, "main");
await buildIndexHtml(
config, appname, appPath,
pages, "unauthenticated");
await copyClientLib(appPath, "main");
await copyClientLib(appPath, "unauthenticated");
2019-09-06 14:04:23 +02:00
}
2019-09-09 06:24:14 +02:00
const publicPath = (appPath, pageName) => join(appPath, "public", pageName);
2019-09-06 14:04:23 +02:00
const rootPath = (config, appname) => config.useAppRootPath ? `/${appname}` : "";
2019-09-07 07:50:35 +02:00
const copyClientLib = async (appPath, pageName) => {
2019-11-09 09:14:10 +01:00
var sourcepath = require.resolve("@budibase/client");
2019-09-07 07:50:35 +02:00
var destPath = join(publicPath(appPath, pageName), "budibase-client.js");
2019-09-06 14:04:23 +02:00
await copyFile(sourcepath, destPath, constants.COPYFILE_FICLONE);
2019-09-12 07:10:50 +02:00
await copyFile(sourcepath + ".map", destPath + ".map", constants.COPYFILE_FICLONE);
2019-09-06 14:04:23 +02:00
}
2019-09-07 07:50:35 +02:00
const buildIndexHtml = async (config, appname, appPath, pages, pageName) => {
2019-09-06 14:04:23 +02:00
2019-09-07 07:50:35 +02:00
const appPublicPath = publicPath(appPath, pageName);
2019-09-06 14:04:23 +02:00
const appRootPath = rootPath(config, appname);
const stylesheetUrl = s =>
s.indexOf('http://') === 0 || s.indexOf('https://') === 0
? s
: `/${rootPath(config, appname)}/${s}`;
const templateObj = {
2019-09-07 07:50:35 +02:00
title: pages[pageName].index.title || "Budibase App",
2019-09-12 16:55:36 +02:00
favicon: `${appRootPath}/${pages[pageName].index.favicon || "/_shared/favicon.png"}`,
2019-09-09 06:24:14 +02:00
stylesheets: (pages.stylesheets || []).map(stylesheetUrl),
2019-09-06 14:04:23 +02:00
appRootPath
}
const indexHtmlTemplate = await readFile(
2019-09-09 06:24:14 +02:00
resolve(__dirname, "index.template.html"), "utf8");
2019-09-06 14:04:23 +02:00
const indexHtmlPath = join(appPublicPath, "index.html");
2019-09-09 06:24:14 +02:00
const indexHtml = sqrl.Render(indexHtmlTemplate, templateObj)
2019-09-06 14:04:23 +02:00
await writeFile(
indexHtmlPath,
2019-09-09 06:24:14 +02:00
indexHtml,
2019-09-06 14:04:23 +02:00
{flag:"w+"});
2019-09-09 06:24:14 +02:00
2019-09-06 14:04:23 +02:00
}
2019-09-07 07:50:35 +02:00
const buildClientAppDefinition = async (config, appname, appdefinition, appPath, pages, pageName) => {
const appPublicPath = publicPath(appPath, pageName);
2019-09-06 14:04:23 +02:00
const appRootPath = rootPath(config, appname);
2019-09-07 07:50:35 +02:00
const componentLibraries = [];
2019-09-06 14:04:23 +02:00
for(let lib of pages.componentLibraries) {
const info = await componentLibraryInfo(appPath, lib);
2019-09-09 06:24:14 +02:00
const libFile = info.components._lib || "index.js";
2019-09-11 07:08:39 +02:00
const source = join(info.libDir, libFile);
const moduleDir = join(appPublicPath, "lib", info.libDir.replace(appPath, ""));
const destPath = join(moduleDir, libFile);
2019-09-06 14:04:23 +02:00
2019-09-11 07:08:39 +02:00
await ensureDir(dirname(destPath));
2019-09-12 07:10:50 +02:00
componentLibraries.push({
importPath: destPath.replace(appPublicPath, "")
.replace(/\\/g, "/"),
libName: lib
});
2019-09-06 14:04:23 +02:00
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, "clientAppDefinition.js");
2019-09-07 07:50:35 +02:00
const clientAppDefObj = {
hierarchy: appdefinition.hierarchy,
2019-09-12 07:10:50 +02:00
componentLibraries: componentLibraries,
2019-09-07 07:50:35 +02:00
appRootPath: appRootPath,
props: appdefinition.props[pageName]
}
2019-09-06 14:04:23 +02:00
await writeFile(filename,
`window['##BUDIBASE_APPDEFINITION##'] = ${JSON.stringify(clientAppDefObj)};
window['##BUDIBASE_UIFUNCTIONS##'] = ${appdefinition.uiFunctions}`);
2019-09-06 14:04:23 +02:00
}