A quick refactor to get rid of the old 'FieldTypes' enumeration, considering how core it is to all data handling in Budibase, the fact we had both 'FieldType' and 'FieldTypes' was confusing - righting this fully.
This commit is contained in:
parent
34d7fe4372
commit
ccc751d09c
|
@ -1,4 +1,4 @@
|
||||||
import { FieldTypes, RelationshipType, FormulaTypes } from "../../src/constants"
|
import { FieldType, FormulaType, RelationshipType } from "@budibase/types"
|
||||||
import { object } from "./utils"
|
import { object } from "./utils"
|
||||||
import Resource from "./utils/Resource"
|
import Resource from "./utils/Resource"
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ const table = {
|
||||||
const baseColumnDef = {
|
const baseColumnDef = {
|
||||||
type: {
|
type: {
|
||||||
type: "string",
|
type: "string",
|
||||||
enum: Object.values(FieldTypes),
|
enum: Object.values(FieldType),
|
||||||
description:
|
description:
|
||||||
"Defines the type of the column, most explain themselves, a link column is a relationship.",
|
"Defines the type of the column, most explain themselves, a link column is a relationship.",
|
||||||
},
|
},
|
||||||
|
@ -81,7 +81,7 @@ const tableSchema = {
|
||||||
...baseColumnDef,
|
...baseColumnDef,
|
||||||
type: {
|
type: {
|
||||||
type: "string",
|
type: "string",
|
||||||
enum: [FieldTypes.LINK],
|
enum: [FieldType.LINK],
|
||||||
description: "A relationship column.",
|
description: "A relationship column.",
|
||||||
},
|
},
|
||||||
fieldName: {
|
fieldName: {
|
||||||
|
@ -128,7 +128,7 @@ const tableSchema = {
|
||||||
...baseColumnDef,
|
...baseColumnDef,
|
||||||
type: {
|
type: {
|
||||||
type: "string",
|
type: "string",
|
||||||
enum: [FieldTypes.FORMULA],
|
enum: [FieldType.FORMULA],
|
||||||
description: "A formula column.",
|
description: "A formula column.",
|
||||||
},
|
},
|
||||||
formula: {
|
formula: {
|
||||||
|
@ -138,7 +138,7 @@ const tableSchema = {
|
||||||
},
|
},
|
||||||
formulaType: {
|
formulaType: {
|
||||||
type: "string",
|
type: "string",
|
||||||
enum: Object.values(FormulaTypes),
|
enum: Object.values(FormulaType),
|
||||||
description:
|
description:
|
||||||
"Defines whether this is a static or dynamic formula.",
|
"Defines whether this is a static or dynamic formula.",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
AutoFieldSubType,
|
||||||
AutoReason,
|
AutoReason,
|
||||||
Datasource,
|
Datasource,
|
||||||
FieldSchema,
|
FieldSchema,
|
||||||
|
@ -27,7 +28,6 @@ import {
|
||||||
isSQL,
|
isSQL,
|
||||||
} from "../../../integrations/utils"
|
} from "../../../integrations/utils"
|
||||||
import { getDatasourceAndQuery } from "../../../sdk/app/rows/utils"
|
import { getDatasourceAndQuery } from "../../../sdk/app/rows/utils"
|
||||||
import { AutoFieldSubTypes, FieldTypes } from "../../../constants"
|
|
||||||
import { processObjectSync } from "@budibase/string-templates"
|
import { processObjectSync } from "@budibase/string-templates"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import { processDates, processFormulas } from "../../../utilities/rowProcessor"
|
import { processDates, processFormulas } from "../../../utilities/rowProcessor"
|
||||||
|
@ -111,10 +111,10 @@ function buildFilters(
|
||||||
*/
|
*/
|
||||||
function cleanupConfig(config: RunConfig, table: Table): RunConfig {
|
function cleanupConfig(config: RunConfig, table: Table): RunConfig {
|
||||||
const primaryOptions = [
|
const primaryOptions = [
|
||||||
FieldTypes.STRING,
|
FieldType.STRING,
|
||||||
FieldTypes.LONGFORM,
|
FieldType.LONGFORM,
|
||||||
FieldTypes.OPTIONS,
|
FieldType.OPTIONS,
|
||||||
FieldTypes.NUMBER,
|
FieldType.NUMBER,
|
||||||
]
|
]
|
||||||
// filter out fields which cannot be keys
|
// filter out fields which cannot be keys
|
||||||
const fieldNames = Object.entries(table.schema)
|
const fieldNames = Object.entries(table.schema)
|
||||||
|
@ -241,10 +241,7 @@ function basicProcessing({
|
||||||
|
|
||||||
function fixArrayTypes(row: Row, table: Table) {
|
function fixArrayTypes(row: Row, table: Table) {
|
||||||
for (let [fieldName, schema] of Object.entries(table.schema)) {
|
for (let [fieldName, schema] of Object.entries(table.schema)) {
|
||||||
if (
|
if (schema.type === FieldType.ARRAY && typeof row[fieldName] === "string") {
|
||||||
schema.type === FieldTypes.ARRAY &&
|
|
||||||
typeof row[fieldName] === "string"
|
|
||||||
) {
|
|
||||||
try {
|
try {
|
||||||
row[fieldName] = JSON.parse(row[fieldName])
|
row[fieldName] = JSON.parse(row[fieldName])
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -274,8 +271,8 @@ function isEditableColumn(column: FieldSchema) {
|
||||||
const isExternalAutoColumn =
|
const isExternalAutoColumn =
|
||||||
column.autocolumn &&
|
column.autocolumn &&
|
||||||
column.autoReason !== AutoReason.FOREIGN_KEY &&
|
column.autoReason !== AutoReason.FOREIGN_KEY &&
|
||||||
column.subtype !== AutoFieldSubTypes.AUTO_ID
|
column.subtype !== AutoFieldSubType.AUTO_ID
|
||||||
const isFormula = column.type === FieldTypes.FORMULA
|
const isFormula = column.type === FieldType.FORMULA
|
||||||
return !(isExternalAutoColumn || isFormula)
|
return !(isExternalAutoColumn || isFormula)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,11 +319,11 @@ export class ExternalRequest<T extends Operation> {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// parse floats/numbers
|
// parse floats/numbers
|
||||||
if (field.type === FieldTypes.NUMBER && !isNaN(parseFloat(row[key]))) {
|
if (field.type === FieldType.NUMBER && !isNaN(parseFloat(row[key]))) {
|
||||||
newRow[key] = parseFloat(row[key])
|
newRow[key] = parseFloat(row[key])
|
||||||
}
|
}
|
||||||
// if its not a link then just copy it over
|
// if its not a link then just copy it over
|
||||||
if (field.type !== FieldTypes.LINK) {
|
if (field.type !== FieldType.LINK) {
|
||||||
newRow[key] = row[key]
|
newRow[key] = row[key]
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -532,7 +529,7 @@ export class ExternalRequest<T extends Operation> {
|
||||||
buildRelationships(table: Table): RelationshipsJson[] {
|
buildRelationships(table: Table): RelationshipsJson[] {
|
||||||
const relationships = []
|
const relationships = []
|
||||||
for (let [fieldName, field] of Object.entries(table.schema)) {
|
for (let [fieldName, field] of Object.entries(table.schema)) {
|
||||||
if (field.type !== FieldTypes.LINK) {
|
if (field.type !== FieldType.LINK) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const { tableName: linkTableName } = breakExternalTableId(field.tableId)
|
const { tableName: linkTableName } = breakExternalTableId(field.tableId)
|
||||||
|
@ -586,7 +583,7 @@ export class ExternalRequest<T extends Operation> {
|
||||||
// we need this to work out if any relationships need removed
|
// we need this to work out if any relationships need removed
|
||||||
for (const field of Object.values(table.schema)) {
|
for (const field of Object.values(table.schema)) {
|
||||||
if (
|
if (
|
||||||
field.type !== FieldTypes.LINK ||
|
field.type !== FieldType.LINK ||
|
||||||
!field.fieldName ||
|
!field.fieldName ||
|
||||||
isOneSide(field)
|
isOneSide(field)
|
||||||
) {
|
) {
|
||||||
|
@ -730,15 +727,15 @@ export class ExternalRequest<T extends Operation> {
|
||||||
return Object.entries(table.schema)
|
return Object.entries(table.schema)
|
||||||
.filter(
|
.filter(
|
||||||
column =>
|
column =>
|
||||||
column[1].type !== FieldTypes.LINK &&
|
column[1].type !== FieldType.LINK &&
|
||||||
column[1].type !== FieldTypes.FORMULA &&
|
column[1].type !== FieldType.FORMULA &&
|
||||||
!existing.find((field: string) => field === column[0])
|
!existing.find((field: string) => field === column[0])
|
||||||
)
|
)
|
||||||
.map(column => `${table.name}.${column[0]}`)
|
.map(column => `${table.name}.${column[0]}`)
|
||||||
}
|
}
|
||||||
let fields = extractRealFields(table)
|
let fields = extractRealFields(table)
|
||||||
for (let field of Object.values(table.schema)) {
|
for (let field of Object.values(table.schema)) {
|
||||||
if (field.type !== FieldTypes.LINK || !includeRelations) {
|
if (field.type !== FieldType.LINK || !includeRelations) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const { tableName: linkTableName } = breakExternalTableId(field.tableId)
|
const { tableName: linkTableName } = breakExternalTableId(field.tableId)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { FieldTypes } from "../../../constants"
|
|
||||||
import {
|
import {
|
||||||
breakExternalTableId,
|
breakExternalTableId,
|
||||||
breakRowIdField,
|
breakRowIdField,
|
||||||
|
@ -9,6 +8,7 @@ import {
|
||||||
RunConfig,
|
RunConfig,
|
||||||
} from "./ExternalRequest"
|
} from "./ExternalRequest"
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
Datasource,
|
Datasource,
|
||||||
IncludeRelationship,
|
IncludeRelationship,
|
||||||
Operation,
|
Operation,
|
||||||
|
@ -154,7 +154,7 @@ export async function fetchEnrichedRow(ctx: UserCtx) {
|
||||||
// for a single row, there is probably a better way to do this with some smart multi-layer joins
|
// for a single row, there is probably a better way to do this with some smart multi-layer joins
|
||||||
for (let [fieldName, field] of Object.entries(table.schema)) {
|
for (let [fieldName, field] of Object.entries(table.schema)) {
|
||||||
if (
|
if (
|
||||||
field.type !== FieldTypes.LINK ||
|
field.type !== FieldType.LINK ||
|
||||||
!row[fieldName] ||
|
!row[fieldName] ||
|
||||||
row[fieldName].length === 0
|
row[fieldName].length === 0
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -6,12 +6,12 @@ import {
|
||||||
inputProcessing,
|
inputProcessing,
|
||||||
outputProcessing,
|
outputProcessing,
|
||||||
} from "../../../utilities/rowProcessor"
|
} from "../../../utilities/rowProcessor"
|
||||||
import { FieldTypes } from "../../../constants"
|
|
||||||
import * as utils from "./utils"
|
import * as utils from "./utils"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import { context } from "@budibase/backend-core"
|
import { context } from "@budibase/backend-core"
|
||||||
import { finaliseRow, updateRelatedFormula } from "./staticFormula"
|
import { finaliseRow, updateRelatedFormula } from "./staticFormula"
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
LinkDocumentValue,
|
LinkDocumentValue,
|
||||||
PatchRowRequest,
|
PatchRowRequest,
|
||||||
PatchRowResponse,
|
PatchRowResponse,
|
||||||
|
@ -225,7 +225,7 @@ export async function fetchEnrichedRow(ctx: UserCtx) {
|
||||||
// insert the link rows in the correct place throughout the main row
|
// insert the link rows in the correct place throughout the main row
|
||||||
for (let fieldName of Object.keys(table.schema)) {
|
for (let fieldName of Object.keys(table.schema)) {
|
||||||
let field = table.schema[fieldName]
|
let field = table.schema[fieldName]
|
||||||
if (field.type === FieldTypes.LINK) {
|
if (field.type === FieldType.LINK) {
|
||||||
// find the links that pertain to this field
|
// find the links that pertain to this field
|
||||||
const links = linkVals.filter(link => link.fieldName === fieldName)
|
const links = linkVals.filter(link => link.fieldName === fieldName)
|
||||||
// find the rows that the links state are linked to this field
|
// find the rows that the links state are linked to this field
|
||||||
|
|
|
@ -4,9 +4,15 @@ import {
|
||||||
processAutoColumn,
|
processAutoColumn,
|
||||||
processFormulas,
|
processFormulas,
|
||||||
} from "../../../utilities/rowProcessor"
|
} from "../../../utilities/rowProcessor"
|
||||||
import { FieldTypes, FormulaTypes } from "../../../constants"
|
|
||||||
import { context, locks } from "@budibase/backend-core"
|
import { context, locks } from "@budibase/backend-core"
|
||||||
import { Table, Row, LockType, LockName } from "@budibase/types"
|
import {
|
||||||
|
Table,
|
||||||
|
Row,
|
||||||
|
LockType,
|
||||||
|
LockName,
|
||||||
|
FormulaType,
|
||||||
|
FieldType,
|
||||||
|
} from "@budibase/types"
|
||||||
import * as linkRows from "../../../db/linkedRows"
|
import * as linkRows from "../../../db/linkedRows"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import isEqual from "lodash/isEqual"
|
import isEqual from "lodash/isEqual"
|
||||||
|
@ -35,7 +41,7 @@ export async function updateRelatedFormula(
|
||||||
let relatedRows: Record<string, Row[]> = {}
|
let relatedRows: Record<string, Row[]> = {}
|
||||||
for (let [key, field] of Object.entries(enrichedRow)) {
|
for (let [key, field] of Object.entries(enrichedRow)) {
|
||||||
const columnDefinition = table.schema[key]
|
const columnDefinition = table.schema[key]
|
||||||
if (columnDefinition && columnDefinition.type === FieldTypes.LINK) {
|
if (columnDefinition && columnDefinition.type === FieldType.LINK) {
|
||||||
const relatedTableId = columnDefinition.tableId!
|
const relatedTableId = columnDefinition.tableId!
|
||||||
if (!relatedRows[relatedTableId]) {
|
if (!relatedRows[relatedTableId]) {
|
||||||
relatedRows[relatedTableId] = []
|
relatedRows[relatedTableId] = []
|
||||||
|
@ -63,8 +69,8 @@ export async function updateRelatedFormula(
|
||||||
for (let column of Object.values(relatedTable!.schema)) {
|
for (let column of Object.values(relatedTable!.schema)) {
|
||||||
// needs updated in related rows
|
// needs updated in related rows
|
||||||
if (
|
if (
|
||||||
column.type === FieldTypes.FORMULA &&
|
column.type === FieldType.FORMULA &&
|
||||||
column.formulaType === FormulaTypes.STATIC
|
column.formulaType === FormulaType.STATIC
|
||||||
) {
|
) {
|
||||||
// re-enrich rows for all the related, don't update the related formula for them
|
// re-enrich rows for all the related, don't update the related formula for them
|
||||||
promises = promises.concat(
|
promises = promises.concat(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { FormulaTypes } from "../../../constants"
|
import { FormulaType } from "../../../constants"
|
||||||
import { clearColumns } from "./utils"
|
import { clearColumns } from "./utils"
|
||||||
import { doesContainStrings } from "@budibase/string-templates"
|
import { doesContainStrings } from "@budibase/string-templates"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
@ -17,10 +17,10 @@ import { isRelationshipColumn } from "../../../db/utils"
|
||||||
|
|
||||||
function isStaticFormula(
|
function isStaticFormula(
|
||||||
column: FieldSchema
|
column: FieldSchema
|
||||||
): column is FormulaFieldMetadata & { formulaType: FormulaTypes.STATIC } {
|
): column is FormulaFieldMetadata & { formulaType: FormulaType.STATIC } {
|
||||||
return (
|
return (
|
||||||
column.type === FieldType.FORMULA &&
|
column.type === FieldType.FORMULA &&
|
||||||
column.formulaType === FormulaTypes.STATIC
|
column.formulaType === FormulaType.STATIC
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { FieldType } from "@budibase/types"
|
import { FieldType } from "@budibase/types"
|
||||||
import { AutoFieldSubTypes } from "../../../../constants"
|
import { AutoFieldSubType } from "../../../../constants"
|
||||||
import TestConfiguration from "../../../../tests/utilities/TestConfiguration"
|
import TestConfiguration from "../../../../tests/utilities/TestConfiguration"
|
||||||
import { importToRows } from "../utils"
|
import { importToRows } from "../utils"
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ describe("utils", () => {
|
||||||
autoId: {
|
autoId: {
|
||||||
name: "autoId",
|
name: "autoId",
|
||||||
type: FieldType.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldType.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
|
@ -69,7 +69,7 @@ describe("utils", () => {
|
||||||
autoId: {
|
autoId: {
|
||||||
name: "autoId",
|
name: "autoId",
|
||||||
type: FieldType.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldType.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
|
|
|
@ -2,8 +2,6 @@ import { parse, isSchema, isRows } from "../../../utilities/schema"
|
||||||
import { getRowParams, generateRowID, InternalTables } from "../../../db/utils"
|
import { getRowParams, generateRowID, InternalTables } from "../../../db/utils"
|
||||||
import isEqual from "lodash/isEqual"
|
import isEqual from "lodash/isEqual"
|
||||||
import {
|
import {
|
||||||
AutoFieldSubTypes,
|
|
||||||
FieldTypes,
|
|
||||||
GOOGLE_SHEETS_PRIMARY_KEY,
|
GOOGLE_SHEETS_PRIMARY_KEY,
|
||||||
USERS_TABLE_SCHEMA,
|
USERS_TABLE_SCHEMA,
|
||||||
SwitchableTypes,
|
SwitchableTypes,
|
||||||
|
@ -19,6 +17,7 @@ import { cloneDeep } from "lodash/fp"
|
||||||
import { quotas } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
import { events, context } from "@budibase/backend-core"
|
import { events, context } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
|
AutoFieldSubType,
|
||||||
ContextUser,
|
ContextUser,
|
||||||
Datasource,
|
Datasource,
|
||||||
Row,
|
Row,
|
||||||
|
@ -106,7 +105,7 @@ export function makeSureTableUpToDate(table: Table, tableToSave: Table) {
|
||||||
for ([field, column] of Object.entries(table.schema)) {
|
for ([field, column] of Object.entries(table.schema)) {
|
||||||
if (
|
if (
|
||||||
column.autocolumn &&
|
column.autocolumn &&
|
||||||
column.subtype === AutoFieldSubTypes.AUTO_ID &&
|
column.subtype === AutoFieldSubType.AUTO_ID &&
|
||||||
tableToSave.schema[field]
|
tableToSave.schema[field]
|
||||||
) {
|
) {
|
||||||
const tableCol = tableToSave.schema[field] as NumberFieldMetadata
|
const tableCol = tableToSave.schema[field] as NumberFieldMetadata
|
||||||
|
@ -144,8 +143,8 @@ export async function importToRows(
|
||||||
? row[fieldName]
|
? row[fieldName]
|
||||||
: [row[fieldName]]
|
: [row[fieldName]]
|
||||||
if (
|
if (
|
||||||
(schema.type === FieldTypes.OPTIONS ||
|
(schema.type === FieldType.OPTIONS ||
|
||||||
schema.type === FieldTypes.ARRAY) &&
|
schema.type === FieldType.ARRAY) &&
|
||||||
row[fieldName]
|
row[fieldName]
|
||||||
) {
|
) {
|
||||||
let merged = [...schema.constraints!.inclusion!, ...rowVal]
|
let merged = [...schema.constraints!.inclusion!, ...rowVal]
|
||||||
|
@ -403,7 +402,7 @@ export async function checkForViewUpdates(
|
||||||
)
|
)
|
||||||
const newViewTemplate = viewTemplate(
|
const newViewTemplate = viewTemplate(
|
||||||
viewMetadata,
|
viewMetadata,
|
||||||
groupByField?.type === FieldTypes.ARRAY
|
groupByField?.type === FieldType.ARRAY
|
||||||
)
|
)
|
||||||
const viewName = view.name!
|
const viewName = view.name!
|
||||||
await saveView(null, viewName, newViewTemplate)
|
await saveView(null, viewName, newViewTemplate)
|
||||||
|
@ -434,7 +433,7 @@ export function generateJunctionTableName(
|
||||||
|
|
||||||
export function foreignKeyStructure(keyName: string, meta?: any) {
|
export function foreignKeyStructure(keyName: string, meta?: any) {
|
||||||
const structure: any = {
|
const structure: any = {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
constraints: {},
|
constraints: {},
|
||||||
name: keyName,
|
name: keyName,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ import { fetchView } from "../row"
|
||||||
import { context, events } from "@budibase/backend-core"
|
import { context, events } from "@budibase/backend-core"
|
||||||
import { DocumentType } from "../../../db/utils"
|
import { DocumentType } from "../../../db/utils"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import { FieldTypes } from "../../../constants"
|
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
Ctx,
|
Ctx,
|
||||||
Row,
|
Row,
|
||||||
Table,
|
Table,
|
||||||
|
@ -37,7 +37,7 @@ export async function save(ctx: Ctx) {
|
||||||
(field: any) => field.name == viewToSave.groupBy
|
(field: any) => field.name == viewToSave.groupBy
|
||||||
)
|
)
|
||||||
|
|
||||||
const view = viewTemplate(viewToSave, groupByField?.type === FieldTypes.ARRAY)
|
const view = viewTemplate(viewToSave, groupByField?.type === FieldType.ARRAY)
|
||||||
const viewName = viewToSave.name
|
const viewName = viewToSave.name
|
||||||
|
|
||||||
if (!viewName) {
|
if (!viewName) {
|
||||||
|
|
|
@ -6,11 +6,11 @@ import * as setup from "./utilities"
|
||||||
import { context, InternalTable, roles, tenancy } from "@budibase/backend-core"
|
import { context, InternalTable, roles, tenancy } from "@budibase/backend-core"
|
||||||
import { quotas } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
import {
|
import {
|
||||||
AutoFieldSubTypes,
|
AutoFieldSubType,
|
||||||
FieldSchema,
|
FieldSchema,
|
||||||
FieldType,
|
FieldType,
|
||||||
FieldTypeSubtypes,
|
FieldTypeSubtypes,
|
||||||
FormulaTypes,
|
FormulaType,
|
||||||
INTERNAL_TABLE_SOURCE_ID,
|
INTERNAL_TABLE_SOURCE_ID,
|
||||||
MonthlyQuotaName,
|
MonthlyQuotaName,
|
||||||
PermissionLevel,
|
PermissionLevel,
|
||||||
|
@ -192,7 +192,7 @@ describe.each([
|
||||||
"Row ID": {
|
"Row ID": {
|
||||||
name: "Row ID",
|
name: "Row ID",
|
||||||
type: FieldType.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
icon: "ri-magic-line",
|
icon: "ri-magic-line",
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
|
@ -2032,7 +2032,7 @@ describe.each([
|
||||||
name: "formula",
|
name: "formula",
|
||||||
type: FieldType.FORMULA,
|
type: FieldType.FORMULA,
|
||||||
formula: "{{ links.0.name }}",
|
formula: "{{ links.0.name }}",
|
||||||
formulaType: FormulaTypes.DYNAMIC,
|
formulaType: FormulaType.DYNAMIC,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -2086,7 +2086,7 @@ describe.each([
|
||||||
name: "formula",
|
name: "formula",
|
||||||
type: FieldType.FORMULA,
|
type: FieldType.FORMULA,
|
||||||
formula: `{{ js "${js}"}}`,
|
formula: `{{ js "${js}"}}`,
|
||||||
formulaType: FormulaTypes.DYNAMIC,
|
formulaType: FormulaType.DYNAMIC,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -2129,7 +2129,7 @@ describe.each([
|
||||||
name: "formula",
|
name: "formula",
|
||||||
type: FieldType.FORMULA,
|
type: FieldType.FORMULA,
|
||||||
formula: `{{ js "${js}"}}`,
|
formula: `{{ js "${js}"}}`,
|
||||||
formulaType: FormulaTypes.DYNAMIC,
|
formulaType: FormulaType.DYNAMIC,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { context, events } from "@budibase/backend-core"
|
import { context, events } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
AutoFieldSubTypes,
|
AutoFieldSubType,
|
||||||
FieldSubtype,
|
FieldSubtype,
|
||||||
FieldType,
|
FieldType,
|
||||||
INTERNAL_TABLE_SOURCE_ID,
|
INTERNAL_TABLE_SOURCE_ID,
|
||||||
|
@ -205,7 +205,7 @@ describe("/tables", () => {
|
||||||
autoId: {
|
autoId: {
|
||||||
name: "id",
|
name: "id",
|
||||||
type: FieldType.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: "number",
|
type: "number",
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as rowController from "../../api/controllers/row"
|
import * as rowController from "../../api/controllers/row"
|
||||||
import * as tableController from "../../api/controllers/table"
|
import * as tableController from "../../api/controllers/table"
|
||||||
import { FieldTypes } from "../../constants"
|
|
||||||
import { buildCtx } from "./utils"
|
import { buildCtx } from "./utils"
|
||||||
import * as automationUtils from "../automationUtils"
|
import * as automationUtils from "../automationUtils"
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
AutomationActionStepId,
|
AutomationActionStepId,
|
||||||
AutomationCustomIOType,
|
AutomationCustomIOType,
|
||||||
AutomationFeature,
|
AutomationFeature,
|
||||||
|
@ -115,7 +115,7 @@ function typeCoercion(filters: SearchFilters, table: Table) {
|
||||||
if (!column || typeof value !== "string") {
|
if (!column || typeof value !== "string") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (column.type === FieldTypes.NUMBER) {
|
if (column.type === FieldType.NUMBER) {
|
||||||
if (key === "oneOf") {
|
if (key === "oneOf") {
|
||||||
searchParam[property] = value
|
searchParam[property] = value
|
||||||
.split(",")
|
.split(",")
|
||||||
|
@ -148,11 +148,11 @@ export async function run({ inputs, appId }: AutomationStepInput) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const table = await getTable(appId, tableId)
|
const table = await getTable(appId, tableId)
|
||||||
let sortType = FieldTypes.STRING
|
let sortType = FieldType.STRING
|
||||||
if (table && table.schema && table.schema[sortColumn] && sortColumn) {
|
if (table && table.schema && table.schema[sortColumn] && sortColumn) {
|
||||||
const fieldType = table.schema[sortColumn].type
|
const fieldType = table.schema[sortColumn].type
|
||||||
sortType =
|
sortType =
|
||||||
fieldType === FieldTypes.NUMBER ? FieldTypes.NUMBER : FieldTypes.STRING
|
fieldType === FieldType.NUMBER ? FieldType.NUMBER : FieldType.STRING
|
||||||
}
|
}
|
||||||
const ctx: any = buildCtx(appId, null, {
|
const ctx: any = buildCtx(appId, null, {
|
||||||
params: {
|
params: {
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import { constants, objectStore, roles } from "@budibase/backend-core"
|
import { constants, objectStore, roles } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
FieldType as FieldTypes,
|
FieldType,
|
||||||
INTERNAL_TABLE_SOURCE_ID,
|
INTERNAL_TABLE_SOURCE_ID,
|
||||||
Table,
|
Table,
|
||||||
TableSourceType,
|
TableSourceType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export {
|
export {
|
||||||
FieldType as FieldTypes,
|
|
||||||
RelationshipType,
|
RelationshipType,
|
||||||
AutoFieldSubTypes,
|
AutoFieldSubType,
|
||||||
FormulaTypes,
|
FormulaType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export enum FilterTypes {
|
export enum FilterTypes {
|
||||||
|
@ -36,14 +35,14 @@ export const NoEmptyFilterStrings = [
|
||||||
]
|
]
|
||||||
|
|
||||||
export const CanSwitchTypes = [
|
export const CanSwitchTypes = [
|
||||||
[FieldTypes.JSON, FieldTypes.ARRAY],
|
[FieldType.JSON, FieldType.ARRAY],
|
||||||
[
|
[
|
||||||
FieldTypes.STRING,
|
FieldType.STRING,
|
||||||
FieldTypes.OPTIONS,
|
FieldType.OPTIONS,
|
||||||
FieldTypes.LONGFORM,
|
FieldType.LONGFORM,
|
||||||
FieldTypes.BARCODEQR,
|
FieldType.BARCODEQR,
|
||||||
],
|
],
|
||||||
[FieldTypes.BOOLEAN, FieldTypes.NUMBER],
|
[FieldType.BOOLEAN, FieldType.NUMBER],
|
||||||
]
|
]
|
||||||
|
|
||||||
export const SwitchableTypes = CanSwitchTypes.reduce((prev, current) =>
|
export const SwitchableTypes = CanSwitchTypes.reduce((prev, current) =>
|
||||||
|
@ -86,9 +85,9 @@ export const USERS_TABLE_SCHEMA: Table = {
|
||||||
// TODO: ADMIN PANEL - when implemented this doesn't need to be carried out
|
// TODO: ADMIN PANEL - when implemented this doesn't need to be carried out
|
||||||
schema: {
|
schema: {
|
||||||
email: {
|
email: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
email: true,
|
email: true,
|
||||||
length: {
|
length: {
|
||||||
maximum: "",
|
maximum: "",
|
||||||
|
@ -99,34 +98,34 @@ export const USERS_TABLE_SCHEMA: Table = {
|
||||||
},
|
},
|
||||||
firstName: {
|
firstName: {
|
||||||
name: "firstName",
|
name: "firstName",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
lastName: {
|
lastName: {
|
||||||
name: "lastName",
|
name: "lastName",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
roleId: {
|
roleId: {
|
||||||
name: "roleId",
|
name: "roleId",
|
||||||
type: FieldTypes.OPTIONS,
|
type: FieldType.OPTIONS,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
presence: false,
|
presence: false,
|
||||||
inclusion: Object.values(roles.BUILTIN_ROLE_IDS),
|
inclusion: Object.values(roles.BUILTIN_ROLE_IDS),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
name: "status",
|
name: "status",
|
||||||
type: FieldTypes.OPTIONS,
|
type: FieldType.OPTIONS,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
presence: false,
|
presence: false,
|
||||||
inclusion: Object.values(constants.UserStatus),
|
inclusion: Object.values(constants.UserStatus),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import {
|
import {
|
||||||
AutoFieldSubTypes,
|
|
||||||
FieldTypes,
|
|
||||||
DEFAULT_BB_DATASOURCE_ID,
|
DEFAULT_BB_DATASOURCE_ID,
|
||||||
DEFAULT_INVENTORY_TABLE_ID,
|
DEFAULT_INVENTORY_TABLE_ID,
|
||||||
DEFAULT_EMPLOYEE_TABLE_ID,
|
DEFAULT_EMPLOYEE_TABLE_ID,
|
||||||
|
@ -16,6 +14,7 @@ import { jobsImport } from "./jobsImport"
|
||||||
import { expensesImport } from "./expensesImport"
|
import { expensesImport } from "./expensesImport"
|
||||||
import { db as dbCore } from "@budibase/backend-core"
|
import { db as dbCore } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
|
AutoFieldSubType,
|
||||||
FieldType,
|
FieldType,
|
||||||
RelationshipType,
|
RelationshipType,
|
||||||
Row,
|
Row,
|
||||||
|
@ -40,7 +39,7 @@ function syncLastIds(table: Table, rowCount: number) {
|
||||||
if (
|
if (
|
||||||
entry.autocolumn &&
|
entry.autocolumn &&
|
||||||
entry.type === FieldType.NUMBER &&
|
entry.type === FieldType.NUMBER &&
|
||||||
entry.subtype == AutoFieldSubTypes.AUTO_ID
|
entry.subtype == AutoFieldSubType.AUTO_ID
|
||||||
) {
|
) {
|
||||||
entry.lastID = rowCount
|
entry.lastID = rowCount
|
||||||
}
|
}
|
||||||
|
@ -58,12 +57,12 @@ async function tableImport(table: Table, data: Row[]) {
|
||||||
const AUTO_COLUMNS: TableSchema = {
|
const AUTO_COLUMNS: TableSchema = {
|
||||||
"Created At": {
|
"Created At": {
|
||||||
name: "Created At",
|
name: "Created At",
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
subtype: AutoFieldSubTypes.CREATED_AT,
|
subtype: AutoFieldSubType.CREATED_AT,
|
||||||
icon: "ri-magic-line",
|
icon: "ri-magic-line",
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
datetime: {
|
datetime: {
|
||||||
|
@ -74,12 +73,12 @@ const AUTO_COLUMNS: TableSchema = {
|
||||||
},
|
},
|
||||||
"Updated At": {
|
"Updated At": {
|
||||||
name: "Updated At",
|
name: "Updated At",
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
subtype: AutoFieldSubTypes.UPDATED_AT,
|
subtype: AutoFieldSubType.UPDATED_AT,
|
||||||
icon: "ri-magic-line",
|
icon: "ri-magic-line",
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
datetime: {
|
datetime: {
|
||||||
|
@ -101,12 +100,12 @@ export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
|
||||||
schema: {
|
schema: {
|
||||||
"Item ID": {
|
"Item ID": {
|
||||||
name: "Item ID",
|
name: "Item ID",
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
icon: "ri-magic-line",
|
icon: "ri-magic-line",
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
presence: false,
|
presence: false,
|
||||||
numericality: {
|
numericality: {
|
||||||
greaterThanOrEqualTo: "",
|
greaterThanOrEqualTo: "",
|
||||||
|
@ -115,9 +114,9 @@ export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Item Name": {
|
"Item Name": {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {
|
length: {
|
||||||
maximum: null,
|
maximum: null,
|
||||||
},
|
},
|
||||||
|
@ -128,9 +127,9 @@ export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
|
||||||
name: "Item Name",
|
name: "Item Name",
|
||||||
},
|
},
|
||||||
"Item Tags": {
|
"Item Tags": {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
presence: {
|
presence: {
|
||||||
allowEmpty: false,
|
allowEmpty: false,
|
||||||
},
|
},
|
||||||
|
@ -140,9 +139,9 @@ export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
|
||||||
sortable: false,
|
sortable: false,
|
||||||
},
|
},
|
||||||
Notes: {
|
Notes: {
|
||||||
type: FieldTypes.LONGFORM,
|
type: FieldType.LONGFORM,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
|
@ -150,9 +149,9 @@ export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
|
||||||
useRichText: null,
|
useRichText: null,
|
||||||
},
|
},
|
||||||
Status: {
|
Status: {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
presence: {
|
presence: {
|
||||||
allowEmpty: false,
|
allowEmpty: false,
|
||||||
},
|
},
|
||||||
|
@ -162,18 +161,18 @@ export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
|
||||||
sortable: false,
|
sortable: false,
|
||||||
},
|
},
|
||||||
SKU: {
|
SKU: {
|
||||||
type: FieldTypes.BARCODEQR,
|
type: FieldType.BARCODEQR,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
name: "SKU",
|
name: "SKU",
|
||||||
},
|
},
|
||||||
"Purchase Date": {
|
"Purchase Date": {
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
datetime: {
|
datetime: {
|
||||||
|
@ -185,9 +184,9 @@ export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
|
||||||
ignoreTimezones: true,
|
ignoreTimezones: true,
|
||||||
},
|
},
|
||||||
"Purchase Price": {
|
"Purchase Price": {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
presence: false,
|
presence: false,
|
||||||
numericality: {
|
numericality: {
|
||||||
greaterThanOrEqualTo: null,
|
greaterThanOrEqualTo: null,
|
||||||
|
@ -211,75 +210,75 @@ export const DEFAULT_EMPLOYEE_TABLE_SCHEMA: Table = {
|
||||||
schema: {
|
schema: {
|
||||||
"First Name": {
|
"First Name": {
|
||||||
name: "First Name",
|
name: "First Name",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Last Name": {
|
"Last Name": {
|
||||||
name: "Last Name",
|
name: "Last Name",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Email: {
|
Email: {
|
||||||
name: "Email",
|
name: "Email",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Address: {
|
Address: {
|
||||||
name: "Address",
|
name: "Address",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
City: {
|
City: {
|
||||||
name: "City",
|
name: "City",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Postcode: {
|
Postcode: {
|
||||||
name: "Postcode",
|
name: "Postcode",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Phone: {
|
Phone: {
|
||||||
name: "Phone",
|
name: "Phone",
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"EMPLOYEE ID": {
|
"EMPLOYEE ID": {
|
||||||
name: "EMPLOYEE ID",
|
name: "EMPLOYEE ID",
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
icon: "ri-magic-line",
|
icon: "ri-magic-line",
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
presence: false,
|
presence: false,
|
||||||
numericality: {
|
numericality: {
|
||||||
greaterThanOrEqualTo: "",
|
greaterThanOrEqualTo: "",
|
||||||
|
@ -288,9 +287,9 @@ export const DEFAULT_EMPLOYEE_TABLE_SCHEMA: Table = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Employee Level": {
|
"Employee Level": {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
presence: false,
|
presence: false,
|
||||||
inclusion: ["Manager", "Junior", "Senior", "Apprentice", "Contractor"],
|
inclusion: ["Manager", "Junior", "Senior", "Apprentice", "Contractor"],
|
||||||
},
|
},
|
||||||
|
@ -298,18 +297,18 @@ export const DEFAULT_EMPLOYEE_TABLE_SCHEMA: Table = {
|
||||||
sortable: false,
|
sortable: false,
|
||||||
},
|
},
|
||||||
"Badge Photo": {
|
"Badge Photo": {
|
||||||
type: FieldTypes.ATTACHMENT,
|
type: FieldType.ATTACHMENT,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
name: "Badge Photo",
|
name: "Badge Photo",
|
||||||
sortable: false,
|
sortable: false,
|
||||||
},
|
},
|
||||||
Jobs: {
|
Jobs: {
|
||||||
type: FieldTypes.LINK,
|
type: FieldType.LINK,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
fieldName: "Assigned",
|
fieldName: "Assigned",
|
||||||
|
@ -318,9 +317,9 @@ export const DEFAULT_EMPLOYEE_TABLE_SCHEMA: Table = {
|
||||||
tableId: DEFAULT_JOBS_TABLE_ID,
|
tableId: DEFAULT_JOBS_TABLE_ID,
|
||||||
},
|
},
|
||||||
"Start Date": {
|
"Start Date": {
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
datetime: {
|
datetime: {
|
||||||
|
@ -332,9 +331,9 @@ export const DEFAULT_EMPLOYEE_TABLE_SCHEMA: Table = {
|
||||||
ignoreTimezones: true,
|
ignoreTimezones: true,
|
||||||
},
|
},
|
||||||
"End Date": {
|
"End Date": {
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
datetime: {
|
datetime: {
|
||||||
|
@ -359,12 +358,12 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
schema: {
|
schema: {
|
||||||
"Job ID": {
|
"Job ID": {
|
||||||
name: "Job ID",
|
name: "Job ID",
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
icon: "ri-magic-line",
|
icon: "ri-magic-line",
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
presence: false,
|
presence: false,
|
||||||
numericality: {
|
numericality: {
|
||||||
greaterThanOrEqualTo: "",
|
greaterThanOrEqualTo: "",
|
||||||
|
@ -373,9 +372,9 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Quote Date": {
|
"Quote Date": {
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: {
|
presence: {
|
||||||
allowEmpty: false,
|
allowEmpty: false,
|
||||||
|
@ -389,9 +388,9 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
ignoreTimezones: true,
|
ignoreTimezones: true,
|
||||||
},
|
},
|
||||||
"Quote Price": {
|
"Quote Price": {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
presence: {
|
presence: {
|
||||||
allowEmpty: false,
|
allowEmpty: false,
|
||||||
},
|
},
|
||||||
|
@ -403,9 +402,9 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
name: "Quote Price",
|
name: "Quote Price",
|
||||||
},
|
},
|
||||||
"Works Start": {
|
"Works Start": {
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
datetime: {
|
datetime: {
|
||||||
|
@ -417,9 +416,9 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
ignoreTimezones: true,
|
ignoreTimezones: true,
|
||||||
},
|
},
|
||||||
Address: {
|
Address: {
|
||||||
type: FieldTypes.LONGFORM,
|
type: FieldType.LONGFORM,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
|
@ -427,9 +426,9 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
useRichText: null,
|
useRichText: null,
|
||||||
},
|
},
|
||||||
"Customer Name": {
|
"Customer Name": {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {
|
length: {
|
||||||
maximum: null,
|
maximum: null,
|
||||||
},
|
},
|
||||||
|
@ -438,9 +437,9 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
name: "Customer Name",
|
name: "Customer Name",
|
||||||
},
|
},
|
||||||
Notes: {
|
Notes: {
|
||||||
type: FieldTypes.LONGFORM,
|
type: FieldType.LONGFORM,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
|
@ -448,9 +447,9 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
useRichText: null,
|
useRichText: null,
|
||||||
},
|
},
|
||||||
"Customer Phone": {
|
"Customer Phone": {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {
|
length: {
|
||||||
maximum: null,
|
maximum: null,
|
||||||
},
|
},
|
||||||
|
@ -459,9 +458,9 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
name: "Customer Phone",
|
name: "Customer Phone",
|
||||||
},
|
},
|
||||||
"Customer Email": {
|
"Customer Email": {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {
|
length: {
|
||||||
maximum: null,
|
maximum: null,
|
||||||
},
|
},
|
||||||
|
@ -471,14 +470,14 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
},
|
},
|
||||||
Assigned: {
|
Assigned: {
|
||||||
name: "Assigned",
|
name: "Assigned",
|
||||||
type: FieldTypes.LINK,
|
type: FieldType.LINK,
|
||||||
tableId: DEFAULT_EMPLOYEE_TABLE_ID,
|
tableId: DEFAULT_EMPLOYEE_TABLE_ID,
|
||||||
fieldName: "Jobs",
|
fieldName: "Jobs",
|
||||||
relationshipType: RelationshipType.MANY_TO_MANY,
|
relationshipType: RelationshipType.MANY_TO_MANY,
|
||||||
// sortable: true,
|
// sortable: true,
|
||||||
},
|
},
|
||||||
"Works End": {
|
"Works End": {
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: "string",
|
type: "string",
|
||||||
length: {},
|
length: {},
|
||||||
|
@ -492,7 +491,7 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
|
||||||
ignoreTimezones: true,
|
ignoreTimezones: true,
|
||||||
},
|
},
|
||||||
"Updated Price": {
|
"Updated Price": {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: "number",
|
type: "number",
|
||||||
presence: false,
|
presence: false,
|
||||||
|
@ -518,12 +517,12 @@ export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = {
|
||||||
schema: {
|
schema: {
|
||||||
"Expense ID": {
|
"Expense ID": {
|
||||||
name: "Expense ID",
|
name: "Expense ID",
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
icon: "ri-magic-line",
|
icon: "ri-magic-line",
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
presence: false,
|
presence: false,
|
||||||
numericality: {
|
numericality: {
|
||||||
greaterThanOrEqualTo: "",
|
greaterThanOrEqualTo: "",
|
||||||
|
@ -532,9 +531,9 @@ export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Expense Tags": {
|
"Expense Tags": {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
presence: {
|
presence: {
|
||||||
allowEmpty: false,
|
allowEmpty: false,
|
||||||
},
|
},
|
||||||
|
@ -554,9 +553,9 @@ export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = {
|
||||||
sortable: false,
|
sortable: false,
|
||||||
},
|
},
|
||||||
Cost: {
|
Cost: {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.NUMBER,
|
type: FieldType.NUMBER,
|
||||||
presence: {
|
presence: {
|
||||||
allowEmpty: false,
|
allowEmpty: false,
|
||||||
},
|
},
|
||||||
|
@ -568,9 +567,9 @@ export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = {
|
||||||
name: "Cost",
|
name: "Cost",
|
||||||
},
|
},
|
||||||
Notes: {
|
Notes: {
|
||||||
type: FieldTypes.LONGFORM,
|
type: FieldType.LONGFORM,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
|
@ -578,9 +577,9 @@ export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = {
|
||||||
useRichText: null,
|
useRichText: null,
|
||||||
},
|
},
|
||||||
"Payment Due": {
|
"Payment Due": {
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
datetime: {
|
datetime: {
|
||||||
|
@ -592,9 +591,9 @@ export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = {
|
||||||
ignoreTimezones: true,
|
ignoreTimezones: true,
|
||||||
},
|
},
|
||||||
"Date Paid": {
|
"Date Paid": {
|
||||||
type: FieldTypes.DATETIME,
|
type: FieldType.DATETIME,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.STRING,
|
type: FieldType.STRING,
|
||||||
length: {},
|
length: {},
|
||||||
presence: false,
|
presence: false,
|
||||||
datetime: {
|
datetime: {
|
||||||
|
@ -606,9 +605,9 @@ export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = {
|
||||||
ignoreTimezones: true,
|
ignoreTimezones: true,
|
||||||
},
|
},
|
||||||
Attachment: {
|
Attachment: {
|
||||||
type: FieldTypes.ATTACHMENT,
|
type: FieldType.ATTACHMENT,
|
||||||
constraints: {
|
constraints: {
|
||||||
type: FieldTypes.ARRAY,
|
type: FieldType.ARRAY,
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
name: "Attachment",
|
name: "Attachment",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { IncludeDocs, getLinkDocuments } from "./linkUtils"
|
import { IncludeDocs, getLinkDocuments } from "./linkUtils"
|
||||||
import { InternalTables, getUserMetadataParams } from "../utils"
|
import { InternalTables, getUserMetadataParams } from "../utils"
|
||||||
import { FieldTypes } from "../../constants"
|
|
||||||
import { context, logging } from "@budibase/backend-core"
|
import { context, logging } from "@budibase/backend-core"
|
||||||
import LinkDocument from "./LinkDocument"
|
import LinkDocument from "./LinkDocument"
|
||||||
import {
|
import {
|
||||||
|
@ -62,7 +61,7 @@ class LinkController {
|
||||||
}
|
}
|
||||||
for (let fieldName of Object.keys(table.schema)) {
|
for (let fieldName of Object.keys(table.schema)) {
|
||||||
const { type } = table.schema[fieldName]
|
const { type } = table.schema[fieldName]
|
||||||
if (type === FieldTypes.LINK) {
|
if (type === FieldType.LINK) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +95,7 @@ class LinkController {
|
||||||
validateTable(table: Table) {
|
validateTable(table: Table) {
|
||||||
const usedAlready = []
|
const usedAlready = []
|
||||||
for (let schema of Object.values(table.schema)) {
|
for (let schema of Object.values(table.schema)) {
|
||||||
if (schema.type !== FieldTypes.LINK) {
|
if (schema.type !== FieldType.LINK) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const unique = schema.tableId! + schema?.fieldName
|
const unique = schema.tableId! + schema?.fieldName
|
||||||
|
@ -172,7 +171,7 @@ class LinkController {
|
||||||
// get the links this row wants to make
|
// get the links this row wants to make
|
||||||
const rowField = row[fieldName]
|
const rowField = row[fieldName]
|
||||||
const field = table.schema[fieldName]
|
const field = table.schema[fieldName]
|
||||||
if (field.type === FieldTypes.LINK && rowField != null) {
|
if (field.type === FieldType.LINK && rowField != null) {
|
||||||
// check which links actual pertain to the update in this row
|
// check which links actual pertain to the update in this row
|
||||||
const thisFieldLinkDocs = linkDocs.filter(
|
const thisFieldLinkDocs = linkDocs.filter(
|
||||||
linkDoc =>
|
linkDoc =>
|
||||||
|
@ -353,7 +352,7 @@ class LinkController {
|
||||||
const schema = table.schema
|
const schema = table.schema
|
||||||
for (let fieldName of Object.keys(schema)) {
|
for (let fieldName of Object.keys(schema)) {
|
||||||
const field = schema[fieldName]
|
const field = schema[fieldName]
|
||||||
if (field.type === FieldTypes.LINK && field.fieldName) {
|
if (field.type === FieldType.LINK && field.fieldName) {
|
||||||
// handle this in a separate try catch, want
|
// handle this in a separate try catch, want
|
||||||
// the put to bubble up as an error, if can't update
|
// the put to bubble up as an error, if can't update
|
||||||
// table for some reason
|
// table for some reason
|
||||||
|
@ -366,7 +365,7 @@ class LinkController {
|
||||||
}
|
}
|
||||||
const fields = this.handleRelationshipType(field, {
|
const fields = this.handleRelationshipType(field, {
|
||||||
name: field.fieldName,
|
name: field.fieldName,
|
||||||
type: FieldTypes.LINK,
|
type: FieldType.LINK,
|
||||||
// these are the props of the table that initiated the link
|
// these are the props of the table that initiated the link
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
fieldName: fieldName,
|
fieldName: fieldName,
|
||||||
|
@ -413,10 +412,7 @@ class LinkController {
|
||||||
for (let fieldName of Object.keys(oldTable?.schema || {})) {
|
for (let fieldName of Object.keys(oldTable?.schema || {})) {
|
||||||
const field = oldTable?.schema[fieldName] as FieldSchema
|
const field = oldTable?.schema[fieldName] as FieldSchema
|
||||||
// this field has been removed from the table schema
|
// this field has been removed from the table schema
|
||||||
if (
|
if (field.type === FieldType.LINK && newTable.schema[fieldName] == null) {
|
||||||
field.type === FieldTypes.LINK &&
|
|
||||||
newTable.schema[fieldName] == null
|
|
||||||
) {
|
|
||||||
await this.removeFieldFromTable(fieldName)
|
await this.removeFieldFromTable(fieldName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,7 +433,7 @@ class LinkController {
|
||||||
for (let fieldName of Object.keys(schema)) {
|
for (let fieldName of Object.keys(schema)) {
|
||||||
const field = schema[fieldName]
|
const field = schema[fieldName]
|
||||||
try {
|
try {
|
||||||
if (field.type === FieldTypes.LINK && field.fieldName) {
|
if (field.type === FieldType.LINK && field.fieldName) {
|
||||||
const linkedTable = await this._db.get<Table>(field.tableId)
|
const linkedTable = await this._db.get<Table>(field.tableId)
|
||||||
delete linkedTable.schema[field.fieldName]
|
delete linkedTable.schema[field.fieldName]
|
||||||
field.tableRev = (await this._db.put(linkedTable)).rev
|
field.tableRev = (await this._db.put(linkedTable)).rev
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { generateLinkID } from "../utils"
|
import { generateLinkID } from "../utils"
|
||||||
import { FieldTypes } from "../../constants"
|
import { FieldType, LinkDocument } from "@budibase/types"
|
||||||
import { LinkDocument } from "@budibase/types"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new link document structure which can be put to the database. It is important to
|
* Creates a new link document structure which can be put to the database. It is important to
|
||||||
|
@ -43,7 +42,7 @@ class LinkDocumentImpl implements LinkDocument {
|
||||||
fieldName1,
|
fieldName1,
|
||||||
fieldName2
|
fieldName2
|
||||||
)
|
)
|
||||||
this.type = FieldTypes.LINK
|
this.type = FieldType.LINK
|
||||||
this.doc1 = {
|
this.doc1 = {
|
||||||
tableId: tableId1,
|
tableId: tableId1,
|
||||||
fieldName: fieldName1,
|
fieldName: fieldName1,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { ViewName, getQueryIndex, isRelationshipColumn } from "../utils"
|
import { ViewName, getQueryIndex, isRelationshipColumn } from "../utils"
|
||||||
import { FieldTypes } from "../../constants"
|
|
||||||
import { createLinkView } from "../views/staticViews"
|
import { createLinkView } from "../views/staticViews"
|
||||||
import { context, logging } from "@budibase/backend-core"
|
import { context, logging } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
DatabaseQueryOpts,
|
DatabaseQueryOpts,
|
||||||
LinkDocument,
|
LinkDocument,
|
||||||
LinkDocumentValue,
|
LinkDocumentValue,
|
||||||
|
@ -131,11 +131,11 @@ export async function getLinkedTable(id: string, tables: Table[]) {
|
||||||
export function getRelatedTableForField(table: Table, fieldName: string) {
|
export function getRelatedTableForField(table: Table, fieldName: string) {
|
||||||
// look to see if its on the table, straight in the schema
|
// look to see if its on the table, straight in the schema
|
||||||
const field = table.schema[fieldName]
|
const field = table.schema[fieldName]
|
||||||
if (field?.type === FieldTypes.LINK) {
|
if (field?.type === FieldType.LINK) {
|
||||||
return field.tableId
|
return field.tableId
|
||||||
}
|
}
|
||||||
for (let column of Object.values(table.schema)) {
|
for (let column of Object.values(table.schema)) {
|
||||||
if (column.type === FieldTypes.LINK && column.fieldName === fieldName) {
|
if (column.type === FieldType.LINK && column.fieldName === fieldName) {
|
||||||
return column.tableId
|
return column.tableId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import newid from "./newid"
|
import newid from "./newid"
|
||||||
import { db as dbCore } from "@budibase/backend-core"
|
import { db as dbCore } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
DocumentType,
|
DocumentType,
|
||||||
FieldSchema,
|
FieldSchema,
|
||||||
RelationshipFieldMetadata,
|
RelationshipFieldMetadata,
|
||||||
|
@ -8,7 +9,6 @@ import {
|
||||||
INTERNAL_TABLE_SOURCE_ID,
|
INTERNAL_TABLE_SOURCE_ID,
|
||||||
DatabaseQueryOpts,
|
DatabaseQueryOpts,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { FieldTypes } from "../constants"
|
|
||||||
|
|
||||||
export { DocumentType, VirtualDocumentType } from "@budibase/types"
|
export { DocumentType, VirtualDocumentType } from "@budibase/types"
|
||||||
|
|
||||||
|
@ -315,5 +315,5 @@ export function extractViewInfoFromID(viewId: string) {
|
||||||
export function isRelationshipColumn(
|
export function isRelationshipColumn(
|
||||||
column: FieldSchema
|
column: FieldSchema
|
||||||
): column is RelationshipFieldMetadata {
|
): column is RelationshipFieldMetadata {
|
||||||
return column.type === FieldTypes.LINK
|
return column.type === FieldType.LINK
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
DatasourceFieldType,
|
DatasourceFieldType,
|
||||||
Integration,
|
Integration,
|
||||||
Operation,
|
Operation,
|
||||||
|
@ -21,7 +22,6 @@ import {
|
||||||
SqlClient,
|
SqlClient,
|
||||||
} from "./utils"
|
} from "./utils"
|
||||||
import Sql from "./base/sql"
|
import Sql from "./base/sql"
|
||||||
import { FieldTypes } from "../constants"
|
|
||||||
import {
|
import {
|
||||||
BindParameters,
|
BindParameters,
|
||||||
Connection,
|
Connection,
|
||||||
|
@ -302,7 +302,7 @@ class OracleIntegration extends Sql implements DatasourcePlus {
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this.isBooleanType(oracleColumn)) {
|
if (this.isBooleanType(oracleColumn)) {
|
||||||
fieldSchema.type = FieldTypes.BOOLEAN
|
fieldSchema.type = FieldType.BOOLEAN
|
||||||
}
|
}
|
||||||
|
|
||||||
table.schema[columnName] = fieldSchema
|
table.schema[columnName] = fieldSchema
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { CouchFindOptions, Table, Row } from "@budibase/types"
|
import { FieldType, CouchFindOptions, Table, Row } from "@budibase/types"
|
||||||
import { db as dbCore } from "@budibase/backend-core"
|
import { db as dbCore } from "@budibase/backend-core"
|
||||||
import { DocumentType, SEPARATOR } from "../../../db/utils"
|
import { DocumentType, SEPARATOR } from "../../../db/utils"
|
||||||
import { FieldTypes } from "../../../constants"
|
|
||||||
|
|
||||||
// default limit - seems to work well for performance
|
// default limit - seems to work well for performance
|
||||||
export const FIND_LIMIT = 25
|
export const FIND_LIMIT = 25
|
||||||
|
@ -31,7 +30,7 @@ export async function getRowsWithAttachments(appId: string, table: Table) {
|
||||||
const db = dbCore.getDB(appId)
|
const db = dbCore.getDB(appId)
|
||||||
const attachmentCols: string[] = []
|
const attachmentCols: string[] = []
|
||||||
for (let [key, column] of Object.entries(table.schema)) {
|
for (let [key, column] of Object.entries(table.schema)) {
|
||||||
if (column.type === FieldTypes.ATTACHMENT) {
|
if (column.type === FieldType.ATTACHMENT) {
|
||||||
attachmentCols.push(key)
|
attachmentCols.push(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
TableSourceType,
|
TableSourceType,
|
||||||
FieldType,
|
FieldType,
|
||||||
Table,
|
Table,
|
||||||
AutoFieldSubTypes,
|
AutoFieldSubType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
import TestConfiguration from "../../../../tests/utilities/TestConfiguration"
|
import TestConfiguration from "../../../../tests/utilities/TestConfiguration"
|
||||||
|
@ -117,7 +117,7 @@ describe("sdk >> rows >> internal", () => {
|
||||||
id: {
|
id: {
|
||||||
name: "id",
|
name: "id",
|
||||||
type: FieldType.AUTO,
|
type: FieldType.AUTO,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
lastID: 0,
|
lastID: 0,
|
||||||
},
|
},
|
||||||
|
@ -181,7 +181,7 @@ describe("sdk >> rows >> internal", () => {
|
||||||
id: {
|
id: {
|
||||||
name: "id",
|
name: "id",
|
||||||
type: FieldType.AUTO,
|
type: FieldType.AUTO,
|
||||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
subtype: AutoFieldSubType.AUTO_ID,
|
||||||
autocolumn: true,
|
autocolumn: true,
|
||||||
lastID: 0,
|
lastID: 0,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import cloneDeep from "lodash/cloneDeep"
|
import cloneDeep from "lodash/cloneDeep"
|
||||||
import validateJs from "validate.js"
|
import validateJs from "validate.js"
|
||||||
import { Row, Table, TableSchema } from "@budibase/types"
|
import { FieldType, Row, Table, TableSchema } from "@budibase/types"
|
||||||
import { FieldTypes } from "../../../constants"
|
|
||||||
import { makeExternalQuery } from "../../../integrations/base/query"
|
import { makeExternalQuery } from "../../../integrations/base/query"
|
||||||
import { Format } from "../../../api/controllers/view/exporters"
|
import { Format } from "../../../api/controllers/view/exporters"
|
||||||
import sdk from "../.."
|
import sdk from "../.."
|
||||||
|
@ -22,7 +21,7 @@ export function cleanExportRows(
|
||||||
let cleanRows = [...rows]
|
let cleanRows = [...rows]
|
||||||
|
|
||||||
const relationships = Object.entries(schema)
|
const relationships = Object.entries(schema)
|
||||||
.filter((entry: any[]) => entry[1].type === FieldTypes.LINK)
|
.filter((entry: any[]) => entry[1].type === FieldType.LINK)
|
||||||
.map(entry => entry[0])
|
.map(entry => entry[0])
|
||||||
|
|
||||||
relationships.forEach(column => {
|
relationships.forEach(column => {
|
||||||
|
@ -88,17 +87,17 @@ export async function validate({
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// formulas shouldn't validated, data will be deleted anyway
|
// formulas shouldn't validated, data will be deleted anyway
|
||||||
if (type === FieldTypes.FORMULA || column.autocolumn) {
|
if (type === FieldType.FORMULA || column.autocolumn) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// special case for options, need to always allow unselected (empty)
|
// special case for options, need to always allow unselected (empty)
|
||||||
if (type === FieldTypes.OPTIONS && constraints?.inclusion) {
|
if (type === FieldType.OPTIONS && constraints?.inclusion) {
|
||||||
constraints.inclusion.push(null as any, "")
|
constraints.inclusion.push(null as any, "")
|
||||||
}
|
}
|
||||||
let res
|
let res
|
||||||
|
|
||||||
// Validate.js doesn't seem to handle array
|
// Validate.js doesn't seem to handle array
|
||||||
if (type === FieldTypes.ARRAY && row[fieldName]) {
|
if (type === FieldType.ARRAY && row[fieldName]) {
|
||||||
if (row[fieldName].length) {
|
if (row[fieldName].length) {
|
||||||
if (!Array.isArray(row[fieldName])) {
|
if (!Array.isArray(row[fieldName])) {
|
||||||
row[fieldName] = row[fieldName].split(",")
|
row[fieldName] = row[fieldName].split(",")
|
||||||
|
@ -116,13 +115,13 @@ export async function validate({
|
||||||
errors[fieldName] = [`${fieldName} is required`]
|
errors[fieldName] = [`${fieldName} is required`]
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
(type === FieldTypes.ATTACHMENT || type === FieldTypes.JSON) &&
|
(type === FieldType.ATTACHMENT || type === FieldType.JSON) &&
|
||||||
typeof row[fieldName] === "string"
|
typeof row[fieldName] === "string"
|
||||||
) {
|
) {
|
||||||
// this should only happen if there is an error
|
// this should only happen if there is an error
|
||||||
try {
|
try {
|
||||||
const json = JSON.parse(row[fieldName])
|
const json = JSON.parse(row[fieldName])
|
||||||
if (type === FieldTypes.ATTACHMENT) {
|
if (type === FieldType.ATTACHMENT) {
|
||||||
if (Array.isArray(json)) {
|
if (Array.isArray(json)) {
|
||||||
row[fieldName] = json
|
row[fieldName] = json
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
Operation,
|
Operation,
|
||||||
RelationshipType,
|
RelationshipType,
|
||||||
RenameColumn,
|
RenameColumn,
|
||||||
|
@ -14,7 +15,6 @@ import {
|
||||||
setStaticSchemas,
|
setStaticSchemas,
|
||||||
} from "../../../../api/controllers/table/utils"
|
} from "../../../../api/controllers/table/utils"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import { FieldTypes } from "../../../../constants"
|
|
||||||
import { makeTableRequest } from "../../../../api/controllers/table/ExternalRequest"
|
import { makeTableRequest } from "../../../../api/controllers/table/ExternalRequest"
|
||||||
import {
|
import {
|
||||||
isRelationshipSetup,
|
isRelationshipSetup,
|
||||||
|
@ -78,7 +78,7 @@ export async function save(
|
||||||
|
|
||||||
// check if relations need setup
|
// check if relations need setup
|
||||||
for (let schema of Object.values(tableToSave.schema)) {
|
for (let schema of Object.values(tableToSave.schema)) {
|
||||||
if (schema.type !== FieldTypes.LINK || isRelationshipSetup(schema)) {
|
if (schema.type !== FieldType.LINK || isRelationshipSetup(schema)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const schemaTableId = schema.tableId
|
const schemaTableId = schema.tableId
|
||||||
|
|
|
@ -9,7 +9,6 @@ import {
|
||||||
Table,
|
Table,
|
||||||
TableSourceType,
|
TableSourceType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { FieldTypes } from "../../../../constants"
|
|
||||||
import {
|
import {
|
||||||
foreignKeyStructure,
|
foreignKeyStructure,
|
||||||
generateForeignKey,
|
generateForeignKey,
|
||||||
|
@ -27,7 +26,7 @@ export function cleanupRelationships(
|
||||||
// clean up relationships in couch table schemas
|
// clean up relationships in couch table schemas
|
||||||
for (let [key, schema] of Object.entries(tableToIterate.schema)) {
|
for (let [key, schema] of Object.entries(tableToIterate.schema)) {
|
||||||
if (
|
if (
|
||||||
schema.type === FieldTypes.LINK &&
|
schema.type === FieldType.LINK &&
|
||||||
(!oldTable || table.schema[key] == null)
|
(!oldTable || table.schema[key] == null)
|
||||||
) {
|
) {
|
||||||
const schemaTableId = schema.tableId
|
const schemaTableId = schema.tableId
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
FieldType,
|
||||||
RenameColumn,
|
RenameColumn,
|
||||||
Table,
|
Table,
|
||||||
ViewStatisticsSchema,
|
ViewStatisticsSchema,
|
||||||
|
@ -10,7 +11,6 @@ import {
|
||||||
hasTypeChanged,
|
hasTypeChanged,
|
||||||
TableSaveFunctions,
|
TableSaveFunctions,
|
||||||
} from "../../../../api/controllers/table/utils"
|
} from "../../../../api/controllers/table/utils"
|
||||||
import { FieldTypes } from "../../../../constants"
|
|
||||||
import { EventType, updateLinks } from "../../../../db/linkedRows"
|
import { EventType, updateLinks } from "../../../../db/linkedRows"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import isEqual from "lodash/isEqual"
|
import isEqual from "lodash/isEqual"
|
||||||
|
@ -63,7 +63,7 @@ export async function save(
|
||||||
}
|
}
|
||||||
|
|
||||||
// rename row fields when table column is renamed
|
// rename row fields when table column is renamed
|
||||||
if (renaming && table.schema[renaming.updated].type === FieldTypes.LINK) {
|
if (renaming && table.schema[renaming.updated].type === FieldType.LINK) {
|
||||||
throw new Error("Cannot rename a linked column.")
|
throw new Error("Cannot rename a linked column.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import { FieldTypes, 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 { RenameColumn, Row, RowAttachment, 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> {
|
||||||
|
@ -28,7 +34,7 @@ export class AttachmentCleanup {
|
||||||
let files: string[] = []
|
let files: string[] = []
|
||||||
const tableSchema = opts.oldTable?.schema || table.schema
|
const tableSchema = opts.oldTable?.schema || table.schema
|
||||||
for (let [key, schema] of Object.entries(tableSchema)) {
|
for (let [key, schema] of Object.entries(tableSchema)) {
|
||||||
if (schema.type !== FieldTypes.ATTACHMENT) {
|
if (schema.type !== FieldType.ATTACHMENT) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const columnRemoved = opts.oldTable && !table.schema[key]
|
const columnRemoved = opts.oldTable && !table.schema[key]
|
||||||
|
@ -62,7 +68,7 @@ export class AttachmentCleanup {
|
||||||
return AttachmentCleanup.coreCleanup(() => {
|
return AttachmentCleanup.coreCleanup(() => {
|
||||||
let files: string[] = []
|
let files: string[] = []
|
||||||
for (let [key, schema] of Object.entries(table.schema)) {
|
for (let [key, schema] of Object.entries(table.schema)) {
|
||||||
if (schema.type !== FieldTypes.ATTACHMENT) {
|
if (schema.type !== FieldType.ATTACHMENT) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
rows.forEach(row => {
|
rows.forEach(row => {
|
||||||
|
@ -79,7 +85,7 @@ export class AttachmentCleanup {
|
||||||
return AttachmentCleanup.coreCleanup(() => {
|
return AttachmentCleanup.coreCleanup(() => {
|
||||||
let files: string[] = []
|
let files: string[] = []
|
||||||
for (let [key, schema] of Object.entries(table.schema)) {
|
for (let [key, schema] of Object.entries(table.schema)) {
|
||||||
if (schema.type !== FieldTypes.ATTACHMENT) {
|
if (schema.type !== FieldType.ATTACHMENT) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const oldKeys =
|
const oldKeys =
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
import * as linkRows from "../../db/linkedRows"
|
import * as linkRows from "../../db/linkedRows"
|
||||||
import { FieldTypes, AutoFieldSubTypes } from "../../constants"
|
|
||||||
import { processFormulas, fixAutoColumnSubType } from "./utils"
|
import { processFormulas, fixAutoColumnSubType } 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 { FieldSubtype, Row, RowAttachment, Table } from "@budibase/types"
|
import {
|
||||||
|
FieldType,
|
||||||
|
AutoFieldSubType,
|
||||||
|
FieldSubtype,
|
||||||
|
Row,
|
||||||
|
RowAttachment,
|
||||||
|
Table,
|
||||||
|
} from "@budibase/types"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import {
|
import {
|
||||||
processInputBBReferences,
|
processInputBBReferences,
|
||||||
|
@ -54,25 +60,25 @@ export function processAutoColumn(
|
||||||
schema = fixAutoColumnSubType(schema)
|
schema = fixAutoColumnSubType(schema)
|
||||||
}
|
}
|
||||||
switch (schema.subtype) {
|
switch (schema.subtype) {
|
||||||
case AutoFieldSubTypes.CREATED_BY:
|
case AutoFieldSubType.CREATED_BY:
|
||||||
if (creating && shouldUpdateUserFields && userId) {
|
if (creating && shouldUpdateUserFields && userId) {
|
||||||
row[key] = [userId]
|
row[key] = [userId]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case AutoFieldSubTypes.CREATED_AT:
|
case AutoFieldSubType.CREATED_AT:
|
||||||
if (creating) {
|
if (creating) {
|
||||||
row[key] = now
|
row[key] = now
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case AutoFieldSubTypes.UPDATED_BY:
|
case AutoFieldSubType.UPDATED_BY:
|
||||||
if (shouldUpdateUserFields && userId) {
|
if (shouldUpdateUserFields && userId) {
|
||||||
row[key] = [userId]
|
row[key] = [userId]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case AutoFieldSubTypes.UPDATED_AT:
|
case AutoFieldSubType.UPDATED_AT:
|
||||||
row[key] = now
|
row[key] = now
|
||||||
break
|
break
|
||||||
case AutoFieldSubTypes.AUTO_ID:
|
case AutoFieldSubType.AUTO_ID:
|
||||||
if (creating) {
|
if (creating) {
|
||||||
schema.lastID = !schema.lastID ? BASE_AUTO_ID : schema.lastID + 1
|
schema.lastID = !schema.lastID ? BASE_AUTO_ID : schema.lastID + 1
|
||||||
row[key] = schema.lastID
|
row[key] = schema.lastID
|
||||||
|
@ -134,7 +140,7 @@ export async function inputProcessing(
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// remove any formula values, they are to be generated
|
// remove any formula values, they are to be generated
|
||||||
if (field.type === FieldTypes.FORMULA) {
|
if (field.type === FieldType.FORMULA) {
|
||||||
delete clonedRow[key]
|
delete clonedRow[key]
|
||||||
}
|
}
|
||||||
// otherwise coerce what is there to correct types
|
// otherwise coerce what is there to correct types
|
||||||
|
@ -143,7 +149,7 @@ export async function inputProcessing(
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove any attachment urls, they are generated on read
|
// remove any attachment urls, they are generated on read
|
||||||
if (field.type === FieldTypes.ATTACHMENT) {
|
if (field.type === FieldType.ATTACHMENT) {
|
||||||
const attachments = clonedRow[key]
|
const attachments = clonedRow[key]
|
||||||
if (attachments?.length) {
|
if (attachments?.length) {
|
||||||
attachments.forEach((attachment: RowAttachment) => {
|
attachments.forEach((attachment: RowAttachment) => {
|
||||||
|
@ -152,7 +158,7 @@ export async function inputProcessing(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.type === FieldTypes.BB_REFERENCE && value) {
|
if (field.type === FieldType.BB_REFERENCE && value) {
|
||||||
clonedRow[key] = await processInputBBReferences(
|
clonedRow[key] = await processInputBBReferences(
|
||||||
value,
|
value,
|
||||||
field.subtype as FieldSubtype
|
field.subtype as FieldSubtype
|
||||||
|
@ -214,7 +220,7 @@ export async function outputProcessing<T extends Row[] | Row>(
|
||||||
|
|
||||||
// process complex types: attachements, bb references...
|
// process complex types: attachements, bb references...
|
||||||
for (let [property, column] of Object.entries(table.schema)) {
|
for (let [property, column] of Object.entries(table.schema)) {
|
||||||
if (column.type === FieldTypes.ATTACHMENT) {
|
if (column.type === FieldType.ATTACHMENT) {
|
||||||
for (let row of enriched) {
|
for (let row of enriched) {
|
||||||
if (row[property] == null || !Array.isArray(row[property])) {
|
if (row[property] == null || !Array.isArray(row[property])) {
|
||||||
continue
|
continue
|
||||||
|
@ -227,7 +233,7 @@ export async function outputProcessing<T extends Row[] | Row>(
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
!opts.skipBBReferences &&
|
!opts.skipBBReferences &&
|
||||||
column.type == FieldTypes.BB_REFERENCE
|
column.type == FieldType.BB_REFERENCE
|
||||||
) {
|
) {
|
||||||
for (let row of enriched) {
|
for (let row of enriched) {
|
||||||
row[property] = await processOutputBBReferences(
|
row[property] = await processOutputBBReferences(
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// @ts-nocheck
|
import { FieldType } from "@budibase/types"
|
||||||
import { FieldTypes } from "../../constants"
|
|
||||||
|
|
||||||
const parseArrayString = value => {
|
const parseArrayString = (value: any) => {
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
if (value === "") {
|
if (value === "") {
|
||||||
return []
|
return []
|
||||||
|
@ -21,11 +20,13 @@ const parseArrayString = value => {
|
||||||
* A map of how we convert various properties in rows to each other based on the row type.
|
* A map of how we convert various properties in rows to each other based on the row type.
|
||||||
*/
|
*/
|
||||||
export const TYPE_TRANSFORM_MAP: any = {
|
export const TYPE_TRANSFORM_MAP: any = {
|
||||||
[FieldTypes.LINK]: {
|
[FieldType.LINK]: {
|
||||||
"": [],
|
"": [],
|
||||||
|
//@ts-ignore
|
||||||
[null]: [],
|
[null]: [],
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
parse: link => {
|
parse: (link: any) => {
|
||||||
if (Array.isArray(link) && typeof link[0] === "object") {
|
if (Array.isArray(link) && typeof link[0] === "object") {
|
||||||
return link.map(el => (el && el._id ? el._id : el))
|
return link.map(el => (el && el._id ? el._id : el))
|
||||||
}
|
}
|
||||||
|
@ -35,75 +36,97 @@ export const TYPE_TRANSFORM_MAP: any = {
|
||||||
return link
|
return link
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[FieldTypes.OPTIONS]: {
|
[FieldType.OPTIONS]: {
|
||||||
"": null,
|
"": null,
|
||||||
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
[FieldTypes.ARRAY]: {
|
[FieldType.ARRAY]: {
|
||||||
|
//@ts-ignore
|
||||||
[null]: [],
|
[null]: [],
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
parse: parseArrayString,
|
parse: parseArrayString,
|
||||||
},
|
},
|
||||||
[FieldTypes.STRING]: {
|
[FieldType.STRING]: {
|
||||||
"": null,
|
"": null,
|
||||||
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
[FieldTypes.BARCODEQR]: {
|
[FieldType.BARCODEQR]: {
|
||||||
"": null,
|
"": null,
|
||||||
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
[FieldTypes.FORMULA]: {
|
[FieldType.FORMULA]: {
|
||||||
"": null,
|
"": null,
|
||||||
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
[FieldTypes.LONGFORM]: {
|
[FieldType.LONGFORM]: {
|
||||||
"": null,
|
"": null,
|
||||||
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
[FieldTypes.NUMBER]: {
|
[FieldType.NUMBER]: {
|
||||||
"": null,
|
"": null,
|
||||||
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
parse: n => parseFloat(n),
|
parse: (n: any) => parseFloat(n),
|
||||||
},
|
},
|
||||||
[FieldTypes.BIGINT]: {
|
[FieldType.BIGINT]: {
|
||||||
"": null,
|
"": null,
|
||||||
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
[FieldTypes.DATETIME]: {
|
[FieldType.DATETIME]: {
|
||||||
"": null,
|
"": null,
|
||||||
[undefined]: undefined,
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
parse: date => {
|
//@ts-ignore
|
||||||
|
[undefined]: undefined,
|
||||||
|
parse: (date: any) => {
|
||||||
if (date instanceof Date) {
|
if (date instanceof Date) {
|
||||||
return date.toISOString()
|
return date.toISOString()
|
||||||
}
|
}
|
||||||
return date
|
return date
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[FieldTypes.ATTACHMENT]: {
|
[FieldType.ATTACHMENT]: {
|
||||||
|
//@ts-ignore
|
||||||
[null]: [],
|
[null]: [],
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
parse: parseArrayString,
|
parse: parseArrayString,
|
||||||
},
|
},
|
||||||
[FieldTypes.BOOLEAN]: {
|
[FieldType.BOOLEAN]: {
|
||||||
"": null,
|
"": null,
|
||||||
|
//@ts-ignore
|
||||||
[null]: null,
|
[null]: null,
|
||||||
|
//@ts-ignore
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
true: true,
|
true: true,
|
||||||
false: false,
|
false: false,
|
||||||
},
|
},
|
||||||
[FieldTypes.AUTO]: {
|
[FieldType.AUTO]: {
|
||||||
parse: () => undefined,
|
parse: () => undefined,
|
||||||
},
|
},
|
||||||
[FieldTypes.JSON]: {
|
[FieldType.JSON]: {
|
||||||
parse: input => {
|
parse: (input: any) => {
|
||||||
try {
|
try {
|
||||||
if (input === "") {
|
if (input === "") {
|
||||||
return undefined
|
return undefined
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { fixAutoColumnSubType } from "../utils"
|
import { fixAutoColumnSubType } from "../utils"
|
||||||
import { AutoFieldDefaultNames, AutoFieldSubTypes } from "../../../constants"
|
import { AutoFieldDefaultNames, AutoFieldSubType } from "../../../constants"
|
||||||
import { FieldSchema, FieldType, RelationshipType } from "@budibase/types"
|
import { FieldSchema, FieldType, RelationshipType } from "@budibase/types"
|
||||||
|
|
||||||
describe("rowProcessor utility", () => {
|
describe("rowProcessor utility", () => {
|
||||||
|
@ -20,37 +20,37 @@ describe("rowProcessor utility", () => {
|
||||||
it("updates the schema with the correct subtype", async () => {
|
it("updates the schema with the correct subtype", async () => {
|
||||||
schema.name = AutoFieldDefaultNames.CREATED_BY
|
schema.name = AutoFieldDefaultNames.CREATED_BY
|
||||||
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
||||||
AutoFieldSubTypes.CREATED_BY
|
AutoFieldSubType.CREATED_BY
|
||||||
)
|
)
|
||||||
schema.subtype = undefined
|
schema.subtype = undefined
|
||||||
|
|
||||||
schema.name = AutoFieldDefaultNames.UPDATED_BY
|
schema.name = AutoFieldDefaultNames.UPDATED_BY
|
||||||
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
||||||
AutoFieldSubTypes.UPDATED_BY
|
AutoFieldSubType.UPDATED_BY
|
||||||
)
|
)
|
||||||
schema.subtype = undefined
|
schema.subtype = undefined
|
||||||
|
|
||||||
schema.name = AutoFieldDefaultNames.CREATED_AT
|
schema.name = AutoFieldDefaultNames.CREATED_AT
|
||||||
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
||||||
AutoFieldSubTypes.CREATED_AT
|
AutoFieldSubType.CREATED_AT
|
||||||
)
|
)
|
||||||
schema.subtype = undefined
|
schema.subtype = undefined
|
||||||
|
|
||||||
schema.name = AutoFieldDefaultNames.UPDATED_AT
|
schema.name = AutoFieldDefaultNames.UPDATED_AT
|
||||||
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
||||||
AutoFieldSubTypes.UPDATED_AT
|
AutoFieldSubType.UPDATED_AT
|
||||||
)
|
)
|
||||||
schema.subtype = undefined
|
schema.subtype = undefined
|
||||||
|
|
||||||
schema.name = AutoFieldDefaultNames.AUTO_ID
|
schema.name = AutoFieldDefaultNames.AUTO_ID
|
||||||
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
expect(fixAutoColumnSubType(schema).subtype).toEqual(
|
||||||
AutoFieldSubTypes.AUTO_ID
|
AutoFieldSubType.AUTO_ID
|
||||||
)
|
)
|
||||||
schema.subtype = undefined
|
schema.subtype = undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns the column if subtype exists", async () => {
|
it("returns the column if subtype exists", async () => {
|
||||||
schema.subtype = AutoFieldSubTypes.CREATED_BY
|
schema.subtype = AutoFieldSubType.CREATED_BY
|
||||||
schema.name = AutoFieldDefaultNames.CREATED_AT
|
schema.name = AutoFieldDefaultNames.CREATED_AT
|
||||||
expect(fixAutoColumnSubType(schema)).toEqual(schema)
|
expect(fixAutoColumnSubType(schema)).toEqual(schema)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
import {
|
import { AutoFieldDefaultNames } from "../../constants"
|
||||||
AutoFieldDefaultNames,
|
|
||||||
AutoFieldSubTypes,
|
|
||||||
FieldTypes,
|
|
||||||
FormulaTypes,
|
|
||||||
} from "../../constants"
|
|
||||||
import { processStringSync } from "@budibase/string-templates"
|
import { processStringSync } from "@budibase/string-templates"
|
||||||
import {
|
import {
|
||||||
AutoColumnFieldMetadata,
|
AutoColumnFieldMetadata,
|
||||||
FieldSchema,
|
FieldSchema,
|
||||||
Row,
|
Row,
|
||||||
Table,
|
Table,
|
||||||
|
FormulaType,
|
||||||
|
AutoFieldSubType,
|
||||||
|
FieldType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import tracer from "dd-trace"
|
import tracer from "dd-trace"
|
||||||
|
|
||||||
|
@ -30,15 +28,15 @@ export function fixAutoColumnSubType(
|
||||||
}
|
}
|
||||||
// the columns which get auto generated
|
// the columns which get auto generated
|
||||||
if (column.name.endsWith(AutoFieldDefaultNames.CREATED_BY)) {
|
if (column.name.endsWith(AutoFieldDefaultNames.CREATED_BY)) {
|
||||||
column.subtype = AutoFieldSubTypes.CREATED_BY
|
column.subtype = AutoFieldSubType.CREATED_BY
|
||||||
} else if (column.name.endsWith(AutoFieldDefaultNames.UPDATED_BY)) {
|
} else if (column.name.endsWith(AutoFieldDefaultNames.UPDATED_BY)) {
|
||||||
column.subtype = AutoFieldSubTypes.UPDATED_BY
|
column.subtype = AutoFieldSubType.UPDATED_BY
|
||||||
} else if (column.name.endsWith(AutoFieldDefaultNames.CREATED_AT)) {
|
} else if (column.name.endsWith(AutoFieldDefaultNames.CREATED_AT)) {
|
||||||
column.subtype = AutoFieldSubTypes.CREATED_AT
|
column.subtype = AutoFieldSubType.CREATED_AT
|
||||||
} else if (column.name.endsWith(AutoFieldDefaultNames.UPDATED_AT)) {
|
} else if (column.name.endsWith(AutoFieldDefaultNames.UPDATED_AT)) {
|
||||||
column.subtype = AutoFieldSubTypes.UPDATED_AT
|
column.subtype = AutoFieldSubType.UPDATED_AT
|
||||||
} else if (column.name.endsWith(AutoFieldDefaultNames.AUTO_ID)) {
|
} else if (column.name.endsWith(AutoFieldDefaultNames.AUTO_ID)) {
|
||||||
column.subtype = AutoFieldSubTypes.AUTO_ID
|
column.subtype = AutoFieldSubType.AUTO_ID
|
||||||
}
|
}
|
||||||
return column
|
return column
|
||||||
}
|
}
|
||||||
|
@ -57,11 +55,11 @@ export function processFormulas<T extends Row | Row[]>(
|
||||||
const rows = Array.isArray(inputRows) ? inputRows : [inputRows]
|
const rows = Array.isArray(inputRows) ? inputRows : [inputRows]
|
||||||
if (rows) {
|
if (rows) {
|
||||||
for (let [column, schema] of Object.entries(table.schema)) {
|
for (let [column, schema] of Object.entries(table.schema)) {
|
||||||
if (schema.type !== FieldTypes.FORMULA) {
|
if (schema.type !== FieldType.FORMULA) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const isStatic = schema.formulaType === FormulaTypes.STATIC
|
const isStatic = schema.formulaType === FormulaType.STATIC
|
||||||
|
|
||||||
if (
|
if (
|
||||||
schema.formula == null ||
|
schema.formula == null ||
|
||||||
|
@ -100,7 +98,7 @@ export function processDates<T extends Row | Row[]>(
|
||||||
let rows = Array.isArray(inputRows) ? inputRows : [inputRows]
|
let rows = Array.isArray(inputRows) ? inputRows : [inputRows]
|
||||||
let datesWithTZ: string[] = []
|
let datesWithTZ: string[] = []
|
||||||
for (let [column, schema] of Object.entries(table.schema)) {
|
for (let [column, schema] of Object.entries(table.schema)) {
|
||||||
if (schema.type !== FieldTypes.DATETIME) {
|
if (schema.type !== FieldType.DATETIME) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (!schema.timeOnly && !schema.ignoreTimezones) {
|
if (!schema.timeOnly && !schema.ignoreTimezones) {
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import { FieldSubtype } from "@budibase/types"
|
import { FieldType, FieldSubtype } from "@budibase/types"
|
||||||
import { FieldTypes } from "../constants"
|
|
||||||
import { ValidColumnNameRegex, utils } from "@budibase/shared-core"
|
import { ValidColumnNameRegex, utils } from "@budibase/shared-core"
|
||||||
import { db } from "@budibase/backend-core"
|
import { db } from "@budibase/backend-core"
|
||||||
import { parseCsvExport } from "../api/controllers/view/exporters"
|
import { parseCsvExport } from "../api/controllers/view/exporters"
|
||||||
|
|
||||||
interface SchemaColumn {
|
interface SchemaColumn {
|
||||||
readonly name: string
|
readonly name: string
|
||||||
readonly type: FieldTypes
|
readonly type: FieldType
|
||||||
readonly subtype: FieldSubtype
|
readonly subtype: FieldSubtype
|
||||||
readonly autocolumn?: boolean
|
readonly autocolumn?: boolean
|
||||||
readonly constraints?: {
|
readonly constraints?: {
|
||||||
|
@ -36,13 +35,13 @@ interface ValidationResults {
|
||||||
}
|
}
|
||||||
|
|
||||||
const PARSERS: any = {
|
const PARSERS: any = {
|
||||||
[FieldTypes.NUMBER]: (attribute?: string) => {
|
[FieldType.NUMBER]: (attribute?: string) => {
|
||||||
if (!attribute) {
|
if (!attribute) {
|
||||||
return attribute
|
return attribute
|
||||||
}
|
}
|
||||||
return Number(attribute)
|
return Number(attribute)
|
||||||
},
|
},
|
||||||
[FieldTypes.DATETIME]: (attribute?: string) => {
|
[FieldType.DATETIME]: (attribute?: string) => {
|
||||||
if (!attribute) {
|
if (!attribute) {
|
||||||
return attribute
|
return attribute
|
||||||
}
|
}
|
||||||
|
@ -60,7 +59,7 @@ export function isSchema(schema: any): schema is Schema {
|
||||||
column !== null &&
|
column !== null &&
|
||||||
typeof column === "object" &&
|
typeof column === "object" &&
|
||||||
typeof column.type === "string" &&
|
typeof column.type === "string" &&
|
||||||
Object.values(FieldTypes).includes(column.type as FieldTypes)
|
Object.values(FieldType).includes(column.type as FieldType)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -110,20 +109,17 @@ export function validate(rows: Rows, schema: Schema): ValidationResults {
|
||||||
isAutoColumn
|
isAutoColumn
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
} else if (
|
} else if (columnType === FieldType.NUMBER && isNaN(Number(columnData))) {
|
||||||
columnType === FieldTypes.NUMBER &&
|
|
||||||
isNaN(Number(columnData))
|
|
||||||
) {
|
|
||||||
// If provided must be a valid number
|
// If provided must be a valid number
|
||||||
results.schemaValidation[columnName] = false
|
results.schemaValidation[columnName] = false
|
||||||
} else if (
|
} else if (
|
||||||
// If provided must be a valid date
|
// If provided must be a valid date
|
||||||
columnType === FieldTypes.DATETIME &&
|
columnType === FieldType.DATETIME &&
|
||||||
isNaN(new Date(columnData).getTime())
|
isNaN(new Date(columnData).getTime())
|
||||||
) {
|
) {
|
||||||
results.schemaValidation[columnName] = false
|
results.schemaValidation[columnName] = false
|
||||||
} else if (
|
} else if (
|
||||||
columnType === FieldTypes.BB_REFERENCE &&
|
columnType === FieldType.BB_REFERENCE &&
|
||||||
!isValidBBReference(columnData, columnSubtype)
|
!isValidBBReference(columnData, columnSubtype)
|
||||||
) {
|
) {
|
||||||
results.schemaValidation[columnName] = false
|
results.schemaValidation[columnName] = false
|
||||||
|
@ -155,15 +151,15 @@ export function parse(rows: Rows, schema: Schema): Rows {
|
||||||
const columnType = schema[columnName].type
|
const columnType = schema[columnName].type
|
||||||
const columnSubtype = schema[columnName].subtype
|
const columnSubtype = schema[columnName].subtype
|
||||||
|
|
||||||
if (columnType === FieldTypes.NUMBER) {
|
if (columnType === FieldType.NUMBER) {
|
||||||
// If provided must be a valid number
|
// If provided must be a valid number
|
||||||
parsedRow[columnName] = columnData ? Number(columnData) : columnData
|
parsedRow[columnName] = columnData ? Number(columnData) : columnData
|
||||||
} else if (columnType === FieldTypes.DATETIME) {
|
} else if (columnType === FieldType.DATETIME) {
|
||||||
// If provided must be a valid date
|
// If provided must be a valid date
|
||||||
parsedRow[columnName] = columnData
|
parsedRow[columnName] = columnData
|
||||||
? new Date(columnData).toISOString()
|
? new Date(columnData).toISOString()
|
||||||
: columnData
|
: columnData
|
||||||
} else if (columnType === FieldTypes.BB_REFERENCE) {
|
} else if (columnType === FieldType.BB_REFERENCE) {
|
||||||
const parsedValues =
|
const parsedValues =
|
||||||
!!columnData && parseCsvExport<{ _id: string }[]>(columnData)
|
!!columnData && parseCsvExport<{ _id: string }[]>(columnData)
|
||||||
if (!parsedValues) {
|
if (!parsedValues) {
|
||||||
|
|
Loading…
Reference in New Issue