development setup, adding data components
|
@ -20,7 +20,7 @@
|
||||||
"publishdev": "lerna run publishdev",
|
"publishdev": "lerna run publishdev",
|
||||||
"publishnpm": "yarn build && lerna publish",
|
"publishnpm": "yarn build && lerna publish",
|
||||||
"clean": "lerna clean",
|
"clean": "lerna clean",
|
||||||
"dev": "lerna run --parallel --stream dev:builder",
|
"dev": "./scripts/symlinkDev.js && lerna run --parallel --stream dev:builder",
|
||||||
"test": "lerna run test",
|
"test": "lerna run test",
|
||||||
"lint": "eslint packages",
|
"lint": "eslint packages",
|
||||||
"lint:fix": "eslint --fix packages",
|
"lint:fix": "eslint --fix packages",
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
@ -151,7 +151,7 @@ export default {
|
||||||
targets: [
|
targets: [
|
||||||
{ src: "src/index.html", dest: outputpath },
|
{ src: "src/index.html", dest: outputpath },
|
||||||
{ src: "src/favicon.png", dest: outputpath },
|
{ src: "src/favicon.png", dest: outputpath },
|
||||||
{ src: "src/assets", dest: outputpath },
|
{ src: "assets", dest: outputpath },
|
||||||
{
|
{
|
||||||
src: "node_modules/@budibase/client/dist/budibase-client.esm.mjs",
|
src: "node_modules/@budibase/client/dist/budibase-client.esm.mjs",
|
||||||
dest: outputpath,
|
dest: outputpath,
|
||||||
|
|
|
@ -161,10 +161,6 @@
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select {
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
table {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
|
|
||||||
export async function createUser(user, instanceId) {
|
export async function createUser(user, appId, instanceId) {
|
||||||
const CREATE_USER_URL = `/api/${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;
|
||||||
|
@ -21,11 +21,11 @@ export async function deleteRecord(record, instanceId) {
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadRecord(key, { appname, instanceId }) {
|
// export async function loadRecord(key, { appname, instanceId }) {
|
||||||
const LOAD_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record${key}`
|
// const LOAD_RECORDS_URL = `/_builder/instance/${appname}/${instanceId}/api/record${key}`
|
||||||
const response = await api.get(LOAD_RECORDS_URL)
|
// const response = await api.get(LOAD_RECORDS_URL)
|
||||||
return await response.json()
|
// 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`
|
||||||
|
|
|
@ -10,10 +10,11 @@
|
||||||
|
|
||||||
$: valid = username && password
|
$: valid = username && password
|
||||||
$: instanceId = $backendUiStore.selectedDatabase.id
|
$: instanceId = $backendUiStore.selectedDatabase.id
|
||||||
|
$: appId = $store.appId
|
||||||
|
|
||||||
async function createUser() {
|
async function createUser() {
|
||||||
const user = { name: username, username, password }
|
const user = { name: username, username, password }
|
||||||
const response = await api.createUser(user, instanceId);
|
const response = await api.createUser(user, appId, instanceId);
|
||||||
backendUiStore.actions.users.create(response)
|
backendUiStore.actions.users.create(response)
|
||||||
onClosed()
|
onClosed()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
import iframeTemplate from "./iframeTemplate";
|
import iframeTemplate from "./iframeTemplate";
|
||||||
import { pipe } from "components/common/core"
|
import { pipe } from "components/common/core"
|
||||||
|
|
||||||
|
|
||||||
let iframe
|
let iframe
|
||||||
|
let styles = ""
|
||||||
|
|
||||||
function transform_component(comp) {
|
function transform_component(comp) {
|
||||||
const props = comp.props || comp
|
const props = comp.props || comp
|
||||||
|
@ -24,7 +24,15 @@
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
$: hasComponent = !!$store.currentPreviewItem
|
$: hasComponent = !!$store.currentPreviewItem
|
||||||
$: styles = hasComponent ? $store.currentPreviewItem._css : ""
|
$: {
|
||||||
|
// Apply the CSS from the currently selected page and its screens
|
||||||
|
const currentPage = $store.pages[$store.currentPageName];
|
||||||
|
styles += currentPage._css;
|
||||||
|
for (let screen of currentPage._screens) {
|
||||||
|
styles += screen._css;
|
||||||
|
}
|
||||||
|
styles = styles
|
||||||
|
}
|
||||||
|
|
||||||
$: stylesheetLinks = pipe(
|
$: stylesheetLinks = pipe(
|
||||||
$store.pages.stylesheets,
|
$store.pages.stylesheets,
|
||||||
|
@ -67,7 +75,7 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
appRootPath: `/_builder/instance/${$store.appname}/${$backendUiStore.selectedDatabase.id}/`,
|
appRootPath: `/`,
|
||||||
}
|
}
|
||||||
|
|
||||||
$: selectedComponentId = $store.currentComponentInfo ? $store.currentComponentInfo._id : ""
|
$: selectedComponentId = $store.currentComponentInfo ? $store.currentComponentInfo._id : ""
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
const onStyleChanged = store.setComponentStyle
|
const onStyleChanged = store.setComponentStyle
|
||||||
|
|
||||||
function getProps(obj, keys) {
|
function getProps(obj, keys) {
|
||||||
return keys.map((k, i) => [k, obj[k], obj.props._id + i])
|
return keys.map((key, i) => [key, obj[key], obj.props._id + i])
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<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"}
|
||||||
<div class="prop-container">
|
<div class="prop-container">
|
||||||
|
|
||||||
<PropControl
|
<PropControl
|
||||||
{setProp}
|
{setProp}
|
||||||
{prop_name}
|
{prop_name}
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
disabled={false} />
|
disabled={false} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -166,7 +166,23 @@ export default {
|
||||||
name: "@budibase/materialdesign-components/recordForm",
|
name: "@budibase/materialdesign-components/recordForm",
|
||||||
},
|
},
|
||||||
children: []
|
children: []
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
_component: "@budibase/standard-components/datatable",
|
||||||
|
name: 'DataTable',
|
||||||
|
description: 'A table for displaying data from the backend.',
|
||||||
|
icon: 'ri-archive-drawer-fill',
|
||||||
|
commonProps: {},
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_component: "@budibase/standard-components/dataform",
|
||||||
|
name: 'DataForm',
|
||||||
|
description: 'Form stuff',
|
||||||
|
icon: 'ri-file-edit-fill',
|
||||||
|
commonProps: {},
|
||||||
|
children: []
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rollup -c",
|
"build": "rollup -c",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"publishdev": "yarn build && node ./scripts/publishDev.js"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"globals": {
|
"globals": {
|
||||||
|
|
|
@ -102,7 +102,6 @@ export default {
|
||||||
}),
|
}),
|
||||||
builtins(),
|
builtins(),
|
||||||
nodeglobals(),
|
nodeglobals(),
|
||||||
//terser()
|
|
||||||
],
|
],
|
||||||
watch: {
|
watch: {
|
||||||
clearScreen: false,
|
clearScreen: false,
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
const { readdir, stat, copyFile, ensureDir } = require("fs-extra")
|
|
||||||
const { constants } = require("fs")
|
|
||||||
const { join, basename } = require("path")
|
|
||||||
|
|
||||||
const packagesFolder = ".."
|
|
||||||
|
|
||||||
const jsFile = dir => join(dir, "budibase-client.js")
|
|
||||||
const jsMapFile = dir => join(dir, "budibase-client.js.map")
|
|
||||||
const sourceJs = jsFile("dist")
|
|
||||||
const sourceJsMap = jsMapFile("dist")
|
|
||||||
|
|
||||||
const appPackages = join(
|
|
||||||
packagesFolder,
|
|
||||||
"server",
|
|
||||||
serverConfig.latestPackagesFolder
|
|
||||||
)
|
|
||||||
|
|
||||||
const publicMain = appName => join(appPackages, appName, "public", "main")
|
|
||||||
const publicUnauth = appName =>
|
|
||||||
join(appPackages, appName, "public", "unauthenticated")
|
|
||||||
|
|
||||||
;(async () => {
|
|
||||||
const apps = await readdir(appPackages)
|
|
||||||
|
|
||||||
const copySource = file => async toDir => {
|
|
||||||
await ensureDir(toDir)
|
|
||||||
const dest = join(toDir, basename(file))
|
|
||||||
try {
|
|
||||||
await copyFile(file, dest, constants.COPYFILE_FICLONE)
|
|
||||||
console.log(`COPIED ${file} to ${dest}`)
|
|
||||||
} catch (e) {
|
|
||||||
console.log(`COPY FAILED ${file} to ${dest}: ${e}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const copySourceJs = copySource(sourceJs)
|
|
||||||
const copySourceJsMap = copySource(sourceJsMap)
|
|
||||||
|
|
||||||
for (let app of apps) {
|
|
||||||
if (app === ".data") continue
|
|
||||||
if (!(await stat(join(appPackages, app))).isDirectory()) continue
|
|
||||||
|
|
||||||
//await copySourceJs(nodeModules(app))
|
|
||||||
//await copySourceJsMap(nodeModules(app))
|
|
||||||
|
|
||||||
await copySourceJs(publicMain(app))
|
|
||||||
await copySourceJsMap(publicMain(app))
|
|
||||||
|
|
||||||
await copySourceJs(publicUnauth(app))
|
|
||||||
await copySourceJsMap(publicUnauth(app))
|
|
||||||
|
|
||||||
await copySource(join("dist", "budibase-client.esm.mjs"))(
|
|
||||||
join(packagesFolder, "server", "builder")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})()
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { createApp } from "./createApp"
|
import { createApp } from "./createApp"
|
||||||
import { trimSlash } from "./common/trimSlash"
|
import { trimSlash } from "./common/trimSlash"
|
||||||
import { builtins, builtinLibName } from "./render/builtinComponents"
|
import { builtins, builtinLibName } from "./render/builtinComponents"
|
||||||
import * as standardComponents from "@budibase/standard-components";
|
import * as standardComponents from "../../standard-components/dist";
|
||||||
import * as materialDesignComponents from "@budibase/materialdesign-components";
|
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.
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"testbuild": "rollup -w -c rollup.testconfig.js",
|
"testbuild": "rollup -w -c rollup.testconfig.js",
|
||||||
"dev": "run-p start:dev testbuild",
|
"dev": "run-p start:dev testbuild",
|
||||||
"start:dev": "sirv public --single --dev",
|
"start:dev": "sirv public --single --dev",
|
||||||
"publishdev": "yarn build && node ./scripts/publishDev.js"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@budibase/client": "^0.0.32",
|
"@budibase/client": "^0.0.32",
|
||||||
|
|
|
@ -1,94 +0,0 @@
|
||||||
const { readdir, stat, copyFile, ensureDir } = require("fs-extra")
|
|
||||||
const { constants } = require("fs")
|
|
||||||
const { join, basename } = require("path")
|
|
||||||
const serverConfig = require("../../server/config")()
|
|
||||||
|
|
||||||
const packagesFolder = ".."
|
|
||||||
|
|
||||||
const jsFile = dir => join(dir, "index.js")
|
|
||||||
const jsMapFile = dir => join(dir, "index.js.map")
|
|
||||||
const sourceJs = jsFile("dist")
|
|
||||||
const sourceJsMap = jsMapFile("dist")
|
|
||||||
const componentsFile = "components.json"
|
|
||||||
|
|
||||||
const appPackages = join(
|
|
||||||
packagesFolder,
|
|
||||||
"server",
|
|
||||||
serverConfig.latestPackagesFolder
|
|
||||||
)
|
|
||||||
|
|
||||||
const publicMain = appName =>
|
|
||||||
join(
|
|
||||||
appPackages,
|
|
||||||
appName,
|
|
||||||
"public",
|
|
||||||
"main",
|
|
||||||
"lib",
|
|
||||||
"node_modules",
|
|
||||||
"@budibase",
|
|
||||||
"materialdesign-components"
|
|
||||||
)
|
|
||||||
const publicUnauth = appName =>
|
|
||||||
join(
|
|
||||||
appPackages,
|
|
||||||
appName,
|
|
||||||
"public",
|
|
||||||
"unauthenticated",
|
|
||||||
"lib",
|
|
||||||
"node_modules",
|
|
||||||
"@budibase",
|
|
||||||
"materialdesign-components"
|
|
||||||
)
|
|
||||||
const nodeModulesDist = appName =>
|
|
||||||
join(
|
|
||||||
appPackages,
|
|
||||||
appName,
|
|
||||||
"node_modules",
|
|
||||||
"@budibase",
|
|
||||||
"materialdesign-components",
|
|
||||||
"dist"
|
|
||||||
)
|
|
||||||
|
|
||||||
const nodeModules = appName =>
|
|
||||||
join(
|
|
||||||
appPackages,
|
|
||||||
appName,
|
|
||||||
"node_modules",
|
|
||||||
"@budibase",
|
|
||||||
"materialdesign-components"
|
|
||||||
)
|
|
||||||
|
|
||||||
;(async () => {
|
|
||||||
const apps = await readdir(appPackages)
|
|
||||||
|
|
||||||
const copySource = file => async toDir => {
|
|
||||||
await ensureDir(toDir)
|
|
||||||
const dest = join(toDir, basename(file))
|
|
||||||
try {
|
|
||||||
await copyFile(file, dest, constants.COPYFILE_FICLONE)
|
|
||||||
console.log(`COPIED ${file} to ${dest}`)
|
|
||||||
} catch (e) {
|
|
||||||
console.log(`COPY FAILED ${file} to ${dest}: ${e}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const copySourceJs = copySource(sourceJs)
|
|
||||||
const copySourceJsMap = copySource(sourceJsMap)
|
|
||||||
const copyComponentsJson = copySource(componentsFile)
|
|
||||||
|
|
||||||
for (let app of apps) {
|
|
||||||
if (app === ".data") continue
|
|
||||||
if (!(await stat(join(appPackages, app))).isDirectory()) continue
|
|
||||||
|
|
||||||
await copySourceJs(nodeModulesDist(app))
|
|
||||||
await copySourceJsMap(nodeModulesDist(app))
|
|
||||||
|
|
||||||
await copyComponentsJson(nodeModules(app))
|
|
||||||
|
|
||||||
await copySourceJs(join(publicMain(app), "dist"))
|
|
||||||
await copySourceJsMap(join(publicMain(app), "dist"))
|
|
||||||
|
|
||||||
await copySourceJs(join(publicUnauth(app), "dist"))
|
|
||||||
await copySourceJsMap(join(publicUnauth(app), "dist"))
|
|
||||||
}
|
|
||||||
})()
|
|
|
@ -8,24 +8,43 @@ exports.authenticate = async ctx => {
|
||||||
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");
|
||||||
|
|
||||||
// query couch for their username
|
// TODO: Don't use this. It can't be relied on
|
||||||
const db = new CouchDB(ctx.params.clientId);
|
const referer = ctx.request.headers.referer.split("/");
|
||||||
const dbUser = await db.query("by_username", {
|
const appId = referer[3];
|
||||||
|
|
||||||
|
// find the instance that the user is associated with
|
||||||
|
const db = new CouchDB(`client-${process.env.CLIENT_ID}`);
|
||||||
|
const app = await db.get(appId);
|
||||||
|
const instanceId = app.userInstanceMap[username];
|
||||||
|
|
||||||
|
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
|
||||||
|
const instanceDb = new CouchDB(instanceId);
|
||||||
|
const { rows } = await instanceDb.query("database/by_username", {
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
key: username
|
username
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (rows.length === 0) ctx.throw(500, `User does not exist.`);
|
||||||
|
|
||||||
|
const dbUser = rows[0].doc;
|
||||||
|
|
||||||
|
// 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: ctx.params.instanceId
|
instanceId: instanceId
|
||||||
};
|
};
|
||||||
const token = jwt.sign(payload, ctx.config.secret, {
|
const token = jwt.sign(payload, ctx.config.secret, {
|
||||||
expiresIn: "1 day"
|
expiresIn: "1 day"
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.body = token;
|
ctx.body = {
|
||||||
|
token,
|
||||||
|
...dbUser
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
ctx.throw(401, "Invalid credentials.");
|
ctx.throw(401, "Invalid credentials.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,20 @@ 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";
|
||||||
|
|
||||||
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) => {
|
||||||
const appDirectory = resolve(homedir(), ".budibase", ctx.params.appId, "node_modules");
|
|
||||||
|
let appDirectory = resolve(homedir(), ".budibase", ctx.params.appId, "node_modules");
|
||||||
|
|
||||||
|
if (isDev) {
|
||||||
|
appDirectory = "/tmp/.budibase";
|
||||||
|
}
|
||||||
|
|
||||||
const componentJson = require(join(appDirectory, componentLibrary, "components.json"));
|
const componentJson = require(join(appDirectory, componentLibrary, "components.json"));
|
||||||
|
|
||||||
const result = {};
|
const result = {};
|
||||||
|
|
|
@ -2,7 +2,6 @@ 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;
|
||||||
// await couchdb.db.create(instanceName);
|
|
||||||
|
|
||||||
const { clientId, applicationId } = ctx.params;
|
const { clientId, applicationId } = ctx.params;
|
||||||
const db = new CouchDB(instanceName);
|
const db = new CouchDB(instanceName);
|
||||||
|
@ -13,6 +12,13 @@ exports.create = async function(ctx) {
|
||||||
applicationId
|
applicationId
|
||||||
},
|
},
|
||||||
views: {
|
views: {
|
||||||
|
by_username: {
|
||||||
|
map: function(doc) {
|
||||||
|
if (doc.type === "user") {
|
||||||
|
emit([doc.username], doc._id);
|
||||||
|
}
|
||||||
|
}.toString()
|
||||||
|
},
|
||||||
by_type: {
|
by_type: {
|
||||||
map: function(doc) {
|
map: function(doc) {
|
||||||
emit([doc.type], doc._id);
|
emit([doc.type], doc._id);
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
const send = require("koa-send");
|
const send = require("koa-send");
|
||||||
const { resolve } = require("path")
|
const { resolve, join } = require("path")
|
||||||
const { homedir } = require("os");
|
const { homedir } = require("os");
|
||||||
|
|
||||||
|
const isProduction = process.env.NODE_ENV === "production";
|
||||||
|
|
||||||
exports.serveBuilder = async function(ctx) {
|
exports.serveBuilder = async function(ctx) {
|
||||||
const builderPath = resolve(process.cwd(), "builder")
|
const builderPath = resolve(process.cwd(), "builder")
|
||||||
await send(ctx, ctx.file, { root: builderPath })
|
await send(ctx, ctx.file, { root: builderPath })
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.serveApp = async function(ctx) {
|
exports.serveApp = async function(ctx) {
|
||||||
|
|
||||||
|
// ONLY RELEVANT FOR THE CLIENT LIB
|
||||||
|
// const devPath = join("/tmp", ".budibase", ctx.params.appId);
|
||||||
|
|
||||||
// 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(
|
||||||
|
@ -18,31 +24,22 @@ exports.serveApp = async function(ctx) {
|
||||||
ctx.isAuthenticated ? "main" : "unauthenticated"
|
ctx.isAuthenticated ? "main" : "unauthenticated"
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: Hook up to JWT auth in real app
|
|
||||||
// TODO: serve CSS and other assets
|
|
||||||
// resolve main page if user authenticated
|
|
||||||
await send(ctx, ctx.file, { root: appPath })
|
await send(ctx, ctx.file, { root: appPath })
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.serveComponentLibrary = async function(ctx) {
|
exports.serveComponentLibrary = async function(ctx) {
|
||||||
|
|
||||||
|
let componentLibraryPath = join(
|
||||||
|
"/tmp",
|
||||||
|
".budibase",
|
||||||
|
decodeURI(ctx.query.library),
|
||||||
|
"dist"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isProduction) {
|
||||||
// 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 componentLibraryPath = resolve(
|
componentLibraryPath = resolve(
|
||||||
homedir(),
|
|
||||||
".budibase",
|
|
||||||
ctx.params.appId,
|
|
||||||
"node_modules",
|
|
||||||
decodeURI(ctx.query.library),
|
|
||||||
"dist"
|
|
||||||
);
|
|
||||||
|
|
||||||
await send(ctx, "/index.js", { root: componentLibraryPath })
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.serveComponentDefinitions = async function(ctx) {
|
|
||||||
// TODO: update homedir stuff to wherever budi is run
|
|
||||||
// default to homedir
|
|
||||||
const componentLibraryPath = resolve(
|
|
||||||
homedir(),
|
homedir(),
|
||||||
".budibase",
|
".budibase",
|
||||||
ctx.params.appId,
|
ctx.params.appId,
|
||||||
|
@ -50,6 +47,7 @@ exports.serveComponentDefinitions = async function(ctx) {
|
||||||
decodeURI(ctx.query.library),
|
decodeURI(ctx.query.library),
|
||||||
"dist"
|
"dist"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
await send(ctx, "/index.js", { root: componentLibraryPath })
|
await send(ctx, "/index.js", { root: componentLibraryPath })
|
||||||
}
|
}
|
|
@ -25,12 +25,12 @@ exports.create = async function(ctx) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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(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,
|
||||||
[response._id]: ctx.params.instanceId
|
[username]: ctx.params.instanceId
|
||||||
}
|
}
|
||||||
await clientDb.put(app);
|
await clientDb.put(app);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ const controller = {
|
||||||
const response = [];
|
const response = [];
|
||||||
|
|
||||||
for (let name in designDoc.views) {
|
for (let name in designDoc.views) {
|
||||||
if (!name.startsWith("all") && name !== "by_type") {
|
if (!name.startsWith("all") && name !== "by_type" && name !== "by_username") {
|
||||||
response.push({
|
response.push({
|
||||||
name,
|
name,
|
||||||
...designDoc.views[name]
|
...designDoc.views[name]
|
||||||
|
|
|
@ -36,7 +36,10 @@ module.exports = app => {
|
||||||
// TODO: temp dev middleware
|
// TODO: temp dev middleware
|
||||||
// ctx.sessionId = ctx.session._sessCtx.externalKey
|
// ctx.sessionId = ctx.session._sessCtx.externalKey
|
||||||
// ctx.session.accessed = true
|
// ctx.session.accessed = true
|
||||||
ctx.config = { latestPackagesFolder: resolve(homedir(), ".budibase") }
|
ctx.config = {
|
||||||
|
latestPackagesFolder: resolve(homedir(), ".budibase"),
|
||||||
|
secret: "foo"
|
||||||
|
}
|
||||||
await next();
|
await next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,30 +11,30 @@ const {
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
router.post("/_builder/api/:appname/pages/:pageName", async ctx => {
|
router.post("/_builder/api/:appId/pages/:pageName", async ctx => {
|
||||||
await buildPage(
|
await buildPage(
|
||||||
ctx.config,
|
ctx.config,
|
||||||
ctx.params.appname,
|
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.get("/_builder/api/:appname/pages/:pagename/screens", async ctx => {
|
router.get("/_builder/api/:appId/pages/:pagename/screens", async ctx => {
|
||||||
ctx.body = await listScreens(
|
ctx.body = await listScreens(
|
||||||
ctx.config,
|
ctx.config,
|
||||||
ctx.params.appname,
|
ctx.params.appId,
|
||||||
ctx.params.pagename
|
ctx.params.pagename
|
||||||
)
|
)
|
||||||
ctx.response.status = StatusCodes.OK
|
ctx.response.status = StatusCodes.OK
|
||||||
})
|
})
|
||||||
|
|
||||||
router
|
router
|
||||||
.post("/_builder/api/:appname/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.appname,
|
ctx.params.appId,
|
||||||
ctx.params.pagename,
|
ctx.params.pagename,
|
||||||
ctx.request.body
|
ctx.request.body
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,7 @@ const {
|
||||||
readFile,
|
readFile,
|
||||||
writeJSON,
|
writeJSON,
|
||||||
} = require("fs-extra")
|
} = require("fs-extra")
|
||||||
const { join, resolve, dirname } = require("path")
|
const { join, resolve } = require("path")
|
||||||
const sqrl = require("squirrelly")
|
const sqrl = require("squirrelly")
|
||||||
const { convertCssToFiles } = require("./convertCssToFiles")
|
const { convertCssToFiles } = require("./convertCssToFiles")
|
||||||
const publicPath = require("./publicPath")
|
const publicPath = require("./publicPath")
|
||||||
|
|
|
@ -4977,9 +4977,9 @@ supports-color@^7.1.0:
|
||||||
has-flag "^4.0.0"
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
svelte@^3.9.2:
|
svelte@^3.9.2:
|
||||||
version "3.21.0"
|
version "3.22.2"
|
||||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.21.0.tgz#e326591cb92267e90b4fb5b961d80d9763792551"
|
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.22.2.tgz#06585244191bf7a112af2a0025610f33d77c3715"
|
||||||
integrity sha512-smh3LZKPCGJ+UXa0iZvUmuDctPYCwPY1opmClTWTm+l6e4y9FHLoCZMiue8YIeyc9JvlGT/EK0xry0diXjFDZQ==
|
integrity sha512-DxumO0+vvHA6NSc2jtVty08I8lFI43q8P2zX6JxZL8J1kqK5NVjad6TRM/twhnWXC+QScnwkZ15O6X1aTsEKTA==
|
||||||
|
|
||||||
symbol-tree@^3.2.2:
|
symbol-tree@^3.2.2:
|
||||||
version "3.2.4"
|
version "3.2.4"
|
||||||
|
|
|
@ -262,6 +262,29 @@
|
||||||
"color": "colour"
|
"color": "colour"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"datatable": {
|
||||||
|
"description": "Other thingwy",
|
||||||
|
"props": {
|
||||||
|
"_viewName": "string",
|
||||||
|
"_instanceId": "string",
|
||||||
|
"model": {
|
||||||
|
"store": true,
|
||||||
|
"type": "options",
|
||||||
|
"default": "",
|
||||||
|
"options": [
|
||||||
|
"something",
|
||||||
|
"something"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dataform": {
|
||||||
|
"description": "an HTML table that fetches data from a model or view and displays it.",
|
||||||
|
"props": {
|
||||||
|
"_viewName": "string",
|
||||||
|
"_instanceId": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"description": "an HTML anchor <a> tag",
|
"description": "an HTML anchor <a> tag",
|
||||||
"props": {
|
"props": {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"testbuild": "rollup -w -c rollup.testconfig.js",
|
"testbuild": "rollup -w -c rollup.testconfig.js",
|
||||||
"dev": "run-p start:dev testbuild",
|
"dev": "run-p start:dev testbuild",
|
||||||
"start:dev": "sirv public --single --dev",
|
"start:dev": "sirv public --single --dev",
|
||||||
"publishdev": "yarn build && node ./scripts/publishDev.js"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@budibase/client": "^0.0.32",
|
"@budibase/client": "^0.0.32",
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
const { readdir, stat, copyFile, ensureDir } = require("fs-extra")
|
|
||||||
const { constants } = require("fs")
|
|
||||||
const { join, basename } = require("path")
|
|
||||||
const serverConfig = require("../../server/config")()
|
|
||||||
|
|
||||||
const packagesFolder = ".."
|
|
||||||
|
|
||||||
const jsFile = dir => join(dir, "index.js")
|
|
||||||
const jsMapFile = dir => join(dir, "index.js.map")
|
|
||||||
const sourceJs = jsFile("dist")
|
|
||||||
const sourceJsMap = jsMapFile("dist")
|
|
||||||
const componentsFile = "components.json"
|
|
||||||
|
|
||||||
const appPackages = join(
|
|
||||||
packagesFolder,
|
|
||||||
"server",
|
|
||||||
resolve(homedir(), ".budibase")
|
|
||||||
)
|
|
||||||
|
|
||||||
const publicMain = appName =>
|
|
||||||
join(
|
|
||||||
appPackages,
|
|
||||||
appName,
|
|
||||||
"public",
|
|
||||||
"main",
|
|
||||||
"lib",
|
|
||||||
"node_modules",
|
|
||||||
"@budibase",
|
|
||||||
"standard-components"
|
|
||||||
)
|
|
||||||
const publicUnauth = appName =>
|
|
||||||
join(
|
|
||||||
appPackages,
|
|
||||||
appName,
|
|
||||||
"public",
|
|
||||||
"unauthenticated",
|
|
||||||
"lib",
|
|
||||||
"node_modules",
|
|
||||||
"@budibase",
|
|
||||||
"standard-components"
|
|
||||||
)
|
|
||||||
const nodeModulesDist = appName =>
|
|
||||||
join(
|
|
||||||
appPackages,
|
|
||||||
appName,
|
|
||||||
"node_modules",
|
|
||||||
"@budibase",
|
|
||||||
"standard-components",
|
|
||||||
"dist"
|
|
||||||
)
|
|
||||||
|
|
||||||
const nodeModules = appName =>
|
|
||||||
join(appPackages, appName, "node_modules", "@budibase", "standard-components")
|
|
||||||
|
|
||||||
;(async () => {
|
|
||||||
const apps = await readdir(appPackages)
|
|
||||||
|
|
||||||
const copySource = file => async toDir => {
|
|
||||||
await ensureDir(toDir)
|
|
||||||
const dest = join(toDir, basename(file))
|
|
||||||
try {
|
|
||||||
await copyFile(file, dest, constants.COPYFILE_FICLONE)
|
|
||||||
console.log(`COPIED ${file} to ${dest}`)
|
|
||||||
} catch (e) {
|
|
||||||
console.log(`COPY FAILED ${file} to ${dest}: ${e}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const copySourceJs = copySource(sourceJs)
|
|
||||||
const copySourceJsMap = copySource(sourceJsMap)
|
|
||||||
const copyComponentsJson = copySource(componentsFile)
|
|
||||||
|
|
||||||
for (let app of apps) {
|
|
||||||
if (app === ".data") continue
|
|
||||||
if (!(await stat(join(appPackages, app))).isDirectory()) continue
|
|
||||||
|
|
||||||
await copySourceJs(nodeModulesDist(app))
|
|
||||||
await copySourceJsMap(nodeModulesDist(app))
|
|
||||||
|
|
||||||
await copyComponentsJson(nodeModules(app))
|
|
||||||
|
|
||||||
await copySourceJs(join(publicMain(app), "dist"))
|
|
||||||
await copySourceJsMap(join(publicMain(app), "dist"))
|
|
||||||
|
|
||||||
await copySourceJs(join(publicUnauth(app), "dist"))
|
|
||||||
await copySourceJsMap(join(publicUnauth(app), "dist"))
|
|
||||||
}
|
|
||||||
})()
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script>
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
export let _bb
|
||||||
|
export let _viewName
|
||||||
|
export let _instanceId
|
||||||
|
|
||||||
|
let username
|
||||||
|
let password
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form class="uk-form">
|
||||||
|
<div>
|
||||||
|
<div class="uk-margin">
|
||||||
|
<label class="uk-form-label" for="form-stacked-text">Username</label>
|
||||||
|
<input class="uk-input" type="text" bind:value={username} />
|
||||||
|
</div>
|
||||||
|
<div class="uk-margin">
|
||||||
|
<label class="uk-form-label" for="form-stacked-text">Password</label>
|
||||||
|
<input class="uk-input" type="password" bind:value={password} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
|
@ -0,0 +1,110 @@
|
||||||
|
<script>
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
// import { cssVars, createClasses } from "./cssVars"
|
||||||
|
// import { buildStyle } from "./buildStyle"
|
||||||
|
|
||||||
|
export let _bb
|
||||||
|
export let onLoad
|
||||||
|
export let _viewName
|
||||||
|
export let _instanceId
|
||||||
|
|
||||||
|
let cssVariables
|
||||||
|
let headers = []
|
||||||
|
let data = []
|
||||||
|
|
||||||
|
async function fetchData() {
|
||||||
|
const FETCH_RECORDS_URL = `/api/${_instanceId}/${_viewName}/records`;
|
||||||
|
const response = await _bb.api.get(FETCH_RECORDS_URL);
|
||||||
|
if (response.status === 200) {
|
||||||
|
const json = await response.json();
|
||||||
|
|
||||||
|
if (json.length > 0) {
|
||||||
|
data = json;
|
||||||
|
headers = Object.keys(data[0]);
|
||||||
|
} else {
|
||||||
|
console.log("NO DATA");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error("Failed to fetch records..");
|
||||||
|
console.log("FAILED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
await fetchData();
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- This prop was in the old one -->
|
||||||
|
<!-- use:cssVars={cssVariables} -->
|
||||||
|
|
||||||
|
<table class="uk-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{#each headers as header}
|
||||||
|
<th>{header}</th>
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each data as row}
|
||||||
|
<tr>
|
||||||
|
{#each headers as header}
|
||||||
|
{#if row[header]}
|
||||||
|
<td>
|
||||||
|
{row[header]}
|
||||||
|
</td>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <button
|
||||||
|
bind:this={theButton}
|
||||||
|
use:cssVars={cssVariables}
|
||||||
|
class="{className}
|
||||||
|
{customClasses}"
|
||||||
|
disabled={disabled || false}
|
||||||
|
on:click={clickHandler}
|
||||||
|
style={buttonStyles}>
|
||||||
|
{#if !_bb.props._children || _bb.props._children.length === 0}
|
||||||
|
{contentText}
|
||||||
|
{/if}
|
||||||
|
</button> -->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 3px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
background: #f9f9f9;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th {
|
||||||
|
color: var(--button-text);
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
transition: 0.3s background-color;
|
||||||
|
color: var(--secondary100);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:hover {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -4,7 +4,6 @@
|
||||||
export let usernameLabel = "Username"
|
export let usernameLabel = "Username"
|
||||||
export let passwordLabel = "Password"
|
export let passwordLabel = "Password"
|
||||||
export let loginButtonLabel = "Login"
|
export let loginButtonLabel = "Login"
|
||||||
export let loginRedirect = ""
|
|
||||||
export let logo = ""
|
export let logo = ""
|
||||||
export let buttonClass = ""
|
export let buttonClass = ""
|
||||||
export let inputClass = ""
|
export let inputClass = ""
|
||||||
|
@ -13,8 +12,8 @@
|
||||||
|
|
||||||
let username = ""
|
let username = ""
|
||||||
let password = ""
|
let password = ""
|
||||||
let busy = false
|
let loading = false
|
||||||
let incorrect = false
|
let error = false
|
||||||
let _logo = ""
|
let _logo = ""
|
||||||
let _buttonClass = ""
|
let _buttonClass = ""
|
||||||
let _inputClass = ""
|
let _inputClass = ""
|
||||||
|
@ -25,32 +24,25 @@
|
||||||
_inputClass = inputClass || "default-input"
|
_inputClass = inputClass || "default-input"
|
||||||
}
|
}
|
||||||
|
|
||||||
const login = () => {
|
const login = async () => {
|
||||||
busy = true
|
loading = true
|
||||||
_bb.api
|
const response = _bb.api.post("/api/authenticate", { username, password });
|
||||||
.post("/api/authenticate", { username, password })
|
|
||||||
.then(r => {
|
if (response.status === 200) {
|
||||||
busy = false
|
const json = await response.json();
|
||||||
if (r.status === 200) {
|
localStorage.setItem("budibase:token", json.token);
|
||||||
return r.json()
|
// TODO: possibly do something with the user information in the response?
|
||||||
} else {
|
|
||||||
incorrect = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(user => {
|
|
||||||
if (user) {
|
|
||||||
localStorage.setItem("budibase:user", JSON.stringify(user))
|
|
||||||
location.reload()
|
location.reload()
|
||||||
|
} else {
|
||||||
|
loading = false
|
||||||
|
error = true
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
<div class="root">
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|
||||||
{#if _logo}
|
{#if _logo}
|
||||||
<div class="logo-container">
|
<div class="logo-container">
|
||||||
<img src={_logo} alt="logo" />
|
<img src={_logo} alt="logo" />
|
||||||
|
@ -69,17 +61,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="login-button-container">
|
<div class="login-button-container">
|
||||||
<button disabled={busy} on:click={login} class={_buttonClass}>
|
<button disabled={loading} on:click={login} class={_buttonClass}>
|
||||||
{loginButtonLabel}
|
{loginButtonLabel}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if incorrect}
|
{#if error}
|
||||||
<div class="incorrect-details-panel">Incorrect username or password</div>
|
<div class="incorrect-details-panel">Incorrect username or password</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -14,3 +14,5 @@ export { default as link } from "./Link.svelte"
|
||||||
export { default as image } from "./Image.svelte"
|
export { default as image } from "./Image.svelte"
|
||||||
export { default as icon } from "./Icon.svelte"
|
export { default as icon } from "./Icon.svelte"
|
||||||
export { default as Navigation } from "./Navigation.svelte"
|
export { default as Navigation } from "./Navigation.svelte"
|
||||||
|
export { default as datatable } from "./DataTable.svelte"
|
||||||
|
export { default as dataform } from "./DataForm.svelte"
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
This script symlinks the budibase component and client paths to the
|
||||||
|
ones that exist in your local development directories. This means you
|
||||||
|
can work your budibase apps but also change code for the components
|
||||||
|
and client library in real time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const { resolve } = require("path")
|
||||||
|
|
||||||
|
const devDir = "/tmp/.budibase/@budibase";
|
||||||
|
|
||||||
|
// create the dev directory if it doesn't exist
|
||||||
|
if (!fs.existsSync(devDir)) {
|
||||||
|
fs.mkdirSync(devDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const SYMLINK_PATHS = [
|
||||||
|
{
|
||||||
|
symlink: "/tmp/.budibase/@budibase/materialdesign-components",
|
||||||
|
destination: resolve("packages/materialdesign-components"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symlink: "/tmp/.budibase/@budibase/standard-components",
|
||||||
|
destination: resolve("packages/standard-components")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symlink: "/tmp/.budibase/budibase-client.esm.mjs",
|
||||||
|
destination: resolve("packages/client/dist/budibase-client.esm.mjs")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symlink: "/tmp/.budibase/budibase-client.js",
|
||||||
|
destination: resolve("packages/client/dist/budibase-client.js"),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
SYMLINK_PATHS.forEach(sym => {
|
||||||
|
fs.symlinkSync(sym.destination, sym.symlink);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Dev Symlinks Created Successfully.")
|