Merge branch 'master' into qa-core-changes

This commit is contained in:
Mitch-Budibase 2024-02-02 15:28:44 +00:00
commit abe4e57961
29 changed files with 89 additions and 58 deletions

View File

@ -45,6 +45,16 @@
"no-prototype-builtins": "off", "no-prototype-builtins": "off",
"local-rules/no-budibase-imports": "error" "local-rules/no-budibase-imports": "error"
} }
},
{
"files": [
"packages/builder/**/*",
"packages/client/**/*",
"packages/frontend-core/**/*"
],
"rules": {
"no-console": ["error", { "allow": ["warn", "error", "debug"] } ]
}
} }
], ],
"rules": { "rules": {

View File

@ -1,5 +1,5 @@
{ {
"version": "2.16.1", "version": "2.17.2",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*", "packages/*",

@ -1 +1 @@
Subproject commit 485ec16a9eed48c548a5f1239772139f3319f028 Subproject commit 52f51dcfb96d3fe58c8cc7a905e7d733f7cd84c2

View File

@ -7,7 +7,7 @@ import tar from "tar-fs"
import zlib from "zlib" import zlib from "zlib"
import { promisify } from "util" import { promisify } from "util"
import { join } from "path" import { join } from "path"
import fs from "fs" import fs, { ReadStream } from "fs"
import env from "../environment" import env from "../environment"
import { budibaseTempDir } from "./utils" import { budibaseTempDir } from "./utils"
import { v4 } from "uuid" import { v4 } from "uuid"
@ -184,7 +184,7 @@ export async function upload({
export async function streamUpload( export async function streamUpload(
bucketName: string, bucketName: string,
filename: string, filename: string,
stream: any, stream: ReadStream | ReadableStream,
extra = {} extra = {}
) { ) {
const objectStore = ObjectStore(bucketName) const objectStore = ObjectStore(bucketName)

View File

@ -364,7 +364,6 @@ const getContextBindings = (asset, componentId) => {
* Generates a set of bindings for a given component context * Generates a set of bindings for a given component context
*/ */
const generateComponentContextBindings = (asset, componentContext) => { const generateComponentContextBindings = (asset, componentContext) => {
console.log("Hello ")
const { component, definition, contexts } = componentContext const { component, definition, contexts } = componentContext
if (!component || !definition || !contexts?.length) { if (!component || !definition || !contexts?.length) {
return [] return []

View File

@ -158,6 +158,7 @@ export const getFrontendStore = () => {
...INITIAL_FRONTEND_STATE.features, ...INITIAL_FRONTEND_STATE.features,
...application.features, ...application.features,
}, },
automations: application.automations || {},
icon: application.icon || {}, icon: application.icon || {},
initialised: true, initialised: true,
})) }))

View File

@ -21,7 +21,7 @@ export const createBuilderWebsocket = appId => {
}) })
}) })
socket.on("connect_error", err => { socket.on("connect_error", err => {
console.log("Failed to connect to builder websocket:", err.message) console.error("Failed to connect to builder websocket:", err.message)
}) })
socket.on("disconnect", () => { socket.on("disconnect", () => {
userStore.actions.reset() userStore.actions.reset()

View File

@ -157,6 +157,7 @@
let bindings = [] let bindings = []
let loopBlockCount = 0 let loopBlockCount = 0
const addBinding = (name, value, icon, idx, isLoopBlock, bindingName) => { const addBinding = (name, value, icon, idx, isLoopBlock, bindingName) => {
if (!name) return
const runtimeBinding = determineRuntimeBinding(name, idx, isLoopBlock) const runtimeBinding = determineRuntimeBinding(name, idx, isLoopBlock)
const categoryName = determineCategoryName(idx, isLoopBlock, bindingName) const categoryName = determineCategoryName(idx, isLoopBlock, bindingName)
@ -291,7 +292,6 @@
loopBlockCount++ loopBlockCount++
continue continue
} }
Object.entries(schema).forEach(([name, value]) => Object.entries(schema).forEach(([name, value]) =>
addBinding(name, value, icon, idx, isLoopBlock, bindingName) addBinding(name, value, icon, idx, isLoopBlock, bindingName)
) )

View File

@ -312,7 +312,7 @@ export const insertBinding = (view, from, to, text, mode) => {
} else if (mode.name == "handlebars") { } else if (mode.name == "handlebars") {
parsedInsert = hbInsert(view.state.doc?.toString(), from, to, text) parsedInsert = hbInsert(view.state.doc?.toString(), from, to, text)
} else { } else {
console.log("Unsupported") console.warn("Unsupported")
return return
} }

View File

@ -67,7 +67,7 @@
})) }))
navigateStep(target) navigateStep(target)
} else { } else {
console.log("Could not retrieve step") console.warn("Could not retrieve step")
} }
} else { } else {
if (typeof tourStep.onComplete === "function") { if (typeof tourStep.onComplete === "function") {

View File

@ -3,11 +3,11 @@ import { get } from "svelte/store"
const registerNode = async (node, tourStepKey) => { const registerNode = async (node, tourStepKey) => {
if (!node) { if (!node) {
console.log("Tour Handler - an anchor node is required") console.warn("Tour Handler - an anchor node is required")
} }
if (!get(store).tourKey) { if (!get(store).tourKey) {
console.log("Tour Handler - No active tour ", tourStepKey, node) console.error("Tour Handler - No active tour ", tourStepKey, node)
return return
} }

View File

@ -45,7 +45,7 @@ const endUserOnboarding = async ({ skipped = false } = {}) => {
onboarding: false, onboarding: false,
})) }))
} catch (e) { } catch (e) {
console.log("Onboarding failed", e) console.error("Onboarding failed", e)
return false return false
} }
return true return true

