fraci
Version:
Fractional indexing that's robust, performant, and secure, with first-class support for Drizzle ORM and Prisma ORM.
430 lines (423 loc) • 20.1 kB
TypeScript
import * as _prisma_client_extension_js from '@prisma/client/extension.js';
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.js';
import { Prisma } from '@prisma/client';
/**
* The Prisma conflict error code.
*/
declare const PRISMA_CONFLICT_CODE = "P2002";
/**
* {@link PrismaClientKnownRequestError} of the conflict error.
*/
type PrismaClientConflictError = {
name: "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.
*
* @template C - The Prisma client type
*
* @example "article" | "photo" | "user"
*/
type ModelKey<C> = Extract<Exclude<keyof C, `$${string}`>, string>;
/**
* The payload of a model containing only scalar fields.
*
* @template C - The Prisma client type
* @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<C, M extends ModelKey<C>> = C extends Record<M, {
[K: symbol]: {
types: {
payload: {
scalars: any;
};
};
};
}> ? C[M][symbol]["types"]["payload"]["scalars"] : never;
/**
* A union of the field names of a model.
*
* @template C - The Prisma client type
* @template M - The model name
*
* @example "id" | "title" | "content" | "fi" | "userId" | "createdAt" | "updatedAt", where M = "article"
*/
type AllModelFieldName<C, M extends ModelKey<C>> = Extract<keyof ModelScalarPayload<C, M>, string>;
/**
* A union of the field names of a model that are of type `T`.
*
* @template C - The Prisma client type
* @template M - The model name
* @template T - The type of the field
*
* @example "title" | "content" | "fi", where M = "article" and T = string
*/
type ModelFieldNameByType<C, M extends ModelKey<C>, T> = {
[F in AllModelFieldName<C, M>]: ModelScalarPayload<C, M>[F] extends T ? F : never;
}[AllModelFieldName<C, M>];
/**
* A union of the field names of a model that are serializable.
*
* @template C - The Prisma client type
* @template M - The model name
*
* @example "id" | "title" | "content" | "fi" | "userId", where M = "article"
*/
type SerializableModelFieldName<C, M extends ModelKey<C>> = ModelFieldNameByType<C, M, boolean | bigint | number | string>;
/**
* A union of the field names of a model that are of type `string`.
*
* @template C - The Prisma client type
* @template M - The model name
*
* @example "title" | "content" | "fi", where M = "User"
*/
type StringModelFieldName<C, M extends ModelKey<C>> = ModelFieldNameByType<C, M, string>;
/**
* A union of the field names of a model that are of type `Uint8Array`.
*
* @template C - The Prisma client type
* @template M - The model name
*
* @example "title" | "content" | "fi", where M = "User"
*/
type BinaryModelFieldName<C, M extends ModelKey<C>> = ModelFieldNameByType<C, 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.
*
* @template C - The Prisma client type
*
* @example ["article.title", "id" | "content" | "fi" | "userId", "string"] | ["article.fi", "id" | "title" | "content" | "userId", "string"] | ... | ["user.fi", "id" | "name" | "email", "binary"] | ...
*/
type QualifiedFields<C> = {
[M in ModelKey<C>]: {
[F in BinaryModelFieldName<C, M>]: [
`${M}.${F}`,
Exclude<SerializableModelFieldName<C, M>, F>,
"binary"
];
}[BinaryModelFieldName<C, M>] | {
[F in StringModelFieldName<C, M>]: [
`${M}.${F}`,
Exclude<SerializableModelFieldName<C, M>, F>,
"string"
];
}[StringModelFieldName<C, M>];
}[ModelKey<C>];
/**
* The arguments for the `findMany` method of a Prisma model.
*
* @template M - The model name
*/
type QueryArgs<C, M extends ModelKey<C> = ModelKey<C>> = Prisma.Args<C[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.
*
* @template Client - The Prisma client type
*
* @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<Client> = {
readonly [Q in QualifiedFields<Client>[0]]?: PrismaFraciFieldOptions<Extract<QualifiedFields<Client>, [Q, any, any]>[1], Extract<QualifiedFields<Client>, [Q, any, any]>[2]> | undefined;
};
/**
* The options for the fractional indexing extension.
*
* @template Client - The Prisma client type
*
* @example { fields: { "article.fi": { group: ["userId"], lengthBase: "0123456789", digitBase: "0123456789" } } }
*
* @see {@link PrismaFraciFieldOptions} - The unified type for fractional index field options
* @see {@link PrismaFraciFieldOptionsRecord} - The record of the fractional index fields
*/
interface PrismaFraciOptions<Client> {
/**
* 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<Client>;
}
/**
* 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 Client - The Prisma client type
* @template Options - The options type
*
* @param _clientOrConstructor - The Prisma client or constructor. Only used for type inference and not used at runtime.
* @param options - The options for the fractional indexing extension
* @returns The options object with default values applied
*/
declare function definePrismaFraci<Client, const Options extends PrismaFraciOptions<Client>>(_clientOrConstructor: (new (...args: any) => Client) | ((...args: any) => Client) | Client, 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 Client - The Prisma client type
* @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<Client, Model extends ModelKey<Client>, 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<Client, Model>["where"], cursor: QueryArgs<Client, Model>["cursor"], client?: Client): Promise<Indices<FI> | undefined>;
(where: Where & QueryArgs<Client, Model>["where"], cursor: null, client?: Client): 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<Client>["where"], cursor: QueryArgs<Client>["cursor"], client?: Client): Promise<Indices<FI> | undefined>;
(where: Where & QueryArgs<Client>["where"], cursor: null, client?: Client): 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<Client, Model>["where"], client?: Client): 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<Client, Model>["where"], client?: Client): 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 Client - The Prisma client type
* @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<Client, Options extends PrismaFraciFieldOptions, Model extends ModelKey<Client>, Field extends BinaryModelFieldName<Client, Model> | StringModelFieldName<Client, Model>> = FraciForPrismaInternal<Client, Model, Pick<ModelScalarPayload<Client, Model>, Extract<Options["group"][number], AllModelFieldName<Client, Model>>>, Field extends BinaryModelFieldName<Client, 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 Client - The Prisma client type
* @template Options - The options type
* @template QualifiedField - The qualified field name
*
* @see {@link Fraci} - The main fractional indexing utility type
*/
type FraciForPrisma<Client, Options extends PrismaFraciOptions<Client>, QualifiedField extends keyof Options["fields"]> = Options["fields"][QualifiedField] extends PrismaFraciFieldOptions ? QualifiedField extends `${infer M extends ModelKey<Client>}.${infer F}` ? F extends BinaryModelFieldName<Client, M> ? FraciForPrismaByFieldOptions<Client, Options["fields"][QualifiedField], M, F> : F extends StringModelFieldName<Client, M> ? FraciForPrismaByFieldOptions<Client, Options["fields"][QualifiedField], M, F> : never : never : never;
/**
* A union of the pairs of the key and value of the {@link PrismaFraciOptions.fields fields} property of the options.
*
* @template Client - The Prisma client type
* @template Options - The options type
*
* @example ["article.fi", { group: ["userId"], lengthBase: "0123456789", digitBase: "0123456789" }] | ["photo.fi", { group: ["userId"], lengthBase: "0123456789", digitBase: "0123456789" }] | ...
*/
type FieldsUnion<Client, Options extends PrismaFraciOptions<Client>> = {
[K in keyof Options["fields"]]: [K, Options["fields"][K]];
}[keyof Options["fields"]];
/**
* The field information for each model.
*
* @template Client - The Prisma client type
* @template Options - The options type
*/
type PerModelFieldInfo<Client, Options extends PrismaFraciOptions<Client>> = {
[M in ModelKey<Client>]: {
[F in BinaryModelFieldName<Client, M> | StringModelFieldName<Client, M> as `${M}.${F}` extends FieldsUnion<Client, Options>[0] ? F : never]: {
readonly helper: Options["fields"][`${M}.${F}`] extends PrismaFraciFieldOptions ? FraciForPrismaByFieldOptions<Client, 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 Client - The Prisma client type
* @template Options - The options type
*/
type PrismaFraciExtensionModel<Client, Options extends PrismaFraciOptions<Client>> = {
[M in keyof PerModelFieldInfo<Client, Options>]: {
fraci<F extends keyof PerModelFieldInfo<Client, Options>[M]>(field: F): PerModelFieldInfo<Client, Options>[M][F]["helper"];
};
};
/**
* The type of our Prisma extension.
*
* @template Client - The Prisma client type
* @template Options - The options type
*/
type PrismaFraciExtension<Client, Options extends PrismaFraciOptions<Client>> = {
name: typeof EXTENSION_NAME;
model: PrismaFraciExtensionModel<Client, Options>;
};
/**
* Creates a Prisma extension for fractional indexing.
*
* @template Client - The Prisma client type
* @template Options - The options type
*
* @param _clientOrConstructor - The Prisma client or constructor. Only used for type inference and not used at runtime.
* @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<Client, const Options extends PrismaFraciOptions<Client>>(_clientOrConstructor: (new (...args: any) => Client) | ((...args: any) => Client) | Client, { fields, maxLength, maxRetries, }: Options): (client: any) => _prisma_client_extension_js.PrismaClientExtends<_prisma_client_runtime_library.InternalArgs<{}, PrismaFraciExtensionModel<Client, 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 };