Type everywhere!
This commit is contained in:
parent
0b3a48b2b7
commit
0827cc6bda
|
@ -60,7 +60,7 @@ function generateSchema(
|
|||
schema.text(key)
|
||||
break
|
||||
case FieldType.BB_REFERENCE: {
|
||||
const subtype = column.subtype as FieldSubtype
|
||||
const subtype = column.subtype
|
||||
switch (subtype) {
|
||||
case FieldSubtype.USER:
|
||||
schema.text(key)
|
||||
|
|
|
@ -67,7 +67,7 @@ export function searchInputMapping(table: Table, options: SearchParams) {
|
|||
for (let [key, column] of Object.entries(table.schema)) {
|
||||
switch (column.type) {
|
||||
case FieldType.BB_REFERENCE: {
|
||||
const subtype = column.subtype as FieldSubtype
|
||||
const subtype = column.subtype
|
||||
switch (subtype) {
|
||||
case FieldSubtype.USER:
|
||||
case FieldSubtype.USERS:
|
||||
|
|
|
@ -7,7 +7,7 @@ const ROW_PREFIX = DocumentType.ROW + SEPARATOR
|
|||
|
||||
export async function processInputBBReferences(
|
||||
value: string | string[] | { _id: string } | { _id: string }[],
|
||||
subtype: FieldSubtype
|
||||
subtype: FieldSubtype.USER | FieldSubtype.USERS
|
||||
): Promise<string | string[] | null> {
|
||||
let referenceIds: string[] = []
|
||||
|
||||
|
@ -61,7 +61,7 @@ export async function processInputBBReferences(
|
|||
|
||||
export async function processOutputBBReferences(
|
||||
value: string | string[],
|
||||
subtype: FieldSubtype
|
||||
subtype: FieldSubtype.USER | FieldSubtype.USERS
|
||||
) {
|
||||
if (value === null || value === undefined) {
|
||||
// Already processed or nothing to process
|
||||
|
|
|
@ -159,10 +159,7 @@ export async function inputProcessing(
|
|||
}
|
||||
|
||||
if (field.type === FieldType.BB_REFERENCE && value) {
|
||||
clonedRow[key] = await processInputBBReferences(
|
||||
value,
|
||||
field.subtype as FieldSubtype
|
||||
)
|
||||
clonedRow[key] = await processInputBBReferences(value, field.subtype)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,7 +235,7 @@ export async function outputProcessing<T extends Row[] | Row>(
|
|||
for (let row of enriched) {
|
||||
row[property] = await processOutputBBReferences(
|
||||
row[property],
|
||||
column.subtype as FieldSubtype
|
||||
column.subtype
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,14 @@
|
|||
import { FieldType, FieldSubtype } from "@budibase/types"
|
||||
import {
|
||||
FieldType,
|
||||
FieldSubtype,
|
||||
TableSchema,
|
||||
FieldSchema,
|
||||
Row,
|
||||
} from "@budibase/types"
|
||||
import { ValidColumnNameRegex, utils } from "@budibase/shared-core"
|
||||
import { db } from "@budibase/backend-core"
|
||||
import { parseCsvExport } from "../api/controllers/view/exporters"
|
||||
|
||||
interface SchemaColumn {
|
||||
readonly name: string
|
||||
readonly type: FieldType
|
||||
readonly subtype: FieldSubtype
|
||||
readonly autocolumn?: boolean
|
||||
readonly constraints?: {
|
||||
presence: boolean
|
||||
}
|
||||
}
|
||||
|
||||
interface Schema {
|
||||
readonly [index: string]: SchemaColumn
|
||||
}
|
||||
|
||||
interface Row {
|
||||
[index: string]: any
|
||||
}
|
||||
|
||||
type Rows = Array<Row>
|
||||
|
||||
interface SchemaValidation {
|
||||
|
@ -34,12 +22,10 @@ interface ValidationResults {
|
|||
errors: Record<string, string>
|
||||
}
|
||||
|
||||
export function isSchema(schema: any): schema is Schema {
|
||||
export function isSchema(schema: any): schema is TableSchema {
|
||||
return (
|
||||
typeof schema === "object" &&
|
||||
Object.values(schema).every(rawColumn => {
|
||||
const column = rawColumn as SchemaColumn
|
||||
|
||||
Object.values<FieldSchema>(schema).every(column => {
|
||||
return (
|
||||
column !== null &&
|
||||
typeof column === "object" &&
|
||||
|
@ -54,7 +40,7 @@ export function isRows(rows: any): rows is Rows {
|
|||
return Array.isArray(rows) && rows.every(row => typeof row === "object")
|
||||
}
|
||||
|
||||
export function validate(rows: Rows, schema: Schema): ValidationResults {
|
||||
export function validate(rows: Rows, schema: TableSchema): ValidationResults {
|
||||
const results: ValidationResults = {
|
||||
schemaValidation: {},
|
||||
allValid: false,
|
||||
|
@ -64,9 +50,11 @@ export function validate(rows: Rows, schema: Schema): ValidationResults {
|
|||
|
||||
rows.forEach(row => {
|
||||
Object.entries(row).forEach(([columnName, columnData]) => {
|
||||
const columnType = schema[columnName]?.type
|
||||
const columnSubtype = schema[columnName]?.subtype
|
||||
const isAutoColumn = schema[columnName]?.autocolumn
|
||||
const {
|
||||
type: columnType,
|
||||
subtype: columnSubtype,
|
||||
autocolumn: isAutoColumn,
|
||||
} = schema[columnName]
|
||||
|
||||
// If the column had an invalid value we don't want to override it
|
||||
if (results.schemaValidation[columnName] === false) {
|
||||
|
@ -123,7 +111,7 @@ export function validate(rows: Rows, schema: Schema): ValidationResults {
|
|||
return results
|
||||
}
|
||||
|
||||
export function parse(rows: Rows, schema: Schema): Rows {
|
||||
export function parse(rows: Rows, schema: TableSchema): Rows {
|
||||
return rows.map(row => {
|
||||
const parsedRow: Row = {}
|
||||
|
||||
|
@ -133,9 +121,7 @@ export function parse(rows: Rows, schema: Schema): Rows {
|
|||
return
|
||||
}
|
||||
|
||||
const columnType = schema[columnName].type
|
||||
const columnSubtype = schema[columnName].subtype
|
||||
|
||||
const { type: columnType, subtype: columnSubtype } = schema[columnName]
|
||||
if (columnType === FieldType.NUMBER) {
|
||||
// If provided must be a valid number
|
||||
parsedRow[columnName] = columnData ? Number(columnData) : columnData
|
||||
|
@ -172,7 +158,7 @@ export function parse(rows: Rows, schema: Schema): Rows {
|
|||
|
||||
function isValidBBReference(
|
||||
columnData: any,
|
||||
columnSubtype: FieldSubtype
|
||||
columnSubtype: FieldSubtype.USER | FieldSubtype.USERS
|
||||
): boolean {
|
||||
switch (columnSubtype) {
|
||||
case FieldSubtype.USER:
|
||||
|
|
|
@ -41,12 +41,13 @@ export enum FieldSubtype {
|
|||
SINGLE = "single",
|
||||
}
|
||||
|
||||
// The 'as' are required for typescript not to type the outputs as generic FieldSubtype
|
||||
export const FieldTypeSubtypes = {
|
||||
BB_REFERENCE: {
|
||||
USER: FieldSubtype.USER,
|
||||
USERS: FieldSubtype.USERS,
|
||||
USER: FieldSubtype.USER as FieldSubtype.USER,
|
||||
USERS: FieldSubtype.USERS as FieldSubtype.USERS,
|
||||
},
|
||||
ATTACHMENT: {
|
||||
SINGLE: FieldSubtype.SINGLE,
|
||||
SINGLE: FieldSubtype.SINGLE as FieldSubtype.SINGLE,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -17,13 +17,14 @@ export interface UIFieldMetadata {
|
|||
}
|
||||
|
||||
interface BaseRelationshipFieldMetadata
|
||||
extends Omit<BaseFieldSchema, "subtype"> {
|
||||
extends BaseFieldSchema<
|
||||
AutoFieldSubType.CREATED_BY | AutoFieldSubType.UPDATED_BY | undefined
|
||||
> {
|
||||
type: FieldType.LINK
|
||||
main?: boolean
|
||||
fieldName: string
|
||||
tableId: string
|
||||
tableRev?: string
|
||||
subtype?: AutoFieldSubType.CREATED_BY | AutoFieldSubType.UPDATED_BY
|
||||
}
|
||||
|
||||
// External tables use junction tables, internal tables don't require them
|
||||
|
@ -60,18 +61,17 @@ export type RelationshipFieldMetadata =
|
|||
| ManyToOneRelationshipFieldMetadata
|
||||
|
||||
export interface AutoColumnFieldMetadata
|
||||
extends Omit<BaseFieldSchema, "subtype"> {
|
||||
extends BaseFieldSchema<AutoFieldSubType | undefined> {
|
||||
type: FieldType.AUTO
|
||||
autocolumn: true
|
||||
subtype?: AutoFieldSubType
|
||||
lastID?: number
|
||||
// if the column was turned to an auto-column for SQL, explains why (primary, foreign etc)
|
||||
autoReason?: AutoReason
|
||||
}
|
||||
|
||||
export interface NumberFieldMetadata extends Omit<BaseFieldSchema, "subtype"> {
|
||||
export interface NumberFieldMetadata
|
||||
extends BaseFieldSchema<AutoFieldSubType.AUTO_ID | undefined> {
|
||||
type: FieldType.NUMBER
|
||||
subtype?: AutoFieldSubType.AUTO_ID
|
||||
lastID?: number
|
||||
autoReason?: AutoReason.FOREIGN_KEY
|
||||
// used specifically when Budibase generates external tables, this denotes if a number field
|
||||
|
@ -82,16 +82,18 @@ export interface NumberFieldMetadata extends Omit<BaseFieldSchema, "subtype"> {
|
|||
}
|
||||
}
|
||||
|
||||
export interface JsonFieldMetadata extends Omit<BaseFieldSchema, "subtype"> {
|
||||
export interface JsonFieldMetadata
|
||||
extends BaseFieldSchema<JsonFieldSubType.ARRAY | undefined> {
|
||||
type: FieldType.JSON
|
||||
subtype?: JsonFieldSubType.ARRAY
|
||||
}
|
||||
|
||||
export interface DateFieldMetadata extends Omit<BaseFieldSchema, "subtype"> {
|
||||
export interface DateFieldMetadata
|
||||
extends BaseFieldSchema<
|
||||
AutoFieldSubType.CREATED_AT | AutoFieldSubType.UPDATED_AT | undefined
|
||||
> {
|
||||
type: FieldType.DATETIME
|
||||
ignoreTimezones?: boolean
|
||||
timeOnly?: boolean
|
||||
subtype?: AutoFieldSubType.CREATED_AT | AutoFieldSubType.UPDATED_AT
|
||||
}
|
||||
|
||||
export interface LongFormFieldMetadata extends BaseFieldSchema {
|
||||
|
@ -106,12 +108,17 @@ export interface FormulaFieldMetadata extends BaseFieldSchema {
|
|||
}
|
||||
|
||||
export interface BBReferenceFieldMetadata
|
||||
extends Omit<BaseFieldSchema, "subtype"> {
|
||||
extends BaseFieldSchema<FieldSubtype.USER | FieldSubtype.USERS> {
|
||||
type: FieldType.BB_REFERENCE
|
||||
subtype: FieldSubtype.USER | FieldSubtype.USERS
|
||||
|
||||
relationshipType?: RelationshipType
|
||||
}
|
||||
|
||||
export interface AttachmentFieldMetadata
|
||||
extends BaseFieldSchema<FieldSubtype.SINGLE | undefined> {
|
||||
type: FieldType.ATTACHMENT
|
||||
}
|
||||
|
||||
export interface FieldConstraints {
|
||||
type?: string
|
||||
email?: boolean
|
||||
|
@ -136,7 +143,7 @@ export interface FieldConstraints {
|
|||
}
|
||||
}
|
||||
|
||||
interface BaseFieldSchema extends UIFieldMetadata {
|
||||
interface BaseFieldSchema<TSubtype = never> extends UIFieldMetadata {
|
||||
type: FieldType
|
||||
name: string
|
||||
sortable?: boolean
|
||||
|
@ -145,11 +152,7 @@ interface BaseFieldSchema extends UIFieldMetadata {
|
|||
constraints?: FieldConstraints
|
||||
autocolumn?: boolean
|
||||
autoReason?: AutoReason.FOREIGN_KEY
|
||||
subtype?: never
|
||||
}
|
||||
interface AttachmentFieldMetadata extends Omit<BaseFieldSchema, "subtype"> {
|
||||
type: FieldType.ATTACHMENT
|
||||
subtype?: FieldSubtype.SINGLE
|
||||
subtype: TSubtype
|
||||
}
|
||||
|
||||
interface OtherFieldMetadata extends BaseFieldSchema {
|
||||
|
|
Loading…
Reference in New Issue