View File

@ -52,7 +52,7 @@ export const syncURLToState = options => {
let cachedPage = get(routify.page) let cachedPage = get(routify.page)
let previousParamsHash = null let previousParamsHash = null
let debug = false let debug = false
const log = (...params) => debug && console.log(`[${urlParam}]`, ...params) const log = (...params) => debug && console.debug(`[${urlParam}]`, ...params)
// Navigate to a certain URL // Navigate to a certain URL
const gotoUrl = (url, params) => { const gotoUrl = (url, params) => {

View File

@ -107,7 +107,7 @@
return return
} }
if (!prodAppId) { if (!prodAppId) {
console.log("Application id required") console.error("Application id required")
return return
} }
await usersFetch.update({ await usersFetch.update({

View File

@ -66,7 +66,7 @@
try { try {
await store.actions.screens.updateSetting(get(selectedScreen), key, value) await store.actions.screens.updateSetting(get(selectedScreen), key, value)
} catch (error) { } catch (error) {
console.log(error) console.error(error)
notifications.error("Error saving screen settings") notifications.error("Error saving screen settings")
} }
} }

View File

@ -71,7 +71,7 @@
$goto(`./${screenId}`) $goto(`./${screenId}`)
store.actions.screens.select(screenId) store.actions.screens.select(screenId)
} catch (error) { } catch (error) {
console.log(error) console.error(error)
notifications.error("Error creating screens") notifications.error("Error creating screens")
} }
} }

View File

