2019-07-25 08:31:54 +02:00
|
|
|
const {
|
|
|
|
appPackageFolder,
|
|
|
|
appsFolder
|
|
|
|
} = require("./createAppPackage");
|
|
|
|
const {
|
2019-07-26 18:08:59 +02:00
|
|
|
readJSON,
|
|
|
|
writeJSON,
|
2019-07-25 08:31:54 +02:00
|
|
|
readdir,
|
2019-07-26 16:13:15 +02:00
|
|
|
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");
|
2019-07-26 16:13:15 +02:00
|
|
|
const {
|
|
|
|
resolve,
|
2019-07-26 18:08:59 +02:00
|
|
|
join,
|
|
|
|
dirname
|
2019-07-26 16:13:15 +02:00
|
|
|
} = require("path");
|
2019-07-25 08:31:54 +02:00
|
|
|
const { $ } = require("budibase-core").common;
|
|
|
|
const {
|
|
|
|
keys,
|
|
|
|
reduce,
|
2019-07-26 16:13:15 +02:00
|
|
|
some,
|
|
|
|
keyBy
|
2019-07-25 08:31:54 +02:00
|
|
|
} = require("lodash/fp");
|
2019-07-26 16:13:15 +02:00
|
|
|
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 16:13:15 +02:00
|
|
|
|
2019-07-26 18:08:59 +02:00
|
|
|
const pages = await readJSON(`${appPath}/pages.json`);
|
2019-07-26 16:13:15 +02:00
|
|
|
|
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`),
|
2019-07-25 08:31:54 +02:00
|
|
|
|
2019-07-26 16:13:15 +02:00
|
|
|
pages,
|
|
|
|
|
|
|
|
rootComponents: await getRootComponents(appPath, pages),
|
|
|
|
|
2019-07-28 09:03:11 +02:00
|
|
|
derivedComponents: keyBy("name")(
|
2019-07-26 16:13:15 +02:00
|
|
|
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(
|
2019-07-25 08:31:54 +02:00
|
|
|
`${appPath}/pages.json`,
|
2019-07-26 18:08:59 +02:00
|
|
|
pkg.pages);
|
2019-07-14 08:46:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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(
|
2019-07-28 09:03:11 +02:00
|
|
|
componentPath(appPath, component.name),
|
2019-07-26 18:08:59 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2019-07-26 16:13:15 +02:00
|
|
|
const getRootComponents = async (appPath, pages ,lib) => {
|
2019-07-25 08:31:54 +02:00
|
|
|
|
2019-07-26 16:13:15 +02:00
|
|
|
const componentsInLibrary = async (libname) => {
|
2019-07-25 08:31:54 +02:00
|
|
|
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);
|
2019-07-25 08:31:54 +02:00
|
|
|
} catch(e) {
|
2019-07-26 16:13:15 +02:00
|
|
|
const err = `could not parse JSON - ${componentsPath} : ${e.message}`;
|
|
|
|
throw new Error(err);
|
2019-07-25 08:31:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return $(components, [
|
|
|
|
keys,
|
|
|
|
reduce((obj, k) => {
|
2019-08-02 15:54:10 +02:00
|
|
|
const component = components[k];
|
|
|
|
component.name = `${libname}/${k}`;
|
|
|
|
obj[component.name] = component;
|
2019-07-25 08:31:54 +02:00
|
|
|
return obj;
|
|
|
|
}, {})
|
|
|
|
])
|
|
|
|
}
|
|
|
|
|
|
|
|
let libs;
|
|
|
|
if(!lib) {
|
2019-07-26 18:08:59 +02:00
|
|
|
pages = pages || await readJSON(
|
|
|
|
`${appPath}/pages.json`);
|
2019-07-25 08:31:54 +02:00
|
|
|
|
|
|
|
if(!pages.componentLibraries) return [];
|
|
|
|
|
|
|
|
libs = pages.componentLibraries;
|
|
|
|
} else {
|
|
|
|
libs = [lib];
|
|
|
|
}
|
|
|
|
|
2019-07-26 16:13:15 +02:00
|
|
|
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);
|
2019-07-26 16:13:15 +02:00
|
|
|
|
2019-07-28 09:03:11 +02:00
|
|
|
component.name = itemRelativePath
|
2019-07-26 16:13:15 +02:00
|
|
|
.substring(0, itemRelativePath.length - 5)
|
|
|
|
.replace(/\\/g, "/");
|
|
|
|
|
2019-08-07 10:03:49 +02:00
|
|
|
component.props = component.props || {};
|
|
|
|
component.props._component = component.name;
|
|
|
|
|
2019-07-26 16:13:15 +02:00
|
|
|
components.push(component);
|
|
|
|
} else {
|
|
|
|
const childComponents = await fetchDerivedComponents(
|
|
|
|
appPath, join(relativePath, item)
|
|
|
|
);
|
|
|
|
|
|
|
|
for(let c of childComponents) {
|
|
|
|
components.push(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return components;
|
2019-07-25 08:31:54 +02:00
|
|
|
}
|
2019-07-14 08:46:36 +02:00
|
|
|
|
2019-07-26 16:13:15 +02:00
|
|
|
module.exports.getRootComponents = getRootComponents;
|