1
0
Fork 0
mirror of synced 2024-06-01 18:20:18 +12:00

builder now web based and talking to api

This commit is contained in:
michael shanks 2019-07-14 07:46:36 +01:00
parent 13dd99be02
commit 363cbdd6c3
16 changed files with 95 additions and 191 deletions

View file

View file

@ -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,

View file

@ -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>

View file

@ -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:[],

View file

@ -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();
})
}

View file

@ -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),
});
}

View file

@ -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;

View file

@ -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}

View file

@ -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":{}}]}}

View file

@ -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}

View file

@ -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":{}}]]]}}

View file

@ -0,0 +1,9 @@
const fs = require("fs");
module.exports = (config) => ({
main: {
outputToFile : ({filename, content}) => {
fs.writeFile(`./tests/.data/${filename}`, content, {encoding:"utf8"});
}
}
})

View file

@ -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) => {

View file

@ -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));

View file

@ -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(

View file

@ -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);