1
0
Fork 0
mirror of synced 2024-06-21 11:51:00 +12:00

formatting + fixing builder tests

This commit is contained in:
Martin McKeaveney 2020-05-07 10:53:34 +01:00
parent e55120bb62
commit c255883aed
103 changed files with 906 additions and 1369 deletions

View file

@ -9,14 +9,14 @@ import builtins from "rollup-plugin-node-builtins"
import nodeglobals from "rollup-plugin-node-globals" import nodeglobals from "rollup-plugin-node-globals"
import copy from "rollup-plugin-copy" import copy from "rollup-plugin-copy"
import replace from "rollup-plugin-replace" import replace from "rollup-plugin-replace"
import json from '@rollup/plugin-json'; import json from "@rollup/plugin-json"
import path from "path" import path from "path"
const production = !process.env.ROLLUP_WATCH const production = !process.env.ROLLUP_WATCH
const lodash_fp_exports = [ const lodash_fp_exports = [
"flow",
"pipe", "pipe",
"union", "union",
"reduce", "reduce",
@ -121,7 +121,16 @@ const coreExternal = [
] ]
const customResolver = resolve({ const customResolver = resolve({
extensions: [".mjs", ".js", ".jsx", ".json", ".sass", ".scss", ".svelte", ".css"] extensions: [
".mjs",
".js",
".jsx",
".json",
".sass",
".scss",
".svelte",
".css",
],
}) })
const projectRootDir = path.resolve(__dirname) const projectRootDir = path.resolve(__dirname)

View file

@ -1,11 +1,8 @@
const apiCall = method => async (url, body) => { const apiCall = method => async (url, body) => {
const jwt = localStorage.getItem("budibase:token");
const response = await fetch(url, { const response = await fetch(url, {
method: method, method: method,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": `Bearer ${jwt}`
}, },
body: body && JSON.stringify(body), body: body && JSON.stringify(body),
}) })
@ -14,7 +11,7 @@ const apiCall = method => async (url, body) => {
// throw new Error("Server Error"); // throw new Error("Server Error");
// } // }
return response; return response
} }
const post = apiCall("POST") const post = apiCall("POST")

View file

