docs/docs/en/plugin-development/server/collection-options.md
export type MigrationRule =
| 'overwrite'
| 'skip'
| 'upsert'
| 'schema-only'
| 'insert-ignore';
export interface CollectionOptions {
name: string;
title?: string;
migrationRules?: MigrationRule[];
inherits?: string[] | string;
filterTargetKey?: string | string[];
fields?: FieldOptions[];
model?: string | ModelStatic<Model>;
repository?: string | RepositoryType;
autoGenId?: boolean;
timestamps?: boolean;
createdAt?: boolean;
updatedAt?: boolean;
deletedAt?: boolean;
paranoid?: boolean;
underscored?: boolean;
indexes?: ModelIndexesOptions[];
}
name - Collection Namestring{
name: 'users' // User collection
}
title - Collection Titlestring{
name: 'users',
title: 'User Management' // Displays as "User Management" in the interface
}
migrationRules - Migration RulesMigrationRule[]{
name: 'users',
migrationRules: ['overwrite'], // Overwrite existing data
fields: [...]
}
inherits - Inherit Collectionsstring[] | string// Single inheritance
{
name: 'admin_users',
inherits: 'users', // Inherit all fields from the users collection
fields: [
{
type: 'string',
name: 'admin_level'
}
]
}
// Multiple inheritance
{
name: 'super_admin_users',
inherits: ['users', 'admin_users'], // Inherit from multiple collections
fields: [...]
}
filterTargetKey - Filter Target Keystring | string[]{
name: 'user_posts',
filterTargetKey: 'userId', // Filter by user ID
fields: [...]
}
// Multiple filter keys
{
name: 'user_category_posts',
filterTargetKey: ['userId', 'categoryId'], // Filter by user ID and category ID
fields: [...]
}
fields - Field DefinitionsFieldOptions[][]{
name: 'users',
fields: [
{
type: 'string',
name: 'username',
unique: true,
title: 'Username'
},
{
type: 'string',
name: 'email',
unique: true,
title: 'Email'
},
{
type: 'password',
name: 'password',
title: 'Password'
},
{
type: 'date',
name: 'createdAt',
title: 'Created At'
}
]
}
model - Custom Modelstring | ModelStatic<Model>// Specify model class name as a string
{
name: 'users',
model: 'UserModel',
fields: [...]
}
// Use the model class
import { UserModel } from './models/UserModel';
{
name: 'users',
model: UserModel,
fields: [...]
}
repository - Custom Repositorystring | RepositoryType// Specify repository class name as a string
{
name: 'users',
repository: 'UserRepository',
fields: [...]
}
// Use the repository class
import { UserRepository } from './repositories/UserRepository';
{
name: 'users',
repository: UserRepository,
fields: [...]
}
autoGenId - Auto-generate IDbooleantrue{
name: 'users',
autoGenId: true, // Automatically generate primary key ID
fields: [...]
}
// Disable auto-generation of ID (requires manual primary key specification)
{
name: 'external_data',
autoGenId: false,
fields: [
{
type: 'string',
name: 'id',
primaryKey: true
}
]
}
timestamps - Enable TimestampsbooleantruecreatedAt and updatedAt fields.{
name: 'users',
timestamps: true, // Enable timestamps
fields: [...]
}
createdAt - Created At Fieldboolean | stringtruecreatedAt field.{
name: 'users',
createdAt: 'created_at', // Custom name for the createdAt field
fields: [...]
}
updatedAt - Updated At Fieldboolean | stringtrueupdatedAt field.{
name: 'users',
updatedAt: 'updated_at', // Custom name for the updatedAt field
fields: [...]
}
deletedAt - Soft Delete Fieldboolean | stringfalse{
name: 'users',
deletedAt: 'deleted_at', // Enable soft delete
paranoid: true,
fields: [...]
}
paranoid - Soft Delete Modebooleanfalse{
name: 'users',
paranoid: true, // Enable soft delete
deletedAt: 'deleted_at',
fields: [...]
}
underscored - Underscore Namingbooleanfalse{
name: 'users',
underscored: true, // Use underscore naming style
fields: [...]
}
indexes - Index ConfigurationModelIndexesOptions[]{
name: 'users',
indexes: [
{
fields: ['email'],
unique: true
},
{
fields: ['username', 'status']
}
],
fields: [...]
}
NocoBase supports multiple field types, all defined based on the FieldOptions union type. Field configuration includes basic properties, data type-specific properties, relationship properties, and frontend rendering properties.
All field types inherit from BaseFieldOptions, providing common field configuration capabilities:
interface BaseFieldOptions<T extends BasicType = BasicType> {
// Common parameters
name?: string; // Field name
hidden?: boolean; // Whether to hide
validation?: ValidationOptions<T>; // Validation rules
// Common column field properties
allowNull?: boolean;
defaultValue?: any;
unique?: boolean;
primaryKey?: boolean;
autoIncrement?: boolean;
field?: string;
comment?: string;
// Frontend related
title?: string;
description?: string;
interface?: string;
uiSchema?: any;
}
Example:
{
type: 'string',
name: 'username',
allowNull: false, // Do not allow null values
unique: true, // Unique constraint
defaultValue: '', // Default to an empty string
index: true, // Create an index
comment: 'User login name' // Database comment
}
name - Field Namestring{
type: 'string',
name: 'username', // Field name
title: 'Username'
}
hidden - Hide Fieldbooleanfalse{
type: 'string',
name: 'internalId',
hidden: true, // Hide the internal ID field
title: 'Internal ID'
}
validation - Validation Rulesinterface ValidationOptions<T extends BasicType = BasicType> {
type: T; // Validation type
rules: FieldValidationRule<T>[]; // Array of validation rules
[key: string]: any; // Other validation options
}
interface FieldValidationRule<T extends BasicType> {
key: string; // Rule key
name: FieldValidationRuleName<T>; // Rule name
args?: { // Rule arguments
[key: string]: any;
};
paramsType?: 'object'; // Parameter type
}
ValidationOptions<T>{
type: 'string',
name: 'email',
validation: {
type: 'string',
rules: [
{ key: 'email', name: 'email' },
{ key: 'required', name: 'required' }
]
}
}
allowNull - Allow Null ValuesbooleantrueNULL values.{
type: 'string',
name: 'username',
allowNull: false, // Do not allow null values
title: 'Username'
}
defaultValue - Default Valueany{
type: 'string',
name: 'status',
defaultValue: 'draft', // Default to draft status
title: 'Status'
}
unique - Unique Constraintboolean | stringfalse{
type: 'string',
name: 'email',
unique: true, // Email must be unique
title: 'Email'
}
primaryKey - Primary Keybooleanfalse{
type: 'integer',
name: 'id',
primaryKey: true, // Set as primary key
autoIncrement: true
}
autoIncrement - Auto-incrementbooleanfalse{
type: 'integer',
name: 'id',
autoIncrement: true, // Auto-increment
primaryKey: true
}
field - Database Column Namestringfield).{
type: 'string',
name: 'userId',
field: 'user_id', // Column name in the database
title: 'User ID'
}
comment - Database Commentstring{
type: 'string',
name: 'username',
comment: 'User login name, used for system login', // Database comment
title: 'Username'
}
title - Display Titlestring{
type: 'string',
name: 'username',
title: 'Username', // Title displayed on the frontend
allowNull: false
}
description - Field Descriptionstring{
type: 'string',
name: 'email',
title: 'Email',
description: 'Please enter a valid email address', // Field description
validation: {
type: 'string',
rules: [{ key: 'email', name: 'email' }]
}
}
interface - Interface Componentstring{
type: 'string',
name: 'content',
title: 'Content',
interface: 'textarea', // Recommend using the textarea component
uiSchema: {
'x-component': 'Input.TextArea'
}
}
type: 'string' - String FieldVARCHARlength: String length limit.trim: Whether to automatically remove leading and trailing spaces.interface StringFieldOptions extends BaseColumnFieldOptions<'string'> {
type: 'string';
length?: number; // String length limit
trim?: boolean; // Whether to automatically remove leading and trailing spaces
}
Example:
{
type: 'string',
name: 'username',
title: 'Username',
length: 50, // Maximum 50 characters
trim: true, // Automatically remove spaces
allowNull: false,
unique: true,
validation: {
type: 'string',
rules: [
{ key: 'min', name: 'min', args: { limit: 3 } },
{ key: 'max', name: 'max', args: { limit: 20 } }
]
}
}
type: 'text' - Text FieldTEXT, MEDIUMTEXT, LONGTEXTlength: MySQL text length type (tiny/medium/long).interface TextFieldOptions extends BaseColumnFieldOptions {
type: 'text';
length?: 'tiny' | 'medium' | 'long'; // MySQL text length type
}
Example:
{
type: 'text',
name: 'content',
title: 'Content',
length: 'medium', // Use MEDIUMTEXT
allowNull: true
}
type: 'integer' - Integer FieldINTEGERinterface IntegerFieldOptions extends BaseColumnFieldOptions<'number'> {
type: 'integer';
// Inherits all options from the Sequelize INTEGER type
}
Example:
{
type: 'integer',
name: 'id',
title: 'ID',
primaryKey: true,
autoIncrement: true,
allowNull: false
}
type: 'bigInt' - Big Integer Fieldinteger.BIGINTinterface BigIntFieldOptions extends BaseColumnFieldOptions<'number'> {
type: 'bigInt';
}
Example:
{
type: 'bigInt',
name: 'userId',
title: 'User ID',
allowNull: false,
unique: true
}
type: 'float' - Float FieldFLOATprecision: The total number of digits.scale: The number of decimal places.interface FloatFieldOptions extends BaseColumnFieldOptions<'number'> {
type: 'float';
precision?: number; // Precision
scale?: number; // Scale (decimal places)
}
Example:
{
type: 'float',
name: 'score',
title: 'Score',
precision: 5,
scale: 2,
allowNull: true,
defaultValue: 0.0
}
type: 'double' - Double-precision Float Fieldfloat.DOUBLEprecision: The total number of digits.scale: The number of decimal places.interface DoubleFieldOptions extends BaseColumnFieldOptions<'number'> {
type: 'double';
precision?: number;
scale?: number;
}
Example:
{
type: 'double',
name: 'price',
title: 'Price',
precision: 10,
scale: 2,
allowNull: false,
defaultValue: 0.00
}
type: 'real' - Real FieldREALprecision: The total number of digits.scale: The number of decimal places.interface RealFieldOptions extends BaseColumnFieldOptions<'number'> {
type: 'real';
precision?: number;
scale?: number;
}
Example:
{
type: 'real',
name: 'rate',
title: 'Rate',
precision: 8,
scale: 4,
allowNull: true
}
type: 'decimal' - Decimal FieldDECIMALprecision: The total number of digits.scale: The number of decimal places.interface DecimalFieldOptions extends BaseColumnFieldOptions<'number'> {
type: 'decimal';
precision?: number; // Precision (total number of digits)
scale?: number; // Scale (decimal places)
}
Example:
{
type: 'decimal',
name: 'amount',
title: 'Amount',
precision: 10,
scale: 2,
allowNull: false,
defaultValue: 0.00,
validation: {
type: 'number',
rules: [
{ key: 'min', name: 'min', args: { limit: 0 } }
]
}
}
type: 'boolean' - Boolean FieldBOOLEAN or TINYINT(1)interface BooleanFieldOptions extends BaseColumnFieldOptions<'boolean'> {
type: 'boolean';
}
Example:
{
type: 'boolean',
name: 'isActive',
title: 'Is Active',
defaultValue: true,
allowNull: false
}
type: 'radio' - Radio FieldBOOLEAN or TINYINT(1)interface RadioFieldOptions extends BaseColumnFieldOptions<'boolean'> {
type: 'radio';
}
Example:
{
type: 'radio',
name: 'isDefault',
title: 'Is Default',
defaultValue: false,
allowNull: false
}
type: 'date' - Date FieldDATEtimezone: Whether to include timezone information.interface DateFieldOptions extends BaseColumnFieldOptions<'date'> {
type: 'date';
timezone?: boolean; // Whether to include timezone information
}
Example:
{
type: 'date',
name: 'birthday',
title: 'Birthday',
allowNull: true,
timezone: false
}
type: 'time' - Time FieldTIMEtimezone: Whether to include timezone information.interface TimeFieldOptions extends BaseColumnFieldOptions<'time'> {
type: 'time';
timezone?: boolean;
}
Example:
{
type: 'time',
name: 'startTime',
title: 'Start Time',
allowNull: false,
timezone: false
}
type: 'datetimeTz' - Datetime with Timezone FieldTIMESTAMP WITH TIME ZONEtimezone: Whether to include timezone information.interface DatetimeTzFieldOptions extends BaseColumnFieldOptions<'datetime'> {
type: 'datetimeTz';
timezone?: boolean;
}
Example:
{
type: 'datetimeTz',
name: 'createdAt',
title: 'Created At',
allowNull: false,
timezone: true,
defaultToCurrentTime: true,
onUpdateToCurrentTime: true
}
type: 'datetimeNoTz' - Datetime without Timezone FieldTIMESTAMP or DATETIMEtimezone: Whether to include timezone information.interface DatetimeNoTzFieldOptions extends BaseColumnFieldOptions<'datetime'> {
type: 'datetimeNoTz';
timezone?: boolean;
}
Example:
{
type: 'datetimeNoTz',
name: 'updatedAt',
title: 'Updated At',
allowNull: false,
timezone: false,
defaultToCurrentTime: true,
onUpdateToCurrentTime: true
}
type: 'dateOnly' - Date Only FieldDATE{
type: 'dateOnly',
name: 'publishDate',
title: 'Publish Date',
allowNull: true
}
type: 'unixTimestamp' - Unix Timestamp FieldBIGINTepoch: The epoch time.interface UnixTimestampFieldOptions extends BaseColumnFieldOptions<'unixTimestamp'> {
type: 'unixTimestamp';
epoch?: number; // Epoch time
}
Example:
{
type: 'unixTimestamp',
name: 'lastLoginAt',
title: 'Last Login At',
allowNull: true,
epoch: 0
}
type: 'json' - JSON FieldJSON or TEXT{
type: 'json',
name: 'metadata',
title: 'Metadata',
allowNull: true,
defaultValue: {}
}
type: 'jsonb' - JSONB FieldJSONB (PostgreSQL){
type: 'jsonb',
name: 'config',
title: 'Configuration',
allowNull: true,
defaultValue: {}
}
type: 'array' - Array FieldJSON or ARRAYdataType: Storage type (json/array).elementType: Element type (STRING/INTEGER/BOOLEAN/JSON).interface ArrayFieldOptions extends BaseColumnFieldOptions<'array'> {
type: 'array';
dataType?: 'json' | 'array'; // Storage type
elementType?: 'STRING' | 'INTEGER' | 'BOOLEAN' | 'JSON'; // Element type
}
Example:
{
type: 'array',
name: 'tags',
title: 'Tags',
dataType: 'json',
elementType: 'STRING',
allowNull: true,
defaultValue: []
}
type: 'set' - Set FieldJSON or ARRAYdataType: Storage type (json/array).elementType: Element type (STRING/INTEGER/BOOLEAN/JSON).interface SetFieldOptions extends BaseColumnFieldOptions<'set'> {
type: 'set';
dataType?: 'json' | 'array';
elementType?: 'STRING' | 'INTEGER' | 'BOOLEAN' | 'JSON';
}
Example:
{
type: 'set',
name: 'categories',
title: 'Categories',
dataType: 'json',
elementType: 'STRING',
allowNull: true,
defaultValue: []
}
type: 'uuid' - UUID FieldUUID or VARCHAR(36)autoFill: Automatically fills the value.interface UUIDFieldOptions extends BaseColumnFieldOptions<'uuid'> {
type: 'uuid';
autoFill?: boolean; // Auto-fill
}
Example:
{
type: 'uuid',
name: 'id',
title: 'ID',
autoFill: true,
allowNull: false,
primaryKey: true
}
type: 'nanoid' - Nanoid FieldVARCHARsize: Length of the ID.customAlphabet: Custom character set.autoFill: Automatically fills the value.interface NanoidFieldOptions extends BaseColumnFieldOptions<'nanoid'> {
type: 'nanoid';
size?: number; // ID length
customAlphabet?: string; // Custom character set
autoFill?: boolean;
}
Example:
{
type: 'nanoid',
name: 'shortId',
title: 'Short ID',
size: 12,
customAlphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
autoFill: true,
allowNull: false,
unique: true
}
type: 'uid' - Custom UID FieldVARCHARprefix: A prefix for the identifier.pattern: A validation pattern.interface UidFieldOptions extends BaseColumnFieldOptions<'uid'> {
type: 'uid';
prefix?: string; // Prefix
pattern?: string; // Validation pattern
}
Example:
{
type: 'uid',
name: 'code',
title: 'Code',
prefix: 'USR_',
pattern: '^[A-Za-z0-9_][A-Za-z0-9_-]*$',
allowNull: false,
unique: true
}
type: 'snowflakeId' - Snowflake ID FieldBIGINT{
type: 'snowflakeId',
name: 'snowflakeId',
title: 'Snowflake ID',
allowNull: false,
unique: true
}
type: 'password' - Password FieldVARCHARlength: Hash length.randomBytesSize: Size of the random bytes.interface PasswordFieldOptions extends BaseColumnFieldOptions<'password'> {
type: 'password';
length?: number; // Hash length
randomBytesSize?: number; // Random bytes size
}
Example:
{
type: 'password',
name: 'password',
title: 'Password',
length: 64,
randomBytesSize: 8,
allowNull: false,
hidden: true
}
type: 'encryption' - Encryption FieldVARCHAR{
type: 'encryption',
name: 'secret',
title: 'Secret',
allowNull: true,
hidden: true
}
type: 'virtual' - Virtual Field{
type: 'virtual',
name: 'fullName',
title: 'Full Name'
}
type: 'context' - Context FielddataType.dataIndex: Data index path.dataType: Data type.createOnly: Set only on creation.interface ContextFieldOptions extends BaseFieldOptions {
type: 'context';
dataIndex?: string; // Data index path
dataType?: string; // Data type
createOnly?: boolean; // Set only on creation
}
Example:
{
type: 'context',
name: 'currentUserId',
title: 'Current User ID',
dataIndex: 'user.id',
dataType: 'integer',
createOnly: true,
allowNull: false
}
type: 'belongsTo' - Belongs To Relationshiptarget: Target collection name.foreignKey: Foreign key field name.targetKey: Target key field name in the target collection.onDelete: Cascade action on delete.onUpdate: Cascade action on update.constraints: Whether to enable foreign key constraints.interface BelongsToFieldOptions extends BaseRelationFieldOptions {
type: 'belongsTo';
target: string; // Target collection name
foreignKey?: string; // Foreign key field name
targetKey?: string; // Target key field name in the target collection
onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
constraints?: boolean; // Whether to enable foreign key constraints
}
Example:
{
type: 'belongsTo',
name: 'author',
title: 'Author',
target: 'users',
foreignKey: 'authorId',
targetKey: 'id',
onDelete: 'SET NULL',
onUpdate: 'CASCADE',
constraints: false
}
type: 'hasOne' - Has One Relationshiptarget: Target collection name.foreignKey: Foreign key field name.sourceKey: Source key field name in the source collection.onDelete: Cascade action on delete.onUpdate: Cascade action on update.constraints: Whether to enable foreign key constraints.interface HasOneFieldOptions extends BaseRelationFieldOptions {
type: 'hasOne';
target: string;
foreignKey?: string;
sourceKey?: string; // Source key field name
onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
constraints?: boolean;
}
Example:
{
type: 'hasOne',
name: 'profile',
title: 'User Profile',
target: 'user_profiles',
foreignKey: 'userId',
sourceKey: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
constraints: false
}
type: 'hasMany' - Has Many Relationshiptarget: Target collection name.foreignKey: Foreign key field name.sourceKey: Source key field name in the source collection.sortBy: Sorting field.sortable: Whether the field is sortable.onDelete: Cascade action on delete.onUpdate: Cascade action on update.constraints: Whether to enable foreign key constraints.interface HasManyFieldOptions extends BaseRelationFieldOptions {
type: 'hasMany';
target: string;
foreignKey?: string;
sourceKey?: string;
sortBy?: string[]; // Sorting field
sortable?: boolean; // Whether sortable
onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
constraints?: boolean;
}
Example:
{
type: 'hasMany',
name: 'posts',
title: 'Posts',
target: 'articles',
foreignKey: 'authorId',
sourceKey: 'id',
sortBy: ['createdAt'],
sortable: true,
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
constraints: false
}
type: 'belongsToMany' - Belongs To Many Relationshiptarget: Target collection name.through: Junction table name.foreignKey: Foreign key field name.otherKey: The other foreign key in the junction table.sourceKey: Source key field name in the source collection.targetKey: Target key field name in the target collection.onDelete: Cascade action on delete.onUpdate: Cascade action on update.constraints: Whether to enable foreign key constraints.interface BelongsToManyFieldOptions extends BaseRelationFieldOptions {
type: 'belongsToMany';
target: string;
through: string; // Junction table name
foreignKey?: string;
otherKey?: string; // The other foreign key in the junction table
sourceKey?: string;
targetKey?: string;
onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
constraints?: boolean;
}
Example:
{
type: 'belongsToMany',
name: 'tags',
title: 'Tags',
target: 'article_tags',
through: 'article_tag_relations',
foreignKey: 'articleId',
otherKey: 'tagId',
sourceKey: 'id',
targetKey: 'id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
constraints: false
}