UNPKG

@palmares/databases

Version:

Add support for working with databases with palmares framework

777 lines 41.7 kB
import { Field } from './field'; import { BigAutoField, IntegerField } from '../..'; import { type BaseModel, type Model, type ModelType } from '../model'; import type { CustomImportsForFieldType, ExtractFieldNameOptionsOfModel, ExtractFieldOperationTypeForSearch, ExtractTypeFromFieldOfAModel, FieldWithOperationTypeForSearch, ON_DELETE } from './types'; import type { CompareCallback, NewInstanceArgumentsCallback, OptionsCallback, ToStringCallback } from './utils'; import type { AdapterAutoFieldParser, AdapterBigAutoFieldParser, AutoField, BigIntegerField, BooleanField, CharField, DateField, DecimalField, EnumField, TextField, UuidField } from '../..'; import type { DatabaseAdapter } from '../../engine'; /** * This allows us to create a foreign key field on the database. * A foreign key field represents a relation between two models. * So pretty much a model will be related * to another model. * * @example * ```ts * class User extends models.Model<User>() { * fields = { * id: models.AutoField.new(), * firstName: models.CharField.new(), * lastName: models.CharField.new(), * } * } * * const userId = foreignKey({ * relatedTo: User, * toField: 'id', * onDelete: models.fields.ON_DELETE.CASCADE, * relatedName: 'user', * relationName: 'userProfile' * }) * ``` */ export declare function foreignKey<const TRelatedTo extends any | (() => any) | ((_: { create: any; read: any; update: any; }) => any), const TForeignKeyParams extends { toField: ExtractFieldNameOptionsOfModel<TRelatedTo>; onDelete: ON_DELETE; relatedName: string; relationName: string; }>(params: TForeignKeyParams & { relatedTo: TRelatedTo; }): ForeignKeyField<{ create: TRelatedTo extends () => any ? ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'create'> : TRelatedTo extends (_: { create: any; read: any; update: any; }) => any ? TRelatedTo extends (_: { create: infer TCreate; read: any; update: any; }) => any ? TCreate : never : ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'create'>; read: TRelatedTo extends () => any ? ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'read'> : TRelatedTo extends (_: { create: any; read: any; update: any; }) => any ? TRelatedTo extends (_: { create: any; read: infer TRead; update: any; }) => any ? TRead : never : ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'read'>; update: TRelatedTo extends () => any ? ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'update'> : TRelatedTo extends (_: { create: any; read: any; update: any; }) => any ? TRelatedTo extends (_: { create: any; read: any; update: infer TUpdate; }) => any ? TUpdate : never : ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'update'>; }, { unique: boolean; auto: boolean; allowNull: boolean; dbIndex: boolean; isPrimaryKey: boolean; defaultValue: any; underscored: boolean; typeName: string; databaseName: string | undefined; engineInstance: DatabaseAdapter; customAttributes: any; hasDefaultValue: false; relatedTo: TRelatedTo; onDelete: TForeignKeyParams['onDelete']; relatedName: TForeignKeyParams['relatedName']; relationName: TForeignKeyParams['relationName']; toField: TForeignKeyParams['toField']; }, ExtractFieldOperationTypeForSearch<TRelatedTo, TForeignKeyParams['toField']>>; /** * This type of field is special and is supposed to hold foreign key references to another field of another model. * Usually in relational databases like postgres we can have related fields like `user_id` inside of the table `posts`. * What this means that each value in the column `user_id` is one of the ids of the `users` table. This means that we * can use this value to join them together. * * We don't offer stuff like Many-to-many or many-to-one or one-to-one relations by default, the user needs to model it * themselves. This is because we want to keep the library as simple as possible. */ export declare class ForeignKeyField<out TType extends { create: any; read: any; update: any; } = { create: any; read: any; update: any; }, out TDefinitions extends { unique: boolean; auto: boolean; allowNull: boolean; dbIndex: boolean; isPrimaryKey: boolean; defaultValue: any; underscored: boolean; typeName: string; databaseName: string | undefined; engineInstance: DatabaseAdapter; customAttributes: any; relatedTo: any; onDelete: ON_DELETE; relatedName: string; relationName: string; hasDefaultValue: boolean; toField: string; } = { unique: false; auto: false; allowNull: false; dbIndex: false; isPrimaryKey: false; defaultValue: any; underscored: false; typeName: string; hasDefaultValue: false; databaseName: string | undefined; engineInstance: DatabaseAdapter; customAttributes: any; relatedTo: any; onDelete: ON_DELETE; relatedName: string; relationName: string; toField: string; }, out TFieldOperationTypes = FieldWithOperationTypeForSearch<any>> extends Field<TType, TDefinitions, TFieldOperationTypes> { protected $$type: string; protected __typeName: string; protected __relatedToAsString?: string; protected __relatedTo: TDefinitions['relatedTo']; /** Preferably use __relatedTo, this is just to cache the model if `__relatedTo` is either a function or a string */ protected __modelRelatedTo?: { new (...args: unknown[]): any; }; protected __allowedQueryOperations: Set<any>; protected __onDelete: TDefinitions['onDelete']; protected __relatedName: TDefinitions['relatedName']; protected __relationName: TDefinitions['relationName']; protected __toField: TDefinitions['toField']; protected __originalRelatedName?: string; protected __inputParsers: Map<string, (args: import("../..").AdapterFieldParserInputAndOutputArgs<"field" | "auto" | "big-auto" | "big-integer" | "boolean" | "char" | "date" | "decimal" | "enum" | "foreign-key" | "integer" | "text" | "uuid">) => Promise<any>>; protected __outputParsers: Map<string, (args: import("../..").AdapterFieldParserInputAndOutputArgs<"field" | "auto" | "big-auto" | "big-integer" | "boolean" | "char" | "date" | "decimal" | "enum" | "foreign-key" | "integer" | "text" | "uuid">) => Promise<any>>; /** * This is used internally by the engine to compare if the field is equal to another field. * You can override this if you want to extend the ForeignKeyField class. */ protected __compareCallback: (engine: DatabaseAdapter<any, import("../..").AdapterFields, import("../..").AdapterModels<any>, import("../..").AdapterQuery, import("../..").AdapterMigrations>, oldField: Field<any, any, any>, newField: Field<any, any, any>, defaultCompareCallback: CompareCallback) => [boolean, string[]]; /** * This is used internally by the engine for cloning the field to a new instance. * By doing that you are able to get the constructor options of the field when using Field.new(<instanceArguments>) */ protected __newInstanceCallback: (oldField: Field<any, any, any>, defaultNewInstanceArgumentsCallback: NewInstanceArgumentsCallback) => any[]; /** * This is used internally by the engine to convert the field to string. * You can override this if you want to extend the ForeignKeyField class. */ protected __toStringCallback: (engine: DatabaseAdapter<any, import("../..").AdapterFields, import("../..").AdapterModels<any>, import("../..").AdapterQuery, import("../..").AdapterMigrations>, field: Field<any, any, any>, defaultToStringCallback: ToStringCallback, _customParams?: { constructorParams?: string; builderParams?: string; } | undefined) => Promise<{ stringfied: string; customImports: CustomImportsForFieldType[]; }>; protected __getArgumentsCallback: (field: Field<any, any, any>, defaultCallback: typeof import("./utils").defaultGetArgumentsCallback) => { toField: any; relatedTo: string; relationName: any; relatedName: any; onDelete: ON_DELETE; $field: Field<any, any, any>; $model: (ModelType<any, any> & typeof Model & typeof BaseModel) | undefined; typeName: string; fieldName: string; modelName: string; isAuto: boolean; primaryKey: boolean; defaultValue: any; allowNull: boolean; unique: boolean; dbIndex: boolean; databaseName: string | undefined; underscored: boolean; customAttributes: unknown; }; constructor({ onDelete, relatedName, relatedTo, relationName, toField, ...rest }: Pick<TDefinitions, 'relatedTo' | 'onDelete' | 'relatedName' | 'relationName' | 'toField'>); /** * Check if the related model is from the engine instance so we can override the * field creation and change the type of the field to some other field. * * This is useful to manage unmanaged relations. For example, we have a * model in this database and another one in the other database. We can relate both * of them without any issues. What this will do is convert the value of this * field that does not exist on this database to the field it relates to. * * @example * ``` * class Facebook extends models.model<Facebook>() { * fields = { * id: IntegerField.new(), * campaignName: CharField.new() * } * * options = { * managed: false * } * } * * const User = models.initialize('User', { * fields: { * id: AutoField.new(), * firstName: CharField.new(), * facebookId: ForeignKeyField({ * relatedTo: Facebook, * toField: 'id', * relatedName: 'facebookUsers', * relationName: 'facebook' * }) * } * }) * ``` * * Since the `facebookId` field is matching a field in an unmanaged model, the facebookId * field will be translated to `IntegerField` AND NOT * the `ForeignKeyField` * * @param engineInstance - Needs the engine instance to check if the model exists in the engine instance or not. * * @returns - Returns an array where the first item is if the relatedModel is * from the engine instance (false if not) and the field it should change to. */ isRelatedModelFromEngineInstance(engineInstance: DatabaseAdapter): Promise<[boolean, Field<any, any, any>?]>; /** * This is needed for the state. Some ORMs cannot have the same relatedName twice. * What happens is that when recreating the state * we repeat the models from the database. By doing it this way we able to create * a random relatedName so we guarantee that the same related name will not be * used twice inside inside of the engine to two different models. * * This is a logic that should live here and not on the engine itself because the * engine should not be aware of such errors that might occur. We just want * to keep it simple to develop engines. * * @return - Returns a random relatedName if it is a state model, otherwise returns the normal related name. */ protected get _relatedName(): string | undefined; /** * Supposed to be used by library maintainers. * * When you custom create a field, you might want to take advantage of the builder pattern we already support. * This let's you create functions that can be chained together to create a new field. It should be used * alongside the `_setPartialAttributes` method like * * @example * ```ts * const customBigInt = TextField.overrideType< * { create: bigint; read: bigint; update: bigint }, * { * customAttributes: { name: string }; * unique: boolean; * auto: boolean; * allowNull: true; * dbIndex: boolean; * isPrimaryKey: boolean; * defaultValue: any; * typeName: string; * engineInstance: DatabaseAdapter; * } * >({ * typeName: 'CustomBigInt' * }); * * const customBuilder = <TParams extends { name: string }>(params: TParams) => { * const field = customBigInt.new(params); * return field._setNewBuilderMethods({ * test: <TTest extends { age: number }>(param: TTest) => * // This will union the type `string` with what already exists in the field 'create' type * field._setPartialAttributes<{ create: string }, { create: 'union' }>(param) * }); * }; * * // Then your user can use it like: * * const field = customBuilder({ name: 'test' }).test({ age: 2 }); * ``` * * **Important**: `customBuilder` will be used by the end user and you are responsible for documenting it. */ _setNewBuilderMethods<const TFunctions extends InstanceType<any>>(functions?: TFunctions): ForeignKeyField<TType, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue' | 'allowedQueryOperations'>]: TDefinitions[TKey]; } & { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; hasDefaultValue: TDefinitions['hasDefaultValue']; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; }, TFieldOperationTypes> & TFunctions; /** * FOR LIBRARY MAINTAINERS ONLY * * Focused for library maintainers that want to support a custom field type not supported by palmares. * This let's them partially update the custom attributes of the field. By default setCustomAttributes * will override the custom attributes entirely. */ _setPartialAttributes<TNewType extends { create?: any; read?: any; update?: any; }, TActions extends { create?: 'merge' | 'union' | 'replace'; read?: 'merge' | 'union' | 'replace'; update?: 'merge' | 'union' | 'replace'; }, TNewAllowedQueryOperations extends FieldWithOperationTypeForSearch<TActions['read'] extends 'merge' ? TType['read'] & TNewType['read'] : TActions['read'] extends 'union' ? TType['read'] | TNewType['read'] : TActions['read'] extends 'replace' ? TNewType['read'] : TType['read']> = Pick<FieldWithOperationTypeForSearch<TType['read'] | null | undefined>, keyof TFieldOperationTypes extends keyof FieldWithOperationTypeForSearch<TType['read'] | null | undefined> ? keyof TFieldOperationTypes : never>>(): <const TCustomPartialAttributes>(partialCustomAttributes: TCustomPartialAttributes) => ForeignKeyField<{ create: TActions['create'] extends 'merge' ? TType['create'] & TNewType['create'] : TActions['create'] extends 'union' ? TType['create'] | TNewType['create'] : TActions['create'] extends 'replace' ? TNewType['create'] : TType['create']; read: TActions['read'] extends 'merge' ? TType['read'] & TNewType['read'] : TActions['read'] extends 'union' ? TType['read'] | TNewType['read'] : TActions['read'] extends 'replace' ? TNewType['read'] : TType['read']; update: TActions['update'] extends 'merge' ? TType['update'] & TNewType['update'] : TActions['update'] extends 'union' ? TType['update'] | TNewType['update'] : TActions['update'] extends 'replace' ? TNewType['update'] : TType['update']; }, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes'>]: TDefinitions[TKey]; } & { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; hasDefaultValue: TDefinitions['hasDefaultValue']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes'] & TCustomPartialAttributes; }, TNewAllowedQueryOperations>; setCustomAttributes<const TCustomAttributes extends TDefinitions['relatedTo'] extends { new (...args: any): { fields: infer TFields; }; } | (() => { new (...args: any): { fields: infer TFields; }; }) | ((_: any) => { new (...args: any): { fields: infer TFields; }; }) ? TDefinitions['toField'] extends keyof TFields ? TFields[TDefinitions['toField']] extends Field<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['fieldsParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends AutoField<any, any, any> ? TDefinitions['engineInstance']['fields']['autoFieldParser'] extends AdapterAutoFieldParser ? Parameters<TDefinitions['engineInstance']['fields']['autoFieldParser']['translate']>[0]['customAttributes'] : Parameters<TDefinitions['engineInstance']['fields']['integerFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends BigAutoField<any, any, any> ? TDefinitions['engineInstance']['fields']['bigAutoFieldParser'] extends AdapterBigAutoFieldParser ? Parameters<TDefinitions['engineInstance']['fields']['bigAutoFieldParser']['translate']>[0]['customAttributes'] : Parameters<TDefinitions['engineInstance']['fields']['bigIntegerFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends IntegerField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['integerFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends BigIntegerField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['bigIntegerFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends DecimalField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['decimalFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends BooleanField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['booleanFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends CharField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['charFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends TextField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['textFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends EnumField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['enumFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends DateField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['dateFieldParser']['translate']>[0]['customAttributes'] : TFields[TDefinitions['toField']] extends UuidField<any, any, any> ? Parameters<TDefinitions['engineInstance']['fields']['uuidFieldParser']['translate']>[0]['customAttributes'] : Parameters<TDefinitions['engineInstance']['fields']['fieldsParser']['translate']>[0]['customAttributes'] : any : any>(customAttributes: TCustomAttributes): ForeignKeyField<TType, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue' | 'allowedQueryOperations'>]: TDefinitions[TKey]; } & { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; hasDefaultValue: TDefinitions['hasDefaultValue']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; customAttributes: TCustomAttributes; }, TFieldOperationTypes>; unique<TUnique extends boolean = true>(isUnique?: TUnique): ForeignKeyField<TType, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue'>]: TDefinitions[TKey]; } & { unique: TUnique extends false ? false : true; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; hasDefaultValue: TDefinitions['hasDefaultValue']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; }, TFieldOperationTypes>; allowNull<TNull extends boolean = true>(isNull?: TNull): ForeignKeyField<{ create: TType['create'] | null | undefined; read: TType['read'] | null | undefined; update: TType['update'] | null | undefined; }, { unique: TDefinitions['unique']; allowNull: TNull extends false ? false : true; dbIndex: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; hasDefaultValue: TDefinitions['hasDefaultValue']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; } & { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue'>]: TDefinitions[TKey]; }, Pick<FieldWithOperationTypeForSearch<TType['read'] | null | undefined>, keyof TFieldOperationTypes extends keyof FieldWithOperationTypeForSearch<TType['read'] | null | undefined> ? keyof TFieldOperationTypes : never>>; /** * This method is used to create an index on the database for this field. */ dbIndex<TDbIndex extends boolean = true>(isDbIndex?: TDbIndex): ForeignKeyField<TType, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue'>]: TDefinitions[TKey]; } & { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDbIndex extends false ? false : true; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; defaultValue: TDefinitions['defaultValue']; hasDefaultValue: TDefinitions['hasDefaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; }, TFieldOperationTypes>; underscored<TUnderscored extends boolean = true>(isUnderscored?: TUnderscored): ForeignKeyField<TType, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue' | 'allowedQueryOperations'>]: TDefinitions[TKey]; } & { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; underscored: TUnderscored extends false ? false : true; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; defaultValue: TDefinitions['defaultValue']; hasDefaultValue: TDefinitions['hasDefaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; }, TFieldOperationTypes>; primaryKey<TIsPrimaryKey extends boolean = true>(isPrimaryKey?: TIsPrimaryKey): ForeignKeyField<TType, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue' | 'allowedQueryOperations'>]: TDefinitions[TKey]; } & { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TIsPrimaryKey extends false ? false : true; auto: TDefinitions['auto']; defaultValue: TDefinitions['defaultValue']; hasDefaultValue: TDefinitions['hasDefaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; }, TFieldOperationTypes>; auto<TIsAuto extends boolean = true>(isAuto?: TIsAuto): ForeignKeyField<{ create: TType['create'] | undefined; read: TType['read']; update: TType['update'] | undefined; }, { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TIsAuto extends false ? false : true; hasDefaultValue: TDefinitions['hasDefaultValue']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; } & { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue' | 'allowedQueryOperations'>]: TDefinitions[TKey]; }, TFieldOperationTypes>; default<TDefault extends TType['create']>(defaultValue: TDefault): ForeignKeyField<{ create: TType['create'] | TDefault | undefined; read: TType['read']; update: TType['update'] | undefined; }, { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; defaultValue: TDefault; hasDefaultValue: true; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; } & { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue' | 'allowedQueryOperations'>]: TDefinitions[TKey]; }, TFieldOperationTypes>; databaseName<TDatabaseName extends string>(databaseName: TDatabaseName): ForeignKeyField<TType, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue' | 'allowedQueryOperations'>]: TDefinitions[TKey]; } & { unique: TDefinitions['unique']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TDefinitions['isPrimaryKey']; auto: TDefinitions['auto']; defaultValue: TDefinitions['defaultValue']; hasDefaultValue: TDefinitions['hasDefaultValue']; databaseName: TDatabaseName; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; relatedTo: TDefinitions['relatedTo']; relationName: TDefinitions['relationName']; relatedName: TDefinitions['relatedName']; onDelete: TDefinitions['onDelete']; toField: TDefinitions['toField']; }, TFieldOperationTypes>; /** * This method can be used to override the type of a field. This is useful for library * maintainers that want to support the field type but the default type provided by palmares * is not the one that the user want to use. * * ### Note * * Your library should provide documentation of the fields that are supported. */ static _overrideType<const TDefinitions extends { customAttributes: any; unique: boolean; auto: boolean; allowNull: boolean; dbIndex: boolean; isPrimaryKey: boolean; defaultValue: any; typeName: string; engineInstance: DatabaseAdapter; } & Record<string, any>, const _TFieldOperationTypes extends FieldWithOperationTypeForSearch<any> | Pick<FieldWithOperationTypeForSearch<any>, any>>(args: { typeName: string; toStringCallback?: ToStringCallback; compareCallback?: CompareCallback; optionsCallback?: OptionsCallback; newInstanceCallback?: NewInstanceArgumentsCallback; allowedQueryOperations?: (keyof TDefinitions['allowedQueryOperations'])[]; customImports?: CustomImportsForFieldType[]; }): TDefinitions['customAttributes'] extends undefined ? { new: <const TRelatedTo extends any | (() => any) | ((_: { create: any; read: any; update: any; }) => any), const TForeignKeyParams extends { toField: ExtractFieldNameOptionsOfModel<TRelatedTo>; onDelete: ON_DELETE; relatedName: string; relationName: string; }>(params: TForeignKeyParams & { relatedTo: TRelatedTo; }) => ForeignKeyField<{ create: ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'create'>; read: ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'read'>; update: ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'update'>; }, { unique: TDefinitions['unique']; auto: TDefinitions['auto']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; isPrimaryKey: TDefinitions['isPrimaryKey']; defaultValue: TDefinitions['defaultValue']; underscored: boolean; databaseName: string | undefined; hasDefaultValue: TDefinitions['hasDefaultValue']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; typeName: TDefinitions['typeName']; relatedTo: TRelatedTo; onDelete: TForeignKeyParams['onDelete']; relatedName: TForeignKeyParams['relatedName']; relationName: TForeignKeyParams['relationName']; toField: TForeignKeyParams['toField']; }, ExtractFieldOperationTypeForSearch<TRelatedTo, TForeignKeyParams['toField']>>; } : { new: <const TRelatedTo extends any | (() => any) | ((_: { create: any; read: any; update: any; }) => any), const TForeignKeyParams extends { toField: ExtractFieldNameOptionsOfModel<TRelatedTo>; onDelete: ON_DELETE; relatedName: string; relationName: string; }>(params: TForeignKeyParams & { relatedTo: TRelatedTo; } & TDefinitions['customAttributes']) => ForeignKeyField<{ create: ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'create'>; read: ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'read'>; update: ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'update'>; }, { unique: TDefinitions['unique']; auto: TDefinitions['auto']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; isPrimaryKey: TDefinitions['isPrimaryKey']; defaultValue: TDefinitions['defaultValue']; underscored: boolean; hasDefaultValue: TDefinitions['hasDefaultValue']; databaseName: string | undefined; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; typeName: TDefinitions['typeName']; relatedTo: TRelatedTo; onDelete: TForeignKeyParams['onDelete']; relatedName: TForeignKeyParams['relatedName']; relationName: TForeignKeyParams['relationName']; toField: TForeignKeyParams['toField']; }, ExtractFieldOperationTypeForSearch<TRelatedTo, TForeignKeyParams['toField']>>; }; /** * This is quite confusing, i know. * * This method is used to keep track of the relation on models. I won't go too far. Let's use an example: * * @example ```typescript * const User = models.initialize('User', { * fields: { * id: AutoField.new(), * name: CharField.new(), * email: CharField.new(), * profileId: ForeignKeyField.new({ * relatedTo: 'Profile', * toField: 'id', * relatedName: 'profileOfUsers', * relationName: 'profile', * onDelete: 'CASCADE' * }) * } * }); * * const Profile = models.initialize('Profile', { * fields: { * id: AutoField.new(), * name: CharField.new(), * } * }); * ``` * * On this example, the `profileId` field on the `User` model is related to the `Profile` model. * __directlyRelatedTo is an object that keeps track of the models that are directly related to the model. * In this case, the `User` model is directly related to the `Profile` model. * This means we should update the `User` model to keep track of the `Profile` model. * * __indirectlyRelatedTo is an object that keeps track of the models that are indirectly related to the model. * In this case, the `Profile` model is indirectly related to the `User` model. * This means we should update the `Profile` model to keep track of the `User` model. * * __associations is an object that keeps track of the fields that are related to the model. It's two way. * So the `Profile` model keeps track of all it's associations with other models. Wether Profile defined the * relation or not. * * With this configuration, no matter which model we have "in hands" we can always keep track of all of the relations. * It's confusing because at the end of the day it'll look like a complex graph. */ protected __attachRelationsToModel(_field: ForeignKeyField<any, any, any>, fieldName: string, modelOfField: ModelType<any, any> & typeof Model & typeof BaseModel, relatedModel: string | (ModelType<any, any> & typeof Model & typeof BaseModel)): void; protected __init(fieldName: string, model: ModelType<any, any> & typeof Model & typeof BaseModel): void; static new<const TRelatedTo extends any | (() => any) | ((_: { create: any; read: any; update: any; }) => any), const TForeignKeyParams extends { toField: ExtractFieldNameOptionsOfModel<TRelatedTo>; onDelete: ON_DELETE; relatedName: string; relationName: string; }>(params: TForeignKeyParams & { relatedTo: TRelatedTo; }): ForeignKeyField<{ create: TRelatedTo extends () => any ? ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'create'> : TRelatedTo extends (_: { create: any; read: any; update: any; }) => any ? TRelatedTo extends (_: { create: infer TCreate; read: any; update: any; }) => any ? TCreate : never : ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'create'>; read: TRelatedTo extends () => any ? ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'read'> : TRelatedTo extends (_: { create: any; read: any; update: any; }) => any ? TRelatedTo extends (_: { create: any; read: infer TRead; update: any; }) => any ? TRead : never : ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'read'>; update: TRelatedTo extends () => any ? ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'update'> : TRelatedTo extends (_: { create: any; read: any; update: any; }) => any ? TRelatedTo extends (_: { create: any; read: any; update: infer TUpdate; }) => any ? TUpdate : never : ExtractTypeFromFieldOfAModel<TRelatedTo, TForeignKeyParams['toField'], 'update'>; }, { onDelete: TForeignKeyParams['onDelete']; relatedName: TForeignKeyParams['relatedName']; relationName: TForeignKeyParams['relationName']; toField: TForeignKeyParams['toField']; unique: false; auto: false; allowNull: false; dbIndex: false; isPrimaryKey: false; defaultValue: any; hasDefaultValue: false; underscored: true; typeName: string; databaseName: string | undefined; engineInstance: DatabaseAdapter; customAttributes: any; relatedTo: TRelatedTo; }, ExtractFieldOperationTypeForSearch<TRelatedTo, TForeignKeyParams['toField']>>; } //# sourceMappingURL=foreign-key.d.ts.map