@ -36,15 +36,12 @@
let status = null let status = null
let timeRange = null let timeRange = null
let loaded = false let loaded = false
$: app = $apps.find(app => $store.appId?.includes(app.appId))
$: app = $apps.find(app => app.devId === $store.appId?.includes(app.appId))
$: licensePlan = $auth.user?.license?.plan $: licensePlan = $auth.user?.license?.plan
$: page = $pageInfo.page $: page = $pageInfo.page
$: fetchLogs(automationId, status, page, timeRange) $: fetchLogs(automationId, status, page, timeRange)
$: isCloud = $admin.cloud $: isCloud = $admin.cloud
$: chainAutomations = app?.automations?.chainAutomations ?? !isCloud $: chainAutomations = app?.automations?.chainAutomations ?? !isCloud
const timeOptions = [ const timeOptions = [
{ value: "90-d", label: "Past 90 days" }, { value: "90-d", label: "Past 90 days" },
{ value: "30-d", label: "Past 30 days" }, { value: "30-d", label: "Past 30 days" },

View File

@ -13,6 +13,7 @@
import CreateRestoreModal from "./CreateRestoreModal.svelte" import CreateRestoreModal from "./CreateRestoreModal.svelte"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
import { isOnlyUser } from "builderStore" import { isOnlyUser } from "builderStore"
import { BackupType } from "constants/backend/backups"
export let row export let row
@ -42,12 +43,11 @@
</script> </script>
<div class="cell"> <div class="cell">
<ActionMenu align="right"> {#if row.type !== BackupType.RESTORE}
<div slot="control"> <ActionMenu align="right">
<Icon size="M" hoverable name="MoreSmallList" /> <div slot="control">
</div> <Icon size="M" hoverable name="MoreSmallList" />
</div>
{#if row.type !== "restore"}
<AbsTooltip <AbsTooltip
position={TooltipPosition.Left} position={TooltipPosition.Left}
text="Unavailable - another user is editing this app" text="Unavailable - another user is editing this app"
@ -62,8 +62,8 @@
</AbsTooltip> </AbsTooltip>
<MenuItem on:click={deleteDialog.show} icon="Delete">Delete</MenuItem> <MenuItem on:click={deleteDialog.show} icon="Delete">Delete</MenuItem>
<MenuItem on:click={downloadExport} icon="Download">Download</MenuItem> <MenuItem on:click={downloadExport} icon="Download">Download</MenuItem>
{/if} </ActionMenu>
</ActionMenu> {/if}
</div> </div>
<Modal bind:this={restoreBackupModal}> <Modal bind:this={restoreBackupModal}>

View File

@ -31,7 +31,7 @@
async function login() { async function login() {
form.validate() form.validate()
if (Object.keys(errors).length > 0) { if (Object.keys(errors).length > 0) {
console.log("errors", errors) console.error("errors", errors)
return return
} }
try { try {

View File

@ -307,7 +307,7 @@
// Reset view // Reset view
resetView() resetView()
} catch (e) { } catch (e) {
console.log("There was a problem with the map", e) console.error("There was a problem with the map", e)
} }
} }

View File

@ -61,7 +61,7 @@
resolve({ initialised: true }) resolve({ initialised: true })
}) })
.catch(err => { .catch(err => {
console.log("There was a problem scanning the image", err) console.error("There was a problem scanning the image", err)
resolve({ initialised: false }) resolve({ initialised: false })
}) })
}) })

View File

@ -28,6 +28,7 @@ import { fetchDatasourceSchema } from "./utils/schema.js"
import { getAPIKey } from "./utils/api.js" import { getAPIKey } from "./utils/api.js"
import { enrichButtonActions } from "./utils/buttonActions.js" import { enrichButtonActions } from "./utils/buttonActions.js"
import { processStringSync, makePropSafe } from "@budibase/string-templates" import { processStringSync, makePropSafe } from "@budibase/string-templates"
import { fetchData, LuceneUtils } from "@budibase/frontend-core"
export default { export default {
API, API,
@ -54,6 +55,8 @@ export default {
linkable, linkable,
getAction, getAction,
fetchDatasourceSchema, fetchDatasourceSchema,
fetchData,
LuceneUtils,
ContextScopes, ContextScopes,
getAPIKey, getAPIKey,
enrichButtonActions, enrichButtonActions,

View File

@ -14,7 +14,7 @@ const createOrgStore = () => {
const settingsConfigDoc = await API.getTenantConfig(tenantId) const settingsConfigDoc = await API.getTenantConfig(tenantId)
set({ logoUrl: settingsConfigDoc.config.logoUrl }) set({ logoUrl: settingsConfigDoc.config.logoUrl })
} catch (e) { } catch (e) {
console.log("Could not init org ", e) console.error("Could not init org ", e)
} }
} }

View File

