query-2jz
Version:
Query-2jz: A GraphQL alternative with faster performance and simpler use
200 lines (169 loc) • 4.84 kB
text/typescript
import { Query2jz, Query2jzConfig, Query2jzModel } from '../index';
/**
* Sails.js Adapter for Query2jz
*/
export class Query2jzSailsAdapter {
private qryn: Query2jz;
constructor(config: Query2jzConfig, models: Query2jzModel[] = []) {
this.qryn = new Query2jz(config, models);
}
/**
* Initialize the adapter
*/
async initialize(): Promise<void> {
await this.qryn.initialize();
}
/**
* Get Query2jz instance
*/
getQuery2jz(): Query2jz {
return this.qryn;
}
/**
* Register Sails.js routes
*/
registerRoutes(sails: any): void {
// Health check
sails.config.routes['GET /health'] = {
controller: 'Query2jzController',
action: 'health'
};
// Query endpoint
sails.config.routes['GET /api/qryn/:model'] = {
controller: 'Query2jzController',
action: 'query'
};
// Mutation endpoint
sails.config.routes['POST /api/qryn/:model'] = {
controller: 'Query2jzController',
action: 'mutate'
};
// Statistics endpoint
sails.config.routes['GET /api/qryn/stats'] = {
controller: 'Query2jzController',
action: 'stats'
};
}
}
/**
* Sails.js controller
*/
export class Query2jzController {
private qrynAdapter: Query2jzSailsAdapter;
constructor(qrynAdapter: Query2jzSailsAdapter) {
this.qrynAdapter = qrynAdapter;
}
async health(req: any, res: any): Promise<void> {
try {
const stats = this.qrynAdapter.getQuery2jz().getStats();
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
...stats
});
} catch (error) {
res.status(500).json({
status: 'unhealthy',
error: error instanceof Error ? error.message : 'Unknown error'
});
}
}
async query(req: any, res: any): Promise<void> {
try {
const model = req.param('model');
const query = this.parseQueryParams(req.query);
const result = await this.qrynAdapter.getQuery2jz().query(query, model);
if (result.meta?.etag) {
res.set('ETag', result.meta.etag);
}
if (result.meta?.lastModified) {
res.set('Last-Modified', result.meta.lastModified);
}
res.set('Cache-Control', 'public, max-age=300');
res.json(result);
} catch (error) {
res.status(500).json({
error: 'Query execution failed',
message: error instanceof Error ? error.message : 'Unknown error'
});
}
}
async mutate(req: any, res: any): Promise<void> {
try {
const model = req.param('model');
const mutation = req.body;
if (!mutation.operation) {
res.status(400).json({
error: 'Invalid mutation',
message: 'Operation is required'
});
return;
}
const result = await this.qrynAdapter.getQuery2jz().mutate(mutation, model);
res.set('Cache-Control', 'no-cache');
res.json(result);
} catch (error) {
res.status(500).json({
error: 'Mutation execution failed',
message: error instanceof Error ? error.message : 'Unknown error'
});
}
}
async stats(req: any, res: any): Promise<void> {
try {
const stats = this.qrynAdapter.getQuery2jz().getStats();
res.json(stats);
} catch (error) {
res.status(500).json({
error: 'Failed to get statistics',
message: error instanceof Error ? error.message : 'Unknown error'
});
}
}
private parseQueryParams(queryParams: any): any {
const query: any = {};
if (queryParams.select) {
try {
query.select = JSON.parse(queryParams.select);
} catch {
query.select = {};
}
}
if (queryParams.where) {
try {
query.where = JSON.parse(queryParams.where);
} catch {
query.where = {};
}
}
if (queryParams.orderBy) {
try {
query.orderBy = JSON.parse(queryParams.orderBy);
} catch {
query.orderBy = {};
}
}
if (queryParams.limit) {
query.limit = parseInt(queryParams.limit);
}
if (queryParams.offset) {
query.offset = parseInt(queryParams.offset);
}
if (queryParams.live === 'true') {
query.live = true;
}
return query;
}
}
/**
* Sails.js plugin factory
*/
export function createQuery2jzPlugin(config: Query2jzConfig, models: Query2jzModel[] = []) {
const adapter = new Query2jzSailsAdapter(config, models);
return {
adapter,
controller: Query2jzController,
registerRoutes: adapter.registerRoutes.bind(adapter),
initialize: () => adapter.initialize()
};
}