import * as OutlineIcons from "@heroicons/react/24/outline"; import type { NextAdminJSONSchema } from "@premieroctet/next-admin-json-schema"; import type { NextApiRequest } from "next"; import type React from "react"; import type { ChangeEvent, ComponentProps, ReactNode } from "react"; import type { PropertyValidationError } from "./exceptions/ValidationError"; import type { Prisma, PrismaClient } from "./types-prisma"; declare type JSONSchema7Definition = NextAdminJSONSchema & { relation?: ModelName; }; type OmitNever = { [K in keyof T as T[K] extends never ? never : K]: T[K]; }; type ExtendsStringButIsNotString = T extends string ? string extends T ? false : true : false; /** Type for Model */ export type ModelName = Prisma.ModelName; export type Payload = Prisma.TypeMap["model"][ModelName]["payload"]; export type ModelPayload = Prisma.TypeMap["model"][M]["payload"]; export type ScalarField = ModelPayload["scalars"]; export type ObjectField = ModelPayload["objects"]; export type NonArrayObjectField = OmitNever<{ [K in keyof ModelPayload["objects"]]: ModelPayload["objects"][K] extends Array ? never : ModelPayload["objects"][K]; }>; export type ModelFromPayload

= { [Property in keyof P["scalars"]]: P["scalars"][Property]; } & { [Property in keyof P["objects"]]: P["objects"][Property] extends { scalars: infer S; } ? T extends object ? S : T : never | P["objects"][Property] extends { scalars: infer S; }[] ? T extends object ? S[] : T[] : never | P["objects"][Property] extends { scalars: infer S; } | null ? T extends object ? S | null : T | null : never; }; export type Model = ModelFromPayload; export type PropertyPayload> = Prisma.TypeMap["model"][M]["payload"]["objects"][P] extends Array ? T : never | Prisma.TypeMap["model"][M]["payload"]["objects"][P] extends infer T | null ? T : never | Prisma.TypeMap["model"][M]["payload"]["objects"][P]; export type ModelFromProperty> = PropertyPayload extends Payload ? ModelFromPayload> : never; export type ModelWithoutRelationships = Model; export type NoticeField = { readonly id: string; title: string; description?: string; }; type GreaterThan = S["length"] extends A ? false : S["length"] extends B ? true : GreaterThan; type LessThan = S["length"] extends B ? false : S["length"] extends A ? true : LessThan; type Substract = LessThan extends true ? never : LessThan extends true ? Substract extends true ? O : [...O, any]> : O["length"]; type Leaves = T extends object ? { [K in keyof T]: `${Exclude}${Leaves extends never ? "" : `.${Leaves>}`}`; }[keyof T] : never; export type NestableField

= { [K in keyof P["scalars"]]: true; } & { [K in keyof P["objects"]]: P["objects"][K] extends infer T | null ? T extends Payload ? GreaterThan extends true ? NestableField> : never : T extends Array ? U extends Payload ? GreaterThan extends true ? NestableField> : never : never : never : never; }; export type Field

= keyof Model

