UNPKG

digitaltwin-core

Version:

Minimalist framework to collect and handle data in a Digital Twin project

110 lines 3.72 kB
/** * @fileoverview Handler component base class for HTTP endpoint providers * * Handlers are lightweight, stateless components that expose HTTP endpoints * for on-demand data access, computation, or utility services within the digital twin. */ /** * Abstract base class for Handler components. * * Handlers are lightweight, stateless components that expose HTTP endpoints * for on-demand data access, computation, or utility services. Unlike Collectors * and Harvesters, they don't run on schedules but respond to HTTP requests. * * Key features: * - Expose HTTP endpoints using the @servableEndpoint decorator * - Stateless operation (no database or storage dependencies by default) * - Suitable for real-time computations, data queries, or API proxies * * @example * ```typescript * class CalculatorHandler extends Handler { * getConfiguration() { * return { * name: 'calculator-handler', * type: 'handler', * contentType: 'application/json' * }; * } * * @servableEndpoint({ path: '/api/calculate/sum', method: 'post' }) * async calculateSum(req: Request) { * const { a, b } = req.body; * return { * status: 200, * content: { result: a + b } * }; * } * } * ``` */ export class Handler { /** * Resolves and returns HTTP endpoints defined on this handler. * * Automatically discovers endpoints declared with the @servableEndpoint * decorator and creates bound handler functions for registration with * the Express router. * * @returns Array of endpoint descriptors with bound handler functions */ getEndpoints() { const config = this.getConfiguration(); const ctor = this.constructor; const endpoints = ctor.__endpoints || []; return endpoints.map(ep => { const handlerFn = this[ep.handlerName].bind(this); return { method: ep.method, path: ep.path, responseType: ep.responseType || config.contentType, handler: handlerFn }; }); } /** * Returns the OpenAPI specification for this handler's endpoints. * * Generates documentation for all endpoints declared with @servableEndpoint. * Can be overridden by subclasses for more detailed specifications. * * @returns {OpenAPIComponentSpec} OpenAPI paths, tags, and schemas for this handler */ getOpenAPISpec() { const config = this.getConfiguration(); const endpoints = this.getEndpoints(); const tagName = config.tags?.[0] || config.name; const paths = {}; for (const endpoint of endpoints) { const method = endpoint.method.toLowerCase(); if (!paths[endpoint.path]) { paths[endpoint.path] = {}; } paths[endpoint.path][method] = { summary: `${method.toUpperCase()} ${endpoint.path}`, description: config.description, tags: [tagName], responses: { '200': { description: 'Successful response', content: { [endpoint.responseType || config.contentType]: { schema: { type: 'object' } } } } } }; } return { paths, tags: [ { name: tagName, description: config.description } ] }; } } //# sourceMappingURL=handler.js.map