UNPKG

@palmares/databases

Version:

Add support for working with databases with palmares framework

458 lines 24.3 kB
import { defaultCompareCallback, defaultGetArgumentsCallback, defaultNewInstanceArgumentsCallback, defaultOptionsCallback, defaultToStringCallback } from './utils'; import { type BaseModel, type Model, type ModelType } from '../model'; import type { CustomImportsForFieldType, FieldWithOperationTypeForSearch } from './types'; import type { CompareCallback, NewInstanceArgumentsCallback, OptionsCallback, ToStringCallback } from './utils'; import type { DatabaseAdapter } from '../../engine'; /** * This is the default field of the model, every other field type should override this * one but this one SHOULDN't be called directly. * Generally we do not offer any translation to this type of field. */ export declare class Field<in out TType extends { create: any; read: any; update: any; } = { create: any; read: any; update: any; }, in out TDefinitions extends { unique: boolean; auto: boolean; allowNull: boolean; dbIndex: boolean; isPrimaryKey: boolean; hasDefaultValue: boolean; defaultValue: any; underscored: boolean; typeName: string; databaseName: string | undefined; engineInstance: DatabaseAdapter; customAttributes: any; } & Record<string, any> = { unique: false; allowNull: false; dbIndex: false; underscored: true; hasDefaultValue: false; isPrimaryKey: false; auto: false; defaultValue: undefined; typeName: string; databaseName: undefined; engineInstance: DatabaseAdapter; customAttributes: any; }, in out TFieldOperationTypes = FieldWithOperationTypeForSearch<any>> { protected $$type: string; protected __typeName: string; protected __isAuto: TDefinitions['auto']; protected __hasDefaultValue: boolean; protected __primaryKey: TDefinitions['isPrimaryKey']; protected __defaultValue: TDefinitions['defaultValue']; protected __allowNull: TDefinitions['allowNull']; protected __unique: TDefinitions['unique']; protected __dbIndex: TDefinitions['dbIndex']; protected __databaseName: TDefinitions['databaseName']; protected __underscored: TDefinitions['underscored']; protected __customAttributes: Parameters<TDefinitions['engineInstance']['fields']['fieldsParser']['translate']>[0]['customAttributes']; protected __allowedQueryOperations: Set<keyof Required<TFieldOperationTypes>>; protected __toStringCallback: typeof defaultToStringCallback; protected __compareCallback: typeof defaultCompareCallback; protected __optionsCallback: typeof defaultOptionsCallback; protected __newInstanceCallback: typeof defaultNewInstanceArgumentsCallback; protected __customImports: CustomImportsForFieldType[]; protected __getArgumentsCallback: typeof defaultGetArgumentsCallback; 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>) | null>; 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>) | null>; protected __model?: ModelType<any, any> & typeof Model & typeof BaseModel; protected __fieldName: string; constructor(..._args: any[]); /** * 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): Field<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']> = 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']>>(): <const TCustomPartialAttributes>(partialCustomAttributes: TCustomPartialAttributes) => Field<{ 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' | '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']; customAttributes: TDefinitions['customAttributes'] & TCustomPartialAttributes; }, TNewAllowedQueryOperations>; setCustomAttributes<const TCustomAttributes extends Parameters<TDefinitions['engineInstance']['fields']['fieldsParser']['translate']>[0]['customAttributes']>(customAttributes: TCustomAttributes): Field<TType, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'hasDefaultValue' | 'allowedQueryOperations' | '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: TCustomAttributes; }, TFieldOperationTypes>; unique<TUnique extends boolean = true>(isUnique?: TUnique): Field<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']; }, TFieldOperationTypes>; allowNull<TNull extends boolean = true>(isNull?: TNull): Field<{ create: TType['create'] | null | undefined; read: TType['read'] | null | undefined; update: TType['update'] | null | undefined; }, { [TKey in Exclude<keyof TDefinitions, 'underscored' | 'allowNull' | 'dbIndex' | 'unique' | 'isPrimaryKey' | 'auto' | 'defaultValue' | 'databaseName' | 'typeName' | 'engineInstance' | 'customAttributes' | 'hasDefaultValue'>]: TDefinitions[TKey]; } & { 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']; }, FieldWithOperationTypeForSearch<TType['read'] | null>>; /** * This method is used to create an index on the database for this field. */ dbIndex<TDbIndex extends boolean = true>(dbIndex?: TDbIndex): Field<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']; hasDefaultValue: TDefinitions['hasDefaultValue']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; }, TFieldOperationTypes>; underscored<TUnderscored extends boolean = true>(isUnderscored?: TUnderscored): Field<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']; hasDefaultValue: TDefinitions['hasDefaultValue']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; }, TFieldOperationTypes>; primaryKey<TIsPrimaryKey extends boolean = true>(isPrimaryKey?: TIsPrimaryKey): Field<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: TDefinitions['dbIndex']; underscored: TDefinitions['underscored']; isPrimaryKey: TIsPrimaryKey extends false ? false : true; auto: TDefinitions['auto']; hasDefaultValue: TDefinitions['hasDefaultValue']; defaultValue: TDefinitions['defaultValue']; databaseName: TDefinitions['databaseName']; typeName: TDefinitions['typeName']; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; }, TFieldOperationTypes>; auto<TIsAuto extends boolean = true>(isAuto?: TIsAuto): Field<{ create: TType['create'] | undefined; read: TType['read']; update: TType['update'] | undefined; }, { [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: 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']; }, TFieldOperationTypes>; default<TDefault extends TType['create']>(defaultValue: TDefault): Field<{ create: TType['create'] | TDefault | undefined; read: TType['read']; update: TType['update'] | undefined; }, { [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: 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']; }, TFieldOperationTypes>; databaseName<TDatabaseName extends string>(databaseName: TDatabaseName): Field<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: 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']; }, 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. * * @example * ```ts * const MyCustomDatabaseAutoField = AutoField.overrideType<{ input: string; output: string }>(); * * // then the user can use as normal: * * const autoField = MyCustomDatabaseAutoField.new(); * * // now the type inferred for the field will be a string instead of a number. * ``` * * ### Note * * Your library should provide documentation of the fields that are supported. */ static _overrideType<const TNewType extends { create: any; update: any; read: any; }, 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; allowedQueryOperations?: (keyof TFieldOperationTypes)[]; newInstanceCallback?: NewInstanceArgumentsCallback; customImports?: CustomImportsForFieldType[]; }): TDefinitions['customAttributes'] extends undefined ? { new: (...args: any[]) => Field<TNewType, { unique: TDefinitions['unique']; auto: TDefinitions['auto']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; isPrimaryKey: TDefinitions['isPrimaryKey']; defaultValue: TDefinitions['defaultValue']; hasDefaultValue: boolean; underscored: boolean; databaseName: string | undefined; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; typeName: TDefinitions['typeName']; }, TFieldOperationTypes>; } : { new: (params: TDefinitions['customAttributes']) => Field<TNewType, { unique: TDefinitions['unique']; auto: TDefinitions['auto']; allowNull: TDefinitions['allowNull']; dbIndex: TDefinitions['dbIndex']; isPrimaryKey: TDefinitions['isPrimaryKey']; defaultValue: TDefinitions['defaultValue']; hasDefaultValue: boolean; underscored: boolean; databaseName: string | undefined; engineInstance: TDefinitions['engineInstance']; customAttributes: TDefinitions['customAttributes']; typeName: TDefinitions['typeName']; }, TFieldOperationTypes>; }; /** * This method enables the framework to automatically import the files when generating the migrations. * * This is generally useful for custom field types. * * @return - Returns a list of packages that we want to import in the migration file. */ protected __getCustomImports(): Promise<CustomImportsForFieldType[]>; protected __init(fieldName: string, model: ModelType<any, any> & typeof Model & typeof BaseModel): void; /** * Gets all of the arguments to pass to the field during migration, translation, etc. * * Everything in the field is protected, this way end users don't access the internal implementation. */ protected __getArguments(): ReturnType<Field<any, any, any>['__getArgumentsCallback']>; protected __toString(engine: DatabaseAdapter): Promise<ReturnType<typeof defaultToStringCallback>>; /** * Used for comparing one field with the other so we are able to tell if they are different or not. * * This is obligatory to add if you create any custom fields. * * For custom fields you will call this super method before continuing, we first check if they are the same type. * * @param field - The field to compare to. * * @return - Returns true if the fields are equal and false otherwise */ protected __compare(engine: DatabaseAdapter, field: Field<any, any, any>): [boolean, string[]]; /** * Used for cloning the field to a new field. * * @param oldField - The field to clone. If not provided it will use the current field. * * @returns - Returns the cloned field. */ protected __clone(oldField: Field<any, any, any>, args?: { newInstanceOverrideCallback?: (args: any[]) => any[]; optionsOverrideCallback?: Partial<Record<keyof ReturnType<Field['__getArguments']>, (oldValue: any) => any>>; }): Field<any, any, any>; /** * You should not use this method directly, it is used internally by the framework. * * This method is used to create a new instance of the field with the same options as the old field. */ static new<TType extends { create: any; read: any; update: any; }, 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; hasDefaultValue: boolean; } & Record<string, any>, TFieldOperationTypes extends FieldWithOperationTypeForSearch<any>>(..._args: any[]): Field<TType, TDefinitions, TFieldOperationTypes>; } //# sourceMappingURL=field.d.ts.map