import { Arrayable, DataValue, Maybe, ModelInstance, ModelType, DataDescription, PrimaryKeyType, MinimalModelDefinition, PropertyConfig, ValidatorContext, ToObjectResult, ModelInstanceFetcher, ModelFactoryOptions, CreateParams, PropertyType, CanBeNullableType } from '../types.js'; /** * Equals symbols for doing database matching */ export declare enum EqualitySymbol { eq = "=", lt = "<", lte = "<=", gt = ">", gte = ">=", ne = "!=" } /** * The value types that map to database types. */ export declare enum DatastoreValueType { string = "string", number = "number", date = "date", object = "object", boolean = "boolean" } /** * A list of allowable equality symbols. */ export declare const AllowableEqualitySymbols: EqualitySymbol[]; /** * A function that can save. */ type SaveMethod = ( /** * An instance to save */ instance: ModelInstance) => Promise>; /** * A method that can delete */ type DeleteMethod = (instance: ModelInstance) => Promise; /** * A function that allows overriding the save functionality for a specific model. */ export type SaveOverride = (existingSave: SaveMethod, instance: ModelInstance) => Promise>; /** * A function that allows overriding the delete functionality for a specific model. */ export type DeleteOverride = (existingDelete: DeleteMethod, instance: ModelInstance) => Promise; /** * A result of an ORM search. * @interface */ export type OrmSearchResult = Readonly<{ /** * A list of instances */ instances: readonly OrmModelInstance[]; /** * An optional page value. The exact structure is provided by the datastore itself. */ page?: any; }>; /** * ORM based ModelFactory extensions. * @interface */ export type OrmModelFactoryOptionsExtensions = Readonly<{ /** * Optional: The save function to override. */ save?: SaveOverride; /** * Optional: The delete function to override. */ delete?: DeleteOverride; }>; /** * Extensions to the Model type * @interface */ export type OrmModelExtensions = Readonly<{ /** * Save the model * @param instance - The instance to save. */ save: (instance: OrmModelInstance) => Promise>; /** * Deletes an instance by its id. * @param id - The id to delete */ delete: (id: PrimaryKeyType) => Promise; /** * Attempts to get an instance by its id * @param primaryKey */ retrieve: (primaryKey: PrimaryKeyType) => Promise>>; /** * Searches instances by the provided search query * @param query */ search: (query: OrmSearch) => Promise>>; /** * Searches for a single instance with the given query. * @param query */ searchOne: (query: Omit) => Promise | undefined>; /** * Creates and saves an instance. An optimization in some databases * @param query */ createAndSave: (data: OrmModelInstance) => Promise>; /** * Inserts multiple objects at once. Can often see great optimizations in some databases. * @param query */ bulkInsert: (instances: readonly OrmModelInstance[]) => Promise; /** * Deletes multiple instances at once. * @param instances */ bulkDelete: (keysOrInstances: readonly OrmModelInstance[] | readonly PrimaryKeyType[]) => Promise; /** * Counts the number of models saved in the database. */ count: () => Promise; }>; /** * Instance overrides that give it ORM functions. * @interface */ export type OrmModelInstanceExtensions = Readonly<{ /** * Save this model. */ save: () => Promise>; /** * Delete this model. */ delete: () => Promise; }>; /** * ORM based configurations for a model. * @interface */ export type OrmModelConfigurations = Readonly<{ /** * Validator that there is only a single value in the datastore that has the properties given. * Example: * ["name", "text"] * This will make sure that there can only be a single row in the database that has a unique combination of name and text. */ uniqueTogether?: readonly string[]; /** * Optional property name that stores the model's expiry as a Unix timestamp in minutes. * Datastores can use this to prune expired records. */ ttlPropertyName?: string; }>; /** * A minimum orm model definition * @interface */ export type MinimumOrmModelDefinition = MinimalModelDefinition & OrmModelConfigurations; /** * A model factory that produces ORM based models. * */ export type OrmModelFactory = ( /** * The model definition for the model */ modelDef: MinimumOrmModelDefinition, /** * Additional options for this model. */ options?: ModelFactoryOptions & TModelOptionsExtensions>) => OrmModel; /** * A search result from a datastore * @interface */ export type DatastoreSearchResult = Readonly<{ /** * An array of objects that represent the data from the datastore. */ instances: readonly ToObjectResult[]; /** * Any pagination information. */ page?: any; }>; /** * A model that has ORM functions attached. * @interface */ export type OrmModel = ModelType, OrmModelInstanceExtensions> & { getModelDefinition: () => ReturnType['getModelDefinition']> & OrmModelConfigurations; }; /** * A Model Instance with ORM functions attached. * @interface */ export type OrmModelInstance = ModelInstance, OrmModelInstanceExtensions>; /** * An interface that describes a datastore. By implementing this interface, databases can be swapped. * @interface */ export type DatastoreAdapter = Readonly<{ /** * Saving a model. * @param instance */ save: (instance: ModelInstance) => Promise>; /** * Deleting an instance. * @param model * @param id */ delete: (model: OrmModel, id: PrimaryKeyType) => Promise; /** * Attempts to retrieves an instance. * @param model * @param primaryKey */ retrieve: (model: OrmModel, primaryKey: PrimaryKeyType) => Promise>>; /** * Searches for instances by a query. * @param model * @param query */ search: (model: OrmModel, query: OrmSearch) => Promise>; /** * Optional: An optimized bulkInsert function. (Highly recommended) * @param model * @param instances */ bulkInsert?: (model: OrmModel, instances: readonly ModelInstance[]) => Promise; /** * Optional: An optimized bulkDelete function. (Highly recommended) * @param model * @param keysOrInstances */ bulkDelete?: (model: OrmModel, keys: readonly PrimaryKeyType[]) => Promise; /** * Optional: An optimized createAndSave function. * @param instance */ createAndSave?: (instance: ModelInstance) => Promise>; /** * Optional: An optimized counting function. Highly recommended. * @param model */ count?: (model: OrmModel) => Promise; }>; /** * A search that describes a property and its value. * @interface */ export type PropertyQuery = Readonly<{ /** * Distinguishes this as a property query. */ type: 'property'; /** * The property's key */ key: string; /** * The value to search for. */ value: any; /** * The type of database value. */ valueType: DatastoreValueType; /** * How the value should be compared. */ equalitySymbol: EqualitySymbol; /** * Options for additional matching. */ options: PropertyOptions; }>; /** * A property search for a string value. */ export type StringPropertyQuery = PropertyQuery & { valueType: DatastoreValueType.string; equalitySymbol: EqualitySymbol.eq | EqualitySymbol.ne; options: PropertyOptions; }; /** * A search that looks at dated objects after the given date. * @interface */ export type DatesAfterQuery = Readonly<{ /** * Distinguishes this query */ type: 'datesAfter'; /** * The property's key */ key: string; /** * The date value being examined. */ date: string; /** * The database type. */ valueType: DatastoreValueType; /** * Options for additional searching */ options: { /** * Should this search be equalsTo as well as after? */ equalToAndAfter: boolean; }; }>; /** * A search query that looks at dates before the given date. * @interface */ export type DatesBeforeQuery = Readonly<{ /** * Distinguishes this query */ type: 'datesBefore'; /** * The property's key. */ key: string; /** * The date value being examined. */ date: string; /** * The database value type. */ valueType: DatastoreValueType; /** * Options for additional searching */ options: { /** * Should this search be equalsTo as well as before? */ equalToAndBefore: boolean; }; }>; /** * Additional configurations for ORM based properties. * @interface */ export type OrmPropertyConfig> = PropertyConfig & Readonly<{ /** * Validator: Checks to make sure that there is only one instance in a datastore that has this property's value. * NOTE: The value is a property KEY. Not true or false. */ unique?: string; }>; /** * Additional context that is provided for ORM based instance. * @interface */ export type OrmValidatorContext = Readonly<{ /** * IMPORTANT: Sometimes you do not want to do any ORM based validation because of speed. * This disables any orm based validation, and only runs non-orm validation. */ noOrmValidation?: boolean; }> & ValidatorContext; /** * Options for a property query. */ export type PropertyOptions = { /** * Is this a case sensitive search? */ caseSensitive?: boolean; /** * Is the value a startsWith query? */ startsWith?: boolean; /** * Is the value a endsWith query? */ endsWith?: boolean; /** * Is the value a includes query? */ includes?: boolean; /** * The type of value */ type?: DatastoreValueType; /** * An equality symbol. */ equalitySymbol?: EqualitySymbol; }; /** * An object that has both an Orm Model Factory (that can make Orm Models) as well as a loaded fetcher * that can retrieve referenced models as needed. See {@see "functional-models.ModelReference"} * @interface */ export type Orm = { /** * A model factory that can produce {@link OrmModel} */ Model: OrmModelFactory; /** * A fetcher for use with Model References */ fetcher: ModelInstanceFetcher; }; /** * The sort order. */ export declare enum SortOrder { asc = "asc", dsc = "dsc" } /** * The number of instances to receive back from a query. */ export type MaxMatchStatement = number; /** * Defines how a sort should happen. Which column and what order. * @interface */ export type SortStatement = { /** * The property's key/name. Also could be a "column" */ key: string; /** * Ascending or Descending sort. */ order: SortOrder; }; /** * Pagination can be anything. */ export type PaginationQuery = any; /** * A query to a search function. * @interface */ export type OrmSearch = { /** * Optional: A number of max records to return. */ take?: MaxMatchStatement; /** * Optional: Sorting. */ sort?: SortStatement; /** * Optional: Pagination information */ page?: PaginationQuery; /** * Optional: Querying tokens. */ query: readonly QueryTokens[]; }; /** * Statements that make up the meat of QueryTokens */ export type Query = PropertyQuery | DatesAfterQuery | DatesBeforeQuery | StringPropertyQuery; /** * A token type that links two queries together. */ export type BooleanQuery = 'AND' | 'OR'; /** * A generic structure of querys. */ export type QueryTokens = readonly QueryTokens[][] | readonly QueryTokens[] | BooleanQuery | Query; /** * Builder functions that are not property related. * @interface */ type NonQueryBuilder = Readonly<{ /** * Creates a pagination. * @param value - Can be anything */ pagination: (value: any) => BuilderV2Link & InnerBuilderV2; /** * Creates a sort. * @param key - The key to sort on * @param sortOrder - The order to sort by. Defaults to ascending. */ sort: (key: string, sortOrder?: SortOrder) => BuilderV2Link & InnerBuilderV2; /** * Maximum number of elements to return. * @param count - The count */ take: (count: number) => BuilderV2Link & InnerBuilderV2; /** * Compiles the builder into a search query. */ compile: () => OrmSearch; }>; /** * An in between or ending type to a builder creating a SearchQuery * @interface */ export type BuilderV2Link = NonQueryBuilder & Readonly<{ /** * Links together two or more {@link Query} or complex queries. */ and: () => QueryBuilder; /** * Links together two or more {@link Query} or complex queries. */ or: () => QueryBuilder; }>; /** * A function that can either take a builder or raw QueryTokens[] and create a sub-query. * @param builder - Can be either a BuilderV2 or a hand written Query **/ export type SubBuilderFunction = (builder: QueryBuilder) => Omit | (QueryBuilder | BuilderV2Link); /** * A search builder is a structured way to create a complex query. * @interface */ export type QueryBuilder = InnerBuilderV2 & NonQueryBuilder; /** * A builder for version 3.0 search queries. * @interface */ export type InnerBuilderV2 = { /** * Creates a query that has nested property queries. * @param subBuilderFunc - A function that can return a Builder */ complex: (subBuilderFunc: SubBuilderFunction) => BuilderV2Link; /** * Searches for elements that are after the given date. * NOTE: It can be very important to set the valueType to either string or Date depending on what datastore you are using. * @param key - The property name/key to use. * @param jsDate - The date to search. * @param options - Additional options. */ datesAfter: (key: string, jsDate: Date | string, options?: { valueType?: DatastoreValueType; equalToAndAfter?: boolean; }) => BuilderV2Link; /** * Searches for elements that are before the given date. * NOTE: It can be very important to set the valueType to either string or Date depending on what datastore you are using. * @param key - The property name/key to use. * @param jsDate - The date to search. * @param options - Additional options. */ datesBefore: (key: string, jsDate: Date | string, options?: { valueType?: DatastoreValueType; equalToAndBefore?: boolean; }) => BuilderV2Link; /** * Search a value * @param key - The property name/key to use. * @param value - The value to match. * @param options - Additional options. */ property: (key: string, value: any, options?: Partial) => BuilderV2Link; }; /** * The types of primary key properties. */ export type PrimaryKeyPropertyType = PropertyType.UniqueId | PropertyType.Text | PropertyType.Integer; /** * A function that can generate a primary key for a model. * @param model - The model to generate a primary key for. * @returns A promise that resolves to the primary key. */ export type PrimaryKeyGenerator = (value: TValue, modelData: CreateParams, instance: ModelInstance) => Promise; /** * A property that represents a key in a database. * By default it is a "uuid" type, but if you want to use an arbitrary string, or an integer type you can set the `dataType` property. * @interface */ export type DatabaseKeyPropertyConfig = PrimaryKeyType> = PropertyConfig & Readonly<{ /** * Sets the type of the key. * @default PrimaryKeyDataType.Uuid */ dataType?: PrimaryKeyPropertyType; /** * If true, the key will be automatically generated if not provided. Only applies to uuids and integers * @default true */ auto?: boolean; /** * Optional: A custom primary key generator function to use for models. If the property type is UniqueId (default) then this will produce random UUID. If the property type is a number, a random number will be generated. * If using a SQL-like database that uses numbers, its HIGHLY recommended to get a number from the database itself. */ primaryKeyGenerator?: PrimaryKeyGenerator; }>; export {};