get components server endpoint ... tested
This commit is contained in:
parent
4891c6de80
commit
ebf5dfeeea
|
@ -13,9 +13,22 @@
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Jest All",
|
"name": "Jest App Server",
|
||||||
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
||||||
"args": ["--runInBand"],
|
"args": ["apps", "--runInBand"],
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"internalConsoleOptions": "neverOpen",
|
||||||
|
"disableOptimisticBPs": true,
|
||||||
|
"windows": {
|
||||||
|
"program": "${workspaceFolder}/node_modules/jest-cli/bin/jest",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Jest Builder",
|
||||||
|
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
||||||
|
"args": ["builder", "--runInBand"],
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"internalConsoleOptions": "neverOpen",
|
"internalConsoleOptions": "neverOpen",
|
||||||
"disableOptimisticBPs": true,
|
"disableOptimisticBPs": true,
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"_component": "./customComponents/textbox",
|
||||||
|
"label": "hello"
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"_component": "./moreCustomComponents/textbox",
|
||||||
|
"label": "hello"
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"textbox" : {
|
||||||
|
"path": "./textbox",
|
||||||
|
"name": "Textbox",
|
||||||
|
"description": "A text input, with a label",
|
||||||
|
"props": {
|
||||||
|
"label": "string"
|
||||||
|
},
|
||||||
|
"tags": ["textboxt", "input", "text"]
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,5 +15,5 @@
|
||||||
},
|
},
|
||||||
"appBody" : "./unauthenticated.app.json"
|
"appBody" : "./unauthenticated.app.json"
|
||||||
},
|
},
|
||||||
"componentLibraries": ["./myComponents"]
|
"componentLibraries": ["./customComponents", "./moreCustomComponents"]
|
||||||
}
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
const Sequencer = require('@jest/test-sequencer').default;
|
|
||||||
|
|
||||||
const testOrder = [""]
|
|
||||||
|
|
||||||
class CustomSequencer extends Sequencer {
|
|
||||||
sort(tests) {
|
|
||||||
// Test structure information
|
|
||||||
// https://github.com/facebook/jest/blob/6b8b1404a1d9254e7d5d90a8934087a9c9899dab/packages/jest-runner/src/types.ts#L17-L21
|
|
||||||
const copyTests = Array.from(tests);
|
|
||||||
return copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,13 +4,10 @@ const StatusCodes = require("../utilities/statusCodes");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const { resolve } = require("path");
|
const { resolve } = require("path");
|
||||||
const send = require('koa-send');
|
const send = require('koa-send');
|
||||||
const { getPackageForBuilder, getComponents,
|
const { getPackageForBuilder, getRootComponents: getComponents,
|
||||||
savePackage, getApps } = require("../utilities/builder");
|
savePackage, getApps } = require("../utilities/builder");
|
||||||
|
|
||||||
const builderPath = resolve(__dirname, "../builder");
|
const builderPath = resolve(__dirname, "../builder");
|
||||||
const appUiPath = appname => {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = (config, app) => {
|
module.exports = (config, app) => {
|
||||||
|
|
||||||
|
@ -33,8 +30,13 @@ module.exports = (config, app) => {
|
||||||
ctx.throw(StatusCodes.NOT_FOUND, "App Name not declared");
|
ctx.throw(StatusCodes.NOT_FOUND, "App Name not declared");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const appname = pathParts[1];
|
||||||
|
|
||||||
|
if(appname === "_builder") {
|
||||||
|
await next();
|
||||||
|
} else {
|
||||||
const instance = await ctx.master.getInstanceApiForSession(
|
const instance = await ctx.master.getInstanceApiForSession(
|
||||||
pathParts[1],
|
appname,
|
||||||
ctx.sessionId);
|
ctx.sessionId);
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,11 +45,12 @@ module.exports = (config, app) => {
|
||||||
ctx.isAuthenticated = !!instance.instance;
|
ctx.isAuthenticated = !!instance.instance;
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.get("/_builder", async (ctx) => {
|
.get("/_builder", async (ctx) => {
|
||||||
if(!config.dev) {
|
if(!config.dev) {
|
||||||
ctx.request.status = StatusCodes.FORBIDDEN;
|
ctx.response.status = StatusCodes.FORBIDDEN;
|
||||||
ctx.request.body = "run in dev mode to access builder";
|
ctx.body = "run in dev mode to access builder";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,8 +59,8 @@ module.exports = (config, app) => {
|
||||||
})
|
})
|
||||||
.get("/_builder/*", async (ctx, next) => {
|
.get("/_builder/*", async (ctx, next) => {
|
||||||
if(!config.dev) {
|
if(!config.dev) {
|
||||||
ctx.request.status = StatusCodes.FORBIDDEN;
|
ctx.response.status = StatusCodes.FORBIDDEN;
|
||||||
ctx.request.body = "run in dev mode to access builder";
|
ctx.body = "run in dev mode to access builder";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,8 +120,8 @@ module.exports = (config, app) => {
|
||||||
})
|
})
|
||||||
.get("/_builder/api/apps", async (ctx) => {
|
.get("/_builder/api/apps", async (ctx) => {
|
||||||
if(!config.dev) {
|
if(!config.dev) {
|
||||||
ctx.request.status = StatusCodes.FORBIDDEN;
|
ctx.response.status = StatusCodes.FORBIDDEN;
|
||||||
ctx.request.body = "run in dev mode to access builder";
|
ctx.response.body = "run in dev mode to access builder";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,8 +131,8 @@ module.exports = (config, app) => {
|
||||||
})
|
})
|
||||||
.get("/_builder/api/:appname/appPackage", async (ctx) => {
|
.get("/_builder/api/:appname/appPackage", async (ctx) => {
|
||||||
if(!config.dev) {
|
if(!config.dev) {
|
||||||
ctx.request.status = StatusCodes.FORBIDDEN;
|
ctx.response.status = StatusCodes.FORBIDDEN;
|
||||||
ctx.request.body = "run in dev mode to access builder";
|
ctx.body = "run in dev mode to access builder";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +144,7 @@ module.exports = (config, app) => {
|
||||||
})
|
})
|
||||||
.post("/_builder/api/:appname/appPackage", async (ctx) => {
|
.post("/_builder/api/:appname/appPackage", async (ctx) => {
|
||||||
if(!config.dev) {
|
if(!config.dev) {
|
||||||
ctx.request.status = StatusCodes.FORBIDDEN;
|
ctx.response.status = StatusCodes.FORBIDDEN;
|
||||||
ctx.body = "run in dev mode to access builder";
|
ctx.body = "run in dev mode to access builder";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +157,7 @@ module.exports = (config, app) => {
|
||||||
})
|
})
|
||||||
.get("/_builder/api/:appname/components", async (ctx) => {
|
.get("/_builder/api/:appname/components", async (ctx) => {
|
||||||
if(!config.dev) {
|
if(!config.dev) {
|
||||||
ctx.request.status = StatusCodes.FORBIDDEN;
|
ctx.response.status = StatusCodes.FORBIDDEN;
|
||||||
ctx.body = "run in dev mode to access builder";
|
ctx.body = "run in dev mode to access builder";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
const testAppDef = require("../appPackages/testApp/appDefinition.json");
|
||||||
|
const testAccessLevels = require("../appPackages/testApp/access_levels.json");
|
||||||
|
const testPages = require("../appPackages/testApp/pages.json");
|
||||||
|
const testComponents = require("../appPackages/testApp/customComponents/components.json");
|
||||||
|
const testMoreComponents = require("../appPackages/testApp/moreCustomComponents/components.json");
|
||||||
|
const statusCodes = require("../utilities/statusCodes");
|
||||||
|
const derivedComponent1 = require("../appPackages/testApp/components/myTextBox.json");
|
||||||
|
const derivedComponent2 = require("../appPackages/testApp/components/subfolder/otherTextBox.json");
|
||||||
|
|
||||||
|
const app = require("./testApp")();
|
||||||
|
|
||||||
|
beforeAll(async () => await app.start());
|
||||||
|
afterAll(async () => await app.destroy());
|
||||||
|
|
||||||
|
|
||||||
|
it("/apppackage should get appDefinition", async () => {
|
||||||
|
|
||||||
|
const {body} = await app.get("/_builder/api/testApp/appPackage")
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
|
||||||
|
expect(body.appDefinition).toEqual(testAppDef);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("/apppackage should get access levels", async () => {
|
||||||
|
|
||||||
|
const {body} = await app.get("/_builder/api/testApp/appPackage")
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
|
||||||
|
expect(body.accessLevels).toEqual(testAccessLevels);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("/apppackage should get pages", async () => {
|
||||||
|
|
||||||
|
const {body} = await app.get("/_builder/api/testApp/appPackage")
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
expect(body.pages).toEqual(testPages);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("/apppackage should get rootComponents", async () => {
|
||||||
|
|
||||||
|
const {body} = await app.get("/_builder/api/testApp/appPackage")
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
|
||||||
|
expect(body.rootComponents["./customComponents/textbox"]).toBeDefined();
|
||||||
|
expect(body.rootComponents["./moreCustomComponents/textbox"]).toBeDefined();
|
||||||
|
|
||||||
|
expect(body.rootComponents["./customComponents/textbox"])
|
||||||
|
.toEqual(testComponents.textbox);
|
||||||
|
|
||||||
|
expect(body.rootComponents["./moreCustomComponents/textbox"])
|
||||||
|
.toEqual(testMoreComponents.textbox);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("/apppackage should get derivedComponents", async () => {
|
||||||
|
|
||||||
|
const {body} = await app.get("/_builder/api/testApp/appPackage")
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
|
||||||
|
const expectedComponents = {
|
||||||
|
"myTextBox" : {...derivedComponent1, _name:"myTextBox"},
|
||||||
|
"subfolder/otherTextBox": {...derivedComponent2, _name:"subfolder/otherTextBox"}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(body.derivedComponents).toEqual(expectedComponents);
|
||||||
|
});
|
|
@ -46,7 +46,8 @@ const config = {
|
||||||
port: 4002,
|
port: 4002,
|
||||||
latestPackagesFolder: "./appPackages",
|
latestPackagesFolder: "./appPackages",
|
||||||
extraMasterPlugins,
|
extraMasterPlugins,
|
||||||
customizeMaster
|
customizeMaster,
|
||||||
|
dev:true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,20 +6,29 @@ const {
|
||||||
writeFile,
|
writeFile,
|
||||||
readFile,
|
readFile,
|
||||||
readdir,
|
readdir,
|
||||||
exists
|
exists,
|
||||||
|
stat
|
||||||
} = require("./fsawait");
|
} = require("./fsawait");
|
||||||
const { resolve } = require("path");
|
const {
|
||||||
|
resolve,
|
||||||
|
join
|
||||||
|
} = require("path");
|
||||||
const { $ } = require("budibase-core").common;
|
const { $ } = require("budibase-core").common;
|
||||||
const {
|
const {
|
||||||
keys,
|
keys,
|
||||||
reduce,
|
reduce,
|
||||||
map,
|
some,
|
||||||
flatten,
|
keyBy
|
||||||
some
|
|
||||||
} = require("lodash/fp");
|
} = require("lodash/fp");
|
||||||
|
const {merge} = require("lodash");
|
||||||
|
|
||||||
module.exports.getPackageForBuilder = async (config, appname) => {
|
module.exports.getPackageForBuilder = async (config, appname) => {
|
||||||
const appPath = appPackageFolder(config, appname);
|
const appPath = appPackageFolder(config, appname);
|
||||||
|
|
||||||
|
const pages = JSON.parse(await readFile(
|
||||||
|
`${appPath}/pages.json`,
|
||||||
|
"utf8"));
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
appDefinition: JSON.parse(await readFile(
|
appDefinition: JSON.parse(await readFile(
|
||||||
`${appPath}/appDefinition.json`,
|
`${appPath}/appDefinition.json`,
|
||||||
|
@ -29,9 +38,12 @@ module.exports.getPackageForBuilder = async (config, appname) => {
|
||||||
`${appPath}/access_levels.json`,
|
`${appPath}/access_levels.json`,
|
||||||
"utf8")),
|
"utf8")),
|
||||||
|
|
||||||
pages: JSON.parse(await readFile(
|
pages,
|
||||||
`${appPath}/pages.json`,
|
|
||||||
"utf8"))
|
rootComponents: await getRootComponents(appPath, pages),
|
||||||
|
|
||||||
|
derivedComponents: keyBy("_name")(
|
||||||
|
await fetchDerivedComponents(appPath))
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,7 +62,7 @@ module.exports.savePackage = async (config, appname, pkg) => {
|
||||||
|
|
||||||
await writeFile(
|
await writeFile(
|
||||||
`${appPath}/pages.json`,
|
`${appPath}/pages.json`,
|
||||||
JSON.stringify(pkg.accessLevels),
|
JSON.stringify(pkg.pages),
|
||||||
"utf8");
|
"utf8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +70,9 @@ module.exports.getApps = async (config) =>
|
||||||
await readdir(appsFolder(config));
|
await readdir(appsFolder(config));
|
||||||
|
|
||||||
|
|
||||||
module.exports.getComponents = async (config, appname, lib) => {
|
const getRootComponents = async (appPath, pages ,lib) => {
|
||||||
|
|
||||||
const componentsInLibrary = (libname) => {
|
const componentsInLibrary = async (libname) => {
|
||||||
const isRelative = some(c => c === libname.substring(0,1))
|
const isRelative = some(c => c === libname.substring(0,1))
|
||||||
("./~\\".split(""));
|
("./~\\".split(""));
|
||||||
|
|
||||||
|
@ -77,10 +89,10 @@ module.exports.getComponents = async (config, appname, lib) => {
|
||||||
let components;
|
let components;
|
||||||
try {
|
try {
|
||||||
components = JSON.parse(
|
components = JSON.parse(
|
||||||
readFile(componentsPath, "utf8"));
|
await readFile(componentsPath, "utf8"));
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
const e = new Error(`could not parse JSON - ${componentsPath} `);
|
const err = `could not parse JSON - ${componentsPath} : ${e.message}`;
|
||||||
throw e;
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $(components, [
|
return $(components, [
|
||||||
|
@ -94,9 +106,7 @@ module.exports.getComponents = async (config, appname, lib) => {
|
||||||
|
|
||||||
let libs;
|
let libs;
|
||||||
if(!lib) {
|
if(!lib) {
|
||||||
const appPath = appPackageFolder(config, appname);
|
pages = pages || JSON.parse(await readFile(
|
||||||
|
|
||||||
const pages = JSON.parse(await readFile(
|
|
||||||
`${appPath}/pages.json`,
|
`${appPath}/pages.json`,
|
||||||
"utf8"));
|
"utf8"));
|
||||||
|
|
||||||
|
@ -107,9 +117,51 @@ module.exports.getComponents = async (config, appname, lib) => {
|
||||||
libs = [lib];
|
libs = [lib];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $(libs, [
|
const components = {};
|
||||||
map(componentsInLibrary),
|
for(let l of libs) {
|
||||||
flatten
|
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;
|
||||||
|
|
||||||
|
const component = JSON.parse(
|
||||||
|
await readFile(itemFullPath, "utf8"));
|
||||||
|
|
||||||
|
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;
|
Loading…
Reference in New Issue