builder now web based and talking to api
This commit is contained in:
parent
13dd99be02
commit
363cbdd6c3
|
@ -10,8 +10,9 @@ import copy from 'rollup-plugin-copy';
|
|||
import browsersync from "rollup-plugin-browsersync";
|
||||
import proxy from "http-proxy-middleware";
|
||||
|
||||
const target = 'http://localhost:4001/_builder';
|
||||
const apiProxy = proxy('/api', {
|
||||
target: 'http://localhost:4001/_builder',
|
||||
target,
|
||||
logLevel: "debug",
|
||||
changeOrigin: true,
|
||||
cookieDomainRewrite: true,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
|
||||
import Button from "./common/Button.svelte"
|
||||
import { database } from "./builderStore";
|
||||
|
||||
let errors = [];
|
||||
|
||||
|
@ -12,15 +13,10 @@ let errors = [];
|
|||
<div>
|
||||
|
||||
<div>
|
||||
<h4 style="margin-bottom: 20px">What would you like not to do?</h4>
|
||||
<Button color="primary"
|
||||
class="option">
|
||||
Create a New Package
|
||||
</Button>
|
||||
<Button color="primary-outline"
|
||||
class="option">
|
||||
Import a Package
|
||||
</Button>
|
||||
<h4 style="margin-bottom: 20px">Choose an Application</h4>
|
||||
{#each $database.apps as app}
|
||||
<a href={`#/${app}`} class="app-link">{app}</a>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,4 +48,9 @@ let errors = [];
|
|||
width:250px;
|
||||
}
|
||||
|
||||
.app-link {
|
||||
margin-top: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -1,8 +1,8 @@
|
|||
import {createNewHeirarchy} from "../common/core";
|
||||
import {createNewHierarchy} from "../common/core";
|
||||
|
||||
export const createPackage = (packageInfo, database) => {
|
||||
packageInfo.createNewPackage("");
|
||||
const root = createNewHeirarchy();
|
||||
const root = createNewHierarchy();
|
||||
database.importAppDefinition({
|
||||
hierarchy:root,
|
||||
actions:[],
|
||||
|
|
|
@ -2,18 +2,29 @@ import {createPackage} from "./createPackage";
|
|||
import getStore from "./store";
|
||||
import { last } from "lodash/fp";
|
||||
|
||||
const appName = last(window.location.hash.substr(1).split("/"));
|
||||
|
||||
export const database = getStore(appName);
|
||||
export const database = getStore();
|
||||
|
||||
export const createNewPackage = () =>
|
||||
createPackage(packageInfo, database);
|
||||
|
||||
export const initialise = async () => {
|
||||
try {
|
||||
setupRouter(database);
|
||||
await database.initialise();
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const setupRouter = (writable) => {
|
||||
const pushState = history.pushState;
|
||||
history.pushState = () => {
|
||||
pushState.apply(history, arguments);
|
||||
//fireEvents('pushState', arguments);
|
||||
writable.initialise();
|
||||
}
|
||||
window.addEventListener('hashchange',()=>{
|
||||
writable.initialise();
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,28 +1,29 @@
|
|||
import {hierarchy as hierarchyFunctions,
|
||||
common, getTemplateApi } from "budibase-core";
|
||||
import {filter, cloneDeep, sortBy, map,
|
||||
import {filter, cloneDeep, sortBy, map, last,
|
||||
find, isEmpty, groupBy, reduce} from "lodash/fp";
|
||||
import {chain, getNode, validate,
|
||||
constructHierarchy, templateApi} from "../common/core";
|
||||
import {writable} from "svelte/store";
|
||||
|
||||
export const getStore = (appname) => {
|
||||
export const getStore = () => {
|
||||
|
||||
const initial = {
|
||||
apps:[],
|
||||
appname:"",
|
||||
hierarchy: {},
|
||||
actions: [],
|
||||
triggers: [],
|
||||
currentNodeIsNew: false,
|
||||
errors: [],
|
||||
activeNav: "database",
|
||||
hasAppPackage: (!!appname && appname.length > 0),
|
||||
hasAppPackage: false,
|
||||
accessLevels: [],
|
||||
currentNode: null};
|
||||
|
||||
const store = writable(initial);
|
||||
|
||||
store.appname = appname;
|
||||
store.initialise = initialise(store, initial, appname);
|
||||
store.initialise = initialise(store, initial);
|
||||
store.newChildRecord = newRecord(store, false);
|
||||
store.newRootRecord = newRecord(store, true);
|
||||
store.selectExistingNode = selectExistingNode(store);
|
||||
|
@ -47,9 +48,23 @@ export default getStore;
|
|||
|
||||
const initialise = (store, initial) => async () => {
|
||||
|
||||
const pkg = await fetch(`/api/${store.appname}/appPackage`)
|
||||
const appname = window.location.hash
|
||||
? last(window.location.hash.substr(1).split("/"))
|
||||
: "";
|
||||
|
||||
if(!appname) {
|
||||
initial.apps = await fetch(`/api/apps`)
|
||||
.then(r => r.json());
|
||||
initial.hasAppPackage = false;
|
||||
store.set(initial);
|
||||
return initial;
|
||||
}
|
||||
|
||||
const pkg = await fetch(`/api/${appname}/appPackage`)
|
||||
.then(r => r.json());
|
||||
|
||||
initial.appname = appname;
|
||||
initial.hasAppPackage = true;
|
||||
initial.hierarchy = pkg.appDefinition.hierarchy;
|
||||
initial.accessLevels = pkg.accessLevels;
|
||||
initial.actions = reduce((arr, action) => {
|
||||
|
@ -320,11 +335,11 @@ const savePackage = (store, db) => {
|
|||
accessLevels:db.accessLevels
|
||||
}
|
||||
|
||||
fetch(`/api/${store.appname}/appPackage`, {
|
||||
fetch(`/api/${db.appname}/appPackage`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data), // body data type must match "Content-Type" header
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,16 +15,16 @@ export const getNode = (hierarchy, nodeId) =>
|
|||
|
||||
export const constructHierarchy = node => {
|
||||
if(!node) return node;
|
||||
return templateApi(node).constructHeirarchy(node);
|
||||
return templateApi(node).constructHierarchy(node);
|
||||
}
|
||||
|
||||
export const createNewHeirarchy = () => {
|
||||
export const createNewHierarchy = () => {
|
||||
return templateApi().getNewRootLevel();
|
||||
}
|
||||
|
||||
export const templateApi = hierarchy => getTemplateApi({heirarchy:hierarchy})
|
||||
export const templateApi = hierarchy => getTemplateApi({hierarchy})
|
||||
export const authApi = (hierarchy, actions) => getAuthApi({
|
||||
heirarchy:hierarchy, actions: keyBy("name")(actions), publish:()=>{}})
|
||||
hierarchy, actions: keyBy("name")(actions), publish:()=>{}})
|
||||
|
||||
export const allTypes = templateApi({}).allTypes;
|
||||
|
||||
|
|
|
@ -1,75 +1 @@
|
|||
{
|
||||
"levels": [
|
||||
{
|
||||
"name": "owner",
|
||||
"permissions": [
|
||||
{
|
||||
"type": "create record",
|
||||
"nodeKey": "/customers/1-{id}"
|
||||
},
|
||||
{
|
||||
"type": "delete record",
|
||||
"nodeKey": "/customers/1-{id}"
|
||||
},
|
||||
{
|
||||
"type": "update record",
|
||||
"nodeKey": "/customers/1-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read record",
|
||||
"nodeKey": "/customers/1-{id}"
|
||||
},
|
||||
{
|
||||
"type": "create record",
|
||||
"nodeKey": "/customers/1-{id}/invoices/2-{id}"
|
||||
},
|
||||
{
|
||||
"type": "update record",
|
||||
"nodeKey": "/customers/1-{id}/invoices/2-{id}"
|
||||
},
|
||||
{
|
||||
"type": "delete record",
|
||||
"nodeKey": "/customers/1-{id}/invoices/2-{id}"
|
||||
},
|
||||
{
|
||||
"type": "read record",
|
||||
"nodeKey": "/customers/1-{id}/invoices/2-{id}"
|
||||
},
|
||||
{
|
||||
"type": "write templates"
|
||||
},
|
||||
{
|
||||
"type": "create user"
|
||||
},
|
||||
{
|
||||
"type": "set password"
|
||||
},
|
||||
{
|
||||
"type": "create temporary access"
|
||||
},
|
||||
{
|
||||
"type": "enable or disable user"
|
||||
},
|
||||
{
|
||||
"type": "write access levels"
|
||||
},
|
||||
{
|
||||
"type": "list users"
|
||||
},
|
||||
{
|
||||
"type": "list access levels"
|
||||
},
|
||||
{
|
||||
"type": "manage index"
|
||||
},
|
||||
{
|
||||
"type": "set user access levels"
|
||||
},
|
||||
{
|
||||
"type": "manage collection"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 0
|
||||
}
|
||||
{"levels":[{"name":"owner","permissions":[{"type":"create record","nodeKey":"/customers/1-{id}"},{"type":"delete record","nodeKey":"/customers/1-{id}"},{"type":"update record","nodeKey":"/customers/1-{id}"},{"type":"read record","nodeKey":"/customers/1-{id}"},{"type":"create record","nodeKey":"/customers/1-{id}/invoices/2-{id}"},{"type":"update record","nodeKey":"/customers/1-{id}/invoices/2-{id}"},{"type":"delete record","nodeKey":"/customers/1-{id}/invoices/2-{id}"},{"type":"read record","nodeKey":"/customers/1-{id}/invoices/2-{id}"},{"type":"write templates"},{"type":"create user"},{"type":"set password"},{"type":"create temporary access"},{"type":"enable or disable user"},{"type":"write access levels"},{"type":"list users"},{"type":"list access levels"},{"type":"manage index"},{"type":"set user access levels"},{"type":"manage collection"}]}],"version":0}
|
|
@ -1,84 +1 @@
|
|||
{
|
||||
"hierarchy": {
|
||||
"name": "root",
|
||||
"type": "root",
|
||||
"children": [
|
||||
{
|
||||
"name": "customer",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"typeOptions": {
|
||||
"maxLength": 1000,
|
||||
"values": null,
|
||||
"allowDeclaredValuesOnly": false
|
||||
},
|
||||
"label": "name",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
}
|
||||
],
|
||||
"children": [
|
||||
{
|
||||
"name": "invoice",
|
||||
"type": "record",
|
||||
"fields": [
|
||||
{
|
||||
"name": "amount",
|
||||
"type": "number",
|
||||
"typeOptions": {
|
||||
"minValue": 99999999999,
|
||||
"maxValue": 99999999999,
|
||||
"decimalPlaces": 2
|
||||
},
|
||||
"label": "amount",
|
||||
"getInitialValue": "default",
|
||||
"getUndefinedValue": "default"
|
||||
}
|
||||
],
|
||||
"children": [],
|
||||
"validationRules": [],
|
||||
"nodeId": 2,
|
||||
"indexes": [],
|
||||
"allidsShardFactor": 1,
|
||||
"collectionName": "invoices",
|
||||
"isSingle": false
|
||||
}
|
||||
],
|
||||
"validationRules": [],
|
||||
"nodeId": 1,
|
||||
"indexes": [],
|
||||
"allidsShardFactor": 64,
|
||||
"collectionName": "customers",
|
||||
"isSingle": false
|
||||
}
|
||||
],
|
||||
"pathMaps": [],
|
||||
"indexes": [],
|
||||
"nodeId": 0
|
||||
},
|
||||
"actions": {
|
||||
"output_to_file": {
|
||||
"name": "output_to_file",
|
||||
"behaviourSource": "main",
|
||||
"behaviourName": "outputToFile",
|
||||
"initialOptions": {}
|
||||
}
|
||||
},
|
||||
"triggers": [
|
||||
{
|
||||
"actionName": "output_to_file",
|
||||
"eventName": "authApi:createUser:onComplete",
|
||||
"optionsCreator": "return { filename:'tempaccess' + context.user.name, content:context.result.tempCode };",
|
||||
"condition": "!context.password"
|
||||
},
|
||||
{
|
||||
"actionName": "output_to_file",
|
||||
"eventName": "authApi:createTemporaryAccess:onComplete",
|
||||
"optionsCreator": "return { filename:'tempaccess' + context.userName, content:context.result };",
|
||||
"condition": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
{"hierarchy":{"name":"root","type":"root","children":[{"name":"customer","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"invoiceyooo","type":"record","fields":[{"name":"amount","type":"number","typeOptions":{"minValue":99999999999,"maxValue":99999999999,"decimalPlaces":2},"label":"amount","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[],"allidsShardFactor":1,"collectionName":"invoices","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[],"allidsShardFactor":64,"collectionName":"customers","isSingle":false}],"pathMaps":[],"indexes":[],"nodeId":0},"triggers":[{"actionName":"output_to_file","eventName":"authApi:createUser:onComplete","optionsCreator":"return { filename:'tempaccess' + context.user.name, content:context.result.tempCode };","condition":"!context.password"},{"actionName":"output_to_file","eventName":"authApi:createTemporaryAccess:onComplete","optionsCreator":"return { filename:'tempaccess' + context.userName, content:context.result };","condition":""}],"actions":{"output_to_file":[{"name":"output_to_file","behaviourSource":"main","behaviourName":"outputToFile","initialOptions":{}}]}}
|
|
@ -0,0 +1 @@
|
|||
{"levels":[{"name":"owner","permissions":[{"type":"create record","nodeKey":"/customers/1-{id}"},{"type":"delete record","nodeKey":"/customers/1-{id}"},{"type":"update record","nodeKey":"/customers/1-{id}"},{"type":"read record","nodeKey":"/customers/1-{id}"},{"type":"create record","nodeKey":"/customers/1-{id}/invoices/2-{id}"},{"type":"update record","nodeKey":"/customers/1-{id}/invoices/2-{id}"},{"type":"delete record","nodeKey":"/customers/1-{id}/invoices/2-{id}"},{"type":"read record","nodeKey":"/customers/1-{id}/invoices/2-{id}"},{"type":"write templates"},{"type":"create user"},{"type":"set password"},{"type":"create temporary access"},{"type":"enable or disable user"},{"type":"write access levels"},{"type":"list users"},{"type":"list access levels"},{"type":"manage index"},{"type":"set user access levels"},{"type":"manage collection"}]}],"version":0}
|
|
@ -0,0 +1 @@
|
|||
{"hierarchy":{"name":"root","type":"root","children":[{"name":"customer","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"invoiceyooo","type":"record","fields":[{"name":"amount","type":"number","typeOptions":{"minValue":99999999999,"maxValue":99999999999,"decimalPlaces":2},"label":"amount","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[],"allidsShardFactor":1,"collectionName":"invoices","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[],"allidsShardFactor":64,"collectionName":"customers","isSingle":false}],"pathMaps":[],"indexes":[],"nodeId":0},"triggers":[{"actionName":"output_to_file","eventName":"authApi:createUser:onComplete","optionsCreator":"return { filename:'tempaccess' + context.user.name, content:context.result.tempCode };","condition":"!context.password"},{"actionName":"output_to_file","eventName":"authApi:createTemporaryAccess:onComplete","optionsCreator":"return { filename:'tempaccess' + context.userName, content:context.result };","condition":""}],"actions":{"undefined":[[[{"name":"output_to_file","behaviourSource":"main","behaviourName":"outputToFile","initialOptions":{}}]]]}}
|
|
@ -0,0 +1,9 @@
|
|||
const fs = require("fs");
|
||||
|
||||
module.exports = (config) => ({
|
||||
main: {
|
||||
outputToFile : ({filename, content}) => {
|
||||
fs.writeFile(`./tests/.data/${filename}`, content, {encoding:"utf8"});
|
||||
}
|
||||
}
|
||||
})
|
|
@ -2,7 +2,8 @@ const Router = require("@koa/router");
|
|||
const session = require("./session");
|
||||
const StatusCodes = require("../utilities/statusCodes");
|
||||
const fs = require("fs");
|
||||
const { getPackageForBuilder, savePackage } = require("../utilities/builder");
|
||||
const { getPackageForBuilder,
|
||||
savePackage, getApps } = require("../utilities/builder");
|
||||
|
||||
module.exports = (config, app) => {
|
||||
|
||||
|
@ -74,6 +75,17 @@ module.exports = (config, app) => {
|
|||
|
||||
ctx.response.status = StatusCodes.OK;
|
||||
})
|
||||
.get("/_builder/api/apps", async (ctx) => {
|
||||
if(!config.dev) {
|
||||
ctx.request.status = StatusCodes.FORBIDDEN;
|
||||
ctx.request.body = "run in dev mode to access builder";
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.body = await getApps(config);
|
||||
ctx.response.status = StatusCodes.OK;
|
||||
|
||||
})
|
||||
.get("/_builder/api/:appname/appPackage", async (ctx) => {
|
||||
if(!config.dev) {
|
||||
ctx.request.status = StatusCodes.FORBIDDEN;
|
||||
|
@ -98,7 +110,7 @@ module.exports = (config, app) => {
|
|||
config,
|
||||
ctx.params.appname,
|
||||
ctx.request.body);
|
||||
ctx.reqponse.status = StatusCodes.OK;
|
||||
ctx.response.status = StatusCodes.OK;
|
||||
})
|
||||
.use(async (ctx, next) => {
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const { appPackageFolder } = require("./createAppPackage");
|
||||
const { writeFile, readFile } = require("./fsawait");
|
||||
const { appPackageFolder, appsFolder } = require("./createAppPackage");
|
||||
const { writeFile, readFile, readdir } = require("./fsawait");
|
||||
const { pipe : $ } = require("budibase-core").common;
|
||||
|
||||
module.exports.getPackageForBuilder = async (config, appname) => {
|
||||
const appPath = appPackageFolder(config, appname);
|
||||
|
@ -28,4 +29,10 @@ module.exports.savePackage = async (config, appname, pkg) => {
|
|||
JSON.stringify(pkg.accessLevels),
|
||||
"utf8");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.getApps = async (config) =>
|
||||
await readdir(appsFolder(config));
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ const appPackageFolder = (config, appname) =>
|
|||
|
||||
module.exports.appPackageFolder = appPackageFolder;
|
||||
|
||||
module.exports.appsFolder = (config) => appPackageFolder(config, "");
|
||||
|
||||
module.exports.masterAppPackage = (context) => {
|
||||
const { config } = context;
|
||||
const standardPackage = createAppPackage(
|
||||
|
|
|
@ -2,6 +2,7 @@ const util = require("util");
|
|||
const fs = require("fs");
|
||||
|
||||
module.exports.readFile = util.promisify(fs.readFile);
|
||||
module.exports.readdir = util.promisify(fs.readdir);
|
||||
module.exports.writeFile = util.promisify(fs.writeFile);
|
||||
module.exports.rimraf = util.promisify(require("rimraf"));
|
||||
module.exports.mkdir = util.promisify(fs.mkdir);
|
||||
|
|
Loading…
Reference in New Issue