; /** Type for Form */ /** Type for Options */ export type ListFieldsOptions = { [P in Field]?: { /** * a function that takes the field value as a parameter, and that return a JSX node. It also accepts a second argument which is the `NextAdmin` context. * @param item * @param context * @returns */ formatter?: (item: P extends keyof ObjectField ? ObjectField[P] extends Array ? number : ModelFromProperty : Model[P], context?: NextAdminContext) => ReactNode; } & (P extends keyof NonArrayObjectField ? { /** * The field to use for relationship sorting, defaults to the id field */ sortBy?: keyof ModelFromProperty; } : {}); }; export declare enum LogicalOperator { And = "AND", Or = "OR", Not = "NOT" } export type Filter = Prisma.TypeMap["model"][T]["operations"]["findMany"]["args"]["where"]; export type FilterWrapper = { /** * a string to identify filter, must be unique */ name: string; /** * a boolean to set filter as default active on list page */ active?: boolean; /** * a Prisma filter, equivalent to `where` clause in Prisma queries * @link https://www.prisma.io/docs/orm/reference/prisma-client-reference#filter-conditions-and-operators */ value: Filter; /** * An id that will be used to give filters with the same group name a radio like behavior */ group?: string; }; type RelationshipSearch = { [S in keyof T]: { field: T[S] extends object ? S : never; }; }[keyof T]; type OptionFormatterFromRelationshipSearch> = { [S in RelationshipSearch>["field"]]: { /** * only for relation fields, a function that takes the field values as a parameter and returns a string. Useful to display your record in related list. * @param item * @returns */ relationOptionFormatter?: (item: ModelFromProperty[S]) => string; /** * model name on which to execute a research. Useful in case the field is related to an explicit many-to-many table */ relationshipSearchField?: S; } | { /** * only for relation fields, a function that takes the field values as a parameter and returns a string. Useful to display your record in related list. * @param item * @returns */ optionFormatter?: (item: ModelFromProperty) => string; }; }[RelationshipSearch>["field"]]; export type RelationshipPagination = { perPage?: number; }; export type ScalarArray = string[] | number[] | boolean[]; export type EditFieldsOptions = { [P in Field]?: { /** * a function that takes the field value as a parameter, and that returns a boolean. * @param value * @returns */ validate?: (value: ModelWithoutRelationships[P]) => true | string; /** * a string defining an OpenAPI field format, overriding the one set in the generator. An extra `file` format can be used to be able to have a file input. */ format?: FormatOptions[P]>; /** * an object that can take the following properties. */ handler?: Handler[P]>; /** * a React Element that should receive [`CustomInputProps`](#custominputprops). For App Router, this element must be a client component. Don't set any props, they will be passed automatically to the component. */ input?: React.ReactElement; /** * a helper text that is displayed underneath the input. */ helperText?: string; /** * a tooltip content to show for the field. */ tooltip?: string; /** * a boolean to indicate that the field is read only. */ disabled?: boolean; /** * a true value to force a field to be required in the form, note that if the field is required by the Prisma schema, you cannot set `required` to false */ required?: true; /** * a function that takes the field value as parameter and returns a boolean to determine if the field is displayed in the form. */ visible?: (value: ModelWithoutRelationships) => boolean; maxLength?: Model[P] extends ScalarArray ? number : never; } & (P extends keyof ObjectField ? OptionFormatterFromRelationshipSearch & ({ /** * Property to indicate how to display the multi select widget : * - `list`: displayed as a list of elements that has a link and a delete button * - `table`: displayed as the table list for a resource. Requires to have display options configured for the related model * - `select`: displayed as a multi select dropdown * * @default "select" */ display?: "select"; } | { display?: "table"; pagination?: RelationshipPagination; } | { display?: "list"; orderField?: keyof ModelFromProperty; pagination?: RelationshipPagination; }) : P extends keyof ScalarField ? ScalarField[P] extends (infer Q)[] ? ExtendsStringButIsNotString extends true ? { display?: "list" | "select"; } : {} : {} : {}); }; export type UploadedFile = { buffer: Buffer; infos: { name: string; type: string | null; }; }; export type Handler, T extends Model[P]> = { /** * a function that takes the field value as a parameter and returns a transformed value displayed in the form. * @param input * @returns */ get?: (input: T) => any; /** * an async function that is used only for formats `file` and `data-url`. It takes a buffer as parameter and must return a string. Useful to upload a file to a remote provider. * @param file - This object contains the file buffer and information. * @param context - This object contains record information, such as the resource ID. * @returns result - Promise - the file uri */ upload?: (buffer: Buffer, infos: { name: string; type: string | null; }, context: { /** * the resource ID if it exists, otherwise undefined */ resourceId: string | number | undefined; }) => Promise; /** * an async function that is used to remove a file from a remote provider * * @param fileUri string - the remote file uri * @returns success - Promise - true if the deletion succeeded, false otherwise. If false is returned, the file will not be removed from the record. */ deleteFile?: (fileUri: string) => Promise; /** * an optional string displayed in the input field as an error message in case of a failure during the upload handler. */ uploadErrorMessage?: string; /** * an async function that takes the resource value as parameter and returns a boolean. If false is returned, the deletion will not happen. * @param input * @returns boolean */ delete?: (input: T) => Promise | boolean; }; export type RichTextFormat = "html" | "json"; export type FormatOptions = T extends string ? "textarea" | "password" | "color" | "email" | "uri" | "data-url" | "date" | "date-time" | "time" | "time-second" | "alt-datetime" | "alt-date" | "file" | `richtext-${RichTextFormat}` | "json" : never | T extends Date ? "date" | "date-time" | "time" : never | T extends number ? "updown" | "range" : never | T extends string[] ? "file" : never; export type ListExport = { /** * a string defining the format of the export. It is mandatory. */ format: string; /** * a string defining the URL of the export. It is mandatory. */ url: string; }; export type FieldSort = { /** * the model's field name on which the sort is applied. It is mandatory. */ field: Field; /** * the sort direction to apply. It is optional */ direction?: Prisma.SortOrder; }; type VirtualFieldWithType = { formatter: (context: NextAdminContext>) => string; } & ({ type?: "link"; url: (context: NextAdminContext>) => string; } | { type?: Exclude; }); export type VirtualField = { key: string; label: string; dependsOn?: Field[]; } & (VirtualFieldWithType | { formatter: (context: NextAdminContext>) => React.ReactElement; type?: never; }); export type ListOptions = { /** * an url to export the list data as CSV. */ exports?: ListExport[] | ListExport; /** * an array of fields that are displayed in the list. * @default all scalar */ display?: Array | VirtualField>; /** * an array of searchable fields. * @default all scalar */ search?: Leaves>[]; /** * an array of fields that are copyable into the clipboard. * @default none */ copy?: Field[]; /** * an object containing the model fields as keys, and customization values. */ fields?: ListFieldsOptions; /** * an optional object to determine the default sort to apply on the list. */ defaultSort?: FieldSort | FieldSort[]; /** * An optional field to enable ordering on the list. * ⚠️ When enabled, it will disable all other types of sorting. * @restriction Only scalar fields are allowed, and primary keys are not permitted. The field must be a numeric type. */ orderField?: keyof ScalarField; /** * define a set of Prisma filters that user can choose in list */ filters?: Array | (() => Promise[]>)>; /** * define a set of Prisma filters that are always active in list */ where?: Filter[]; /** * an optional number indicating the default amount of items in the list */ defaultListSize?: number; }; export type RelationshipsRawData = Record; export type SubmitResourceResponse = { error: string; updated?: undefined; data?: undefined; redirect?: undefined; created?: undefined; createdId?: undefined; validation?: undefined; } | { error: string; updated?: undefined; data?: undefined; redirect?: undefined; created?: undefined; createdId?: undefined; validation: PropertyValidationError[]; } | { error?: undefined; updated: true; data: any; redirect: boolean; created?: undefined; createdId?: undefined; validation?: undefined; relationshipsRawData?: RelationshipsRawData; } | { error?: undefined; updated?: undefined; data: any; redirect: boolean; created: true; createdId: any; validation?: undefined; relationshipsRawData?: RelationshipsRawData; }; export type EditModelHooks = { /** * a function that is called before the form data is sent to the database. * * @param data - the form data as a record * @param mode - the mode of the form, either "create" or "edit" * @param request - the request object. Note: on App Router, it will not be possible to call `formData` as the handler already calls it once * @returns the transformed form data record or a Response or NextApiResponse. * @throws HookError - if the hook fails, the status and message will be sent in the handler's response */ beforeDb?: (data: Record, mode: "create" | "edit", request: Request | NextApiRequest) => Promise>; /** * a function that is called after the form submission. It takes the response of the db insertion as a parameter. * @param data */ afterDb?: (data: SubmitResourceResponse, mode: "create" | "edit", request: Request | NextApiRequest) => Promise; }; export type EditOptions = { /** * an array of fields that are displayed in the form. It can also be an object that will be displayed in the form of a notice. * @default all scalar */ display?: Array | NoticeField | (string & {})>; /** * an object containing the styles of the form. */ styles?: { /** * a string defining the classname of the form. */ _form?: string; } & Partial<{ [Key in Field]: string; } & Record>; /** * an object containing the model fields as keys, and customization values. */ fields?: EditFieldsOptions; /** * a message displayed if an error occurs during the form submission, after the form validation and before any call to prisma. */ submissionErrorMessage?: string; /** * a set of hooks to call before and after the form data insertion into the database. */ hooks?: EditModelHooks; customFields?: CustomFieldsType; }; type CustomFieldsType = { [key: string]: { input?: React.ReactElement; tooltip?: string; format?: FormatOptions; helperText?: string; required?: boolean; }; }; export type ActionStyle = "default" | "destructive"; export type MessageData = { type: "error" | "info" | "success"; message: string; }; export type ServerActionCustomComponent = React.ReactElement<{ message?: string; }>; export type MessageDataWithCustomComponent = MessageData & { component?: ServerActionCustomComponent; }; export type MessageContextType = { showMessage: (message: MessageDataWithCustomComponent) => void; message: MessageDataWithCustomComponent | null; hideMessage: () => void; }; export type BareModelAction = { title: string; id: string; canExecute?: (item: Model) => boolean; icon?: keyof typeof OutlineIcons; style?: ActionStyle; /** * Max depth of the related records to select * * @default 2 */ depth?: number; }; export type ServerAction = { type: "server"; action: (ids: string[] | number[]) => Promise; successMessage?: string; errorMessage?: string; /** * Component shown inside the Message component. If not passed, the message * string is displayed in a `p` HTML element. */ component?: ServerActionCustomComponent; } & BareModelAction; export type ClientAction = { type: "dialog"; component: React.ReactElement>; /** * Class name to apply to the dialog content */ className?: string; } & BareModelAction; export type ModelAction = ServerAction | ClientAction; export type UnionModelAction = { [M in ModelName]: ModelAction; }[ModelName]; export type OutputModelAction = (Omit & { allowedIds?: string[] | number[]; })[]; export type ModelIcon = keyof typeof OutlineIcons; export declare enum Permission { CREATE = "create", EDIT = "edit", DELETE = "delete" } export type PermissionType = "create" | "edit" | "delete"; export type ModelMiddleware = { /** * a function that is called before the form data is sent to the database. * @param data - the form data as a record * @param currentData - the current data in the database * @returns boolean - if false is returned, the update will not happen. */ edit?: (updatedData: Model, currentData: Model) => Promise | boolean; /** * a function that is called before resource is deleted from the database. * @param data - the current data in the database * @returns boolean - if false is returned, the deletion will not happen. */ delete?: (data: Model) => Promise | boolean; }; export type ModelOptions = { [P in T]?: { /** * a function that is used to display your record in related list. * @default "id" */ toString?: (item: Model

) => string; /** * define list options for this model. */ list?: ListOptions

; /** * define edit options for this model. */ edit?: EditOptions

; /** * a string used to display the model name in the sidebar and in the section title. */ title?: string; /** * an object containing the aliases of the model fields as keys, and the field name. */ aliases?: Partial, string>> & { [key: string]: string; }; actions?: ModelAction

[]; /** * the outline HeroIcon name displayed in the sidebar and pages title * @type ModelIcon * @link https://heroicons.com/outline */ icon?: ModelIcon; permissions?: PermissionType[]; middlewares?: ModelMiddleware

; }; }; export type SidebarGroup = { /** * Some optional css classes to improve appearance of group title. */ className?: string; /** * the name of the group. */ title: string; /** * the model names to display in the group. */ models: ModelName[]; }; export type SidebarConfiguration = { /** * an array of objects that creates groups for specific resources. */ groups: SidebarGroup[]; }; export type ExternalLink = { /** * the label of the link displayed on the sidebar. This is mandatory. */ label: string; /** * the URL of the link. This is mandatory. */ url: string; }; export type NextAdminOptions = { /** * Global admin title * * @default "Admin" */ title?: ReactNode; /** * `model` is an object that represents the customization options for each model in your schema. */ model?: ModelOptions; /** * `pages` is an object that allows you to add your own sub pages as a sidebar menu entry. */ pages?: Record; /** * The `sidebar` property allows you to customise the aspect of the sidebar menu. */ sidebar?: SidebarConfiguration; /** * The `externalLinks` property allows you to add external links to the sidebar menu. */ externalLinks?: ExternalLink[]; /** * The `forceColorScheme` property defines a default color palette between `light`, `dark` and `system`, don't allows the user to modify it. * @default 'system' */ forceColorScheme?: ColorScheme; /** * The `defaultColorScheme` property defines a default color palette between `light`, `dark` and `system`, but allows the user to modify it. * @default 'system' */ defaultColorScheme?: ColorScheme; }; /** Type for Schema */ export type SchemaProperty = { [P in Field]?: NextAdminJSONSchema & { items?: JSONSchema7Definition; relation?: ModelName; }; }; export type SchemaModel = Partial> & { properties: SchemaProperty; }; export type SchemaDefinitions = { [M in ModelName]: SchemaModel; }; export type Schema = Partial> & { definitions: SchemaDefinitions; }; export type AdminFormData = { [P in Field]?: string; }; export type Body = { [P in keyof F]?: string; } & { [key: string]: string; }; export type Order = { [P in Field]?: Prisma.SortOrder | { _count: Prisma.SortOrder; } | { [key: string]: Prisma.SortOrder; }; }; export type Select = { [P in Field]?: boolean; } & { _count?: { select: { [key in string]: boolean; }; }; }; export type Enumeration = { label: string; value: string; data?: any; }; export type PrismaListRequest = { select?: Select; where?: {}; orderBy?: Order; skip?: number; take?: number; }; export type ListData = ListDataItem[]; export type ListDataItem = Model & Record; export type ListDataFieldValueWithFormat = { __nextadmin_formatted: React.ReactNode; }; export type ListDataFieldValue = ListDataFieldValueWithFormat & ({ type: "scalar"; value: string | number | boolean; } | { type: "count"; value: number; } | { type: "link"; value: { label: string; url: string; }; isOverridden?: boolean | null; } | { type: "date"; value: Date; }); export type UserData = { name: string; picture?: string; }; export type AdminUser = { data: UserData; logout?: [RequestInfo, RequestInit?] | (() => void | Promise) | string; }; export type AdminComponentProps = { basePath: string; apiBasePath: string; schema: Schema; data?: ListData; rawData?: any[]; relationshipsRawData?: RelationshipsRawData; listFilterOptions?: Array>; resource?: ModelName | null; slug?: string; /** * Page router only */ message?: { type: "success" | "info"; content: string; }; error?: string | null; validation?: PropertyValidationError[]; resources?: ModelName[]; total?: number; isAppDir?: boolean; locale?: string | null; /** * Mandatory for page router */ options?: NextAdminOptions; resourcesTitles?: Record; resourcesIcons?: Record; customInputs?: Record, React.ReactElement | undefined> | null; resourcesIdProperty?: Record; /** * App router only */ pageComponent?: React.ComponentType; customPages?: Array<{ title: string; path: string; icon?: ModelIcon; }>; actions?: OutputModelAction; translations?: Translations; /** * Global admin title * * @default "Admin" */ title?: ReactNode; sidebar?: SidebarConfiguration; user?: AdminUser; externalLinks?: ExternalLink[]; dialogComponents?: Record>> | null; }; export type AppRouterComponentProps = AdminComponentProps; export type PageRouterComponentProps = AppRouterComponentProps | Omit | Pick; export type MainLayoutProps = Pick; export type CustomUIProps = { dashboard?: React.JSX.Element | (() => React.JSX.Element); pageLoader?: React.JSX.Element; }; export type ActionFullParams = ActionParams & { prisma: PrismaClient; options: NextAdminOptions; }; export type ActionParams = { params?: string[]; schema: any; }; export type SubmitFormResult = { deleted?: boolean; created?: boolean; updated?: boolean; redirect?: boolean; error?: string; createdId?: number; validation?: any; }; export type NextAdminContext = { locale?: string | null; row?: ModelData; }; export type CustomInputProps = Partial<{ name: string; value: string; onChange: (evt: ChangeEvent) => void; readonly: boolean; rawErrors: string[]; disabled: boolean; required?: boolean; mode: "create" | "edit"; item: TItem; }> & ComponentProps<"input">; export type TranslationKeys = "actions.delete.label" | "actions.label" | "export.label" | "actions.create.label" | "actions.edit.label" | "form.button.delete.label" | "form.delete.alert" | "form.button.save.label" | "form.button.save_edit.label" | "list.empty.label" | "list.empty.caption" | "list.footer.indicator.showing" | "list.footer.indicator.to" | "list.footer.indicator.of" | "list.header.add.label" | "list.header.search.placeholder" | "list.header.result" | "list.header.search.result" | "list.header.search.result_filtered" | "list.row.actions.delete.label" | "list.row.actions.delete.alert" | "list.row.actions.delete.success" | "list.row.actions.delete.error" | "list.row.actions.export" | "form.widgets.file_upload.label" | "form.widgets.file_upload.drag_and_drop" | "form.widgets.file_upload.delete" | "form.widgets.multiselect.select" | "form.widgets.scalar_array.add" | "selector.loading" | "theme.dark" | "theme.light" | "theme.system" | "user.logout" | "search.advanced.title" | "search.advanced.add" | "search.advanced.clear" | "search.advanced.cancel" | "search.advanced.save" | "search.advanced.and_or_group" | "search.advanced.conditions.equals" | "search.advanced.conditions.not" | "search.advanced.conditions.in" | "search.advanced.conditions.notIn" | "search.advanced.conditions.lt" | "search.advanced.conditions.lte" | "search.advanced.conditions.gt" | "search.advanced.conditions.gte" | "search.advanced.conditions.contains" | "search.advanced.conditions.search" | "search.advanced.conditions.startsWith" | "search.advanced.conditions.endsWith" | "search.advanced.conditions.null" | "search.advanced.conditions.nnull"; export type Translations = { [key in TranslationKeys]?: string; } & { [key: string]: string; }; export declare const colorSchemes: string[]; export type ColorScheme = (typeof colorSchemes)[number]; export type BasicColorScheme = Exclude; export type PageProps = { params: { [key: string]: string[] | string; }; searchParams: { [key: string]: string | string[] | undefined; } | undefined; }; export type PromisePageProps = { [key in keyof PageProps]: Promise; }; export type GetNextAdminPropsParams = { /** * `params` is an array of strings that represents the dynamic segments of your route. (e.g. `[[...params]]`) */ params?: string | string[]; /** * `searchParams` is an object that represents the query parameters of your route. (e.g. `?key=value`) */ searchParams: { [key: string]: string | string[] | undefined; } | undefined; /** * `basePath` is a string that represents the base path of your admin. (e.g. `/admin`) */ basePath: string; /** * `apiBasePath` is a string that represents the base path of the admin API route. (e.g. `/api/admin`) */ apiBasePath: string; /** * `options` is an object that represents the options of your admin. * @link https://next-admin.js.org/docs/api-docs#next-admin-options */ options?: NextAdminOptions; /** * `prisma` is an instance of PrismaClient. */ prisma: PrismaClient; isAppDir?: boolean; /** * `locale` is a string that represents the locale of your admin. (e.g. `en`) */ locale?: string; /** * `getMessages` is a function that returns a promise of an object that represents the translations of your admin. * @param locale * @returns */ getMessages?: (locale: string) => Promise>; }; export type GetMainLayoutPropsParams = Omit; export type RequestContext

