Merge branch 'develop' of github.com:Budibase/budibase into feature/sync-automations

This commit is contained in:
mike12345567 2023-05-26 16:42:01 +01:00
commit 7ba21d836b
52 changed files with 401 additions and 259 deletions

View File

@ -44,7 +44,10 @@ jobs:
node-version: 14.x
cache: "yarn"
- run: yarn
- run: yarn nx run-many -t=build --configuration=production
# Run build all the projects
- run: yarn build
# Check the types of the projects built via esbuild
- run: yarn check:types
test-libraries:
runs-on: ubuntu-latest

View File

@ -54,6 +54,9 @@ jobs:
- run: yarn build --configuration=production
- run: yarn build:sdk
- name: Reset pro dependencies
run: node scripts/resetProDependencies.js
- name: Publish budibase packages to NPM
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -60,6 +60,9 @@ jobs:
- run: yarn build --configuration=production
- run: yarn build:sdk
- name: Reset pro dependencies
run: node scripts/resetProDependencies.js
- name: Publish budibase packages to NPM
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -1,5 +1,5 @@
{
"version": "2.6.19-alpha.12",
"version": "2.6.19-alpha.20",
"npmClient": "yarn",
"packages": [
"packages/backend-core",

View File

@ -4,7 +4,6 @@
"devDependencies": {
"@esbuild-plugins/node-resolve": "^0.2.2",
"@esbuild-plugins/tsconfig-paths": "^0.1.2",
"@nx/esbuild": "16.2.1",
"@nx/js": "16.2.1",
"@rollup/plugin-json": "^4.0.2",
"@typescript-eslint/parser": "5.45.0",
@ -34,6 +33,7 @@
"bootstrap": "./scripts/link-dependencies.sh && echo '***BOOTSTRAP ONLY REQUIRED FOR USE WITH ACCOUNT PORTAL***'",
"build": "yarn nx run-many -t=build",
"build:dev": "lerna run --stream prebuild && yarn nx run-many --target=build --output-style=dynamic --watch --preserveWatchOutput",
"check:types": "lerna run check:types --skip-nx-cache",
"backend:bootstrap": "./scripts/scopeBackend.sh && yarn run bootstrap",
"backend:build": "./scripts/scopeBackend.sh 'lerna run --stream build'",
"build:sdk": "lerna run --stream build:sdk",
@ -52,7 +52,7 @@
"dev:noserver": "yarn run kill-builder && lerna run --stream dev:stack:up && lerna run --stream --parallel dev:builder --ignore @budibase/backend-core --ignore @budibase/server --ignore @budibase/worker",
"dev:server": "yarn run kill-server && lerna run --stream --parallel dev:builder --scope @budibase/worker --scope @budibase/server",
"dev:built": "yarn run kill-all && cd packages/server && yarn dev:stack:up && cd ../../ && lerna run --stream --parallel dev:built",
"dev:docker": "yarn build && docker-compose -f hosting/docker-compose.dev.yaml -f hosting/docker-compose.build.yaml up --build --scale proxy-service=0 ",
"dev:docker": "yarn build && docker-compose -f hosting/docker-compose.build.yaml -f hosting/docker-compose.dev.yaml --env-file hosting/.env up --build --scale proxy-service=0",
"test": "lerna run --stream test --stream",
"lint:eslint": "eslint packages && eslint qa-core",
"lint:prettier": "prettier --check \"packages/**/*.{js,ts,svelte}\" && prettier --write \"examples/**/*.{js,ts,svelte}\" && prettier --check \"qa-core/**/*.{js,ts,svelte}\"",

View File

@ -2,6 +2,7 @@ import { datasources, tables } from "../stores/backend"
import { IntegrationNames } from "../constants/backend"
import { get } from "svelte/store"
import cloneDeep from "lodash/cloneDeepWith"
import { API } from "api"
function prepareData(config) {
let datasource = {}
@ -37,3 +38,9 @@ export async function createRestDatasource(integration) {
const config = cloneDeep(integration)
return saveDatasource(config)
}
export async function validateDatasourceConfig(config) {
const datasource = prepareData(config)
const resp = await API.validateDatasource(datasource)
return resp
}

View File

@ -53,6 +53,7 @@
config,
schema: selected.datasource,
auth: selected.auth,
features: selected.features || [],
}
if (selected.friendlyName) {
integration.name = selected.friendlyName

View File

@ -4,55 +4,68 @@
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
import { IntegrationNames } from "constants/backend"
import cloneDeep from "lodash/cloneDeepWith"
import { saveDatasource as save } from "builderStore/datasource"
import { onMount } from "svelte"
import {
saveDatasource as save,
validateDatasourceConfig,
} from "builderStore/datasource"
import { DatasourceFeature } from "@budibase/types"
export let integration
export let modal
// kill the reference so the input isn't saved
let datasource = cloneDeep(integration)
let skipFetch = false
let isValid = false
$: name =
IntegrationNames[datasource.type] || datasource.name || datasource.type
async function validateConfig() {
const displayError = message =>
notifications.error(message ?? "Error validating datasource")
let connected = false
try {
const resp = await validateDatasourceConfig(datasource)
if (!resp.connected) {
displayError(`Unable to connect - ${resp.error}`)
}
connected = resp.connected
} catch (err) {
displayError(err?.message)
}
return connected
}
async function saveDatasource() {
if (integration.features[DatasourceFeature.CONNECTION_CHECKING]) {
const valid = await validateConfig()
if (!valid) {
return false
}
}
try {
if (!datasource.name) {
datasource.name = name
}
const resp = await save(datasource, skipFetch)
const resp = await save(datasource)
$goto(`./datasource/${resp._id}`)
notifications.success(`Datasource updated successfully.`)
notifications.success(`Datasource created successfully.`)
} catch (err) {
notifications.error(err?.message ?? "Error saving datasource")
// prevent the modal from closing
return false
}
}
onMount(() => {
skipFetch = false
})
</script>
<ModalContent
title={`Connect to ${name}`}
onConfirm={() => saveDatasource()}
onCancel={() => modal.show()}
confirmText={datasource.plus
? "Save and fetch tables"
: "Save and continue to query"}
confirmText={datasource.plus ? "Connect" : "Save and continue to query"}
cancelText="Back"
showSecondaryButton={datasource.plus}
secondaryButtonText={datasource.plus ? "Skip table fetch" : undefined}
secondaryAction={() => {
skipFetch = true
saveDatasource()
return true
}}
size="L"
disabled={!isValid}
>

View File

@ -20,6 +20,8 @@
import { isEqual } from "lodash"
import { cloneDeep } from "lodash/fp"
import ImportRestQueriesModal from "components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte"
import { API } from "api"
import { DatasourceFeature } from "@budibase/types"
const querySchema = {
name: {},
@ -45,7 +47,30 @@
}
}
async function validateConfig() {
const displayError = message =>
notifications.error(message ?? "Error validating datasource")
let connected = false
try {
const resp = await API.validateDatasource(datasource)
if (!resp.connected) {
displayError(`Unable to connect - ${resp.error}`)
}
connected = resp.connected
} catch (err) {
displayError(err?.message)
}
return connected
}
const saveDatasource = async () => {
if (integration.features[DatasourceFeature.CONNECTION_CHECKING]) {
const valid = await validateConfig()
if (!valid) {
return false
}
}
try {
// Create datasource
await datasources.save(datasource)

View File

@ -31,6 +31,18 @@
return "Invalid URL"
}
}
$: urlManuallySet = false
const updateUrl = event => {
const appName = event.detail
if (urlManuallySet) {
return
}
const parsedUrl = appName.toLowerCase().replace(/\s+/g, "-")
url = encodeURI(parsedUrl)
}
</script>
<div>
@ -43,11 +55,13 @@
bind:value={name}
bind:error={nameError}
validate={validateName}
on:change={updateUrl}
label="Name"
/>
<FancyInput
bind:value={url}
bind:error={urlError}
on:change={() => (urlManuallySet = true)}
validate={validateUrl}
label="URL"
/>

View File

@ -18,6 +18,8 @@
import { Roles } from "constants/backend"
import Spinner from "components/common/Spinner.svelte"
import { helpers } from "@budibase/shared-core"
import { validateDatasourceConfig } from "builderStore/datasource"
import { DatasourceFeature } from "@budibase/types"
let name = "My first app"
let url = "my-first-app"
@ -108,7 +110,24 @@
isGoogle,
}) => {
let app
try {
if (
datasourceConfig &&
plusIntegrations[stage].features[DatasourceFeature.CONNECTION_CHECKING]
) {
const resp = await validateDatasourceConfig({
config: datasourceConfig,
type: stage,
})
if (!resp.connected) {
notifications.error(
`Unable to connect - ${resp.error ?? "Error validating datasource"}`
)
return false
}
}
app = await createApp(useSampleData)
let datasource

View File

@ -1,7 +1,7 @@
import { writable } from "svelte/store"
import { API } from "api"
import { licensing } from "./licensing"
import { ConfigType } from "../../../../types/src/documents"
import { ConfigType } from "@budibase/types"
export const createFeatureStore = () => {
const internalStore = writable({

View File

@ -58,4 +58,15 @@ export const buildDatasourceEndpoints = API => ({
url: `/api/datasources/${datasourceId}/${datasourceRev}`,
})
},
/**
* Validate a datasource configuration
* @param datasource the datasource configuration to validate
*/
validateDatasource: async datasource => {
return await API.post({
url: `/api/datasources/verify`,
body: { datasource },
})
},
})

View File

@ -37,6 +37,9 @@
.boolean-cell {
padding: 2px var(--cell-padding);
pointer-events: none;
flex: 1 1 auto;
display: flex;
justify-content: center;
}
.boolean-cell.editable {
pointer-events: all;

View File

@ -11,6 +11,7 @@
export let selected
export let rowFocused
export let rowIdx
export let topRow = false
export let focused
export let selectedUser
export let column
@ -68,6 +69,7 @@
{highlighted}
{selected}
{rowIdx}
{topRow}
{focused}
{selectedUser}
{readonly}

View File

@ -6,6 +6,7 @@
export let selectedUser = null
export let error = null
export let rowIdx
export let topRow = false
export let defaultHeight = false
export let center = false
export let readonly = false
@ -31,13 +32,14 @@
class:readonly
class:default-height={defaultHeight}
class:selected-other={selectedUser != null}
class:alt={rowIdx % 2 === 1}
class:top={topRow}
on:focus
on:mousedown
on:mouseup
on:click
on:contextmenu
{style}
data-row={rowIdx}
>
{#if error}
<div class="label">
@ -70,6 +72,9 @@
width: 0;
--cell-color: transparent;
}
.cell.alt {
--cell-background: var(--cell-background-alt);
}
.cell.default-height {
height: var(--default-row-height);
}
@ -98,8 +103,8 @@
.cell.selected-other:not(.focused):after {
border-radius: 0 2px 2px 2px;
}
.cell[data-row="0"].error:after,
.cell[data-row="0"].selected-other:not(.focused):after {
.cell.top.error:after,
.cell.top.selected-other:not(.focused):after {
border-radius: 2px 2px 2px 0;
}
@ -152,7 +157,7 @@
overflow: hidden;
user-select: none;
}
.cell[data-row="0"] .label {
.cell.top .label {
bottom: auto;
top: 100%;
border-radius: 0 2px 2px 2px;

View File

@ -21,16 +21,7 @@
svelteDispatch("select")
const id = row?._id
if (id) {
selectedRows.update(state => {
let newState = {
...state,
[id]: !state[id],
}
if (!newState[id]) {
delete newState[id]
}
return newState
})
selectedRows.actions.toggleRow(id)
}
}
@ -47,6 +38,7 @@
highlighted={rowFocused || rowHovered}
selected={rowSelected}
{defaultHeight}
rowIdx={row?.__idx}
>
<div class="gutter">
{#if $$slots.default}

View File

@ -196,7 +196,11 @@
<MenuItem disabled={!canMoveRight} icon="ChevronRight" on:click={moveRight}>
Move right
</MenuItem>
<MenuItem icon="VisibilityOff" on:click={hideColumn}>Hide column</MenuItem>
<MenuItem
disabled={idx === "sticky"}
icon="VisibilityOff"
on:click={hideColumn}>Hide column</MenuItem
>
</Menu>
</Popover>

View File

@ -41,6 +41,7 @@
export let allowExpandRows = true
export let allowEditRows = true
export let allowDeleteRows = true
export let stripeRows = false
// Unique identifier for DOM nodes inside this instance
const rand = Math.random()
@ -55,6 +56,7 @@
allowExpandRows,
allowEditRows,
allowDeleteRows,
stripeRows,
})
// Build up context
@ -90,6 +92,7 @@
allowExpandRows,
allowEditRows,
allowDeleteRows,
stripeRows,
})
// Set context for children to consume
@ -107,6 +110,7 @@
id="grid-{rand}"
class:is-resizing={$isResizing}
class:is-reordering={$isReordering}
class:stripe={$config.stripeRows}
style="--row-height:{$rowHeight}px; --default-row-height:{DefaultRowHeight}px; --gutter-width:{GutterWidth}px; --max-cell-render-height:{MaxCellRenderHeight}px; --max-cell-render-width-overflow:{MaxCellRenderWidthOverflow}px; --content-lines:{$contentLines};"
>
<div class="controls">
@ -169,6 +173,7 @@
/* Variables */
--cell-background: var(--spectrum-global-color-gray-50);
--cell-background-hover: var(--spectrum-global-color-gray-100);
--cell-background-alt: var(--cell-background);
--cell-padding: 8px;
--cell-spacing: 4px;
--cell-border: 1px solid var(--spectrum-global-color-gray-200);
@ -185,6 +190,9 @@
.grid.is-reordering :global(*) {
cursor: grabbing !important;
}
.grid.stripe {
--cell-background-alt: var(--spectrum-global-color-gray-75);
}
.grid-data-outer,
.grid-data-inner {

View File

@ -36,7 +36,11 @@
<div bind:this={body} class="grid-body">
<GridScrollWrapper scrollHorizontally scrollVertically wheelInteractive>
{#each $renderedRows as row, idx}
<GridRow {row} {idx} invertY={idx >= $rowVerticalInversionIndex} />
<GridRow
{row}
top={idx === 0}
invertY={idx >= $rowVerticalInversionIndex}
/>
{/each}
{#if $config.allowAddRows && $renderedColumns.length}
<div

View File

@ -3,7 +3,7 @@
import DataCell from "../cells/DataCell.svelte"
export let row
export let idx
export let top = false
export let invertY = false
const {
@ -41,7 +41,8 @@
invertX={columnIdx >= $columnHorizontalInversionIndex}
highlighted={rowHovered || rowFocused || reorderSource === column.name}
selected={rowSelected}
rowIdx={idx}
rowIdx={row.__idx}
topRow={top}
focused={$focusedCellId === cellId}
selectedUser={$selectedCellMap[cellId]}
width={column.width}

View File

@ -61,7 +61,7 @@
border-right: var(--cell-border);
border-bottom: var(--cell-border);
background: var(--spectrum-global-color-gray-100);
z-index: 20;
z-index: 1;
}
.add:hover {
background: var(--spectrum-global-color-gray-200);

View File

@ -38,7 +38,7 @@
padding: 2px 6px;
font-size: 12px;
font-weight: 600;
background-color: var(--spectrum-global-color-gray-200);
background-color: var(--spectrum-global-color-gray-300);
color: var(--spectrum-global-color-gray-700);
border-radius: 4px;
text-align: center;

View File

@ -167,7 +167,7 @@
focused={$focusedCellId === cellId}
width={$stickyColumn.width}
{updateValue}
rowIdx={0}
topRow={offset === 0}
{invertY}
>
{#if $stickyColumn?.schema?.autocolumn}
@ -193,7 +193,7 @@
row={newRow}
focused={$focusedCellId === cellId}
width={column.width}
rowIdx={0}
topRow={offset === 0}
invertX={columnIdx >= $columnHorizontalInversionIndex}
{invertY}
>
@ -219,7 +219,7 @@
<Button size="M" secondary newStyles on:click={clear}>
<div class="button-with-keys">
Cancel
<KeyboardShortcut overlay keybind="Esc" />
<KeyboardShortcut keybind="Esc" />
</div>
</Button>
</div>

View File

@ -82,7 +82,8 @@
{rowFocused}
selected={rowSelected}
highlighted={rowHovered || rowFocused}
rowIdx={idx}
rowIdx={row.__idx}
topRow={idx === 0}
focused={$focusedCellId === cellId}
selectedUser={$selectedCellMap[cellId]}
width={$stickyColumn.width}

View File

@ -224,10 +224,7 @@
if (!id || id === NewRowID) {
return
}
selectedRows.update(state => {
state[id] = !state[id]
return state
})
selectedRows.actions.toggleRow(id)
}
onMount(() => {

View File

@ -4,9 +4,10 @@ const reorderInitialState = {
sourceColumn: null,
targetColumn: null,
breakpoints: [],
initialMouseX: null,
scrollLeft: 0,
gridLeft: 0,
width: 0,
latestX: 0,
increment: 0,
}
export const createStores = () => {
@ -23,14 +24,24 @@ export const createStores = () => {
}
export const deriveStores = context => {
const { reorder, columns, visibleColumns, scroll, bounds, stickyColumn, ui } =
context
const {
reorder,
columns,
visibleColumns,
scroll,
bounds,
stickyColumn,
ui,
maxScrollLeft,
} = context
let autoScrollInterval
let isAutoScrolling
// Callback when dragging on a colum header and starting reordering
const startReordering = (column, e) => {
const $visibleColumns = get(visibleColumns)
const $bounds = get(bounds)
const $scroll = get(scroll)
const $stickyColumn = get(stickyColumn)
ui.actions.blur()
@ -51,9 +62,8 @@ export const deriveStores = context => {
sourceColumn: column,
targetColumn: null,
breakpoints,
initialMouseX: e.clientX,
scrollLeft: $scroll.left,
gridLeft: $bounds.left,
width: $bounds.width,
})
// Add listeners to handle mouse movement
@ -66,12 +76,44 @@ export const deriveStores = context => {
// Callback when moving the mouse when reordering columns
const onReorderMouseMove = e => {
// Immediately handle the current position
const x = e.clientX
reorder.update(state => ({
...state,
latestX: x,
}))
considerReorderPosition()
// Check if we need to start auto-scrolling
const $reorder = get(reorder)
const proximityCutoff = 140
const speedFactor = 8
const rightProximity = Math.max(0, $reorder.gridLeft + $reorder.width - x)
const leftProximity = Math.max(0, x - $reorder.gridLeft)
if (rightProximity < proximityCutoff) {
const weight = proximityCutoff - rightProximity
const increment = (weight / proximityCutoff) * speedFactor
reorder.update(state => ({ ...state, increment }))
startAutoScroll()
} else if (leftProximity < proximityCutoff) {
const weight = -1 * (proximityCutoff - leftProximity)
const increment = (weight / proximityCutoff) * speedFactor
reorder.update(state => ({ ...state, increment }))
startAutoScroll()
} else {
stopAutoScroll()
}
}
// Actual logic to consider the current position and determine the new order
const considerReorderPosition = () => {
const $reorder = get(reorder)
const $scroll = get(scroll)
// Compute the closest breakpoint to the current position
let targetColumn
let minDistance = Number.MAX_SAFE_INTEGER
const mouseX = e.clientX - $reorder.gridLeft + $reorder.scrollLeft
const mouseX = $reorder.latestX - $reorder.gridLeft + $scroll.left
$reorder.breakpoints.forEach(point => {
const distance = Math.abs(point.x - mouseX)
if (distance < minDistance) {
@ -79,7 +121,6 @@ export const deriveStores = context => {
targetColumn = point.column
}
})
if (targetColumn !== $reorder.targetColumn) {
reorder.update(state => ({
...state,
@ -88,8 +129,35 @@ export const deriveStores = context => {
}
}
// Commences auto-scrolling in a certain direction, triggered when the mouse
// approaches the edges of the grid
const startAutoScroll = () => {
if (isAutoScrolling) {
return
}
isAutoScrolling = true
autoScrollInterval = setInterval(() => {
const $maxLeft = get(maxScrollLeft)
const { increment } = get(reorder)
scroll.update(state => ({
...state,
left: Math.max(0, Math.min($maxLeft, state.left + increment)),
}))
considerReorderPosition()
}, 10)
}
// Stops auto scrolling
const stopAutoScroll = () => {
isAutoScrolling = false
clearInterval(autoScrollInterval)
}
// Callback when stopping reordering columns
const stopReordering = async () => {
// Ensure auto-scrolling is stopped
stopAutoScroll()
// Swap position of columns
let { sourceColumn, targetColumn } = get(reorder)
moveColumn(sourceColumn, targetColumn)

View File

@ -25,14 +25,33 @@ export const createStores = () => {
null
)
// Toggles whether a certain row ID is selected or not
const toggleSelectedRow = id => {
selectedRows.update(state => {
let newState = {
...state,
[id]: !state[id],
}
if (!newState[id]) {
delete newState[id]
}
return newState
})
}
return {
focusedCellId,
focusedCellAPI,
focusedRowId,
previousFocusedRowId,
selectedRows,
hoveredRowId,
rowHeight,
selectedRows: {
...selectedRows,
actions: {
toggleRow: toggleSelectedRow,
},
},
}
}

View File

@ -11,6 +11,7 @@
"scripts": {
"prebuild": "rimraf dist/",
"build": "node ./scripts/build.js",
"check:types": "tsc -p tsconfig.build.json --noEmit",
"postbuild": "copyfiles -f ../client/dist/budibase-client.js ../client/manifest.json client",
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
"debug": "yarn build && node --expose-gc --inspect=9222 dist/index.js",
@ -47,7 +48,7 @@
"@apidevtools/swagger-parser": "10.0.3",
"@budibase/backend-core": "0.0.1",
"@budibase/client": "0.0.1",
"@budibase/pro": "develop",
"@budibase/pro": "0.0.1",
"@budibase/shared-core": "0.0.1",
"@budibase/string-templates": "0.0.1",
"@budibase/types": "0.0.1",

View File

@ -25,9 +25,8 @@ export async function runView(
}))
)
let fn = (doc: Document, emit: any) => emit(doc._id)
;(0, eval)(
"fn = " + view?.map?.replace("function (doc)", "function (doc, emit)")
)
// BUDI-7060 -> indirect eval call appears to cause issues in cloud
eval("fn = " + view?.map?.replace("function (doc)", "function (doc, emit)"))
const queryFns: any = {
meta: view.meta,
map: fn,

View File

@ -20,7 +20,9 @@ const SCHEMA: Integration = {
"Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.",
friendlyName: "Airtable",
type: "Spreadsheet",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
apiKey: {
type: DatasourceFieldType.PASSWORD,

View File

@ -23,7 +23,9 @@ const SCHEMA: Integration = {
type: "Non-relational",
description:
"ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. ",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
url: {
type: DatasourceFieldType.STRING,

View File

@ -20,7 +20,9 @@ const SCHEMA: Integration = {
type: "Non-relational",
description:
"Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
url: {
type: DatasourceFieldType.STRING,

View File

@ -25,7 +25,9 @@ const SCHEMA: Integration = {
"Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.",
friendlyName: "DynamoDB",
type: "Non-relational",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
region: {
type: DatasourceFieldType.STRING,

View File

@ -22,7 +22,9 @@ const SCHEMA: Integration = {
"Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.",
friendlyName: "ElasticSearch",
type: "Non-relational",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
url: {
type: DatasourceFieldType.STRING,

View File

@ -20,7 +20,9 @@ const SCHEMA: Integration = {
type: "Non-relational",
description:
"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
email: {
type: DatasourceFieldType.STRING,

View File

@ -66,10 +66,10 @@ const SCHEMA: Integration = {
"Create and collaborate on online spreadsheets in real-time and from any device.",
friendlyName: "Google Sheets",
type: "Spreadsheet",
features: [
DatasourceFeature.CONNECTION_CHECKING,
DatasourceFeature.FETCH_TABLE_NAMES,
],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
},
datasource: {
spreadsheetId: {
display: "Google Sheet URL",

View File

@ -40,10 +40,10 @@ const SCHEMA: Integration = {
"Microsoft SQL Server is a relational database management system developed by Microsoft. ",
friendlyName: "MS SQL Server",
type: "Relational",
features: [
DatasourceFeature.CONNECTION_CHECKING,
DatasourceFeature.FETCH_TABLE_NAMES,
],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
},
datasource: {
user: {
type: DatasourceFieldType.STRING,

View File

@ -40,7 +40,9 @@ const getSchema = () => {
type: "Non-relational",
description:
"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
connectionString: {
type: DatasourceFieldType.STRING,

View File

@ -36,10 +36,10 @@ const SCHEMA: Integration = {
type: "Relational",
description:
"MySQL Database Service is a fully managed database service to deploy cloud-native applications. ",
features: [
DatasourceFeature.CONNECTION_CHECKING,
DatasourceFeature.FETCH_TABLE_NAMES,
],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
},
datasource: {
host: {
type: DatasourceFieldType.STRING,

View File

@ -50,10 +50,10 @@ const SCHEMA: Integration = {
type: "Relational",
description:
"Oracle Database is an object-relational database management system developed by Oracle Corporation",
features: [
DatasourceFeature.CONNECTION_CHECKING,
DatasourceFeature.FETCH_TABLE_NAMES,
],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
},
datasource: {
host: {
type: DatasourceFieldType.STRING,

View File

@ -52,10 +52,10 @@ const SCHEMA: Integration = {
type: "Relational",
description:
"PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.",
features: [
DatasourceFeature.CONNECTION_CHECKING,
DatasourceFeature.FETCH_TABLE_NAMES,
],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
},
datasource: {
host: {
type: DatasourceFieldType.STRING,

View File

@ -21,7 +21,9 @@ const SCHEMA: Integration = {
"Redis is a caching tool, providing powerful key-value store capabilities.",
friendlyName: "Redis",
type: "Non-relational",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
host: {
type: "string",

View File

@ -24,7 +24,9 @@ const SCHEMA: Integration = {
"Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.",
friendlyName: "Amazon S3",
type: "Object store",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
region: {
type: "string",

View File

@ -22,7 +22,9 @@ const SCHEMA: Integration = {
"Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.",
friendlyName: "Snowflake",
type: "Relational",
features: [DatasourceFeature.CONNECTION_CHECKING],
features: {
[DatasourceFeature.CONNECTION_CHECKING]: true,
},
datasource: {
account: {
type: "string",

View File

@ -116,7 +116,7 @@ export interface Integration {
docs: string
plus?: boolean
auth?: { type: string }
features?: DatasourceFeature[]
features?: Partial<Record<DatasourceFeature, boolean>>
relationships?: boolean
description: string
friendlyName: string

View File

@ -1,3 +1,4 @@
*
!/dist/
!/docker_run.sh
!/docker_run.sh
!/package.json

View File

@ -12,7 +12,7 @@ RUN apk add --no-cache --virtual .gyp python3 make g++
RUN yarn global add pm2
COPY dist/package.json .
COPY package.json .
RUN yarn install --frozen-lockfile --production=true
# Remove unneeded data from file system to reduce image size
RUN apk del .gyp \

View File

@ -13,7 +13,8 @@
],
"scripts": {
"prebuild": "rimraf dist/",
"build": "cd ../.. && nx build @budibase/worker",
"build": "node ../../scripts/build.js",
"check:types": "tsc -p tsconfig.build.json --noEmit",
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
"run:docker": "node dist/index.js",
"debug": "yarn build && node --expose-gc --inspect=9223 dist/index.js",
@ -38,7 +39,7 @@
"license": "GPL-3.0",
"dependencies": {
"@budibase/backend-core": "0.0.1",
"@budibase/pro": "develop",
"@budibase/pro": "0.0.1",
"@budibase/string-templates": "0.0.1",
"@budibase/types": "0.0.1",
"@koa/router": "8.0.8",

View File

@ -1,48 +0,0 @@
{
"name": "@budibase/worker",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"targets": {
"build": {
"executor": "@nx/esbuild:esbuild",
"outputs": ["{options.outputPath}"],
"options": {
"main": "packages/worker/src/index.ts",
"outputPath": "packages/worker/dist",
"outputFileName": "index.js",
"tsConfig": "packages/worker/tsconfig.build.json",
"assets": [
{
"glob": "**/*.hbs",
"input": "packages/worker/src/constants/templates",
"output": "."
}
],
"external": ["graphql/*", "deasync", "mock-aws-s3", "nock"],
"format": ["cjs"],
"esbuildOptions": {
"outExtension": {
".js": ".js"
},
"sourcemap": true
},
"minify": true,
"generatePackageJson": true,
"skipTypeCheck": true
},
"configurations": {
"production": {
"skipTypeCheck": false,
"esbuildOptions": {
"sourcemap": false
}
}
},
"dependsOn": [
{
"projects": ["@budibase/types", "@budibase/string-templates"],
"target": "build"
}
]
}
}
}

38
scripts/resetProDependencies.js Executable file
View File

@ -0,0 +1,38 @@
const fs = require("fs")
const path = require("path")
const { execSync } = require("child_process")
// Get the list of workspaces with mismatched dependencies
const output = execSync("yarn --silent workspaces info --json", {
encoding: "utf-8",
})
const data = JSON.parse(output)
const packageJsonPath = path.join(
data["@budibase/pro"].location,
"package.json"
)
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"))
let hasChanges = false
const dependencies = data["@budibase/pro"].workspaceDependencies
dependencies.forEach(dependency => {
if (packageJson.dependencies?.[dependency]) {
packageJson.dependencies[dependency] = "0.0.1"
hasChanges = true
}
if (packageJson.devDependencies?.[dependency]) {
packageJson.devDependencies[dependency] = "0.0.1"
hasChanges = true
}
if (packageJson.peerDependencies?.[dependency]) {
packageJson.peerDependencies[dependency] = "0.0.1"
hasChanges = true
}
})
// Write changes to package.json if there are any
if (hasChanges) {
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n")
}

149
yarn.lock
View File

@ -1728,47 +1728,6 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@budibase/backend-core@2.6.19-alpha.4":
version "2.6.19-alpha.4"
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.6.19-alpha.4.tgz#525dd7ba6c5db4404cf00d1165f79d34a1093826"
integrity sha512-1pfOr+J9xYawedVmvqpQ4b/8C2SQP4cKhFmSz5uErM2SCgbRj+JuzOUTPNX0vzAXPvat/kEegt79xThummDvhA==
dependencies:
"@budibase/nano" "10.1.2"
"@budibase/pouchdb-replication-stream" "1.2.10"
"@budibase/types" "2.6.19-alpha.4"
"@shopify/jest-koa-mocks" "5.0.1"
"@techpass/passport-openidconnect" "0.3.2"
aws-cloudfront-sign "2.2.0"
aws-sdk "2.1030.0"
bcrypt "5.0.1"
bcryptjs "2.4.3"
bull "4.10.1"
correlation-id "4.0.0"
dotenv "16.0.1"
emitter-listener "1.1.2"
ioredis "4.28.0"
joi "17.6.0"
jsonwebtoken "9.0.0"
koa-passport "4.1.4"
koa-pino-logger "4.0.0"
lodash "4.17.21"
lodash.isarguments "3.1.0"
node-fetch "2.6.7"
passport-google-oauth "2.0.0"
passport-jwt "4.0.0"
passport-local "1.0.0"
passport-oauth2-refresh "^2.1.0"
pino "8.11.0"
pino-http "8.3.3"
posthog-node "1.3.0"
pouchdb "7.3.0"
pouchdb-find "7.2.2"
redlock "4.2.0"
sanitize-s3-objectkey "0.0.1"
semver "7.3.7"
tar-fs "2.1.1"
uuid "8.3.2"
"@budibase/bbui@^0.9.139":
version "0.9.190"
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.190.tgz#e1ec400ac90f556bfbc80fc23a04506f1585ea81"
@ -1869,32 +1828,6 @@
pouchdb-promise "^6.0.4"
through2 "^2.0.0"
"@budibase/pro@develop":
version "2.6.19-alpha.4"
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.6.19-alpha.4.tgz#5d4c885ac9ac4ccfb2f8896961aca903c1178750"
integrity sha512-iu2QzV8Z77c00muBSK+NVsZdug3lLD0lR+vcKancGEz1PPE4yNIH7g8jB6i8h9agArbx9S2ICeHQqGb6nQaGHQ==
dependencies:
"@budibase/backend-core" "2.6.19-alpha.4"
"@budibase/shared-core" "2.6.19-alpha.4"
"@budibase/string-templates" "2.6.19-alpha.4"
"@budibase/types" "2.6.19-alpha.4"
"@koa/router" "8.0.8"
bull "4.10.1"
joi "17.6.0"
jsonwebtoken "8.5.1"
lru-cache "^7.14.1"
memorystream "^0.3.1"
node-fetch "^2.6.1"
scim-patch "^0.7.0"
scim2-parse-filter "^0.2.8"
"@budibase/shared-core@2.6.19-alpha.4":
version "2.6.19-alpha.4"
resolved "https://registry.yarnpkg.com/@budibase/shared-core/-/shared-core-2.6.19-alpha.4.tgz#dd22dd0a18ee4d6739b629f461e5caec90706282"
integrity sha512-ac6iWSsgz70OYbdA+QHPLpTnRbIZ4OecVc6Y7gnEZ78hZ4S5da8a+73jswuy0/t4YsiT/gjukjzjoihg3NemVg==
dependencies:
"@budibase/types" "2.6.19-alpha.4"
"@budibase/standard-components@^0.9.139":
version "0.9.139"
resolved "https://registry.yarnpkg.com/@budibase/standard-components/-/standard-components-0.9.139.tgz#cf8e2b759ae863e469e50272b3ca87f2827e66e3"
@ -1913,25 +1846,6 @@
svelte-apexcharts "^1.0.2"
svelte-flatpickr "^3.1.0"
"@budibase/string-templates@2.6.19-alpha.4":
version "2.6.19-alpha.4"
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-2.6.19-alpha.4.tgz#92ebd69a6841174b8af91f338c4754ca7c402707"
integrity sha512-KsH3NlQcJibRj98Q8zQ3KQHhfSIWPQfvR80MmBTIe05llEZGox4re4pQQUnlMafaUEyNNtIqVnbTJ1XP0LmFng==
dependencies:
"@budibase/handlebars-helpers" "^0.11.8"
dayjs "^1.10.4"
handlebars "^4.7.6"
handlebars-utils "^1.0.6"
lodash "^4.17.20"
vm2 "^3.9.15"
"@budibase/types@2.6.19-alpha.4":
version "2.6.19-alpha.4"
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.6.19-alpha.4.tgz#bcf81699329d3f8509e4b0a489211f35b6cfa7ce"
integrity sha512-qFsXHZTSigcfCv02aTZGsf17vBT/MC+zK9ky7WZVX4h0sJiE0li4A66/tMaSDz3/vQ7ToPRhJK/p+LOWA/oceg==
dependencies:
scim-patch "^0.7.0"
"@bull-board/api@3.7.0":
version "3.7.0"
resolved "https://registry.yarnpkg.com/@bull-board/api/-/api-3.7.0.tgz#231f687187c0cb34e0b97f463917b6aaeb4ef6af"
@ -3543,6 +3457,11 @@
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
"@jridgewell/sourcemap-codec@^1.4.13":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@jridgewell/trace-mapping@0.3.9":
version "0.3.9"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
@ -3861,13 +3780,6 @@
dependencies:
"@nx/devkit" "16.2.2"
"@nrwl/esbuild@16.2.1":
version "16.2.1"
resolved "https://registry.yarnpkg.com/@nrwl/esbuild/-/esbuild-16.2.1.tgz#83f8fbf2c7c541c220ccfff8be17a0e542aa7d01"
integrity sha512-qyNpdtPAzk2IhYmK5Qzn9gM1cvEtWFp6vJfgdbCKQngdqioYcJpGtdKhRm6Vcj8mFXF7zDgtUd2ecqJSiJU6VA==
dependencies:
"@nx/esbuild" "16.2.1"
"@nrwl/js@16.2.1":
version "16.2.1"
resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-16.2.1.tgz#6eacfa1f0658ca1e288da86b6c38be4846f2779a"
@ -3920,21 +3832,6 @@
tmp "~0.2.1"
tslib "^2.3.0"
"@nx/esbuild@16.2.1":
version "16.2.1"
resolved "https://registry.yarnpkg.com/@nx/esbuild/-/esbuild-16.2.1.tgz#157a408a617b5095ba1372ec27b03d6c9aa3b78c"
integrity sha512-jG4zsGc1EN+SfEBUky44+4cpj7M0Sf0v3pGWsw4hCOuBeLl6qW+eAcFypDXecDosS7ct/M2nEtlZP45IVDMZgQ==
dependencies:
"@nrwl/esbuild" "16.2.1"
"@nx/devkit" "16.2.1"
"@nx/js" "16.2.1"
chalk "^4.1.0"
dotenv "~10.0.0"
fast-glob "3.2.7"
fs-extra "^11.1.0"
tsconfig-paths "^4.1.2"
tslib "^2.3.0"
"@nx/js@16.2.1":
version "16.2.1"
resolved "https://registry.yarnpkg.com/@nx/js/-/js-16.2.1.tgz#41c8c2d610131fa064bbb2b6bb25bd67ed06be79"
@ -4323,7 +4220,7 @@
dependencies:
slash "^3.0.0"
"@rollup/plugin-commonjs@^16.0.0":
"@rollup/plugin-commonjs@16.0.0", "@rollup/plugin-commonjs@^16.0.0":
version "16.0.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-16.0.0.tgz#169004d56cd0f0a1d0f35915d31a036b0efe281f"
integrity sha512-LuNyypCP3msCGVQJ7ki8PqYdpjfEkE/xtFa5DqlF+7IBD0JsfMZ87C58heSwIMint58sAUZbt3ITqOmdQv/dXw==
@ -4406,6 +4303,22 @@
"@rollup/pluginutils" "^3.1.0"
magic-string "^0.25.7"
"@rollup/plugin-replace@^5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz#45f53501b16311feded2485e98419acb8448c61d"
integrity sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==
dependencies:
"@rollup/pluginutils" "^5.0.1"
magic-string "^0.27.0"
"@rollup/plugin-typescript@8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz#bc1077fa5897b980fc27e376c4e377882c63e68b"
integrity sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==
dependencies:
"@rollup/pluginutils" "^3.1.0"
resolve "^1.17.0"
"@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
@ -12433,7 +12346,7 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2:
fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.1, fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
@ -17481,6 +17394,13 @@ magic-string@^0.26.2:
dependencies:
sourcemap-codec "^1.4.8"
magic-string@^0.27.0:
version "0.27.0"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3"
integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.13"
make-dir@3.1.0, make-dir@^3.0.0, make-dir@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
@ -22307,6 +22227,13 @@ rollup-pluginutils@^2.3.1, rollup-pluginutils@^2.5.0, rollup-pluginutils@^2.6.0,
dependencies:
estree-walker "^0.6.1"
rollup@2.45.2:
version "2.45.2"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.45.2.tgz#8fb85917c9f35605720e92328f3ccbfba6f78b48"
integrity sha512-kRRU7wXzFHUzBIv0GfoFFIN3m9oteY4uAsKllIpQDId5cfnkWF2J130l+27dzDju0E6MScKiV0ZM5Bw8m4blYQ==
optionalDependencies:
fsevents "~2.3.1"
rollup@^2.36.2, rollup@^2.44.0, rollup@^2.45.2, rollup@^2.79.1:
version "2.79.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7"
@ -24312,7 +24239,7 @@ timed-out@^4.0.1:
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==
timekeeper@2.2.0:
timekeeper@2.2.0, timekeeper@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/timekeeper/-/timekeeper-2.2.0.tgz#9645731fce9e3280a18614a57a9d1b72af3ca368"
integrity sha512-W3AmPTJWZkRwu+iSNxPIsLZ2ByADsOLbbLxe46UJyWj3mlYLlwucKiq+/dPm0l9wTzqoF3/2PH0AGFCebjq23A==