// Type definitions for outlet-orm API Layer (v13.0.0) // ── Error classes ────────────────────────────────────────────────────── export class ApiError extends Error { constructor(message?: string); name: string; } export class ApiNetworkError extends ApiError { constructor(message?: string, cause?: Error); cause: Error | null; } export class ApiResponseError extends ApiError { constructor(message?: string, statusCode?: number); statusCode: number; } export class ApiNotFoundError extends ApiResponseError { constructor(message?: string); } export class ApiValidationError extends ApiResponseError { constructor(message?: string, options?: { statusCode?: number; errors?: Record; source?: 'client' | 'server' }); errors: Record; source: 'client' | 'server'; } export class ApiUnauthorizedError extends ApiResponseError { constructor(message?: string); } export class ApiForbiddenError extends ApiResponseError { constructor(message?: string); } export class ApiServerError extends ApiResponseError { constructor(message?: string, statusCode?: number); } export class ApiRateLimitError extends ApiResponseError { constructor(message?: string, retryAfterHeader?: string | null); retryAfter: number | null; } export class ApiQueryNotSupportedError extends ApiError { constructor(operation?: string); operation: string | null; } // ── Config interfaces ────────────────────────────────────────────────── export interface AuthConfig { type?: 'bearer' | 'basic' | 'apiKey' | 'oauth2' | 'custom'; token?: string; username?: string; password?: string; apiKey?: string; apiKeyHeader?: string; accessToken?: string; refreshToken?: string; refreshUrl?: string; onRefresh?: (newToken: string) => void; customHeaders?: () => Record | Promise>; } export interface RetryConfig { retries?: number; retryCodes?: number[]; retryDelay?: number; } export interface CircuitBreakerConfig { enabled?: boolean; threshold?: number; timeout?: number; } export interface CacheConfig { enabled?: boolean; ttl?: number; store?: 'memory' | 'localStorage' | 'sessionStorage'; } export interface SecurityConfig { redactHeaders?: string[]; redactFields?: string[]; strictResponse?: boolean; } export interface SerializationConfig { requestTransformer?: (data: unknown) => unknown; responseTransformer?: (data: unknown) => unknown; } export interface PaginationConfig { type?: 'page' | 'cursor' | 'offset'; pageParam?: string; perPageParam?: string; cursorParam?: string; } export interface ApiAdapterConfig { baseUrl: string; timeout?: number; headers?: Record; auth?: AuthConfig; retry?: RetryConfig; circuitBreaker?: CircuitBreakerConfig; cache?: CacheConfig; security?: SecurityConfig; pagination?: PaginationConfig; serialization?: SerializationConfig; onError?: (error: ApiError) => void; redactHeaders?: string[]; } // ── Request log entry ────────────────────────────────────────────────── export interface RequestLogEntry { method: string; url: string; headers: Record; params: Record | null; timestamp: string; } // ── ApiAdapter ──────────────────────────────────────────────────────── export class ApiAdapter { constructor(config: ApiAdapterConfig); request(method: string, path: string, options?: { params?: Record; data?: unknown; headers?: Record; }): Promise; toRequest(method: string, path: string, options?: { params?: Record; data?: unknown; headers?: Record; }): { method: string; url: string; params: Record | null; headers: Record }; enableRequestLog(): void; getRequestLog(): RequestLogEntry[]; flushRequestLog(): void; dd(method: string, path: string, options?: Record): void; } export function createAdapter(config: ApiAdapterConfig): ApiAdapter; // ── Interceptors ───────────────────────────────────────────────────── export interface InterceptorHandler { fulfilled?: (value: T) => T | Promise; rejected?: (error: unknown) => unknown; } export class InterceptorManager { use(fulfilled?: (value: T) => T | Promise, rejected?: (error: unknown) => unknown): number; eject(id: number): void; clear(): void; } // ── Mock adapter ───────────────────────────────────────────────────── export interface MockHandler { method: string; path: string | RegExp; response: unknown | ((req: { method: string; path: string; options: unknown }) => unknown); status?: number; delay?: number; } export class MockAdapter extends ApiAdapter { constructor(handlers?: MockHandler[]); onGet(path: string | RegExp, response: unknown, options?: { status?: number; delay?: number }): this; onPost(path: string | RegExp, response: unknown, options?: { status?: number; delay?: number }): this; onPut(path: string | RegExp, response: unknown, options?: { status?: number; delay?: number }): this; onPatch(path: string | RegExp, response: unknown, options?: { status?: number; delay?: number }): this; onDelete(path: string | RegExp, response: unknown, options?: { status?: number; delay?: number }): this; reset(): void; } // ── Cache ───────────────────────────────────────────────────────────── export interface CacheStore { get(key: string): unknown | null; set(key: string, value: unknown, ttl?: number): void; delete(key: string): void; clear(): void; has(key: string): boolean; } export class CacheMemoryStore implements CacheStore { get(key: string): unknown | null; set(key: string, value: unknown, ttl?: number): void; delete(key: string): void; clear(): void; has(key: string): boolean; } export class CacheLocalStorageStore implements CacheStore { constructor(prefix?: string); get(key: string): unknown | null; set(key: string, value: unknown, ttl?: number): void; delete(key: string): void; clear(): void; has(key: string): boolean; } export class CacheSessionStorageStore implements CacheStore { constructor(prefix?: string); get(key: string): unknown | null; set(key: string, value: unknown, ttl?: number): void; delete(key: string): void; clear(): void; has(key: string): boolean; } export class ApiCache { constructor(store?: CacheStore, defaultTtl?: number); remember(key: string, ttl: number, fn: () => Promise): Promise; forget(key: string): void; flush(): void; } // ── Validation ──────────────────────────────────────────────────────── export interface ValidationRule { required?: boolean; type?: 'string' | 'number' | 'boolean' | 'array' | 'object'; min?: number; max?: number; minLength?: number; maxLength?: number; pattern?: string | RegExp; enum?: unknown[]; custom?: (value: unknown) => boolean | string; } export class ApiValidator { constructor(rules: Record); validate(data: Record): { valid: boolean; errors: Record }; validateOrFail(data: Record): void; } // ── Pagination ──────────────────────────────────────────────────────── export interface PaginationMeta { current_page: number; last_page: number; per_page: number; total: number; from?: number; to?: number; } export class ApiPaginator { constructor(data: unknown[], meta: PaginationMeta, fetchPage: (page: number) => Promise); readonly data: T[]; readonly meta: PaginationMeta; readonly currentPage: number; readonly lastPage: number; readonly total: number; hasNextPage(): boolean; hasPrevPage(): boolean; nextPage(): Promise>; prevPage(): Promise>; goToPage(page: number): Promise>; [Symbol.asyncIterator](): AsyncIterator; } // ── Query builder ───────────────────────────────────────────────────── export class ApiQueryBuilder { where(field: string, operator: string, value?: unknown): this; orWhere(field: string, operator: string, value?: unknown): this; whereIn(field: string, values: unknown[]): this; whereNull(field: string): this; whereNotNull(field: string): this; orderBy(field: string, direction?: 'asc' | 'desc'): this; limit(n: number): this; offset(n: number): this; with(...relations: string[]): this; select(...fields: string[]): this; paginate(perPage?: number, page?: number): Promise>; get(): Promise; first(): Promise; find(id: number | string): Promise; count(): Promise; toParams(): Record; } // ── Relation helpers ────────────────────────────────────────────────── export interface HasManyRelation { get(): Promise; create(data: Partial): Promise; first(): Promise; } export interface HasOneRelation { get(): Promise; create(data: Partial): Promise; } export interface BelongsToRelation { get(): Promise; } // ── Api model ───────────────────────────────────────────────────────── export interface ApiConfig { adapter: ApiAdapter; baseUrl?: string; auth?: AuthConfig; cache?: CacheConfig; retry?: RetryConfig; timeout?: number; headers?: Record; } export class Api = Record> { // Static configuration static endpoint: string; static primaryKey: string; static fillable: string[]; static hidden: string[]; static casts: Record; static responseSchema: string[] | null; static strictResponse: boolean; static timestamps: boolean; static configure(config: ApiConfig): void; static adapter(): ApiAdapter; // Static CRUD static find(this: M, id: number | string): Promise>; static all(this: M): Promise[]>; static create(this: M, data: Record): Promise>; static update(this: M, id: number | string, data: Record): Promise>; static destroy(this: M, id: number | string): Promise; // Static query static query(this: M): ApiQueryBuilder>; static where(this: M, field: string, operator: string, value?: unknown): ApiQueryBuilder>; static with(this: M, ...relations: string[]): ApiQueryBuilder>; static paginate(this: M, perPage?: number, page?: number): Promise>>; // Instance constructor(attributes?: Partial); get(key: keyof T): unknown; set(key: keyof T, value: unknown): this; fill(data: Partial): this; getAttribute(key: string): unknown; setAttribute(key: string, value: unknown): void; toJSON(): Record; toObject(): Record; isDirty(key?: string): boolean; getOriginal(key?: string): unknown; save(): Promise; delete(): Promise; // Lifecycle events (EventEmitter-style on the class) static on(event: string, listener: (...args: unknown[]) => void): void; static off(event: string, listener: (...args: unknown[]) => void): void; static removeAllListeners(event?: string): void; } /** Alias — ApiModel is the same as Api */ export class ApiModel = Record> extends Api {} // ── GraphQL ─────────────────────────────────────────────────────────── export class ApiGraphQL = Record> extends Api { static query(this: M, gql: string, variables?: Record): Promise; static mutate(this: M, gql: string, variables?: Record): Promise; static subscribe(this: M, gql: string, variables?: Record): AsyncGenerator; } // ── Offline / Storage ───────────────────────────────────────────────── export class StorageAdapter { constructor(store: CacheStore); get(key: string): Promise; set(key: string, value: unknown, ttl?: number): Promise; delete(key: string): Promise; clear(): Promise; has(key: string): Promise; } export class MemoryStore implements CacheStore { get(key: string): unknown | null; set(key: string, value: unknown, ttl?: number): void; delete(key: string): void; clear(): void; has(key: string): boolean; } export class LocalStorageStore implements CacheStore { constructor(prefix?: string); get(key: string): unknown | null; set(key: string, value: unknown, ttl?: number): void; delete(key: string): void; clear(): void; has(key: string): boolean; } export class SessionStorageStore implements CacheStore { constructor(prefix?: string); get(key: string): unknown | null; set(key: string, value: unknown, ttl?: number): void; delete(key: string): void; clear(): void; has(key: string): boolean; } export interface QueuedMutation { id: string; method: string; endpoint: string; data: unknown; timestamp: number; attempts: number; } export class MutationQueue { constructor(store?: StorageAdapter); enqueue(method: string, endpoint: string, data: unknown): Promise; dequeue(): Promise; peek(): Promise; size(): Promise; clear(): Promise; replay(adapter: ApiAdapter): Promise<{ success: number; failed: number }>; } // ── Realtime ────────────────────────────────────────────────────────── export class Watcher { constructor(adapter: ApiAdapter, options?: { interval?: number; compare?: (a: unknown, b: unknown) => boolean }); watch(endpoint: string, callback: (data: unknown) => void): () => void; stop(): void; } export class EventStream { constructor(url: string, options?: { headers?: Record; withCredentials?: boolean }); on(event: string, callback: (data: unknown) => void): this; off(event: string, callback: (data: unknown) => void): this; connect(): void; disconnect(): void; readonly readyState: number; } export class WebSocketConnection { constructor(url: string, options?: { protocols?: string | string[]; reconnect?: boolean; reconnectDelay?: number }); send(data: unknown): void; on(event: string, callback: (data: unknown) => void): this; off(event: string, callback: (data: unknown) => void): this; connect(): Promise; disconnect(): void; readonly readyState: number; }