Validate user column

This commit is contained in:
Adria Navarro 2023-10-09 18:02:21 +02:00
parent a514358e57
commit f22467fa53
3 changed files with 81 additions and 2 deletions

View File

@ -45,6 +45,11 @@ export function generateGlobalUserID(id?: any) {
return `${DocumentType.USER}${SEPARATOR}${id || newid()}` return `${DocumentType.USER}${SEPARATOR}${id || newid()}`
} }
const isGlobalUserIDRegex = new RegExp(`^${DocumentType.USER}${SEPARATOR}.+`)
export function isGlobalUserID(id: string) {
return isGlobalUserIDRegex.test(id)
}
/** /**
* Generates a new user ID based on the passed in global ID. * Generates a new user ID based on the passed in global ID.
* @param {string} globalId The ID of the global user. * @param {string} globalId The ID of the global user.

View File

@ -3,6 +3,7 @@
import { FIELDS } from "constants/backend" import { FIELDS } from "constants/backend"
import { API } from "api" import { API } from "api"
import { parseFile } from "./utils" import { parseFile } from "./utils"
import { FieldType } from "@budibase/types"
export let rows = [] export let rows = []
export let schema = {} export let schema = {}
@ -86,10 +87,35 @@
let validateHash = "" let validateHash = ""
let errors = {} let errors = {}
let selectedColumnTypes = {} let selectedColumnTypes = {}
let rawRows = []
$: displayColumnOptions = Object.keys(schema || {}).filter(column => { $: displayColumnOptions = Object.keys(schema || {}).filter(column => {
return validation[column] return validation[column]
}) })
$: {
rows = []
for (const row of rawRows) {
const castedRow = { ...row }
for (const fieldSchema of Object.values(schema || {})) {
if (fieldSchema.type === FieldType.BB_REFERENCE) {
try {
castedRow[fieldSchema.name] = JSON.parse(
row[fieldSchema.name].replace(/'/g, '"')
)
} catch {
console.warn("Not a valid json", {
field: fieldSchema.name,
data: row[fieldSchema.name],
})
}
}
}
rows.push(castedRow)
}
}
$: { $: {
// binding in consumer is causing double renders here // binding in consumer is causing double renders here
const newValidateHash = JSON.stringify(rows) + JSON.stringify(schema) const newValidateHash = JSON.stringify(rows) + JSON.stringify(schema)
@ -107,7 +133,7 @@
try { try {
const response = await parseFile(e) const response = await parseFile(e)
rows = response.rows rawRows = response.rows
schema = response.schema schema = response.schema
fileName = response.fileName fileName = response.fileName
selectedColumnTypes = Object.entries(response.schema).reduce( selectedColumnTypes = Object.entries(response.schema).reduce(

View File

@ -1,9 +1,12 @@
import { FieldSubtype } from "@budibase/types"
import { FieldTypes } from "../constants" import { FieldTypes } from "../constants"
import { ValidColumnNameRegex } from "@budibase/shared-core" import { ValidColumnNameRegex, utils } from "@budibase/shared-core"
import { db } from "@budibase/backend-core"
interface SchemaColumn { interface SchemaColumn {
readonly name: string readonly name: string
readonly type: FieldTypes readonly type: FieldTypes
readonly subtype: FieldSubtype
readonly autocolumn?: boolean readonly autocolumn?: boolean
readonly constraints?: { readonly constraints?: {
presence: boolean presence: boolean
@ -77,8 +80,14 @@ export function validate(rows: Rows, schema: Schema): ValidationResults {
rows.forEach(row => { rows.forEach(row => {
Object.entries(row).forEach(([columnName, columnData]) => { Object.entries(row).forEach(([columnName, columnData]) => {
const columnType = schema[columnName]?.type const columnType = schema[columnName]?.type
const columnSubtype = schema[columnName]?.subtype
const isAutoColumn = schema[columnName]?.autocolumn const isAutoColumn = schema[columnName]?.autocolumn
// If the column had an invalid value we don't want to override it
if (results.schemaValidation[columnName] === false) {
return
}
// If the columnType is not a string, then it's not present in the schema, and should be added to the invalid columns array // If the columnType is not a string, then it's not present in the schema, and should be added to the invalid columns array
if (typeof columnType !== "string") { if (typeof columnType !== "string") {
results.invalidColumns.push(columnName) results.invalidColumns.push(columnName)
@ -112,6 +121,11 @@ export function validate(rows: Rows, schema: Schema): ValidationResults {
isNaN(new Date(columnData).getTime()) isNaN(new Date(columnData).getTime())
) { ) {
results.schemaValidation[columnName] = false results.schemaValidation[columnName] = false
} else if (
columnType === FieldTypes.BB_REFERENCE &&
!isValidBBReference(columnData, columnSubtype)
) {
results.schemaValidation[columnName] = false
} else { } else {
results.schemaValidation[columnName] = true results.schemaValidation[columnName] = true
} }
@ -155,3 +169,37 @@ export function parse(rows: Rows, schema: Schema): Rows {
return parsedRow return parsedRow
}) })
} }
function isValidBBReference(
columnData: any,
columnSubtype: FieldSubtype
): boolean {
switch (columnSubtype) {
case FieldSubtype.USER:
case FieldSubtype.USERS:
if (!columnData) {
// Empty columns are valid by default
return true
}
if (!Array.isArray(columnData)) {
// It must be an array field
return false
}
if (columnSubtype === FieldSubtype.USER && columnData.length > 1) {
return false
}
for (const d of columnData) {
if (!db.isGlobalUserID(d._id)) {
return false
}
}
return true
default:
throw utils.unreachable(columnSubtype)
}
}