Fixing some typing that was added.
This commit is contained in:
commit
ad0c1a94c9
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "2.20.13",
|
"version": "2.20.14",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*",
|
"packages/*",
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
Document,
|
Document,
|
||||||
isDocument,
|
isDocument,
|
||||||
RowResponse,
|
RowResponse,
|
||||||
|
RowValue,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { getCouchInfo } from "./connections"
|
import { getCouchInfo } from "./connections"
|
||||||
import { directCouchUrlCall } from "./utils"
|
import { directCouchUrlCall } from "./utils"
|
||||||
|
@ -222,7 +223,7 @@ export class DatabaseImpl implements Database {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async allDocs<T extends Document>(
|
async allDocs<T extends Document | RowValue>(
|
||||||
params: DatabaseQueryOpts
|
params: DatabaseQueryOpts
|
||||||
): Promise<AllDocsResponse<T>> {
|
): Promise<AllDocsResponse<T>> {
|
||||||
return this.performCall(db => {
|
return this.performCall(db => {
|
||||||
|
@ -230,7 +231,7 @@ export class DatabaseImpl implements Database {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async sql<T>(sql: string): Promise<T> {
|
async sql<T extends Document>(sql: string): Promise<T> {
|
||||||
const dbName = this.name
|
const dbName = this.name
|
||||||
const url = `/${dbName}/${SQLITE_DESIGN_DOC_ID}`
|
const url = `/${dbName}/${SQLITE_DESIGN_DOC_ID}`
|
||||||
const response = await directCouchUrlCall({
|
const response = await directCouchUrlCall({
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {
|
import {
|
||||||
DocumentScope,
|
|
||||||
DocumentDestroyResponse,
|
DocumentDestroyResponse,
|
||||||
DocumentInsertResponse,
|
DocumentInsertResponse,
|
||||||
DocumentBulkResponse,
|
DocumentBulkResponse,
|
||||||
|
@ -13,6 +12,7 @@ import {
|
||||||
DatabasePutOpts,
|
DatabasePutOpts,
|
||||||
DatabaseQueryOpts,
|
DatabaseQueryOpts,
|
||||||
Document,
|
Document,
|
||||||
|
RowValue,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import tracer from "dd-trace"
|
import tracer from "dd-trace"
|
||||||
import { Writable } from "stream"
|
import { Writable } from "stream"
|
||||||
|
@ -79,7 +79,7 @@ export class DDInstrumentedDatabase implements Database {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
allDocs<T extends Document>(
|
allDocs<T extends Document | RowValue>(
|
||||||
params: DatabaseQueryOpts
|
params: DatabaseQueryOpts
|
||||||
): Promise<AllDocsResponse<T>> {
|
): Promise<AllDocsResponse<T>> {
|
||||||
return tracer.trace("db.allDocs", span => {
|
return tracer.trace("db.allDocs", span => {
|
||||||
|
@ -147,7 +147,7 @@ export class DDInstrumentedDatabase implements Database {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
sql<T>(sql: string): Promise<T> {
|
sql<T extends Document>(sql: string): Promise<T> {
|
||||||
return tracer.trace("db.sql", span => {
|
return tracer.trace("db.sql", span => {
|
||||||
span?.addTags({ db_name: this.name })
|
span?.addTags({ db_name: this.name })
|
||||||
return this.db.sql(sql)
|
return this.db.sql(sql)
|
||||||
|
|
|
@ -116,7 +116,6 @@
|
||||||
$: pagerText = `Page ${currentPage} of ${totalPages}`
|
$: pagerText = `Page ${currentPage} of ${totalPages}`
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
a11y-click-events-have-key-events
|
|
||||||
<div bind:this={buttonAnchor}>
|
<div bind:this={buttonAnchor}>
|
||||||
<ActionButton on:click={dropdown.show}>
|
<ActionButton on:click={dropdown.show}>
|
||||||
{displayValue}
|
{displayValue}
|
||||||
|
|
|
@ -12,11 +12,17 @@
|
||||||
hoverStore,
|
hoverStore,
|
||||||
} from "stores/builder"
|
} from "stores/builder"
|
||||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
import { Layout, Heading, Body, Icon, notifications } from "@budibase/bbui"
|
import {
|
||||||
|
ProgressCircle,
|
||||||
|
Layout,
|
||||||
|
Heading,
|
||||||
|
Body,
|
||||||
|
Icon,
|
||||||
|
notifications,
|
||||||
|
} from "@budibase/bbui"
|
||||||
import ErrorSVG from "@budibase/frontend-core/assets/error.svg?raw"
|
import ErrorSVG from "@budibase/frontend-core/assets/error.svg?raw"
|
||||||
import { findComponent, findComponentPath } from "helpers/components"
|
import { findComponent, findComponentPath } from "helpers/components"
|
||||||
import { isActive, goto } from "@roxi/routify"
|
import { isActive, goto } from "@roxi/routify"
|
||||||
import { ClientAppSkeleton } from "@budibase/frontend-core"
|
|
||||||
|
|
||||||
let iframe
|
let iframe
|
||||||
let layout
|
let layout
|
||||||
|
@ -234,16 +240,8 @@
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div class="component-container">
|
<div class="component-container">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div
|
<div class="center">
|
||||||
class={`loading ${$builderStore.theme}`}
|
<ProgressCircle />
|
||||||
class:tablet={$previewStore.previewDevice === "tablet"}
|
|
||||||
class:mobile={$previewStore.previewDevice === "mobile"}
|
|
||||||
>
|
|
||||||
<ClientAppSkeleton
|
|
||||||
sideNav={$builderStore.navigation?.navigation === "Left"}
|
|
||||||
hideFooter
|
|
||||||
hideDevTools
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
{:else if error}
|
{:else if error}
|
||||||
<div class="center error">
|
<div class="center error">
|
||||||
|
@ -260,6 +258,8 @@
|
||||||
bind:this={iframe}
|
bind:this={iframe}
|
||||||
src="/app/preview"
|
src="/app/preview"
|
||||||
class:hidden={loading || error}
|
class:hidden={loading || error}
|
||||||
|
class:tablet={$previewStore.previewDevice === "tablet"}
|
||||||
|
class:mobile={$previewStore.previewDevice === "mobile"}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="add-component"
|
class="add-component"
|
||||||
|
@ -279,25 +279,6 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.loading {
|
|
||||||
position: absolute;
|
|
||||||
container-type: inline-size;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading.tablet {
|
|
||||||
width: calc(1024px + 6px);
|
|
||||||
max-height: calc(768px + 6px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading.mobile {
|
|
||||||
width: calc(390px + 6px);
|
|
||||||
max-height: calc(844px + 6px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.component-container {
|
.component-container {
|
||||||
grid-row-start: middle;
|
grid-row-start: middle;
|
||||||
grid-column-start: middle;
|
grid-column-start: middle;
|
||||||
|
|
|
@ -1,22 +1,16 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount, onDestroy } from "svelte"
|
|
||||||
import { params, goto } from "@roxi/routify"
|
import { params, goto } from "@roxi/routify"
|
||||||
import { licensing, apps, auth, sideBarCollapsed } from "stores/portal"
|
import { apps, auth, sideBarCollapsed } from "stores/portal"
|
||||||
import { Link, Body, ActionButton } from "@budibase/bbui"
|
import { Link, Body, ActionButton } from "@budibase/bbui"
|
||||||
import { sdk } from "@budibase/shared-core"
|
import { sdk } from "@budibase/shared-core"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import ErrorSVG from "./ErrorSVG.svelte"
|
import ErrorSVG from "./ErrorSVG.svelte"
|
||||||
import { ClientAppSkeleton } from "@budibase/frontend-core"
|
|
||||||
|
|
||||||
$: app = $apps.find(app => app.appId === $params.appId)
|
$: app = $apps.find(app => app.appId === $params.appId)
|
||||||
$: iframeUrl = getIframeURL(app)
|
$: iframeUrl = getIframeURL(app)
|
||||||
$: isBuilder = sdk.users.isBuilder($auth.user, app?.devId)
|
$: isBuilder = sdk.users.isBuilder($auth.user, app?.devId)
|
||||||
|
|
||||||
let loading = true
|
|
||||||
|
|
||||||
const getIframeURL = app => {
|
const getIframeURL = app => {
|
||||||
loading = true
|
|
||||||
|
|
||||||
if (app.status === "published") {
|
if (app.status === "published") {
|
||||||
return `/app${app.url}`
|
return `/app${app.url}`
|
||||||
}
|
}
|
||||||
|
@ -34,20 +28,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$: fetchScreens(app?.devId)
|
$: fetchScreens(app?.devId)
|
||||||
|
|
||||||
const receiveMessage = async message => {
|
|
||||||
if (message.data.type === "docLoaded") {
|
|
||||||
loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
window.addEventListener("message", receiveMessage)
|
|
||||||
})
|
|
||||||
|
|
||||||
onDestroy(() => {
|
|
||||||
window.removeEventListener("message", receiveMessage)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -98,17 +78,7 @@
|
||||||
</Body>
|
</Body>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class:hide={!loading} class="loading">
|
<iframe src={iframeUrl} title={app.name} />
|
||||||
<div class={`loadingThemeWrapper ${app.theme}`}>
|
|
||||||
<ClientAppSkeleton
|
|
||||||
noAnimation
|
|
||||||
hideDevTools={app?.status === "published"}
|
|
||||||
sideNav={app?.navigation.navigation === "Left"}
|
|
||||||
hideFooter={$licensing.brandingEnabled}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<iframe class:hide={loading} src={iframeUrl} title={app.name} />
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -130,23 +100,6 @@
|
||||||
flex: 0 0 50px;
|
flex: 0 0 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading {
|
|
||||||
height: 100%;
|
|
||||||
border: 1px solid var(--spectrum-global-color-gray-300);
|
|
||||||
border-radius: var(--spacing-s);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.loadingThemeWrapper {
|
|
||||||
height: 100%;
|
|
||||||
container-type: inline-size;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hide {
|
|
||||||
visibility: hidden;
|
|
||||||
height: 0;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
iframe {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
border-radius: var(--spacing-s);
|
border-radius: var(--spacing-s);
|
||||||
|
|
|
@ -80,18 +80,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fontsLoaded = false
|
|
||||||
|
|
||||||
// Load app config
|
// Load app config
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
document.fonts.ready.then(() => {
|
|
||||||
fontsLoaded = true
|
|
||||||
})
|
|
||||||
|
|
||||||
await initialise()
|
await initialise()
|
||||||
await authStore.actions.fetchUser()
|
await authStore.actions.fetchUser()
|
||||||
dataLoaded = true
|
dataLoaded = true
|
||||||
|
|
||||||
if (get(builderStore).inBuilder) {
|
if (get(builderStore).inBuilder) {
|
||||||
builderStore.actions.notifyLoaded()
|
builderStore.actions.notifyLoaded()
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,12 +93,6 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$: {
|
|
||||||
if (dataLoaded && fontsLoaded) {
|
|
||||||
document.getElementById("clientAppSkeletonLoader")?.remove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
@ -116,140 +103,140 @@
|
||||||
{/if}
|
{/if}
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div
|
{#if dataLoaded}
|
||||||
id="spectrum-root"
|
<div
|
||||||
lang="en"
|
id="spectrum-root"
|
||||||
dir="ltr"
|
lang="en"
|
||||||
class="spectrum spectrum--medium {$themeStore.baseTheme} {$themeStore.theme}"
|
dir="ltr"
|
||||||
class:builder={$builderStore.inBuilder}
|
class="spectrum spectrum--medium {$themeStore.baseTheme} {$themeStore.theme}"
|
||||||
class:show={fontsLoaded && dataLoaded}
|
class:builder={$builderStore.inBuilder}
|
||||||
>
|
>
|
||||||
<DeviceBindingsProvider>
|
<DeviceBindingsProvider>
|
||||||
<UserBindingsProvider>
|
<UserBindingsProvider>
|
||||||
<StateBindingsProvider>
|
<StateBindingsProvider>
|
||||||
<RowSelectionProvider>
|
<RowSelectionProvider>
|
||||||
<QueryParamsProvider>
|
<QueryParamsProvider>
|
||||||
<!-- Settings bar can be rendered outside of device preview -->
|
<!-- Settings bar can be rendered outside of device preview -->
|
||||||
<!-- Key block needs to be outside the if statement or it breaks -->
|
<!-- Key block needs to be outside the if statement or it breaks -->
|
||||||
{#key $builderStore.selectedComponentId}
|
{#key $builderStore.selectedComponentId}
|
||||||
{#if $builderStore.inBuilder}
|
{#if $builderStore.inBuilder}
|
||||||
<SettingsBar />
|
<SettingsBar />
|
||||||
{/if}
|
|
||||||
{/key}
|
|
||||||
|
|
||||||
<!-- Clip boundary for selection indicators -->
|
|
||||||
<div
|
|
||||||
id="clip-root"
|
|
||||||
class:preview={$builderStore.inBuilder}
|
|
||||||
class:tablet-preview={$builderStore.previewDevice === "tablet"}
|
|
||||||
class:mobile-preview={$builderStore.previewDevice === "mobile"}
|
|
||||||
>
|
|
||||||
<!-- Actual app -->
|
|
||||||
<div id="app-root">
|
|
||||||
{#if showDevTools}
|
|
||||||
<DevToolsHeader />
|
|
||||||
{/if}
|
{/if}
|
||||||
|
{/key}
|
||||||
|
|
||||||
<div id="app-body">
|
<!-- Clip boundary for selection indicators -->
|
||||||
{#if permissionError}
|
<div
|
||||||
<div class="error">
|
id="clip-root"
|
||||||
<Layout justifyItems="center" gap="S">
|
class:preview={$builderStore.inBuilder}
|
||||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
class:tablet-preview={$builderStore.previewDevice === "tablet"}
|
||||||
{@html ErrorSVG}
|
class:mobile-preview={$builderStore.previewDevice === "mobile"}
|
||||||
<Heading size="L">
|
>
|
||||||
You don't have permission to use this app
|
<!-- Actual app -->
|
||||||
</Heading>
|
<div id="app-root">
|
||||||
<Body size="S">
|
{#if showDevTools}
|
||||||
Ask your administrator to grant you access
|
<DevToolsHeader />
|
||||||
</Body>
|
|
||||||
</Layout>
|
|
||||||
</div>
|
|
||||||
{:else if !$screenStore.activeLayout}
|
|
||||||
<div class="error">
|
|
||||||
<Layout justifyItems="center" gap="S">
|
|
||||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
||||||
{@html ErrorSVG}
|
|
||||||
<Heading size="L">
|
|
||||||
Something went wrong rendering your app
|
|
||||||
</Heading>
|
|
||||||
<Body size="S">
|
|
||||||
Get in touch with support if this issue persists
|
|
||||||
</Body>
|
|
||||||
</Layout>
|
|
||||||
</div>
|
|
||||||
{:else if embedNoScreens}
|
|
||||||
<div class="error">
|
|
||||||
<Layout justifyItems="center" gap="S">
|
|
||||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
||||||
{@html ErrorSVG}
|
|
||||||
<Heading size="L">
|
|
||||||
This Budibase app is not publicly accessible
|
|
||||||
</Heading>
|
|
||||||
</Layout>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<CustomThemeWrapper>
|
|
||||||
{#key $screenStore.activeLayout._id}
|
|
||||||
<Component
|
|
||||||
isLayout
|
|
||||||
instance={$screenStore.activeLayout.props}
|
|
||||||
/>
|
|
||||||
{/key}
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Flatpickr needs to be inside the theme wrapper.
|
|
||||||
It also needs its own container because otherwise it hijacks
|
|
||||||
key events on the whole page. It is painful to work with.
|
|
||||||
-->
|
|
||||||
<div id="flatpickr-root" />
|
|
||||||
|
|
||||||
<!-- Modal container to ensure they sit on top -->
|
|
||||||
<div class="modal-container" />
|
|
||||||
|
|
||||||
<!-- Layers on top of app -->
|
|
||||||
<NotificationDisplay />
|
|
||||||
<ConfirmationDisplay />
|
|
||||||
<PeekScreenDisplay />
|
|
||||||
</CustomThemeWrapper>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if showDevTools}
|
<div id="app-body">
|
||||||
<DevTools />
|
{#if permissionError}
|
||||||
|
<div class="error">
|
||||||
|
<Layout justifyItems="center" gap="S">
|
||||||
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||||
|
{@html ErrorSVG}
|
||||||
|
<Heading size="L">
|
||||||
|
You don't have permission to use this app
|
||||||
|
</Heading>
|
||||||
|
<Body size="S">
|
||||||
|
Ask your administrator to grant you access
|
||||||
|
</Body>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
{:else if !$screenStore.activeLayout}
|
||||||
|
<div class="error">
|
||||||
|
<Layout justifyItems="center" gap="S">
|
||||||
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||||
|
{@html ErrorSVG}
|
||||||
|
<Heading size="L">
|
||||||
|
Something went wrong rendering your app
|
||||||
|
</Heading>
|
||||||
|
<Body size="S">
|
||||||
|
Get in touch with support if this issue persists
|
||||||
|
</Body>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
{:else if embedNoScreens}
|
||||||
|
<div class="error">
|
||||||
|
<Layout justifyItems="center" gap="S">
|
||||||
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||||
|
{@html ErrorSVG}
|
||||||
|
<Heading size="L">
|
||||||
|
This Budibase app is not publicly accessible
|
||||||
|
</Heading>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<CustomThemeWrapper>
|
||||||
|
{#key $screenStore.activeLayout._id}
|
||||||
|
<Component
|
||||||
|
isLayout
|
||||||
|
instance={$screenStore.activeLayout.props}
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Flatpickr needs to be inside the theme wrapper.
|
||||||
|
It also needs its own container because otherwise it hijacks
|
||||||
|
key events on the whole page. It is painful to work with.
|
||||||
|
-->
|
||||||
|
<div id="flatpickr-root" />
|
||||||
|
|
||||||
|
<!-- Modal container to ensure they sit on top -->
|
||||||
|
<div class="modal-container" />
|
||||||
|
|
||||||
|
<!-- Layers on top of app -->
|
||||||
|
<NotificationDisplay />
|
||||||
|
<ConfirmationDisplay />
|
||||||
|
<PeekScreenDisplay />
|
||||||
|
</CustomThemeWrapper>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if showDevTools}
|
||||||
|
<DevTools />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if !$builderStore.inBuilder && licensing.logoEnabled()}
|
||||||
|
<FreeFooter />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !$builderStore.inBuilder && licensing.logoEnabled()}
|
<!-- Preview and dev tools utilities -->
|
||||||
<FreeFooter />
|
{#if $appStore.isDevApp}
|
||||||
|
<SelectionIndicator />
|
||||||
|
{/if}
|
||||||
|
{#if $builderStore.inBuilder || $devToolsStore.allowSelection}
|
||||||
|
<HoverIndicator />
|
||||||
|
{/if}
|
||||||
|
{#if $builderStore.inBuilder}
|
||||||
|
<DNDHandler />
|
||||||
|
<GridDNDHandler />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
</QueryParamsProvider>
|
||||||
<!-- Preview and dev tools utilities -->
|
</RowSelectionProvider>
|
||||||
{#if $appStore.isDevApp}
|
</StateBindingsProvider>
|
||||||
<SelectionIndicator />
|
</UserBindingsProvider>
|
||||||
{/if}
|
</DeviceBindingsProvider>
|
||||||
{#if $builderStore.inBuilder || $devToolsStore.allowSelection}
|
</div>
|
||||||
<HoverIndicator />
|
<KeyboardManager />
|
||||||
{/if}
|
{/if}
|
||||||
{#if $builderStore.inBuilder}
|
|
||||||
<DNDHandler />
|
|
||||||
<GridDNDHandler />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</QueryParamsProvider>
|
|
||||||
</RowSelectionProvider>
|
|
||||||
</StateBindingsProvider>
|
|
||||||
</UserBindingsProvider>
|
|
||||||
</DeviceBindingsProvider>
|
|
||||||
</div>
|
|
||||||
<KeyboardManager />
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#spectrum-root {
|
#spectrum-root {
|
||||||
height: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -270,11 +257,6 @@
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#spectrum-root.show {
|
|
||||||
height: 100%;
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-root {
|
#app-root {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.free-footer {
|
.free-footer {
|
||||||
min-height: 51px;
|
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
border-top: 1px solid var(--spectrum-global-color-gray-300);
|
border-top: 1px solid var(--spectrum-global-color-gray-300);
|
||||||
|
|
|
@ -1,244 +0,0 @@
|
||||||
<script>
|
|
||||||
export let sideNav = false
|
|
||||||
export let hideDevTools = false
|
|
||||||
export let hideFooter = false
|
|
||||||
export let noAnimation = false
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class:sideNav id="clientAppSkeletonLoader" class="skeleton">
|
|
||||||
<div class="animation" class:noAnimation />
|
|
||||||
|
|
||||||
{#if !hideDevTools}
|
|
||||||
<div class="devTools" />
|
|
||||||
{/if}
|
|
||||||
<div class="main">
|
|
||||||
<div class="nav" />
|
|
||||||
<div class="body">
|
|
||||||
<div class="bodyVerticalPadding" />
|
|
||||||
<div class="bodyHorizontal">
|
|
||||||
<div class="bodyHorizontalPadding" />
|
|
||||||
<svg
|
|
||||||
class="svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
width="240"
|
|
||||||
height="256"
|
|
||||||
>
|
|
||||||
<mask id="mask">
|
|
||||||
<rect x="0" y="0" width="240" height="256" fill="white" />
|
|
||||||
<rect x="0" y="0" width="240" height="32" rx="6" fill="black" />
|
|
||||||
<rect x="0" y="56" width="240" height="32" rx="6" fill="black" />
|
|
||||||
<rect x="0" y="112" width="240" height="32" rx="6" fill="black" />
|
|
||||||
<rect x="0" y="168" width="240" height="32" rx="6" fill="black" />
|
|
||||||
<rect x="71" y="224" width="98" height="32" rx="6" fill="black" />
|
|
||||||
</mask>
|
|
||||||
|
|
||||||
<rect
|
|
||||||
x="0"
|
|
||||||
y="0"
|
|
||||||
width="240"
|
|
||||||
height="256"
|
|
||||||
fill="black"
|
|
||||||
mask="url(#mask)"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<div class="bodyHorizontalPadding" />
|
|
||||||
</div>
|
|
||||||
<div class="bodyVerticalPadding" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{#if !hideFooter}
|
|
||||||
<div class="footer" />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.skeleton {
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: var(--spectrum-global-color-gray-200);
|
|
||||||
}
|
|
||||||
|
|
||||||
.animation {
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
background: linear-gradient(
|
|
||||||
to right,
|
|
||||||
transparent 0%,
|
|
||||||
var(--spectrum-global-color-gray-300) 20%,
|
|
||||||
transparent 40%,
|
|
||||||
transparent 100%
|
|
||||||
);
|
|
||||||
animation-duration: 1.3s;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
animation-name: shimmer;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.noAnimation {
|
|
||||||
animation-name: none;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.devTools {
|
|
||||||
display: flex;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color: black;
|
|
||||||
height: 60px;
|
|
||||||
padding: 1px 24px 1px 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 1;
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
mix-blend-mode: multiply;
|
|
||||||
background: rgb(0 0 0);
|
|
||||||
font-size: 30px;
|
|
||||||
font-family: Source Sans Pro;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
#clientAppSkeletonLoader .main {
|
|
||||||
flex-direction: column;
|
|
||||||
width: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@container (max-width: 720px) {
|
|
||||||
#clientAppSkeletonLoader .main {
|
|
||||||
flex-direction: column;
|
|
||||||
width: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sideNav .main {
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav {
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 141px;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
#clientAppSkeletonLoader .nav {
|
|
||||||
height: 61px;
|
|
||||||
width: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@container (max-width: 720px) {
|
|
||||||
#clientAppSkeletonLoader .nav {
|
|
||||||
height: 61px;
|
|
||||||
width: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sideNav .nav {
|
|
||||||
height: 100%;
|
|
||||||
width: 251px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body {
|
|
||||||
z-index: 2;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
#clientAppSkeletonLoader .body {
|
|
||||||
width: initial;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@container (max-width: 720px) {
|
|
||||||
#clientAppSkeletonLoader .body {
|
|
||||||
width: initial;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sideNav .body {
|
|
||||||
width: 100%;
|
|
||||||
height: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body :global(svg > rect) {
|
|
||||||
fill: var(--spectrum-alias-background-color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.body :global(svg) {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bodyHorizontal {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bodyHorizontalPadding {
|
|
||||||
height: 100%;
|
|
||||||
flex-grow: 1;
|
|
||||||
background-color: var(--spectrum-alias-background-color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bodyVerticalPadding {
|
|
||||||
width: 100%;
|
|
||||||
flex-grow: 1;
|
|
||||||
background-color: var(--spectrum-alias-background-color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
flex-shrink: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 1;
|
|
||||||
height: 52px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
#clientAppSkeletonLoader .footer {
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@container (max-width: 720px) {
|
|
||||||
#clientAppSkeletonLoader .footer {
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sideNav .footer {
|
|
||||||
border-top: 3px solid var(--spectrum-alias-background-color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes shimmer {
|
|
||||||
0% {
|
|
||||||
left: -170%;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
left: 170%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -5,4 +5,3 @@ export { default as UserAvatar } from "./UserAvatar.svelte"
|
||||||
export { default as UserAvatars } from "./UserAvatars.svelte"
|
export { default as UserAvatars } from "./UserAvatars.svelte"
|
||||||
export { default as Updating } from "./Updating.svelte"
|
export { default as Updating } from "./Updating.svelte"
|
||||||
export { Grid } from "./grid"
|
export { Grid } from "./grid"
|
||||||
export { default as ClientAppSkeleton } from "./ClientAppSkeleton.svelte"
|
|
||||||
|
|
|
@ -17,8 +17,5 @@
|
||||||
--modal-background: var(--spectrum-global-color-gray-50);
|
--modal-background: var(--spectrum-global-color-gray-50);
|
||||||
--drop-shadow: rgba(0, 0, 0, 0.25) !important;
|
--drop-shadow: rgba(0, 0, 0, 0.25) !important;
|
||||||
--spectrum-global-color-blue-100: rgba(35, 40, 50) !important;
|
--spectrum-global-color-blue-100: rgba(35, 40, 50) !important;
|
||||||
|
|
||||||
--spectrum-alias-background-color-secondary: var(--spectrum-global-color-gray-75);
|
|
||||||
--spectrum-alias-background-color-primary: var(--spectrum-global-color-gray-100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,4 @@
|
||||||
--modal-background: var(--spectrum-global-color-gray-50);
|
--modal-background: var(--spectrum-global-color-gray-50);
|
||||||
--drop-shadow: rgba(0, 0, 0, 0.15) !important;
|
--drop-shadow: rgba(0, 0, 0, 0.15) !important;
|
||||||
--spectrum-global-color-blue-100: rgb(56, 65, 84) !important;
|
--spectrum-global-color-blue-100: rgb(56, 65, 84) !important;
|
||||||
|
|
||||||
--spectrum-alias-background-color-secondary: var(--spectrum-global-color-gray-75);
|
|
||||||
--spectrum-alias-background-color-primary: var(--spectrum-global-color-gray-100);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
"@budibase/pro": "0.0.0",
|
"@budibase/pro": "0.0.0",
|
||||||
"@budibase/shared-core": "0.0.0",
|
"@budibase/shared-core": "0.0.0",
|
||||||
"@budibase/string-templates": "0.0.0",
|
"@budibase/string-templates": "0.0.0",
|
||||||
"@budibase/frontend-core": "0.0.0",
|
|
||||||
"@budibase/types": "0.0.0",
|
"@budibase/types": "0.0.0",
|
||||||
"@bull-board/api": "5.10.2",
|
"@bull-board/api": "5.10.2",
|
||||||
"@bull-board/koa": "5.10.2",
|
"@bull-board/koa": "5.10.2",
|
||||||
|
|
|
@ -15,10 +15,14 @@ import {
|
||||||
FieldType,
|
FieldType,
|
||||||
RelationshipFieldMetadata,
|
RelationshipFieldMetadata,
|
||||||
SourceName,
|
SourceName,
|
||||||
|
UpdateDatasourceRequest,
|
||||||
UpdateDatasourceResponse,
|
UpdateDatasourceResponse,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
VerifyDatasourceRequest,
|
VerifyDatasourceRequest,
|
||||||
VerifyDatasourceResponse,
|
VerifyDatasourceResponse,
|
||||||
|
Table,
|
||||||
|
RowValue,
|
||||||
|
DynamicVariable,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import sdk from "../../sdk"
|
import sdk from "../../sdk"
|
||||||
import { builderSocket } from "../../websockets"
|
import { builderSocket } from "../../websockets"
|
||||||
|
@ -90,8 +94,10 @@ async function invalidateVariables(
|
||||||
existingDatasource: Datasource,
|
existingDatasource: Datasource,
|
||||||
updatedDatasource: Datasource
|
updatedDatasource: Datasource
|
||||||
) {
|
) {
|
||||||
const existingVariables: any = existingDatasource.config?.dynamicVariables
|
const existingVariables: DynamicVariable[] =
|
||||||
const updatedVariables: any = updatedDatasource.config?.dynamicVariables
|
existingDatasource.config?.dynamicVariables || []
|
||||||
|
const updatedVariables: DynamicVariable[] =
|
||||||
|
updatedDatasource.config?.dynamicVariables || []
|
||||||
const toInvalidate = []
|
const toInvalidate = []
|
||||||
|
|
||||||
if (!existingVariables) {
|
if (!existingVariables) {
|
||||||
|
@ -103,9 +109,9 @@ async function invalidateVariables(
|
||||||
toInvalidate.push(...existingVariables)
|
toInvalidate.push(...existingVariables)
|
||||||
} else {
|
} else {
|
||||||
// invaldate changed / removed
|
// invaldate changed / removed
|
||||||
existingVariables.forEach((existing: any) => {
|
existingVariables.forEach(existing => {
|
||||||
const unchanged = updatedVariables.find(
|
const unchanged = updatedVariables.find(
|
||||||
(updated: any) =>
|
updated =>
|
||||||
existing.name === updated.name &&
|
existing.name === updated.name &&
|
||||||
existing.queryId === updated.queryId &&
|
existing.queryId === updated.queryId &&
|
||||||
existing.value === updated.value
|
existing.value === updated.value
|
||||||
|
@ -118,24 +124,32 @@ async function invalidateVariables(
|
||||||
await invalidateDynamicVariables(toInvalidate)
|
await invalidateDynamicVariables(toInvalidate)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(ctx: UserCtx<any, UpdateDatasourceResponse>) {
|
export async function update(
|
||||||
|
ctx: UserCtx<UpdateDatasourceRequest, UpdateDatasourceResponse>
|
||||||
|
) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const datasourceId = ctx.params.datasourceId
|
const datasourceId = ctx.params.datasourceId
|
||||||
const baseDatasource = await sdk.datasources.get(datasourceId)
|
const baseDatasource = await sdk.datasources.get(datasourceId)
|
||||||
const auth = baseDatasource.config?.auth
|
|
||||||
await invalidateVariables(baseDatasource, ctx.request.body)
|
await invalidateVariables(baseDatasource, ctx.request.body)
|
||||||
|
|
||||||
const isBudibaseSource =
|
const isBudibaseSource =
|
||||||
baseDatasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE
|
baseDatasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE
|
||||||
|
|
||||||
const dataSourceBody = isBudibaseSource
|
const dataSourceBody: Datasource = isBudibaseSource
|
||||||
? { name: ctx.request.body?.name }
|
? {
|
||||||
|
name: ctx.request.body?.name,
|
||||||
|
type: dbCore.BUDIBASE_DATASOURCE_TYPE,
|
||||||
|
source: SourceName.BUDIBASE,
|
||||||
|
}
|
||||||
: ctx.request.body
|
: ctx.request.body
|
||||||
|
|
||||||
let datasource: Datasource = {
|
let datasource: Datasource = {
|
||||||
...baseDatasource,
|
...baseDatasource,
|
||||||
...sdk.datasources.mergeConfigs(dataSourceBody, baseDatasource),
|
...sdk.datasources.mergeConfigs(dataSourceBody, baseDatasource),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this block is specific to GSheets, if no auth set, set it back
|
||||||
|
const auth = baseDatasource.config?.auth
|
||||||
if (auth && !ctx.request.body.auth) {
|
if (auth && !ctx.request.body.auth) {
|
||||||
// don't strip auth config from DB
|
// don't strip auth config from DB
|
||||||
datasource.config!.auth = auth
|
datasource.config!.auth = auth
|
||||||
|
@ -204,7 +218,7 @@ async function destroyInternalTablesBySourceId(datasourceId: string) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
|
|
||||||
// Get all internal tables
|
// Get all internal tables
|
||||||
const internalTables = await db.allDocs(
|
const internalTables = await db.allDocs<Table>(
|
||||||
getTableParams(null, {
|
getTableParams(null, {
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
})
|
})
|
||||||
|
@ -212,8 +226,8 @@ async function destroyInternalTablesBySourceId(datasourceId: string) {
|
||||||
|
|
||||||
// Filter by datasource and return the docs.
|
// Filter by datasource and return the docs.
|
||||||
const datasourceTableDocs = internalTables.rows.reduce(
|
const datasourceTableDocs = internalTables.rows.reduce(
|
||||||
(acc: any, table: any) => {
|
(acc: Table[], table) => {
|
||||||
if (table.doc.sourceId == datasourceId) {
|
if (table.doc?.sourceId == datasourceId) {
|
||||||
acc.push(table.doc)
|
acc.push(table.doc)
|
||||||
}
|
}
|
||||||
return acc
|
return acc
|
||||||
|
@ -254,9 +268,9 @@ export async function destroy(ctx: UserCtx) {
|
||||||
if (datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE) {
|
if (datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE) {
|
||||||
await destroyInternalTablesBySourceId(datasourceId)
|
await destroyInternalTablesBySourceId(datasourceId)
|
||||||
} else {
|
} else {
|
||||||
const queries = await db.allDocs(getQueryParams(datasourceId))
|
const queries = await db.allDocs<RowValue>(getQueryParams(datasourceId))
|
||||||
await db.bulkDocs(
|
await db.bulkDocs(
|
||||||
queries.rows.map((row: any) => ({
|
queries.rows.map(row => ({
|
||||||
_id: row.id,
|
_id: row.id,
|
||||||
_rev: row.value.rev,
|
_rev: row.value.rev,
|
||||||
_deleted: true,
|
_deleted: true,
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import { getDefinition, getDefinitions } from "../../integrations"
|
import { getDefinition, getDefinitions } from "../../integrations"
|
||||||
import { SourceName, UserCtx } from "@budibase/types"
|
import { SourceName, UserCtx } from "@budibase/types"
|
||||||
|
|
||||||
const DISABLED_EXTERNAL_INTEGRATIONS = [SourceName.AIRTABLE]
|
const DISABLED_EXTERNAL_INTEGRATIONS = [
|
||||||
|
SourceName.AIRTABLE,
|
||||||
|
SourceName.BUDIBASE,
|
||||||
|
]
|
||||||
|
|
||||||
export async function fetch(ctx: UserCtx) {
|
export async function fetch(ctx: UserCtx) {
|
||||||
const definitions = await getDefinitions()
|
const definitions = await getDefinitions()
|
||||||
|
|
|
@ -296,11 +296,12 @@ export async function fetchEnrichedRow(ctx: UserCtx) {
|
||||||
const tableId = utils.getTableId(ctx)
|
const tableId = utils.getTableId(ctx)
|
||||||
const rowId = ctx.params.rowId as string
|
const rowId = ctx.params.rowId as string
|
||||||
// need table to work out where links go in row, as well as the link docs
|
// need table to work out where links go in row, as well as the link docs
|
||||||
const [table, row, links] = await Promise.all([
|
const [table, links] = await Promise.all([
|
||||||
sdk.tables.getTable(tableId),
|
sdk.tables.getTable(tableId),
|
||||||
utils.findRow(ctx, tableId, rowId),
|
|
||||||
linkRows.getLinkDocuments({ tableId, rowId, fieldName }),
|
linkRows.getLinkDocuments({ tableId, rowId, fieldName }),
|
||||||
])
|
])
|
||||||
|
let row = await utils.findRow(ctx, tableId, rowId)
|
||||||
|
row = await outputProcessing(table, row)
|
||||||
const linkVals = links as LinkDocumentValue[]
|
const linkVals = links as LinkDocumentValue[]
|
||||||
|
|
||||||
// look up the actual rows based on the ids
|
// look up the actual rows based on the ids
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { InvalidFileExtensions } from "@budibase/shared-core"
|
import { InvalidFileExtensions } from "@budibase/shared-core"
|
||||||
|
|
||||||
import AppComponent from "./templates/BudibaseApp.svelte"
|
import AppComponent from "./templates/BudibaseApp.svelte"
|
||||||
|
|
||||||
import { join } from "../../../utilities/centralPath"
|
import { join } from "../../../utilities/centralPath"
|
||||||
import * as uuid from "uuid"
|
import * as uuid from "uuid"
|
||||||
import { ObjectStoreBuckets } from "../../../constants"
|
import { ObjectStoreBuckets } from "../../../constants"
|
||||||
|
@ -23,11 +25,9 @@ import sdk from "../../../sdk"
|
||||||
import * as pro from "@budibase/pro"
|
import * as pro from "@budibase/pro"
|
||||||
import {
|
import {
|
||||||
DocumentType,
|
DocumentType,
|
||||||
UserCtx,
|
|
||||||
App,
|
App,
|
||||||
Ctx,
|
Ctx,
|
||||||
ProcessAttachmentResponse,
|
ProcessAttachmentResponse,
|
||||||
Feature,
|
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import {
|
import {
|
||||||
getAppMigrationVersion,
|
getAppMigrationVersion,
|
||||||
|
@ -36,61 +36,6 @@ import {
|
||||||
|
|
||||||
import send from "koa-send"
|
import send from "koa-send"
|
||||||
|
|
||||||
const getThemeVariables = (theme: string) => {
|
|
||||||
if (theme === "spectrum--lightest") {
|
|
||||||
return `
|
|
||||||
--spectrum-global-color-gray-50: rgb(255, 255, 255);
|
|
||||||
--spectrum-global-color-gray-200: rgb(244, 244, 244);
|
|
||||||
--spectrum-global-color-gray-300: rgb(234, 234, 234);
|
|
||||||
--spectrum-alias-background-color-primary: var(--spectrum-global-color-gray-50);
|
|
||||||
`
|
|
||||||
}
|
|
||||||
if (theme === "spectrum--light") {
|
|
||||||
return `
|
|
||||||
--spectrum-global-color-gray-50: rgb(255, 255, 255);
|
|
||||||
--spectrum-global-color-gray-200: rgb(234, 234, 234);
|
|
||||||
--spectrum-global-color-gray-300: rgb(225, 225, 225);
|
|
||||||
--spectrum-alias-background-color-primary: var(--spectrum-global-color-gray-50);
|
|
||||||
|
|
||||||
`
|
|
||||||
}
|
|
||||||
if (theme === "spectrum--dark") {
|
|
||||||
return `
|
|
||||||
--spectrum-global-color-gray-100: rgb(50, 50, 50);
|
|
||||||
--spectrum-global-color-gray-200: rgb(62, 62, 62);
|
|
||||||
--spectrum-global-color-gray-300: rgb(74, 74, 74);
|
|
||||||
--spectrum-alias-background-color-primary: var(--spectrum-global-color-gray-100);
|
|
||||||
`
|
|
||||||
}
|
|
||||||
if (theme === "spectrum--darkest") {
|
|
||||||
return `
|
|
||||||
--spectrum-global-color-gray-100: rgb(30, 30, 30);
|
|
||||||
--spectrum-global-color-gray-200: rgb(44, 44, 44);
|
|
||||||
--spectrum-global-color-gray-300: rgb(57, 57, 57);
|
|
||||||
--spectrum-alias-background-color-primary: var(--spectrum-global-color-gray-100);
|
|
||||||
`
|
|
||||||
}
|
|
||||||
if (theme === "spectrum--nord") {
|
|
||||||
return `
|
|
||||||
--spectrum-global-color-gray-100: #3b4252;
|
|
||||||
|
|
||||||
--spectrum-global-color-gray-200: #424a5c;
|
|
||||||
--spectrum-global-color-gray-300: #4c566a;
|
|
||||||
--spectrum-alias-background-color-primary: var(--spectrum-global-color-gray-100);
|
|
||||||
`
|
|
||||||
}
|
|
||||||
if (theme === "spectrum--midnight") {
|
|
||||||
return `
|
|
||||||
--hue: 220;
|
|
||||||
--sat: 10%;
|
|
||||||
--spectrum-global-color-gray-100: hsl(var(--hue), var(--sat), 17%);
|
|
||||||
--spectrum-global-color-gray-200: hsl(var(--hue), var(--sat), 20%);
|
|
||||||
--spectrum-global-color-gray-300: hsl(var(--hue), var(--sat), 24%);
|
|
||||||
--spectrum-alias-background-color-primary: var(--spectrum-global-color-gray-100);
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const toggleBetaUiFeature = async function (ctx: Ctx) {
|
export const toggleBetaUiFeature = async function (ctx: Ctx) {
|
||||||
const cookieName = `beta:${ctx.params.feature}`
|
const cookieName = `beta:${ctx.params.feature}`
|
||||||
|
|
||||||
|
@ -205,7 +150,7 @@ const requiresMigration = async (ctx: Ctx) => {
|
||||||
return requiresMigrations
|
return requiresMigrations
|
||||||
}
|
}
|
||||||
|
|
||||||
export const serveApp = async function (ctx: UserCtx) {
|
export const serveApp = async function (ctx: Ctx) {
|
||||||
const needMigrations = await requiresMigration(ctx)
|
const needMigrations = await requiresMigration(ctx)
|
||||||
|
|
||||||
const bbHeaderEmbed =
|
const bbHeaderEmbed =
|
||||||
|
@ -226,19 +171,9 @@ export const serveApp = async function (ctx: UserCtx) {
|
||||||
const appInfo = await db.get<any>(DocumentType.APP_METADATA)
|
const appInfo = await db.get<any>(DocumentType.APP_METADATA)
|
||||||
let appId = context.getAppId()
|
let appId = context.getAppId()
|
||||||
|
|
||||||
const hideDevTools = !!ctx.params.appUrl
|
|
||||||
const sideNav = appInfo.navigation.navigation === "Left"
|
|
||||||
const hideFooter =
|
|
||||||
ctx?.user?.license?.features?.includes(Feature.BRANDING) || false
|
|
||||||
const themeVariables = getThemeVariables(appInfo?.theme)
|
|
||||||
|
|
||||||
if (!env.isJest()) {
|
if (!env.isJest()) {
|
||||||
const plugins = objectStore.enrichPluginURLs(appInfo.usedPlugins)
|
const plugins = objectStore.enrichPluginURLs(appInfo.usedPlugins)
|
||||||
|
|
||||||
const { head, html, css } = AppComponent.render({
|
const { head, html, css } = AppComponent.render({
|
||||||
hideDevTools,
|
|
||||||
sideNav,
|
|
||||||
hideFooter,
|
|
||||||
metaImage:
|
metaImage:
|
||||||
branding?.metaImageUrl ||
|
branding?.metaImageUrl ||
|
||||||
"https://res.cloudinary.com/daog6scxm/image/upload/v1698759482/meta-images/plain-branded-meta-image-coral_ocxmgu.png",
|
"https://res.cloudinary.com/daog6scxm/image/upload/v1698759482/meta-images/plain-branded-meta-image-coral_ocxmgu.png",
|
||||||
|
@ -263,7 +198,7 @@ export const serveApp = async function (ctx: UserCtx) {
|
||||||
ctx.body = await processString(appHbs, {
|
ctx.body = await processString(appHbs, {
|
||||||
head,
|
head,
|
||||||
body: html,
|
body: html,
|
||||||
css: `:root{${themeVariables}} ${css.code}`,
|
style: css.code,
|
||||||
appId,
|
appId,
|
||||||
embedded: bbHeaderEmbed,
|
embedded: bbHeaderEmbed,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<script>
|
<script>
|
||||||
import ClientAppSkeleton from "@budibase/frontend-core/src/components/ClientAppSkeleton.svelte"
|
|
||||||
|
|
||||||
export let title = ""
|
export let title = ""
|
||||||
export let favicon = ""
|
export let favicon = ""
|
||||||
|
|
||||||
|
@ -11,10 +9,6 @@
|
||||||
export let clientLibPath
|
export let clientLibPath
|
||||||
export let usedPlugins
|
export let usedPlugins
|
||||||
export let appMigrating
|
export let appMigrating
|
||||||
|
|
||||||
export let hideDevTools
|
|
||||||
export let sideNav
|
|
||||||
export let hideFooter
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
@ -102,7 +96,6 @@
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<body id="app">
|
<body id="app">
|
||||||
<ClientAppSkeleton {hideDevTools} {sideNav} {hideFooter} />
|
|
||||||
<div id="error">
|
<div id="error">
|
||||||
{#if clientLibPath}
|
{#if clientLibPath}
|
||||||
<h1>There was an error loading your app</h1>
|
<h1>There was an error loading your app</h1>
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
<html>
|
<html>
|
||||||
<script>
|
|
||||||
document.fonts.ready.then(() => {
|
|
||||||
window.parent.postMessage({ type: "docLoaded" });
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
<head>
|
<head>
|
||||||
{{{head}}}
|
{{{head}}}
|
||||||
<style>{{{css}}}</style>
|
<style>{{{style}}}</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -51,8 +51,8 @@ router
|
||||||
controller.deleteObjects
|
controller.deleteObjects
|
||||||
)
|
)
|
||||||
.get("/app/preview", authorized(BUILDER), controller.serveBuilderPreview)
|
.get("/app/preview", authorized(BUILDER), controller.serveBuilderPreview)
|
||||||
.get("/app/:appUrl/:path*", controller.serveApp)
|
|
||||||
.get("/:appId/:path*", controller.serveApp)
|
.get("/:appId/:path*", controller.serveApp)
|
||||||
|
.get("/app/:appUrl/:path*", controller.serveApp)
|
||||||
.post(
|
.post(
|
||||||
"/api/attachments/:datasourceId/url",
|
"/api/attachments/:datasourceId/url",
|
||||||
authorized(PermissionType.TABLE, PermissionLevel.READ),
|
authorized(PermissionType.TABLE, PermissionLevel.READ),
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import {
|
import {
|
||||||
DEFAULT_BB_DATASOURCE_ID,
|
DEFAULT_BB_DATASOURCE_ID,
|
||||||
DEFAULT_INVENTORY_TABLE_ID,
|
|
||||||
DEFAULT_EMPLOYEE_TABLE_ID,
|
DEFAULT_EMPLOYEE_TABLE_ID,
|
||||||
DEFAULT_EXPENSES_TABLE_ID,
|
DEFAULT_EXPENSES_TABLE_ID,
|
||||||
|
DEFAULT_INVENTORY_TABLE_ID,
|
||||||
DEFAULT_JOBS_TABLE_ID,
|
DEFAULT_JOBS_TABLE_ID,
|
||||||
} from "../../constants"
|
} from "../../constants"
|
||||||
import { importToRows } from "../../api/controllers/table/utils"
|
import { importToRows } from "../../api/controllers/table/utils"
|
||||||
|
@ -15,19 +15,21 @@ import { expensesImport } from "./expensesImport"
|
||||||
import { db as dbCore } from "@budibase/backend-core"
|
import { db as dbCore } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
AutoFieldSubType,
|
AutoFieldSubType,
|
||||||
|
Datasource,
|
||||||
FieldType,
|
FieldType,
|
||||||
RelationshipType,
|
RelationshipType,
|
||||||
Row,
|
Row,
|
||||||
|
SourceName,
|
||||||
Table,
|
Table,
|
||||||
TableSchema,
|
TableSchema,
|
||||||
TableSourceType,
|
TableSourceType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
const defaultDatasource = {
|
const defaultDatasource: Datasource = {
|
||||||
_id: DEFAULT_BB_DATASOURCE_ID,
|
_id: DEFAULT_BB_DATASOURCE_ID,
|
||||||
type: dbCore.BUDIBASE_DATASOURCE_TYPE,
|
type: dbCore.BUDIBASE_DATASOURCE_TYPE,
|
||||||
name: "Sample Data",
|
name: "Sample Data",
|
||||||
source: "BUDIBASE",
|
source: SourceName.BUDIBASE,
|
||||||
config: {},
|
config: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import newid from "./newid"
|
import newid from "./newid"
|
||||||
import { db as dbCore } from "@budibase/backend-core"
|
import { db as dbCore } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
FieldType,
|
DatabaseQueryOpts,
|
||||||
|
Datasource,
|
||||||
DocumentType,
|
DocumentType,
|
||||||
FieldSchema,
|
FieldSchema,
|
||||||
RelationshipFieldMetadata,
|
FieldType,
|
||||||
VirtualDocumentType,
|
|
||||||
INTERNAL_TABLE_SOURCE_ID,
|
INTERNAL_TABLE_SOURCE_ID,
|
||||||
DatabaseQueryOpts,
|
RelationshipFieldMetadata,
|
||||||
|
SourceName,
|
||||||
|
VirtualDocumentType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export { DocumentType, VirtualDocumentType } from "@budibase/types"
|
export { DocumentType, VirtualDocumentType } from "@budibase/types"
|
||||||
|
@ -20,11 +22,11 @@ export const enum AppStatus {
|
||||||
DEPLOYED = "published",
|
DEPLOYED = "published",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BudibaseInternalDB = {
|
export const BudibaseInternalDB: Datasource = {
|
||||||
_id: INTERNAL_TABLE_SOURCE_ID,
|
_id: INTERNAL_TABLE_SOURCE_ID,
|
||||||
type: dbCore.BUDIBASE_DATASOURCE_TYPE,
|
type: dbCore.BUDIBASE_DATASOURCE_TYPE,
|
||||||
name: "Budibase DB",
|
name: "Budibase DB",
|
||||||
source: "BUDIBASE",
|
source: SourceName.BUDIBASE,
|
||||||
config: {},
|
config: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ const DEFINITIONS: Record<SourceName, Integration | undefined> = {
|
||||||
[SourceName.REDIS]: redis.schema,
|
[SourceName.REDIS]: redis.schema,
|
||||||
[SourceName.SNOWFLAKE]: snowflake.schema,
|
[SourceName.SNOWFLAKE]: snowflake.schema,
|
||||||
[SourceName.ORACLE]: undefined,
|
[SourceName.ORACLE]: undefined,
|
||||||
|
[SourceName.BUDIBASE]: undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
const INTEGRATIONS: Record<SourceName, any> = {
|
const INTEGRATIONS: Record<SourceName, any> = {
|
||||||
|
@ -56,6 +57,7 @@ const INTEGRATIONS: Record<SourceName, any> = {
|
||||||
[SourceName.REDIS]: redis.integration,
|
[SourceName.REDIS]: redis.integration,
|
||||||
[SourceName.SNOWFLAKE]: snowflake.integration,
|
[SourceName.SNOWFLAKE]: snowflake.integration,
|
||||||
[SourceName.ORACLE]: undefined,
|
[SourceName.ORACLE]: undefined,
|
||||||
|
[SourceName.BUDIBASE]: undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
// optionally add oracle integration if the oracle binary can be installed
|
// optionally add oracle integration if the oracle binary can be installed
|
||||||
|
|
|
@ -85,7 +85,9 @@ async function getImportableDocuments(db: Database) {
|
||||||
const docPromises = []
|
const docPromises = []
|
||||||
for (let docType of DocumentTypesToImport) {
|
for (let docType of DocumentTypesToImport) {
|
||||||
docPromises.push(
|
docPromises.push(
|
||||||
db.allDocs(dbCore.getDocParams(docType, null, { include_docs: true }))
|
db.allDocs<Document>(
|
||||||
|
dbCore.getDocParams(docType, null, { include_docs: true })
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// map the responses to the document itself
|
// map the responses to the document itself
|
||||||
|
|
|
@ -229,7 +229,7 @@ export async function removeSecretSingle(datasource: Datasource) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mergeConfigs(update: Datasource, old: Datasource) {
|
export function mergeConfigs(update: Datasource, old: Datasource) {
|
||||||
if (!update.config) {
|
if (!update.config || !old.config) {
|
||||||
return update
|
return update
|
||||||
}
|
}
|
||||||
// specific to REST datasources, fix the auth configs again if required
|
// specific to REST datasources, fix the auth configs again if required
|
||||||
|
|
|
@ -32,9 +32,7 @@ export interface FetchDatasourceInfoResponse {
|
||||||
tableNames: string[]
|
tableNames: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateDatasourceRequest extends Datasource {
|
export interface UpdateDatasourceRequest extends Datasource {}
|
||||||
datasource: Datasource
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BuildSchemaFromSourceRequest {
|
export interface BuildSchemaFromSourceRequest {
|
||||||
tablesFilter?: string[]
|
tablesFilter?: string[]
|
||||||
|
|
|
@ -6,6 +6,9 @@ export interface Datasource extends Document {
|
||||||
type: string
|
type: string
|
||||||
name?: string
|
name?: string
|
||||||
source: SourceName
|
source: SourceName
|
||||||
|
// this is a googlesheets specific property which
|
||||||
|
// can be found in the GSheets schema - pertains to SSO creds
|
||||||
|
auth?: { type: string }
|
||||||
// the config is defined by the schema
|
// the config is defined by the schema
|
||||||
config?: Record<string, any>
|
config?: Record<string, any>
|
||||||
plus?: boolean
|
plus?: boolean
|
||||||
|
@ -36,6 +39,12 @@ export interface RestAuthConfig {
|
||||||
config: RestBasicAuthConfig | RestBearerAuthConfig
|
config: RestBasicAuthConfig | RestBearerAuthConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DynamicVariable {
|
||||||
|
name: string
|
||||||
|
queryId: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface RestConfig {
|
export interface RestConfig {
|
||||||
url: string
|
url: string
|
||||||
rejectUnauthorized: boolean
|
rejectUnauthorized: boolean
|
||||||
|
@ -47,11 +56,5 @@ export interface RestConfig {
|
||||||
staticVariables: {
|
staticVariables: {
|
||||||
[key: string]: string
|
[key: string]: string
|
||||||
}
|
}
|
||||||
dynamicVariables: [
|
dynamicVariables: DynamicVariable[]
|
||||||
{
|
|
||||||
name: string
|
|
||||||
queryId: string
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,15 @@ export interface RowValue {
|
||||||
deleted: boolean
|
deleted: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RowResponse<T extends Document> {
|
export interface RowResponse<T extends Document | RowValue> {
|
||||||
id: string
|
id: string
|
||||||
key: string
|
key: string
|
||||||
error: string
|
error: string
|
||||||
value: T | RowValue
|
value: T
|
||||||
doc?: T
|
doc?: T
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AllDocsResponse<T extends Document> {
|
export interface AllDocsResponse<T extends Document | RowValue> {
|
||||||
offset: number
|
offset: number
|
||||||
total_rows: number
|
total_rows: number
|
||||||
rows: RowResponse<T>[]
|
rows: RowResponse<T>[]
|
||||||
|
|
|
@ -57,6 +57,7 @@ export enum SourceName {
|
||||||
FIRESTORE = "FIRESTORE",
|
FIRESTORE = "FIRESTORE",
|
||||||
REDIS = "REDIS",
|
REDIS = "REDIS",
|
||||||
SNOWFLAKE = "SNOWFLAKE",
|
SNOWFLAKE = "SNOWFLAKE",
|
||||||
|
BUDIBASE = "BUDIBASE",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum IncludeRelationship {
|
export enum IncludeRelationship {
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
import type Nano from "@budibase/nano"
|
import type Nano from "@budibase/nano"
|
||||||
import { AllDocsResponse, AnyDocument, Document, ViewTemplateOpts } from "../"
|
import {
|
||||||
|
AllDocsResponse,
|
||||||
|
AnyDocument,
|
||||||
|
Document,
|
||||||
|
RowValue,
|
||||||
|
ViewTemplateOpts,
|
||||||
|
} from "../"
|
||||||
import { Writable } from "stream"
|
import { Writable } from "stream"
|
||||||
|
|
||||||
export enum SearchIndex {
|
export enum SearchIndex {
|
||||||
|
@ -135,8 +141,8 @@ export interface Database {
|
||||||
opts?: DatabasePutOpts
|
opts?: DatabasePutOpts
|
||||||
): Promise<Nano.DocumentInsertResponse>
|
): Promise<Nano.DocumentInsertResponse>
|
||||||
bulkDocs(documents: AnyDocument[]): Promise<Nano.DocumentBulkResponse[]>
|
bulkDocs(documents: AnyDocument[]): Promise<Nano.DocumentBulkResponse[]>
|
||||||
sql<T>(sql: string): Promise<T>
|
sql<T extends Document>(sql: string): Promise<T>
|
||||||
allDocs<T extends Document>(
|
allDocs<T extends Document | RowValue>(
|
||||||
params: DatabaseQueryOpts
|
params: DatabaseQueryOpts
|
||||||
): Promise<AllDocsResponse<T>>
|
): Promise<AllDocsResponse<T>>
|
||||||
query<T extends Document>(
|
query<T extends Document>(
|
||||||
|
|
|
@ -17,6 +17,12 @@ const { nodeExternalsPlugin } = require("esbuild-node-externals")
|
||||||
const svelteCompilePlugin = {
|
const svelteCompilePlugin = {
|
||||||
name: 'svelteCompile',
|
name: 'svelteCompile',
|
||||||
setup(build) {
|
setup(build) {
|
||||||
|
// This resolve handler is necessary to bundle the Svelte runtime into the the final output,
|
||||||
|
// otherwise the bundled script will attempt to resolve it at runtime
|
||||||
|
build.onResolve({ filter: /svelte\/internal/ }, async () => {
|
||||||
|
return { path: `${process.cwd()}/../../node_modules/svelte/src/runtime/internal/ssr.js` }
|
||||||
|
})
|
||||||
|
|
||||||
// Compiles `.svelte` files into JS classes so that they can be directly imported into our
|
// Compiles `.svelte` files into JS classes so that they can be directly imported into our
|
||||||
// Typescript packages
|
// Typescript packages
|
||||||
build.onLoad({ filter: /\.svelte$/ }, async (args) => {
|
build.onLoad({ filter: /\.svelte$/ }, async (args) => {
|
||||||
|
@ -31,7 +37,7 @@ const svelteCompilePlugin = {
|
||||||
contents: js.code,
|
contents: js.code,
|
||||||
// The loader this is passed to, basically how the above provided content is "treated",
|
// The loader this is passed to, basically how the above provided content is "treated",
|
||||||
// the contents provided above will be transpiled and bundled like any other JS file.
|
// the contents provided above will be transpiled and bundled like any other JS file.
|
||||||
loader: 'js',
|
loader: 'js',
|
||||||
// Where to resolve any imports present in the loaded file
|
// Where to resolve any imports present in the loaded file
|
||||||
resolveDir: dir
|
resolveDir: dir
|
||||||
}
|
}
|
||||||
|
@ -74,11 +80,11 @@ async function runBuild(entry, outfile) {
|
||||||
plugins: [
|
plugins: [
|
||||||
svelteCompilePlugin,
|
svelteCompilePlugin,
|
||||||
TsconfigPathsPlugin({ tsconfig: tsconfigPathPluginContent }),
|
TsconfigPathsPlugin({ tsconfig: tsconfigPathPluginContent }),
|
||||||
nodeExternalsPlugin({
|
nodeExternalsPlugin(),
|
||||||
allowList: ["@budibase/frontend-core", "svelte"]
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
preserveSymlinks: true,
|
preserveSymlinks: true,
|
||||||
|
loader: {
|
||||||
|
},
|
||||||
metafile: true,
|
metafile: true,
|
||||||
external: [
|
external: [
|
||||||
"deasync",
|
"deasync",
|
||||||
|
|
Loading…
Reference in New Issue