Allow field creation with just field/type combo (#3990)

Fixes #3926
This commit is contained in:
Rijk van Zanten
2021-02-09 18:43:25 -05:00
committed by GitHub
parent df22a58c6a
commit e6fa07dba8
3 changed files with 12 additions and 14 deletions

View File

@@ -39,3 +39,5 @@ export const SYSTEM_ASSET_ALLOW_LIST: Transformation[] = [
export const ASSET_TRANSFORM_QUERY_KEYS = ['key', 'width', 'height', 'fit', 'withoutEnlargement'];
export const FILTER_VARIABLES = ['$NOW', '$CURRENT_USER', '$CURRENT_ROLE'];
export const ALIAS_TYPES = ['alias', 'o2m', 'm2m', 'm2a', 'files', 'files', 'translations'];

View File

@@ -65,13 +65,14 @@ router.get(
const newFieldSchema = Joi.object({
collection: Joi.string().optional(),
field: Joi.string().required(),
type: Joi.string().valid(...types, null),
type: Joi.string()
.valid(...types, null)
.required(),
schema: Joi.object({
default_value: Joi.any(),
max_length: [Joi.number(), Joi.string(), Joi.valid(null)],
is_nullable: Joi.bool(),
}).unknown(),
/** @todo base this on default validation */
meta: Joi.any(),
});
@@ -79,8 +80,6 @@ router.post(
'/:collection',
validateCollection,
asyncHandler(async (req, res, next) => {
if (!req.body.schema && !req.body.meta) throw new InvalidPayloadException(`"schema" or "meta" is required`);
const service = new FieldsService({
accountability: req.accountability,
schema: req.schema,
@@ -115,12 +114,12 @@ router.post(
router.patch(
'/:collection/:field',
validateCollection,
// @todo: validate field
asyncHandler(async (req, res, next) => {
const service = new FieldsService({
accountability: req.accountability,
schema: req.schema,
});
const fieldData: Partial<Field> & { field: string; type: typeof types[number] } = req.body;
if (!fieldData.field) fieldData.field = req.params.field;

View File

@@ -1,3 +1,4 @@
import { ALIAS_TYPES } from '../constants';
import database, { schemaInspector } from '../database';
import { Field } from '../types/field';
import { Accountability, AbstractServiceOptions, FieldMeta, Relation, SchemaOverview } from '../types';
@@ -93,12 +94,10 @@ export class FieldsService {
aliasFields.push(...systemFieldRows);
}
const aliasTypes = ['alias', 'o2m', 'm2m', 'm2a', 'files', 'files', 'translations'];
aliasFields = aliasFields.filter((field) => {
const specials = toArray(field.special);
for (const type of aliasTypes) {
for (const type of ALIAS_TYPES) {
if (specials.includes(type)) return true;
}
@@ -210,7 +209,7 @@ export class FieldsService {
throw new InvalidPayloadException(`Field "${field.field}" already exists in collection "${collection}"`);
}
if (field.schema) {
if (ALIAS_TYPES.includes(field.type) === false) {
if (table) {
this.addColumnToTable(table, field as Field);
} else {
@@ -318,14 +317,12 @@ export class FieldsService {
}
public addColumnToTable(table: CreateTableBuilder, field: RawField | Field, alter: boolean = false) {
if (!field.schema) return;
let column: ColumnBuilder;
if (field.schema?.has_auto_increment) {
column = table.increments(field.field);
} else if (field.type === 'string') {
column = table.string(field.field, field.schema.max_length !== null ? field.schema.max_length : undefined);
column = table.string(field.field, field.schema?.max_length ?? undefined);
} else if (['float', 'decimal'].includes(field.type)) {
const type = field.type as 'float' | 'decimal';
column = table[type](field.field, field.schema?.numeric_precision || 10, field.schema?.numeric_scale || 5);
@@ -337,7 +334,7 @@ export class FieldsService {
column = table[field.type](field.field);
}
if (field.schema.default_value !== undefined) {
if (field.schema?.default_value !== undefined) {
if (typeof field.schema.default_value === 'string' && field.schema.default_value.toLowerCase() === 'now()') {
column.defaultTo(this.knex.fn.now());
} else {
@@ -345,7 +342,7 @@ export class FieldsService {
}
}
if (field.schema.is_nullable !== undefined && field.schema.is_nullable === false) {
if (field.schema?.is_nullable !== undefined && field.schema.is_nullable === false) {
column.notNullable();
} else {
column.nullable();