@palmares/databases
Version:
Add support for working with databases with palmares framework
777 lines • 41.7 kB
TypeScript
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