budibase/packages/server/utilities/builder.js

199 lines
5.0 KiB
JavaScript
Raw Normal View History

const {
appPackageFolder,
appsFolder
} = require("./createAppPackage");
const {
2019-07-26 18:08:59 +02:00
readJSON,
writeJSON,
readdir,
exists,
2019-07-26 18:08:59 +02:00
stat,
ensureDir,
rename,
2019-07-27 08:43:03 +02:00
unlink,
rmdir
2019-07-26 18:08:59 +02:00
} = require("fs-extra");
const {
resolve,
2019-07-26 18:08:59 +02:00
join,
dirname
} = require("path");
const { $ } = require("budibase-core").common;
const {
keys,
reduce,
some,
keyBy
} = require("lodash/fp");
const {merge} = require("lodash");
2019-07-13 11:35:57 +02:00
module.exports.getPackageForBuilder = async (config, appname) => {
const appPath = appPackageFolder(config, appname);
2019-07-26 18:08:59 +02:00
const pages = await readJSON(`${appPath}/pages.json`);
2019-07-13 11:35:57 +02:00
return ({
2019-07-26 18:08:59 +02:00
appDefinition: await readJSON(`${appPath}/appDefinition.json`),
2019-07-13 11:35:57 +02:00
2019-07-26 18:08:59 +02:00
accessLevels: await readJSON(`${appPath}/access_levels.json`),
pages,
rootComponents: await getRootComponents(appPath, pages),
derivedComponents: keyBy("_name")(
await fetchDerivedComponents(appPath))
2019-07-13 11:35:57 +02:00
})
}
module.exports.savePackage = async (config, appname, pkg) => {
const appPath = appPackageFolder(config, appname);
2019-07-26 18:08:59 +02:00
await writeJSON(
2019-07-13 11:35:57 +02:00
`${appPath}/appDefinition.json`,
2019-07-26 18:08:59 +02:00
pkg.appDefinition);
2019-07-13 11:35:57 +02:00
2019-07-26 18:08:59 +02:00
await writeJSON(
2019-07-13 11:35:57 +02:00
`${appPath}/access_levels.json`,
2019-07-26 18:08:59 +02:00
pkg.accessLevels);
2019-07-13 11:35:57 +02:00
2019-07-26 18:08:59 +02:00
await writeJSON(
`${appPath}/pages.json`,
2019-07-26 18:08:59 +02:00
pkg.pages);
}
module.exports.getApps = async (config) =>
await readdir(appsFolder(config));
2019-07-26 18:08:59 +02:00
const componentPath = (appPath, name) =>
join(appPath, "components", name + ".json");
module.exports.saveDerivedComponent = async (config, appname, component) => {
const appPath = appPackageFolder(config, appname);
await writeJSON(
componentPath(appPath, component._name),
component,
{encoding:"utf8", flag:"w"});
}
module.exports.renameDerivedComponent = async (config, appname, oldName, newName) => {
const appPath = appPackageFolder(config, appname);
const oldComponentPath = componentPath(
appPath, oldName);
2019-07-27 08:31:31 +02:00
const newComponentPath = componentPath(
2019-07-26 18:08:59 +02:00
appPath, newName);
await ensureDir(dirname(newComponentPath));
await rename(
oldComponentPath,
newComponentPath);
}
module.exports.deleteDerivedComponent = async (config, appname, name) => {
const appPath = appPackageFolder(config, appname);
2019-07-27 08:43:03 +02:00
const componentFile = componentPath(appPath, name);
await unlink(componentFile);
const dir = dirname(componentFile);
if((await readdir(dir)).length === 0) {
await rmdir(dir);
}
2019-07-26 18:08:59 +02:00
}
const getRootComponents = async (appPath, pages ,lib) => {
const componentsInLibrary = async (libname) => {
const isRelative = some(c => c === libname.substring(0,1))
("./~\\".split(""));
const componentsPath = isRelative
? resolve(appPath, libname, "components.json")
: resolve(libname, "components.json");
if(!await exists(componentsPath)) {
const e = new Error(`could not find components definition file at ${componentsPath}`);
e.statusCode = 404;
throw e;
}
let components;
try {
2019-07-26 18:08:59 +02:00
components = await readJSON(componentsPath);
} catch(e) {
const err = `could not parse JSON - ${componentsPath} : ${e.message}`;
throw new Error(err);
}
return $(components, [
keys,
reduce((obj, k) => {
obj[`${libname}/${k}`] = components[k]
return obj;
}, {})
])
}
let libs;
if(!lib) {
2019-07-26 18:08:59 +02:00
pages = pages || await readJSON(
`${appPath}/pages.json`);
if(!pages.componentLibraries) return [];
libs = pages.componentLibraries;
} else {
libs = [lib];
}
const components = {};
for(let l of libs) {
merge(components, await componentsInLibrary(l))
}
return components;
}
const fetchDerivedComponents = 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;
2019-07-26 18:08:59 +02:00
const component =
await readJSON(itemFullPath);
component._name = itemRelativePath
.substring(0, itemRelativePath.length - 5)
.replace(/\\/g, "/");
components.push(component);
} else {
const childComponents = await fetchDerivedComponents(
appPath, join(relativePath, item)
);
for(let c of childComponents) {
components.push(c);
}
}
}
return components;
}
module.exports.getRootComponents = getRootComponents;