UNPKG

fraci

Version:

Fractional indexing that's robust, performant, and secure, with first-class support for Drizzle ORM and Prisma ORM.

396 lines (389 loc) 18 kB
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library.js'; import * as _prisma_client_extension_js from '@prisma/client/extension.js'; import { PrismaClient, Prisma } from '@prisma/client'; import * as _prisma_client_runtime_library from '@prisma/client/runtime/library'; import { a as AnyFractionalIndex, o as FraciOf, s as FractionalIndex } from './types-Gn-I8HuO.cjs'; /** * The Prisma conflict error code. */ declare const PRISMA_CONFLICT_CODE = "P2002"; /** * {@link PrismaClientKnownRequestError} of the conflict error. */ type PrismaClientConflictError = PrismaClientKnownRequestError & { code: typeof PRISMA_CONFLICT_CODE; meta: { modelName: string; target: string[]; }; }; /** * The extension name for the Prisma fractional indexing extension. */ declare const EXTENSION_NAME = "fraci"; /** * A union of all model names. * * @example "article" | "photo" | "user" */ type ModelKey = Extract<Exclude<keyof PrismaClient, `$${string}`>, string>; /** * The payload of a model containing only scalar fields. * * @template M - The model name * * @example { id: number; title: string; content: string; fi: string; userId: number; createdAt: Date; updatedAt: Date }, where M = "article" */ type ModelScalarPayload<M extends ModelKey> = PrismaClient[M][symbol]["types"]["payload"]["scalars"]; /** * A union of the field names of a model. * * @template M - The model name * * @example "id" | "title" | "content" | "fi" | "userId" | "createdAt" | "updatedAt", where M = "article" */ type AllModelFieldName<M extends ModelKey> = Extract<keyof ModelScalarPayload<M>, string>; /** * A union of the field names of a model that are of type `T`. * * @template M - The model name * @template T - The type of the field * * @example "title" | "content" | "fi", where M = "article" and T = string */ type ModelFieldNameByType<M extends ModelKey, T> = { [F in AllModelFieldName<M>]: ModelScalarPayload<M>[F] extends T ? F : never; }[AllModelFieldName<M>]; /** * A union of the field names of a model that are serializable. * * @template M The model name * * @example "id" | "title" | "content" | "fi" | "userId", where M = "article" */ type SerializableModelFieldName<M extends ModelKey> = ModelFieldNameByType<M, boolean | bigint | number | string>; /** * A union of the field names of a model that are of type `string`. * * @template M The model name * * @example "title" | "content" | "fi", where M = "User" */ type StringModelFieldName<M extends ModelKey> = ModelFieldNameByType<M, string>; /** * A union of the field names of a model that are of type `Uint8Array`. * * @template M The model name * * @example "title" | "content" | "fi", where M = "User" */ type BinaryModelFieldName<M extends ModelKey> = ModelFieldNameByType<M, Uint8Array>; /** * A union of a tuple of 1) a qualified binary or string field key and 2) a union of the names of the other serializable fields of its model. * * @example ["article.title", "id" | "content" | "fi" | "userId", "string"] | ["article.fi", "id" | "title" | "content" | "userId", "string"] | ... | ["user.fi", "id" | "name" | "email", "binary"] | ... */ type QualifiedFields = { [M in ModelKey]: { [F in BinaryModelFieldName<M>]: [ `${M}.${F}`, Exclude<SerializableModelFieldName<M>, F>, "binary" ]; }[BinaryModelFieldName<M>] | { [F in StringModelFieldName<M>]: [ `${M}.${F}`, Exclude<SerializableModelFieldName<M>, F>, "string" ]; }[StringModelFieldName<M>]; }[ModelKey]; /** * Prisma client or transaction client. */ type AnyPrismaClient = PrismaClient | Prisma.TransactionClient; /** * The arguments for the `findMany` method of a Prisma model. * * @template M - The model name */ type QueryArgs<M extends ModelKey> = Prisma.Args<PrismaClient[M], "findMany">; /** * The options for the binary fractional index fields. * * @template Group - The type of the name of the group fields * * @example { type: "binary", group: ["userId"] } * * @see {@link PrismaFraciFieldOptions} - The unified type for fractional index field options * @see {@link PrismaFraciFieldOptionsString} - The string fractional index field options * @see {@link PrismaFraciOptions} - The options for the fractional indexing extension */ interface PrismaFraciFieldOptionsBinary<Group extends string = string> { /** * The type of the fractional index. * Must be "binary" for binary fractional indices. */ readonly type: "binary"; /** * The fields that define the grouping context for the fractional index. * This is an array of field names. */ readonly group: readonly Group[]; } /** * The options for the string fractional index fields. * * @template Group - The type of the name of the group fields * * @example { group: ["userId"], lengthBase: "0123456789", digitBase: "0123456789" } * * @see {@link PrismaFraciFieldOptions} - The unified type for fractional index field options * @see {@link PrismaFraciFieldOptionsBinary} - The binary fractional index field options * @see {@link PrismaFraciOptions} - The options for the fractional indexing extension */ interface PrismaFraciFieldOptionsString<Group extends string = string> { /** * The type of the fractional index. * Must be "string" or `undefined` for string fractional indices. */ readonly type?: "string" | undefined; /** * The fields that define the grouping context for the fractional index. * This is an array of field names. */ readonly group: readonly Group[]; /** * The character set used for encoding the length of the integer part. */ readonly lengthBase: string; /** * The character set used for representing digits in the fractional index. */ readonly digitBase: string; } /** * The options for the fractional index fields. * * @template Group - The type of the name of the group fields * * @example { group: ["userId", "title"], lengthBase: "0123456789", digitBase: "0123456789" } * * @see {@link PrismaFraciFieldOptionsBinary} - The binary fractional index field options * @see {@link PrismaFraciFieldOptionsString} - The string fractional index field options * @see {@link PrismaFraciOptions} - The options for the fractional indexing extension */ type PrismaFraciFieldOptions<Group extends string = string, Mode extends "binary" | "string" = "binary" | "string"> = { readonly binary: PrismaFraciFieldOptionsBinary<Group>; readonly string: PrismaFraciFieldOptionsString<Group>; }[Mode]; /** * The record of the fractional index fields. * * @example { "article.fi": { group: ["userId"], lengthBase: "0123456789", digitBase: "0123456789" } } * * @see {@link PrismaFraciFieldOptions} - The unified type for fractional index field options * @see {@link PrismaFraciOptions} - The options for the fractional indexing extension */ type PrismaFraciFieldOptionsRecord = { readonly [Q in QualifiedFields[0]]?: PrismaFraciFieldOptions<Extract<QualifiedFields, [Q, any, any]>[1], Extract<QualifiedFields, [Q, any, any]>[2]> | undefined; }; /** * The options for the fractional indexing extension. */ interface PrismaFraciOptions { /** * The maximum number of retries to generate a fractional index. * * @default 5 */ readonly maxRetries?: number | undefined; /** * The maximum length of the fractional index. * * @default 50 */ readonly maxLength?: number | undefined; /** * The fractional index fields. */ readonly fields: PrismaFraciFieldOptionsRecord; } /** * Creates a Prisma extension for fractional indexing. * This function defines the options for integrating fractional indexing * into a Prisma schema, including field configurations and performance settings. * * @template Options - The options type * * @param options - The options for the fractional indexing extension * @returns The options object with default values applied */ declare function definePrismaFraci<const Options extends PrismaFraciOptions>(options: Options): Options; /** * A brand for Prisma models and fields. * * @template Model - The model name * @template Field - The field name */ type PrismaBrand<Model extends string, Field extends string> = { readonly __prisma__: { model: Model; field: Field; }; }; /** * A tuple of two fractional indices, used for generating a new index between them. * * @template FI - The fractional index type */ type Indices<FI extends AnyFractionalIndex> = [a: FI | null, b: FI | null]; /** * Type representing the enhanced fractional indexing utility for Prisma ORM. * This type extends the base fractional indexing utility with additional methods for retrieving indices. * * This is an internal type used to define the methods for the Prisma extension. * * @template Model - The model name * @template Where - The type of the required fields for the `where` argument of the `findMany` method * @template FI - The fractional index type * * @see {@link Fraci} - The base fractional indexing utility type */ type FraciForPrismaInternal<Model extends ModelKey, Where, FI extends AnyFractionalIndex> = FraciOf<FI> & { /** * Checks if the error is a conflict error for the fractional index. * * @param error - The error to check. * @returns `true` if the error is a conflict error for the fractional index, or `false` otherwise. */ isIndexConflictError(error: unknown): error is PrismaClientConflictError; /** * Retrieves the existing indices to generate a new fractional index for the item after the specified item. * * @param where - The `where` argument of the `findMany` method. Must have the fields specified in the {@link PrismaFraciFieldOptions.group group} property of the field options. * @param cursor - The cursor (selector) of the item. If `null`, this method returns the indices to generate a new fractional index for the first item. * @param client - The Prisma client to use. Should be specified when using transactions. If not specified, the client used to create the extension is used. * @returns The indices to generate a new fractional index for the item after the specified item, or `undefined` if the item specified by the `cursor` does not exist. */ indicesForAfter: { (where: Where & QueryArgs<Model>["where"], cursor: QueryArgs<Model>["cursor"], client?: AnyPrismaClient): Promise<Indices<FI> | undefined>; (where: Where & QueryArgs<Model>["where"], cursor: null, client?: AnyPrismaClient): Promise<Indices<FI>>; }; /** * Retrieves the existing indices to generate a new fractional index for the item before the specified item. * * @param where - The `where` argument of the `findMany` method. Must have the fields specified in the {@link PrismaFraciFieldOptions.group group} property of the field options. * @param cursor - The cursor (selector) of the item. If `null`, this method returns the indices to generate a new fractional index for the last item. * @param client - The Prisma client to use. Should be specified when using transactions. If not specified, the client used to create the extension is used. * @returns The indices to generate a new fractional index for the item before the specified item, or `undefined` if the item specified by the `cursor` does not exist. */ indicesForBefore: { (where: Where & QueryArgs<Model>["where"], cursor: QueryArgs<Model>["cursor"], client?: AnyPrismaClient): Promise<Indices<FI> | undefined>; (where: Where & QueryArgs<Model>["where"], cursor: null, client?: AnyPrismaClient): Promise<Indices<FI>>; }; /** * Retrieves the existing indices to generate a new fractional index for the first item. * Equivalent to {@link FraciForPrismaInternal.indicesForAfter `indicesForAfter(where, null, client)`}. * * @param where - The `where` argument of the `findMany` method. Must have the fields specified in the {@link PrismaFraciOptions.group group} property of the field options. * @param client - The Prisma client to use. Should be specified when using transactions. If not specified, the client used to create the extension is used. * @returns The indices to generate a new fractional index for the first item. */ indicesForFirst(where: Where & QueryArgs<Model>["where"], client?: AnyPrismaClient): Promise<Indices<FI>>; /** * Retrieves the existing indices to generate a new fractional index for the last item. * Equivalent to {@link FraciForPrismaInternal.indicesForBefore `indicesForBefore(where, null, client)`}. * * @param where - The `where` argument of the `findMany` method. Must have the fields specified in the {@link PrismaFraciOptions.group group} property of the field options. * @param client - The Prisma client to use. Should be specified when using transactions. If not specified, the client used to create the extension is used. * @returns The indices to generate a new fractional index for the last item. */ indicesForLast(where: Where & QueryArgs<Model>["where"], client?: AnyPrismaClient): Promise<Indices<FI>>; }; /** * Type representing the enhanced fractional indexing utility for Prisma ORM. * This type extends the base fractional indexing utility with additional methods for retrieving indices. * * @template Options - The field options type * @template Model - The model name * @template Field - The field name * * @see {@link Fraci} - The main fractional indexing utility type */ type FraciForPrismaByFieldOptions<Options extends PrismaFraciFieldOptions, Model extends ModelKey, Field extends BinaryModelFieldName<Model> | StringModelFieldName<Model>> = FraciForPrismaInternal<Model, Pick<ModelScalarPayload<Model>, Extract<Options["group"][number], AllModelFieldName<Model>>>, Field extends BinaryModelFieldName<Model> ? Options extends { readonly type: "binary"; } ? FractionalIndex<Options, PrismaBrand<Model, Field>> : never : Options extends { readonly lengthBase: string; readonly digitBase: string; } ? FractionalIndex<{ readonly type: "string"; readonly lengthBase: Options["lengthBase"]; readonly digitBase: Options["digitBase"]; }, PrismaBrand<Model, Field>> : never>; /** * Type representing the enhanced fractional indexing utility for Prisma ORM. * This type extends the base fractional indexing utility with additional methods for retrieving indices. * * @template Options - The options type * @template QualifiedField - The qualified field name * * @see {@link Fraci} - The main fractional indexing utility type */ type FraciForPrisma<Options extends PrismaFraciOptions, QualifiedField extends keyof Options["fields"]> = Options["fields"][QualifiedField] extends PrismaFraciFieldOptions ? QualifiedField extends `${infer M}.${infer F}` ? FraciForPrismaByFieldOptions<Options["fields"][QualifiedField], M, F> : never : never; /** * A union of the pairs of the key and value of the {@link PrismaFraciOptions.fields fields} property of the options. * * @template Options - The options type * * @example ["article.fi", { group: ["userId"], lengthBase: "0123456789", digitBase: "0123456789" }] | ["photo.fi", { group: ["userId"], lengthBase: "0123456789", digitBase: "0123456789" }] | ... */ type FieldsUnion<Options extends PrismaFraciOptions> = { [K in keyof Options["fields"]]: [K, Options["fields"][K]]; }[keyof Options["fields"]]; /** * The field information for each model. * * @template Options - The options type */ type PerModelFieldInfo<Options extends PrismaFraciOptions> = { [M in ModelKey]: { [F in BinaryModelFieldName<M> | StringModelFieldName<M> as `${M}.${F}` extends FieldsUnion<Options>[0] ? F : never]: { readonly helper: Options["fields"][`${M}.${F}`] extends PrismaFraciFieldOptions ? FraciForPrismaByFieldOptions<Options["fields"][`${M}.${F}`], M, F> : never; }; }; }; /** * [model component](https://www.prisma.io/docs/orm/prisma-client/client-extensions/model) of the Prisma extension. * * @template Options - The options type */ type PrismaFraciExtensionModel<Options extends PrismaFraciOptions> = { [M in keyof PerModelFieldInfo<Options>]: { fraci<F extends keyof PerModelFieldInfo<Options>[M]>(field: F): PerModelFieldInfo<Options>[M][F]["helper"]; }; }; /** * The type of our Prisma extension. * * @template Options - The options type */ type PrismaFraciExtension<Options extends PrismaFraciOptions> = { name: typeof EXTENSION_NAME; model: PrismaFraciExtensionModel<Options>; }; /** * Creates a Prisma extension for fractional indexing. * * @template Options - The options type * * @param options - The options for the fractional indexing extension * @returns The Prisma extension. * @throws {FraciError} Throws a {@link FraciError} when field information for a specified model.field cannot be retrieved * @throws {FraciError} Throws a {@link FraciError} when the digit or length base strings are invalid * * @see {@link FraciForPrisma} - The enhanced fractional indexing utility for Prisma ORM * @see {@link FraciError} - The custom error class for the Fraci library */ declare function prismaFraci<const Options extends PrismaFraciOptions>({ fields, maxLength, maxRetries, }: Options): (client: any) => _prisma_client_extension_js.PrismaClientExtends<_prisma_client_runtime_library.InternalArgs<{}, PrismaFraciExtensionModel<Options>, {}, {}> & _prisma_client_runtime_library.DefaultArgs>; export { type FraciForPrisma, type PrismaClientConflictError, type PrismaFraciExtension, type PrismaFraciFieldOptions, type PrismaFraciFieldOptionsBinary, type PrismaFraciFieldOptionsRecord, type PrismaFraciFieldOptionsString, type PrismaFraciOptions, definePrismaFraci, prismaFraci };