import type Collection from "./collection.js"; import type Context from "../context.js"; import type { ActionName } from "../action.js"; import type { QueryStage } from "../datastore/query-stage.js"; import type { App } from "../app/app.js"; import { ItemListResult } from "./item-list-result.js"; import { OpenApiTypes } from "../schemas/open-api-types.js"; import type CollectionItem from "./collection-item.js"; export type Depromisify = T extends Promise ? V : T; export type ExtractParams> = Parameters[0]; export type ExtractFilterParams> = Parameters[1]; export type ValidationResult = { valid: boolean; reason?: string; }; export type ExtractFieldDecoded> = F extends Field ? T : never; export type ExtractFieldInput> = F extends Field ? T : never; export type ExtractFieldStorage> = F extends Field ? T : never; export type TransitionChecker = (params: { context: Context; old_value: DecodedType | undefined; new_value: DecodedType; }) => Promise; export type RequiredField = Field & { required: true; }; /** The field class itself. Stores information on the field name, and * methods that decide waht values are valid and how they are * stored. The {@link Field} class describes a type of field in * general (like "Text" and "Number"), and a {@link Field} instance * describes one particular field in a collection (like "name" and * "age"). * * Extend this class to create fields with custom behavior. * * **The recommended way to create a field for a collection is {@link * FieldDefinitionHelper}, as it performs type checking of the * field params.** * * Some of the most useful field types include: * * {@link Boolean} * * {@link DateField | Date} * * {@link Datetime} * * {@link Email} * * {@link Enum} * * {@link FileField | Field} * * {@link Float} * * {@link Html} * * {@link Image} * * {@link Int} * * {@link SingleReference} * * {@link Text} */ export declare abstract class Field { /** the name of the field */ name: string; /** the app that the field exists in * @internal */ app: App; /** The display hints specified for this field */ display_hints: any; /** Whether or not the field handles large data * @todo: see if there's any viability in storing this */ handles_large_data: boolean; /** The collection this field is attached to */ collection: Collection; /** Whether or not this field should always have a value. Creating * a resource with a value missing for a required field will throw * an error */ required: boolean; transitionChecker: TransitionChecker; builtinTransitionChecker(_context: Context, _old_value: DecodedType | undefined, _new_value: DecodedType): Promise; setTransitionChecker(checker: TransitionChecker): this; /** Sets the collection @internal */ setCollection(collection: Collection): void; setRequired(required: boolean): RequiredField; /** Sets the name @internal */ setName(name: string): void; /** This method is used to set and process the params upon the * field's creation when the app starts up. The type of argument * of this method determines type checking that's performed by * @{link FieldDefinitionHelper}. */ setParams(_: any): void; /** Return a summary of this field */ getSpecification(): { name: string; type: string; display_hints: any; }; /** Whether or not this field should have a dedicated index in the * database */ hasIndex(): Promise; /** Value path is where inside a single record should the DB look * for the field's value when filtering resources. Some fields use * complex objects for storage and overwrite this method, and * thanks to that they don't have to reimplement {@link * Field.getAggregationStages} */ getValuePath(): Promise; abstract typeName: string; abstract open_api_type: OpenApiTypes; getOpenApiSchema(context: Context): Promise>; protected abstract isProperValue(context: Context, new_value: unknown, old_value: unknown, new_value_blessing_token: symbol | null, item: CollectionItem | undefined): Promise; checkValue(context: Context, new_value: unknown, old_value: unknown, new_value_blessing_token: symbol | null, item: CollectionItem | undefined): Promise; /** Decides how to store the given value in the database, based on * the context and previous value of the field */ encode(_: Context, value: InputType | null, __?: any): Promise; /** Reverse to the {@link Field.encode} function. Takes what's inside the database and returns the decoded value */ decode(context: Context, storage_value: StorageType, old_value: any, _is_http_api_request?: boolean): Promise; /** Generates a mongo query based on the filter value */ getMatchQueryValue(context: Context, filter: any): Promise; getMatchQuery(context: Context, filter: any, value_path: string): Promise; /** Whether or not the db should create a fulltext index on this field */ fullTextSearchEnabled(): Promise; /** Whether or not a field has a default value - that is, a value * given to the field if no value is provided */ hasDefaultValue(): boolean; /** The default value that will be assigned to the field if no * value is given */ getDefaultValue(_: Context): Promise; /** Whether or not any of the methods of the field depend on the * previous value of the field */ isOldValueSensitive(_: ActionName): boolean; /** Used to signal a positive decision from within {@link * Field.isProperValue}. */ static valid(): ValidationResult; /** Used to signal a negative decition from within {@link * Field.isProperValue}. */ static invalid(reason: string): ValidationResult; /** Runs when the app is being started. Hooks can be set up within * this function */ init(app: App, collection: Collection): Promise; getAttachments(_context: Context, _values: any[], // this method gets called once for multiple resources, to limit the number of queries. Field values of all the resources are passed in this array attachment_options: any): Promise>; /** Creates parts of a Mongo Pipieline that will be used to filter * the items when listing items of a collection */ getAggregationStages(context: Context, field_filter: unknown): Promise; getPostgreSqlFieldDefinitions(): string[]; getPostgreSqlConstraintFieldDefinitions(): string[]; getPostgreSqlShouldFieldBeCreatedInitially(): boolean; getAttachmentIDs(_value: DecodedType): string[]; }