1
0
Fork 0
mirror of synced 2024-09-12 23:43:09 +12:00

Fixing some issues with updating rows with attachments, there were some UI bugs that had been raised (undefined being displayed) and the uploading from a URL was not working as expected, due to the stream not matching the expected format of the S3 SDK - this has been fixed by converting the stream to a true readable stream with .

This commit is contained in:
mike12345567 2024-05-13 18:11:40 +01:00
parent 9c312826ca
commit 5b5e7e47a2
7 changed files with 70 additions and 54 deletions

View file

@ -9,6 +9,9 @@ import {
AutomationAttachmentContent, AutomationAttachmentContent,
BucketedContent, BucketedContent,
} from "@budibase/types" } from "@budibase/types"
import stream from "stream"
import streamWeb from "node:stream/web"
/**************************************************** /****************************************************
* NOTE: When adding a new bucket - name * * NOTE: When adding a new bucket - name *
* sure that S3 usages (like budibase-infra) * * sure that S3 usages (like budibase-infra) *
@ -53,12 +56,10 @@ export const bucketTTLConfig = (
Rules: [lifecycleRule], Rules: [lifecycleRule],
} }
const params = { return {
Bucket: bucketName, Bucket: bucketName,
LifecycleConfiguration: lifecycleConfiguration, LifecycleConfiguration: lifecycleConfiguration,
} }
return params
} }
async function processUrlAttachment( async function processUrlAttachment(
@ -71,7 +72,7 @@ async function processUrlAttachment(
const fallbackFilename = path.basename(new URL(attachment.url).pathname) const fallbackFilename = path.basename(new URL(attachment.url).pathname)
return { return {
filename: attachment.filename || fallbackFilename, filename: attachment.filename || fallbackFilename,
content: response.body, content: stream.Readable.fromWeb(response.body as streamWeb.ReadableStream),
} }
} }

View file

@ -374,6 +374,16 @@
return `${value.title || (key === "row" ? "Table" : key)} ${requiredSuffix}` return `${value.title || (key === "row" ? "Table" : key)} ${requiredSuffix}`
} }
function handleAttachmentParams(keyValueObj) {
let params = {}
if (keyValueObj?.length) {
for (let param of keyValueObj) {
params[param.url] = param.filename
}
}
return params
}
onMount(async () => { onMount(async () => {
try { try {
await environment.loadVariables() await environment.loadVariables()
@ -381,15 +391,6 @@
console.error(error) console.error(error)
} }
}) })
const handleAttachmentParams = keyValuObj => {
let params = {}
if (keyValuObj?.length) {
for (let param of keyValuObj) {
params[param.url] = param.filename
}
}
return params
}
</script> </script>
<div class="fields"> <div class="fields">

View file

@ -25,21 +25,21 @@
return !!schema.constraints?.inclusion?.length return !!schema.constraints?.inclusion?.length
} }
const handleAttachmentParams = keyValuObj => { function handleAttachmentParams(keyValueObj) {
let params = {} let params = {}
if ( if (
schema.type === FieldType.ATTACHMENT_SINGLE && schema.type === FieldType.ATTACHMENT_SINGLE &&
Object.keys(keyValuObj).length === 0 Object.keys(keyValueObj).length === 0
) { ) {
return [] return []
} }
if (!Array.isArray(keyValuObj)) { if (!Array.isArray(keyValueObj) && keyValueObj) {
keyValuObj = [keyValuObj] keyValueObj = [keyValueObj]
} }
if (keyValuObj.length) { if (keyValueObj.length) {
for (let param of keyValuObj) { for (let param of keyValueObj) {
params[param.url] = param.filename params[param.url] = param.filename
} }
} }

View file

@ -163,7 +163,7 @@ async function generateAttachmentRow(attachment: AutomationAttachment) {
try { try {
const { filename } = attachment const { filename } = attachment
const extension = path.extname(filename) const extension = path.extname(filename).replaceAll(".", "")
const attachmentResult = await objectStore.processAutomationAttachment( const attachmentResult = await objectStore.processAutomationAttachment(
attachment attachment
) )
@ -183,7 +183,7 @@ async function generateAttachmentRow(attachment: AutomationAttachment) {
return { return {
size, size,
name: filename, name: filename,
extension, extension: extension,
key: s3Key, key: s3Key,
} }
} catch (error) { } catch (error) {

View file

@ -94,18 +94,6 @@ export async function run({ inputs, appId, emitter }: AutomationStepInput) {
} }
} }
// have to clean up the row, remove the table from it
const ctx: any = buildCtx(appId, emitter, {
body: {
...inputs.row,
_id: inputs.rowId,
},
params: {
rowId: inputs.rowId,
tableId: tableId,
},
})
try { try {
if (tableId) { if (tableId) {
inputs.row = await automationUtils.cleanUpRow( inputs.row = await automationUtils.cleanUpRow(
@ -118,6 +106,17 @@ export async function run({ inputs, appId, emitter }: AutomationStepInput) {
inputs.row inputs.row
) )
} }
// have to clean up the row, remove the table from it
const ctx: any = buildCtx(appId, emitter, {
body: {
...inputs.row,
_id: inputs.rowId,
},
params: {
rowId: inputs.rowId,
tableId: tableId,
},
})
await rowController.patch(ctx) await rowController.patch(ctx)
return { return {
row: ctx.body, row: ctx.body,

View file

@ -1,6 +1,12 @@
import { ObjectStoreBuckets } from "../../constants" import { ObjectStoreBuckets } from "../../constants"
import { context, db as dbCore, objectStore } from "@budibase/backend-core" import { context, db as dbCore, objectStore } from "@budibase/backend-core"
import { FieldType, RenameColumn, Row, Table } from "@budibase/types" import {
FieldType,
RenameColumn,
Row,
RowAttachment,
Table,
} from "@budibase/types"
export class AttachmentCleanup { export class AttachmentCleanup {
static async coreCleanup(fileListFn: () => string[]): Promise<void> { static async coreCleanup(fileListFn: () => string[]): Promise<void> {
@ -21,7 +27,7 @@ export class AttachmentCleanup {
private static extractAttachmentKeys( private static extractAttachmentKeys(
type: FieldType, type: FieldType,
rowData: any rowData: RowAttachment[] | RowAttachment
): string[] { ): string[] {
if ( if (
type !== FieldType.ATTACHMENTS && type !== FieldType.ATTACHMENTS &&
@ -34,10 +40,15 @@ export class AttachmentCleanup {
return [] return []
} }
if (type === FieldType.ATTACHMENTS) { if (type === FieldType.ATTACHMENTS && Array.isArray(rowData)) {
return rowData.map((attachment: any) => attachment.key) return rowData
.filter(attachment => attachment.key)
.map(attachment => attachment.key)
} else if ("key" in rowData) {
return [rowData.key]
} }
return [rowData.key]
return []
} }
private static async tableChange( private static async tableChange(

View file

@ -1,11 +1,11 @@
import * as linkRows from "../../db/linkedRows" import * as linkRows from "../../db/linkedRows"
import { processFormulas, fixAutoColumnSubType } from "./utils" import { fixAutoColumnSubType, processFormulas } from "./utils"
import { objectStore, utils } from "@budibase/backend-core" import { objectStore, utils } from "@budibase/backend-core"
import { InternalTables } from "../../db/utils" import { InternalTables } from "../../db/utils"
import { TYPE_TRANSFORM_MAP } from "./map" import { TYPE_TRANSFORM_MAP } from "./map"
import { import {
FieldType,
AutoFieldSubType, AutoFieldSubType,
FieldType,
Row, Row,
RowAttachment, RowAttachment,
Table, Table,
@ -221,27 +221,31 @@ export async function outputProcessing<T extends Row[] | Row>(
opts.squash = true opts.squash = true
} }
// process complex types: attachements, bb references... // process complex types: attachments, bb references...
for (let [property, column] of Object.entries(table.schema)) { for (let [property, column] of Object.entries(table.schema)) {
if (column.type === FieldType.ATTACHMENTS) { if (
column.type === FieldType.ATTACHMENTS ||
column.type === FieldType.ATTACHMENT_SINGLE
) {
for (let row of enriched) { for (let row of enriched) {
if (row[property] == null || !Array.isArray(row[property])) { if (row[property] == null) {
continue continue
} }
row[property].forEach((attachment: RowAttachment) => { const process = (attachment: RowAttachment) => {
if (!attachment.url) { if (!attachment.url && attachment.key) {
attachment.url = objectStore.getAppFileUrl(attachment.key) attachment.url = objectStore.getAppFileUrl(attachment.key)
} }
}) return attachment
}
} else if (column.type === FieldType.ATTACHMENT_SINGLE) {
for (let row of enriched) {
if (!row[property] || Object.keys(row[property]).length === 0) {
continue
} }
if (typeof row[property] === "string") {
if (!row[property].url) { row[property] = JSON.parse(row[property])
row[property].url = objectStore.getAppFileUrl(row[property].key) }
if (Array.isArray(row[property])) {
row[property].forEach((attachment: RowAttachment) => {
process(attachment)
})
} else {
process(row[property])
} }
} }
} else if ( } else if (