@ -1,4 +1,4 @@
import { pipe } from "components/common/core"; import { pipe } from "components/common/core"
import { filter, map, reduce, toPairs } from "lodash/fp" import { filter, map, reduce, toPairs } from "lodash/fp"
const self = n => n const self = n => n
@ -88,7 +88,7 @@ const css_map = {
} }
export const generate_rule = ([name, values]) => export const generate_rule = ([name, values]) =>
`${css_map[name].name}: ${css_map[name].generate(values)} !important;` `${css_map[name].name}: ${css_map[name].generate(values)};`
const handle_grid = (acc, [name, value]) => { const handle_grid = (acc, [name, value]) => {
let tmp = [] let tmp = []
@ -113,9 +113,7 @@ const object_to_css_string = [
export const generate_css = ({ layout, position }) => { export const generate_css = ({ layout, position }) => {
let _layout = pipe(layout, object_to_css_string) let _layout = pipe(layout, object_to_css_string)
if (_layout.length) { if (_layout.length) {
_layout += `\ndisplay: ${ _layout += `\ndisplay: ${_layout.includes("flex") ? "flex" : "grid"};`
_layout.includes("flex") ? "flex" : "grid"
} !important;`
} }
return { return {

View file

@ -13,4 +13,4 @@ export const initialise = async () => {
} catch (err) { } catch (err) {
console.log(err) console.log(err)
} }
} }

View file

@ -5,14 +5,14 @@
* @param {string} appId - ID of the currently running app * @param {string} appId - ID of the currently running app
*/ */
export const fetchComponentLibDefinitions = async (clientId, appId) => { export const fetchComponentLibDefinitions = async (clientId, appId) => {
const LIB_DEFINITION_URL = `/${clientId}/${appId}/components/definitions`; const LIB_DEFINITION_URL = `/${clientId}/${appId}/components/definitions`
try { try {
const libDefinitionResponse = await fetch(LIB_DEFINITION_URL); const libDefinitionResponse = await fetch(LIB_DEFINITION_URL)
return await libDefinitionResponse.json(); return await libDefinitionResponse.json()
} catch (err) { } catch (err) {
console.error(`Error fetching component definitions for ${appId}`, err); console.error(`Error fetching component definitions for ${appId}`, err)
} }
}; }
/** /**
* Loads the JavaScript files for app component libraries and returns a map of their modules. * Loads the JavaScript files for app component libraries and returns a map of their modules.
@ -22,52 +22,10 @@ export const fetchComponentLibModules = async application => {
const allLibraries = {} const allLibraries = {}
for (let libraryName of application.componentLibraries) { for (let libraryName of application.componentLibraries) {
const LIBRARY_URL = `/${application._id}/componentlibrary?library=${libraryName}`; const LIBRARY_URL = `/${application._id}/componentlibrary?library=${libraryName}`
const libraryModule = await import(LIBRARY_URL) const libraryModule = await import(LIBRARY_URL)
allLibraries[libraryName] = libraryModule allLibraries[libraryName] = libraryModule
} }
return allLibraries return allLibraries
} }
// export const loadLibUrls = (appId, appPackage) => {
// const allLibraries = []
// for (let lib of libsFromPages(appPackage.pages)) {
// const libUrl = makeLibraryUrl(appId, lib)
// allLibraries.push({ libName: lib, importPath: libUrl })
// }
// return allLibraries
// }
// export const loadLib = async (appId, lib, allLibs) => {
// allLibs[lib] = await import(makeLibraryUrl(appId, lib))
// return allLibs
// }
// export const makeLibraryUrl = (appId, lib) =>
// `/_builder/${appId}/componentlibrary?lib=${encodeURI(lib)}`
// export const libsFromPages = pages =>
// pipe(pages, [values, map(p => p.componentLibraries), flatten, uniq])
// export const libUrlsForPreview = (appPackage, pageName) => {
// const resolve = path => {
// let file = appPackage.components.libraryPaths[path]
// if (file.startsWith("./")) file = file.substring(2)
// if (file.startsWith("/")) file = file.substring(1)
// let newPath = path
// if (!newPath.startsWith("./") && !newPath.startsWith("/")) {
// newPath = `/node_modules/${path}`
// }
// return {
// importPath: `/lib${newPath}/${file}`,
// libName: path,
// }
// }
// return pipe([appPackage.pages[pageName]], [libsFromPages, map(resolve)])
// }

View file

@ -24,10 +24,10 @@ export const getBackendUiStore = () => {
state.selectedDatabase = db state.selectedDatabase = db
state.breadcrumbs = [db.name] state.breadcrumbs = [db.name]
state.models = models state.models = models
state.views = views; state.views = views
return state return state
}) })
} },
}, },
records: { records: {
delete: () => delete: () =>
@ -47,11 +47,12 @@ export const getBackendUiStore = () => {
}), }),
}, },
models: { models: {
create: model => store.update(state => { create: model =>
state.models.push(model) store.update(state => {
state.models = state.models state.models.push(model)
return state state.models = state.models
}) return state
}),
}, },
views: { views: {
select: view => select: view =>
@ -90,4 +91,4 @@ export const saveBackend = async state => {
}, },
accessLevels: state.accessLevels, accessLevels: state.accessLevels,
}) })
} }

View file

@ -3,9 +3,7 @@ import { pipe } from "components/common/core"
import * as backendStoreActions from "./backend" import * as backendStoreActions from "./backend"
import { writable, get } from "svelte/store" import { writable, get } from "svelte/store"
import api from "../api" import api from "../api"
import { import { DEFAULT_PAGES_OBJECT } from "../../constants"
DEFAULT_PAGES_OBJECT
} from "../../constants";
import { getExactComponent } from "components/userInterface/pagesParsing/searchComponents" import { getExactComponent } from "components/userInterface/pagesParsing/searchComponents"
import { rename } from "components/userInterface/pagesParsing/renameScreen" import { rename } from "components/userInterface/pagesParsing/renameScreen"
import { import {
@ -13,9 +11,9 @@ import {
makePropsSafe, makePropsSafe,
getBuiltin, getBuiltin,
} from "components/userInterface/pagesParsing/createProps" } from "components/userInterface/pagesParsing/createProps"
import { import {
fetchComponentLibModules, fetchComponentLibModules,
fetchComponentLibDefinitions fetchComponentLibDefinitions,
} from "../loadComponentLibraries" } from "../loadComponentLibraries"
import { buildCodeForScreens } from "../buildCodeForScreens" import { buildCodeForScreens } from "../buildCodeForScreens"
import { generate_screen_css } from "../generate_css" import { generate_screen_css } from "../generate_css"
@ -39,7 +37,7 @@ export const getStore = () => {
errors: [], errors: [],
hasAppPackage: false, hasAppPackage: false,
libraries: null, libraries: null,
appId: "" appId: "",
} }
const store = writable(initial) const store = writable(initial)
@ -82,10 +80,11 @@ export const getStore = () => {
export default getStore export default getStore
const setPackage = (store, initial) => async (pkg) => { const setPackage = (store, initial) => async pkg => {
const [main_screens, unauth_screens] = await Promise.all([ const [main_screens, unauth_screens] = await Promise.all([
api.get(`/_builder/api/${pkg.application._id}/pages/main/screens`).then(r => r.json()), api
.get(`/_builder/api/${pkg.application._id}/pages/main/screens`)
.then(r => r.json()),
api api
.get(`/_builder/api/${pkg.application._id}/pages/unauthenticated/screens`) .get(`/_builder/api/${pkg.application._id}/pages/unauthenticated/screens`)
.then(r => r.json()), .then(r => r.json()),
@ -103,8 +102,10 @@ const setPackage = (store, initial) => async (pkg) => {
} }
initial.libraries = await fetchComponentLibModules(pkg.application) initial.libraries = await fetchComponentLibModules(pkg.application)
// TODO: Rename to componentDefinitions initial.components = await fetchComponentLibDefinitions(
initial.components = await fetchComponentLibDefinitions(pkg.clientId, pkg.application._id); pkg.clientId,
pkg.application._id
)
initial.appname = pkg.application.name initial.appname = pkg.application.name
initial.appId = pkg.application._id initial.appId = pkg.application._id
initial.pages = pkg.pages initial.pages = pkg.pages
@ -129,10 +130,7 @@ const _saveScreen = async (store, s, screen) => {
const currentPageScreens = s.pages[s.currentPageName]._screens const currentPageScreens = s.pages[s.currentPageName]._screens
await api await api
.post( .post(`/_builder/api/${s.appId}/pages/${s.currentPageName}/screen`, screen)
`/_builder/api/${s.appId}/pages/${s.currentPageName}/screen`,
screen
)
.then(() => { .then(() => {
if (currentPageScreens.includes(screen)) return if (currentPageScreens.includes(screen)) return
@ -159,10 +157,7 @@ const _saveScreen = async (store, s, screen) => {
const _saveScreenApi = (screen, s) => const _saveScreenApi = (screen, s) =>
api api
.post( .post(`/_builder/api/${s.appId}/pages/${s.currentPageName}/screen`, screen)
`/_builder/api/${s.appId}/pages/${s.currentPageName}/screen`,
screen
)
.then(() => _savePage(s)) .then(() => _savePage(s))
const createScreen = store => (screenName, route, layoutComponentName) => { const createScreen = store => (screenName, route, layoutComponentName) => {
@ -309,7 +304,7 @@ const setCurrentPage = store => pageName => {
store.update(state => { store.update(state => {
const current_screens = state.pages[pageName]._screens const current_screens = state.pages[pageName]._screens
const currentPage = state.pages[pageName]; const currentPage = state.pages[pageName]
state.currentFrontEndType = "page" state.currentFrontEndType = "page"
state.currentPageName = pageName state.currentPageName = pageName
@ -486,7 +481,9 @@ const deleteComponent = store => componentName => {
const parent = getParent(state.currentPreviewItem.props, componentName) const parent = getParent(state.currentPreviewItem.props, componentName)
if (parent) { if (parent) {
parent._children = parent._children.filter(component => component !== componentName) parent._children = parent._children.filter(
component => component !== componentName
)
} }
_saveCurrentPreviewItem(state) _saveCurrentPreviewItem(state)
@ -549,11 +546,10 @@ const copyComponent = store => component => {
} }
const getPathToComponent = store => component => { const getPathToComponent = store => component => {
// Gets all the components to needed to construct a path. // Gets all the components to needed to construct a path.
const tempStore = get(store) const tempStore = get(store)
let pathComponents = [] let pathComponents = []
let parent = component; let parent = component
let root = false let root = false
while (!root) { while (!root) {
parent = getParent(tempStore.currentPreviewItem.props, parent) parent = getParent(tempStore.currentPreviewItem.props, parent)
@ -575,7 +571,7 @@ const getPathToComponent = store => component => {
const IdList = allComponents.map(c => c._id) const IdList = allComponents.map(c => c._id)
// Construct ID Path: // Construct ID Path:
const path = IdList.join('/') const path = IdList.join("/")
return path return path
} }

View file

@ -47,7 +47,7 @@
.button:hover { .button:hover {
cursor: pointer; cursor: pointer;
font-weight: 600; font-weight: 600;
filter:saturate(90%); filter: saturate(90%);
} }
.button:disabled { .button:disabled {

View file

@ -13,7 +13,7 @@
</div> </div>
`, `,
status, status,
timeout: 100000 timeout: 100000,
}) })
} }
</script> </script>

View file

@ -1,10 +1,8 @@
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width="100%" width="100%"
height="100%"> height="100%">
<path fill="none" d="M0 0h24v24H0z"/> <path fill="none" d="M0 0h24v24H0z" />
<path <path fill="rgba(0,3,51,1)" d="M12 14l-4-4h8z" />
fill="rgba(0,3,51,1)"
d="M12 14l-4-4h8z" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 196 B

View file

@ -16,6 +16,10 @@
<div class="uk-margin"> <div class="uk-margin">
<label class="uk-form-label">{label}</label> <label class="uk-form-label">{label}</label>
<div class="uk-form-controls"> <div class="uk-form-controls">
<input class="budibase__input" type="number" {value} on:change={inputChanged} /> <input
class="budibase__input"
type="number"
{value}
on:change={inputChanged} />
</div> </div>
</div> </div>

View file

@ -1,3 +1,3 @@
import { flow } from "lodash/fp"; import { flow } from "lodash/fp"
export const pipe = (arg, funcs) => flow(funcs)(arg) export const pipe = (arg, funcs) => flow(funcs)(arg)

View file

@ -1,21 +1,18 @@
import { eventHandlers } from "../../../../client/src/state/eventHandlers" import { eventHandlers } from "../../../../client/src/state/eventHandlers"
import { writable } from "svelte/store" import { writable } from "svelte/store"
export { EVENT_TYPE_MEMBER_NAME } from "../../../../client/src/state/eventHandlers" export { EVENT_TYPE_MEMBER_NAME } from "../../../../client/src/state/eventHandlers"
import { createCoreApi } from "../../../../client/src/core"
export const allHandlers = (appDefinition, user) => { export const allHandlers = user => {
const coreApi = createCoreApi(appDefinition, user)
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(
appDefinition.hierarchy
)
const store = writable({ const store = writable({
_bbuser: user, _bbuser: user,
}) })
const handlersObj = eventHandlers(store, coreApi) const handlersObj = eventHandlers(store)
const handlersArray = []
for (let key in handlersObj) { const handlers = Object.keys(handlersObj).map(name => ({
handlersArray.push({ name: key, ...handlersObj[key] }) name,
} ...handlersObj[name],
return handlersArray }))
return handlers
} }

View file

@ -64,10 +64,14 @@
$: { $: {
if ($backendUiStore.selectedView) { if ($backendUiStore.selectedView) {
api.fetchDataForView($backendUiStore.selectedView, instanceId).then(records => { api
data = records || [] .fetchDataForView($backendUiStore.selectedView, instanceId)
headers = Object.keys($backendUiStore.selectedModel.schema).filter(key => !INTERNAL_HEADERS.includes(key)); .then(records => {
}) data = records || []
headers = Object.keys($backendUiStore.selectedModel.schema).filter(
key => !INTERNAL_HEADERS.includes(key)
)
})
} }
} }
@ -94,9 +98,7 @@
<section> <section>
<div class="table-controls"> <div class="table-controls">
<h2 class="title"> <h2 class="title">{$backendUiStore.selectedModel.name}</h2>
{$backendUiStore.selectedModel.name}
</h2>
</div> </div>
<table class="uk-table"> <table class="uk-table">
<thead> <thead>

View file

@ -4,13 +4,13 @@ export async function createUser(user, appId, instanceId) {
const CREATE_USER_URL = `/api/${appId}/${instanceId}/users` const CREATE_USER_URL = `/api/${appId}/${instanceId}/users`
const response = await api.post(CREATE_USER_URL, user) const response = await api.post(CREATE_USER_URL, user)
const json = await response.json() const json = await response.json()
return json.user; return json.user
} }
export async function createDatabase(clientId, appname, instanceName) { export async function createDatabase(clientId, appname, instanceName) {
const CREATE_DATABASE_URL = `/api/${clientId}/${appname}/instances` const CREATE_DATABASE_URL = `/api/${clientId}/${appname}/instances`
const response = await api.post(CREATE_DATABASE_URL, { const response = await api.post(CREATE_DATABASE_URL, {
name: instanceName name: instanceName,
}) })
return await response.json() return await response.json()
} }
@ -21,16 +21,10 @@ export async function deleteRecord(record, instanceId) {
return response return response
} }
// export async function loadRecord(key, { appname, instanceId }) {
// const LOAD_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record${key}`
// const response = await api.get(LOAD_RECORDS_URL)
// return await response.json()
// }
export async function saveRecord(record, instanceId) { export async function saveRecord(record, instanceId) {
const SAVE_RECORDS_URL = `/api/${instanceId}/records` const SAVE_RECORDS_URL = `/api/${instanceId}/records`
const response = await api.post(SAVE_RECORDS_URL, record) const response = await api.post(SAVE_RECORDS_URL, record)
return await response.json() return await response.json()
} }
@ -39,4 +33,4 @@ export async function fetchDataForView(viewName, instanceId) {
const response = await api.get(FETCH_RECORDS_URL) const response = await api.get(FETCH_RECORDS_URL)
return await response.json() return await response.json()
} }

View file

@ -9,7 +9,11 @@
let databaseName let databaseName
async function createDatabase() { async function createDatabase() {
const response = await api.createDatabase($store.clientId, $store.appId, databaseName) const response = await api.createDatabase(
$store.clientId,
$store.appId,
databaseName
)
store.createDatabaseForApp(response.instance) store.createDatabaseForApp(response.instance)
onClosed() onClosed()
} }

View file

@ -8,7 +8,6 @@
import FieldView from "./FieldView.svelte" import FieldView from "./FieldView.svelte"
import api from "builderStore/api" import api from "builderStore/api"
import { store, backendUiStore } from "builderStore" import { store, backendUiStore } from "builderStore"
import { common, hierarchy } from "../../../../../../../core/src/"
import { pipe } from "components/common/core" import { pipe } from "components/common/core"
import ErrorsBox from "components/common/ErrorsBox.svelte" import ErrorsBox from "components/common/ErrorsBox.svelte"
@ -21,24 +20,18 @@
$: modelFields = model.schema ? Object.entries(model.schema) : [] $: modelFields = model.schema ? Object.entries(model.schema) : []
$: instanceId = $backendUiStore.selectedDatabase.id $: instanceId = $backendUiStore.selectedDatabase.id
function editField() { function editField() {}
} function deleteField() {}
function deleteField() { function onFinishedFieldEdit() {}
}
function onFinishedFieldEdit() {
}
async function saveModel() { async function saveModel() {
const SAVE_MODEL_URL = `/api/${instanceId}/models` const SAVE_MODEL_URL = `/api/${instanceId}/models`
const response = await api.post(SAVE_MODEL_URL, model) const response = await api.post(SAVE_MODEL_URL, model)
const newModel = await response.json() const newModel = await response.json()
backendUiStore.actions.models.create(newModel.model) backendUiStore.actions.models.create(newModel.model)
onClosed(); onClosed()
} }
</script> </script>
@ -98,18 +91,15 @@
</tbody> </tbody>
</table> </table>
<div class="uk-margin"> <div class="uk-margin">
<ActionButton color="secondary" on:click={saveModel}> <ActionButton color="secondary" on:click={saveModel}>Save</ActionButton>
Save
</ActionButton>
</div> </div>
</div> </div>
{:else} {:else}
<FieldView <FieldView
field={fieldToEdit} field={fieldToEdit}
onFinished={onFinishedFieldEdit} onFinished={onFinishedFieldEdit}
schema={model.schema} schema={model.schema}
goBack={() => showFieldView = false} goBack={() => (showFieldView = false)} />
/>
{/if} {/if}
<style> <style>

View file

@ -9,7 +9,7 @@
import ErrorsBox from "components/common/ErrorsBox.svelte" import ErrorsBox from "components/common/ErrorsBox.svelte"
const CLASS_NAME_MAP = { const CLASS_NAME_MAP = {
boolean: "uk-checkbox" boolean: "uk-checkbox",
} }
export let record = {} export let record = {}
@ -55,7 +55,7 @@
backendUiStore.update(state => { backendUiStore.update(state => {
state.selectedView = state.selectedView state.selectedView = state.selectedView
onClosed(); onClosed()
return state return state
}) })
} }

View file

@ -35,7 +35,7 @@
state.views = [...state.views, response.view] state.views = [...state.views, response.view]
return state return state
}) })
onClosed(); onClosed()
} }
</script> </script>
@ -71,9 +71,7 @@
<CodeArea bind:text={view.reduce} label="Reduce" /> <CodeArea bind:text={view.reduce} label="Reduce" />
{/if} {/if}
<ActionButton color="secondary" on:click={saveView}> <ActionButton color="secondary" on:click={saveView}>Save</ActionButton>
Save
</ActionButton>
<ActionButton alert on:click={deleteView}>Delete</ActionButton> <ActionButton alert on:click={deleteView}>Delete</ActionButton>
</form> </form>

View file

@ -14,7 +14,7 @@
async function createUser() { async function createUser() {
const user = { name: username, username, password } const user = { name: username, username, password }
const response = await api.createUser(user, appId, instanceId); const response = await api.createUser(user, appId, instanceId)
backendUiStore.actions.users.create(response) backendUiStore.actions.users.create(response)
onClosed() onClosed()
} }

View file

@ -5,20 +5,20 @@
export let errors = [] export let errors = []
export let className = "uk-input" export let className = "uk-input"
let checked = type === "checkbox" ? value : false; let checked = type === "checkbox" ? value : false
const handleInput = event => { const handleInput = event => {
if (event.target.type === "checkbox") { if (event.target.type === "checkbox") {
value = event.target.checked; value = event.target.checked
return; return
} }
if (event.target.type === "number") { if (event.target.type === "number") {
value = parseInt(event.target.value); value = parseInt(event.target.value)
return; return
} }
value = event.target.value; value = event.target.value
} }
</script> </script>

View file

@ -51,12 +51,13 @@
}) })
} }
async function deleteModel(modelToDelete) { async function deleteModel(modelToDelete) {
const DELETE_MODEL_URL = `/api/${instanceId}/models/${node._id}/${node._rev}` const DELETE_MODEL_URL = `/api/${instanceId}/models/${node._id}/${node._rev}`
const response = await api.delete(DELETE_MODEL_URL) const response = await api.delete(DELETE_MODEL_URL)
backendUiStore.update(state => { backendUiStore.update(state => {
state.models = state.models.filter(model => model._id !== modelToDelete._id) state.models = state.models.filter(
model => model._id !== modelToDelete._id
)
state.selectedView = {} state.selectedView = {}
return state return state
}) })
@ -83,11 +84,7 @@
<div class="hierarchy-items-container"> <div class="hierarchy-items-container">
{#each $backendUiStore.models as model} {#each $backendUiStore.models as model}
<HierarchyRow <HierarchyRow onSelect={selectModel} node={model} type="model" />
onSelect={selectModel}
node={model}
type="model"
/>
{/each} {/each}
</div> </div>
</div> </div>
@ -104,11 +101,7 @@
<div class="hierarchy-items-container"> <div class="hierarchy-items-container">
{#each $backendUiStore.views as view} {#each $backendUiStore.views as view}
<HierarchyRow <HierarchyRow onSelect={selectView} node={view} type="view" />
onSelect={selectView}
node={view}
type="view"
/>
{/each} {/each}
</div> </div>
</div> </div>

View file

@ -1,7 +1,7 @@
<script> <script>
import { store, backendUiStore } from "builderStore" import { store, backendUiStore } from "builderStore"
import { map, join } from "lodash/fp" import { map, join } from "lodash/fp"
import iframeTemplate from "./iframeTemplate"; import iframeTemplate from "./iframeTemplate"
import { pipe } from "components/common/core" import { pipe } from "components/common/core"
let iframe let iframe
@ -25,61 +25,71 @@
) )
$: hasComponent = !!$store.currentPreviewItem $: hasComponent = !!$store.currentPreviewItem
$: { $: {
// Apply the CSS from the currently selected page and its screens // Apply the CSS from the currently selected page and its screens
const currentPage = $store.pages[$store.currentPageName]; const currentPage = $store.pages[$store.currentPageName]
styles += currentPage._css; styles += currentPage._css
for (let screen of currentPage._screens) { for (let screen of currentPage._screens) {
styles += screen._css; styles += screen._css
} }
styles = styles styles = styles
} }
$: stylesheetLinks = pipe( $: stylesheetLinks = pipe($store.pages.stylesheets, [
$store.pages.stylesheets, map(s => `<link rel="stylesheet" href="${s}"/>`),
[map(s => `<link rel="stylesheet" href="${s}"/>`), join("\n")] join("\n"),
) ])
$: screensExist = $store.currentPreviewItem._screens && $store.currentPreviewItem._screens.length > 0 $: screensExist =
$store.currentPreviewItem._screens &&
$store.currentPreviewItem._screens.length > 0
$: frontendDefinition = { $: frontendDefinition = {
appId: $store.appId, appId: $store.appId,
libraries: Object.keys($store.libraries), libraries: Object.keys($store.libraries),
page: $store.currentPreviewItem, page: $store.currentPreviewItem,
screens: screensExist ? $store.currentPreviewItem._screens : [{ screens: screensExist
name: "Screen Placeholder", ? $store.currentPreviewItem._screens
route: "*", : [
props: {
_component: "@budibase/standard-components/container",
type: "div",
_children: [
{ {
_component: "@budibase/standard-components/container", name: "Screen Placeholder",
_styles: { "position": {},"layout": {} }, route: "*",
_id: "__screenslot__text", props: {
_code: "", _component: "@budibase/standard-components/container",
className: "", type: "div",
onLoad: [], _children: [
type: "div", {
_children: [{ _component: "@budibase/standard-components/container",
_component:"@budibase/standard-components/text", _styles: { position: {}, layout: {} },
_styles: { "position": {}, "layout": {} }, _id: "__screenslot__text",
_id: "__screenslot__text_2", _code: "",
_code: "", className: "",
text: "content", onLoad: [],
font: "", type: "div",
color: "", _children: [
textAlign: "inline", {
verticalAlign: "inline", _component: "@budibase/standard-components/text",
formattingTag: "none" _styles: { position: {}, layout: {} },
}] _id: "__screenslot__text_2",
} _code: "",
] text: "content",
} font: "",
}], color: "",
appRootPath: "" textAlign: "inline",
verticalAlign: "inline",
formattingTag: "none",
},
],
},
],
},
},
],
appRootPath: "",
} }
$: selectedComponentId = $store.currentComponentInfo ? $store.currentComponentInfo._id : "" $: selectedComponentId = $store.currentComponentInfo
? $store.currentComponentInfo._id
: ""
</script> </script>
<div class="component-container"> <div class="component-container">
@ -93,7 +103,7 @@
stylesheetLinks, stylesheetLinks,
selectedComponentId, selectedComponentId,
frontendDefinition: JSON.stringify(frontendDefinition), frontendDefinition: JSON.stringify(frontendDefinition),
currentPageFunctions: $store.currentPageFunctions currentPageFunctions: $store.currentPageFunctions,
})} /> })} />
{/if} {/if}
</div> </div>

View file

@ -3,13 +3,13 @@ export default ({
stylesheetLinks, stylesheetLinks,
selectedComponentId, selectedComponentId,
frontendDefinition, frontendDefinition,
currentPageFunctions currentPageFunctions,
}) => `<html> }) => `<html>
<head> <head>
${stylesheetLinks} ${stylesheetLinks}
<style> <style>
${styles || ''} ${styles || ""}
.pos-${selectedComponentId} { .pos-${selectedComponentId} {
border: 2px solid #0055ff; border: 2px solid #0055ff;
@ -45,4 +45,4 @@ export default ({
</head> </head>
<body> <body>
</body> </body>
</html>` </html>`

View file

@ -1 +1 @@
export { default } from "./CurrentItemPreview.svelte"; export { default } from "./CurrentItemPreview.svelte"

View file

@ -31,10 +31,10 @@
const isComponentSelected = (current, comp) => current === comp const isComponentSelected = (current, comp) => current === comp
$: _screens = pipe( $: _screens = pipe(screens, [
screens, map(c => ({ component: c, title: lastPartOfName(c) })),
[map(c => ({ component: c, title: lastPartOfName(c) })), sortBy("title")] sortBy("title"),
) ])
const isScreenSelected = component => const isScreenSelected = component =>
component.component && component.component &&

View file

@ -2,7 +2,7 @@
import { goto } from "@sveltech/routify" import { goto } from "@sveltech/routify"
import { store } from "builderStore" import { store } from "builderStore"
import { last } from "lodash/fp" import { last } from "lodash/fp"
import { pipe } from "components/common/core"; import { pipe } from "components/common/core"
import { import {
XCircleIcon, XCircleIcon,
ChevronUpIcon, ChevronUpIcon,

View file

@ -33,11 +33,9 @@
let selectedEvent = null let selectedEvent = null
$: { $: {
const componentDefinition = components[component._component]; const componentDefinition = components[component._component]
events = Object.keys(componentDefinition.props) events = Object.keys(componentDefinition.props)
.filter( .filter(propName => componentDefinition.props[propName] === EVENT_TYPE)
propName => componentDefinition.props[propName] === EVENT_TYPE
)
.map(propName => ({ .map(propName => ({
name: propName, name: propName,
handlers: component[propName] || [], handlers: component[propName] || [],

View file

@ -24,14 +24,7 @@
let handlerType let handlerType
let parameters = [] let parameters = []
$: eventOptions = allHandlers( $: eventOptions = allHandlers()
{ hierarchy: $store.hierarchy },
{}
// userWithFullAccess({
// hierarchy: $store.hierarchy,
// actions: keyBy("name")($store.actions),
// })
)
$: { $: {
if (handler) { if (handler) {

View file

@ -26,10 +26,14 @@
let saveAttempted = false let saveAttempted = false
$: layoutComponents = Object.values($store.components).filter(componentDefinition => componentDefinition.container) $: layoutComponents = Object.values($store.components).filter(
componentDefinition => componentDefinition.container
)
$: layoutComponent = layoutComponent $: layoutComponent = layoutComponent
? layoutComponents.find(component => component._component === layoutComponent._component) ? layoutComponents.find(
component => component._component === layoutComponent._component
)
: layoutComponents[0] : layoutComponents[0]
$: route = !route && $store.screens.length === 0 ? "*" : route $: route = !route && $store.screens.length === 0 ? "*" : route
@ -55,11 +59,15 @@
} }
const screenNameExists = name => { const screenNameExists = name => {
return $store.screens.some(screen => screen.name.toLowerCase() === name.toLowerCase()); return $store.screens.some(
screen => screen.name.toLowerCase() === name.toLowerCase()
)
} }
const routeNameExists = route => { const routeNameExists = route => {
return $store.screens.some(screen => screen.route.toLowerCase() === route.toLowerCase()); return $store.screens.some(
screen => screen.route.toLowerCase() === route.toLowerCase()
)
} }
const routeChanged = event => { const routeChanged = event => {

View file

@ -3,7 +3,15 @@
// import { tick } from "svelte" // import { tick } from "svelte"
import ComponentsHierarchyChildren from "./ComponentsHierarchyChildren.svelte" import ComponentsHierarchyChildren from "./ComponentsHierarchyChildren.svelte"
import { last, sortBy, map, trimCharsStart, trimChars, join, compose } from "lodash/fp" import {
last,
sortBy,
map,
trimCharsStart,
trimChars,
join,
compose,
} from "lodash/fp"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import { pipe } from "components/common/core" import { pipe } from "components/common/core"
import { store } from "builderStore" import { store } from "builderStore"
@ -23,7 +31,7 @@
$: _layout = { $: _layout = {
component: layout, component: layout,
title: lastPartOfName(layout) title: lastPartOfName(layout),
} }
const isScreenSelected = component => const isScreenSelected = component =>

View file

@ -11,10 +11,10 @@
$: page = $store.pages[$store.currentPageName] $: page = $store.pages[$store.currentPageName]
$: title = page.index.title $: title = page.index.title
$: components = pipe( $: components = pipe($store.components, [
$store.components, filter(store => !isRootComponent($store)),
[filter(store => !isRootComponent($store)), concat([notSelectedComponent])] concat([notSelectedComponent]),
) ])
$: entryComponent = components[page.appBody] || notSelectedComponent $: entryComponent = components[page.appBody] || notSelectedComponent
const save = () => { const save = () => {

View file

@ -24,7 +24,7 @@
<form on:submit|preventDefault class="uk-form-stacked form-root"> <form on:submit|preventDefault class="uk-form-stacked form-root">
{#if componentDef} {#if componentDef}
{#each Object.entries(componentDef.props) as [prop_name, prop_def], index} {#each Object.entries(componentDef.props) as [prop_name, prop_def], index}
{#if prop_def !== "event"} {#if prop_def !== 'event'}
<div class="prop-container"> <div class="prop-container">
<PropControl <PropControl
{setProp} {setProp}

View file

@ -36,9 +36,9 @@ export const createProps = (componentDefinition, derivedFromProps) => {
for (let propName in componentDefinition.props) { for (let propName in componentDefinition.props) {
const parsedPropDef = parsePropDef(componentDefinition.props[propName]) const parsedPropDef = parsePropDef(componentDefinition.props[propName])
if (parsedPropDef.error) { if (parsedPropDef.error) {
errors.push({ propName, error: parsedPropDef.error }) errors.push({ propName, error: parsedPropDef.error })
} else { } else {
props[propName] = parsedPropDef props[propName] = parsedPropDef
} }
} }

View file

@ -1,5 +1,5 @@
import { find, isUndefined, filter, some, includes } from "lodash/fp" import { find, isUndefined, filter, some, includes } from "lodash/fp"
import { pipe } from "components/common/core"; import { pipe } from "components/common/core"
const normalString = s => (s || "").trim().toLowerCase() const normalString = s => (s || "").trim().toLowerCase()

View file

@ -1,5 +1,5 @@
import { split, last } from "lodash/fp" import { split, last } from "lodash/fp"
import { pipe } from "components/common/core"; import { pipe } from "components/common/core"
export const splitName = fullname => { export const splitName = fullname => {
const componentName = pipe(fullname, [split("/"), last]) const componentName = pipe(fullname, [split("/"), last])

View file

@ -1,99 +1,23 @@
import {
isString,
isBoolean,
isNumber,
isArray,
isPlainObject,
every,
} from "lodash/fp"
import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers"
import {
isBound,
BB_STATE_BINDINGPATH,
} from "@budibase/client/src/state/parseBinding"
// const defaultDef = typeName => () => ({
// type: typeName,
// required: false,
// default: types[typeName].default,
// options: typeName === "options" ? [] : undefined,
// })
// const propType = (defaultValue, isOfType, defaultDefinition) => ({
// isOfType,
// default: defaultValue,
// defaultDefinition,
// })
// const expandSingleProp = propDef => {
// const p = isString(propDef) ? types[propDef].defaultDefinition() : propDef
// if (!isString(propDef)) {
// const def = types[propDef.type].defaultDefinition()
// for (let p in def) {
// if (propDef[p] === undefined) {
// propDef[p] = def[p]
// }
// }
// }
// return p
// }
// export const expandComponentDefinition = componentDefinition => {
// const expandedProps = {}
// const expandedComponent = { ...componentDefinition }
// for (let p in componentDefinition.props) {
// expandedProps[p] = expandSingleProp(componentDefinition.props[p])
// }
// expandedComponent.props = expandedProps
// if (expandedComponent.children !== false) {
// expandedComponent.children = true
// }
// return expandedComponent
// }
// const isEvent = e =>
// isPlainObject(e) &&
// isString(e[EVENT_TYPE_MEMBER_NAME]) &&
// isPlainObject(e.parameters)
// const isEventList = e => isArray(e) && every(isEvent)(e)
// const EMPTY_STATE = () => ({ [BB_STATE_BINDINGPATH]: "" });
// export const types = {
// string: propType("", isString, defaultDef("string")),
// bool: propType(false, isBoolean, defaultDef("bool")),
// number: propType(0, isNumber, defaultDef("number")),
// options: propType("", isString, defaultDef("options")),
// asset: propType("", isString, defaultDef("asset")),
// event: propType([], isEventList, defaultDef("event")),
// // state: propType(EMPTY_STATE, isBound, defaultDef("state")),
// }
export const TYPE_MAP = { export const TYPE_MAP = {
string: { string: {
default: "" default: "",
}, },
bool: { bool: {
default: false default: false,
}, },
number: { number: {
default: 0 default: 0,
}, },
options: { options: {
default: [], default: [],
options: [] options: [],
}, },
event: { event: {
default: [], default: [],
} },
}; state: {
default: {
"##bbstate": "",
},
},
}

View file

@ -1,34 +1,35 @@
export default { export default {
categories: [ categories: [
{ {
name: 'Basic', name: "Basic",
isCategory: true, isCategory: true,
children: [ children: [
{ {
_component: "##builtin/screenslot", _component: "##builtin/screenslot",
name: 'Screenslot', name: "Screenslot",
description: 'This component is a placeholder for the rendering of a screen within a page.', description:
icon: 'ri-crop-2-line', "This component is a placeholder for the rendering of a screen within a page.",
icon: "ri-crop-2-line",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
{ {
_component: "@budibase/standard-components/container", _component: "@budibase/standard-components/container",
name: 'Container', name: "Container",
description: 'This component contains things within itself', description: "This component contains things within itself",
icon: 'ri-layout-row-fill', icon: "ri-layout-row-fill",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
{ {
name: 'Text', name: "Text",
description: 'This is a simple text component', description: "This is a simple text component",
icon: 'ri-t-box-fill', icon: "ri-t-box-fill",
commonProps: {}, commonProps: {},
children: [ children: [
{ {
_component: '@budibase/standard-components/heading', _component: "@budibase/standard-components/heading",
name: 'Headline', name: "Headline",
description: "A component for displaying heading text", description: "A component for displaying heading text",
icon: "ri-heading", icon: "ri-heading",
props: { props: {
@ -41,123 +42,128 @@ export default {
}, },
}, },
{ {
_component: '@budibase/standard-components/text', _component: "@budibase/standard-components/text",
name: 'Paragraph', name: "Paragraph",
description: "A component for displaying paragraph text.", description: "A component for displaying paragraph text.",
icon: 'ri-paragraph', icon: "ri-paragraph",
props: {} props: {},
} },
] ],
}, },
{ {
name: 'Input', name: "Input",
description: "These components handle user input.", description: "These components handle user input.",
icon: 'ri-edit-box-line', icon: "ri-edit-box-line",
commonProps: {}, commonProps: {},
children: [ children: [
{ {
_component: "@budibase/standard-components/input", _component: "@budibase/standard-components/input",
name: "Textfield", name: "Textfield",
description: "A textfield component that allows the user to input text.", description:
icon: 'ri-edit-box-line', "A textfield component that allows the user to input text.",
props: {} icon: "ri-edit-box-line",
props: {},
}, },
{ {
_component: "@budibase/standard-components/checkbox", _component: "@budibase/standard-components/checkbox",
name: "Checkbox", name: "Checkbox",
description: "A selectable checkbox component", description: "A selectable checkbox component",
icon: 'ri-checkbox-line', icon: "ri-checkbox-line",
props: {} props: {},
}, },
{ {
_component: "@budibase/standard-components/radiobutton", _component: "@budibase/standard-components/radiobutton",
name: "Radiobutton", name: "Radiobutton",
description: "A selectable radiobutton component", description: "A selectable radiobutton component",
icon: 'ri-radio-button-line', icon: "ri-radio-button-line",
props: {} props: {},
}, },
{ {
_component: "@budibase/standard-components/select", _component: "@budibase/standard-components/select",
name: "Select", name: "Select",
description: "A select component for choosing from different options", description:
icon: 'ri-file-list-line', "A select component for choosing from different options",
props: {} icon: "ri-file-list-line",
} props: {},
] },
],
}, },
{ {
_component: "@budibase/standard-components/button", _component: "@budibase/standard-components/button",
name: 'Button', name: "Button",
description: 'A basic html button that is ready for styling', description: "A basic html button that is ready for styling",
icon: 'ri-radio-button-fill', icon: "ri-radio-button-fill",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
{ {
_component: "@budibase/standard-components/icon", _component: "@budibase/standard-components/icon",
name: 'Icon', name: "Icon",
description: 'A basic component for displaying icons', description: "A basic component for displaying icons",
icon: 'ri-sun-fill', icon: "ri-sun-fill",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
{ {
_component: "@budibase/standard-components/link", _component: "@budibase/standard-components/link",
name: 'Link', name: "Link",
description: 'A basic link component for internal and external links', description: "A basic link component for internal and external links",
icon: 'ri-link', icon: "ri-link",
commonProps: {}, commonProps: {},
children: [] children: [],
} },
] ],
}, },
{ {
name: 'Blocks', name: "Blocks",
isCategory: true, isCategory: true,
children: [ children: [
{ {
_component: "@budibase/materialdesign-components/BasicCard", _component: "@budibase/materialdesign-components/BasicCard",
name: 'Card', name: "Card",
description: 'A basic card component that can contain content and actions.', description:
icon: 'ri-layout-bottom-line', "A basic card component that can contain content and actions.",
icon: "ri-layout-bottom-line",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
{ {
_component: "@budibase/standard-components/login", _component: "@budibase/standard-components/login",
name: 'Login', name: "Login",
description: 'A component that automatically generates a login screen for your app.', description:
icon: 'ri-login-box-fill', "A component that automatically generates a login screen for your app.",
icon: "ri-login-box-fill",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
{ {
name: "Navigation Bar", name: "Navigation Bar",
_component: "@budibase/standard-components/Navigation", _component: "@budibase/standard-components/Navigation",
description: "A component for handling the navigation within your app.", description:
"A component for handling the navigation within your app.",
icon: "ri-navigation-fill", icon: "ri-navigation-fill",
commonProps: {}, commonProps: {},
children: [] children: [],
} },
] ],
}, },
{ {
name: 'Data', name: "Data",
isCategory: true, isCategory: true,
children: [ children: [
{ {
name: 'Table', name: "Table",
_component: "@budibase/materialdesign-components/Datatable", _component: "@budibase/materialdesign-components/Datatable",
description: 'A component that generates a table from your data.', description: "A component that generates a table from your data.",
icon: 'ri-archive-drawer-fill', icon: "ri-archive-drawer-fill",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
{ {
_component: "@budibase/materialdesign-components/Form", _component: "@budibase/materialdesign-components/Form",
name: 'Form', name: "Form",
description: 'A component that generates a form from your data.', description: "A component that generates a form from your data.",
icon: 'ri-file-edit-fill', icon: "ri-file-edit-fill",
commonProps: {}, commonProps: {},
component: "@budibase/materialdesign-components/Form", component: "@budibase/materialdesign-components/Form",
template: { template: {
@ -165,25 +171,25 @@ export default {
description: "Form for saving a record", description: "Form for saving a record",
name: "@budibase/materialdesign-components/recordForm", name: "@budibase/materialdesign-components/recordForm",
}, },
children: [] children: [],
}, },
{ {
_component: "@budibase/standard-components/datatable", _component: "@budibase/standard-components/datatable",
name: 'DataTable', name: "DataTable",
description: 'A table for displaying data from the backend.', description: "A table for displaying data from the backend.",
icon: 'ri-archive-drawer-fill', icon: "ri-archive-drawer-fill",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
{ {
_component: "@budibase/standard-components/dataform", _component: "@budibase/standard-components/dataform",
name: 'DataForm', name: "DataForm",
description: 'Form stuff', description: "Form stuff",
icon: 'ri-file-edit-fill', icon: "ri-file-edit-fill",
commonProps: {}, commonProps: {},
children: [] children: [],
}, },
] ],
}, },
] ],
} }

View file

@ -60,7 +60,7 @@
<span <span
class:active={false} class:active={false}
class="topnavitemright" class="topnavitemright"
on:click={() => location = `/${application}`}> on:click={() => (location = `/${application}`)}>
<PreviewIcon /> <PreviewIcon />
</span> </span>
</div> </div>
@ -72,7 +72,7 @@
{:then} {:then}
<slot /> <slot />
{:catch error} {:catch error}
<p>Something went wrong: {error.message}</p> <p>Something went wrong: {error.message}</p>
{/await} {/await}
</div> </div>

View file

@ -12,7 +12,7 @@
open( open(
CreateEditRecordModal, CreateEditRecordModal,
{ {
onClosed: close onClosed: close,
}, },
{ styleContent: { padding: "0" } } { styleContent: { padding: "0" } }
) )

View file

@ -30,7 +30,6 @@
// Find Component with ID and continue // Find Component with ID and continue
function findComponent(ids, children) { function findComponent(ids, children) {
console.log(ids, children);
// Setup stuff // Setup stuff
let componentToSelect let componentToSelect
let currentChildren = children let currentChildren = children

View file

@ -0,0 +1,4 @@
<script>
import { goto } from "@sveltech/routify"
$goto("../page-layout")
</script>

View file

@ -1,5 +1,5 @@
<script> <script>
import { store } from "builderStore"; import { store } from "builderStore"
import AppList from "components/start/AppList.svelte" import AppList from "components/start/AppList.svelte"
import { onMount } from "svelte" import { onMount } from "svelte"
import IconButton from "components/common/IconButton.svelte" import IconButton from "components/common/IconButton.svelte"

View file

@ -1,42 +0,0 @@
import { componentDependencies } from "../src/components/userInterface/pagesParsing/findDependencies"
import { componentsAndScreens } from "./testData"
import { some, find } from "lodash/fp"
describe("component dependencies", () => {
const contains = (result, name) => some(c => c.name === name)(result)
const get = (all, name) => find(c => c.name === name)(all)
it("should include component that inheirts", () => {
const { components, screens } = componentsAndScreens()
const result = componentDependencies(
{},
screens,
components,
get([...components, ...screens], "budibase-components/TextBox")
)
expect(contains(result.dependantComponents, "common/SmallTextbox")).toBe(
true
)
})
it("should include components in page apbody", () => {
const { components, screens } = componentsAndScreens()
const pages = {
main: {
appBody: "PrimaryButton",
},
}
const result = componentDependencies(
pages,
screens,
components,
get([...components, ...screens], "PrimaryButton")
)
expect(result.dependantPages).toEqual(["main"])
})
})

View file

@ -5,6 +5,7 @@ import { stripStandardProps } from "./testData"
describe("createDefaultProps", () => { describe("createDefaultProps", () => {
const getcomponent = () => ({ const getcomponent = () => ({
_component: "some_component",
name: "some_component", name: "some_component",
props: { props: {
fieldName: { type: "string", default: "something" }, fieldName: { type: "string", default: "something" },
@ -21,7 +22,7 @@ describe("createDefaultProps", () => {
expect(keys(props).length).toBe(3) expect(keys(props).length).toBe(3)
}) })
it("should set component name", () => { it("should set component _component", () => {
const { props, errors } = createProps(getcomponent()) const { props, errors } = createProps(getcomponent())
expect(errors).toEqual([]) expect(errors).toEqual([])
@ -37,17 +38,6 @@ describe("createDefaultProps", () => {
expect(errors.length).toEqual(1) expect(errors.length).toEqual(1)
}) })
it("should create a object with single blank string value, when no default", () => {
const comp = getcomponent()
comp.props.fieldName = { type: "string" }
const { props, errors } = createProps(comp)
expect(errors).toEqual([])
expect(props.fieldName).toBeDefined()
expect(props.fieldName).toBe("")
})
it("should create a object with single blank string value, when prop definition is 'string' ", () => { it("should create a object with single blank string value, when prop definition is 'string' ", () => {
const comp = getcomponent() const comp = getcomponent()
comp.props.fieldName = "string" comp.props.fieldName = "string"
@ -181,16 +171,6 @@ describe("createDefaultProps", () => {
expect(some(e => e.propName === "fieldLength")(errors)).toBeTruthy() expect(some(e => e.propName === "fieldLength")(errors)).toBeTruthy()
}) })
it("should return error default value is not of declared type", () => {
const comp = getcomponent()
comp.props.fieldName = { type: "string", default: 1 }
const { errors } = createProps(comp)
expect(errors.length).toBe(1)
expect(some(e => e.propName === "fieldName")(errors)).toBeTruthy()
})
it("should merge in derived props", () => { it("should merge in derived props", () => {
const comp = getcomponent() const comp = getcomponent()
comp.props.fieldName = "string" comp.props.fieldName = "string"

View file

@ -1,45 +0,0 @@
import { expandComponentDefinition } from "../src/components/userInterface/pagesParsing/types"
const componentDef = () => ({
name: "comp",
props: {
label: "string",
width: { type: "number" },
color: { type: "string", required: true },
},
})
describe("expandPropDefintion", () => {
it("should expand property defined as string, into default for that type", () => {
const result = expandComponentDefinition(componentDef())
expect(result.props.label.type).toBe("string")
expect(result.props.label.required).toBe(false)
})
it("should add members to property defined as object, when members do not exist", () => {
const result = expandComponentDefinition(componentDef())
expect(result.props.width.required).toBe(false)
})
it("should not override existing memebers", () => {
const result = expandComponentDefinition(componentDef())
expect(result.props.color.required).toBe(true)
})
it("should set children=true when not included", () => {
const result = expandComponentDefinition(componentDef())
expect(result.children).toBe(true)
})
it("should not change children when specified", () => {
const c = componentDef()
c.children = false
const result = expandComponentDefinition(c)
expect(result.children).toBe(false)
c.children = true
const result2 = expandComponentDefinition(c)
expect(result2.children).toBe(true)
})
})

View file

@ -1,30 +0,0 @@
import { getNewScreen } from "../src/components/userInterface/pagesParsing/createProps"
import { componentsAndScreens, stripStandardProps } from "./testData"
describe("geNewScreen", () => {
it("should return correct props for screen", () => {
const { components } = componentsAndScreens()
const result = getNewScreen(
components,
"budibase-components/TextBox",
"newscreen"
)
expect(result.props._code).toBeDefined()
expect(result.props._id).toBeDefined()
expect(result.props._styles).toBeDefined()
stripStandardProps(result.props)
const expectedProps = {
_component: "budibase-components/TextBox",
size: "",
isPassword: false,
placeholder: "",
label: "",
}
expect(result.props).toEqual(expectedProps)
expect(result.name).toBe("newscreen")
expect(result.url).toBeDefined()
})
})

View file

@ -26,7 +26,8 @@ module.exports = {
}) })
yargs.positional("couchDbUrl", { yargs.positional("couchDbUrl", {
type: "string", type: "string",
describe: "connection string for couch db, format: https://username:password@localhost:5984", describe:
"connection string for couch db, format: https://username:password@localhost:5984",
alias: "x", alias: "x",
default: "", default: "",
}) })

View file

@ -1,7 +1,9 @@
const { xPlatHomeDir } = require("../../common") const { xPlatHomeDir } = require("../../common")
const dotenv = require("dotenv") const dotenv = require("dotenv")
const createInstance = require("@budibase/server/api/controllers/instance").create const createInstance = require("@budibase/server/api/controllers/instance")
const createApplication = require("@budibase/server/api/controllers/application").create .create
const createApplication = require("@budibase/server/api/controllers/application")
.create
const { copy, readJSON, writeJSON, remove, exists } = require("fs-extra") const { copy, readJSON, writeJSON, remove, exists } = require("fs-extra")
const { resolve, join } = require("path") const { resolve, join } = require("path")
const chalk = require("chalk") const chalk = require("chalk")
@ -13,7 +15,7 @@ module.exports = opts => {
} }
const run = async opts => { const run = async opts => {
console.log(opts); console.log(opts)
try { try {
opts.dir = xPlatHomeDir(opts.dir) opts.dir = xPlatHomeDir(opts.dir)
process.chdir(opts.dir) process.chdir(opts.dir)
@ -22,7 +24,7 @@ const run = async opts => {
await createEmptyAppPackage(opts) await createEmptyAppPackage(opts)
exec(`cd ${join(opts.dir, opts.applicationId)} && npm install`) exec(`cd ${join(opts.dir, opts.applicationId)} && npm install`)
} catch (error) { } catch (error) {
console.error(chalk.red("Error creating new app", error)); console.error(chalk.red("Error creating new app", error))
} }
} }

View file

@ -17,4 +17,5 @@ module.exports.serverFileName = relativePath =>
// return await buildAppContext(config, masterIsCreated) // return await buildAppContext(config, masterIsCreated)
// } // }
module.exports.xPlatHomeDir = dir => dir.startsWith("~") ? join(homedir(), dir.substring(1)) : dir; module.exports.xPlatHomeDir = dir =>
dir.startsWith("~") ? join(homedir(), dir.substring(1)) : dir

View file

@ -5,6 +5,7 @@ import nodeglobals from "rollup-plugin-node-globals"
const lodash_fp_exports = [ const lodash_fp_exports = [
"find", "find",
"compose",
"isUndefined", "isUndefined",
"split", "split",
"max", "max",

View file

@ -1 +0,0 @@
export { $ } from "../../../core/src/common"

View file

@ -1,12 +0,0 @@
export const createCoreApp = (backendDefinition, user) => {
const app = {
datastore: null,
crypto: null,
publish: () => {},
hierarchy: backendDefinition.hierarchy,
actions: backendDefinition.actions,
user,
}
return app
}

View file

@ -1,18 +0,0 @@
import { createCoreApp } from "./createCoreApp"
import { getNew, getNewChild } from "../../../core/src/recordApi/getNew"
import { constructHierarchy } from "../../../core/src/templateApi/createNodes"
export const createCoreApi = (backendDefinition, user) => {
const app = createCoreApp(backendDefinition, user)
return {
recordApi: {
getNew: getNew(app),
getNewChild: getNewChild(app),
},
templateApi: {
constructHierarchy,
},
}
}

View file

@ -1,5 +1,4 @@
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { createCoreApi } from "./core"
import { attachChildren } from "./render/attachChildren" import { attachChildren } from "./render/attachChildren"
import { createTreeNode } from "./render/prepareRenderComponent" import { createTreeNode } from "./render/prepareRenderComponent"
import { screenRouter } from "./render/screenRouter" import { screenRouter } from "./render/screenRouter"

View file

@ -1,8 +1,5 @@
import { createApp } from "./createApp" import { createApp } from "./createApp"
import { trimSlash } from "./common/trimSlash"
import { builtins, builtinLibName } from "./render/builtinComponents" import { builtins, builtinLibName } from "./render/builtinComponents"
// import * as standardComponents from "../../standard-components/dist";
// import * as materialDesignComponents from "../../materialdesign-components/dist";
/** /**
* create a web application from static budibase definition files. * create a web application from static budibase definition files.
@ -10,37 +7,43 @@ import { builtins, builtinLibName } from "./render/builtinComponents"
*/ */
export const loadBudibase = async opts => { export const loadBudibase = async opts => {
const _window = (opts && opts.window) || window const _window = (opts && opts.window) || window
const _localStorage = (opts && opts.localStorage) || localStorage // const _localStorage = (opts && opts.localStorage) || localStorage
const frontendDefinition = _window["##BUDIBASE_FRONTEND_DEFINITION##"] const frontendDefinition = _window["##BUDIBASE_FRONTEND_DEFINITION##"]
const uiFunctions = _window["##BUDIBASE_FRONTEND_FUNCTIONS##"] const uiFunctions = _window["##BUDIBASE_FRONTEND_FUNCTIONS##"]
const userFromStorage = _localStorage.getItem("budibase:user") // TODO: Update
const user = {}
const user = userFromStorage // const userFromStorage = _localStorage.getItem("budibase:user")
? JSON.parse(userFromStorage)
: {
name: "annonymous",
permissions: [],
isUser: false,
temp: false,
}
let { appRootPath } = frontendDefinition; // const user = userFromStorage
appRootPath = appRootPath === "" ? "" : "/" + trimSlash(appRootPath) // ? JSON.parse(userFromStorage)
// : {
// name: "annonymous",
// permissions: [],
// isUser: false,
// temp: false,
// }
// let { appRootPath } = frontendDefinition;
// appRootPath = appRootPath === "" ? "" : "/" + trimSlash(appRootPatl)
const componentLibraryModules = {}
const componentLibraryModules = {};
const libraries = frontendDefinition.libraries || [ const libraries = frontendDefinition.libraries || [
"@budibase/standard-components", "@budibase/standard-components",
"@budibase/materialdesign-components", "@budibase/materialdesign-components",
]; ]
for (let library of libraries) { for (let library of libraries) {
// fetch the JavaScript for the component libraries from the server // fetch the JavaScript for the component libraries from the server
componentLibraryModules[library] = await import( componentLibraryModules[library] = await import(
`/${frontendDefinition.appId}/componentlibrary?library=${encodeURI(library)}` `/${frontendDefinition.appId}/componentlibrary?library=${encodeURI(
); library
}; )}`
)
}
componentLibraryModules[builtinLibName] = builtins(_window) componentLibraryModules[builtinLibName] = builtins(_window)

View file

@ -1,5 +1,4 @@
import { split, last } from "lodash/fp" import { split, last } from "lodash/fp"
import { $ } from "../core/common"
import { prepareRenderComponent } from "./prepareRenderComponent" import { prepareRenderComponent } from "./prepareRenderComponent"
import { isScreenSlot } from "./builtinComponents" import { isScreenSlot } from "./builtinComponents"
import deepEqual from "deep-equal" import deepEqual from "deep-equal"
@ -77,7 +76,9 @@ export const attachChildren = initialiseOpts => (htmlElement, options) => {
} }
const splitName = fullname => { const splitName = fullname => {
const componentName = $(fullname, [split("/"), last]) const getComponentName = compose(last, split("/"))
const componentName = getComponentName(fullname)
const libName = fullname.substring( const libName = fullname.substring(
0, 0,

View file

@ -44,7 +44,7 @@ export const screenRouter = (screens, onScreenSelected, appRootPath) => {
storeInitial["##routeParams"] = params storeInitial["##routeParams"] = params
const store = writable(storeInitial) const store = writable(storeInitial)
const screenIndex = current !== -1 ? current : fallback; const screenIndex = current !== -1 ? current : fallback
onScreenSelected(screens[screenIndex], store, _url) onScreenSelected(screens[screenIndex], store, _url)

View file

@ -3,7 +3,6 @@ import { getState } from "./getState"
import { isArray, isUndefined } from "lodash/fp" import { isArray, isUndefined } from "lodash/fp"
import { createApi } from "../api" import { createApi } from "../api"
import { getNewChildRecordToState, getNewRecordToState } from "./coreHandlers"
export const EVENT_TYPE_MEMBER_NAME = "##eventHandlerType" export const EVENT_TYPE_MEMBER_NAME = "##eventHandlerType"
@ -16,8 +15,8 @@ export const eventHandlers = (store, rootPath, routeTo) => {
const setStateWithStore = (path, value) => setState(store, path, value) const setStateWithStore = (path, value) => setState(store, path, value)
let currentState let currentState
store.subscribe(s => { store.subscribe(state => {
currentState = s currentState = state
}) })
const api = createApi({ const api = createApi({
@ -33,17 +32,6 @@ export const eventHandlers = (store, rootPath, routeTo) => {
"Load Record": handler(["recordKey", "statePath"], api.loadRecord), "Load Record": handler(["recordKey", "statePath"], api.loadRecord),
"List Records": handler(["indexKey", "statePath"], api.listRecords), "List Records": handler(["indexKey", "statePath"], api.listRecords),
"Save Record": handler(["statePath"], api.saveRecord), "Save Record": handler(["statePath"], api.saveRecord),
// "Get New Child Record": handler(
// ["recordKey", "collectionName", "childRecordType", "statePath"],
// getNewChildRecordToState(coreApi, setStateWithStore)
// ),
// "Get New Record": handler(
// ["collectionKey", "childRecordType", "statePath"],
// getNewRecordToState(coreApi, setStateWithStore)
// ),
"Navigate To": handler(["url"], param => routeTo(param && param.url)), "Navigate To": handler(["url"], param => routeTo(param && param.url)),
Authenticate: handler(["username", "password"], api.authenticate), Authenticate: handler(["username", "password"], api.authenticate),

View file

@ -27,13 +27,7 @@ export const load = async (page, screens, url, appRootPath) => {
return { dom, app } return { dom, app }
} }
const addWindowGlobals = ( const addWindowGlobals = (window, page, screens, appRootPath, uiFunctions) => {
window,
page,
screens,
appRootPath,
uiFunctions
) => {
window["##BUDIBASE_FRONTEND_DEFINITION##"] = { window["##BUDIBASE_FRONTEND_DEFINITION##"] = {
page, page,
screens, screens,

View file

@ -4,4 +4,4 @@ export { default as BasicCard } from "./BasicCard.svelte"
export { default as CardBody } from "./CardBody.svelte" export { default as CardBody } from "./CardBody.svelte"
export { default as CardFooter } from "./CardFooter.svelte" export { default as CardFooter } from "./CardFooter.svelte"
export { default as CardHeader } from "./CardHeader.svelte" export { default as CardHeader } from "./CardHeader.svelte"
export { default as CardImage } from "./CardImage.svelte" export { default as CardImage } from "./CardImage.svelte"

View file

@ -1,10 +1,9 @@
export default class ClassBuilder { export default class ClassBuilder {
constructor(block, defaultIgnoreList) { constructor(block, defaultIgnoreList) {
this.block = `mdc-${block}` this.block = `mdc-${block}`
this.defaultIgnoreList = defaultIgnoreList //will be ignored when building custom classes this.defaultIgnoreList = defaultIgnoreList //will be ignored when building custom classes
} }
/* /*
handles both blocks and elementss (BEM MD Notation) handles both blocks and elementss (BEM MD Notation)
params = {elementName: string, props: {modifiers{}, customs:{}, extras: []}} params = {elementName: string, props: {modifiers{}, customs:{}, extras: []}}

View file

@ -1,17 +1,16 @@
import { writable } from "svelte/store" import { writable } from "svelte/store"
function createItemsStore(componentOnSelect, initialState = []) { function createItemsStore(componentOnSelect, initialState = []) {
const { subscribe, set, update } = writable(initialState) const { subscribe, set, update } = writable(initialState)
function addItem(item) {
update(items => {
return [...items, item]
})
if (componentOnSelect) {
componentOnSelect()
}
function addItem(item) {
update(items => {
return [...items, item]
})
if (componentOnSelect) {
componentOnSelect()
} }
}
function addSingleItem(item) { function addSingleItem(item) {
set([item]) set([item])

View file

@ -58,7 +58,7 @@
const isDate = /^\d{1,2}\/\d{1,2}\/\d{4}$/ const isDate = /^\d{1,2}\/\d{1,2}\/\d{4}$/
if (isDate.test(value)) { if (isDate.test(value)) {
const [year, month, day] = value.split("/").reverse() const [year, month, day] = value.split("/").reverse()
if (month > 0 && month <= 12 && (day > 0 && day <= 31)) { if (month > 0 && month <= 12 && day > 0 && day <= 31) {
date = new Date(year, month - 1, day) date = new Date(year, month - 1, day)
navDate = date navDate = date
openCalendar(true) openCalendar(true)

View file

@ -22,7 +22,14 @@ export { Menu } from "./Menu"
export { Select } from "./Select" export { Select } from "./Select"
export { DatePicker } from "./DatePicker" export { DatePicker } from "./DatePicker"
export { IconButton } from "./IconButton" export { IconButton } from "./IconButton"
export { Card, CardHeader, CardImage, CardBody, CardFooter, BasicCard } from "./Card" export {
Card,
CardHeader,
CardImage,
CardBody,
CardFooter,
BasicCard,
} from "./Card"
export { Dialog, DialogHeader, DialogContent, DialogActions } from "./Dialog" export { Dialog, DialogHeader, DialogContent, DialogActions } from "./Dialog"
export { Switch } from "./Switch" export { Switch } from "./Switch"
export { Slider } from "./Slider" export { Slider } from "./Slider"

View file

@ -1,40 +1,38 @@
const CouchDB = require("../../db"); const CouchDB = require("../../db")
const { const { getPackageForBuilder } = require("../../utilities/builder")
getPackageForBuilder,
} = require("../../utilities/builder")
exports.fetch = async function(ctx) { exports.fetch = async function(ctx) {
const clientDb = new CouchDB(`client-${ctx.params.clientId}`); const clientDb = new CouchDB(`client-${ctx.params.clientId}`)
const body = await clientDb.query("client/by_type", { const body = await clientDb.query("client/by_type", {
include_docs: true, include_docs: true,
key: ["app"] key: ["app"],
}); })
ctx.body = body.rows.map(row => row.doc); ctx.body = body.rows.map(row => row.doc)
}; }
exports.fetchAppPackage = async function(ctx) { exports.fetchAppPackage = async function(ctx) {
const clientDb = new CouchDB(`client-${ctx.params.clientId}`); const clientDb = new CouchDB(`client-${ctx.params.clientId}`)
const application = await clientDb.get(ctx.params.applicationId); const application = await clientDb.get(ctx.params.applicationId)
ctx.body = await getPackageForBuilder(ctx.config, application); ctx.body = await getPackageForBuilder(ctx.config, application)
} }
exports.create = async function(ctx) { exports.create = async function(ctx) {
const clientDb = new CouchDB(`client-${ctx.params.clientId}`); const clientDb = new CouchDB(`client-${ctx.params.clientId}`)
const { id, rev } = await clientDb.post({ const { id, rev } = await clientDb.post({
type: "app", type: "app",
instances: [], instances: [],
userInstanceMap: {}, userInstanceMap: {},
componentLibraries: [ componentLibraries: [
"@budibase/standard-components", "@budibase/standard-components",
"@budibase/materialdesign-components" "@budibase/materialdesign-components",
], ],
...ctx.request.body, ...ctx.request.body,
}); })
ctx.body = { ctx.body = {
id, id,
rev, rev,
message: `Application ${ctx.request.body.name} created successfully` message: `Application ${ctx.request.body.name} created successfully`,
} }
}; }

View file

@ -1,56 +1,57 @@
const jwt = require("jsonwebtoken"); const jwt = require("jsonwebtoken")
const CouchDB = require("../../db"); const CouchDB = require("../../db")
const bcrypt = require("../../utilities/bcrypt"); const bcrypt = require("../../utilities/bcrypt")
exports.authenticate = async ctx => { exports.authenticate = async ctx => {
const { username, password } = ctx.request.body; const { username, password } = ctx.request.body
if (!username) ctx.throw(400, "Username Required."); if (!username) ctx.throw(400, "Username Required.")
if (!password) ctx.throw(400, "Password Required"); if (!password) ctx.throw(400, "Password Required")
// TODO: Don't use this. It can't be relied on // TODO: Don't use this. It can't be relied on
const referer = ctx.request.headers.referer.split("/"); const referer = ctx.request.headers.referer.split("/")
const appId = referer[3]; const appId = referer[3]
// find the instance that the user is associated with // find the instance that the user is associated with
const db = new CouchDB(`client-${process.env.CLIENT_ID}`); const db = new CouchDB(`client-${process.env.CLIENT_ID}`)
const app = await db.get(appId); const app = await db.get(appId)
const instanceId = app.userInstanceMap[username]; const instanceId = app.userInstanceMap[username]
if (!instanceId) ctx.throw(500, "User is not associated with an instance of app", appId) if (!instanceId)
ctx.throw(500, "User is not associated with an instance of app", appId)
// Check the user exists in the instance DB by username // Check the user exists in the instance DB by username
const instanceDb = new CouchDB(instanceId); const instanceDb = new CouchDB(instanceId)
const { rows } = await instanceDb.query("database/by_username", { const { rows } = await instanceDb.query("database/by_username", {
include_docs: true, include_docs: true,
username username,
}); })
if (rows.length === 0) ctx.throw(500, `User does not exist.`); if (rows.length === 0) ctx.throw(500, `User does not exist.`)
const dbUser = rows[0].doc; const dbUser = rows[0].doc
// authenticate // authenticate
if (await bcrypt.compare(password, dbUser.password)) { if (await bcrypt.compare(password, dbUser.password)) {
const payload = { const payload = {
userId: dbUser._id, userId: dbUser._id,
accessLevel: "", accessLevel: "",
instanceId: instanceId instanceId: instanceId,
}; }
const token = jwt.sign(payload, ctx.config.jwtSecret, { const token = jwt.sign(payload, ctx.config.jwtSecret, {
expiresIn: "1 day" expiresIn: "1 day",
}); })
const ONE_DAY_FROM_NOW = new Date(Date.now() + (24 * 3600)) const ONE_DAY_FROM_NOW = new Date(Date.now() + 24 * 3600)
ctx.cookies.set('budibase:token', token, { expires: ONE_DAY_FROM_NOW }); ctx.cookies.set("budibase:token", token, { expires: ONE_DAY_FROM_NOW })
ctx.body = { ctx.body = {
token, token,
...dbUser ...dbUser,
}; }
} else { } else {
ctx.throw(401, "Invalid credentials."); ctx.throw(401, "Invalid credentials.")
} }
} }

View file

@ -1,36 +1,36 @@
const CouchDB = require("../../db"); const CouchDB = require("../../db")
exports.getClientId = async function(ctx) { exports.getClientId = async function(ctx) {
ctx.body = process.env.CLIENT_ID; ctx.body = process.env.CLIENT_ID
}; }
exports.create = async function(ctx) { exports.create = async function(ctx) {
const clientId = `client-${ctx.request.body.clientId}`; const clientId = `client-${ctx.request.body.clientId}`
const db = new CouchDB(clientId); const db = new CouchDB(clientId)
await db.put({ await db.put({
_id: "_design/client", _id: "_design/client",
views: { views: {
by_type: { by_type: {
map: function(doc) { map: function(doc) {
emit([doc.type], doc._id); emit([doc.type], doc._id)
}.toString() }.toString(),
} },
} },
}); })
ctx.body = { ctx.body = {
message: `Client Database ${clientId} successfully provisioned.` message: `Client Database ${clientId} successfully provisioned.`,
} }
}; }
exports.destroy = async function(ctx) { exports.destroy = async function(ctx) {
const dbId = `client-${ctx.params.clientId}`; const dbId = `client-${ctx.params.clientId}`
await new CouchDB(dbId).destroy(); await new CouchDB(dbId).destroy()
ctx.body = { ctx.body = {
status: 200, status: 200,
message: `Client Database ${dbId} successfully deleted.` message: `Client Database ${dbId} successfully deleted.`,
} }
}; }

View file

@ -1,40 +1,51 @@
const CouchDB = require("../../db"); const CouchDB = require("../../db")
const { homedir } = require("os"); const { homedir } = require("os")
const { resolve, join } = require("path"); const { resolve, join } = require("path")
const isDev = process.env.NODE_ENV !== "production"; const isDev = process.env.NODE_ENV !== "production"
exports.fetchAppComponentDefinitions = async function(ctx) { exports.fetchAppComponentDefinitions = async function(ctx) {
const db = new CouchDB(`client-${ctx.params.clientId}`); const db = new CouchDB(`client-${ctx.params.clientId}`)
const app = await db.get(ctx.params.appId) const app = await db.get(ctx.params.appId)
const componentDefinitions = app.componentLibraries.reduce((acc, componentLibrary) => { const componentDefinitions = app.componentLibraries.reduce(
(acc, componentLibrary) => {
let appDirectory = resolve(
homedir(),
".budibase",
ctx.params.appId,
"node_modules"
)
let appDirectory = resolve(homedir(), ".budibase", ctx.params.appId, "node_modules"); if (isDev) {
appDirectory = "/tmp/.budibase"
}
if (isDev) { const componentJson = require(join(
appDirectory = "/tmp/.budibase"; appDirectory,
} componentLibrary,
"components.json"
))
const componentJson = require(join(appDirectory, componentLibrary, "components.json")); const result = {}
const result = {}; // map over the components.json and add the library identifier as a key
// button -> @budibase/standard-components/button
for (key in componentJson) {
const fullComponentName = `${componentLibrary}/${key}`
result[fullComponentName] = {
_component: fullComponentName,
...componentJson[key],
}
}
// map over the components.json and add the library identifier as a key return {
// button -> @budibase/standard-components/button ...acc,
for (key in componentJson) { ...result,
const fullComponentName = `${componentLibrary}/${key}`; }
result[fullComponentName] = { },
_component: fullComponentName, {}
...componentJson[key] )
}
}
return { ctx.body = componentDefinitions
...acc, }
...result
};
}, {});
ctx.body = componentDefinitions;
};

View file

@ -1,61 +1,63 @@
const CouchDB = require("../../db"); const CouchDB = require("../../db")
exports.create = async function(ctx) { exports.create = async function(ctx) {
const instanceName = ctx.request.body.name; const instanceName = ctx.request.body.name
const { clientId, applicationId } = ctx.params; const { clientId, applicationId } = ctx.params
const db = new CouchDB(instanceName); const db = new CouchDB(instanceName)
await db.put({ await db.put({
_id: "_design/database", _id: "_design/database",
metadata: { metadata: {
clientId, clientId,
applicationId applicationId,
}, },
views: { views: {
by_username: { by_username: {
map: function(doc) { map: function(doc) {
if (doc.type === "user") { if (doc.type === "user") {
emit([doc.username], doc._id); emit([doc.username], doc._id)
} }
}.toString() }.toString(),
}, },
by_type: { by_type: {
map: function(doc) { map: function(doc) {
emit([doc.type], doc._id); emit([doc.type], doc._id)
}.toString() }.toString(),
} },
} },
}); })
// Add the new instance under the app clientDB // Add the new instance under the app clientDB
const clientDatabaseId = `client-${clientId}` const clientDatabaseId = `client-${clientId}`
const clientDb = new CouchDB(clientDatabaseId); const clientDb = new CouchDB(clientDatabaseId)
const budibaseApp = await clientDb.get(applicationId); const budibaseApp = await clientDb.get(applicationId)
const instance = { id: instanceName, name: instanceName }; const instance = { id: instanceName, name: instanceName }
budibaseApp.instances.push(instance); budibaseApp.instances.push(instance)
await clientDb.put(budibaseApp); await clientDb.put(budibaseApp)
ctx.body = { ctx.body = {
message: `Instance Database ${instanceName} successfully provisioned.`, message: `Instance Database ${instanceName} successfully provisioned.`,
status: 200, status: 200,
instance instance,
} }
}; }
exports.destroy = async function(ctx) { exports.destroy = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId); const db = new CouchDB(ctx.params.instanceId)
const designDoc = await db.get("_design/database"); const designDoc = await db.get("_design/database")
await db.destroy(); await db.destroy()
// remove instance from client application document // remove instance from client application document
const { metadata } = designDoc; const { metadata } = designDoc
const clientDb = new CouchDB(metadata.clientId); const clientDb = new CouchDB(metadata.clientId)
const budibaseApp = await clientDb.get(metadata.applicationId); const budibaseApp = await clientDb.get(metadata.applicationId)
budibaseApp.instances = budibaseApp.instances.filter(instance => instance !== ctx.params.instanceId); budibaseApp.instances = budibaseApp.instances.filter(
const updatedApp = await clientDb.put(budibaseApp); instance => instance !== ctx.params.instanceId
)
const updatedApp = await clientDb.put(budibaseApp)
ctx.body = { ctx.body = {
message: `Instance Database ${ctx.params.instanceId} successfully destroyed.`, message: `Instance Database ${ctx.params.instanceId} successfully destroyed.`,
status: 200 status: 200,
} }
}; }

View file

@ -1,22 +1,22 @@
const CouchDB = require("../../db"); const CouchDB = require("../../db")
exports.fetch = async function(ctx) { exports.fetch = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId); const db = new CouchDB(ctx.params.instanceId)
const body = await db.query("database/by_type", { const body = await db.query("database/by_type", {
include_docs: true, include_docs: true,
key: ["model"] key: ["model"],
}); })
ctx.body = body.rows.map(row => row.doc); ctx.body = body.rows.map(row => row.doc)
} }
exports.create = async function(ctx) { exports.create = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId); const db = new CouchDB(ctx.params.instanceId)
const newModel = await db.post({ const newModel = await db.post({
type: "model", type: "model",
...ctx.request.body ...ctx.request.body,
}); })
const designDoc = await db.get("_design/database"); const designDoc = await db.get("_design/database")
designDoc.views = { designDoc.views = {
...designDoc.views, ...designDoc.views,
[`all_${newModel.id}`]: { [`all_${newModel.id}`]: {
@ -24,10 +24,10 @@ exports.create = async function(ctx) {
if (doc.modelId === "${newModel.id}") { if (doc.modelId === "${newModel.id}") {
emit(doc[doc.key], doc._id); emit(doc[doc.key], doc._id);
} }
}` }`,
} },
}; }
await db.put(designDoc); await db.put(designDoc)
ctx.body = { ctx.body = {
message: `Model ${ctx.request.body.name} created successfully.`, message: `Model ${ctx.request.body.name} created successfully.`,
@ -35,33 +35,32 @@ exports.create = async function(ctx) {
model: { model: {
_id: newModel.id, _id: newModel.id,
_rev: newModel.rev, _rev: newModel.rev,
...ctx.request.body ...ctx.request.body,
} },
} }
} }
exports.update = async function(ctx) { exports.update = async function(ctx) {}
}
exports.destroy = async function(ctx) { exports.destroy = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId) const db = new CouchDB(ctx.params.instanceId)
const model = await db.remove(ctx.params.modelId, ctx.params.revId); const model = await db.remove(ctx.params.modelId, ctx.params.revId)
const modelViewId = `all_${model.id}` const modelViewId = `all_${model.id}`
// Delete all records for that model // Delete all records for that model
const records = await db.query(`database/${modelViewId}`); const records = await db.query(`database/${modelViewId}`)
await db.bulkDocs( await db.bulkDocs(
records.rows.map(record => ({ id: record.id, _deleted: true })) records.rows.map(record => ({ id: record.id, _deleted: true }))
); )
// delete the "all" view // delete the "all" view
const designDoc = await db.get("_design/database"); const designDoc = await db.get("_design/database")
delete designDoc.views[modelViewId]; delete designDoc.views[modelViewId]
await db.put(designDoc); await db.put(designDoc)
ctx.body = { ctx.body = {
message: `Model ${model.id} deleted.`, message: `Model ${model.id} deleted.`,
status: 200 status: 200,
} }
} }

View file

@ -1,39 +1,39 @@
const CouchDB = require("../../db"); const CouchDB = require("../../db")
const Ajv = require("ajv"); const Ajv = require("ajv")
const ajv = new Ajv(); const ajv = new Ajv()
exports.save = async function(ctx) { exports.save = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId); const db = new CouchDB(ctx.params.instanceId)
const record = ctx.request.body; const record = ctx.request.body
// validation with ajv // validation with ajv
const model = await db.get(record.modelId) const model = await db.get(record.modelId)
const validate = ajv.compile({ const validate = ajv.compile({
properties: model.schema properties: model.schema,
}); })
const valid = validate(record) const valid = validate(record)
if (!valid) { if (!valid) {
ctx.status = 400 ctx.status = 400
ctx.body = { ctx.body = {
status: 400, status: 400,
errors: validate.errors errors: validate.errors,
}; }
return; return
} }
const existingRecord = record._id && await db.get(record._id); const existingRecord = record._id && (await db.get(record._id))
if (existingRecord) { if (existingRecord) {
const response = await db.put({ ...record, _id: existingRecord._id }); const response = await db.put({ ...record, _id: existingRecord._id })
ctx.body = { ctx.body = {
message: `${model.name} updated successfully.`, message: `${model.name} updated successfully.`,
status: 200, status: 200,
record: { record: {
...record, ...record,
...response ...response,
} },
} }
return return
} }
@ -52,13 +52,10 @@ exports.save = async function(ctx) {
exports.fetch = async function(ctx) { exports.fetch = async function(ctx) {
const db = new CouchDB(ctx.params.instanceId) const db = new CouchDB(ctx.params.instanceId)
const response = await db.query( const response = await db.query(`database/${ctx.params.viewName}`, {
`database/${ctx.params.viewName}`, include_docs: true,
{ })
include_docs: true ctx.body = response.rows.map(row => row.doc)
}
)
ctx.body = response.rows.map(row => row.doc);
} }
exports.find = async function(ctx) { exports.find = async function(ctx) {
@ -67,7 +64,7 @@ exports.find = async function(ctx) {
} }
exports.destroy = async function(ctx) { exports.destroy = async function(ctx) {
const databaseId = ctx.params.instanceId; const databaseId = ctx.params.instanceId
const db = new CouchDB(databaseId) const db = new CouchDB(databaseId)
ctx.body = await db.remove(ctx.params.recordId, ctx.params.revId); ctx.body = await db.remove(ctx.params.recordId, ctx.params.revId)
}; }

View file

@ -1,6 +1,6 @@
const send = require("koa-send"); const send = require("koa-send")
const { resolve, join } = require("path") const { resolve, join } = require("path")
const { homedir } = require("os"); const { homedir } = require("os")
exports.serveBuilder = async function(ctx) { exports.serveBuilder = async function(ctx) {
let builderPath = resolve(process.cwd(), "builder") let builderPath = resolve(process.cwd(), "builder")
@ -12,12 +12,12 @@ exports.serveApp = async function(ctx) {
// TODO: update homedir stuff to wherever budi is run // TODO: update homedir stuff to wherever budi is run
// default to homedir // default to homedir
const appPath = resolve( const appPath = resolve(
homedir(), homedir(),
".budibase", ".budibase",
ctx.params.appId, ctx.params.appId,
"public", "public",
ctx.isAuthenticated ? "main" : "unauthenticated" ctx.isAuthenticated ? "main" : "unauthenticated"
); )
await send(ctx, ctx.file, { root: ctx.devPath || appPath }) await send(ctx, ctx.file, { root: ctx.devPath || appPath })
} }
@ -26,21 +26,21 @@ exports.serveComponentLibrary = async function(ctx) {
// TODO: update homedir stuff to wherever budi is run // TODO: update homedir stuff to wherever budi is run
// default to homedir // default to homedir
let componentLibraryPath = resolve( let componentLibraryPath = resolve(
homedir(), homedir(),
".budibase", ".budibase",
ctx.params.appId, ctx.params.appId,
"node_modules", "node_modules",
decodeURI(ctx.query.library), decodeURI(ctx.query.library),
"dist" "dist"
); )
if (ctx.isDev) { if (ctx.isDev) {
componentLibraryPath = join( componentLibraryPath = join(
"/tmp", "/tmp",
".budibase", ".budibase",
decodeURI(ctx.query.library), decodeURI(ctx.query.library),
"dist" "dist"
); )
} }
await send(ctx, "/index.js", { root: componentLibraryPath }) await send(ctx, "/index.js", { root: componentLibraryPath })

View file

@ -1,57 +1,57 @@
const CouchDB = require("../../db"); const CouchDB = require("../../db")
const bcrypt = require("../../utilities/bcrypt"); const bcrypt = require("../../utilities/bcrypt")
exports.fetch = async function(ctx) { exports.fetch = async function(ctx) {
const database = new CouchDB(ctx.params.instanceId); const database = new CouchDB(ctx.params.instanceId)
const data = await database.query("database/by_type", { const data = await database.query("database/by_type", {
include_docs: true, include_docs: true,
key: ["user"] key: ["user"],
}); })
ctx.body = data.rows.map(row => row.doc); ctx.body = data.rows.map(row => row.doc)
}; }
exports.create = async function(ctx) { exports.create = async function(ctx) {
const database = new CouchDB(ctx.params.instanceId); const database = new CouchDB(ctx.params.instanceId)
const { username, password, name } = ctx.request.body; const { username, password, name } = ctx.request.body
if (!username || !password) ctx.throw(400, "Username and Password Required."); if (!username || !password) ctx.throw(400, "Username and Password Required.")
const response = await database.post({ const response = await database.post({
username, username,
password: await bcrypt.hash(password), password: await bcrypt.hash(password),
name, name,
type: "user" type: "user",
}); })
// the clientDB needs to store a map of users against the app // the clientDB needs to store a map of users against the app
const clientDb = new CouchDB(`client-${process.env.CLIENT_ID}`); const clientDb = new CouchDB(`client-${process.env.CLIENT_ID}`)
const app = await clientDb.get(ctx.params.appId); const app = await clientDb.get(ctx.params.appId)
app.userInstanceMap = { app.userInstanceMap = {
...app.userInstanceMap, ...app.userInstanceMap,
[username]: ctx.params.instanceId [username]: ctx.params.instanceId,
} }
await clientDb.put(app); await clientDb.put(app)
ctx.body = { ctx.body = {
user: { user: {
id: response.id, id: response.id,
rev: response.rev, rev: response.rev,
username, username,
name name,
}, },
message: `User created successfully.`, message: `User created successfully.`,
status: 200 status: 200,
} }
}; }
exports.destroy = async function(ctx) { exports.destroy = async function(ctx) {
const database = new CouchDB(ctx.params.instanceId); const database = new CouchDB(ctx.params.instanceId)
const response = await database.destroy(ctx.params.userId) const response = await database.destroy(ctx.params.userId)
ctx.body = { ctx.body = {
...response, ...response,
message: `User deleted.`, message: `User deleted.`,
status: 200 status: 200,
} }
}; }

View file

@ -1,19 +1,21 @@
const CouchDB = require("../../db"); const CouchDB = require("../../db")
const controller = { const controller = {
query: async ctx => { query: async ctx => {},
},
fetch: async ctx => { fetch: async ctx => {
const db = new CouchDB(ctx.params.instanceId); const db = new CouchDB(ctx.params.instanceId)
const designDoc = await db.get("_design/database"); const designDoc = await db.get("_design/database")
const response = []; const response = []
for (let name in designDoc.views) { for (let name in designDoc.views) {
if (!name.startsWith("all") && name !== "by_type" && name !== "by_username") { if (
!name.startsWith("all") &&
name !== "by_type" &&
name !== "by_username"
) {
response.push({ response.push({
name, name,
...designDoc.views[name] ...designDoc.views[name],
}) })
} }
} }
@ -21,29 +23,29 @@ const controller = {
ctx.body = response ctx.body = response
}, },
create: async ctx => { create: async ctx => {
const db = new CouchDB(ctx.params.instanceId); const db = new CouchDB(ctx.params.instanceId)
const { name, ...viewDefinition } = ctx.request.body; const { name, ...viewDefinition } = ctx.request.body
const designDoc = await db.get("_design/database"); const designDoc = await db.get("_design/database")
designDoc.views = { designDoc.views = {
...designDoc.views, ...designDoc.views,
[name]: viewDefinition [name]: viewDefinition,
}; }
const newView = await db.put(designDoc); const newView = await db.put(designDoc)
ctx.body = { ctx.body = {
view: { view: {
...ctx.request.body, ...ctx.request.body,
...newView ...newView,
}, },
message: `View ${name} created successfully.`, message: `View ${name} created successfully.`,
status: 200, status: 200,
} }
}, },
destroy: async ctx => { destroy: async ctx => {
const db = new CouchDB(ctx.params.instanceId); const db = new CouchDB(ctx.params.instanceId)
ctx.body = await db.destroy(ctx.params.userId) ctx.body = await db.destroy(ctx.params.userId)
} },
} }
module.exports = controller; module.exports = controller

View file

@ -1,7 +1,7 @@
const Router = require("@koa/router") const Router = require("@koa/router")
const authenticated = require("../middleware/authenticated"); const authenticated = require("../middleware/authenticated")
const compress = require("koa-compress"); const compress = require("koa-compress")
const zlib = require("zlib"); const zlib = require("zlib")
const { resolve } = require("path") const { resolve } = require("path")
const { homedir } = require("os") const { homedir } = require("os")
const { const {
@ -15,83 +15,85 @@ const {
modelRoutes, modelRoutes,
viewRoutes, viewRoutes,
staticRoutes, staticRoutes,
componentRoutes componentRoutes,
} = require("./routes"); } = require("./routes")
module.exports = app => { module.exports = app => {
const router = new Router() const router = new Router()
router router
.use(compress({ .use(
threshold: 2048, compress({
gzip: { threshold: 2048,
flush: zlib.Z_SYNC_FLUSH gzip: {
}, flush: zlib.Z_SYNC_FLUSH,
deflate: { },
flush: zlib.Z_SYNC_FLUSH, deflate: {
} flush: zlib.Z_SYNC_FLUSH,
})) },
.use(async (ctx, next) => { })
)
.use(async (ctx, next) => {
// TODO: temp dev middleware // TODO: temp dev middleware
ctx.config = { ctx.config = {
latestPackagesFolder: resolve(homedir(), ".budibase"), latestPackagesFolder: resolve(homedir(), ".budibase"),
jwtSecret: "foo" jwtSecret: "foo",
} }
ctx.isDev = process.env.NODE_ENV !== "production"; ctx.isDev = process.env.NODE_ENV !== "production"
await next(); await next()
}) })
.use(authenticated); .use(authenticated)
// error handling middleware // error handling middleware
router.use(async (ctx, next) => { router.use(async (ctx, next) => {
try { try {
await next(); await next()
} catch (err) { } catch (err) {
console.trace(err); console.trace(err)
ctx.status = err.status || err.statusCode || 500; ctx.status = err.status || err.statusCode || 500
ctx.body = { ctx.body = {
message: err.message, message: err.message,
status: ctx.status status: ctx.status,
}; }
} }
}); })
router.use(authRoutes.routes()); router.use(authRoutes.routes())
router.use(authRoutes.allowedMethods()); router.use(authRoutes.allowedMethods())
// authenticated routes // authenticated routes
router.use(viewRoutes.routes()); router.use(viewRoutes.routes())
router.use(viewRoutes.allowedMethods()); router.use(viewRoutes.allowedMethods())
router.use(modelRoutes.routes()); router.use(modelRoutes.routes())
router.use(modelRoutes.allowedMethods()); router.use(modelRoutes.allowedMethods())
router.use(userRoutes.routes()); router.use(userRoutes.routes())
router.use(userRoutes.allowedMethods()); router.use(userRoutes.allowedMethods())
router.use(recordRoutes.routes()); router.use(recordRoutes.routes())
router.use(recordRoutes.allowedMethods()); router.use(recordRoutes.allowedMethods())
router.use(instanceRoutes.routes()); router.use(instanceRoutes.routes())
router.use(instanceRoutes.allowedMethods()); router.use(instanceRoutes.allowedMethods())
// end auth routes // end auth routes
router.use(pageRoutes.routes()); router.use(pageRoutes.routes())
router.use(pageRoutes.allowedMethods()); router.use(pageRoutes.allowedMethods())
router.use(applicationRoutes.routes()); router.use(applicationRoutes.routes())
router.use(applicationRoutes.allowedMethods()); router.use(applicationRoutes.allowedMethods())
router.use(componentRoutes.routes()); router.use(componentRoutes.routes())
router.use(componentRoutes.allowedMethods()); router.use(componentRoutes.allowedMethods())
router.use(clientRoutes.routes()); router.use(clientRoutes.routes())
router.use(clientRoutes.allowedMethods()); router.use(clientRoutes.allowedMethods())
router.use(staticRoutes.routes()); router.use(staticRoutes.routes())
router.use(staticRoutes.allowedMethods()); router.use(staticRoutes.allowedMethods())
router.redirect("/", "/_builder"); router.redirect("/", "/_builder")
return router return router
} }

View file

@ -1,11 +1,11 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/application"); const controller = require("../controllers/application")
const router = Router(); const router = Router()
router router
.get("/api/:clientId/applications", controller.fetch) .get("/api/:clientId/applications", controller.fetch)
.get("/api/:clientId/:applicationId/appPackage", controller.fetchAppPackage) .get("/api/:clientId/:applicationId/appPackage", controller.fetchAppPackage)
.post("/api/:clientId/applications", controller.create); .post("/api/:clientId/applications", controller.create)
module.exports = router; module.exports = router

View file

@ -1,9 +1,8 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/auth"); const controller = require("../controllers/auth")
const router = Router(); const router = Router()
router router.post("/api/authenticate", controller.authenticate)
.post("/api/authenticate", controller.authenticate);
module.exports = router; module.exports = router

View file

@ -1,11 +1,11 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/client"); const controller = require("../controllers/client")
const router = Router(); const router = Router()
router router
.get("/api/client/id", controller.getClientId) .get("/api/client/id", controller.getClientId)
.post("/api/clients", controller.create) .post("/api/clients", controller.create)
.delete("/api/clients/:clientId", controller.destroy); .delete("/api/clients/:clientId", controller.destroy)
module.exports = router; module.exports = router

View file

@ -1,9 +1,11 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/component"); const controller = require("../controllers/component")
const router = Router(); const router = Router()
router router.get(
.get("/:clientId/:appId/components/definitions", controller.fetchAppComponentDefinitions); "/:clientId/:appId/components/definitions",
controller.fetchAppComponentDefinitions
)
module.exports = router; module.exports = router

View file

@ -1,14 +1,14 @@
const authRoutes = require("./auth"); const authRoutes = require("./auth")
const pageRoutes = require("./pages"); const pageRoutes = require("./pages")
const userRoutes = require("./user"); const userRoutes = require("./user")
const recordRoutes = require("./record"); const recordRoutes = require("./record")
const instanceRoutes = require("./instance"); const instanceRoutes = require("./instance")
const clientRoutes = require("./client"); const clientRoutes = require("./client")
const applicationRoutes = require("./application"); const applicationRoutes = require("./application")
const modelRoutes = require("./model"); const modelRoutes = require("./model")
const viewRoutes = require("./view"); const viewRoutes = require("./view")
const staticRoutes = require("./static"); const staticRoutes = require("./static")
const componentRoutes = require("./component"); const componentRoutes = require("./component")
module.exports = { module.exports = {
authRoutes, authRoutes,
@ -21,5 +21,5 @@ module.exports = {
modelRoutes, modelRoutes,
viewRoutes, viewRoutes,
staticRoutes, staticRoutes,
componentRoutes componentRoutes,
}; }

View file

@ -1,10 +1,10 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/instance"); const controller = require("../controllers/instance")
const router = Router(); const router = Router()
router router
.post("/api/:clientId/:applicationId/instances", controller.create) .post("/api/:clientId/:applicationId/instances", controller.create)
.delete("/api/instances/:instanceId", controller.destroy); .delete("/api/instances/:instanceId", controller.destroy)
module.exports = router; module.exports = router

View file

@ -1,13 +1,12 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/model"); const controller = require("../controllers/model")
const router = Router(); const router = Router()
router router
.get("/api/:instanceId/models", controller.fetch) .get("/api/:instanceId/models", controller.fetch)
.post("/api/:instanceId/models", controller.create) .post("/api/:instanceId/models", controller.create)
// .patch("/api/:instanceId/models", controller.update) // .patch("/api/:instanceId/models", controller.update)
.delete("/api/:instanceId/models/:modelId/:revId", controller.destroy); .delete("/api/:instanceId/models/:modelId/:revId", controller.destroy)
module.exports = router
module.exports = router;

View file

@ -1,14 +1,13 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const StatusCodes = require("../../utilities/statusCodes") const StatusCodes = require("../../utilities/statusCodes")
const { const {
listScreens, listScreens,
saveScreen, saveScreen,
buildPage, buildPage,
renameScreen, renameScreen,
deleteScreen deleteScreen,
} = require("../../utilities/builder") } = require("../../utilities/builder")
const router = Router() const router = Router()
router.post("/_builder/api/:appId/pages/:pageName", async ctx => { router.post("/_builder/api/:appId/pages/:pageName", async ctx => {
@ -30,44 +29,41 @@ router.get("/_builder/api/:appId/pages/:pagename/screens", async ctx => {
ctx.response.status = StatusCodes.OK ctx.response.status = StatusCodes.OK
}) })
router router.post("/_builder/api/:appId/pages/:pagename/screen", async ctx => {
.post("/_builder/api/:appId/pages/:pagename/screen", async ctx => { ctx.body = await saveScreen(
ctx.body = await saveScreen( ctx.config,
ctx.config, ctx.params.appId,
ctx.params.appId, ctx.params.pagename,
ctx.params.pagename, ctx.request.body
ctx.request.body )
) ctx.response.status = StatusCodes.OK
ctx.response.status = StatusCodes.OK
})
router
.patch("/_builder/api/:appname/pages/:pagename/screen", async ctx => {
await renameScreen(
ctx.config,
ctx.params.appname,
ctx.params.pagename,
ctx.request.body.oldname,
ctx.request.body.newname
)
ctx.response.status = StatusCodes.OK
})
router
.delete("/_builder/api/:appname/pages/:pagename/screen/*", async ctx => {
const name = ctx.request.path.replace(
`/_builder/api/${ctx.params.appname}/pages/${ctx.params.pagename}/screen/`,
""
)
await deleteScreen(
ctx.config,
ctx.params.appname,
ctx.params.pagename,
decodeURI(name)
)
ctx.response.status = StatusCodes.OK
}) })
module.exports = router router.patch("/_builder/api/:appname/pages/:pagename/screen", async ctx => {
await renameScreen(
ctx.config,
ctx.params.appname,
ctx.params.pagename,
ctx.request.body.oldname,
ctx.request.body.newname
)
ctx.response.status = StatusCodes.OK
})
router.delete("/_builder/api/:appname/pages/:pagename/screen/*", async ctx => {
const name = ctx.request.path.replace(
`/_builder/api/${ctx.params.appname}/pages/${ctx.params.pagename}/screen/`,
""
)
await deleteScreen(
ctx.config,
ctx.params.appname,
ctx.params.pagename,
decodeURI(name)
)
ctx.response.status = StatusCodes.OK
})
module.exports = router

View file

@ -1,12 +1,11 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/screen"); const controller = require("../controllers/screen")
const router = Router(); const router = Router()
router router
.get("/api/:instanceId/screens", controller.fetch) .get("/api/:instanceId/screens", controller.fetch)
.post("/api/:instanceId/screens", controller.save) .post("/api/:instanceId/screens", controller.save)
.delete("/api/:instanceId/:screenId/:revId", controller.destroy); .delete("/api/:instanceId/:screenId/:revId", controller.destroy)
module.exports = router
module.exports = router;

View file

@ -1,21 +1,21 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/static"); const controller = require("../controllers/static")
const router = Router(); const router = Router()
router router
.param("file", async (file, ctx, next) => { .param("file", async (file, ctx, next) => {
ctx.file = file && file.includes(".") ? file : "index.html"; ctx.file = file && file.includes(".") ? file : "index.html"
// Serving the client library from your local dir in dev // Serving the client library from your local dir in dev
if (ctx.isDev && ctx.file.startsWith("budibase-client")) { if (ctx.isDev && ctx.file.startsWith("budibase-client")) {
ctx.devPath = "/tmp/.budibase"; ctx.devPath = "/tmp/.budibase"
} }
await next(); await next()
}) })
.get("/_builder/:file*", controller.serveBuilder) .get("/_builder/:file*", controller.serveBuilder)
.get("/:appId/componentlibrary", controller.serveComponentLibrary) .get("/:appId/componentlibrary", controller.serveComponentLibrary)
.get("/:appId/:file*", controller.serveApp); .get("/:appId/:file*", controller.serveApp)
module.exports = router; module.exports = router

View file

@ -1,20 +1,20 @@
const CouchDB = require("../../../db"); const CouchDB = require("../../../db")
const CLIENT_DB_ID = "client-testing"; const CLIENT_DB_ID = "client-testing"
const TEST_APP_ID = "test-app"; const TEST_APP_ID = "test-app"
exports.createModel = async (instanceId, model) => { exports.createModel = async (instanceId, model) => {
model = model || { model = model || {
"name": "TestModel", name: "TestModel",
"type": "model", type: "model",
"key": "name", key: "name",
"schema": { schema: {
"name": { "type": "string" } name: { type: "string" },
} },
} }
const db = new CouchDB(instanceId); const db = new CouchDB(instanceId)
const response = await db.post(model); const response = await db.post(model)
const designDoc = await db.get("_design/database"); const designDoc = await db.get("_design/database")
designDoc.views = { designDoc.views = {
...designDoc.views, ...designDoc.views,
[`all_${response.id}`]: { [`all_${response.id}`]: {
@ -22,66 +22,66 @@ exports.createModel = async (instanceId, model) => {
if (doc.modelId === "${response.id}") { if (doc.modelId === "${response.id}") {
emit(doc[doc.key], doc._id); emit(doc[doc.key], doc._id);
} }
}` }`,
} },
}; }
await db.put(designDoc); await db.put(designDoc)
return { return {
...response, ...response,
...model ...model,
}; }
} }
exports.createClientDatabase = async () => { exports.createClientDatabase = async () => {
const db = new CouchDB(CLIENT_DB_ID); const db = new CouchDB(CLIENT_DB_ID)
await db.put({ await db.put({
_id: "_design/client", _id: "_design/client",
views: { views: {
by_type: { by_type: {
map: function(doc) { map: function(doc) {
emit([doc.type], doc._id); emit([doc.type], doc._id)
} },
}.toString() }.toString(),
} },
}); })
await db.put({ await db.put({
_id: TEST_APP_ID, _id: TEST_APP_ID,
type: "app", type: "app",
instances: [] instances: [],
}); })
return db; return db
} }
exports.destroyClientDatabase = async () => new CouchDB(CLIENT_DB_ID).destroy(); exports.destroyClientDatabase = async () => new CouchDB(CLIENT_DB_ID).destroy()
exports.createInstanceDatabase = async instanceId => { exports.createInstanceDatabase = async instanceId => {
const db = new CouchDB(instanceId); const db = new CouchDB(instanceId)
await db.put({ await db.put({
_id: "_design/database", _id: "_design/database",
metadata: { metadata: {
clientId: CLIENT_DB_ID, clientId: CLIENT_DB_ID,
applicationId: TEST_APP_ID applicationId: TEST_APP_ID,
}, },
views: { views: {
by_type: { by_type: {
map: function(doc) { map: function(doc) {
emit([doc.type], doc._id); emit([doc.type], doc._id)
}.toString() }.toString(),
} },
} },
}); })
return db; return db
} }
exports.insertDocument = async (databaseId, document) => { exports.insertDocument = async (databaseId, document) => {
const { id, ...documentFields } = document; const { id, ...documentFields } = document
await new CouchDB(databaseId).put({ _id: id, ...documentFields }); await new CouchDB(databaseId).put({ _id: id, ...documentFields })
} }
exports.createSchema = async (request, instanceId, schema) => { exports.createSchema = async (request, instanceId, schema) => {

View file

@ -1,11 +1,11 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/user"); const controller = require("../controllers/user")
const router = Router(); const router = Router()
router router
.get("/api/:instanceId/users", controller.fetch) .get("/api/:instanceId/users", controller.fetch)
.post("/api/:appId/:instanceId/users", controller.create) .post("/api/:appId/:instanceId/users", controller.create)
.delete("/api/:instanceId/users/:userId", controller.destroy); .delete("/api/:instanceId/users/:userId", controller.destroy)
module.exports = router; module.exports = router

View file

@ -1,12 +1,12 @@
const Router = require("@koa/router"); const Router = require("@koa/router")
const controller = require("../controllers/view"); const controller = require("../controllers/view")
const router = Router(); const router = Router()
router router
.get("/api/:instanceId/views", controller.fetch) .get("/api/:instanceId/views", controller.fetch)
// .patch("/api/:databaseId/views", controller.update); // .patch("/api/:databaseId/views", controller.update);
// .delete("/api/:instanceId/views/:viewId/:revId", controller.destroy); // .delete("/api/:instanceId/views/:viewId/:revId", controller.destroy);
.post("/api/:instanceId/views", controller.create); .post("/api/:instanceId/views", controller.create)
module.exports = router; module.exports = router

View file

@ -1,5 +1,5 @@
const Koa = require("koa") const Koa = require("koa")
const logger = require("koa-logger"); const logger = require("koa-logger")
const router = require("./api") const router = require("./api")
const koaBody = require("koa-body") const koaBody = require("koa-body")
const app = new Koa() const app = new Koa()

View file

@ -1,17 +1,17 @@
const PouchDB = require("pouchdb") const PouchDB = require("pouchdb")
const allDbs = require("pouchdb-all-dbs") const allDbs = require("pouchdb-all-dbs")
const os = require("os"); const os = require("os")
const path = require("path"); const path = require("path")
const BUDIBASE_DIR = path.join(os.homedir(), ".budibase"); const BUDIBASE_DIR = path.join(os.homedir(), ".budibase")
const COUCH_DB_URL = process.env.COUCH_DB_URL || `leveldb://${BUDIBASE_DIR}/`; const COUCH_DB_URL = process.env.COUCH_DB_URL || `leveldb://${BUDIBASE_DIR}/`
const DATABASE_TYPE = process.env.DATABASE_TYPE || "couch"; const DATABASE_TYPE = process.env.DATABASE_TYPE || "couch"
const Pouch = PouchDB.defaults({ const Pouch = PouchDB.defaults({
prefix: COUCH_DB_URL, prefix: COUCH_DB_URL,
}); })
allDbs(Pouch); allDbs(Pouch)
module.exports = Pouch; module.exports = Pouch

View file

@ -8,6 +8,6 @@ module.exports = async db => {
}`, }`,
}, },
}, },
}); })
console.log(doc); console.log(doc)
} }

View file

@ -8,4 +8,4 @@ async function startServer() {
}) })
} }
startServer(); startServer()

View file

@ -1,21 +1,21 @@
const jwt = require("jsonwebtoken"); const jwt = require("jsonwebtoken")
module.exports = async (ctx, next) => { module.exports = async (ctx, next) => {
const token = ctx.cookies.get("budibase:token"); const token = ctx.cookies.get("budibase:token")
console.log("TOKEN", token); console.log("TOKEN", token)
if (!token) { if (!token) {
ctx.isAuthenticated = false ctx.isAuthenticated = false
await next(); await next()
return; return
};
try {
ctx.jwtPayload = jwt.verify(token, ctx.config.jwtSecret);
ctx.isAuthenticated = true;
} catch (err) {
ctx.throw(err.status || 403, err.text);
} }
await next(); try {
}; ctx.jwtPayload = jwt.verify(token, ctx.config.jwtSecret)
ctx.isAuthenticated = true
} catch (err) {
ctx.throw(err.status || 403, err.text)
}
await next()
}

View file

@ -1,6 +1,6 @@
const session = require("koa-session") const session = require("koa-session")
module.exports = (app) => { module.exports = app => {
const sessionConfig = { const sessionConfig = {
key: "budi:sess" /** (string) cookie key (default is koa:sess) */, key: "budi:sess" /** (string) cookie key (default is koa:sess) */,
/** (number || 'session') maxAge in ms (default is 1 days) */ /** (number || 'session') maxAge in ms (default is 1 days) */

View file

@ -1,11 +1,12 @@
const bcrypt = require("bcryptjs"); const bcrypt = require("bcryptjs")
const SALT_ROUNDS = process.env.SALT_ROUNDS || 10; const SALT_ROUNDS = process.env.SALT_ROUNDS || 10
exports.hash = async data => { exports.hash = async data => {
const salt = await bcrypt.genSalt(SALT_ROUNDS); const salt = await bcrypt.genSalt(SALT_ROUNDS)
const result = await bcrypt.hash(data, salt); const result = await bcrypt.hash(data, salt)
return result; return result
}; }
exports.compare = async (data, encrypted) => await bcrypt.compare(data, encrypted); exports.compare = async (data, encrypted) =>
await bcrypt.compare(data, encrypted)

View file

@ -22,7 +22,7 @@ const getAppDefinition = async appPath =>
await readJSON(`${appPath}/appDefinition.json`) await readJSON(`${appPath}/appDefinition.json`)
module.exports.getPackageForBuilder = async (config, application) => { module.exports.getPackageForBuilder = async (config, application) => {
const appPath = resolve(config.latestPackagesFolder, application._id); const appPath = resolve(config.latestPackagesFolder, application._id)
const pages = await getPages(appPath) const pages = await getPages(appPath)
@ -31,7 +31,7 @@ module.exports.getPackageForBuilder = async (config, application) => {
application, application,
clientId: process.env.CLIENT_ID clientId: process.env.CLIENT_ID,
} }
} }
@ -96,4 +96,4 @@ module.exports.savePage = async (config, appname, pagename, page) => {
}) })
const appDefinition = await getAppDefinition(appPath) const appDefinition = await getAppDefinition(appPath)
await buildPage(config, appname, appDefinition, pagename, page) await buildPage(config, appname, appDefinition, pagename, page)
} }

View file

@ -189,20 +189,6 @@
lodash "^4.17.13" lodash "^4.17.13"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@budibase/client@^0.0.32":
version "0.0.32"
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.32.tgz#76d9f147563a0bf939eae7f32ce75b2a527ba496"
integrity sha512-jmCCLn0CUoQbL6h623S5IqK6+GYLqX3WzUTZInSb1SCBOM3pI0eLP5HwTR6s7r42SfD0v9jTWRdyTnHiElNj8A==
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.32": "@budibase/core@^0.0.32":
version "0.0.32" version "0.0.32"
resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.32.tgz#c5d9ab869c5e9596a1ac337aaf041e795b1cc7fa" resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.32.tgz#c5d9ab869c5e9596a1ac337aaf041e795b1cc7fa"
@ -690,11 +676,6 @@ array-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
array-filter@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83"
integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=
array-unique@^0.3.2: array-unique@^0.3.2:
version "0.3.2" version "0.3.2"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
@ -747,13 +728,6 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5"
integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==
dependencies:
array-filter "^1.0.0"
aws-sign2@~0.7.0: aws-sign2@~0.7.0:
version "0.7.0" version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
@ -1342,26 +1316,6 @@ decompress-response@^3.3.0:
dependencies: dependencies:
mimic-response "^1.0.0" mimic-response "^1.0.0"
deep-equal@^2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.3.tgz#cad1c15277ad78a5c01c49c2dee0f54de8a6a7b0"
integrity sha512-Spqdl4H+ky45I9ByyJtXteOm9CaIrPmnIPmOhrkKGNYWeDgCvJ8jNYVCTjChxW4FqGuZnLHADc8EKRMX6+CgvA==
dependencies:
es-abstract "^1.17.5"
es-get-iterator "^1.1.0"
is-arguments "^1.0.4"
is-date-object "^1.0.2"
is-regex "^1.0.5"
isarray "^2.0.5"
object-is "^1.1.2"
object-keys "^1.1.1"
object.assign "^4.1.0"
regexp.prototype.flags "^1.3.0"
side-channel "^1.0.2"
which-boxed-primitive "^1.0.1"
which-collection "^1.0.1"
which-typed-array "^1.1.2"
deep-equal@~1.0.1: deep-equal@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@ -1582,7 +1536,7 @@ error-inject@^1.0.0:
resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37"
integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=
es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5: es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5:
version "1.17.5" version "1.17.5"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9"
integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==
@ -1599,19 +1553,6 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstrac
string.prototype.trimleft "^2.1.1" string.prototype.trimleft "^2.1.1"
string.prototype.trimright "^2.1.1" string.prototype.trimright "^2.1.1"
es-get-iterator@^1.1.0:
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: es-to-primitive@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
@ -2312,21 +2253,11 @@ is-accessor-descriptor@^1.0.0:
dependencies: dependencies:
kind-of "^6.0.0" 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: is-arrayish@^0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= 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: is-binary-path@~2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
@ -2334,11 +2265,6 @@ is-binary-path@~2.1.0:
dependencies: dependencies:
binary-extensions "^2.0.0" 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: is-buffer@^1.1.5:
version "1.1.6" version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@ -2375,7 +2301,7 @@ is-data-descriptor@^1.0.0:
dependencies: dependencies:
kind-of "^6.0.0" kind-of "^6.0.0"
is-date-object@^1.0.1, is-date-object@^1.0.2: is-date-object@^1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
@ -2450,21 +2376,11 @@ is-installed-globally@^0.3.1:
global-dirs "^2.0.1" global-dirs "^2.0.1"
is-path-inside "^3.0.1" is-path-inside "^3.0.1"
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@^4.0.0: is-npm@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d"
integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==
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: is-number@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@ -2501,21 +2417,11 @@ is-regex@^1.0.5:
dependencies: dependencies:
has "^1.0.3" 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-stream@^1.1.0: is-stream@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= 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: is-symbol@^1.0.2:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
@ -2532,31 +2438,11 @@ is-type-of@^1.0.0:
is-class-hotfix "~0.0.6" is-class-hotfix "~0.0.6"
isstream "~0.1.2" isstream "~0.1.2"
is-typed-array@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.3.tgz#a4ff5a5e672e1a55f99c7f54e59597af5c1df04d"
integrity sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ==
dependencies:
available-typed-arrays "^1.0.0"
es-abstract "^1.17.4"
foreach "^2.0.5"
has-symbols "^1.0.1"
is-typedarray@^1.0.0, is-typedarray@~1.0.0: is-typedarray@^1.0.0, is-typedarray@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 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: is-windows@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@ -2582,11 +2468,6 @@ isarray@1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 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: isexe@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@ -3860,14 +3741,6 @@ object-inspect@^1.7.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
object-is@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6"
integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.17.5"
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.0.6, object-keys@^1.1.1: object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.0.6, object-keys@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
@ -4361,19 +4234,6 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2" extend-shallow "^3.0.2"
safe-regex "^1.1.0" safe-regex "^1.1.0"
regexp.prototype.flags@^1.3.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@^4.0.0: registry-auth-token@^4.0.0:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.1.1.tgz#40a33be1e82539460f94328b0f7f0f84c16d9479" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.1.1.tgz#40a33be1e82539460f94328b0f7f0f84c16d9479"
@ -4629,14 +4489,6 @@ shortid@^2.2.8:
dependencies: dependencies:
nanoid "^2.1.0" nanoid "^2.1.0"
side-channel@^1.0.2:
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: signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
@ -4976,11 +4828,6 @@ supports-color@^7.1.0:
dependencies: dependencies:
has-flag "^4.0.0" has-flag "^4.0.0"
svelte@^3.9.2:
version "3.22.2"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.22.2.tgz#06585244191bf7a112af2a0025610f33d77c3715"
integrity sha512-DxumO0+vvHA6NSc2jtVty08I8lFI43q8P2zX6JxZL8J1kqK5NVjad6TRM/twhnWXC+QScnwkZ15O6X1aTsEKTA==
symbol-tree@^3.2.2: symbol-tree@^3.2.2:
version "3.2.4" version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
@ -5384,44 +5231,11 @@ whatwg-url@^7.0.0:
tr46 "^1.0.1" tr46 "^1.0.1"
webidl-conversions "^4.0.2" 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.1:
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: which-module@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
which-typed-array@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2"
integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ==
dependencies:
available-typed-arrays "^1.0.2"
es-abstract "^1.17.5"
foreach "^2.0.5"
function-bind "^1.1.1"
has-symbols "^1.0.1"
is-typed-array "^1.1.3"
which@^1.2.9, which@^1.3.0: which@^1.2.9, which@^1.3.0:
version "1.3.1" version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"

View file

@ -1,5 +1,5 @@
<script> <script>
import { onMount } from "svelte"; import { onMount } from "svelte"
export let _bb export let _bb
export let _viewName export let _viewName
@ -7,7 +7,6 @@
let username let username
let password let password
</script> </script>
<form class="uk-form"> <form class="uk-form">
@ -24,4 +23,5 @@
</form> </form>
<style> <style>
</style> </style>

Some files were not shown because too many files have changed in this diff Show more