= { params: Promise<{ [key in P]: string[]; }>; }; export type CreateAppHandlerParams

= { /** * `apiBasePath` is a string that represents the base path of the admin API route. (e.g. `/api`) - optional. */ apiBasePath: string; /** * Next-admin options */ options?: NextAdminOptions; /** * Prisma client instance */ prisma: PrismaClient; /** * A function that acts as a middleware. Useful to add authentication logic for example. */ onRequest?: (req: Request, ctx: RequestContext

) => ReturnType | ReturnType | Promise; /** * A string indicating the name of the dynamic segment. * * Example: * - If the dynamic segment is `[[...nextadmin]]`, then the `paramKey` should be `nextadmin`. * - If the dynamic segment is `[[...admin]]`, then the `paramKey` should be `admin`. * * @default "nextadmin" */ paramKey?: P; }; export type FormProps = { data: any; schema: SchemaDefinitions[ModelName]; resource: ModelName; slug?: string; validation?: PropertyValidationError[]; title: string; customInputs?: Record, React.ReactElement | undefined> | null; actions?: AdminComponentProps["actions"]; icon?: ModelIcon; resourcesIdProperty: Record; clientActionsComponents?: AdminComponentProps["dialogComponents"]; relationshipsRawData?: RelationshipsRawData; }; export type ClientActionDialogContentProps = Partial<{ resource: ModelName; resourceIds: Array; data: Array>; onClose: (message?: MessageData) => void; }>; export {}; //# sourceMappingURL=types.d.ts.map