1
0
Fork 0
mirror of synced 2024-09-25 22:01:43 +12:00
budibase/packages/server/src/utilities/rowProcessor/bbReferenceProcessor.ts

194 lines
4.9 KiB
TypeScript
Raw Normal View History

import { cache, db as dbCore } from "@budibase/backend-core"
2023-09-15 21:21:10 +12:00
import { utils } from "@budibase/shared-core"
2024-04-23 03:27:26 +12:00
import {
FieldType,
2024-04-26 22:23:11 +12:00
BBReferenceFieldSubType,
2024-04-23 03:27:26 +12:00
DocumentType,
SEPARATOR,
} from "@budibase/types"
2023-09-15 22:07:25 +12:00
import { InvalidBBRefError } from "./errors"
2023-09-15 20:33:36 +12:00
const ROW_PREFIX = DocumentType.ROW + SEPARATOR
2024-04-26 19:47:46 +12:00
export function processInputBBReferences(
value: string | { _id: string },
type: FieldType.BB_REFERENCE_SINGLE
2024-04-23 06:58:35 +12:00
): Promise<string | null>
2024-04-26 19:47:46 +12:00
export function processInputBBReferences(
2023-09-15 22:07:25 +12:00
value: string | string[] | { _id: string } | { _id: string }[],
2024-04-26 19:47:46 +12:00
type: FieldType.BB_REFERENCE,
2024-04-26 23:30:08 +12:00
subtype: BBReferenceFieldSubType
2024-04-23 03:27:26 +12:00
): Promise<string | null>
2024-04-26 19:47:46 +12:00
export async function processInputBBReferences(
2024-04-23 03:27:26 +12:00
value: string | string[] | { _id: string } | { _id: string }[],
2024-04-26 19:47:46 +12:00
type: FieldType.BB_REFERENCE | FieldType.BB_REFERENCE_SINGLE,
subtype?: BBReferenceFieldSubType
2023-10-05 03:50:05 +13:00
): Promise<string | string[] | null> {
switch (type) {
2024-04-26 02:40:13 +12:00
case FieldType.BB_REFERENCE: {
let referenceIds: string[] = []
2023-09-20 21:07:32 +12:00
if (Array.isArray(value)) {
referenceIds.push(
...value.map(idOrDoc =>
typeof idOrDoc === "string" ? idOrDoc : idOrDoc._id
)
)
} else if (typeof value !== "string") {
referenceIds.push(value._id)
} else {
referenceIds.push(
...value
.split(",")
.filter(x => x)
.map((id: string) => id.trim())
)
}
2023-09-15 21:21:10 +12:00
// make sure all reference IDs are correct global user IDs
// they may be user metadata references (start with row prefix)
// and these need to be converted to global IDs
referenceIds = referenceIds.map(id => {
if (id?.startsWith(ROW_PREFIX)) {
return dbCore.getGlobalIDFromUserMetadataID(id)
} else {
return id
}
})
2024-04-23 03:27:26 +12:00
switch (subtype) {
case undefined:
throw "Subtype must be defined"
case BBReferenceFieldSubType.USER:
case BBReferenceFieldSubType.USERS: {
2024-04-23 03:27:26 +12:00
const { notFoundIds } = await cache.user.getUsers(referenceIds)
if (notFoundIds?.length) {
throw new InvalidBBRefError(
notFoundIds[0],
BBReferenceFieldSubType.USER
)
2024-04-23 03:27:26 +12:00
}
2024-04-25 23:20:00 +12:00
if (!referenceIds?.length) {
return null
}
if (subtype === BBReferenceFieldSubType.USERS) {
2024-04-23 03:27:26 +12:00
return referenceIds
}
2024-04-25 23:20:00 +12:00
return referenceIds.join(",")
2024-04-23 06:58:35 +12:00
}
2024-04-23 03:27:26 +12:00
default:
throw utils.unreachable(subtype)
2023-09-15 21:21:10 +12:00
}
2024-04-26 02:40:13 +12:00
}
2024-04-23 06:58:35 +12:00
case FieldType.BB_REFERENCE_SINGLE: {
if (value && Array.isArray(value)) {
throw "BB_REFERENCE_SINGLE cannot be an array"
}
const id = typeof value === "string" ? value : value._id
const user = await cache.user.getUser(id)
2024-04-23 03:27:26 +12:00
if (!user) {
throw new InvalidBBRefError(id, BBReferenceFieldSubType.USER)
2023-10-05 03:50:05 +13:00
}
2024-04-25 23:38:31 +12:00
return user._id!
2024-04-23 06:58:35 +12:00
}
2024-04-23 03:27:26 +12:00
2023-09-15 21:21:10 +12:00
default:
2024-04-23 03:27:26 +12:00
throw utils.unreachable(type)
2023-09-15 21:21:10 +12:00
}
}
2023-09-15 23:31:22 +12:00
2024-04-23 03:27:26 +12:00
interface UserReferenceInfo {
_id: string
primaryDisplay: string
email: string
firstName: string
lastName: string
}
2024-04-26 19:47:46 +12:00
export function processOutputBBReferences(
2024-04-23 06:58:35 +12:00
value: string,
2024-04-26 19:47:46 +12:00
type: FieldType.BB_REFERENCE_SINGLE
2024-04-23 06:58:35 +12:00
): Promise<UserReferenceInfo>
2024-04-26 19:47:46 +12:00
export function processOutputBBReferences(
value: string,
type: FieldType.BB_REFERENCE,
2024-04-26 23:30:08 +12:00
subtype: BBReferenceFieldSubType
2024-04-26 19:47:46 +12:00
): Promise<UserReferenceInfo[]>
2024-04-23 03:27:26 +12:00
2023-09-15 23:31:22 +12:00
export async function processOutputBBReferences(
2023-10-05 03:50:05 +13:00
value: string | string[],
2024-04-23 03:27:26 +12:00
type: FieldType.BB_REFERENCE | FieldType.BB_REFERENCE_SINGLE,
subtype?: BBReferenceFieldSubType
2023-09-15 23:31:22 +12:00
) {
2023-10-05 03:50:05 +13:00
if (value === null || value === undefined) {
2023-09-19 23:17:07 +12:00
// Already processed or nothing to process
2023-09-30 03:39:18 +13:00
return value || undefined
2023-09-15 23:47:08 +12:00
}
2024-04-23 03:27:26 +12:00
switch (type) {
2024-04-26 02:40:13 +12:00
case FieldType.BB_REFERENCE: {
2024-04-23 03:27:26 +12:00
const ids =
typeof value === "string" ? value.split(",").filter(id => !!id) : value
switch (subtype) {
case undefined:
throw "Subtype must be defined"
case BBReferenceFieldSubType.USER:
case BBReferenceFieldSubType.USERS: {
2024-04-23 03:27:26 +12:00
const { users } = await cache.user.getUsers(ids)
if (!users.length) {
return undefined
}
return users.map(u => ({
_id: u._id,
primaryDisplay: u.email,
email: u.email,
firstName: u.firstName,
lastName: u.lastName,
}))
2024-04-23 06:58:35 +12:00
}
2024-04-23 03:27:26 +12:00
default:
throw utils.unreachable(subtype)
}
2024-04-26 02:40:13 +12:00
}
case FieldType.BB_REFERENCE_SINGLE: {
2024-04-26 01:50:28 +12:00
if (!value) {
return undefined
}
let user
try {
user = await cache.user.getUser(value as string)
} catch (err: any) {
if (err.code !== 404) {
throw err
}
}
2024-04-23 03:27:26 +12:00
if (!user) {
2023-09-20 21:07:32 +12:00
return undefined
}
2024-04-23 03:27:26 +12:00
return {
_id: user._id,
primaryDisplay: user.email,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
}
2024-04-26 02:40:13 +12:00
}
2024-04-23 03:27:26 +12:00
2023-09-15 23:31:22 +12:00
default:
2024-04-23 03:27:26 +12:00
throw utils.unreachable(type)
2023-09-15 23:31:22 +12:00
}
}