@jsonql-standard/jsonql-ts
v1.1.0
Published
Official Node.js SDK for JSONQL with support for Express, Fastify, and NestJS
Downloads
158
Maintainers
Readme
jsonql-ts
The official Node.js/TypeScript SDK for JSONQL.
| | |
|---|---|
| Package | @jsonql-standard/jsonql-ts |
| Import | import { ... } from '@jsonql-standard/jsonql-ts' |
| Version | 1.0.1 |
| Node | ≥ 18 |
| Docs | jsonql.org/sdk/typescript |
JSONQL is a secure, lightweight, and polyglot JSON-based query language for filtering, sorting, pagination, field selection, and mutations in RESTful APIs.
Features
- JSONQL v1.0 Parser — parse and validate incoming JSON queries and mutations
- Query Builder — fluent, type-safe API with
JSONQLQueryBuilder - Mutation Builder — fluent API for create / update / delete with
JSONQLMutationBuilder - SQL Transpiler — convert parsed queries → parameterized SQL (PostgreSQL, MySQL, SQLite, MSSQL)
- MongoDB Transpiler — convert parsed queries → MongoDB aggregation pipelines
- Schema Validation — permission checking and field-level validation
- Result Hydrator — flatten SQL JOIN rows into nested JSON trees
- Driver Factory —
createDriver()with auto-config for Postgres, MySQL, SQLite, MSSQL - JSONQL Core — combined parser + validator + builder in a single class
- Condition Helpers —
eq,gt,contains,and,or,not, etc. - Express Adapter — middleware with parse-only or full-lifecycle execution
- Fastify Adapter — plugin with parse-only or full-lifecycle execution
- NestJS Adapter — module with decorator support and exception filter
- Provenance — npm package published with build provenance
Installation
npm install @jsonql-standard/jsonql-tsDatabase drivers are optional peer dependencies — install only what you need:
# PostgreSQL
npm install pg
# MySQL
npm install mysql2
# SQLite
npm install sqlite3
# MSSQL
npm install mssqlFramework adapters are also optional — install the framework you use:
# Express
npm install express
# Fastify
npm install fastify
# NestJS
npm install @nestjs/common @nestjs/core reflect-metadata rxjsQuick Start
A working JSONQL API in under 20 lines:
// app.ts
import express from 'express';
import { jsonqlExpress, createDriver, mustLoadSchema } from '@jsonql-standard/jsonql-ts';
async function main() {
const app = express();
const driver = await createDriver('postgres'); // reads DB_DSN from env
app.use('/api', jsonqlExpress({
driver,
schema: mustLoadSchema('schema.json'), // or define inline
}));
app.listen(3000, () => console.log('JSONQL API → http://localhost:3000'));
}
main();{
"tables": {
"users": {
"fields": {
"id": { "type": "number" },
"name": { "type": "string", "allowFilter": true, "allowSort": true },
"email": { "type": "string", "allowFilter": true },
"age": { "type": "number", "allowFilter": true, "allowSort": true }
}
}
}
}Prefer inline? Replace
mustLoadSchema(...)with a{ tables: { ... } }literal — see Schema Validation.
export DB_DSN="postgresql://user:pass@localhost:5432/mydb"
npx ts-node app.ts
# JSONQL API → http://localhost:3000curl -s 'http://localhost:3000/api/users?q={"fields":["id","name"],"where":{"age":{"gt":18}},"sort":{"name":"asc"},"limit":10}'[
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
]Builders
Query Builder
import { JSONQLQueryBuilder, field, eq, gt, and } from '@jsonql-standard/jsonql-ts';
const query = new JSONQLQueryBuilder()
.select('id', 'name', 'email')
.where(and(
field('status', eq('active')),
field('age', gt(18)),
))
.orderBy('name', 'asc')
.limit(10)
.build();Mutation Builder
import { JSONQLMutationBuilder } from '@jsonql-standard/jsonql-ts';
// Create
const insert = new JSONQLMutationBuilder()
.into('users')
.insert({ email: '[email protected]', name: 'Alice' })
.returning('id', 'email')
.build();
// Update
const update = new JSONQLMutationBuilder()
.into('users')
.update({ name: 'Alice Smith' })
.where({ id: { eq: 1 } })
.build();
// Delete
const del = new JSONQLMutationBuilder()
.into('users')
.delete()
.where({ id: { eq: 1 } })
.build();Transpilers
SQL Transpiler
import { SQLTranspiler } from '@jsonql-standard/jsonql-ts';
const transpiler = new SQLTranspiler('postgres');
const { sql, parameters } = transpiler.transpile(query, 'users');
// SELECT "id", "name", "email" FROM "users" WHERE "status" = $1 AND "age" > $2 ...MongoDB Transpiler
import { MongoTranspiler } from '@jsonql-standard/jsonql-ts';
const transpiler = new MongoTranspiler();
const result = transpiler.transpile(query, 'users');
// { collection: 'users', operation: 'find', filter: { status: 'active', age: { $gt: 18 } }, ... }Schema Validation
import { JSONQLValidator, mustLoadSchema } from '@jsonql-standard/jsonql-ts';
const schema = mustLoadSchema('schema.json');
// Or define inline:
// const schema = {
// tables: {
// users: {
// fields: {
// id: { type: 'number' },
// name: { type: 'string', allowFilter: true, allowSort: true },
// email: { type: 'string', allowFilter: true },
// password: { type: 'string', allowFilter: false }, // blocked
// },
// },
// },
// };
const validator = new JSONQLValidator(schema, 'users');
const result = validator.validate(query);
// { valid: true } or { valid: false, errors: [...] }Result Hydrator
import { ResultHydrator } from '@jsonql-standard/jsonql-ts';
const hydrator = new ResultHydrator();
// Flatten SQL JOIN rows into nested JSON
const rows = [
{ id: 1, name: 'Alice', posts__id: 10, posts__title: 'Hello' },
{ id: 1, name: 'Alice', posts__id: 11, posts__title: 'World' },
];
const result = hydrator.hydrate(rows, schema, 'users');
// [{ id: 1, name: 'Alice', posts: [{ id: 10, title: 'Hello' }, { id: 11, title: 'World' }] }]Framework Adapters
Express
See Quick Start for the full lifecycle example. Parse-only mode:
import express from 'express';
import { jsonqlExpress } from '@jsonql-standard/jsonql-ts';
const app = express();
app.use('/api', jsonqlExpress()); // attaches req.jsonql
app.get('/api/users', (req, res) => {
const query = req.jsonql; // Typed JSONQLQuery
// ... handle manually
});Fastify
import Fastify from 'fastify';
import { jsonqlFastify, createDriver } from '@jsonql-standard/jsonql-ts';
async function main() {
const fastify = Fastify();
const driver = await createDriver('postgres');
await fastify.register(jsonqlFastify, { driver });
await fastify.listen({ port: 3000 });
}
main();NestJS
import { Module } from '@nestjs/common';
import { JsonqlModule, createDriver } from '@jsonql-standard/jsonql-ts';
// In your bootstrap function:
const driver = await createDriver('postgres');
@Module({
imports: [
JsonqlModule.forRoot({ driver }),
],
})
export class AppModule {}Core API
| Export | Purpose |
|--------|---------|
| JSONQLParser | Parse & validate incoming JSON |
| SQLTranspiler | Convert parsed query → parameterized SQL |
| MongoTranspiler | Convert parsed query → MongoDB pipeline |
| JSONQLValidator | Schema-based permission checking |
| JSONQLQueryBuilder | Fluent query construction |
| JSONQLMutationBuilder | Fluent mutation construction |
| ResultHydrator | Flatten SQL joins → nested JSON |
| JSONQL | Combined parser + validator + builder |
| createDriver | Factory for database drivers |
| loadSchema | Load schema from a JSON file |
| mustLoadSchema | Load schema or throw on failure |
| envOr | Read env var with fallback |
| DatabaseDriver | Abstract database driver interface |
| jsonqlExpress | Express middleware factory |
| jsonqlFastify | Fastify plugin |
| JsonqlModule | NestJS module |
Supported Dialects
| Dialect | Placeholder | Quoting | RETURNING |
|------------|-------------|--------------|-----------|
| postgres | $1, $2 | "col" | ✅ |
| mysql | ?, ? | `col` | ❌ |
| sqlite | ?, ? | "col" | ❌ |
| mssql | @p1, @p2 | [col] | ❌ |
Condition Helpers
import {
eq, ne, gt, gte, lt, lte,
inArray, nin, contains, starts, ends,
field, and, or, not, fieldRef,
} from '@jsonql-standard/jsonql-ts';Error Hierarchy
JsonQLError
├── JsonQLValidationError (code: VALIDATION_ERROR)
├── JsonQLTranspileError (code: TRANSPILE_ERROR)
└── JsonQLExecutionError (code: EXECUTION_ERROR)Compliance
All 6 TypeScript integration adapters pass the full compliance test suite:
| Adapter | Type | PostgreSQL | |---------|------|:----------:| | Express | simple | ✅ | | Express | lifecycle | ✅ | | Fastify | simple | ✅ | | Fastify | lifecycle | ✅ | | NestJS | simple | ✅ | | NestJS | lifecycle | ✅ |
Tests run via jsonql-tests.
Development
npm install
npm test # 25 suites, 195 tests
npm run build # TypeScript → dist/
npx prettier --check "src/**/*.ts" "tests/**/*.ts"Examples
Check out the examples/ directory for complete reference implementations:
Links
License
MIT