@ -211,29 +211,27 @@ const deleteRowHandler = async action => {
const triggerAutomationHandler = async action => { const triggerAutomationHandler = async action => {
const { fields, notificationOverride, timeout } = action.parameters const { fields, notificationOverride, timeout } = action.parameters
if (fields) { try {
try { const result = await API.triggerAutomation({
const result = await API.triggerAutomation({ automationId: action.parameters.automationId,
automationId: action.parameters.automationId, fields,
fields, timeout,
timeout, })
})
// Value will exist if automation is synchronous, so return it.
if (result.value) {
if (!notificationOverride) {
notificationStore.actions.success("Automation ran successfully")
}
return { result }
}
// Value will exist if automation is synchronous, so return it.
if (result.value) {
if (!notificationOverride) { if (!notificationOverride) {
notificationStore.actions.success("Automation triggered") notificationStore.actions.success("Automation ran successfully")
} }
} catch (error) { return { result }
// Abort next actions
return false
} }
if (!notificationOverride) {
notificationStore.actions.success("Automation triggered")
}
} catch (error) {
// Abort next actions
return false
} }
} }
const navigationHandler = action => { const navigationHandler = action => {

View File

@ -29,7 +29,7 @@ export const createGridWebsocket = context => {
connectToDatasource(get(datasource)) connectToDatasource(get(datasource))
}) })
socket.on("connect_error", err => { socket.on("connect_error", err => {
console.log("Failed to connect to grid websocket:", err.message) console.error("Failed to connect to grid websocket:", err.message)
}) })
// User events // User events

@ -1 +1 @@
Subproject commit eb9565f568cfef14b336b14eee753119acfdd43b Subproject commit 4f9616f163039a0eea81319d8e2288340a2ebc79

View File

@ -1,7 +1,13 @@
import fs from "fs"
import { join } from "path"
module AwsMock { module AwsMock {
const aws: any = {} const aws: any = {}
const response = (body: any) => () => ({ promise: () => body }) const response = (body: any, extra?: any) => () => ({
promise: () => body,
...extra,
})
function DocumentClient() { function DocumentClient() {
// @ts-ignore // @ts-ignore
@ -73,9 +79,18 @@ module AwsMock {
// @ts-ignore // @ts-ignore
this.getObject = jest.fn( this.getObject = jest.fn(
response({ response(
Body: "", {
}) Body: "",
},
{
createReadStream: jest
.fn()
.mockReturnValue(
fs.createReadStream(join(__dirname, "aws-sdk.ts"))
),
}
)
) )
} }

View File

@ -445,6 +445,9 @@ export async function update(ctx: UserCtx) {
name: app.name, name: app.name,
url: app.url, url: app.url,
icon: app.icon, icon: app.icon,
automations: {
chainAutomations: app.automations?.chainAutomations,
},
}) })
} }

View File

@ -165,8 +165,9 @@ export async function importApp(
const isTar = template.file && template?.file?.type?.endsWith("gzip") const isTar = template.file && template?.file?.type?.endsWith("gzip")
const isDirectory = const isDirectory =
template.file && fs.lstatSync(template.file.path).isDirectory() template.file && fs.lstatSync(template.file.path).isDirectory()
let tmpPath: string | undefined = undefined
if (template.file && (isTar || isDirectory)) { if (template.file && (isTar || isDirectory)) {
const tmpPath = isTar ? await untarFile(template.file) : template.file.path tmpPath = isTar ? await untarFile(template.file) : template.file.path
if (isTar && template.file.password) { if (isTar && template.file.password) {
await decryptFiles(tmpPath, template.file.password) await decryptFiles(tmpPath, template.file.password)
} }
@ -208,5 +209,9 @@ export async function importApp(
} }
await updateAttachmentColumns(prodAppId, db) await updateAttachmentColumns(prodAppId, db)
await updateAutomations(prodAppId, db) await updateAutomations(prodAppId, db)
// clear up afterward
if (tmpPath) {
fs.rmSync(tmpPath, { recursive: true, force: true })
}
return ok return ok
} }