Merge branch 'master' of github.com:Budibase/budibase into develop
This commit is contained in:
commit
ea2fb6de1b
|
@ -19,8 +19,8 @@ ADD packages/worker .
|
|||
RUN node /pinVersions.js && yarn && yarn build && /cleanup.sh
|
||||
|
||||
FROM couchdb:3.2.1
|
||||
# TARGETARCH can be amd64 or arm e.g. docker build --build-arg TARGETARCH=amd64
|
||||
ARG TARGETARCH=amd64
|
||||
ARG TARGETARCH
|
||||
ENV TARGETARCH $TARGETARCH
|
||||
#TARGETBUILD can be set to single (for single docker image) or aas (for azure app service)
|
||||
# e.g. docker build --build-arg TARGETBUILD=aas ....
|
||||
ARG TARGETBUILD=single
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/backend-core",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"description": "Budibase backend core libraries used in server and worker",
|
||||
"main": "dist/src/index.js",
|
||||
"types": "dist/src/index.d.ts",
|
||||
|
@ -20,7 +20,7 @@
|
|||
"test:watch": "jest --watchAll"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/types": "2.0.14-alpha.1",
|
||||
"@budibase/types": "^2.0.23",
|
||||
"@shopify/jest-koa-mocks": "5.0.1",
|
||||
"@techpass/passport-openidconnect": "0.3.2",
|
||||
"aws-sdk": "2.1030.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/bbui",
|
||||
"description": "A UI solution used in the different Budibase projects.",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"module": "dist/bbui.es.js",
|
||||
|
@ -38,7 +38,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@adobe/spectrum-css-workflow-icons": "^1.2.1",
|
||||
"@budibase/string-templates": "2.0.14-alpha.1",
|
||||
"@budibase/string-templates": "^2.0.23",
|
||||
"@spectrum-css/actionbutton": "^1.0.1",
|
||||
"@spectrum-css/actiongroup": "^1.0.1",
|
||||
"@spectrum-css/avatar": "^3.0.2",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/builder",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"license": "GPL-3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -71,10 +71,10 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.0.14-alpha.1",
|
||||
"@budibase/client": "2.0.14-alpha.1",
|
||||
"@budibase/frontend-core": "2.0.14-alpha.1",
|
||||
"@budibase/string-templates": "2.0.14-alpha.1",
|
||||
"@budibase/bbui": "^2.0.23",
|
||||
"@budibase/client": "^2.0.23",
|
||||
"@budibase/frontend-core": "^2.0.23",
|
||||
"@budibase/string-templates": "^2.0.23",
|
||||
"@sentry/browser": "5.19.1",
|
||||
"@spectrum-css/page": "^3.0.1",
|
||||
"@spectrum-css/vars": "^3.0.1",
|
||||
|
|
|
@ -396,19 +396,17 @@ export const getUserBindings = () => {
|
|||
|
||||
bindings = keys.reduce((acc, key) => {
|
||||
const fieldSchema = schema[key]
|
||||
if (fieldSchema.type !== "link") {
|
||||
acc.push({
|
||||
type: "context",
|
||||
runtimeBinding: `${safeUser}.${makePropSafe(key)}`,
|
||||
readableBinding: `Current User.${key}`,
|
||||
// Field schema and provider are required to construct relationship
|
||||
// datasource options, based on bindable properties
|
||||
fieldSchema,
|
||||
providerId: "user",
|
||||
category: "Current User",
|
||||
icon: "User",
|
||||
})
|
||||
}
|
||||
acc.push({
|
||||
type: "context",
|
||||
runtimeBinding: `${safeUser}.${makePropSafe(key)}`,
|
||||
readableBinding: `Current User.${key}`,
|
||||
// Field schema and provider are required to construct relationship
|
||||
// datasource options, based on bindable properties
|
||||
fieldSchema,
|
||||
providerId: "user",
|
||||
category: "Current User",
|
||||
icon: "User",
|
||||
})
|
||||
return acc
|
||||
}, [])
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/cli",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||
"main": "src/index.js",
|
||||
"bin": {
|
||||
|
@ -26,9 +26,9 @@
|
|||
"outputPath": "build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "2.0.14-alpha.1",
|
||||
"@budibase/string-templates": "2.0.14-alpha.1",
|
||||
"@budibase/types": "2.0.14-alpha.1",
|
||||
"@budibase/backend-core": "^2.0.23",
|
||||
"@budibase/string-templates": "^2.0.23",
|
||||
"@budibase/types": "^2.0.23",
|
||||
"axios": "0.21.2",
|
||||
"chalk": "4.1.0",
|
||||
"cli-progress": "3.11.2",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/client",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"license": "MPL-2.0",
|
||||
"module": "dist/budibase-client.js",
|
||||
"main": "dist/budibase-client.js",
|
||||
|
@ -19,9 +19,9 @@
|
|||
"dev:builder": "rollup -cw"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.0.14-alpha.1",
|
||||
"@budibase/frontend-core": "2.0.14-alpha.1",
|
||||
"@budibase/string-templates": "2.0.14-alpha.1",
|
||||
"@budibase/bbui": "^2.0.23",
|
||||
"@budibase/frontend-core": "^2.0.23",
|
||||
"@budibase/string-templates": "^2.0.23",
|
||||
"@spectrum-css/button": "^3.0.3",
|
||||
"@spectrum-css/card": "^3.0.3",
|
||||
"@spectrum-css/divider": "^1.0.3",
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
themeStore,
|
||||
appStore,
|
||||
devToolsStore,
|
||||
environmentStore,
|
||||
} from "stores"
|
||||
import NotificationDisplay from "components/overlay/NotificationDisplay.svelte"
|
||||
import ConfirmationDisplay from "components/overlay/ConfirmationDisplay.svelte"
|
||||
|
@ -48,8 +47,6 @@
|
|||
!$builderStore.inBuilder &&
|
||||
$devToolsStore.enabled &&
|
||||
!$routeStore.queryParams?.peek
|
||||
$: objectStoreUrl = $environmentStore.cloud ? "https://cdn.budi.live" : ""
|
||||
$: pluginsUrl = `${objectStoreUrl}/plugins`
|
||||
|
||||
// Handle no matching route
|
||||
$: {
|
||||
|
@ -95,8 +92,7 @@
|
|||
<svelte:head>
|
||||
{#if $builderStore.usedPlugins?.length}
|
||||
{#each $builderStore.usedPlugins as plugin (plugin.hash)}
|
||||
<script
|
||||
src={`${pluginsUrl}/${plugin.jsUrl}?r=${plugin.hash || ""}`}></script>
|
||||
<script src={`${plugin.jsUrl}?r=${plugin.hash || ""}`}></script>
|
||||
{/each}
|
||||
{/if}
|
||||
</svelte:head>
|
||||
|
|
|
@ -1,37 +1,39 @@
|
|||
export class ApexOptionsBuilder {
|
||||
formatters = {
|
||||
["Default"]: val => (isNaN(val) ? val : Math.round(val * 100) / 100),
|
||||
["Thousands"]: val => `${Math.round(val / 1000)}K`,
|
||||
["Millions"]: val => `${Math.round(val / 1000000)}M`,
|
||||
}
|
||||
options = {
|
||||
series: [],
|
||||
legend: {
|
||||
show: false,
|
||||
position: "top",
|
||||
horizontalAlign: "right",
|
||||
showForSingleSeries: true,
|
||||
showForNullSeries: true,
|
||||
showForZeroSeries: true,
|
||||
},
|
||||
chart: {
|
||||
toolbar: {
|
||||
constructor() {
|
||||
this.formatters = {
|
||||
["Default"]: val => (isNaN(val) ? val : Math.round(val * 100) / 100),
|
||||
["Thousands"]: val => `${Math.round(val / 1000)}K`,
|
||||
["Millions"]: val => `${Math.round(val / 1000000)}M`,
|
||||
}
|
||||
this.options = {
|
||||
series: [],
|
||||
legend: {
|
||||
show: false,
|
||||
position: "top",
|
||||
horizontalAlign: "right",
|
||||
showForSingleSeries: true,
|
||||
showForNullSeries: true,
|
||||
showForZeroSeries: true,
|
||||
},
|
||||
zoom: {
|
||||
enabled: false,
|
||||
chart: {
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
zoom: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
labels: {
|
||||
formatter: this.formatters.Default,
|
||||
xaxis: {
|
||||
labels: {
|
||||
formatter: this.formatters.Default,
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: this.formatters.Default,
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: this.formatters.Default,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
setOption(path, value) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "@budibase/frontend-core",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"description": "Budibase frontend core libraries used in builder and client",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.0.14-alpha.1",
|
||||
"@budibase/bbui": "^2.0.23",
|
||||
"lodash": "^4.17.21",
|
||||
"svelte": "^3.46.2"
|
||||
}
|
||||
|
|
|
@ -14,52 +14,52 @@ import { convertJSONSchemaToTableSchema } from "../utils/json"
|
|||
* For other types of datasource, this class is overridden and extended.
|
||||
*/
|
||||
export default class DataFetch {
|
||||
// API client
|
||||
API = null
|
||||
|
||||
// Feature flags
|
||||
featureStore = writable({
|
||||
supportsSearch: false,
|
||||
supportsSort: false,
|
||||
supportsPagination: false,
|
||||
})
|
||||
|
||||
// Config
|
||||
options = {
|
||||
datasource: null,
|
||||
limit: 10,
|
||||
|
||||
// Search config
|
||||
filter: null,
|
||||
query: null,
|
||||
|
||||
// Sorting config
|
||||
sortColumn: null,
|
||||
sortOrder: "ascending",
|
||||
sortType: null,
|
||||
|
||||
// Pagination config
|
||||
paginate: true,
|
||||
}
|
||||
|
||||
// State of the fetch
|
||||
store = writable({
|
||||
rows: [],
|
||||
info: null,
|
||||
schema: null,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
query: null,
|
||||
pageNumber: 0,
|
||||
cursor: null,
|
||||
cursors: [],
|
||||
})
|
||||
|
||||
/**
|
||||
* Constructs a new DataFetch instance.
|
||||
* @param opts the fetch options
|
||||
*/
|
||||
constructor(opts) {
|
||||
// API client
|
||||
this.API = null
|
||||
|
||||
// Feature flags
|
||||
this.featureStore = writable({
|
||||
supportsSearch: false,
|
||||
supportsSort: false,
|
||||
supportsPagination: false,
|
||||
})
|
||||
|
||||
// Config
|
||||
this.options = {
|
||||
datasource: null,
|
||||
limit: 10,
|
||||
|
||||
// Search config
|
||||
filter: null,
|
||||
query: null,
|
||||
|
||||
// Sorting config
|
||||
sortColumn: null,
|
||||
sortOrder: "ascending",
|
||||
sortType: null,
|
||||
|
||||
// Pagination config
|
||||
paginate: true,
|
||||
}
|
||||
|
||||
// State of the fetch
|
||||
this.store = writable({
|
||||
rows: [],
|
||||
info: null,
|
||||
schema: null,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
query: null,
|
||||
pageNumber: 0,
|
||||
cursor: null,
|
||||
cursors: [],
|
||||
})
|
||||
|
||||
// Merge options with their default values
|
||||
this.API = opts?.API
|
||||
this.options = {
|
||||
|
|
|
@ -121,7 +121,12 @@ export const buildLuceneQuery = filter => {
|
|||
query.allOr = true
|
||||
return
|
||||
}
|
||||
if (type === "datetime" && !isHbs) {
|
||||
if (
|
||||
type === "datetime" &&
|
||||
!isHbs &&
|
||||
operator !== "empty" &&
|
||||
operator !== "notEmpty"
|
||||
) {
|
||||
// Ensure date value is a valid date and parse into correct format
|
||||
if (!value) {
|
||||
return
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/sdk",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"description": "Budibase Public API SDK",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/server",
|
||||
"email": "hi@budibase.com",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"description": "Budibase Web Server",
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
|
@ -77,11 +77,11 @@
|
|||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@apidevtools/swagger-parser": "10.0.3",
|
||||
"@budibase/backend-core": "2.0.14-alpha.1",
|
||||
"@budibase/client": "2.0.14-alpha.1",
|
||||
"@budibase/pro": "2.0.14-alpha.0",
|
||||
"@budibase/string-templates": "2.0.14-alpha.1",
|
||||
"@budibase/types": "2.0.14-alpha.1",
|
||||
"@budibase/backend-core": "^2.0.23",
|
||||
"@budibase/client": "^2.0.23",
|
||||
"@budibase/pro": "2.0.23",
|
||||
"@budibase/string-templates": "^2.0.23",
|
||||
"@budibase/types": "^2.0.23",
|
||||
"@bull-board/api": "3.7.0",
|
||||
"@bull-board/koa": "3.9.4",
|
||||
"@elastic/elasticsearch": "7.10.0",
|
||||
|
|
|
@ -50,6 +50,7 @@ import { errors, events, migrations } from "@budibase/backend-core"
|
|||
import { App, Layout, Screen, MigrationType } from "@budibase/types"
|
||||
import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts"
|
||||
import { groups } from "@budibase/pro"
|
||||
import { enrichPluginURLs } from "../../utilities/plugins"
|
||||
|
||||
const URL_REGEX_SLASH = /\/|\\/g
|
||||
|
||||
|
@ -208,10 +209,13 @@ export const fetchAppDefinition = async (ctx: any) => {
|
|||
|
||||
export const fetchAppPackage = async (ctx: any) => {
|
||||
const db = context.getAppDB()
|
||||
const application = await db.get(DocumentType.APP_METADATA)
|
||||
let application = await db.get(DocumentType.APP_METADATA)
|
||||
const layouts = await getLayouts()
|
||||
let screens = await getScreens()
|
||||
|
||||
// Enrich plugin URLs
|
||||
application.usedPlugins = enrichPluginURLs(application.usedPlugins)
|
||||
|
||||
// Only filter screens if the user is not a builder
|
||||
if (!(ctx.user.builder && ctx.user.builder.global)) {
|
||||
const userRoleId = getUserRoleId(ctx)
|
||||
|
|
|
@ -68,6 +68,7 @@ exports.buildSchemaFromDb = async function (ctx) {
|
|||
datasource.entities = tables
|
||||
}
|
||||
|
||||
setDefaultDisplayColumns(datasource)
|
||||
const dbResp = await db.put(datasource)
|
||||
datasource._rev = dbResp.rev
|
||||
|
||||
|
@ -78,6 +79,24 @@ exports.buildSchemaFromDb = async function (ctx) {
|
|||
ctx.body = response
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure all datasource entities have a display name selected
|
||||
*/
|
||||
const setDefaultDisplayColumns = datasource => {
|
||||
//
|
||||
for (let entity of Object.values(datasource.entities)) {
|
||||
if (entity.primaryDisplay) {
|
||||
continue
|
||||
}
|
||||
const notAutoColumn = Object.values(entity.schema).find(
|
||||
schema => !schema.autocolumn
|
||||
)
|
||||
if (notAutoColumn) {
|
||||
entity.primaryDisplay = notAutoColumn.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for variables that have been updated or removed and invalidate them.
|
||||
*/
|
||||
|
@ -155,6 +174,7 @@ exports.save = async function (ctx) {
|
|||
const { tables, error } = await buildSchemaHelper(datasource)
|
||||
schemaError = error
|
||||
datasource.entities = tables
|
||||
setDefaultDisplayColumns(datasource)
|
||||
}
|
||||
|
||||
const dbResp = await db.put(datasource)
|
||||
|
@ -238,19 +258,6 @@ const buildSchemaHelper = async datasource => {
|
|||
const connector = new Connector(datasource.config)
|
||||
await connector.buildSchema(datasource._id, datasource.entities)
|
||||
|
||||
// make sure they all have a display name selected
|
||||
for (let entity of Object.values(datasource.entities ?? {})) {
|
||||
if (entity.primaryDisplay) {
|
||||
continue
|
||||
}
|
||||
const notAutoColumn = Object.values(entity.schema).find(
|
||||
schema => !schema.autocolumn
|
||||
)
|
||||
if (notAutoColumn) {
|
||||
entity.primaryDisplay = notAutoColumn.name
|
||||
}
|
||||
}
|
||||
|
||||
const errors = connector.schemaErrors
|
||||
let error = null
|
||||
if (errors && Object.keys(errors).length > 0) {
|
||||
|
|
|
@ -52,14 +52,19 @@ export async function read(ctx: any, next: any) {
|
|||
}
|
||||
|
||||
export async function update(ctx: any, next: any) {
|
||||
ctx.request.body = await addRev(fixRow(ctx.request.body, ctx.params))
|
||||
const { tableId } = ctx.params
|
||||
ctx.request.body = await addRev(fixRow(ctx.request.body, ctx.params), tableId)
|
||||
await rowController.save(ctx)
|
||||
await next()
|
||||
}
|
||||
|
||||
export async function destroy(ctx: any, next: any) {
|
||||
const { tableId } = ctx.params
|
||||
// set the body as expected, with the _id and _rev fields
|
||||
ctx.request.body = await addRev(fixRow({ _id: ctx.params.rowId }, ctx.params))
|
||||
ctx.request.body = await addRev(
|
||||
fixRow({ _id: ctx.params.rowId }, ctx.params),
|
||||
tableId
|
||||
)
|
||||
await rowController.destroy(ctx)
|
||||
// destroy controller doesn't currently return the row as the body, need to adjust this
|
||||
// in the public API to be correct
|
||||
|
|
|
@ -22,7 +22,7 @@ export async function addRev(
|
|||
}
|
||||
|
||||
/**
|
||||
* Performs a case insensitive search on the provided documents, using the
|
||||
* Performs a case in-sensitive search on the provided documents, using the
|
||||
* provided key and value. This will be a string based search, using the
|
||||
* startsWith function.
|
||||
*/
|
||||
|
|
|
@ -240,6 +240,10 @@ async function execute(
|
|||
const { rows, pagination, extra } = await quotas.addQuery(runFn, {
|
||||
datasourceId: datasource._id,
|
||||
})
|
||||
// remove the raw from execution incase transformer being used to hide data
|
||||
if (extra?.raw) {
|
||||
delete extra.raw
|
||||
}
|
||||
if (opts && opts.rowsOnly) {
|
||||
ctx.body = rows
|
||||
} else {
|
||||
|
|
|
@ -145,7 +145,7 @@ class QueryBuilder {
|
|||
* @param options The preprocess options
|
||||
* @returns {string|*}
|
||||
*/
|
||||
preprocess(value, { escape, lowercase, wrap } = {}) {
|
||||
preprocess(value, { escape, lowercase, wrap, type } = {}) {
|
||||
const hasVersion = !!this.version
|
||||
// Determine if type needs wrapped
|
||||
const originalType = typeof value
|
||||
|
@ -157,8 +157,11 @@ class QueryBuilder {
|
|||
if (escape && originalType === "string") {
|
||||
value = `${value}`.replace(/[ #+\-&|!(){}\]^"~*?:\\]/g, "\\$&")
|
||||
}
|
||||
|
||||
// Wrap in quotes
|
||||
if (hasVersion && wrap) {
|
||||
if (originalType === "string" && !isNaN(value) && !type) {
|
||||
value = `"${value}"`
|
||||
} else if (hasVersion && wrap) {
|
||||
value = originalType === "number" ? value : `"${value}"`
|
||||
}
|
||||
return value
|
||||
|
@ -253,6 +256,7 @@ class QueryBuilder {
|
|||
value = builder.preprocess(value, {
|
||||
escape: true,
|
||||
lowercase: true,
|
||||
type: "string",
|
||||
})
|
||||
return `${key}:${value}*`
|
||||
})
|
||||
|
@ -281,6 +285,7 @@ class QueryBuilder {
|
|||
value = builder.preprocess(value, {
|
||||
escape: true,
|
||||
lowercase: true,
|
||||
type: "fuzzy",
|
||||
})
|
||||
return `${key}:${value}~`
|
||||
})
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { enrichPluginURLs } from "../../../utilities/plugins"
|
||||
|
||||
require("svelte/register")
|
||||
|
||||
const send = require("koa-send")
|
||||
|
@ -107,12 +109,13 @@ export const serveApp = async function (ctx: any) {
|
|||
|
||||
if (!env.isJest()) {
|
||||
const App = require("./templates/BudibaseApp.svelte").default
|
||||
const plugins = enrichPluginURLs(appInfo.usedPlugins)
|
||||
const { head, html, css } = App.render({
|
||||
title: appInfo.name,
|
||||
production: env.isProd(),
|
||||
appId,
|
||||
clientLibPath: clientLibraryPath(appId, appInfo.version, ctx),
|
||||
usedPlugins: appInfo.usedPlugins,
|
||||
usedPlugins: plugins,
|
||||
})
|
||||
|
||||
const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)
|
||||
|
|
|
@ -88,9 +88,7 @@
|
|||
<!-- But before loadBudibase is called -->
|
||||
{#if usedPlugins?.length}
|
||||
{#each usedPlugins as plugin}
|
||||
<script
|
||||
type="application/javascript"
|
||||
src={`/plugins/${plugin.jsUrl}`}></script>
|
||||
<script type="application/javascript" src={plugin.jsUrl}></script>
|
||||
{/each}
|
||||
{/if}
|
||||
<script type="application/javascript">
|
||||
|
|
|
@ -14,8 +14,10 @@ import {
|
|||
fixAutoColumnSubType,
|
||||
} from "../../../utilities/rowProcessor"
|
||||
import { runStaticFormulaChecks } from "./bulkFormula"
|
||||
import { Table } from "../../../definitions/common"
|
||||
import { Table } from "@budibase/types"
|
||||
import { quotas } from "@budibase/pro"
|
||||
import { isEqual } from "lodash"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
|
||||
function checkAutoColumns(table: Table, oldTable: Table) {
|
||||
if (!table.schema) {
|
||||
|
@ -123,10 +125,16 @@ export async function save(ctx: any) {
|
|||
if (updatedRows && updatedRows.length !== 0) {
|
||||
await db.bulkDocs(updatedRows)
|
||||
}
|
||||
const result = await db.put(tableToSave)
|
||||
let result = await db.put(tableToSave)
|
||||
tableToSave._rev = result.rev
|
||||
const savedTable = cloneDeep(tableToSave)
|
||||
|
||||
tableToSave = await tableSaveFunctions.after(tableToSave)
|
||||
// the table may be updated as part of the table save after functionality - need to write it
|
||||
if (!isEqual(savedTable, tableToSave)) {
|
||||
result = await db.put(tableToSave)
|
||||
tableToSave._rev = result.rev
|
||||
}
|
||||
// has to run after, make sure it has _id
|
||||
await runStaticFormulaChecks(tableToSave, { oldTable, deletion: null })
|
||||
return tableToSave
|
||||
|
|
|
@ -247,7 +247,7 @@ class TableSaveFunctions {
|
|||
// after saving
|
||||
async after(table: any) {
|
||||
table = await handleSearchIndexes(table)
|
||||
await handleDataImport(this.user, table, this.dataImport)
|
||||
table = await handleDataImport(this.user, table, this.dataImport)
|
||||
return table
|
||||
}
|
||||
|
||||
|
|
|
@ -173,4 +173,24 @@ describe("internal search", () => {
|
|||
}, PARAMS)
|
||||
checkLucene(response, `*:* AND NOT column:(a AND b AND c)`, PARAMS)
|
||||
})
|
||||
|
||||
it("test equal without version query", async () => {
|
||||
PARAMS.version = null
|
||||
const response = await search.paginatedSearch({
|
||||
equal: {
|
||||
"column": "1",
|
||||
}
|
||||
}, PARAMS)
|
||||
|
||||
const query = response.rows[0].query
|
||||
const json = JSON.parse(query)
|
||||
if (PARAMS.sort) {
|
||||
expect(json.sort).toBe(`${PARAMS.sort}<${PARAMS.sortType}>`)
|
||||
}
|
||||
if (PARAMS.bookmark) {
|
||||
expect(json.bookmark).toBe(PARAMS.bookmark)
|
||||
}
|
||||
expect(json.include_docs).toBe(true)
|
||||
expect(json.q).toBe(`(*:* AND column:"1") AND tableId:${PARAMS.tableId}`)
|
||||
})
|
||||
})
|
|
@ -252,7 +252,7 @@ class Orchestrator {
|
|||
let loopStepNumber: any = undefined
|
||||
let loopSteps: LoopStep[] | undefined = []
|
||||
let metadata
|
||||
|
||||
let wasLoopStep = false
|
||||
// check if this is a recurring automation,
|
||||
if (isProdAppID(this._appId) && isRecurring(automation)) {
|
||||
metadata = await this.getMetadata()
|
||||
|
@ -267,6 +267,7 @@ class Orchestrator {
|
|||
let input,
|
||||
iterations = 1,
|
||||
iterationCount = 0
|
||||
|
||||
if (step.stepId === LOOP_STEP_ID) {
|
||||
loopStep = step
|
||||
loopStepNumber = stepCount
|
||||
|
@ -277,10 +278,8 @@ class Orchestrator {
|
|||
input = await processObject(loopStep.inputs, this._context)
|
||||
iterations = getLoopIterations(loopStep as LoopStep, input)
|
||||
}
|
||||
|
||||
for (let index = 0; index < iterations; index++) {
|
||||
let originalStepInput = cloneDeep(step.inputs)
|
||||
|
||||
// Handle if the user has set a max iteration count or if it reaches the max limit set by us
|
||||
if (loopStep && input.binding) {
|
||||
let newInput = await processObject(
|
||||
|
@ -313,7 +312,6 @@ class Orchestrator {
|
|||
} else {
|
||||
item = loopStep.inputs.binding
|
||||
}
|
||||
|
||||
this._context.steps[loopStepNumber] = {
|
||||
currentItem: item[index],
|
||||
}
|
||||
|
@ -331,6 +329,16 @@ class Orchestrator {
|
|||
innerValue,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
} else if (typeof value === "object") {
|
||||
for (let [innerObject, innerValue] of Object.entries(
|
||||
originalStepInput[key][innerKey]
|
||||
)) {
|
||||
originalStepInput[key][innerKey][innerObject] =
|
||||
automationUtils.substituteLoopStep(
|
||||
innerValue,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -386,6 +394,7 @@ class Orchestrator {
|
|||
let stepFn = await this.getStepFunctionality(step.stepId)
|
||||
let inputs = await processObject(originalStepInput, this._context)
|
||||
inputs = automationUtils.cleanInputValues(inputs, step.schema.inputs)
|
||||
|
||||
try {
|
||||
// appId is always passed
|
||||
const outputs = await stepFn({
|
||||
|
@ -394,6 +403,7 @@ class Orchestrator {
|
|||
emitter: this._emitter,
|
||||
context: this._context,
|
||||
})
|
||||
|
||||
this._context.steps[stepCount] = outputs
|
||||
// if filter causes us to stop execution don't break the loop, set a var
|
||||
// so that we can finish iterating through the steps and record that it stopped
|
||||
|
@ -419,6 +429,7 @@ class Orchestrator {
|
|||
console.error(`Automation error - ${step.stepId} - ${err}`)
|
||||
return err
|
||||
}
|
||||
|
||||
if (loopStep) {
|
||||
iterationCount++
|
||||
if (index === iterations - 1) {
|
||||
|
@ -429,6 +440,13 @@ class Orchestrator {
|
|||
}
|
||||
}
|
||||
|
||||
// Delete the step after the loop step as it's irrelevant, since information is included
|
||||
// in the loop step
|
||||
if (wasLoopStep) {
|
||||
this._context.steps.splice(loopStepNumber + 1, 1)
|
||||
wasLoopStep = false
|
||||
}
|
||||
|
||||
if (loopSteps && loopSteps.length) {
|
||||
let tempOutput = {
|
||||
success: true,
|
||||
|
@ -441,9 +459,10 @@ class Orchestrator {
|
|||
outputs: tempOutput,
|
||||
inputs: step.inputs,
|
||||
})
|
||||
this._context.steps[loopStepNumber] = tempOutput
|
||||
|
||||
this._context.steps.splice(loopStepNumber, 0, tempOutput)
|
||||
loopSteps = undefined
|
||||
wasLoopStep = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
const env = require("../environment")
|
||||
const { plugins: ProPlugins } = require("@budibase/pro")
|
||||
const { objectStore } = require("@budibase/backend-core")
|
||||
|
||||
exports.enrichPluginURLs = plugins => {
|
||||
if (!plugins || !plugins.length) {
|
||||
return []
|
||||
}
|
||||
return plugins.map(plugin => {
|
||||
const cloud = !env.SELF_HOSTED
|
||||
const bucket = objectStore.ObjectStoreBuckets.PLUGINS
|
||||
const jsFileName = "plugin.min.js"
|
||||
|
||||
// In self host we need to prefix the path, as the bucket name is not part
|
||||
// of the bucket path. In cloud, it's already part of the bucket path.
|
||||
let jsUrl = cloud ? "https://cdn.budi.live/" : `/${bucket}/`
|
||||
jsUrl += ProPlugins.getBucketPath(plugin.name)
|
||||
jsUrl += jsFileName
|
||||
return { ...plugin, jsUrl }
|
||||
})
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/string-templates",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"description": "Handlebars wrapper for Budibase templating.",
|
||||
"main": "src/index.cjs",
|
||||
"module": "dist/bundle.mjs",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/types",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"description": "Budibase types",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/worker",
|
||||
"email": "hi@budibase.com",
|
||||
"version": "2.0.14-alpha.1",
|
||||
"version": "2.0.23",
|
||||
"description": "Budibase background service",
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
|
@ -36,10 +36,10 @@
|
|||
"author": "Budibase",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "2.0.14-alpha.1",
|
||||
"@budibase/pro": "2.0.14-alpha.0",
|
||||
"@budibase/string-templates": "2.0.14-alpha.1",
|
||||
"@budibase/types": "2.0.14-alpha.1",
|
||||
"@budibase/backend-core": "^2.0.23",
|
||||
"@budibase/pro": "2.0.23",
|
||||
"@budibase/string-templates": "^2.0.23",
|
||||
"@budibase/types": "^2.0.23",
|
||||
"@koa/router": "8.0.8",
|
||||
"@sentry/node": "6.17.7",
|
||||
"@techpass/passport-openidconnect": "0.3.2",
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#!/bin/bash
|
||||
if [[ $TARGETARCH == arm* ]] ;
|
||||
then
|
||||
echo "INSTALLING ARM64 MINIO"
|
||||
wget https://dl.min.io/server/minio/release/linux-arm64/minio
|
||||
else
|
||||
echo "INSTALLING AMD64 MINIO"
|
||||
wget https://dl.min.io/server/minio/release/linux-amd64/minio
|
||||
fi
|
||||
chmod +x minio
|
||||
|
|
|
@ -18,6 +18,11 @@ git clone https://$PERSONAL_ACCESS_TOKEN@github.com/Budibase/budibase-pro.git
|
|||
if [[ -d "budibase-pro" ]]; then
|
||||
cd budibase-pro
|
||||
|
||||
if [[ -z "${BRANCH}" ]]; then
|
||||
echo Using GITHUB_REF_NAME: $GITHUB_REF_NAME
|
||||
export BRANCH=$GITHUB_REF_NAME
|
||||
fi
|
||||
|
||||
# Try to checkout the matching pro branch
|
||||
git checkout $BRANCH
|
||||
|
||||
|
|
Loading…
Reference in New Issue