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