TypeScript SDK
The official Node.js/TypeScript SDK for JSONQL. One line of configuration gives your API dynamic filtering, sorting, pagination, field selection, and relationships — no custom endpoints needed.
| Package | @jsonql-standard/jsonql-ts |
| Version | 1.1.0 |
| License | MIT |
| Runtime | Node.js 18+ |
Install
Section titled “Install”npm install @jsonql-standard/jsonql-tsConfigure & Use
Section titled “Configure & Use”Pick your framework — one mount gives you a complete JSONQL API:
Express
Section titled “Express”import express from 'express';import { jsonqlExpress } from '@jsonql-standard/jsonql-ts';import { PostgresDriver } from '@jsonql-standard/jsonql-ts/drivers/postgres';
const app = express();app.use(express.json());
const driver = new PostgresDriver('postgres://localhost/mydb');
// One line of config — dynamic query API readyapp.use('/api', jsonqlExpress({ driver }));
app.listen(3000);Fastify
Section titled “Fastify”import Fastify from 'fastify';import { jsonqlFastify } from '@jsonql-standard/jsonql-ts';import { PostgresDriver } from '@jsonql-standard/jsonql-ts/drivers/postgres';
const fastify = Fastify();const driver = new PostgresDriver('postgres://localhost/mydb');
// Auto-registers /:table routesfastify.register(jsonqlFastify, { driver });
fastify.listen({ port: 3000 });NestJS
Section titled “NestJS”import { Module } from '@nestjs/common';import { JsonqlModule } from '@jsonql-standard/jsonql-ts';
@Module({ imports: [ JsonqlModule.forRoot({ driver: new PostgresDriver('postgres://localhost/mydb'), }), ],})export class AppModule {}That’s it. No query controllers, no endpoint-per-filter, no route boilerplate. Your clients can now query any table dynamically.
What Your Clients Can Do
Section titled “What Your Clients Can Do”Every query is a JSON POST to /api/{table}:
# Select specific fields, filter, sort, paginatecurl -X POST http://localhost:3000/api/users -H 'Content-Type: application/json' -d '{ "fields": ["id", "name", "email"], "where": { "status": { "eq": "active" } }, "sort": ["-created_at"], "limit": 20}'# → { "data": [{ "id": 1, "name": "Alice", "email": "alice@co.com" }, ...] }# Complex filters with AND/ORcurl -X POST http://localhost:3000/api/products -d '{ "where": { "and": [ { "price": { "gte": 10, "lte": 100 } }, { "category": { "in": ["electronics", "books"] } } ] }, "sort": ["price"], "limit": 50}'# Include related data — joins resolved automaticallycurl -X POST http://localhost:3000/api/users -d '{ "fields": ["id", "name"], "include": { "posts": { "fields": ["title", "created_at"], "limit": 5 } }}'# → { "data": [{ "id": 1, "name": "Alice", "posts": [{ "title": "Hello", ... }] }] }# Aggregation & groupBycurl -X POST http://localhost:3000/api/orders -d '{ "aggregate": { "total": { "fn": "sum", "field": "amount" } }, "groupBy": ["status"]}'CRUD mutations work too:
# Create (POST with "data")curl -X POST http://localhost:3000/api/users \ -d '{ "data": { "name": "Bob", "email": "bob@co.com" } }'
# Update (PATCH)curl -X PATCH http://localhost:3000/api/users \ -d '{ "patch": { "status": "inactive" }, "where": { "id": { "eq": 1 } } }'
# Deletecurl -X DELETE http://localhost:3000/api/users \ -d '{ "where": { "id": { "eq": 1 } } }'Adding Schema (Optional)
Section titled “Adding Schema (Optional)”Without schema, all columns are queryable. With schema, you control which fields are exposed, hide sensitive columns, and enable relationship resolution:
app.use('/api', jsonqlExpress({ driver, schema: { tables: { users: { fields: { id: { type: 'number' }, name: { type: 'string' }, email: { type: 'string' }, secret: { type: 'string', allowSelect: false }, // hidden from queries }, relations: { posts: { type: 'hasMany', table: 'posts', field: 'user_id' }, }, }, posts: { fields: { id: { type: 'number' }, title: { type: 'string' }, user_id: { type: 'number' }, }, }, }, },}));Lifecycle Hooks
Section titled “Lifecycle Hooks”Inject logic at any point in the pipeline — tenant isolation, audit logging, RLS:
app.use('/api', jsonqlExpress({ driver, hooks: { beforeQuery: (query, table) => { query.where = { ...query.where, tenant_id: { eq: currentTenantId } }; }, afterQuery: (results) => results, },}));Supported Databases
Section titled “Supported Databases”| Database | Driver import | Package |
|---|---|---|
| PostgreSQL | drivers/postgres | pg |
| MySQL | drivers/mysql | mysql2 |
| SQLite | drivers/sqlite | sqlite3 |
| MSSQL | drivers/mssql | mssql |
| MongoDB | drivers/mongodb | mongodb |
Error Handling
Section titled “Error Handling”All errors include a machine-readable error_code:
graph TD E["JsonQLError"] --> V["JsonQLValidationError<br/>(VALIDATION_ERROR)"] E --> T["JsonQLTranspileError<br/>(TRANSPILE_ERROR)"] E --> X["JsonQLExecutionError<br/>(EXECUTION_ERROR)"]{ "error": "Field 'secret' is not allowed", "error_code": "VALIDATION_ERROR" }Advanced: Query Builder
Section titled “Advanced: Query Builder”For server-side programmatic query construction:
import { JSONQLQueryBuilder } from '@jsonql-standard/jsonql-ts';
const query = new JSONQLQueryBuilder() .from('users') .select('id', 'name') .where({ status: { eq: 'active' } }) .orderBy('-created_at') .limit(10) .build();Advanced: Low-Level Transpiler
Section titled “Advanced: Low-Level Transpiler”Use the transpiler directly for custom pipelines:
import { SQLTranspiler } from '@jsonql-standard/jsonql-ts';
const transpiler = new SQLTranspiler('postgres');const { sql, parameters } = transpiler.transpile(query, 'users');// → SELECT "users"."id", "users"."name" FROM "users" WHERE "users"."status" = $1Core API
Section titled “Core API”| Export | Purpose |
|---|---|
jsonqlExpress() | Express middleware — mount and go |
jsonqlFastify | Fastify plugin with auto-routing |
JsonqlModule | NestJS module with injectable service |
JSONQLParser | Parse & validate incoming JSON |
SQLTranspiler | Convert parsed query → SQL + params |
ResultHydrator | Flatten SQL joins → nested JSON |
JSONQLQueryBuilder | Fluent query construction (advanced) |
JSONQLMutationBuilder | Fluent mutation construction (advanced) |
SchemaManager | Load schemas from introspection + JSON |
Compliance
Section titled “Compliance”135/135 tests passing across all configurations:
| Adapter | PostgreSQL | MySQL | SQLite | MSSQL |
|---|---|---|---|---|
| Express | ✅ | ✅ | ✅ | ✅ |
| Fastify | ✅ | ✅ | ✅ | ✅ |
| NestJS | ✅ | ✅ | ✅ | ✅ |
Development
Section titled “Development”npm install && npm test # Install + testnpx prettier --check . # Format check (CI enforced)