UNPKG

@cardql/node

Version:

CardQL SDK for Node.js and serverless applications

128 lines (109 loc) 2.9 kB
import type { Request, Response, NextFunction } from "express"; import { NodeCardQL } from "./client"; import type { NodeCardQLConfig } from "./config"; // Extend Express Request type to include cardql instance declare global { namespace Express { interface Request { cardql?: NodeCardQL; } } } export interface MiddlewareOptions extends NodeCardQLConfig { // Additional middleware-specific options skipHealthCheck?: boolean; errorHandler?: ( error: Error, req: Request, res: Response, next: NextFunction ) => void; } /** * Express middleware to inject CardQL instance into requests */ export function cardqlMiddleware(options: MiddlewareOptions = {}) { const cardql = new NodeCardQL(options); // Perform initial health check unless disabled if (!options.skipHealthCheck) { cardql.healthCheck().catch((error) => { console.warn("[CardQL] Initial health check failed:", error.message); }); } return (req: Request, res: Response, next: NextFunction) => { // Attach CardQL instance to request req.cardql = cardql; next(); }; } /** * Error handling middleware for CardQL errors */ export function cardqlErrorHandler() { return (error: any, req: Request, res: Response, next: NextFunction) => { // Check if it's a CardQL error if (error.code && error.message) { const statusCode = getHttpStatusFromCardQLError(error); res.status(statusCode).json({ error: { message: error.message, code: error.code, details: error.details, }, }); return; } // Pass through other errors next(error); }; } /** * Map CardQL error codes to HTTP status codes */ function getHttpStatusFromCardQLError(error: any): number { switch (error.code) { case "UNAUTHENTICATED": case "INVALID_API_KEY": return 401; case "FORBIDDEN": case "INSUFFICIENT_PERMISSIONS": return 403; case "NOT_FOUND": case "RESOURCE_NOT_FOUND": return 404; case "VALIDATION_ERROR": case "INVALID_INPUT": return 400; case "RATE_LIMITED": return 429; case "HTTP_ERROR": return error.details?.status || 500; default: return 500; } } /** * Utility function to create CardQL context for serverless functions */ export function createCardQLContext(config?: NodeCardQLConfig): { cardql: NodeCardQL; } { return { cardql: new NodeCardQL(config), }; } /** * Higher-order function for serverless function handlers */ export function withCardQL<TEvent = any, TResult = any>( handler: ( event: TEvent, context: any & { cardql: NodeCardQL } ) => Promise<TResult>, config?: NodeCardQLConfig ) { const cardql = new NodeCardQL(config); return async (event: TEvent, context: any): Promise<TResult> => { return handler(event, { ...context, cardql }); }; }