Skip to content

API Reference

Every reusable framework capability is exposed through one import — the facade at @/framework/facade.js. You never reach into framework internals; if it is not on this page, it is not part of the public API.

ts
import {
  createRouter,   // router builder
  createRoute,    // OpenAPI route declaration
  group,          // middleware grouping shorthand
  z,              // Zod + .openapi() schemas
  jsonContent,    // JSON media-type wrapper
  HttpStatusCodes,// status constants
  validate,       // schema validation outside routes
  database,       // init/access the Drizzle instance
  db,             // global query proxy
  paginate,       // request-driven pagination
  paginateModel,  // eager-loading pagination
  paginateQuery,  // custom count/data pagination
  paginateTable,  // single-table pagination
  cache,          // Redis key-value cache
  command,        // register in-process handler
  dispatchCommand,// run an in-process handler
  dispatchEvent,  // broadcast and/or enqueue an event
  queue,          // access a BullMQ queue
  queueJob,       // enqueue a background job
  shouldQueue,    // register a job handler
  broadcast,      // Socket.IO broadcast
  defineSchedule, // named cron schedules
  session,        // server-side sessions
  storage,        // file storage
  notify,         // persisted + realtime notifications
  password,       // bcrypt hashing
  jwt,            // token generation/verification
  cookie,         // auth cookie helpers
  mail,           // SMTP transport
  logger,         // structured logging
  urls,           // absolute URL building
  lodash,         // full Lodash library
} from "@/framework/facade.js";

Function reference

Each facade function has its own page. Every export below is a documented part of the public API.

FunctionPurposeGuide
createRouterHono router with group/route/api helpersRouting · OpenAPI
createRouteDeclare a documented OpenAPI routeRouting · OpenAPI
groupcreateRouter().group() shorthand + role middlewareRouting
zExtended Zod with .openapi()OpenAPI
jsonContentWrap a schema as application/jsonOpenAPI
HttpStatusCodesNumeric HTTP status constantsOpenAPI
validateRun a Zod schema → throws 422 on mismatchOpenAPI
databaseReturns the initialized Drizzle instanceDatabase
dbGlobal Drizzle query proxyDatabase
paginateRequest-driven pagination (joins, aggregates)Database
paginateModelEager-loading pagination (db.query…findMany with)Database
paginateQueryManual total()/data() paginationDatabase
paginateTableSingle-table pagination, no request objectDatabase
cacheRedis key-value cache (graceful fallback)Cache
commandRegister an in-process synchronous handlerEvents & Queue
dispatchCommandRun a registered command (async: enqueue)Events & Queue
dispatchEventBroadcast + enqueue a domain eventEvents & Queue
queueAccess a BullMQ queue instanceEvents & Queue
queueJobEnqueue a background jobEvents & Queue
shouldQueueRegister a job handler (optionally durable)Events & Queue
broadcastSocket.IO emit to targeted audiencesRealtime
defineScheduleNamed cron tasks with distributed lockingScheduler
sessionRedis-backed server-side sessionsSession
storageLocal + S3-compatible file storageStorage
notifyPersist + broadcast + email notificationsNotifications
passwordbcrypt hash / verifyPassword
jwtHS256 token generation / verificationJWT
cookie{name}_access / {name}_refresh cookie helpersCookie
mailSMTP sendMail transportMail
loggerLeveled structured logging + rotating filesLogger
urlsAbsolute URL building from APP_URLURL
lodashFull Lodash re-exportlibraries

When do I use which?

  • HTTP & OpenAPIcreateRouter/group build the router; createRoute documents a route; z writes the schemas; jsonContent + HttpStatusCodes describe responses.
  • Input safetyvalidate runs a schema anywhere (outside routes) and throws a structured 422 on failure.
  • Datadb is the Drizzle client; paginate / paginateModel / paginateQuery / paginateTable wrap queries in a Laravel-style page (see the Which one? table).
  • Cachingcache stores JSON with TTL and degrades to a no-op when Redis is off.
  • Background workcommand/dispatchCommand run in-process handlers; dispatchEvent fans out to sockets and/or queues; queueJob/shouldQueue are the raw BullMQ surface.
  • Realtimebroadcast emits a Socket.IO event to targeted audiences.
  • AutomationdefineSchedule runs cron tasks with distributed locking.
  • State & filessession keeps server-side state; storage reads/writes files on local disk or S3.
  • User-visible eventsnotify persists a notification row and optionally broadcasts + emails it.
  • Supportpassword, jwt, cookie, mail power auth flows; logger is the structured logger; urls builds absolute links; lodash re-exports the full library.

Common recipes

Sign up a user with hashed password + realtime + email

The auth flow composes hashing, persistence, and dispatch:

ts
import { db, password, dispatchEvent, notify } from "@/framework/facade.js";
import * as schema from "@/database/schema.js";

export const register = async (input: { name: string; email: string; password: string }) => {
  const user = await db.insert(schema.users).values({
    name: input.name,
    email: input.email,
    password: await password.hashPassword(input.password),
  });

  await notify(user.id, {
    type: "success",
    title: "Welcome",
    body: "Your account is ready.",
    broadcast: true,
    mail: { subject: "Welcome to nexgen" },
  });

  await dispatchEvent("user.registered", { userId: user.id }, { broadcast: { roles: ["admin"] } });

  return user;
};

List a paginated resource

Route + controller compose routing, querying, and pagination:

ts
import { createRoute, createRouter, group, HttpStatusCodes, jsonContent, db, paginate, z } from "@/framework/facade.js";
import { desc } from "drizzle-orm";
import { posts } from "@/modules/blog/database/models/post.js";

const listRoute = createRoute({
  path: "/",
  method: "get",
  tags: ["Posts"],
  responses: {
    [HttpStatusCodes.OK]: jsonContent(z.array(PostSchema), "list of posts"),
  },
});

export default createRouter().group().api(listRoute, async (c) => {
  const query = db.select().from(posts).orderBy(desc(posts.id));
  return c.json(await paginate(c, query, 15));
});

Throttle background work and broadcast the result

queueJob + shouldQueue handle heavy work; broadcast surfaces the outcome:

ts
import { queueJob, shouldQueue, broadcast } from "@/framework/facade.js";

// Controller: queue it, respond fast
await queueJob("process-image", { path }, { queue: "images", delay: 5 });

// Worker: register handler, then notify the author
shouldQueue("process-image", "images", async (job) => {
  const url = await processImage(job.data.path);
  broadcast("image.processed", { url }, { users: [job.data.userId] });
});

Rules of the facade

  • One import — everything importable lives on @/framework/facade.js; the facade only re-exports what is implemented. If a function is missing here, it does not exist yet.
  • Graceful degradation — Redis-backed features (cache, session, queue, broadcast via adapter) return null/false/fallback when Redis is unavailable instead of throwing.
  • Namespaces over bare functions — grouped utilities (cache, session, storage, jwt, cookie, password, mail, urls, lodash) keep call sites searchable and collide-proof.
  • Compose, don't re-implement — features are built by combining the exports above (see the pagination helpers, which all share one PaginatedResult shape).

Released under the MIT License.