UNPKG

redis-om

Version:

Object mapping, and more, for Redis and Node.js. Written in TypeScript.

1,326 lines (1,313 loc) 52.2 kB
import { createClient, createCluster, RediSearchSchema, SearchOptions } from 'redis'; /** The Symbol used to access the entity ID of an {@link Entity}. */ declare const EntityId: unique symbol; /** The Symbol used to access the keyname of an {@link Entity}. */ declare const EntityKeyName: unique symbol; /** Defines the objects returned from calls to {@link Repository | repositories }. */ type Entity = EntityData & { /** The unique ID of the {@link Entity}. Access using the {@link EntityId} Symbol. */ [EntityId]?: string; /** The key the {@link Entity} is stored under inside of Redis. Access using the {@link EntityKeyName} Symbol. */ [EntityKeyName]?: string; }; /** The free-form data associated with an {@link Entity}. */ type EntityData = { [key: string]: EntityDataValue | EntityData | Array<EntityDataValue | EntityData>; }; /** Valid types for values in an {@link Entity}. */ type EntityDataValue = string | number | boolean | Date | Point | null | undefined | Array<EntityDataValue | EntityData>; /** Defines a point on the globe using longitude and latitude. */ type Point = { /** The longitude of the point. */ longitude: number; /** The latitude of the point. */ latitude: number; }; /** Valid field types for a {@link FieldDefinition}. */ type FieldType = 'boolean' | 'date' | 'number' | 'number[]' | 'point' | 'string' | 'string[]' | 'text'; /** All configuration properties that any field might have, regardless of type. */ type AllFieldDefinition = { /** The type of the field (i.e. string, number, boolean, etc.) */ type: FieldType; /** * The default field name in Redis is the property name defined in the * {@link SchemaDefinition}. Overrides the field name for a Hash to this * value or in the case of JSON documents, sets the JSONPath to this * value preceded by `$.`. Overridden by {@link field} and/or {@link path} * settings. * @deprecated */ alias?: string; /** * Is this field indexed and thus searchable with Redis OM. Defaults * to true. */ indexed?: boolean; /** * The field name used to store this in a Redis Hash. Defaults to the * name used in the {@link SchemaDefinition} or the {@link alias} * property. */ field?: string; /** * The JSONPath expression this field references. Used only by search * and only for JSON documents. Defaults to the name used in the * {@link SchemaDefinition} or the {@link alias} property prefixed * with `$.` . */ path?: string; /** Enables sorting by this field. */ sortable?: boolean; /** Is the original case of this field indexed with Redis OM. Defaults to false. */ caseSensitive?: boolean; /** Is this (sortable) field normalized when indexed. Defaults to true. */ normalized?: boolean; /** * Due to how RediSearch works, strings and arrays are sometimes stored the same in Redis, as a * simple string. This is the separator used to split those strings when it is an array. If your * StringField contains this separator, this can cause problems. You can change it here to avoid * those problems. Defaults to `|`. */ separator?: string; /** * Enables setting the phonetic matcher to use, supported matchers are: * dm:en - Double Metaphone for English * dm:fr - Double Metaphone for French * dm:pt - Double Metaphone for Portuguese * dm:es - Double Metaphone for Spanish */ matcher?: 'dm:en' | 'dm:fr' | 'dm:pt' | 'dm:es'; /** Is word stemming applied to this field with Redis OM. Defaults to true. */ stemming?: boolean; /** Enables setting the weight to apply to a text field */ weight?: number; }; /** The configuration properties that all fields have in common. */ type CommonFieldDefinition = Pick<AllFieldDefinition, "type" | "alias" | "indexed" | "field" | "path">; /** A field representing a boolean. */ type BooleanFieldDefinition = { type: 'boolean'; } & CommonFieldDefinition & Pick<AllFieldDefinition, "sortable">; /** A field representing a date/time. */ type DateFieldDefinition = { type: 'date'; } & CommonFieldDefinition & Pick<AllFieldDefinition, "sortable">; /** A field representing a number. */ type NumberFieldDefinition = { type: 'number'; } & CommonFieldDefinition & Pick<AllFieldDefinition, "sortable">; /** A field representing an array of numbers. */ type NumberArrayFieldDefinition = { type: 'number[]'; } & CommonFieldDefinition & Pick<AllFieldDefinition, "sortable">; /** A field representing a point on the globe. */ type PointFieldDefinition = { type: 'point'; } & CommonFieldDefinition; /** A field representing a whole string. */ type StringFieldDefinition = { type: 'string'; } & CommonFieldDefinition & Pick<AllFieldDefinition, "sortable" | "caseSensitive" | "normalized" | "separator">; /** A field representing an array of strings. */ type StringArrayFieldDefinition = { type: 'string[]'; } & CommonFieldDefinition & Pick<AllFieldDefinition, "sortable" | "caseSensitive" | "normalized" | "separator">; /** A field representing searchable text. */ type TextFieldDefinition = { type: 'text'; } & CommonFieldDefinition & Pick<AllFieldDefinition, "sortable" | "normalized" | "matcher" | "stemming" | "weight">; /** Contains instructions telling how to map a property on an {@link Entity} to Redis. */ type FieldDefinition = BooleanFieldDefinition | DateFieldDefinition | NumberFieldDefinition | NumberArrayFieldDefinition | PointFieldDefinition | StringFieldDefinition | StringArrayFieldDefinition | TextFieldDefinition; /** Group of {@link FieldDefinition}s that define the schema for an {@link Entity}. */ type SchemaDefinition = Record<string, FieldDefinition>; /** * Describes a field in a {@link Schema}. */ declare class Field { #private; /** * Creates a Field. * * @param name The name of the Field. * @param definition The underlying {@link FieldDefinition}. */ constructor(name: string, definition: FieldDefinition); /** The name of the field. */ get name(): string; /** The {@link FieldType | type} of the field. */ get type(): FieldType; /** The field name used to store this {@link Field} in a Hash. */ get hashField(): string; /** The JSONPath used to store this {@link Field} in a JSON document. */ get jsonPath(): string; /** The separator for string[] fields when stored in Hashes. */ get separator(): string; /** Indicates that the field as sortable. */ get sortable(): boolean; /** The case-sensitivity of the field. */ get caseSensitive(): boolean; /** Indicates the field as being indexed—and thus queryable—by RediSearch. */ get indexed(): boolean; /** Indicates that the field as indexed with stemming support. */ get stemming(): boolean; /** Indicates that the field is normalized. Ignored if sortable is false. */ get normalized(): boolean; /** The search weight of the field. */ get weight(): number | null; /** The phonetic matcher for the field. */ get matcher(): string | null; /** Is this type an array or not. */ get isArray(): boolean; } /** The type of data structure in Redis to map objects to. */ type DataStructure = 'HASH' | 'JSON'; /** A function that generates random entityIds. */ type IdStrategy = () => Promise<string>; /** Valid values for how to use stop words for a given {@link Schema}. */ type StopWordOptions = 'OFF' | 'DEFAULT' | 'CUSTOM'; /** Configuration options for a {@link Schema}. */ type SchemaOptions = { /** * The name used by RediSearch to store the index for this {@link Schema}. Defaults * to prefix followed by `:index`. So, for a prefix of `Foo`, it would use `Foo:index`. */ indexName?: string; /** * The name used by Redis OM to store the hash of the index for this {@link Schema}. * Defaults to prefix followed by `:index:hash`. So, for a prefix of `Foo`, it would * use `Foo:index:hash`. */ indexHashName?: string; /** The data structure used to store the {@link Entity} in Redis. Can be set * to either `JSON` or `HASH`. Defaults to JSON. */ dataStructure?: DataStructure; /** * A function that generates a random entityId. Defaults to a function that generates * [ULIDs](https://github.com/ulid/spec). Combined with prefix to generate a Redis key. * If prefix is `Foo` and idStratgey returns `12345` then the generated key would be * `Foo:12345`. */ idStrategy?: IdStrategy; /** * Configures the usage of stop words. Valid values are `OFF`, `DEFAULT`, and `CUSTOM`. * Setting this to `OFF` disables all stop words. Setting this to `DEFAULT` uses the * stop words intrinsic to RediSearch. Setting this to `CUSTOM` tells RediSearch to * use the stop words in `stopWords`. */ useStopWords?: StopWordOptions; /** * Stop words to be used by this schema. If `useStopWords` is * anything other than `CUSTOM`, this option is ignored. */ stopWords?: Array<string>; }; /** * Defines a schema that determines how an {@link Entity} is mapped * to Redis data structures. Construct by passing in a schema name, * a {@link SchemaDefinition}, and optionally {@link SchemaOptions}: * * ```typescript * const schema = new Schema('foo', { * aString: { type: 'string' }, * aNumber: { type: 'number' }, * aBoolean: { type: 'boolean' }, * someText: { type: 'text' }, * aPoint: { type: 'point' }, * aDate: { type: 'date' }, * someStrings: { type: 'string[]' } * }, { * dataStructure: 'HASH' * }) * ``` * * A Schema is primarily used by a {@link Repository} which requires a Schema in * its constructor. */ declare class Schema { #private; /** * Constructs a Schema. * * @param schemaName The name of the schema. Prefixes the ID when creating Redis keys. * @param schemaDef Defines all of the fields for the Schema and how they are mapped to Redis. * @param options Additional options for this Schema. */ constructor(schemaName: string, schemaDef: SchemaDefinition, options?: SchemaOptions); /** * The name of the schema. Prefixes the ID when creating Redis keys. Combined * with the results of idStrategy to generate a key. If name is `foo` and * idStrategy returns `12345` then the generated key would be `foo:12345`. */ get schemaName(): string; /** The {@link Field | Fields} defined by this Schema. */ get fields(): Field[]; /** * Gets a single {@link Field} defined by this Schema. * * @param name The name of the {@link Field} in this Schema. * @returns The {@link Field}, or null of not found. */ fieldByName(name: string): Field | null; /** The configured name for the RediSearch index for this Schema. */ get indexName(): string; /** The configured name for the RediSearch index hash for this Schema. */ get indexHashName(): string; /** * The configured data structure, a string with the value of either `HASH` or `JSON`, * that this Schema uses to store {@link Entity | Entities} in Redis. */ get dataStructure(): DataStructure; /** * The configured usage of stop words, a string with the value of either `OFF`, `DEFAULT`, * or `CUSTOM`. See {@link SchemaOptions} for more details. */ get useStopWords(): StopWordOptions; /** * The configured stop words. Ignored if {@link Schema.useStopWords} is anything other * than `CUSTOM`. */ get stopWords(): Array<string>; /** * Generates a unique string using the configured {@link IdStrategy}. * * @returns The generated id. */ generateId(): Promise<string>; /** * A hash for this Schema that is used to determine if the Schema has been * changed when calling {@link Repository#createIndex}. */ get indexHash(): string; } /** * Abstract base class used extensively with {@link Search}. */ declare abstract class Where { /** * Converts this {@link Where} into a portion of a RediSearch query. */ abstract toString(): string; } type Units = 'm' | 'km' | 'ft' | 'mi'; /** A function that defines a circle for `.inCircle` searches. */ type CircleFunction = (circle: Circle) => Circle; /** A builder that defines a circle. */ declare class Circle { /** @internal */ longitudeOfOrigin: number; /** @internal */ latitudeOfOrigin: number; /** @internal */ size: number; /** @internal */ units: Units; /** * Sets the longitude. If not set, defaults to 0.0. * * @param value The longitude. * @returns This instance. */ longitude(value: number): this; /** * Sets the latitude. If not set, defaults to 0.0. * * @param value The latitude. * @returns This instance. */ latitude(value: number): this; /** * Sets the origin of the circle using a {@link Point}. If not * set, defaults to [Null Island](https://en.wikipedia.org/wiki/Null_Island). * * @param point A {@link Point} containing the longitude and latitude of the origin. * @returns This instance. */ origin(point: Point): Circle; /** * Sets the origin of the circle. If not set, defaults to * [Null Island](https://en.wikipedia.org/wiki/Null_Island). * * @param longitude The longitude. * @param latitude The latitude. * @returns This instance. */ origin(longitude: number, latitude: number): Circle; /** * Sets the radius of the {@link Circle}. Defaults to 1. If units are * not specified, defaults to meters. * * @param size The radius of the circle. * @returns This instance. */ radius(size: number): this; /** * Sets the units to meters. * @returns This instance. */ get m(): this; /** * Sets the units to meters. * @returns This instance. */ get meter(): this; /** * Sets the units to meters. * @returns This instance. */ get meters(): this; /** * Sets the units to kilometers. * @returns This instance. */ get km(): this; /** * Sets the units to kilometers. * @returns This instance. */ get kilometer(): this; /** * Sets the units to kilometers. * @returns This instance. */ get kilometers(): this; /** * Sets the units to feet. * @returns This instance. */ get ft(): this; /** * Sets the units to feet. * @returns This instance. */ get foot(): this; /** * Sets the units to feet. * @returns This instance. */ get feet(): this; /** * Sets the units to miles. * @returns This instance. */ get mi(): this; /** * Sets the units to miles. * @returns This instance. */ get mile(): this; /** * Sets the units to miles. * @returns This instance. */ get miles(): this; } /** * Interface with all the methods from all the concrete * classes under {@link WhereField}. */ interface WhereField extends Where { /** * Adds an equals comparison to the query. * * NOTE: this function is not available for strings where full-text * search is enabled. In that scenario, use `.match`. * @param value The value to be compared * @returns The {@link Search} that was called to create this {@link WhereField}. */ eq(value: string | number | boolean | Date): Search; /** * Adds an equals comparison to the query. * * NOTE: this function is not available for strings where full-text * search is enabled. In that scenario, use `.match`. * @param value The value to be compared * @returns The {@link Search} that was called to create this {@link WhereField}. */ equal(value: string | number | boolean | Date): Search; /** * Adds an equals comparison to the query. * * NOTE: this function is not available for strings where full-text * search is enabled. In that scenario, use `.match`. * @param value The value to be compared * @returns The {@link Search} that was called to create this {@link WhereField}. */ equals(value: string | number | boolean | Date): Search; /** * Adds an equals comparison to the query. * * NOTE: this function is not available for strings where full-text * search is enabled. In that scenario, use `.match`. * @param value The value to be compared * @returns The {@link Search} that was called to create this {@link WhereField}. */ equalTo(value: string | number | boolean | Date): Search; /** * Adds a full-text search comparison to the query. * @param value The word or phrase sought. * @param options.fuzzyMatching Whether to use fuzzy matching to find the sought word or phrase. Defaults to `false`. * @param options.levenshteinDistance The levenshtein distance to use for fuzzy matching. Supported values are `1`, `2`, and `3`. Defaults to `1`. * @returns The {@link Search} that was called to create this {@link WhereField}. */ match(value: string | number | boolean, options?: { fuzzyMatching?: boolean; levenshteinDistance?: 1 | 2 | 3; }): Search; /** * Adds a full-text search comparison to the query. * @param value The word or phrase sought. * @param options.fuzzyMatching Whether to use fuzzy matching to find the sought word or phrase. Defaults to `false`. * @param options.levenshteinDistance The levenshtein distance to use for fuzzy matching. Supported values are `1`, `2`, and `3`. Defaults to `1`. * @returns The {@link Search} that was called to create this {@link WhereField}. */ matches(value: string | number | boolean, options?: { fuzzyMatching?: boolean; levenshteinDistance?: 1 | 2 | 3; }): Search; /** * Adds a full-text search comparison to the query that matches an exact word or phrase. * @param value The word or phrase sought. * @returns The {@link Search} that was called to create this {@link WhereField}. */ matchExact(value: string | number | boolean): Search; /** * Adds a full-text search comparison to the query that matches an exact word or phrase. * @param value The word or phrase sought. * @returns The {@link Search} that was called to create this {@link WhereField}. */ matchExactly(value: string | number | boolean): Search; /** * Adds a full-text search comparison to the query that matches an exact word or phrase. * @param value The word or phrase sought. * @returns The {@link Search} that was called to create this {@link WhereField}. */ matchesExactly(value: string | number | boolean): Search; /** * Makes a call to {@link WhereField.match} a {@link WhereField.matchExact} call. Calling * this multiple times will have no effect. * @returns this. */ readonly exact: WhereField; /** * Makes a call to {@link WhereField.match} a {@link WhereField.matchExact} call. Calling * this multiple times will have no effect. * @returns this. */ readonly exactly: WhereField; /** * Adds a boolean match with a value of `true` to the query. * @returns The {@link Search} that was called to create this {@link WhereField}. */ true(): Search; /** * Adds a boolean match with a value of `false` to the query. * @returns The {@link Search} that was called to create this {@link WhereField}. */ false(): Search; /** * Adds a greater than comparison against a field to the search query. * @param value The value to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ gt(value: string | number | Date): Search; /** * Adds a greater than comparison against a field to the search query. * @param value The value to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ greaterThan(value: string | number | Date): Search; /** * Adds a greater than or equal to comparison against a field to the search query. * @param value The value to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ gte(value: string | number | Date): Search; /** * Adds a greater than or equal to comparison against a field to the search query. * @param value The value to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ greaterThanOrEqualTo(value: string | number | Date): Search; /** * Adds a less than comparison against a field to the search query. * @param value The value to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ lt(value: string | number | Date): Search; /** * Adds a less than comparison against a field to the search query. * @param value The value to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ lessThan(value: string | number | Date): Search; /** * Adds a less than or equal to comparison against a field to the search query. * @param value The value to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ lte(value: string | number | Date): Search; /** * Adds a less than or equal to comparison against a field to the search query. * @param value The value to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ lessThanOrEqualTo(value: string | number | Date): Search; /** * Adds an inclusive range comparison against a field to the search query. * @param lower The lower bound of the range. * @param upper The upper bound of the range. * @returns The {@link Search} that was called to create this {@link WhereField}. */ between(lower: string | number | Date, upper: string | number | Date): Search; /** * Adds a whole-string match for a value within a string array to the search query. * @param value The string to be matched. * @returns The {@link Search} that was called to create this {@link WhereField}. */ contain(value: string): Search; /** * Adds a whole-string match for a value within a string array to the search query. * @param value The string to be matched. * @returns The {@link Search} that was called to create this {@link WhereField}. */ contains(value: string): Search; /** * Adds a whole-string match against a string array to the query. If any of the provided * strings in `value` is matched in the array, this matched. * @param value An array of strings that you want to match one of. * @returns The {@link Search} that was called to create this {@link WhereField}. */ containOneOf(...value: Array<string>): Search; /** * Adds a whole-string match against a string array to the query. If any of the provided * strings in `value` is matched in the array, this matched. * @param value An array of strings that you want to match one of. * @returns The {@link Search} that was called to create this {@link WhereField}. */ containsOneOf(...value: Array<string>): Search; /** * Adds a search for points that fall within a defined circle. * @param circleFn A function that returns a {@link Circle} instance defining the search area. * @returns The {@link Search} that was called to create this {@link WhereField}. */ inCircle(circleFn: CircleFunction): Search; /** * Adds a search for points that fall within a defined radius. * @param circleFn A function that returns a {@link Circle} instance defining the search area. * @returns The {@link Search} that was called to create this {@link WhereField}. */ inRadius(circleFn: CircleFunction): Search; /** * Add a search for an exact UTC datetime to the query. * @param value The datetime to match. * @returns The {@link Search} that was called to create this {@link WhereField}. */ on(value: string | number | Date): Search; /** * Add a search that matches all datetimes *before* the provided UTC datetime to the query. * @param value The datetime to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ before(value: string | number | Date): Search; /** * Add a search that matches all datetimes *after* the provided UTC datetime to the query. * @param value The datetime to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ after(value: string | number | Date): Search; /** * Add a search that matches all datetimes *on or before* the provided UTC datetime to the query. * @param value The datetime to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ onOrBefore(value: string | number | Date): Search; /** * Add a search that matches all datetimes *on or after* the provided UTC datetime to the query. * @param value The datetime to compare against. * @returns The {@link Search} that was called to create this {@link WhereField}. */ onOrAfter(value: string | number | Date): Search; } /** * Abstract base class that all fields you want to filter * with extend. When you call {@link Search.where}, a * subclass of this is returned. */ declare abstract class WhereField { private negated; /** @internal */ protected search: Search; /** @internal */ protected field: Field; /** @internal */ constructor(search: Search, field: Field); /** * Returns the current instance. Syntactic sugar to make your code more fluent. * @returns this */ get is(): this; /** * Returns the current instance. Syntactic sugar to make your code more fluent. * @returns this */ get does(): this; /** * Negates the query on the field, cause it to match when the condition is * *not* met. Calling this multiple times will negate the negation. * @returns this */ get not(): this; abstract toString(): string; /** @internal */ protected negate(): void; /** @internal */ protected buildQuery(valuePortion: string): string; /** @internal */ protected escapePunctuation(value: string): string; /** @internal */ protected escapePunctuationAndSpaces(value: string): string; } /** * A function that takes a {@link Search} and returns a {@link Search}. Used in nested queries. * @template TEntity The type of {@link Entity} being sought. */ type SubSearchFunction = (search: Search) => Search; type SortOptions = { BY: string; DIRECTION: 'ASC' | 'DESC'; }; /** * Abstract base class for {@link Search} and {@link RawSearch} that * contains methods to return search results. * @template TEntity The type of {@link Entity} being sought. */ declare abstract class AbstractSearch { /** @internal */ protected schema: Schema; /** @internal */ protected client: Client; /** @internal */ protected sortOptions?: SortOptions; /** @internal */ constructor(schema: Schema, client: Client); /** @internal */ abstract get query(): string; /** * Applies an ascending sort to the query. * @param field The field to sort by. * @returns this */ sortAscending(field: string): AbstractSearch; /** * Alias for {@link Search.sortDescending}. */ sortDesc(field: string): AbstractSearch; /** * Applies a descending sort to the query. * @param field The field to sort by. * @returns this */ sortDescending(field: string): AbstractSearch; /** * Alias for {@link Search.sortAscending}. */ sortAsc(field: string): AbstractSearch; /** * Applies sorting for the query. * @param field The field to sort by. * @param order The order of returned {@link Entity | Entities} Defaults to `ASC` (ascending) if not specified * @returns this */ sortBy(fieldName: string, order?: 'ASC' | 'DESC'): AbstractSearch; /** * Finds the {@link Entity} with the minimal value for a field. * @param field The field with the minimal value. * @returns The {@link Entity} with the minimal value */ min(field: string): Promise<Entity | null>; /** * Finds the entity ID with the minimal value for a field. * @param field The field with the minimal value. * @returns The entity ID with the minimal value */ minId(field: string): Promise<string | null>; /** * Finds the key name in Redis with the minimal value for a field. * @param field The field with the minimal value. * @returns The key name with the minimal value */ minKey(field: string): Promise<string | null>; /** * Finds the {@link Entity} with the maximal value for a field. * @param field The field with the maximal value. * @returns The entity ID {@link Entity} with the maximal value */ max(field: string): Promise<Entity | null>; /** * Finds the entity ID with the maximal value for a field. * @param field The field with the maximal value. * @returns The entity ID with the maximal value */ maxId(field: string): Promise<string | null>; /** * Finds the key name in Redis with the maximal value for a field. * @param field The field with the maximal value. * @returns The key name with the maximal value */ maxKey(field: string): Promise<string | null>; /** * Returns the number of {@link Entity | Entities} that match this query. * @returns */ count(): Promise<number>; /** * Returns a page of {@link Entity | Entities} that match this query. * @param offset The offset for where to start returning {@link Entity | Entities}. * @param count The number of {@link Entity | Entities} to return. * @returns An array of {@link Entity | Entities} matching the query. */ page(offset: number, count: number): Promise<Entity[]>; /** * Returns a page of entity IDs that match this query. * @param offset The offset for where to start returning entity IDs. * @param count The number of entity IDs to return. * @returns An array of strings matching the query. */ pageOfIds(offset: number, count: number): Promise<string[]>; /** * Returns a page of key names in Redis that match this query. * @param offset The offset for where to start returning key names. * @param count The number of key names to return. * @returns An array of strings matching the query. */ pageOfKeys(offset: number, count: number): Promise<string[]>; /** * Returns the first {@link Entity} that matches this query. */ first(): Promise<Entity | null>; /** * Returns the first entity ID that matches this query. */ firstId(): Promise<string | null>; /** * Returns the first key name that matches this query. */ firstKey(): Promise<string | null>; /** * Returns all the {@link Entity | Entities} that match this query. This method * makes multiple calls to Redis until all the {@link Entity | Entities} are returned. * You can specify the batch size by setting the `pageSize` property on the * options: * * ```typescript * const entities = await repository.search().returnAll({ pageSize: 100 }) * ``` * * @param options Options for the call. * @param options.pageSize Number of {@link Entity | Entities} returned per batch. * @returns An array of {@link Entity | Entities} matching the query. */ all(options?: { pageSize: number; }): Promise<Entity[]>; /** * Returns all the entity IDs that match this query. This method * makes multiple calls to Redis until all the entity IDs are returned. * You can specify the batch size by setting the `pageSize` property on the * options: * * ```typescript * const keys = await repository.search().returnAllIds({ pageSize: 100 }) * ``` * * @param options Options for the call. * @param options.pageSize Number of entity IDs returned per batch. * @returns An array of entity IDs matching the query. */ allIds(options?: { pageSize: number; }): Promise<string[]>; /** * Returns all the key names in Redis that match this query. This method * makes multiple calls to Redis until all the key names are returned. * You can specify the batch size by setting the `pageSize` property on the * options: * * ```typescript * const keys = await repository.search().returnAllKeys({ pageSize: 100 }) * ``` * * @param options Options for the call. * @param options.pageSize Number of key names returned per batch. * @returns An array of key names matching the query. */ allKeys(options?: { pageSize: number; }): Promise<string[]>; /** * Returns the current instance. Syntactic sugar to make your code more fluent. * @returns this */ get return(): AbstractSearch; /** * Alias for {@link Search.min}. */ returnMin(field: string): Promise<Entity | null>; /** * Alias for {@link Search.minId}. */ returnMinId(field: string): Promise<string | null>; /** * Alias for {@link Search.minKey}. */ returnMinKey(field: string): Promise<string | null>; /** * Alias for {@link Search.max}. */ returnMax(field: string): Promise<Entity | null>; /** * Alias for {@link Search.maxId}. */ returnMaxId(field: string): Promise<string | null>; /** * Alias for {@link Search.maxKey}. */ returnMaxKey(field: string): Promise<string | null>; /** * Alias for {@link Search.count}. */ returnCount(): Promise<number>; /** * Alias for {@link Search.page}. */ returnPage(offset: number, count: number): Promise<Entity[]>; /** * Alias for {@link Search.pageOfIds}. */ returnPageOfIds(offset: number, count: number): Promise<string[]>; /** * Alias for {@link Search.pageOfKeys}. */ returnPageOfKeys(offset: number, count: number): Promise<string[]>; /** * Alias for {@link Search.first}. */ returnFirst(): Promise<Entity | null>; /** * Alias for {@link Search.firstId}. */ returnFirstId(): Promise<string | null>; /** * Alias for {@link Search.firstKey}. */ returnFirstKey(): Promise<string | null>; /** * Alias for {@link Search.all}. */ returnAll(options?: { pageSize: number; }): Promise<Entity[]>; /** * Alias for {@link Search.allIds}. */ returnAllIds(options?: { pageSize: number; }): Promise<string[]>; /** * Alias for {@link Search.allKeys}. */ returnAllKeys(options?: { pageSize: number; }): Promise<string[]>; private allThings; private callSearch; } /** * Entry point to raw search which allows using raw RediSearch queries * against Redis OM. Requires that RediSearch (and optionally RedisJSON) be * installed. * @template TEntity The type of {@link Entity} being sought. */ declare class RawSearch extends AbstractSearch { private rawQuery; /** @internal */ constructor(schema: Schema, client: Client, query?: string); /** @internal */ get query(): string; } /** * Entry point to fluent search. This is the default Redis OM experience. * Requires that RediSearch (and optionally RedisJSON) be installed. * @template TEntity The type of {@link Entity} being sought. */ declare class Search extends AbstractSearch { private rootWhere?; /** @internal */ get query(): string; /** * Sets up a query matching a particular field. If there are multiple calls * to {@link Search.where}, they are treated logically as AND. * @param field The field to filter on. * @returns A subclass of {@link WhereField} matching the type of the field. */ where(field: string): WhereField; /** * Sets up a nested search. If there are multiple calls to {@link Search.where}, * they are treated logically as AND. * @param subSearchFn A function that takes a {@link Search} and returns another {@link Search}. * @returns `this`. */ where(subSearchFn: SubSearchFunction): Search; /** * Sets up a query matching a particular field as a logical AND. * @param field The field to filter on. * @returns A subclass of {@link WhereField} matching the type of the field. */ and(field: string): WhereField; /** * Sets up a nested search as a logical AND. * @param subSearchFn A function that takes a {@link Search} and returns another {@link Search}. * @returns `this`. */ and(subSearchFn: SubSearchFunction): Search; /** * Sets up a query matching a particular field as a logical OR. * @param field The field to filter on. * @returns A subclass of {@link WhereField} matching the type of the field. */ or(field: string): WhereField; /** * Sets up a nested search as a logical OR. * @param subSearchFn A function that takes a {@link Search} and returns another {@link Search}. * @returns `this`. */ or(subSearchFn: SubSearchFunction): Search; private anyWhere; private anyWhereForField; private anyWhereForFunction; private createWhere; } /** * A repository is the main interaction point for reading, writing, and * removing {@link Entity | Entities} from Redis. Create one by calling * {@link Client.fetchRepository} and passing in a {@link Schema}. Then * use the {@link Repository#fetch}, {@link Repository#save}, and * {@link Repository#remove} methods to manage your data: * * ```typescript * const repository = client.fetchRepository(schema) * * const foo = await repository.fetch('01FK6TCJBDK41RJ766A4SBWDJ9') * foo.aString = 'bar' * foo.aBoolean = false * await repository.save(foo) * ``` * * Use the repository to create a new instance of an {@link Entity} * before you save it: * * ```typescript * const foo = await repository.createEntity() * foo.aString = 'bar' * foo.aBoolean = false * await repository.save(foo) * ``` * * If you want to use the {@link Repository#search} method, you need to create an index * first, and you need RediSearch or RedisJSON installed on your instance of Redis: * * ```typescript * await repository.createIndex() * const entities = await repository.search() * .where('aString').eq('bar') * .and('aBoolean').is.false().returnAll() * ``` */ declare class Repository { #private; private client; /** * Creates a new {@link Repository}. * * @param schema The schema defining that data in the repository. * @param client A client to talk to Redis. */ constructor(schema: Schema, clientOrConnection: Client | RedisConnection); /** * Creates an index in Redis for use by the {@link Repository#search} method. * Does not create a new index if the index hasn't changed. Requires that * RediSearch and RedisJSON are installed on your instance of Redis. */ createIndex(): Promise<void>; /** * Removes an existing index from Redis. Use this method if you want to swap out your index * because your {@link Entity} has changed. Requires that RediSearch and RedisJSON are installed * on your instance of Redis. */ dropIndex(): Promise<void>; /** * Insert or update an {@link Entity} to Redis using its entityId property * if present. If it's not, one is generated. * * @param entity The Entity to save. * @returns A copy of the provided Entity with EntityId and EntityKeyName properties added. */ save(entity: Entity): Promise<Entity>; /** * Insert or update the {@link Entity} to Redis using the provided entityId. * * @param id The id to save the Entity under. * @param entity The Entity to save. * @returns A copy of the provided Entity with EntityId and EntityKeyName properties added. */ save(id: string, entity: Entity): Promise<Entity>; /** * Read and return an {@link Entity} from Redis for the given id. If * the {@link Entity} is not found, returns an empty {@link Entity}. * * @param id The ID of the {@link Entity} you seek. * @returns The matching Entity. */ fetch(id: string): Promise<Entity>; /** * Read and return the {@link Entity | Entities} from Redis with the given IDs. If * a particular {@link Entity} is not found, returns that {@link Entity} as empty. * * @param ids The IDs of the {@link Entity | Entities} you seek. * @returns The matching Entities. */ fetch(...ids: string[]): Promise<Entity[]>; /** * Read and return the {@link Entity | Entities} from Redis with the given IDs. If * a particular {@link Entity} is not found, returns that {@link Entity} as empty. * * @param ids The IDs of the {@link Entity | Entities} you seek. * @returns The matching Entities. */ fetch(ids: string[]): Promise<Entity[]>; /** * Remove an {@link Entity} from Redis for the given id. If the {@link Entity} is * not found, does nothing. * * @param id The ID of the {@link Entity} you wish to delete. */ remove(id: string): Promise<void>; /** * Remove the {@link Entity | Entities} from Redis for the given ids. If a * particular {@link Entity} is not found, does nothing. * * @param ids The IDs of the {@link Entity | Entities} you wish to delete. */ remove(...ids: string[]): Promise<void>; /** * Remove the {@link Entity | Entities} from Redis for the given ids. If a * particular {@link Entity} is not found, does nothing. * * @param ids The IDs of the {@link Entity | Entities} you wish to delete. */ remove(ids: string[]): Promise<void>; /** * Set the time to live of the {@link Entity}. If the {@link Entity} is not * found, does nothing. * * @param id The ID of the {@link Entity} to set and expiration for. * @param ttlInSeconds The time to live in seconds. */ expire(id: string, ttlInSeconds: number): Promise<void>; /** * Set the time to live of the {@link Entity | Entities} in Redis with the given * ids. If a particular {@link Entity} is not found, does nothing. * * @param ids The IDs of the {@link Entity | Entities} you wish to delete. */ expire(ids: string[], ttlInSeconds: number): Promise<void>; /** * Use Date object to set the {@link Entity}'s time to live. If the {@link Entity} * is not found, does nothing. * * @param id The ID of the {@link Entity} to set an expiration date for. * @param expirationDate The time the data should expire. */ expireAt(id: string, expirationDate: Date): Promise<void>; /** * Use Date object to set the {@link Entity | Entities} in Redis with the given * ids. If a particular {@link Entity} is not found, does nothing. * * @param ids The IDs of the {@link Entity | Entities} to set an expiration date for. * @param expirationDate The time the data should expire. */ expireAt(ids: string[], expirationDate: Date): Promise<void>; /** * Kicks off the process of building a query. Requires that RediSearch (and optionally * RedisJSON) be installed on your instance of Redis. * * @returns A {@link Search} object. */ search(): Search; /** * Creates a search that bypasses Redis OM and instead allows you to execute a raw * RediSearch query. Requires that RediSearch (and optionally RedisJSON) be installed * on your instance of Redis. * * Refer to https://redis.io/docs/stack/search/reference/query_syntax/ for details on * RediSearch query syntax. * * @query The raw RediSearch query you want to rune. * @returns A {@link RawSearch} object. */ searchRaw(query: string): RawSearch; private writeEntity; private readEntities; private writeEntityToHash; private readEntitiesFromHash; private writeEntityToJson; private readEntitiesFromJson; private makeKeys; private makeKey; } /** A conventional Redis connection. */ type RedisClientConnection = ReturnType<typeof createClient>; /** A clustered Redis connection. */ type RedisClusterConnection = ReturnType<typeof createCluster>; /** A Redis connection, clustered or conventional. */ type RedisConnection = RedisClientConnection | RedisClusterConnection; /** @internal This is a defintion for the type that calls to ft.search in Node Redis return. */ type SearchResults = { total: number; documents: SearchDocument[]; }; /** @internal This is a defintion for the return type of calls to ft.search in Node Redis. */ type SearchDocument = { id: string; value: { [key: string]: any; }; }; /** @internal */ type RedisHashData = { [key: string]: string; }; /** @internal */ type RedisJsonData = { [key: string]: any; }; /** @internal */ type SearchDataStructure = 'HASH' | 'JSON'; /** * @internal This is a simplified redefintion of the CreateOptions type that is not exported by Node Redis. * TODO: Remove this type once CreateOptions is exported by Node Redis. * https://github.com/redis/node-redis/blob/master/packages/search/lib/commands/CREATE.ts#L4 */ type CreateOptions = { ON: SearchDataStructure; PREFIX: string; STOPWORDS?: string[]; }; /** * A Client is the starting point for working with Redis OM. Clients manage the * connection to Redis and provide limited functionality for executing Redis commands. * Create a client and open it before you use it: * * ```typescript * const client = new Client() * await client.open() * ``` * * A Client is primarily used by a {@link Repository} which requires a client in * its constructor. * * @deprecated Just used Node Redis client directly and pass it to the Repository. */ declare class Client { #private; /** Returns the underlying Node Redis connection being used. */ get redis(): RedisConnection | undefined; /** * Attaches an existing Node Redis connection to this Redis OM client. Closes * any existing connection. * * @param connection An existing Node Redis client. * @returns This {@link Client} instance. */ use(connection: RedisConnection): Promise<Client>; /** * Attaches an existing Node Redis connection to this Redis OM client. Does * not close any existing connection. * * @param connection An existing Node Redis client. * @returns This {@link Client} instance. */ useNoClose(connection: RedisConnection): Client; /** * Open a connection to Redis at the provided URL. * * @param url A URL to Redis as defined with the [IANA](https://www.iana.org/assignments/uri-schemes/prov/redis). * @returns This {@link Client} instance. */ open(url?: string): Promise<Client>; /** * Creates a repository for the given schema. * * @param schema The schema. * @returns A repository for the provided schema. */ fetchRepository(schema: Schema): Repository; /** * Close the connection to Redis. */ close(): Promise<void>; /** @internal */ createIndex(indexName: string, schema: RediSearchSchema, options: CreateOptions): Promise<void>; /** @internal */ dropIndex(indexName: string): Promise<void>; /** @internal */ search(indexName: string, query: string, options?: SearchOptions): Promise<SearchResults>; /** @internal */ unlink(...keys: string[]): Promise<void>; /** @internal */ expire(key: string, ttl: number): Promise<void>; /** @internal */ expireAt(key: string, timestamp: Date): Promise<void>; /** @internal */ get(key: string): Promise<string | null>; /** @internal */ set(key: string, value: string): Promise<void>; /** @internal */ hgetall(key: string): Promise<RedisHashData>; /** @internal */ hsetall(key: string, data: RedisHashData): Promise<void>; /** @internal */ jsonget(key: string): Promise<RedisJsonData | null>; /** @internal */ jsonset(key: string, data: RedisJsonData): Promise<void>; /** * @returns Whether a connection is already open. */ isOpen(): boolean; } declare class RedisOmError extends Error { } declare class InvalidInput extends RedisOmError { } declare class NullJsonInput extends InvalidInput { #private; constructor(field: Field); get fieldName(): string; get fieldType(): FieldType; get jsonPath(): string; } declare class InvalidJsonInput extends InvalidInput { #private; constructor(field: Field); get fieldName(): string; get fieldType(): FieldType; get jsonPath(): string; } declare class InvalidHashInput extends InvalidInput { #private; constructor(field: Field); get fieldName(): string; get fieldType(): FieldType; } declare class NestedHashInput extends InvalidInpu