Node API
Node API Reference
Section titled “Node API Reference”Complete API reference for the @tabula-lens/node package.
Installation
Section titled “Installation”npm i @tabula-lens/nodepnpm add @tabula-lens/nodeyarn add @tabula-lens/nodeYou must also install the database driver for your chosen database engine:
| Database | Driver package |
|---|---|
| PostgreSQL / CockroachDB | pg |
| MySQL / MariaDB | mysql2 |
| SQLite | better-sqlite3 |
| SQL Server | tedious |
Example for PostgreSQL:
npm i @tabula-lens/node pgpnpm add @tabula-lens/node pgyarn add @tabula-lens/node pgTabulaLens Class
Section titled “TabulaLens Class”The main class for backend database querying and HTTP API implementation.
Constructor
Section titled “Constructor”new TabulaLens(config: string | TabulaLensConfig, options?: TabulaLensOptions)Creates a new TabulaLens instance with the specified database connection and options. Supports both the legacy string form and the new config-object form.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
config |
string | TabulaLensConfig |
Yes | Database connection string or config object |
options |
TabulaLensOptions |
No | Configuration options (only used when config is a string) |
TabulaLensConfig
Section titled “TabulaLensConfig”interface TabulaLensConfig { url: string; type?: DatabaseType; logger?: Logger; logLevel?: LogLevel; enableQueryLogging?: boolean; enableRequestLogging?: boolean; sensitiveDataMasking?: boolean; logFormat?: 'json' | 'text' | 'pretty';}| Option | Type | Required | Default | Description |
|---|---|---|---|---|
url |
string |
Yes | - | Database connection string or file path |
type |
DatabaseType |
No | Auto-detected | Database type ('pg', 'mysql', 'sqlite', 'mssql') |
logger |
Logger |
No | Default logger | Custom logger instance |
logLevel |
LogLevel |
No | - | Log level: 'error' | 'warn' | 'info' | 'debug' | 'silent' |
enableQueryLogging |
boolean |
No | true |
Enable query-level logging |
enableRequestLogging |
boolean |
No | true |
Enable request-level logging |
sensitiveDataMasking |
boolean |
No | true |
Mask sensitive data (like database URLs) in logs |
logFormat |
'json' | 'text' | 'pretty' |
No | - | Log output format |
DatabaseType
Section titled “DatabaseType”type DatabaseType = 'pg' | 'mysql' | 'sqlite' | 'mssql';Represents the supported database engines. The value is auto-detected from the connection URL when omitted.
TabulaLensOptions
Section titled “TabulaLensOptions”| Option | Type | Default | Description |
|---|---|---|---|
logger |
Logger |
- | Custom logger instance (if not provided, default logger is created) |
logLevel |
LogLevel |
- | Log level: 'error' | 'warn' | 'info' | 'debug' | 'silent' |
enableQueryLogging |
boolean |
true |
Enable query-level logging |
enableRequestLogging |
boolean |
true |
Enable request-level logging |
sensitiveDataMasking |
boolean |
true |
Mask sensitive data (like database URLs) in logs |
logFormat |
'json' | 'text' | 'pretty' |
- | Log output format |
Examples
Section titled “Examples”String form (legacy, still supported):
import { TabulaLens } from '@tabula-lens/node';
const tabulaLens = new TabulaLens('postgresql://user:password@localhost:5432/mydb', { logLevel: 'info', enableQueryLogging: true, enableRequestLogging: true, sensitiveDataMasking: true, logFormat: 'pretty'});Config-object form:
import { TabulaLens } from '@tabula-lens/node';
const tabulaLens = new TabulaLens({ url: 'mysql://user:password@localhost:3306/mydb', type: 'mysql', // optional — auto-detected from URL logLevel: 'info', enableQueryLogging: true, sensitiveDataMasking: true,});Auto-detection from a file path:
import { TabulaLens } from '@tabula-lens/node';
const tabulaLens = new TabulaLens({ url: './data.sqlite', // type: 'sqlite' is auto-detected});Methods
Section titled “Methods”async query(options: QueryOptions): Promise<QueryResult>Executes a database query based on the provided parameters.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
table |
string |
No | 'users' |
Table name to query |
page |
number |
No | 1 |
Page number (1-indexed) |
limit |
number |
No | 10 |
Number of rows per page |
sort |
string |
No | - | Sort specification (format: column:direction,column:direction) |
filter |
string |
No | - | Filter string for searching across text columns |
columns |
string[] |
No | - | Specific columns to return |
filterColumns |
string[] |
No | - | Specific columns to filter (comma-separated) |
Returns
Section titled “Returns”Promise<QueryResult> - The query result containing data and metadata.
QueryResult
Section titled “QueryResult”| Field | Type | Description |
|---|---|---|
data |
Record<string, unknown>[] |
Array of data records |
columns |
string[] |
Array of column names |
pagination |
object |
Pagination metadata |
pagination.page |
number |
Current page number |
pagination.limit |
number |
Number of records per page |
pagination.total |
number |
Total number of records |
pagination.totalPages |
number |
Total number of pages |
Example
Section titled “Example”const result = await tabulaLens.query({ table: 'users', page: 1, limit: 25, filter: 'john', filterColumns: ['name', 'email'], sort: 'created_at:desc', columns: ['id', 'name', 'email', 'created_at']});
console.log(result.data);console.log(result.pagination);handle
Section titled “handle”async handle(context: RequestContext): Promise<ResponseContext>Handles an HTTP request and returns a response context. This is the main method used by framework adapters.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
context |
RequestContext |
Yes | HTTP request context |
RequestContext
Section titled “RequestContext”| Field | Type | Description |
|---|---|---|
method |
string |
HTTP method (GET, POST, etc.) |
path |
string |
Request path |
query |
Record<string, string> |
Query parameters |
body |
unknown |
Request body (optional) |
Returns
Section titled “Returns”Promise<ResponseContext> - HTTP response context.
ResponseContext
Section titled “ResponseContext”| Field | Type | Description |
|---|---|---|
status |
number |
HTTP status code |
headers |
Record<string, string> |
Response headers |
body |
unknown |
Response body |
Example
Section titled “Example”// Query data — path must be '/query' (the subpath after the mount point)const response = await tabulaLens.handle({ method: 'GET', path: '/query', query: { table: 'users', page: '1', limit: '25' }});console.log(response.status); // 200console.log(response.body); // Query result data
// List tablesconst tablesResponse = await tabulaLens.handle({ method: 'GET', path: '/tables', query: {}});console.log(tablesResponse.body); // ['users', 'products', ...]getLogger
Section titled “getLogger”getLogger(): LoggerReturns the logger instance used by this TabulaLens instance.
Returns
Section titled “Returns”Logger - The logger instance.
Example
Section titled “Example”const logger = tabulaLens.getLogger();logger.info('Custom log message', { customData: 'value' });getTables
Section titled “getTables”async getTables(): Promise<string[]>Returns a list of all tables in the database.
Returns
Section titled “Returns”Promise<string[]> - Array of table names.
Example
Section titled “Example”const tables = await tabulaLens.getTables();console.log('Available tables:', tables);getFilterableColumns
Section titled “getFilterableColumns”async getFilterableColumns(table: string): Promise<string[]>Returns a list of text-based columns that can be used for filtering in the specified table.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
table |
string |
Yes | Table name |
Returns
Section titled “Returns”Promise<string[]> - Array of filterable column names.
Example
Section titled “Example”const filterableColumns = await tabulaLens.getFilterableColumns('users');console.log('Filterable columns:', filterableColumns);// Output: ['name', 'email', 'status', ...]TabulaLensError Class
Section titled “TabulaLensError Class”Custom error class for Tabula Lens-specific errors.
Constructor
Section titled “Constructor”constructor(statusCode: number, code: string, message: string, details?: unknown)Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
statusCode |
number |
Yes | HTTP status code |
code |
string |
Yes | Machine-readable error code |
message |
string |
Yes | Human-readable error message |
details |
unknown |
No | Additional error details |
Example
Section titled “Example”import { TabulaLensError } from '@tabula-lens/node';
throw new TabulaLensError( 404, 'TABLE_NOT_FOUND', 'Table does not exist', { table: 'users' });Logger API
Section titled “Logger API”Logger Interface
Section titled “Logger Interface”interface Logger { error(message: string, context?: LogContext): void; warn(message: string, context?: LogContext): void; info(message: string, context?: LogContext): void; debug(message: string, context?: LogContext): void;}LogContext
Section titled “LogContext”interface LogContext { component?: string; operation?: string; requestId?: string; userId?: string; table?: string; query?: Record<string, unknown>; error?: Error | string; stack?: string; timestamp?: string; [key: string]: unknown;}LogLevel
Section titled “LogLevel”type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'silent';LoggerOptions
Section titled “LoggerOptions”interface LoggerOptions { level?: LogLevel; includeStack?: boolean; includeTimestamp?: boolean; colorize?: boolean; format?: 'json' | 'text' | 'pretty';}createLogger
Section titled “createLogger”function createLogger(options?: LoggerOptions): LoggerCreates a new logger instance with the specified options.
Example
Section titled “Example”import { createLogger } from '@tabula-lens/node';
const logger = createLogger({ level: 'debug', format: 'pretty', colorize: true, includeTimestamp: true, includeStack: false});
logger.info('Application started', { port: 3000 });generateId
Section titled “generateId”function generateId(): stringGenerates a unique ID for request tracking.
Returns
Section titled “Returns”string - A unique identifier.
Example
Section titled “Example”import { generateId } from '@tabula-lens/node';
const requestId = generateId();console.log(requestId); // e.g., "a1b2c3d4"maskSensitiveData
Section titled “maskSensitiveData”function maskSensitiveData(data: string): stringMasks sensitive data (like database connection strings) for logging.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
data |
string |
Yes | Data to mask |
Returns
Section titled “Returns”string - Masked data.
Example
Section titled “Example”import { maskSensitiveData } from '@tabula-lens/node';
const connectionString = 'postgresql://user:password@localhost:5432/mydb';const masked = maskSensitiveData(connectionString);console.log(masked); // "postgresql://user:****@localhost:5432/mydb"Database Type Helpers
Section titled “Database Type Helpers”detectDatabaseType
Section titled “detectDatabaseType”function detectDatabaseType(url: string): DatabaseTypeDetects the database type from a connection URL or file path. TabulaLens calls this internally when the type field is omitted, but you can use it directly for debugging or validation.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string |
Yes | Database connection URL or file path |
Returns
Section titled “Returns”DatabaseType - The detected database type ('pg', 'mysql', 'sqlite', or 'mssql').
Supported URL Patterns
Section titled “Supported URL Patterns”| Pattern | Detected type | Example |
|---|---|---|
postgresql://, postgres://, pgsql:// |
pg |
postgresql://localhost/mydb |
mysql://, mysql2://, mysqlx://, mariadb:// |
mysql |
mysql://localhost/mydb |
sqlite://, sqlite:, file:, :memory:, paths ending in .db / .sqlite / .sqlite3 / .db3 |
sqlite |
./data.sqlite |
mssql://, sqlserver://, mssql+tcp://, mssql+udp:// |
mssql |
mssql://localhost/mydb |
Example
Section titled “Example”import { detectDatabaseType } from '@tabula-lens/node';
const type = detectDatabaseType('mysql://user:password@localhost:3306/mydb');console.log(type); // 'mysql'validateDatabaseType
Section titled “validateDatabaseType”function validateDatabaseType(type: string): DatabaseTypeValidates that a string is a supported database type. Returns the type narrowed to DatabaseType, or throws a TabulaLensError for unsupported values.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
type |
string |
Yes | Database type string to validate |
Returns
Section titled “Returns”DatabaseType - The validated database type.
Example
Section titled “Example”import { validateDatabaseType } from '@tabula-lens/node';
try { validateDatabaseType('sqlite'); // 'sqlite' validateDatabaseType('oracle'); // throws TabulaLensError} catch (error) { // Handle invalid database type}Framework Adapters
Section titled “Framework Adapters”Tabula Lens provides adapters for 15+ Node.js frameworks. Each adapter implements the HTTP API contract using framework-specific patterns.
Express Adapter (5.x+)
Section titled “Express Adapter (5.x+)”import express from 'express';import { TabulaLens, expressAdapter } from '@tabula-lens/node';
const app = express();const tabulaLens = new TabulaLens(process.env.DATABASE_URL);
// Mount at /api/tabula-lens — sub-routes (/query, /tables, /tables/:table) are handled internallyapp.use('/api/tabula-lens', expressAdapter(tabulaLens));
app.listen(3000);Express 4.x Adapter
Section titled “Express 4.x Adapter”import express from 'express';import { TabulaLens, express4Adapter } from '@tabula-lens/node';
const app = express();const tabulaLens = new TabulaLens(process.env.DATABASE_URL);
app.use('/api/tabula-lens', express4Adapter(tabulaLens));
app.listen(3000);Fastify Adapter
Section titled “Fastify Adapter”import Fastify from 'fastify';import { TabulaLens, fastifyAdapter } from '@tabula-lens/node';
const fastify = Fastify();const tabulaLens = new TabulaLens(process.env.DATABASE_URL);
fastify.all('/api/tabula-lens/*', fastifyAdapter(tabulaLens));
fastify.listen({ port: 3000 });Koa Adapter
Section titled “Koa Adapter”import Koa from 'koa';import { TabulaLens, koaAdapter } from '@tabula-lens/node';
const app = new Koa();const tabulaLens = new TabulaLens(process.env.DATABASE_URL);
// Koa adapter passes ctx.path directly to handle(), so you need to mount// it via a router or filter by path prefix in middlewareapp.use(koaAdapter(tabulaLens));
app.listen(3000);Hapi Adapter
Section titled “Hapi Adapter”import Hapi from '@hapi/hapi';import { TabulaLens, hapiAdapter } from '@tabula-lens/node';
const server = Hapi.server({ port: 3000 });const tabulaLens = new TabulaLens(process.env.DATABASE_URL);
server.route({ method: 'GET', path: '/api/tabula-lens/{path*}', handler: hapiAdapter(tabulaLens),});
await server.start();Restify Adapter
Section titled “Restify Adapter”import restify from 'restify';import { TabulaLens, restifyAdapter } from '@tabula-lens/node';
const server = restify.createServer();const tabulaLens = new TabulaLens(process.env.DATABASE_URL);
server.get('/api/tabula-lens/*', restifyAdapter(tabulaLens));
server.listen(3000);Next.js Adapter
Section titled “Next.js Adapter”// app/api/tabula-lens/[...path]/route.ts (App Router)import { TabulaLens, createNextRouteHandler } from '@tabula-lens/node';
const tabulaLens = new TabulaLens(process.env.DATABASE_URL);const handler = createNextRouteHandler(tabulaLens);
export { handler as GET };TanStack Start Adapter
Section titled “TanStack Start Adapter”import { TabulaLens, createTanStackStartHandler } from '@tabula-lens/node';
const tabulaLens = new TabulaLens(process.env.DATABASE_URL);const handler = createTanStackStartHandler(tabulaLens);
export const APIRoute = createAPIFileRoute('/api/tabula-lens/$')({ GET: ({ request }) => handler(request),});Remix Adapter
Section titled “Remix Adapter”// app/routes/api.tabula-lens.$.tsimport { TabulaLens, createRemixHandler } from '@tabula-lens/node';
const tabulaLens = new TabulaLens(process.env.DATABASE_URL);const handler = createRemixHandler(tabulaLens);
export const loader = ({ request }: { request: Request }) => handler(request);SvelteKit Adapter
Section titled “SvelteKit Adapter”import { TabulaLens, createSvelteKitHandler } from '@tabula-lens/node';
const tabulaLens = new TabulaLens(process.env.DATABASE_URL);const handler = createSvelteKitHandler(tabulaLens);
export const GET = (event: { request: Request; url: URL }) => handler(event);Hono Adapter
Section titled “Hono Adapter”import { Hono } from 'hono';import { TabulaLens, createHonoMiddleware } from '@tabula-lens/node';
const app = new Hono();const tabulaLens = new TabulaLens(process.env.DATABASE_URL);
app.all('/api/tabula-lens/*', createHonoMiddleware(tabulaLens));
export default app;Elysia Adapter
Section titled “Elysia Adapter”import { Elysia } from 'elysia';import { TabulaLens, createElysiaHandler } from '@tabula-lens/node';
const app = new Elysia();const tabulaLens = new TabulaLens(process.env.DATABASE_URL);
app.all('/api/tabula-lens/*', createElysiaHandler(tabulaLens));
app.listen(3000);Fresh Adapter
Section titled “Fresh Adapter”import { TabulaLens, createFreshHandler } from '@tabula-lens/node';
const tabulaLens = new TabulaLens(process.env.DATABASE_URL);const handler = createFreshHandler(tabulaLens);
export const handlers = { GET: (req: Request) => handler(req) };Native Adapter
Section titled “Native Adapter”import http from 'http';import { TabulaLens, nativeAdapter } from '@tabula-lens/node';
const tabulaLens = new TabulaLens(process.env.DATABASE_URL);const handler = nativeAdapter(tabulaLens);
http.createServer(handler).listen(3000);Supported Frameworks
Section titled “Supported Frameworks”- Traditional: Express (4.x & 5.x), Fastify, Koa, Hapi, Restify
- Modern: Next.js, TanStack Start, Remix, SvelteKit
- Edge: Hono, Elysia, Fresh
- Native: Native adapter for custom implementations
Type Exports
Section titled “Type Exports”export type { QueryOptions, QueryResult, RequestContext, ResponseContext, SortOption, FilterOption, TabulaLensOptions, TabulaLensConfig, DatabaseType, Logger, LogContext, LogLevel, LoggerOptions, DialectStrategy, ColumnInfo};Dialect Strategy API
Section titled “Dialect Strategy API”The dialect strategy system provides database-specific operations for each supported database engine. This is used internally by TabulaLens but can also be used directly for advanced use cases.
DialectStrategy Interface
Section titled “DialectStrategy Interface”interface DialectStrategy { getTables(db: Knex): Promise<string[]>; getColumns(db: Knex, table: string): Promise<ColumnInfo[]>; getFilterableTypes(): string[]; getLikeOperator(): 'LIKE' | 'ILIKE';}Methods
Section titled “Methods”| Method | Returns | Description |
|---|---|---|
getTables(db) |
Promise<string[]> |
Get all table names in the database |
getColumns(db, table) |
Promise<ColumnInfo[]> |
Get column metadata for a specific table |
getFilterableTypes() |
string[] |
Get data type names that support text filtering |
getLikeOperator() |
'LIKE' | 'ILIKE' |
Get the LIKE operator for case-insensitive matching |
ColumnInfo Interface
Section titled “ColumnInfo Interface”interface ColumnInfo { name: string; type: string;}Represents column metadata returned by dialect implementations.
| Property | Type | Description |
|---|---|---|
name |
string |
Column name |
type |
string |
Data type (e.g., 'integer', 'character varying', 'text') |
createDialect Function
Section titled “createDialect Function”function createDialect(type: DatabaseType): DialectStrategyFactory function to create a dialect strategy instance based on database type.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
type |
DatabaseType |
Yes | Database type ('pg', 'mysql', 'sqlite', 'mssql') |
Returns
Section titled “Returns”A DialectStrategy instance for the specified database type.
Example
Section titled “Example”import { createDialect } from '@tabula-lens/node';import { DatabaseType } from '@tabula-lens/node';
// Create a PostgreSQL dialectconst postgresDialect = createDialect('pg');
// Create a MySQL dialectconst mysqlDialect = createDialect('mysql');
// Use the dialectconst tables = await postgresDialect.getTables(knexInstance);const columns = await postgresDialect.getColumns(knexInstance, 'users');const filterableTypes = postgresDialect.getFilterableTypes();const likeOperator = postgresDialect.getLikeOperator(); // 'ILIKE' for PostgreSQLDirect Dialect Usage
Section titled “Direct Dialect Usage”You can also use the dialect classes directly if needed:
import { PostgresDialect, MySQLDialect, SQLiteDialect, MSSQLDialect } from '@tabula-lens/node';
// Use PostgreSQL dialect directlyconst postgresDialect = new PostgresDialect();const tables = await postgresDialect.getTables(knexInstance);Dialect-Specific Behavior
Section titled “Dialect-Specific Behavior”Each dialect implements the DialectStrategy interface with database-specific behavior:
| Database | LIKE Operator | Filterable Types Example |
|---|---|---|
| PostgreSQL | ILIKE (case-insensitive) |
['character varying', 'text', 'varchar', 'char', 'character', 'uuid'] |
| MySQL | LIKE (case-insensitive by default) |
['varchar', 'text', 'tinytext', 'mediumtext', 'longtext', 'char'] |
| SQLite | LIKE (case-insensitive by default) |
['TEXT', 'text'] |
| SQL Server | LIKE (case-insensitive by default) |
['varchar', 'nvarchar', 'text', 'char', 'nchar'] |
Advanced Use Cases
Section titled “Advanced Use Cases”The dialect strategy system is useful for:
- Building custom database introspection tools
- Implementing custom query builders
- Creating database-specific migrations
- Building admin panels with dynamic column filtering
- Implementing type-safe database operations
For most use cases, you don’t need to interact with dialects directly — TabulaLens handles this internally. The dialect API is primarily for advanced scenarios requiring direct database introspection.
Complete Example
Section titled “Complete Example”import { TabulaLens, expressAdapter, createLogger } from '@tabula-lens/node';import express from 'express';
// Create custom loggerconst logger = createLogger({ level: 'info', format: 'pretty', colorize: true});
// Initialize TabulaLensconst tabulaLens = new TabulaLens(process.env.DATABASE_URL, { logger, enableQueryLogging: true, enableRequestLogging: true, sensitiveDataMasking: true, logFormat: 'pretty'});
// Create Express appconst app = express();
// Add Tabula Lens endpoint (handles /query, /tables, /tables/:table sub-routes)app.use('/api/tabula-lens', expressAdapter(tabulaLens));
// Start serverapp.listen(3000, () => { logger.info('Server started', { port: 3000 });});