Merge branch 'master' of https://github.com/Budibase/budibase into feature/md-datepicker-and-iconbutton

This commit is contained in:
Conor_Mack 2020-03-11 14:14:43 +00:00
commit 338e65b30a
43 changed files with 1251 additions and 291 deletions

View File

@ -4,13 +4,16 @@
import UserInterfaceRoot from "./userInterface/UserInterfaceRoot.svelte"
import BackendRoot from "./BackendRoot.svelte"
import { fade } from "svelte/transition"
import { SettingsIcon, PreviewIcon, HelpIcon } from "./common/Icons/"
</script>
<div class="root">
<div class="top-nav">
<div class="topleftnav">
<button class="home-logo">
<img src="/_builder/assets/budibase-logo-only.png" />
<img src="/_builder/assets/budibase-emblem-white.svg" />
</button>
<!-- <IconButton icon="home"
color="var(--slate)"
@ -29,6 +32,22 @@
</span>
</div>
<div class="toprightnav">
<span
class:active={!$store.isBackend}
class="topnavitemright"
on:click={store.showFrontend}>
<SettingsIcon />
</span>
<span
class:active={!$store.isBackend}
class="topnavitemright"
on:click={store.showFrontend}>
<PreviewIcon />
</span>
</div>
</div>
<div class="content">
{#if $store.isBackend}
<div in:fade out:fade>
@ -54,12 +73,12 @@
.top-nav {
flex: 0 0 auto;
height: 48px;
background: white;
padding: 0px 15px 0 1.8rem;
background: #0d203b;
padding: 0px 20px 0 20px;
display: flex;
align-items: center;
border-bottom: 1px solid #ddd;
box-sizing: border-box;
justify-content: space-between;
align-items: center;
}
.content {
@ -74,29 +93,54 @@
width: 100%;
}
.toprightnav {
display: flex;
}
.topleftnav {
display: flex;
align-items: center;
}
.topnavitem {
cursor: pointer;
color: var(--secondary50);
margin: 0px 15px;
color: rgb(255, 255, 255, 0.6);
margin: 0px 10px;
padding-top: 4px;
font-weight: 600;
font-weight: 500;
font-size: 1rem;
height: 100%;
display: flex;
align-items: center;
box-sizing: border-box;
}
.topnavitem:hover {
color: var(--secondary75);
font-weight: 600;
color: rgb(255, 255, 255, 0.8);
font-weight: 500;
}
.active {
color: var(--primary100);
color: white;
font-weight: 600;
border-bottom: 2px solid var(--primary100);
border-top: 2px solid transparent;
}
.topnavitemright {
cursor: pointer;
color: rgb(255, 255, 255, 0.6);
margin: 0px 5px;
padding-top: 4px;
font-weight: 500;
font-size: 1rem;
height: 100%;
display: flex;
flex:1;
align-items: center;
box-sizing: border-box;
}
.topnavitemright:hover {
color: rgb(255, 255, 255, 0.8);
font-weight: 500;
}
.home-logo {

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 400 400" style="enable-background:new 0 0 400 400;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#6A78D1;}
.st2{fill:#49C39E;}
.st3{fill:#F2545B;}
.st4{fill:#F5C26B;}
</style>
<g>
<g>
<path class="st0" d="M215,14.1l136.2,79.8c9.3,5.4,15,15.5,15,26.4v159.5c0,10.9-5.7,20.9-15,26.4L215,385.9
c-9.3,5.4-20.7,5.4-30,0L48.8,306.2c-9.3-5.4-15-15.5-15-26.4V120.2c0-10.9,5.7-20.9,15-26.4L185,14.1
C194.3,8.6,205.7,8.6,215,14.1z"/>
</g>
<g>
<path class="st1" d="M288.8,273.7l-83,43.6c-3.6,1.9-8,1.9-11.6,0l-83-43.6c-8.2-4.3-8.2-15.5,0-19.8l83-43.6
c3.6-1.9,8-1.9,11.6,0l83,43.6C297.1,258.3,297.1,269.4,288.8,273.7z"/>
<path class="st2" d="M288.8,231.2l-83,43.6c-3.6,1.9-8,1.9-11.6,0l-83-43.6c-8.2-4.3-8.2-15.5,0-19.8l83-43.6
c3.6-1.9,8-1.9,11.6,0l83,43.6C297.1,215.7,297.1,226.9,288.8,231.2z"/>
<path class="st3" d="M288.8,188.6l-83,43.6c-3.6,1.9-8,1.9-11.6,0l-83-43.6c-8.2-4.3-8.2-15.5,0-19.8l83-43.6
c3.6-1.9,8-1.9,11.6,0l83,43.6C297.1,173.1,297.1,184.3,288.8,188.6z"/>
<path class="st4" d="M288.8,146l-83,43.6c-3.6,1.9-8,1.9-11.6,0l-83-43.6c-8.2-4.3-8.2-15.5,0-19.8l83-43.6c3.6-1.9,8-1.9,11.6,0
l83,43.6C297.1,130.6,297.1,141.7,288.8,146z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -29,6 +29,18 @@ const css_map = {
name: "grid-template-columns",
generate: self,
},
align: {
name: "align-items",
generate: self,
},
justify: {
name: "justify-content",
generate: self,
},
direction: {
name: "flex-direction",
generate: self
},
gridarea: {
name: "grid-area",
generate: make_margin,
@ -100,7 +112,9 @@ const object_to_css_string = [
export const generate_css = ({ layout, position }) => {
let _layout = pipe(layout, object_to_css_string)
_layout = _layout.length ? _layout + "\ndisplay: grid;" : _layout
if (_layout.length) {
_layout += `\ndisplay: ${_layout.includes("flex") ? "flex" : "grid"};`;
}
return {
layout: _layout,

View File

@ -5,7 +5,6 @@ export const store = getStore()
export const initialise = async () => {
try {
console.log(process.env.NODE_ENV);
if (process.env.NODE_ENV === "production") {
LogRocket.init("knlald/budibase");
}

View File

@ -0,0 +1,9 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zM10.622 8.415a.4.4 0 00-.622.332v6.506a.4.4 0 00.622.332l4.879-3.252a.4.4 0 000-.666l-4.88-3.252z"
fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 349 B

View File

@ -0,0 +1,8 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12 1l9.5 5.5v11L12 23l-9.5-5.5v-11L12 1zm0 14a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 244 B

View File

@ -16,3 +16,6 @@ export { default as GridIcon } from "./Grid.svelte"
export { default as ShapeIcon } from "./Shape.svelte"
export { default as AddIcon } from "./Add.svelte"
export { default as JavaScriptIcon } from "./JavaScript.svelte"
export { default as PreviewIcon } from "./Preview.svelte"
export { default as SettingsIcon } from "./Settings.svelte"

View File

@ -4,9 +4,10 @@ import {
getTemplateApi,
getAuthApi,
} from "../../../core/src"
import { _getNew } from "../../../core/src/recordApi/getNew"
import { find, filter, keyBy, flatten, map } from "lodash/fp"
import { generateSchema } from "../../../core/src/indexing/indexSchemaCreator"
import { generate } from "shortid"
export { userWithFullAccess } from "../../../core/src/index"
@ -106,3 +107,18 @@ export const getRecordNodes = hierarchy =>
export const getIndexSchema = hierarchy => index =>
generateSchema(hierarchy, index)
export const getNewRecord = _getNew
export const getNewInstance = (appId, name) => {
const id = `2-${generate()}`
return {
key: `/applications/${appId}/instances/${id}`,
active: true,
version: { key: "" },
isNew: true,
type: "instance",
id,
name,
}
}

View File

@ -6,6 +6,7 @@
<title>Budibase Builder</title>
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.3.0/fonts/remixicon.css" rel="stylesheet">
<link rel='icon' type='image/png' href='/_builder/favicon.png'>
<link rel='stylesheet' href='/_builder/global.css'>
<link rel='stylesheet' href='/_builder/codemirror.css'>

View File

@ -29,7 +29,7 @@
$store.currentFrontEndType === "page"
? getProps($store.currentPreviewItem, ["name", "favicon"])
: getProps($store.currentPreviewItem, ["name", "description", "route"])
$: console.log(screen_props)
const onPropChanged = store.setComponentProp
const onStyleChanged = store.setComponentStyle

View File

@ -1,5 +1,6 @@
<script>
import InputGroup from "../common/Inputs/InputGroup.svelte"
import LayoutTemplateControls from "./LayoutTemplateControls.svelte";
export let onStyleChanged = () => {}
export let component
@ -25,6 +26,12 @@
templatecolumns: ["Grid Columns", single],
}
$: display = {
direction: ["Direction", single],
align: ["Align", single],
justify: ["Justify", single],
}
$: positions = {
column: ["Column", se],
row: ["Row", se],
@ -49,22 +56,24 @@
<h3>Styles</h3>
<h4>Positioning</h4>
<h4>Display</h4>
<div class="layout-pos">
{#each Object.entries(layouts) as [key, [name, meta, size]] (component._id + key)}
{#each Object.entries(display) as [key, [name, meta, size]] (component._id + key)}
<div class="grid">
<h5>{name}:</h5>
<InputGroup
<LayoutTemplateControls
onStyleChanged={_value => onStyleChanged('layout', key, _value)}
values={layout[key] || newValue(meta.length)}
propertyName={name}
{meta}
{size}
type="text" />
type="text"
/>
</div>
{/each}
</div>
<h4>Positioning</h4>
<!-- <h4>Positioning</h4>
<div class="layout-pos">
{#each Object.entries(positions) as [key, [name, meta, size]] (component._id + key)}
<div class="grid">
@ -76,7 +85,7 @@
{size} />
</div>
{/each}
</div>
</div> -->
<h4>Spacing</h4>
<div class="layout-spacing">

View File

@ -0,0 +1,80 @@
<script>
import PlusButton from "../common/PlusButton.svelte"
export let meta = []
export let size = ""
export let values = []
export let propertyName
export let onStyleChanged = () => {}
let selectedLayoutValues = values.map(v => v)
$: onStyleChanged(selectedLayoutValues)
const PROPERTY_OPTIONS = {
Direction: {
vertical: ["column", "ri-arrow-up-down-line"],
horizontal: ["row", "ri-arrow-left-right-line"],
},
Align: {
left: ["flex-start", "ri-layout-bottom-line"],
center: ["center", "ri-layout-row-line"],
right: ["flex-end", "ri-layout-top-line"],
space: ["space-between", "ri-space"],
},
Justify: {
left: ["flex-start", "ri-layout-left-line"],
center: ["center", "ri-layout-column-line"],
right: ["flex-end", "ri-layout-right-line"],
space: ["space-between", "ri-space"],
},
}
$: propertyChoices = Object.entries(PROPERTY_OPTIONS[propertyName])
</script>
<div class="inputs {size}">
{#each meta as { placeholder }, i}
{#each propertyChoices as [displayName, [cssPropValue, icon]]}
<button
class:selected={cssPropValue === selectedLayoutValues[i]}
on:click={() => {
const newPropertyValue = cssPropValue === selectedLayoutValues[i] ? '' : cssPropValue
selectedLayoutValues[i] = newPropertyValue
}}>
<i class={icon} />
</button>
{/each}
{/each}
</div>
<style>
.selected {
color: var(--button-text);
background: var(--background-button);
}
button {
cursor: pointer;
outline: none;
border: none;
border-radius: 5px;
background: rgba(249, 249, 249, 1);
min-width: 1.6rem;
min-height: 1.6rem;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2rem;
font-weight: 500;
color: rgba(22, 48, 87, 1);
}
.inputs {
display: flex;
justify-content: space-between;
}
</style>

View File

@ -128,7 +128,7 @@
.preview-pane {
grid-column: 2;
margin: 80px 60px;
margin: 40px;
background: #fff;
border-radius: 5px;
box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05);

View File

@ -53,6 +53,7 @@ const columnHeaders = indexSchema =>
_component: "@budibase/standard-components/text",
type: "none",
text: col.name,
formattingTag: "<b> - bold",
},
],
}))

View File

@ -3,17 +3,19 @@
"@budibase/client@file:../../../client":
version "0.0.16"
version "0.0.27"
dependencies:
"@nx-js/compiler-util" "^2.0.0"
bcryptjs "^2.4.3"
deep-equal "^2.0.1"
lodash "^4.17.15"
lunr "^2.3.5"
regexparam "^1.3.0"
shortid "^2.2.8"
svelte "^3.9.2"
"@budibase/standard-components@file:../../../standard-components":
version "0.0.16"
version "0.0.27"
"@nx-js/compiler-util@^2.0.0":
version "2.0.0"
@ -25,6 +27,161 @@ bcryptjs@^2.4.3:
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.1.tgz#fc12bbd6850e93212f21344748682ccc5a8813cf"
integrity sha512-7Et6r6XfNW61CPPCIYfm1YPGSmh6+CliYeL4km7GWJcpX5LTAflGF8drLLR+MZX+2P3NZfAfSduutBbSWqER4g==
dependencies:
es-abstract "^1.16.3"
es-get-iterator "^1.0.1"
is-arguments "^1.0.4"
is-date-object "^1.0.1"
is-regex "^1.0.4"
isarray "^2.0.5"
object-is "^1.0.1"
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
side-channel "^1.0.1"
which-boxed-primitive "^1.0.1"
which-collection "^1.0.0"
define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
dependencies:
object-keys "^1.0.12"
es-abstract@^1.16.3, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4:
version "1.17.4"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184"
integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==
dependencies:
es-to-primitive "^1.2.1"
function-bind "^1.1.1"
has "^1.0.3"
has-symbols "^1.0.1"
is-callable "^1.1.5"
is-regex "^1.0.5"
object-inspect "^1.7.0"
object-keys "^1.1.1"
object.assign "^4.1.0"
string.prototype.trimleft "^2.1.1"
string.prototype.trimright "^2.1.1"
es-get-iterator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8"
integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==
dependencies:
es-abstract "^1.17.4"
has-symbols "^1.0.1"
is-arguments "^1.0.4"
is-map "^2.0.1"
is-set "^2.0.1"
is-string "^1.0.5"
isarray "^2.0.5"
es-to-primitive@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
dependencies:
is-callable "^1.1.4"
is-date-object "^1.0.1"
is-symbol "^1.0.2"
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
has-symbols@^1.0.0, has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
dependencies:
function-bind "^1.1.1"
is-arguments@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
is-bigint@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4"
integrity sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g==
is-boolean-object@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e"
integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==
is-callable@^1.1.4, is-callable@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
is-date-object@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
is-map@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1"
integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==
is-number-object@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197"
integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==
is-regex@^1.0.4, is-regex@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
dependencies:
has "^1.0.3"
is-set@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"
integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==
is-string@^1.0.4, is-string@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
is-symbol@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==
dependencies:
has-symbols "^1.0.1"
is-weakmap@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2"
integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==
is-weakset@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83"
integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==
isarray@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
lodash@^4.17.15:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
@ -40,6 +197,44 @@ nanoid@^2.1.0:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.0.tgz#3de3dbd68cfb2f3bd52550e2bfd439cf75040eb2"
integrity sha512-g5WwS+p6Cm+zQhO2YOpRbQThZVnNb7DDq74h8YDCLfAGynrEOrbx2E16dc8ciENiP1va5sqaAruqn2sN+xpkWg==
object-inspect@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
object-is@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4"
integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
object.assign@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
dependencies:
define-properties "^1.1.2"
function-bind "^1.1.1"
has-symbols "^1.0.0"
object-keys "^1.0.11"
regexp.prototype.flags@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75"
integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.17.0-next.1"
regexparam@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
shortid@^2.2.8:
version "2.2.15"
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
@ -47,7 +242,52 @@ shortid@^2.2.8:
dependencies:
nanoid "^2.1.0"
side-channel@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"
integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==
dependencies:
es-abstract "^1.17.0-next.1"
object-inspect "^1.7.0"
string.prototype.trimleft@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==
dependencies:
define-properties "^1.1.3"
function-bind "^1.1.1"
string.prototype.trimright@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9"
integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==
dependencies:
define-properties "^1.1.3"
function-bind "^1.1.1"
svelte@^3.9.2:
version "3.12.1"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.12.1.tgz#ddfacd43272ac3255907c682b74ee7d3d8b06b0c"
integrity sha512-t29WJNjHIqfrdMcVXqIyRfgLEaNz7MihKXTpb8qHlbzvf0WyOOIhIlwIGvl6ahJ9+9CLJwz0sjhFNAmPgo8BHg==
which-boxed-primitive@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1"
integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==
dependencies:
is-bigint "^1.0.0"
is-boolean-object "^1.0.0"
is-number-object "^1.0.3"
is-string "^1.0.4"
is-symbol "^1.0.2"
which-collection@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906"
integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==
dependencies:
is-map "^2.0.1"
is-set "^2.0.1"
is-weakmap "^2.0.1"
is-weakset "^2.0.1"

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 400 400" style="enable-background:new 0 0 400 400;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#6A78D1;}
.st2{fill:#49C39E;}
.st3{fill:#F2545B;}
.st4{fill:#F5C26B;}
</style>
<g>
<g>
<path class="st0" d="M215,14.1l136.2,79.8c9.3,5.4,15,15.5,15,26.4v159.5c0,10.9-5.7,20.9-15,26.4L215,385.9
c-9.3,5.4-20.7,5.4-30,0L48.8,306.2c-9.3-5.4-15-15.5-15-26.4V120.2c0-10.9,5.7-20.9,15-26.4L185,14.1
C194.3,8.6,205.7,8.6,215,14.1z"/>
</g>
<g>
<path class="st1" d="M288.8,273.7l-83,43.6c-3.6,1.9-8,1.9-11.6,0l-83-43.6c-8.2-4.3-8.2-15.5,0-19.8l83-43.6
c3.6-1.9,8-1.9,11.6,0l83,43.6C297.1,258.3,297.1,269.4,288.8,273.7z"/>
<path class="st2" d="M288.8,231.2l-83,43.6c-3.6,1.9-8,1.9-11.6,0l-83-43.6c-8.2-4.3-8.2-15.5,0-19.8l83-43.6
c3.6-1.9,8-1.9,11.6,0l83,43.6C297.1,215.7,297.1,226.9,288.8,231.2z"/>
<path class="st3" d="M288.8,188.6l-83,43.6c-3.6,1.9-8,1.9-11.6,0l-83-43.6c-8.2-4.3-8.2-15.5,0-19.8l83-43.6
c3.6-1.9,8-1.9,11.6,0l83,43.6C297.1,173.1,297.1,184.3,288.8,188.6z"/>
<path class="st4" d="M288.8,146l-83,43.6c-3.6,1.9-8,1.9-11.6,0l-83-43.6c-8.2-4.3-8.2-15.5,0-19.8l83-43.6c3.6-1.9,8-1.9,11.6,0
l83,43.6C297.1,130.6,297.1,141.7,288.8,146z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,12 @@
const StatusCodes = require("../../utilities/statusCodes")
const { getRecordKey } = require("./helpers")
module.exports = async ctx => {
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
ctx.body = await ctx.instance.indexApi.aggregates(indexkey, {
rangeStartParams: ctx.request.body.rangeStartParams,
rangeEndParams: ctx.request.body.rangeEndParams,
searchPhrase: ctx.request.body.searchPhrase,
})
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,19 @@
const send = require("koa-send")
module.exports = async (ctx, next) => {
const path = ctx.path.replace(`/${ctx.params.appname}`, "")
if (path.startsWith("/api/")) {
await next()
} else if (path.startsWith("/_shared/")) {
await send(ctx, path.replace(`/_shared/`, ""), { root: ctx.sharedPath })
} else if (
path.endsWith(".js") ||
path.endsWith(".map") ||
path.endsWith(".css")
) {
await send(ctx, path, { root: ctx.publicPath })
} else {
await send(ctx, "/index.html", { root: ctx.publicPath })
}
}

View File

@ -0,0 +1,15 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
const user = await ctx.master.authenticate(
ctx.sessionId,
ctx.params.appname,
ctx.request.body.username,
ctx.request.body.password
)
if (!user) {
ctx.throw(StatusCodes.UNAUTHORIZED, "invalid username or password")
}
ctx.body = user.user_json
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,9 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
await ctx.instance.authApi.changeMyPassword(
ctx.request.body.currentPassword,
ctx.request.body.newPassword
)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,17 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
ctx.params.appname,
ctx.request.body.username
)
if (!instanceApi) {
ctx.request.status = StatusCodes.OK
return
}
await instanceApi.authApi.createTemporaryAccess(ctx.request.body.username)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,10 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
await ctx.instance.authApi.createUser(
ctx.request.body.user,
ctx.request.body.password
)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,9 @@
const StatusCodes = require("../../utilities/statusCodes")
const { getRecordKey } = require("./helpers")
module.exports = async ctx => {
await ctx.instance.recordApi.delete(
getRecordKey(ctx.params.appname, ctx.request.path)
)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,11 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
await ctx.instance.authApi.disableUser(ctx.request.body.username)
await ctx.master.removeSessionsForUser(
ctx.params.appname,
ctx.request.body.username
)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,6 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
await ctx.instance.authApi.enableUser(ctx.request.body.username)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,9 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
ctx.body = await ctx.instance.actionApi.execute(
ctx.request.body.actionname,
ctx.request.body.parameters
)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,6 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
ctx.body = await ctx.instance.authApi.getAccessLevels()
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,15 @@
const StatusCodes = require("../../utilities/statusCodes")
const { getRecordKey } = require("./helpers")
module.exports = async ctx => {
try {
ctx.body = await ctx.instance.recordApi.load(
getRecordKey(ctx.params.appname, ctx.request.path)
)
ctx.response.status = StatusCodes.OK
} catch (e) {
// need to be catching for 404s here
ctx.response.status = StatusCodes.INTERAL_ERROR
ctx.response.body = e.message
}
}

View File

@ -0,0 +1,6 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
ctx.body = await ctx.instance.authApi.getUsers()
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,7 @@
exports.getRecordKey = (appname, wholePath) =>
wholePath
.replace(`/${appname}/api/files/`, "")
.replace(`/${appname}/api/lookup_field/`, "")
.replace(`/${appname}/api/record/`, "")
.replace(`/${appname}/api/listRecords/`, "")
.replace(`/${appname}/api/aggregates/`, "")

View File

@ -0,0 +1,43 @@
const authenticate = require("./authenticate")
const setPasswordFromTemporaryCode = require("./setPasswordFromTemporaryCode")
const createTemporaryAccess = require("./createTemporaryAccess")
const appDefault = require("./appDefault")
const changeMyPassword = require("./changeMyPassword")
const executeAction = require("./executeAction")
const createUser = require("./createUser")
const enableUser = require("./enableUser")
const disableUser = require("./disableUser")
const getUsers = require("./getUsers")
const getAccessLevels = require("./getAccessLevels")
const listRecordsGet = require("./listRecordsGet")
const listRecordsPost = require("./listRecordsPost")
const aggregatesPost = require("./aggregatesPost")
const postFiles = require("./postFiles")
const saveRecord = require("./saveRecord")
const lookupField = require("./lookupField")
const getRecord = require("./getRecord")
const deleteRecord = require("./deleteRecord")
const saveAppHierarchy = require("./saveAppHierarchy")
module.exports = {
authenticate,
setPasswordFromTemporaryCode,
createTemporaryAccess,
appDefault,
changeMyPassword,
executeAction,
createUser,
enableUser,
disableUser,
getUsers,
getAccessLevels,
listRecordsGet,
listRecordsPost,
aggregatesPost,
postFiles,
saveRecord,
lookupField,
getRecord,
deleteRecord,
saveAppHierarchy,
}

View File

@ -0,0 +1,8 @@
const StatusCodes = require("../../utilities/statusCodes")
const { getRecordKey } = require("./helpers")
module.exports = async ctx => {
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
ctx.body = await ctx.instance.indexApi.listItems(indexkey)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,12 @@
const StatusCodes = require("../../utilities/statusCodes")
const { getRecordKey } = require("./helpers")
module.exports = async ctx => {
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
ctx.body = await ctx.instance.indexApi.listItems(indexkey, {
rangeStartParams: ctx.request.body.rangeStartParams,
rangeEndParams: ctx.request.body.rangeEndParams,
searchPhrase: ctx.request.body.searchPhrase,
})
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,14 @@
const StatusCodes = require("../../utilities/statusCodes")
const { getRecordKey } = require("./helpers")
module.exports = async ctx => {
const recordKey = getRecordKey(ctx.params.appname, ctx.request.path)
const fields = ctx.query.fields.split(",")
const recordContext = await ctx.instance.recordApi.getContext(recordKey)
const allContext = []
for (let field of fields) {
allContext.push(await recordContext.referenceOptions(field))
}
ctx.body = allContext
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,13 @@
const StatusCodes = require("../../utilities/statusCodes")
const { getRecordKey } = require("./helpers")
const fs = require("fs")
module.exports = async ctx => {
const file = ctx.request.files.file
ctx.body = await ctx.instance.recordApi.uploadFile(
getRecordKey(ctx.params.appname, ctx.request.path),
fs.createReadStream(file.path),
file.name
)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,6 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(ctx.body)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,6 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
ctx.body = await ctx.instance.recordApi.save(ctx.request.body)
ctx.response.status = StatusCodes.OK
}

View File

@ -0,0 +1,20 @@
const StatusCodes = require("../../utilities/statusCodes")
module.exports = async ctx => {
const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
ctx.params.appname,
ctx.request.body.username
)
if (!instanceApi) {
ctx.request.status = StatusCodes.OK
return
}
await instanceApi.authApi.setPasswordFromTemporaryCode(
ctx.request.body.tempCode,
ctx.request.body.newPassword
)
ctx.response.status = StatusCodes.OK
}

View File

@ -1,9 +1,10 @@
const Router = require("@koa/router")
const session = require("./session")
const StatusCodes = require("../utilities/statusCodes")
const fs = require("fs")
const { resolve } = require("path")
const send = require("koa-send")
const routeHandlers = require("./routeHandlers")
const {
getPackageForBuilder,
getComponentDefinitions,
@ -38,6 +39,25 @@ module.exports = (config, app) => {
ctx.set("x-bbappname", appname)
if (appname === "_builder") {
if (!config.dev) {
ctx.response.status = StatusCodes.FORBIDDEN
ctx.body = "run in dev mode to access builder"
return
}
if (ctx.path.startsWith("/_builder/instance/_master")) {
ctx.instance = ctx.master.getFullAccessApiForMaster()
ctx.isAuthenticated = !!ctx.instance
} else if (ctx.path.startsWith("/_builder/instance")) {
const builderAppName = pathParts[3]
const instanceId = pathParts[4]
ctx.instance = ctx.master.getFullAccessApiForInstanceId(
builderAppName,
instanceId
).bbInstance
ctx.isAuthenticated = !!ctx.instance
}
await next()
} else {
const instance = await ctx.master.getInstanceApiForSession(
@ -54,12 +74,6 @@ module.exports = (config, app) => {
}
})
.get("/_builder", async ctx => {
if (!config.dev) {
ctx.response.status = StatusCodes.FORBIDDEN
ctx.body = "run in dev mode to access builder"
return
}
await send(ctx, "/index.html", { root: builderPath })
})
.get("/_builder/:appname/componentlibrary", async ctx => {
@ -71,12 +85,6 @@ module.exports = (config, app) => {
await send(ctx, info.components._lib || "index.js", { root: info.libDir })
})
.get("/_builder/*", async (ctx, next) => {
if (!config.dev) {
ctx.response.status = StatusCodes.FORBIDDEN
ctx.body = "run in dev mode to access builder"
return
}
const path = ctx.path.replace("/_builder", "")
if (path.startsWith("/api/")) {
@ -85,58 +93,36 @@ module.exports = (config, app) => {
await send(ctx, path, { root: builderPath })
}
})
.post("/:appname/api/authenticate", async ctx => {
const user = await ctx.master.authenticate(
ctx.sessionId,
ctx.params.appname,
ctx.request.body.username,
ctx.request.body.password
.post("/:appname/api/authenticate", routeHandlers.authenticate)
.post(
"/_builder/instance/:appname/:instanceid/api/authenticate",
routeHandlers.authenticate
)
if (!user) {
ctx.throw(StatusCodes.UNAUTHORIZED, "invalid username or password")
}
ctx.body = user.user_json
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/setPasswordFromTemporaryCode", async ctx => {
const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
ctx.params.appname,
ctx.request.body.username
.post(
"/:appname/api/setPasswordFromTemporaryCode",
routeHandlers.setPasswordFromTemporaryCode
)
if (!instanceApi) {
ctx.request.status = StatusCodes.OK
return
}
await instanceApi.authApi.setPasswordFromTemporaryCode(
ctx.request.body.tempCode,
ctx.request.body.newPassword
.post(
"/_builder/instance/:appname/:instanceid/api/setPasswordFromTemporaryCode",
routeHandlers.setPasswordFromTemporaryCode
)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/createTemporaryAccess", async ctx => {
const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
ctx.params.appname,
ctx.request.body.username
.post(
"/:appname/api/createTemporaryAccess",
routeHandlers.createTemporaryAccess
)
.post(
"/_builder/instance/:appname/:instanceid/api/createTemporaryAccess",
routeHandlers.createTemporaryAccess
)
if (!instanceApi) {
ctx.request.status = StatusCodes.OK
return
}
await instanceApi.authApi.createTemporaryAccess(ctx.request.body.username)
ctx.response.status = StatusCodes.OK
})
.get("/_builder/api/apps", async ctx => {
ctx.body = await getApps(config, ctx.master)
ctx.response.status = StatusCodes.OK
})
.get("/_builder/api/:appname/appPackage", async ctx => {
ctx.body = await getPackageForBuilder(config, ctx.params.appname)
const application = await ctx.master.getApplicationWithInstances(
ctx.params.appname
)
ctx.body = await getPackageForBuilder(config, application)
ctx.response.status = StatusCodes.OK
})
.get("/_builder/api/:appname/components", async ctx => {
@ -228,23 +214,9 @@ module.exports = (config, app) => {
.get("/:appname", async ctx => {
await send(ctx, "/index.html", { root: ctx.publicPath })
})
.get("/:appname/*", async (ctx, next) => {
const path = ctx.path.replace(`/${ctx.params.appname}`, "")
if (path.startsWith("/api/")) {
await next()
} else if (path.startsWith("/_shared/")) {
await send(ctx, path.replace(`/_shared/`, ""), { root: ctx.sharedPath })
} else if (
path.endsWith(".js") ||
path.endsWith(".map") ||
path.endsWith(".css")
) {
await send(ctx, path, { root: ctx.publicPath })
} else {
await send(ctx, "/index.html", { root: ctx.publicPath })
}
})
.get("/:appname/*", routeHandlers.appDefault)
.get("/_builder/instance/:appname/:instanceid/*", routeHandlers.appDefault)
// EVERYTHING BELOW HERE REQUIRES AUTHENTICATION
.use(async (ctx, next) => {
if (ctx.isAuthenticated) {
await next()
@ -252,147 +224,85 @@ module.exports = (config, app) => {
ctx.response.status = StatusCodes.UNAUTHORIZED
}
})
.post("/:appname/api/changeMyPassword", async ctx => {
await ctx.instance.authApi.changeMyPassword(
ctx.request.body.currentPassword,
ctx.request.body.newPassword
.post("/:appname/api/changeMyPassword", routeHandlers.changeMyPassword)
.post(
"/_builder/instance/:appname/:instanceid/api/changeMyPassword",
routeHandlers.changeMyPassword
)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/changeMyPassword", async ctx => {
await ctx.instance.authApi.changeMyPassword(
ctx.request.body.currentPassword,
ctx.request.body.newPassword
.post(
"/:appname/api/executeAction/:actionname",
routeHandlers.executeAction
)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/executeAction/:actionname", async ctx => {
ctx.body = await ctx.instance.actionApi.execute(
ctx.request.body.actionname,
ctx.request.body.parameters
.post(
"/_builder/instance/:appname/:instanceid/api/executeAction/:actionname",
routeHandlers.executeAction
)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/createUser", async ctx => {
await ctx.instance.authApi.createUser(
ctx.request.body.user,
ctx.request.body.password
.post("/:appname/api/createUser", routeHandlers.createUser)
.post(
"/_builder/instance/:appname/:instanceid/api/createUser",
routeHandlers.createUser
)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/enableUser", async ctx => {
await ctx.instance.authApi.enableUser(ctx.request.body.username)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/disableUser", async ctx => {
await ctx.instance.authApi.disableUser(ctx.request.body.username)
await ctx.master.removeSessionsForUser(
ctx.params.appname,
ctx.request.body.username
.post("/:appname/api/enableUser", routeHandlers.enableUser)
.post(
"/_builder/instance/:appname/:instanceid/api/enableUser",
routeHandlers.enableUser
)
ctx.response.status = StatusCodes.OK
})
.get("/:appname/api/users", async ctx => {
ctx.body = await ctx.instance.authApi.getUsers()
ctx.response.status = StatusCodes.OK
})
.get("/:appname/api/accessLevels", async ctx => {
ctx.body = await ctx.instance.authApi.getAccessLevels()
ctx.response.status = StatusCodes.OK
})
.get("/:appname/api/listRecords/*", async ctx => {
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
ctx.body = await ctx.instance.indexApi.listItems(indexkey)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/listRecords/*", async ctx => {
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
ctx.body = await ctx.instance.indexApi.listItems(indexkey, {
rangeStartParams: ctx.request.body.rangeStartParams,
rangeEndParams: ctx.request.body.rangeEndParams,
searchPhrase: ctx.request.body.searchPhrase,
})
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/aggregates/*", async ctx => {
const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
ctx.body = await ctx.instance.indexApi.aggregates(indexkey, {
rangeStartParams: ctx.request.body.rangeStartParams,
rangeEndParams: ctx.request.body.rangeEndParams,
searchPhrase: ctx.request.body.searchPhrase,
})
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/files/*", async ctx => {
const file = ctx.request.files.file
ctx.body = await ctx.instance.recordApi.uploadFile(
getRecordKey(ctx.params.appname, ctx.request.path),
fs.createReadStream(file.path),
file.name
.post("/:appname/api/disableUser", routeHandlers.disableUser)
.post(
"/_builder/instance/:appname/:instanceid/api/disableUser",
routeHandlers.disableUser
)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/record/*", async ctx => {
ctx.body = await ctx.instance.recordApi.save(ctx.request.body)
ctx.response.status = StatusCodes.OK
})
.get("/:appname/api/lookup_field/*", async ctx => {
const recordKey = getRecordKey(ctx.params.appname, ctx.request.path)
const fields = ctx.query.fields.split(",")
const recordContext = await ctx.instance.recordApi.getContext(recordKey)
const allContext = []
for (let field of fields) {
allContext.push(await recordContext.referenceOptions(field))
}
ctx.body = allContext
ctx.response.status = StatusCodes.OK
})
.get("/:appname/api/record/*", async ctx => {
try {
ctx.body = await ctx.instance.recordApi.load(
getRecordKey(ctx.params.appname, ctx.request.path)
.get("/:appname/api/users", routeHandlers.getUsers)
.get(
"/_builder/instance/:appname/:instanceid/api/users",
routeHandlers.getUsers
)
ctx.response.status = StatusCodes.OK
} catch (e) {
// need to be catching for 404s here
ctx.response.status = StatusCodes.INTERAL_ERROR
ctx.response.body = e.message
}
})
.del("/:appname/api/record/*", async ctx => {
await ctx.instance.recordApi.delete(
getRecordKey(ctx.params.appname, ctx.request.path)
.get("/:appname/api/accessLevels", routeHandlers.getAccessLevels)
.get(
"/_builder/instance/:appname/:instanceid/api/accessLevels",
routeHandlers.getAccessLevels
)
ctx.response.status = StatusCodes.OK
})
.post("/:appname/api/apphierarchy", async ctx => {
ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(
ctx.body
.get("/:appname/api/listRecords/*", routeHandlers.listRecordsGet)
.get(
"/_builder/instance/:appname/:instanceid/api/listRecords/*",
routeHandlers.listRecordsGet
)
ctx.response.status = StatusCodes.OK
})
/*.post("/:appname/api/actionsAndTriggers", async (ctx) => {
ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(
ctx.body
);
ctx.response.status = StatusCodes.OK;
})
.get("/:appname/api/appDefinition", async (ctx) => {
ctx.body = await ctx.instance.templateApi.saveActionsAndTriggers(
ctx.body
);
ctx.response.status = StatusCodes.OK;
})*/
const getRecordKey = (appname, wholePath) =>
wholePath
.replace(`/${appname}/api/files/`, "")
.replace(`/${appname}/api/lookup_field/`, "")
.replace(`/${appname}/api/record/`, "")
.replace(`/${appname}/api/listRecords/`, "")
.replace(`/${appname}/api/aggregates/`, "")
.post("/:appname/api/listRecords/*", routeHandlers.listRecordsPost)
.post(
"/_builder/instance/:appname/:instanceid/api/listRecords/*",
routeHandlers.listRecordsPost
)
.post("/:appname/api/aggregates/*", routeHandlers.aggregatesPost)
.post(
"/_builder/instance/:appname/:instanceid/api/aggregates/*",
routeHandlers.aggregatesPost
)
.post("/:appname/api/files/*", routeHandlers.postFiles)
.post(
"/_builder/instance/:appname/:instanceid/api/files/*",
routeHandlers.postFiles
)
.post("/:appname/api/record/*", routeHandlers.saveRecord)
.post(
"/_builder/instance/:appname/:instanceid/api/record/*",
routeHandlers.saveRecord
)
.get("/:appname/api/lookup_field/*", routeHandlers.lookupField)
.get(
"/_builder/instance/:appname/:instanceid/api/lookup_field/*",
routeHandlers.lookupField
)
.get("/:appname/api/record/*", routeHandlers.getRecord)
.get(
"/_builder/instance/:appname/:instanceid/api/record/*",
routeHandlers.getRecord
)
.del("/:appname/api/record/*", routeHandlers.deleteRecord)
.del(
"/_builder/instance/:appname/:instanceid/api/record/*",
routeHandlers.deleteRecord
)
.post("/:appname/api/apphierarchy", routeHandlers.saveAppHierarchy)
return router
}

View File

@ -27,8 +27,8 @@ module.exports.saveBackend = saveBackend
const getAppDefinition = async appPath =>
await readJSON(`${appPath}/appDefinition.json`)
module.exports.getPackageForBuilder = async (config, appname) => {
const appPath = appPackageFolder(config, appname)
module.exports.getPackageForBuilder = async (config, application) => {
const appPath = appPackageFolder(config, application.name)
const pages = await getPages(appPath)
@ -40,6 +40,8 @@ module.exports.getPackageForBuilder = async (config, appname) => {
pages,
components: await getComponentDefinitions(appPath, pages),
application,
}
}

View File

@ -6,7 +6,7 @@ const {
const getDatastore = require("./datastore")
const getDatabaseManager = require("./databaseManager")
const { $ } = require("@budibase/core").common
const { keyBy, values } = require("lodash/fp")
const { keyBy, values, cloneDeep } = require("lodash/fp")
const {
masterAppPackage,
applictionVersionPackage,
@ -128,20 +128,10 @@ module.exports = async context => {
const userInMaster = await getUser(app.id, username)
if (!userInMaster) return null
const instance = await bb.recordApi.load(userInMaster.instance.key)
const versionId = determineVersionId(instance.version)
const dsConfig = JSON.parse(instance.datastoreconfig)
const appPackage = await applictionVersionPackage(
context,
const { instance, bbInstance } = await getFullAccessApiForInstanceId(
appname,
versionId,
instance.key
)
const bbInstance = await getApisWithFullAccess(
datastoreModule.getDatastore(dsConfig),
appPackage
userInMaster.instance.id,
app.id
)
const authUser = await bbInstance.authApi.authenticate(username, password)
@ -164,6 +154,34 @@ module.exports = async context => {
return session
}
const getFullAccessApiForInstanceId = async (appname, instanceId, appId) => {
if (!appId) {
appId = (await getApplication(appname)).id
}
const instanceKey = `/applications/${appId}/instances/${instanceId}`
const instance = await bb.recordApi.load(instanceKey)
const versionId = determineVersionId(instance.version)
const dsConfig = JSON.parse(instance.datastoreconfig)
const appPackage = await applictionVersionPackage(
context,
appname,
versionId,
instance.key
)
return {
bbInstance: await getApisWithFullAccess(
datastoreModule.getDatastore(dsConfig),
appPackage
),
instance,
}
}
const getFullAccessApiForMaster = async () =>
await getApisWithFullAccess(masterDatastore, masterAppPackage(context))
const getInstanceApiForSession = async (appname, sessionId) => {
if (isMaster(appname)) {
const customId = bb.recordApi.customId("mastersession", sessionId)
@ -295,6 +313,14 @@ module.exports = async context => {
}
}
const getApplicationWithInstances = async appname => {
const app = cloneDeep(await getApplication(appname))
app.instances = await bb.indexApi.listItems(
`/applications/${app.id}/allinstances`
)
return app
}
const disableUser = async (app, username) => {
await removeSessionsForUser(app.name, username)
const userInMaster = await getUser(app.id, username)
@ -324,5 +350,8 @@ module.exports = async context => {
createAppUser,
bbMaster: bb,
listApplications,
getFullAccessApiForInstanceId,
getFullAccessApiForMaster,
getApplicationWithInstances,
}
}

View File

@ -131,6 +131,33 @@
lodash "^4.17.13"
to-fast-properties "^2.0.0"
"@budibase/client@^0.0.27":
version "0.0.27"
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.27.tgz#d43a66202a23103ae5ac89d9fa69c3cd36b2a090"
integrity sha512-emS6L66fzfr/CdnpazlqveVKqcSQA9+sQRcbzLZ+sJLFk6FNIezRQcMjGHz+ooeYS91OVgOfleqXDCnvHO+MNg==
dependencies:
"@nx-js/compiler-util" "^2.0.0"
bcryptjs "^2.4.3"
deep-equal "^2.0.1"
lodash "^4.17.15"
lunr "^2.3.5"
regexparam "^1.3.0"
shortid "^2.2.8"
svelte "^3.9.2"
"@budibase/core@^0.0.27":
version "0.0.27"
resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.27.tgz#05bbacce692222089a1ae85b7ea4bb322e327f64"
integrity sha512-V8qGB9Lcwz8CFGzYct6i1oI+WiYgEOCsBBQ6DPPRLLVg07i2DHI9Ynwa35QXWTO3WeyWIxy//WSmVwSlYPAtOw==
dependencies:
"@nx-js/compiler-util" "^2.0.0"
bcryptjs "^2.4.3"
date-fns "^1.29.0"
lodash "^4.17.13"
lunr "^2.3.5"
safe-buffer "^5.1.2"
shortid "^2.2.8"
"@cnakazawa/watch@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
@ -299,6 +326,11 @@
path-to-regexp "^1.1.1"
urijs "^1.19.0"
"@nx-js/compiler-util@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@nx-js/compiler-util/-/compiler-util-2.0.0.tgz#c74c12165fa2f017a292bb79af007e8fce0af297"
integrity sha512-AxSQbwj9zqt8DYPZ6LwZdytqnwfiOEdcFdq4l8sdjkZmU2clTht7RDLCI8xvkp7KqgcNaOGlTeCM55TULWruyQ==
"@types/babel__core@^7.1.0":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f"
@ -646,6 +678,11 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
bcryptjs@^2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
binary-extensions@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
@ -1045,6 +1082,11 @@ data-urls@^1.0.0:
whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0"
date-fns@^1.29.0:
version "1.30.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -1083,6 +1125,24 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.1.tgz#fc12bbd6850e93212f21344748682ccc5a8813cf"
integrity sha512-7Et6r6XfNW61CPPCIYfm1YPGSmh6+CliYeL4km7GWJcpX5LTAflGF8drLLR+MZX+2P3NZfAfSduutBbSWqER4g==
dependencies:
es-abstract "^1.16.3"
es-get-iterator "^1.0.1"
is-arguments "^1.0.4"
is-date-object "^1.0.1"
is-regex "^1.0.4"
isarray "^2.0.5"
object-is "^1.0.1"
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
side-channel "^1.0.1"
which-boxed-primitive "^1.0.1"
which-collection "^1.0.0"
deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@ -1098,7 +1158,7 @@ deep-is@~0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
define-properties@^1.1.2:
define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
@ -1218,6 +1278,23 @@ error-inject@^1.0.0:
resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37"
integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=
es-abstract@^1.16.3, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4:
version "1.17.4"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184"
integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==
dependencies:
es-to-primitive "^1.2.1"
function-bind "^1.1.1"
has "^1.0.3"
has-symbols "^1.0.1"
is-callable "^1.1.5"
is-regex "^1.0.5"
object-inspect "^1.7.0"
object-keys "^1.1.1"
object.assign "^4.1.0"
string.prototype.trimleft "^2.1.1"
string.prototype.trimright "^2.1.1"
es-abstract@^1.5.1:
version "1.13.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
@ -1230,6 +1307,19 @@ es-abstract@^1.5.1:
is-regex "^1.0.4"
object-keys "^1.0.12"
es-get-iterator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8"
integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==
dependencies:
es-abstract "^1.17.4"
has-symbols "^1.0.1"
is-arguments "^1.0.4"
is-map "^2.0.1"
is-set "^2.0.1"
is-string "^1.0.5"
isarray "^2.0.5"
es-to-primitive@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
@ -1239,6 +1329,15 @@ es-to-primitive@^1.2.0:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es-to-primitive@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
dependencies:
is-callable "^1.1.4"
is-date-object "^1.0.1"
is-symbol "^1.0.2"
escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@ -1651,6 +1750,11 @@ has-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@ -1835,11 +1939,21 @@ is-accessor-descriptor@^1.0.0:
dependencies:
kind-of "^6.0.0"
is-arguments@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
is-bigint@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4"
integrity sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g==
is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
@ -1847,6 +1961,11 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
is-boolean-object@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e"
integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@ -1857,6 +1976,11 @@ is-callable@^1.1.4:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
is-callable@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
is-ci@^1.0.10:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
@ -1967,11 +2091,21 @@ is-installed-globally@^0.1.0:
global-dirs "^0.1.0"
is-path-inside "^1.0.0"
is-map@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1"
integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==
is-npm@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ=
is-number-object@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197"
integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==
is-number@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@ -2015,16 +2149,33 @@ is-regex@^1.0.4:
dependencies:
has "^1.0.1"
is-regex@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
dependencies:
has "^1.0.3"
is-retry-allowed@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
is-set@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"
integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==
is-stream@^1.0.0, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
is-string@^1.0.4, is-string@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
is-symbol@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
@ -2046,6 +2197,16 @@ is-typedarray@~1.0.0:
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
is-weakmap@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2"
integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==
is-weakset@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83"
integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==
is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@ -2066,6 +2227,11 @@ isarray@1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
isarray@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@ -2752,7 +2918,7 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
lodash@^4.17.11, lodash@^4.17.13:
lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@ -2777,6 +2943,11 @@ lru-cache@^4.0.1:
pseudomap "^1.0.2"
yallist "^2.1.2"
lunr@^2.3.5:
version "2.3.8"
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072"
integrity sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==
make-dir@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
@ -2938,6 +3109,11 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
nanoid@^2.1.0:
version "2.1.11"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@ -3133,7 +3309,17 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
object-keys@^1.0.12:
object-inspect@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
object-is@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4"
integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
@ -3145,6 +3331,16 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
object.assign@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
dependencies:
define-properties "^1.1.2"
function-bind "^1.1.1"
has-symbols "^1.0.0"
object-keys "^1.0.11"
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
@ -3531,6 +3727,19 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
regexp.prototype.flags@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75"
integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.17.0-next.1"
regexparam@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
registry-auth-token@^3.0.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e"
@ -3773,6 +3982,21 @@ shellwords@^0.1.1:
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
shortid@^2.2.8:
version "2.2.15"
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
integrity sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==
dependencies:
nanoid "^2.1.0"
side-channel@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"
integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==
dependencies:
es-abstract "^1.17.0-next.1"
object-inspect "^1.7.0"
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@ -3962,6 +4186,22 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
string.prototype.trimleft@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==
dependencies:
define-properties "^1.1.3"
function-bind "^1.1.1"
string.prototype.trimright@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9"
integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==
dependencies:
define-properties "^1.1.3"
function-bind "^1.1.1"
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
@ -4050,6 +4290,11 @@ supports-color@^6.1.0:
dependencies:
has-flag "^3.0.0"
svelte@^3.9.2:
version "3.19.2"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.19.2.tgz#4b0169ee33b37399f08eb92163593a0a46c242c7"
integrity sha512-Jswg065u8R9QYcN0rdpTQSFIr0hFq7YUzcPpEY6ZpFSAWkJKZG9AJvHE1d8+NJDTfr7SzKrO6EYssYYkUmszpA==
symbol-tree@^3.2.2:
version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
@ -4428,6 +4673,27 @@ whatwg-url@^7.0.0:
tr46 "^1.0.1"
webidl-conversions "^4.0.2"
which-boxed-primitive@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1"
integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==
dependencies:
is-bigint "^1.0.0"
is-boolean-object "^1.0.0"
is-number-object "^1.0.3"
is-string "^1.0.4"
is-symbol "^1.0.2"
which-collection@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906"
integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==
dependencies:
is-map "^2.0.1"
is-set "^2.0.1"
is-weakmap "^2.0.1"
is-weakset "^2.0.1"
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"

View File

@ -70,19 +70,17 @@ yarn run budi new your-app-name
now build and publish the latest budibase libs, to your new app
```
# from root of repo
cd ../..
# now back in the root of the repository
yarn run publishdev
```
then
`yarn run budi` and to run the budibase server
run the budibase server and builder in dev mode (i.e. with hot reloading):
if you then want to run the builder in dev mode (i.e. with hot reloading):
... keep the server running, and..
1. Open a new console
2. `yarn dev`
2. `yarn dev` (from root)
3. Access the builder on http://localhost:3000
This will enable watch mode for both the client AND the server.