import type { IndexPaginator } from './auto-crud'; import type { ModelCreateData, ModelRow } from './model-types'; /** The listing envelope: rows, the flat paginator, and the deprecated `meta`. */ export declare interface ApiIndexResponse extends IndexPaginator { data: TRow[] meta: Record } /** The single-row envelope, used by show, store and update alike. */ export declare interface ApiItemResponse { data: TRow } /** The definition behind a model, whether it was passed bare or via `defineModel`. */ declare type Definition = M extends { attributes: unknown } ? M : never; declare type ApiTrait = Definition extends { traits?: { useApi?: infer A } } ? A : never; /** `useApi: { uri: 'products' }` → `'products'`, else the table, else name + "s". */ declare type ApiUri = ApiTrait extends { uri: infer U extends string } ? U : (Definition extends { table: infer T extends string } ? T : (Definition extends { name: infer N extends string } ? `${Lowercase}s` : never)); declare type ApiPrefix = ApiTrait extends { prefix: infer P extends string } ? `${P}/` : ''; /** `/api/{prefix/}{uri}` — the same shape `apiBasePath()` builds. */ export type ApiBasePathFor = `/api/${ApiPrefix}${ApiUri}`; declare type DefaultRoutes = 'index' | 'show' | 'store' | 'update' | 'destroy'; /** Which of the CRUD verbs this model publishes. */ declare type EnabledRoutes = ApiTrait extends { routes: infer R extends readonly string[] } ? R[number] : DefaultRoutes; declare type Attributes = Definition extends { attributes: infer A } ? A : never; /** Attributes flagged `hidden: true`, which never appear in a response. */ declare type HiddenKeys = { [K in keyof Attributes]: Attributes[K] extends { hidden: true } ? K : never }[keyof Attributes]; /** A row as the generated endpoints actually return it: hidden fields removed. */ export type ApiRow = Omit, Extract, keyof ModelRow>>; /** What a write accepts: fillable fields, minus anything hidden. */ export type ApiWriteData = Omit, Extract, keyof ModelCreateData>>; declare type Params = { [K in TId]: string } declare type IndexRoute = 'index' extends EnabledRoutes ? { [K in `GET ${TBase}`]: { input: Record, output: ApiIndexResponse>, params: Record } } : Record; declare type ShowRoute = 'show' extends EnabledRoutes ? { [K in `GET ${TBase}/{id}`]: { input: Record, output: ApiItemResponse>, params: Params } } : Record; declare type StoreRoute = 'store' extends EnabledRoutes ? { [K in `POST ${TBase}`]: { input: ApiWriteData, output: ApiItemResponse>, params: Record } } : Record; declare type UpdateRoute = 'update' extends EnabledRoutes ? { [K in `PUT ${TBase}/{id}` | `PATCH ${TBase}/{id}`]: { input: ApiWriteData output: ApiItemResponse> params: Params } } : Record; declare type DestroyRoute = 'destroy' extends EnabledRoutes ? { [K in `DELETE ${TBase}/{id}`]: { input: Record, output: undefined, params: Params } } & { [K in `POST ${TBase}/bulk-delete`]: { input: { ids: Array } output: { message: string } params: Record } } : Record; /** * Every endpoint `useApi` publishes for this model, as a route map the typed * client understands. * * Intersect several of them - one per model - to describe a whole generated * API, and intersect that with `RoutesOf` to describe an app that * has both generated and hand-written routes. */ export type ApiRoutesFor = ApiBasePathFor extends infer TBase extends string ? IndexRoute & ShowRoute & StoreRoute & UpdateRoute & DestroyRoute : never;