import { Express, RequestHandler } from 'express'; import type { Server } from 'http'; import { Connection } from '@mathislair/mtbdb'; import type { OpenOptions } from '@mathislair/mtbdb'; import { RestRouter } from './RestRouter'; import { type CorsOptions } from './cors'; import { type UserBindingOptions, type UserResolver } from './userResolver'; import type { CaseConvention } from './caseConvention'; import type { DaoCtor, MiddlewareOrValidator, ResourceOptions } from './types'; /** * Zero-config Express + mtbDB facade. * * ```ts * import { mtbREST } from '@mathislair/mtbrest'; * * await mtbREST.connect({ driver: 'postgres', database: 'myapp', user: 'postgres', password: 'postgres' }); * mtbREST.get(UserDao); // GET /user, GET /user/:id * mtbREST.post(UserDao, auth); // POST /user * mtbREST.delete(UserDao, auth); // DELETE /user/:id * await mtbREST.start(3000); * ``` * * Path is derived from the bean's `tableName`. Override per DAO with `@Path('/users')`. */ export declare class MtbREST { private _connection?; private _router?; private _app?; private _server?; private _pending; private _pendingMiddleware; private _routerMounted; private _userBinding?; private _caseConvention?; private _paginate?; /** Open a new mtbDB connection and bind the facade to it. */ connect(opts: OpenOptions): Promise; /** Bind the facade to a connection you already opened (or a test fake). */ use(conn: Connection): this; /** * Default for the list-route pagination envelope. When true, GET * returns `{ data, total, limit, offset }` instead of a bare array. * Per-resource override available via `resource(dao, { paginate })`. */ paginate(on?: boolean): this; /** * Add Express middleware that runs **before** the REST routes. Cleaner * than `app().use(...)`, which runs after the routes if called past * `mount()` / `start()` (a common footgun for cors / json / auth). */ beforeRoutes(...handlers: RequestHandler[]): this; /** * Choose the wire-format case convention. Affects request bodies, query-string * filters, and response bodies for all routes mounted *after* this call * (call before declaring routes for the most predictable behavior). * * - `'snake'` (default): clients send & receive snake_case. Snake_case body * keys are now translated to the bean's camelCase setters — previously * they were silently dropped. CamelCase input still works. * - `'camel'`: response keys converted snake → camel; body & filter keys * converted camel → snake before reaching the bean / SQL. * - `'preserve'`: legacy v0.2.x behavior (no transformation). */ caseConvention(c: CaseConvention): this; /** * Bind a "current user" resolver. Its result is forced into per-row auth * columns on POST / PUT / PATCH **after** sanitizeBody runs, so a client * can't impersonate by sending those columns themselves. * * ```ts * mtbREST.use(conn).withUser((req) => req.session?.userId); * ``` * * Defaults: POST sets `user_id` and `created_by`; PUT/PATCH sets * `updated_by`. Override via `{ onCreate, onUpdate }`. */ withUser(resolver: UserResolver, opts?: UserBindingOptions): this; /** * Add a CORS middleware before the REST routes. Equivalent to * `mtbREST.app().use(corsMiddleware(opts))`, but always wires up before * the router so it runs first. * * Must be called before `start()` / `mount()`. For richer behavior, * install the `cors` package and pass `cors()` to `app().use(...)`. */ cors(opts?: CorsOptions): this; /** GET / (list) AND GET //:id (findById) for the same DAO. */ get(dao: DaoCtor, ...mw: MiddlewareOrValidator[]): this; /** POST / (create). */ post(dao: DaoCtor, ...mw: MiddlewareOrValidator[]): this; /** PUT //:id (full update). */ put(dao: DaoCtor, ...mw: MiddlewareOrValidator[]): this; /** PATCH //:id (partial update). */ patch(dao: DaoCtor, ...mw: MiddlewareOrValidator[]): this; /** DELETE //:id. */ delete(dao: DaoCtor, ...mw: MiddlewareOrValidator[]): this; /** Mount the full CRUD bundle (list + getById + create + put + patch + delete). */ resource(dao: DaoCtor, opts?: ResourceOptions): this; /** Mount a class decorated with @Path / @Get / @Post / etc. */ register(controller: object | (new (...args: any[]) => unknown)): this; /** * Get (or lazily create) the underlying Express app. Custom middleware added * via `app().use(...)` runs before the routes, *as long as it is added before* * `mount()` (called automatically by `start()`). */ app(): Express; /** * Append the REST router as the last middleware on the app. Idempotent. * `start()` calls this for you; call it manually if you serve the app * yourself (e.g. through `http.createServer(api.app())`). */ mount(): this; /** * After the REST router is mounted, any subsequent `mtbREST.app().use(mw)` * adds `mw` AFTER the router — so it can never apply to REST routes, * which is rarely what the user wants. Wrap `app.use` to emit a single * warning per call so the footgun is visible (#4). */ private _installAppUseGuard; /** Lazily-created RestRouter instance. Throws if connect()/use() hasn't been called. */ router(): RestRouter; /** Start listening. Returns the Node http.Server. */ start(port?: number): Promise; /** Close server + DB connection. Useful in tests. */ close(): Promise; private _enqueue; private _flushPending; private _apply; /** * Path resolution order: * 1. `@Path('/custom')` on the DAO class * 2. `(DaoClass as any).beanClass.tableName` (in case the bean is a static) * 3. Instantiate via the connection and read `dao.beanClass.tableName` */ private _resolvePath; } /** Build an isolated facade. Useful in tests; production code can use the default `mtbREST` singleton. */ export declare function createMtbREST(): MtbREST; /** Default process-wide facade. */ export declare const mtbREST: MtbREST; //# sourceMappingURL=global.d.ts.map