Restore lost utility files
This commit is contained in:
parent
62edeb3c3d
commit
5536a95c21
|
@ -0,0 +1,134 @@
|
|||
const {
|
||||
appPackageFolder
|
||||
} = require("../createAppPackage");
|
||||
const { componentLibraryInfo } = require("./componentLibraryInfo");
|
||||
const {
|
||||
stat, ensureDir, pathExists,
|
||||
constants, copyFile, writeFile,
|
||||
readFile
|
||||
} = require("fs-extra");
|
||||
const { join, resolve, dirname } = require("path");
|
||||
const sqrl = require('squirrelly');
|
||||
|
||||
module.exports = async (config, appname, pages, appdefinition) => {
|
||||
|
||||
const appPath = appPackageFolder(config, appname);
|
||||
|
||||
await buildClientAppDefinition(
|
||||
config, appname,
|
||||
appdefinition,
|
||||
appPath, pages, "main");
|
||||
|
||||
await buildClientAppDefinition(
|
||||
config, appname,
|
||||
appdefinition,
|
||||
appPath, pages, "unauthenticated")
|
||||
|
||||
await buildIndexHtml(
|
||||
config, appname, appPath,
|
||||
pages, "main");
|
||||
|
||||
await buildIndexHtml(
|
||||
config, appname, appPath,
|
||||
pages, "unauthenticated");
|
||||
|
||||
await copyClientLib(appPath, "main");
|
||||
await copyClientLib(appPath, "unauthenticated");
|
||||
|
||||
}
|
||||
|
||||
const publicPath = (appPath, pageName) => join(appPath, "public", pageName);
|
||||
const rootPath = (config, appname) => config.useAppRootPath ? `/${appname}` : "";
|
||||
|
||||
const copyClientLib = async (appPath, pageName) => {
|
||||
var sourcepath = require.resolve("@budibase/client");
|
||||
var 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, appPath, pages, pageName) => {
|
||||
|
||||
|
||||
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: pages[pageName].index.title || "Budibase App",
|
||||
favicon: `${appRootPath}/${pages[pageName].index.favicon || "/_shared/favicon.png"}`,
|
||||
stylesheets: (pages.stylesheets || []).map(stylesheetUrl),
|
||||
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 buildClientAppDefinition = async (config, appname, appdefinition, appPath, pages, pageName) => {
|
||||
|
||||
|
||||
const appPublicPath = publicPath(appPath, pageName);
|
||||
const appRootPath = rootPath(config, appname);
|
||||
|
||||
|
||||
const componentLibraries = [];
|
||||
|
||||
for(let lib of pages.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, "clientAppDefinition.js");
|
||||
|
||||
const clientAppDefObj = {
|
||||
hierarchy: appdefinition.hierarchy,
|
||||
componentLibraries: componentLibraries,
|
||||
appRootPath: appRootPath,
|
||||
props: appdefinition.props[pageName]
|
||||
}
|
||||
|
||||
await writeFile(filename,
|
||||
`window['##BUDIBASE_APPDEFINITION##'] = ${JSON.stringify(clientAppDefObj)}`);
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
const {
|
||||
readJSON, exists
|
||||
} = require("fs-extra");
|
||||
const {
|
||||
resolve, join , dirname
|
||||
} = require("path");
|
||||
|
||||
const getLibDir = (appPath, libname) => {
|
||||
try {
|
||||
const componentsFile = require.resolve(
|
||||
join(libname, "components.json"),
|
||||
{ paths: [appPath]});
|
||||
return dirname(componentsFile);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
const getComponentsFilepath = libPath =>
|
||||
resolve(libPath, "components.json");
|
||||
|
||||
module.exports.componentsFilepath = (appPath, libname) =>
|
||||
getComponentsFilepath(getLibDir(appPath, libname));
|
||||
|
||||
module.exports.componentLibraryInfo = async (appPath, libname) => {
|
||||
|
||||
const libDir = getLibDir(appPath, libname);
|
||||
const componentsPath = getComponentsFilepath(libDir);
|
||||
|
||||
if(!await exists(componentsPath)) {
|
||||
const e = new Error(`could not find components definition file at ${componentsPath}`);
|
||||
e.statusCode = 404;
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
const components = await readJSON(componentsPath);
|
||||
const namespacedComponents = {_lib:components._lib};
|
||||
for(let cname in components) {
|
||||
if(cname === "_lib" || cname == "_generators") continue;
|
||||
const namespacedName = `${libname}/${cname}`;
|
||||
components[cname].name = namespacedName;
|
||||
namespacedComponents[namespacedName] = components[cname];
|
||||
}
|
||||
|
||||
const namespacedGenerators = {}
|
||||
if(components._generators) {
|
||||
namespacedGenerators._lib=components._generators._lib || "generators.js";
|
||||
for(let gname in components._generators) {
|
||||
if(gname === "_lib") continue;
|
||||
const namespacedName = `${libname}/${gname}`;
|
||||
components._generators[gname].name = namespacedName;
|
||||
namespacedGenerators[namespacedName] = components._generators[gname];
|
||||
}
|
||||
}
|
||||
|
||||
return ({
|
||||
components: namespacedComponents,
|
||||
generators: namespacedGenerators,
|
||||
libDir,
|
||||
componentsPath
|
||||
});
|
||||
} catch(e) {
|
||||
const err = `could not parse JSON - ${componentsPath} : ${e.message}`;
|
||||
throw new Error(err);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
const {
|
||||
appPackageFolder,
|
||||
appsFolder
|
||||
} = require("../createAppPackage");
|
||||
const {
|
||||
readJSON, writeJSON, readdir,
|
||||
stat, ensureDir, rename,
|
||||
unlink, rmdir
|
||||
} = require("fs-extra");
|
||||
const {
|
||||
join,dirname
|
||||
} = require("path");
|
||||
const { $ } = require("@budibase/core").common;
|
||||
const {
|
||||
keyBy, intersection, map
|
||||
} = require("lodash/fp");
|
||||
const {merge} = require("lodash");
|
||||
|
||||
const { componentLibraryInfo } = require("./componentLibraryInfo");
|
||||
const savePackage = require("./savePackage");
|
||||
const buildApp = require("./buildApp");
|
||||
|
||||
module.exports.savePackage = savePackage;
|
||||
|
||||
const getPages = async (appPath) => await readJSON(`${appPath}/pages.json`);
|
||||
const getAppDefinition = async (appPath) => await readJSON(`${appPath}/appDefinition.json`);
|
||||
|
||||
module.exports.getPackageForBuilder = async (config, appname) => {
|
||||
const appPath = appPackageFolder(config, appname);
|
||||
|
||||
const pages = await getPages(appPath);
|
||||
|
||||
return ({
|
||||
appDefinition: await getAppDefinition(appPath),
|
||||
|
||||
accessLevels: await readJSON(`${appPath}/access_levels.json`),
|
||||
|
||||
pages,
|
||||
|
||||
components: await getComponents(appPath, pages),
|
||||
|
||||
screens: keyBy("name")(
|
||||
await fetchscreens(appPath))
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports.getApps = async (config, master) => {
|
||||
const dirs = await readdir(appsFolder(config));
|
||||
|
||||
return $(master.listApplications(), [
|
||||
map(a => a.name),
|
||||
intersection(dirs)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
const componentPath = (appPath, name) =>
|
||||
join(appPath, "components", name + ".json");
|
||||
|
||||
module.exports.saveScreen = async (config, appname, component) => {
|
||||
const appPath = appPackageFolder(config, appname);
|
||||
const compPath = componentPath(appPath, component.name);
|
||||
await ensureDir(dirname(compPath));
|
||||
await writeJSON(
|
||||
compPath,
|
||||
component,
|
||||
{encoding:"utf8", flag:"w", spaces:2});
|
||||
}
|
||||
|
||||
module.exports.renameScreen = async (config, appname, oldName, newName) => {
|
||||
const appPath = appPackageFolder(config, appname);
|
||||
|
||||
const oldComponentPath = componentPath(
|
||||
appPath, oldName);
|
||||
|
||||
const newComponentPath = componentPath(
|
||||
appPath, newName);
|
||||
|
||||
await ensureDir(dirname(newComponentPath));
|
||||
await rename(
|
||||
oldComponentPath,
|
||||
newComponentPath);
|
||||
}
|
||||
|
||||
module.exports.deleteScreen = async (config, appname, name) => {
|
||||
const appPath = appPackageFolder(config, appname);
|
||||
const componentFile = componentPath(appPath, name);
|
||||
await unlink(componentFile);
|
||||
|
||||
const dir = dirname(componentFile);
|
||||
if((await readdir(dir)).length === 0) {
|
||||
await rmdir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.componentLibraryInfo = async (config, appname, lib) => {
|
||||
const appPath = appPackageFolder(config, appname);
|
||||
return await componentLibraryInfo(appPath, lib);
|
||||
};
|
||||
|
||||
|
||||
const getComponents = async (appPath, pages ,lib) => {
|
||||
|
||||
let libs;
|
||||
if(!lib) {
|
||||
pages = pages || await readJSON(
|
||||
`${appPath}/pages.json`);
|
||||
|
||||
if(!pages.componentLibraries) return [];
|
||||
|
||||
libs = pages.componentLibraries;
|
||||
} else {
|
||||
libs = [lib];
|
||||
}
|
||||
|
||||
const components = {};
|
||||
const generators = {};
|
||||
|
||||
for(let l of libs) {
|
||||
const info = await componentLibraryInfo(appPath, l);
|
||||
merge(components, info.components);
|
||||
merge(generators, info.generators);
|
||||
}
|
||||
|
||||
if(components._lib) delete components._lib;
|
||||
if(components._generators) delete components._generators;
|
||||
|
||||
return {components, generators};
|
||||
}
|
||||
|
||||
const fetchscreens = async (appPath, relativePath = "") => {
|
||||
|
||||
const currentDir = join(appPath, "components", relativePath);
|
||||
|
||||
const contents = await readdir(currentDir);
|
||||
|
||||
const components = [];
|
||||
|
||||
for(let item of contents) {
|
||||
const itemRelativePath = join(relativePath, item);
|
||||
const itemFullPath = join(currentDir, item);
|
||||
const stats = await stat(itemFullPath);
|
||||
|
||||
if(stats.isFile()) {
|
||||
|
||||
if(!item.endsWith(".json")) continue;
|
||||
|
||||
const component =
|
||||
await readJSON(itemFullPath);
|
||||
|
||||
component.name = itemRelativePath
|
||||
.substring(0, itemRelativePath.length - 5)
|
||||
.replace(/\\/g, "/");
|
||||
|
||||
component.props = component.props || {};
|
||||
|
||||
components.push(component);
|
||||
} else {
|
||||
const childComponents = await fetchscreens(
|
||||
appPath, join(relativePath, item)
|
||||
);
|
||||
|
||||
for(let c of childComponents) {
|
||||
components.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
module.exports.getComponents = getComponents;
|
|
@ -0,0 +1,32 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf8'>
|
||||
<meta name='viewport' content='width=device-width'>
|
||||
|
||||
<title>{{ title }}</title>
|
||||
<link rel='icon' type='image/png' href='{{ favicon }}'>
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{ each(options.stylesheets) }}
|
||||
<link rel='stylesheet' href='{{ @this }}'>
|
||||
{{ /each }}
|
||||
|
||||
<script src='{{ appRootPath }}/clientAppDefinition.js'></script>
|
||||
<script src='{{ appRootPath }}/budibase-client.js'></script>
|
||||
<script>
|
||||
loadBudibase();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body id="app">
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,25 @@
|
|||
const { appPackageFolder } = require("../createAppPackage");
|
||||
const { writeJSON } = require("fs-extra");
|
||||
const buildApp = require("./buildApp");
|
||||
|
||||
module.exports = async (config, appname, pkg) => {
|
||||
const appPath = appPackageFolder(config, appname);
|
||||
await writeJSON(
|
||||
`${appPath}/appDefinition.json`,
|
||||
pkg.appDefinition,
|
||||
{spaces:2});
|
||||
|
||||
await writeJSON(
|
||||
`${appPath}/access_levels.json`,
|
||||
pkg.accessLevels,
|
||||
{spaces:2});
|
||||
|
||||
await writeJSON(
|
||||
`${appPath}/pages.json`,
|
||||
pkg.pages,
|
||||
{spaces:2});
|
||||
|
||||
await buildApp(
|
||||
config, appname,
|
||||
pkg.pages, pkg.appDefinition);
|
||||
}
|
Loading…
Reference in New Issue