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
text/typescript
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 };