import type { OpenAPIV3 } from "../../bundled_openapi_types"; import type { Exception } from '@poppinss/utils'; import type { NextFn } from '@adonisjs/core/types/http'; import type { ContainerResolver } from '@adonisjs/fold'; import type { HookHandler } from '@poppinss/hooks/types'; import type { LucidModel } from '@adonisjs/lucid/types/model'; import type { ResourcefulModelSerializableAttributes } from "../types"; import type { ResourcefulModel, ResourcefulIndexResult } from "../mixin"; import type { HttpContext, Router, RouteGroup } from '@adonisjs/core/http'; import type { E_UNRESOLVABLE_MODEL } from "../../errors"; import type { ValidationError as JoiValidationError } from "../../joi"; import type { VineValidationError, ResourcefulQueryScopeCallback, ResourcefulPayloadSchemaGetter } from "../../types"; export type Resolvable = T | Promise | PromiseLike | Promise<{ default: T; }> | PromiseLike<{ default: T; }> | (() => T) | (() => Promise) | (() => PromiseLike) | (() => Promise<{ default: T; }>) | (() => PromiseLike<{ default: T; }>); /** * Map of resource names to their corresponding ResourcefulModel classes */ export type MacroModelsMap = { [key: string]: ResourcefulRouterModelMappedOptions; }; /** * Resolved map of resource names to their corresponding ResourcefulModel classes */ export type ResolvedModelsMap = { [key: string]: ResourcefulModel | E_UNRESOLVABLE_MODEL; }; /** * Route callback function type */ export type RouteFn = (ctx: HttpContext) => Promise | unknown; /** * Constructor type for controllers */ export type Constructor = new (...args: any[]) => T; /** * Lazy import type for controllers */ export type LazyImport = () => Promise<{ default: Constructor; }>; /** * Controller handler methods type */ export type GetControllerHandlers = { [K in keyof T as T[K] extends Function ? K : never]?: string; }; /** * Route callback that can be either a function or controller tuple */ export type RouteCallback = Constructor> = RouteFn | [ LazyImport | T, keyof InstanceType ]; /** * Middleware function type (simplified for now) */ export type MiddlewareFn = (ctx: HttpContext, next: () => Promise) => Promise; /** * Parsed named middleware type */ export interface ParsedNamedMiddleware { name: string; handle: (resolver: ContainerResolver, ...args: [ ctx: HttpContext, next: NextFn, params?: any ]) => any; args?: any[]; } export type MiddlewareAsClass = Constructor<{ handle: (ctx: HttpContext, next: NextFn, args?: any) => any; }>; /** * One or more middleware items */ export type OneOrMore = T | T[]; /** * Additional route details with OpenAPI metadata */ export interface AdditionalResourcefulRouteDetails { /** The title for the route in OpenAPI documentation */ title?: string; /** The description for the route in OpenAPI documentation */ description?: string; /** The handler for the route */ handler: RouteCallback; /** The parameters for the route in OpenAPI documentation */ parameters?: OpenAPIV3.ParameterObject[] | OpenAPIV3.ReferenceObject[]; /** The request body schema for the route in OpenAPI documentation */ requestPayloadSchema?: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject; /** The response body schema for the route in OpenAPI documentation */ responsePayloadSchema?: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject; /** The tags (or folders) in which route will be shown in OpenAPI documentation */ tags?: string | string[]; } export declare const ResourcefulHttpVerb: ("delete" | "get" | "post" | "put" | "patch")[]; export type ResourcefulHttpVerb = (typeof ResourcefulHttpVerb)[number]; export declare const ResourcefulResponseFormat: ("html" | "yaml" | "json")[]; export type ResourcefulResponseFormat = (typeof ResourcefulResponseFormat)[number]; export interface AdditionalResourcefulRoutesMap { [methodAndRelativePath: `${ResourcefulHttpVerb}|${string}`]: RouteCallback | AdditionalResourcefulRouteDetails; } export declare const ResourcefulRouterVerb: ("create" | "read" | "update" | "delete" | "index" | "readRelated" | "bulkUpdate" | "syncRelated")[]; export type ResourcefulRouterVerb = (typeof ResourcefulRouterVerb)[number]; export declare const ResourcefulRouterVerbMetaOperation: "meta"[]; export type ResourcefulRouterVerbMetaOperation = (typeof ResourcefulRouterVerbMetaOperation)[number]; export declare const ResourcefulRouterOperation: ("create" | "read" | "update" | "delete" | "index" | "readRelated" | "bulkUpdate" | "syncRelated" | "create:meta" | "read:meta" | "update:meta" | "delete:meta" | "index:meta" | "readRelated:meta" | "bulkUpdate:meta" | "syncRelated:meta")[]; export type ResourcefulRouterOperation = ResourcefulRouterVerb | `${ResourcefulRouterVerb}:${ResourcefulRouterVerbMetaOperation}`; export interface ResourcefulSecuritySchemaDefinition { key: string; schema: OpenAPIV3.SecuritySchemeObject; applyToModels: boolean | { [key: string]: boolean | Partial>>; }; applyToAdditional: boolean | Record<`${ResourcefulHttpVerb}|${string}`, boolean | Array>; } export interface ResourcefulIndexResponse extends Omit { } export type ResourcefulIndexResponseHook = HookHandler<[ ResourcefulIndexResponse, HttpContext ], [ error: Error | null, ResourcefulIndexResponse, HttpContext ]>; export type ResourceResourcefulRecordResponse = ResourcefulModelSerializableAttributes>; export type ResourceResourcefulRecordResponseHook = HookHandler<[ ResourceResourcefulRecordResponse, HttpContext ], [ error: Error | null, ResourceResourcefulRecordResponse, HttpContext ]>; export interface ResourcefulRouterMutatorOptions { index?: ResourcefulIndexResponseHook[]; create?: ResourceResourcefulRecordResponseHook[]; read?: ResourceResourcefulRecordResponseHook[]; readRelated?: ResourcefulIndexResponseHook[]; update?: ResourceResourcefulRecordResponseHook[]; } export interface ResourcefulPolicy { scope?: ResourcefulQueryScopeCallback; payload?: ResourcefulPayloadSchemaGetter; mutators?: ResourcefulRouterMutatorOptions; } /** * Configuration options for the resourceful router macro */ export interface ResourcefulRouterOptions { prefix: string; domain: string | null | undefined; middleware: OneOrMore; except: ResourcefulRouterVerb[]; additional: AdditionalResourcefulRoutesMap; info: OpenAPIV3.InfoObject; externalDocs?: OpenAPIV3.ExternalDocumentationObject; tagMap: { general: string; additional: string; }; catchThrown: boolean; onVineValidationError?: (error: VineValidationError) => void; onJoiValidationError?: (error: JoiValidationError) => void; onException?: (error: Exception) => void; onError?: (error: Error) => void; onUnknown?: (error: unknown) => void; onAny?: (error: unknown) => void; headers: { [key: string]: string; }; security: ResourcefulSecuritySchemaDefinition[]; scopeRestrictors?: ResourcefulQueryScopeCallback[]; payloadRestrictors?: ResourcefulPayloadSchemaGetter[]; policies?: ResourcefulPolicy[]; mutators?: ResourcefulRouterMutatorOptions; } export type ResourcefulRouterOptionsExcludedFromModelOptions = 'prefix' | 'domain' | 'info' | 'externalDocs' | 'tagMap' | 'catchThrown' | 'onVineValidationError' | 'onJoiValidationError' | 'onException' | 'onError' | 'onUnknown' | 'onAny' | 'security'; export interface ResourcefulRouterModelOptions extends Omit { model: Resolvable; crudActionMiddlewares?: Partial<{ [K in ResourcefulRouterVerb]: OneOrMore; }>; } export interface ResourcefulRouterModelMappedOptions extends Partial> { model: Resolvable; } export interface ResourcefulRouterModelServiceOptions extends Omit { } /** * Normalized additional route details for internal processing */ export interface NormalizedAdditionalResourcefulRouteDetails { /** The title for the route in OpenAPI documentation */ title: string; /** The description for the route in OpenAPI documentation */ description: string; /** The handler for the route */ handler: RouteCallback; /** The request body schema for the route in OpenAPI documentation */ requestPayloadSchema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | null; /** The response body schema for the route in OpenAPI documentation */ responsePayloadSchema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | null; /** The tags (or folders) in which route will be shown in OpenAPI documentation */ tags: string[]; } /** * Normalized additional routes for internal processing */ export interface NormalizedAdditionalResourcefulRoutes { index: Map | null; create: Map | null; read: Map | null; update: Map | null; delete: Map | null; } /** * Normalized configuration options for internal processing */ export interface NormalizedResourcefulRouterOptions { /** The prefix of all CRUD and additional routes (Example: "/api/v1/") */ prefix: string | null; /** The middleware to be applied to all routes, including CRUD and additional routes */ middleware: Array; /** The array of operations to exclude from the CRUD generated routes (Example: ["index", "create"]) */ except: ResourcefulRouterVerb[]; /** The additional routes to be generated (Example: { index: new Map([["/:id", (ctx) => ...)]]) ) */ additional: NormalizedAdditionalResourcefulRoutes; } /** * Generated route configuration used internally by services */ export interface GeneratedRoute { method: string; path: string; handler: RouteCallback; middleware: Array; name: string; isAdditional: boolean; belongsToResource: string | null; openApiData: { tags: string[] | null; title: string | null; description: string | null; requestPayloadSchema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | null; responsePayloadSchema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | null; }; } /** * OpenAPI specification structure for resourceful endpoints */ export interface ResourcefulOpenAPISpec { openapi: '3.0.0'; info: { title: string; version: string; }; paths: { [path: string]: OpenAPIV3.PathItemObject; }; components: { schemas: { [modelName: string]: OpenAPIV3.SchemaObject; }; }; } /** * Route generator service interface */ export interface RouteGeneratorService { new (): this; generateRoutes(modelsMap: MacroModelsMap, options: NormalizedResourcefulRouterOptions): GeneratedRoute[]; } /** * OpenAPI generator service interface */ export interface OpenApiGeneratorService { new (): this; generateSpecs(routes: GeneratedRoute[], options: NormalizedResourcefulRouterOptions): ResourcefulOpenAPISpec; } /** * Router registration service interface (AdonisJS router type to be defined) */ export interface RouterRegistrationService { new (router: Router): this; registerRoutes(routes: GeneratedRoute[], options: NormalizedResourcefulRouterOptions): void; } /** * Main resourceful router macro function signature */ export interface ResourcefulRouterMacro { (models: MacroModelsMap, options?: Partial): RouteGroup; }