@kopai/api 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -225,6 +225,10 @@ const metricsRoutes = async function(fastify, opts) {
225
225
  data: zod_v4.z.array(_kopai_core.denormalizedSignals.otelMetricsSchema),
226
226
  nextCursor: zod_v4.z.string().nullable()
227
227
  });
228
+ const aggregatedResponseSchema = zod_v4.z.object({
229
+ data: zod_v4.z.array(_kopai_core.denormalizedSignals.aggregatedMetricSchema),
230
+ nextCursor: zod_v4.z.null()
231
+ });
228
232
  fastify.route({
229
233
  method: "POST",
230
234
  url: "/signals/metrics/search",
@@ -232,16 +236,17 @@ const metricsRoutes = async function(fastify, opts) {
232
236
  description: "Search metrics matching a filter",
233
237
  body: _kopai_core.dataFilterSchemas.metricsDataFilterSchema,
234
238
  response: {
235
- 200: searchResponseSchema,
239
+ 200: zod_v4.z.union([searchResponseSchema, aggregatedResponseSchema]),
236
240
  "4xx": problemDetailsSchema,
237
241
  "5xx": problemDetailsSchema
238
242
  }
239
243
  },
240
244
  handler: async (req, res) => {
241
- const result = await opts.readMetricsDatasource.getMetrics({
245
+ const params = {
242
246
  ...req.body,
243
247
  requestContext: req.requestContext
244
- });
248
+ };
249
+ const result = req.body.aggregate ? await opts.readMetricsDatasource.getAggregatedMetrics(params) : await opts.readMetricsDatasource.getMetrics(params);
245
250
  res.send(result);
246
251
  }
247
252
  });
package/dist/index.mjs CHANGED
@@ -201,6 +201,10 @@ const metricsRoutes = async function(fastify, opts) {
201
201
  data: z.array(denormalizedSignals.otelMetricsSchema),
202
202
  nextCursor: z.string().nullable()
203
203
  });
204
+ const aggregatedResponseSchema = z.object({
205
+ data: z.array(denormalizedSignals.aggregatedMetricSchema),
206
+ nextCursor: z.null()
207
+ });
204
208
  fastify.route({
205
209
  method: "POST",
206
210
  url: "/signals/metrics/search",
@@ -208,16 +212,17 @@ const metricsRoutes = async function(fastify, opts) {
208
212
  description: "Search metrics matching a filter",
209
213
  body: dataFilterSchemas.metricsDataFilterSchema,
210
214
  response: {
211
- 200: searchResponseSchema,
215
+ 200: z.union([searchResponseSchema, aggregatedResponseSchema]),
212
216
  "4xx": problemDetailsSchema,
213
217
  "5xx": problemDetailsSchema
214
218
  }
215
219
  },
216
220
  handler: async (req, res) => {
217
- const result = await opts.readMetricsDatasource.getMetrics({
221
+ const params = {
218
222
  ...req.body,
219
223
  requestContext: req.requestContext
220
- });
224
+ };
225
+ const result = req.body.aggregate ? await opts.readMetricsDatasource.getAggregatedMetrics(params) : await opts.readMetricsDatasource.getMetrics(params);
221
226
  res.send(result);
222
227
  }
223
228
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["z","dashboardsRoutes","_dashboardsRoutes"],"sources":["../src/routes/errors.ts","../src/routes/error-handler.ts","../src/routes/error-schema-zod.ts","../src/routes/traces.ts","../src/routes/logs.ts","../src/routes/metrics.ts","../src/routes/dashboards.ts","../src/index.ts"],"sourcesContent":["export abstract class ApiError extends Error {\n abstract readonly code: string;\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport abstract class SignalsApiError extends ApiError {}\n\nexport class DashboardNotFoundError extends ApiError {\n readonly code = \"DASHBOARD_NOT_FOUND\";\n}\n","import {\n type FastifyError,\n type FastifyReply,\n type FastifyRequest,\n} from \"fastify\";\nimport { ApiError, DashboardNotFoundError } from \"./errors.js\";\nimport type { ApiErrorResponse } from \"./error-schema-zod.js\";\nexport function errorHandler(\n error: FastifyError | Error | string,\n request: FastifyRequest,\n reply: FastifyReply\n) {\n if (isClientError(error)) {\n return reply.status(400).send({\n // https://datatracker.ietf.org/doc/html/rfc9457\n // HTTP/1.1 422 Unprocessable Content\n // Content-Type: application/problem+json\n // Content-Language: en\n //\n // {\n // \"type\": \"https://example.net/validation-error\",\n // \"title\": \"Your request is not valid.\",\n // \"errors\": [\n // {\n // \"detail\": \"must be a positive integer\",\n // \"pointer\": \"#/age\"\n // },\n // {\n // \"detail\": \"must be 'green', 'red' or 'blue'\",\n // \"pointer\": \"#/profile/color\"\n // }\n // ]\n // }\n type: \"https://docs.kopai.app/errors/signals-api-validation-error\", // TODO: document error\n status: 400,\n title: \"Invalid data\",\n detail: error.message,\n } satisfies ApiErrorResponse);\n }\n\n if (error instanceof DashboardNotFoundError) {\n request.log.info(error.message);\n return reply.status(404).send({\n type: \"https://docs.kopai.app/errors/dashboard-not-found\",\n status: 404,\n title: \"Dashboard not found\",\n detail: error.message,\n } satisfies ApiErrorResponse);\n }\n request.log.error(error);\n if (error instanceof ApiError) {\n return reply.status(500).send({\n type: \"https://docs.kopai.app/errors/signals-api-internal-error\", // TODO: document error\n status: 500,\n title: \"Internal server error\",\n detail: error.message,\n } satisfies ApiErrorResponse);\n }\n\n return reply.status(500).send({\n type: \"https://docs.kopai.app/errors/signals-api-internal-error\", // TODO: document error\n status: 500,\n title: \"Internal server error\",\n } satisfies ApiErrorResponse);\n}\n\nfunction isFastifyError(error: unknown): error is FastifyError {\n return (\n error instanceof Error &&\n \"code\" in error &&\n typeof (error as FastifyError).code === \"string\"\n );\n}\n\nfunction isClientError(error: unknown): error is FastifyError {\n return (\n isFastifyError(error) &&\n typeof error.statusCode === \"number\" &&\n error.statusCode >= 400 &&\n error.statusCode < 500\n );\n}\n","import z from \"zod\";\n\nexport const problemDetailsSchema = z.object({\n type: z\n .url()\n .default(\"about:blank\")\n .describe(\"URI reference identifying the problem type\"),\n status: z\n .number()\n .int()\n .min(100)\n .max(599)\n .optional()\n .describe(\"HTTP status code generated by the origin server\"),\n title: z\n .string()\n .optional()\n .describe(\"Short human-readable summary of the problem type\"),\n detail: z\n .string()\n .optional()\n .describe(\"Human-readable explanation specific to this occurrence\"),\n instance: z\n .string()\n .optional()\n .describe(\"URI reference identifying this specific occurrence\"),\n});\n\nexport type ApiErrorResponse = z.infer<typeof problemDetailsSchema>;\n","import { z } from \"zod/v4\";\nimport type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport {\n dataFilterSchemas,\n denormalizedSignals,\n type datasource,\n} from \"@kopai/core\";\nimport { problemDetailsSchema } from \"./error-schema-zod.js\";\n\nexport const tracesRoutes: FastifyPluginAsyncZod<{\n readTracesDatasource: datasource.ReadTracesDatasource &\n datasource.ReadTracesMetaDatasource;\n}> = async function (fastify, opts) {\n fastify.route({\n method: \"GET\",\n url: \"/signals/traces/:traceId\",\n schema: {\n description: \"Get all spans for a trace by traceId\",\n params: z.object({\n traceId: z.string().describe(\"A TraceId of the trace\"),\n }),\n response: {\n 200: z.array(denormalizedSignals.otelTracesSchema),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getTraces({\n traceId: req.params.traceId,\n requestContext: req.requestContext,\n });\n res.send(result.data);\n },\n });\n\n const searchResponseSchema = z.object({\n data: z.array(denormalizedSignals.otelTracesSchema),\n nextCursor: z.string().nullable(),\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/signals/traces/search\",\n schema: {\n description: \"Search spans matching a filter\",\n body: dataFilterSchemas.tracesDataFilterSchema,\n response: {\n 200: searchResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getTraces({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n\n fastify.route({\n method: \"GET\",\n url: \"/signals/services\",\n schema: {\n description: \"List distinct service names\",\n response: {\n 200: z.object({ services: z.array(z.string()) }),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getServices({\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n\n fastify.route({\n method: \"GET\",\n url: \"/signals/traces/operations\",\n schema: {\n description: \"List distinct operations for a service\",\n querystring: z.object({ serviceName: z.string() }),\n response: {\n 200: z.object({ operations: z.array(z.string()) }),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getOperations({\n serviceName: req.query.serviceName,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/signals/traces/summaries\",\n schema: {\n description: \"Search trace summaries\",\n body: dataFilterSchemas.traceSummariesFilterSchema,\n response: {\n 200: z.object({\n data: z.array(dataFilterSchemas.traceSummaryRowSchema),\n nextCursor: z.string().nullable(),\n }),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getTraceSummaries({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n};\n","import { z } from \"zod/v4\";\nimport type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport {\n dataFilterSchemas,\n denormalizedSignals,\n type datasource,\n} from \"@kopai/core\";\nimport { problemDetailsSchema } from \"./error-schema-zod.js\";\n\nexport const logsRoutes: FastifyPluginAsyncZod<{\n readLogsDatasource: datasource.ReadLogsDatasource;\n}> = async function (fastify, opts) {\n const searchResponseSchema = z.object({\n data: z.array(denormalizedSignals.otelLogsSchema),\n nextCursor: z.string().nullable(),\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/signals/logs/search\",\n schema: {\n description: \"Search logs matching a filter\",\n body: dataFilterSchemas.logsDataFilterSchema,\n response: {\n 200: searchResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readLogsDatasource.getLogs({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n};\n","import { z } from \"zod/v4\";\nimport type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport {\n dataFilterSchemas,\n denormalizedSignals,\n type datasource,\n} from \"@kopai/core\";\nimport { problemDetailsSchema } from \"./error-schema-zod.js\";\n\nexport const metricsRoutes: FastifyPluginAsyncZod<{\n readMetricsDatasource: datasource.ReadMetricsDatasource;\n}> = async function (fastify, opts) {\n const searchResponseSchema = z.object({\n data: z.array(denormalizedSignals.otelMetricsSchema),\n nextCursor: z.string().nullable(),\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/signals/metrics/search\",\n schema: {\n description: \"Search metrics matching a filter\",\n body: dataFilterSchemas.metricsDataFilterSchema,\n response: {\n 200: searchResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readMetricsDatasource.getMetrics({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n\n fastify.route({\n method: \"GET\",\n url: \"/signals/metrics/discover\",\n schema: {\n description: \"Discover available metrics and their attributes\",\n response: {\n 200: metricsDiscoveryResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readMetricsDatasource.discoverMetrics({\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n};\n\nconst metricTypeSchema = z.enum([\n \"Gauge\",\n \"Sum\",\n \"Histogram\",\n \"ExponentialHistogram\",\n \"Summary\",\n]);\n\nconst discoveredAttributesSchema = z.object({\n values: z\n .record(z.string(), z.array(z.string()))\n .describe(\"Attribute key/value pairs. Max 100 values per key.\"),\n _truncated: z\n .boolean()\n .optional()\n .describe(\"True if any attribute key exceeded 100 values.\"),\n});\n\nconst discoveredMetricSchema = z.object({\n name: z.string().describe(\"Metric name from MetricName field.\"),\n type: metricTypeSchema.describe(\n \"Metric type: Gauge, Sum, Histogram, ExponentialHistogram, or Summary.\"\n ),\n unit: z.string().optional().describe(\"Metric unit from MetricUnit field.\"),\n description: z\n .string()\n .optional()\n .describe(\"Metric description from MetricDescription field.\"),\n attributes: discoveredAttributesSchema.describe(\n \"Data point attributes aggregated across all data points.\"\n ),\n resourceAttributes: discoveredAttributesSchema.describe(\n \"Resource attributes aggregated across all data points.\"\n ),\n});\n\nconst metricsDiscoveryResponseSchema = z.object({\n metrics: z.array(discoveredMetricSchema),\n});\n","import { z } from \"zod/v4\";\nimport type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport { dashboardDatasource } from \"@kopai/core\";\nimport { problemDetailsSchema } from \"./error-schema-zod.js\";\nimport { DashboardNotFoundError } from \"./errors.js\";\n\nexport const dashboardsRoutes: FastifyPluginAsyncZod<{\n dynamicDashboardDatasource: dashboardDatasource.DynamicDashboardDatasource;\n promptInstructions?: string;\n}> = async function (fastify, opts) {\n fastify.route({\n method: \"GET\",\n url: \"/dashboards/schema\",\n schema: {\n description:\n \"Get UI tree schema as markdown prompt instructions for AI agents\",\n produces: [\"text/markdown\"],\n response: {\n 200: z.string().describe(\"Markdown prompt instructions\"),\n 404: z.string().describe(\"Prompt instructions not configured\"),\n },\n },\n handler: async (_req, reply) => {\n if (!opts.promptInstructions) {\n return reply.status(404).send(\"Dashboard schema not configured\");\n }\n reply.type(\"text/markdown\").send(opts.promptInstructions);\n },\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/dashboards\",\n schema: {\n description: \"Create a dashboard containing a uiTree\",\n body: dashboardDatasource.createDashboardParams,\n response: {\n 201: dashboardDatasource.dashboardSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.dynamicDashboardDatasource.createDashboard({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.status(201).send(result);\n },\n });\n\n fastify.route({\n method: \"GET\",\n url: \"/dashboards/:dashboardId\",\n schema: {\n description: \"Get a dashboard containing a uiTree to be rendered\",\n params: z.object({\n dashboardId: z.string(),\n }),\n response: {\n 200: dashboardDatasource.dashboardSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n try {\n const result = await opts.dynamicDashboardDatasource.getDashboard({\n id: req.params.dashboardId,\n requestContext: req.requestContext,\n });\n res.send(result);\n } catch (error) {\n const msg = error instanceof Error ? error.message.toLowerCase() : \"\";\n if (msg.includes(\"not found\")) {\n throw new DashboardNotFoundError(\n `Dashboard not found: ${req.params.dashboardId}`,\n { cause: error }\n );\n }\n throw error;\n }\n },\n });\n\n const searchResponseSchema = z.object({\n data: z.array(dashboardDatasource.dashboardSchema),\n nextCursor: z.string().nullable(),\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/dashboards/search\",\n schema: {\n description: \"Search dashboards matching a filter\",\n body: dashboardDatasource.searchDashboardsFilter,\n response: {\n 200: searchResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.dynamicDashboardDatasource.searchDashboards({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n};\n","import type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport { type datasource, type dashboardDatasource } from \"@kopai/core\";\n\nimport {\n serializerCompiler,\n validatorCompiler,\n} from \"fastify-type-provider-zod\";\nimport { errorHandler } from \"./routes/error-handler.js\";\nimport { tracesRoutes } from \"./routes/traces.js\";\nimport { logsRoutes } from \"./routes/logs.js\";\nimport { metricsRoutes } from \"./routes/metrics.js\";\nimport { dashboardsRoutes as _dashboardsRoutes } from \"./routes/dashboards.js\";\n\nexport const signalsRoutes: FastifyPluginAsyncZod<{\n readTelemetryDatasource: datasource.ReadTelemetryDatasource;\n}> = async function (fastify, opts) {\n fastify.setValidatorCompiler(validatorCompiler);\n fastify.setSerializerCompiler(serializerCompiler);\n fastify.setErrorHandler(errorHandler);\n\n fastify.register(tracesRoutes, {\n readTracesDatasource: opts.readTelemetryDatasource,\n });\n\n fastify.register(logsRoutes, {\n readLogsDatasource: opts.readTelemetryDatasource,\n });\n\n fastify.register(metricsRoutes, {\n readMetricsDatasource: opts.readTelemetryDatasource,\n });\n};\n\nexport const dashboardsRoutes: FastifyPluginAsyncZod<{\n dynamicDashboardDatasource: dashboardDatasource.DynamicDashboardDatasource;\n promptInstructions?: string;\n}> = async function (fastify, opts) {\n fastify.setValidatorCompiler(validatorCompiler);\n fastify.setSerializerCompiler(serializerCompiler);\n fastify.setErrorHandler(errorHandler);\n\n fastify.register(_dashboardsRoutes, {\n dynamicDashboardDatasource: opts.dynamicDashboardDatasource,\n promptInstructions: opts.promptInstructions,\n });\n};\n\ndeclare module \"fastify\" {\n interface FastifyRequest {\n requestContext?: unknown;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["z","dashboardsRoutes","_dashboardsRoutes"],"sources":["../src/routes/errors.ts","../src/routes/error-handler.ts","../src/routes/error-schema-zod.ts","../src/routes/traces.ts","../src/routes/logs.ts","../src/routes/metrics.ts","../src/routes/dashboards.ts","../src/index.ts"],"sourcesContent":["export abstract class ApiError extends Error {\n abstract readonly code: string;\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport abstract class SignalsApiError extends ApiError {}\n\nexport class DashboardNotFoundError extends ApiError {\n readonly code = \"DASHBOARD_NOT_FOUND\";\n}\n","import {\n type FastifyError,\n type FastifyReply,\n type FastifyRequest,\n} from \"fastify\";\nimport { ApiError, DashboardNotFoundError } from \"./errors.js\";\nimport type { ApiErrorResponse } from \"./error-schema-zod.js\";\nexport function errorHandler(\n error: FastifyError | Error | string,\n request: FastifyRequest,\n reply: FastifyReply\n) {\n if (isClientError(error)) {\n return reply.status(400).send({\n // https://datatracker.ietf.org/doc/html/rfc9457\n // HTTP/1.1 422 Unprocessable Content\n // Content-Type: application/problem+json\n // Content-Language: en\n //\n // {\n // \"type\": \"https://example.net/validation-error\",\n // \"title\": \"Your request is not valid.\",\n // \"errors\": [\n // {\n // \"detail\": \"must be a positive integer\",\n // \"pointer\": \"#/age\"\n // },\n // {\n // \"detail\": \"must be 'green', 'red' or 'blue'\",\n // \"pointer\": \"#/profile/color\"\n // }\n // ]\n // }\n type: \"https://docs.kopai.app/errors/signals-api-validation-error\", // TODO: document error\n status: 400,\n title: \"Invalid data\",\n detail: error.message,\n } satisfies ApiErrorResponse);\n }\n\n if (error instanceof DashboardNotFoundError) {\n request.log.info(error.message);\n return reply.status(404).send({\n type: \"https://docs.kopai.app/errors/dashboard-not-found\",\n status: 404,\n title: \"Dashboard not found\",\n detail: error.message,\n } satisfies ApiErrorResponse);\n }\n request.log.error(error);\n if (error instanceof ApiError) {\n return reply.status(500).send({\n type: \"https://docs.kopai.app/errors/signals-api-internal-error\", // TODO: document error\n status: 500,\n title: \"Internal server error\",\n detail: error.message,\n } satisfies ApiErrorResponse);\n }\n\n return reply.status(500).send({\n type: \"https://docs.kopai.app/errors/signals-api-internal-error\", // TODO: document error\n status: 500,\n title: \"Internal server error\",\n } satisfies ApiErrorResponse);\n}\n\nfunction isFastifyError(error: unknown): error is FastifyError {\n return (\n error instanceof Error &&\n \"code\" in error &&\n typeof (error as FastifyError).code === \"string\"\n );\n}\n\nfunction isClientError(error: unknown): error is FastifyError {\n return (\n isFastifyError(error) &&\n typeof error.statusCode === \"number\" &&\n error.statusCode >= 400 &&\n error.statusCode < 500\n );\n}\n","import z from \"zod\";\n\nexport const problemDetailsSchema = z.object({\n type: z\n .url()\n .default(\"about:blank\")\n .describe(\"URI reference identifying the problem type\"),\n status: z\n .number()\n .int()\n .min(100)\n .max(599)\n .optional()\n .describe(\"HTTP status code generated by the origin server\"),\n title: z\n .string()\n .optional()\n .describe(\"Short human-readable summary of the problem type\"),\n detail: z\n .string()\n .optional()\n .describe(\"Human-readable explanation specific to this occurrence\"),\n instance: z\n .string()\n .optional()\n .describe(\"URI reference identifying this specific occurrence\"),\n});\n\nexport type ApiErrorResponse = z.infer<typeof problemDetailsSchema>;\n","import { z } from \"zod/v4\";\nimport type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport {\n dataFilterSchemas,\n denormalizedSignals,\n type datasource,\n} from \"@kopai/core\";\nimport { problemDetailsSchema } from \"./error-schema-zod.js\";\n\nexport const tracesRoutes: FastifyPluginAsyncZod<{\n readTracesDatasource: datasource.ReadTracesDatasource &\n datasource.ReadTracesMetaDatasource;\n}> = async function (fastify, opts) {\n fastify.route({\n method: \"GET\",\n url: \"/signals/traces/:traceId\",\n schema: {\n description: \"Get all spans for a trace by traceId\",\n params: z.object({\n traceId: z.string().describe(\"A TraceId of the trace\"),\n }),\n response: {\n 200: z.array(denormalizedSignals.otelTracesSchema),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getTraces({\n traceId: req.params.traceId,\n requestContext: req.requestContext,\n });\n res.send(result.data);\n },\n });\n\n const searchResponseSchema = z.object({\n data: z.array(denormalizedSignals.otelTracesSchema),\n nextCursor: z.string().nullable(),\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/signals/traces/search\",\n schema: {\n description: \"Search spans matching a filter\",\n body: dataFilterSchemas.tracesDataFilterSchema,\n response: {\n 200: searchResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getTraces({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n\n fastify.route({\n method: \"GET\",\n url: \"/signals/services\",\n schema: {\n description: \"List distinct service names\",\n response: {\n 200: z.object({ services: z.array(z.string()) }),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getServices({\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n\n fastify.route({\n method: \"GET\",\n url: \"/signals/traces/operations\",\n schema: {\n description: \"List distinct operations for a service\",\n querystring: z.object({ serviceName: z.string() }),\n response: {\n 200: z.object({ operations: z.array(z.string()) }),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getOperations({\n serviceName: req.query.serviceName,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/signals/traces/summaries\",\n schema: {\n description: \"Search trace summaries\",\n body: dataFilterSchemas.traceSummariesFilterSchema,\n response: {\n 200: z.object({\n data: z.array(dataFilterSchemas.traceSummaryRowSchema),\n nextCursor: z.string().nullable(),\n }),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readTracesDatasource.getTraceSummaries({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n};\n","import { z } from \"zod/v4\";\nimport type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport {\n dataFilterSchemas,\n denormalizedSignals,\n type datasource,\n} from \"@kopai/core\";\nimport { problemDetailsSchema } from \"./error-schema-zod.js\";\n\nexport const logsRoutes: FastifyPluginAsyncZod<{\n readLogsDatasource: datasource.ReadLogsDatasource;\n}> = async function (fastify, opts) {\n const searchResponseSchema = z.object({\n data: z.array(denormalizedSignals.otelLogsSchema),\n nextCursor: z.string().nullable(),\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/signals/logs/search\",\n schema: {\n description: \"Search logs matching a filter\",\n body: dataFilterSchemas.logsDataFilterSchema,\n response: {\n 200: searchResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readLogsDatasource.getLogs({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n};\n","import { z } from \"zod/v4\";\nimport type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport {\n dataFilterSchemas,\n denormalizedSignals,\n type datasource,\n} from \"@kopai/core\";\nimport { problemDetailsSchema } from \"./error-schema-zod.js\";\n\nexport const metricsRoutes: FastifyPluginAsyncZod<{\n readMetricsDatasource: datasource.ReadMetricsDatasource;\n}> = async function (fastify, opts) {\n const searchResponseSchema = z.object({\n data: z.array(denormalizedSignals.otelMetricsSchema),\n nextCursor: z.string().nullable(),\n });\n\n const aggregatedResponseSchema = z.object({\n data: z.array(denormalizedSignals.aggregatedMetricSchema),\n nextCursor: z.null(),\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/signals/metrics/search\",\n schema: {\n description: \"Search metrics matching a filter\",\n body: dataFilterSchemas.metricsDataFilterSchema,\n response: {\n 200: z.union([searchResponseSchema, aggregatedResponseSchema]),\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const params = { ...req.body, requestContext: req.requestContext };\n const result = req.body.aggregate\n ? await opts.readMetricsDatasource.getAggregatedMetrics(params)\n : await opts.readMetricsDatasource.getMetrics(params);\n res.send(result);\n },\n });\n\n fastify.route({\n method: \"GET\",\n url: \"/signals/metrics/discover\",\n schema: {\n description: \"Discover available metrics and their attributes\",\n response: {\n 200: metricsDiscoveryResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.readMetricsDatasource.discoverMetrics({\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n};\n\nconst metricTypeSchema = z.enum([\n \"Gauge\",\n \"Sum\",\n \"Histogram\",\n \"ExponentialHistogram\",\n \"Summary\",\n]);\n\nconst discoveredAttributesSchema = z.object({\n values: z\n .record(z.string(), z.array(z.string()))\n .describe(\"Attribute key/value pairs. Max 100 values per key.\"),\n _truncated: z\n .boolean()\n .optional()\n .describe(\"True if any attribute key exceeded 100 values.\"),\n});\n\nconst discoveredMetricSchema = z.object({\n name: z.string().describe(\"Metric name from MetricName field.\"),\n type: metricTypeSchema.describe(\n \"Metric type: Gauge, Sum, Histogram, ExponentialHistogram, or Summary.\"\n ),\n unit: z.string().optional().describe(\"Metric unit from MetricUnit field.\"),\n description: z\n .string()\n .optional()\n .describe(\"Metric description from MetricDescription field.\"),\n attributes: discoveredAttributesSchema.describe(\n \"Data point attributes aggregated across all data points.\"\n ),\n resourceAttributes: discoveredAttributesSchema.describe(\n \"Resource attributes aggregated across all data points.\"\n ),\n});\n\nconst metricsDiscoveryResponseSchema = z.object({\n metrics: z.array(discoveredMetricSchema),\n});\n","import { z } from \"zod/v4\";\nimport type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport { dashboardDatasource } from \"@kopai/core\";\nimport { problemDetailsSchema } from \"./error-schema-zod.js\";\nimport { DashboardNotFoundError } from \"./errors.js\";\n\nexport const dashboardsRoutes: FastifyPluginAsyncZod<{\n dynamicDashboardDatasource: dashboardDatasource.DynamicDashboardDatasource;\n promptInstructions?: string;\n}> = async function (fastify, opts) {\n fastify.route({\n method: \"GET\",\n url: \"/dashboards/schema\",\n schema: {\n description:\n \"Get UI tree schema as markdown prompt instructions for AI agents\",\n produces: [\"text/markdown\"],\n response: {\n 200: z.string().describe(\"Markdown prompt instructions\"),\n 404: z.string().describe(\"Prompt instructions not configured\"),\n },\n },\n handler: async (_req, reply) => {\n if (!opts.promptInstructions) {\n return reply.status(404).send(\"Dashboard schema not configured\");\n }\n reply.type(\"text/markdown\").send(opts.promptInstructions);\n },\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/dashboards\",\n schema: {\n description: \"Create a dashboard containing a uiTree\",\n body: dashboardDatasource.createDashboardParams,\n response: {\n 201: dashboardDatasource.dashboardSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.dynamicDashboardDatasource.createDashboard({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.status(201).send(result);\n },\n });\n\n fastify.route({\n method: \"GET\",\n url: \"/dashboards/:dashboardId\",\n schema: {\n description: \"Get a dashboard containing a uiTree to be rendered\",\n params: z.object({\n dashboardId: z.string(),\n }),\n response: {\n 200: dashboardDatasource.dashboardSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n try {\n const result = await opts.dynamicDashboardDatasource.getDashboard({\n id: req.params.dashboardId,\n requestContext: req.requestContext,\n });\n res.send(result);\n } catch (error) {\n const msg = error instanceof Error ? error.message.toLowerCase() : \"\";\n if (msg.includes(\"not found\")) {\n throw new DashboardNotFoundError(\n `Dashboard not found: ${req.params.dashboardId}`,\n { cause: error }\n );\n }\n throw error;\n }\n },\n });\n\n const searchResponseSchema = z.object({\n data: z.array(dashboardDatasource.dashboardSchema),\n nextCursor: z.string().nullable(),\n });\n\n fastify.route({\n method: \"POST\",\n url: \"/dashboards/search\",\n schema: {\n description: \"Search dashboards matching a filter\",\n body: dashboardDatasource.searchDashboardsFilter,\n response: {\n 200: searchResponseSchema,\n \"4xx\": problemDetailsSchema,\n \"5xx\": problemDetailsSchema,\n },\n },\n handler: async (req, res) => {\n const result = await opts.dynamicDashboardDatasource.searchDashboards({\n ...req.body,\n requestContext: req.requestContext,\n });\n res.send(result);\n },\n });\n};\n","import type { FastifyPluginAsyncZod } from \"fastify-type-provider-zod\";\nimport { type datasource, type dashboardDatasource } from \"@kopai/core\";\n\nimport {\n serializerCompiler,\n validatorCompiler,\n} from \"fastify-type-provider-zod\";\nimport { errorHandler } from \"./routes/error-handler.js\";\nimport { tracesRoutes } from \"./routes/traces.js\";\nimport { logsRoutes } from \"./routes/logs.js\";\nimport { metricsRoutes } from \"./routes/metrics.js\";\nimport { dashboardsRoutes as _dashboardsRoutes } from \"./routes/dashboards.js\";\n\nexport const signalsRoutes: FastifyPluginAsyncZod<{\n readTelemetryDatasource: datasource.ReadTelemetryDatasource;\n}> = async function (fastify, opts) {\n fastify.setValidatorCompiler(validatorCompiler);\n fastify.setSerializerCompiler(serializerCompiler);\n fastify.setErrorHandler(errorHandler);\n\n fastify.register(tracesRoutes, {\n readTracesDatasource: opts.readTelemetryDatasource,\n });\n\n fastify.register(logsRoutes, {\n readLogsDatasource: opts.readTelemetryDatasource,\n });\n\n fastify.register(metricsRoutes, {\n readMetricsDatasource: opts.readTelemetryDatasource,\n });\n};\n\nexport const dashboardsRoutes: FastifyPluginAsyncZod<{\n dynamicDashboardDatasource: dashboardDatasource.DynamicDashboardDatasource;\n promptInstructions?: string;\n}> = async function (fastify, opts) {\n fastify.setValidatorCompiler(validatorCompiler);\n fastify.setSerializerCompiler(serializerCompiler);\n fastify.setErrorHandler(errorHandler);\n\n fastify.register(_dashboardsRoutes, {\n dynamicDashboardDatasource: opts.dynamicDashboardDatasource,\n promptInstructions: opts.promptInstructions,\n });\n};\n\ndeclare module \"fastify\" {\n interface FastifyRequest {\n requestContext?: unknown;\n }\n}\n"],"mappings":";;;;;;AAAA,IAAsB,WAAtB,cAAuC,MAAM;CAG3C,YAAY,SAAiB,SAAwB;AACnD,QAAM,SAAS,QAAQ;AACvB,SAAO,eAAe,MAAM,IAAI,OAAO,UAAU;;;AAMrD,IAAa,yBAAb,cAA4C,SAAS;CACnD,OAAgB;;;;ACLlB,SAAgB,aACd,OACA,SACA,OACA;AACA,KAAI,cAAc,MAAM,CACtB,QAAO,MAAM,OAAO,IAAI,CAAC,KAAK;EAoB5B,MAAM;EACN,QAAQ;EACR,OAAO;EACP,QAAQ,MAAM;EACf,CAA4B;AAG/B,KAAI,iBAAiB,wBAAwB;AAC3C,UAAQ,IAAI,KAAK,MAAM,QAAQ;AAC/B,SAAO,MAAM,OAAO,IAAI,CAAC,KAAK;GAC5B,MAAM;GACN,QAAQ;GACR,OAAO;GACP,QAAQ,MAAM;GACf,CAA4B;;AAE/B,SAAQ,IAAI,MAAM,MAAM;AACxB,KAAI,iBAAiB,SACnB,QAAO,MAAM,OAAO,IAAI,CAAC,KAAK;EAC5B,MAAM;EACN,QAAQ;EACR,OAAO;EACP,QAAQ,MAAM;EACf,CAA4B;AAG/B,QAAO,MAAM,OAAO,IAAI,CAAC,KAAK;EAC5B,MAAM;EACN,QAAQ;EACR,OAAO;EACR,CAA4B;;AAG/B,SAAS,eAAe,OAAuC;AAC7D,QACE,iBAAiB,SACjB,UAAU,SACV,OAAQ,MAAuB,SAAS;;AAI5C,SAAS,cAAc,OAAuC;AAC5D,QACE,eAAe,MAAM,IACrB,OAAO,MAAM,eAAe,YAC5B,MAAM,cAAc,OACpB,MAAM,aAAa;;;;AC7EvB,MAAa,uBAAuBA,IAAE,OAAO;CAC3C,MAAMA,IACH,KAAK,CACL,QAAQ,cAAc,CACtB,SAAS,6CAA6C;CACzD,QAAQA,IACL,QAAQ,CACR,KAAK,CACL,IAAI,IAAI,CACR,IAAI,IAAI,CACR,UAAU,CACV,SAAS,kDAAkD;CAC9D,OAAOA,IACJ,QAAQ,CACR,UAAU,CACV,SAAS,mDAAmD;CAC/D,QAAQA,IACL,QAAQ,CACR,UAAU,CACV,SAAS,yDAAyD;CACrE,UAAUA,IACP,QAAQ,CACR,UAAU,CACV,SAAS,qDAAqD;CAClE,CAAC;;;ACjBF,MAAa,eAGR,eAAgB,SAAS,MAAM;AAClC,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,QAAQ,EAAE,OAAO,EACf,SAAS,EAAE,QAAQ,CAAC,SAAS,yBAAyB,EACvD,CAAC;GACF,UAAU;IACR,KAAK,EAAE,MAAM,oBAAoB,iBAAiB;IAClD,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,qBAAqB,UAAU;IACvD,SAAS,IAAI,OAAO;IACpB,gBAAgB,IAAI;IACrB,CAAC;AACF,OAAI,KAAK,OAAO,KAAK;;EAExB,CAAC;CAEF,MAAM,uBAAuB,EAAE,OAAO;EACpC,MAAM,EAAE,MAAM,oBAAoB,iBAAiB;EACnD,YAAY,EAAE,QAAQ,CAAC,UAAU;EAClC,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,MAAM,kBAAkB;GACxB,UAAU;IACR,KAAK;IACL,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,qBAAqB,UAAU;IACvD,GAAG,IAAI;IACP,gBAAgB,IAAI;IACrB,CAAC;AACF,OAAI,KAAK,OAAO;;EAEnB,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,UAAU;IACR,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;IAChD,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,qBAAqB,YAAY,EACzD,gBAAgB,IAAI,gBACrB,CAAC;AACF,OAAI,KAAK,OAAO;;EAEnB,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;GAClD,UAAU;IACR,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;IAClD,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,qBAAqB,cAAc;IAC3D,aAAa,IAAI,MAAM;IACvB,gBAAgB,IAAI;IACrB,CAAC;AACF,OAAI,KAAK,OAAO;;EAEnB,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,MAAM,kBAAkB;GACxB,UAAU;IACR,KAAK,EAAE,OAAO;KACZ,MAAM,EAAE,MAAM,kBAAkB,sBAAsB;KACtD,YAAY,EAAE,QAAQ,CAAC,UAAU;KAClC,CAAC;IACF,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,qBAAqB,kBAAkB;IAC/D,GAAG,IAAI;IACP,gBAAgB,IAAI;IACrB,CAAC;AACF,OAAI,KAAK,OAAO;;EAEnB,CAAC;;;;ACnHJ,MAAa,aAER,eAAgB,SAAS,MAAM;CAClC,MAAM,uBAAuB,EAAE,OAAO;EACpC,MAAM,EAAE,MAAM,oBAAoB,eAAe;EACjD,YAAY,EAAE,QAAQ,CAAC,UAAU;EAClC,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,MAAM,kBAAkB;GACxB,UAAU;IACR,KAAK;IACL,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,mBAAmB,QAAQ;IACnD,GAAG,IAAI;IACP,gBAAgB,IAAI;IACrB,CAAC;AACF,OAAI,KAAK,OAAO;;EAEnB,CAAC;;;;AC3BJ,MAAa,gBAER,eAAgB,SAAS,MAAM;CAClC,MAAM,uBAAuB,EAAE,OAAO;EACpC,MAAM,EAAE,MAAM,oBAAoB,kBAAkB;EACpD,YAAY,EAAE,QAAQ,CAAC,UAAU;EAClC,CAAC;CAEF,MAAM,2BAA2B,EAAE,OAAO;EACxC,MAAM,EAAE,MAAM,oBAAoB,uBAAuB;EACzD,YAAY,EAAE,MAAM;EACrB,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,MAAM,kBAAkB;GACxB,UAAU;IACR,KAAK,EAAE,MAAM,CAAC,sBAAsB,yBAAyB,CAAC;IAC9D,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS;IAAE,GAAG,IAAI;IAAM,gBAAgB,IAAI;IAAgB;GAClE,MAAM,SAAS,IAAI,KAAK,YACpB,MAAM,KAAK,sBAAsB,qBAAqB,OAAO,GAC7D,MAAM,KAAK,sBAAsB,WAAW,OAAO;AACvD,OAAI,KAAK,OAAO;;EAEnB,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,UAAU;IACR,KAAK;IACL,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,sBAAsB,gBAAgB,EAC9D,gBAAgB,IAAI,gBACrB,CAAC;AACF,OAAI,KAAK,OAAO;;EAEnB,CAAC;;AAGJ,MAAM,mBAAmB,EAAE,KAAK;CAC9B;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,6BAA6B,EAAE,OAAO;CAC1C,QAAQ,EACL,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CACvC,SAAS,qDAAqD;CACjE,YAAY,EACT,SAAS,CACT,UAAU,CACV,SAAS,iDAAiD;CAC9D,CAAC;AAEF,MAAM,yBAAyB,EAAE,OAAO;CACtC,MAAM,EAAE,QAAQ,CAAC,SAAS,qCAAqC;CAC/D,MAAM,iBAAiB,SACrB,wEACD;CACD,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,qCAAqC;CAC1E,aAAa,EACV,QAAQ,CACR,UAAU,CACV,SAAS,mDAAmD;CAC/D,YAAY,2BAA2B,SACrC,2DACD;CACD,oBAAoB,2BAA2B,SAC7C,yDACD;CACF,CAAC;AAEF,MAAM,iCAAiC,EAAE,OAAO,EAC9C,SAAS,EAAE,MAAM,uBAAuB,EACzC,CAAC;;;AC/FF,MAAaC,qBAGR,eAAgB,SAAS,MAAM;AAClC,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aACE;GACF,UAAU,CAAC,gBAAgB;GAC3B,UAAU;IACR,KAAK,EAAE,QAAQ,CAAC,SAAS,+BAA+B;IACxD,KAAK,EAAE,QAAQ,CAAC,SAAS,qCAAqC;IAC/D;GACF;EACD,SAAS,OAAO,MAAM,UAAU;AAC9B,OAAI,CAAC,KAAK,mBACR,QAAO,MAAM,OAAO,IAAI,CAAC,KAAK,kCAAkC;AAElE,SAAM,KAAK,gBAAgB,CAAC,KAAK,KAAK,mBAAmB;;EAE5D,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,MAAM,oBAAoB;GAC1B,UAAU;IACR,KAAK,oBAAoB;IACzB,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,2BAA2B,gBAAgB;IACnE,GAAG,IAAI;IACP,gBAAgB,IAAI;IACrB,CAAC;AACF,OAAI,OAAO,IAAI,CAAC,KAAK,OAAO;;EAE/B,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,QAAQ,EAAE,OAAO,EACf,aAAa,EAAE,QAAQ,EACxB,CAAC;GACF,UAAU;IACR,KAAK,oBAAoB;IACzB,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;AAC3B,OAAI;IACF,MAAM,SAAS,MAAM,KAAK,2BAA2B,aAAa;KAChE,IAAI,IAAI,OAAO;KACf,gBAAgB,IAAI;KACrB,CAAC;AACF,QAAI,KAAK,OAAO;YACT,OAAO;AAEd,SADY,iBAAiB,QAAQ,MAAM,QAAQ,aAAa,GAAG,IAC3D,SAAS,YAAY,CAC3B,OAAM,IAAI,uBACR,wBAAwB,IAAI,OAAO,eACnC,EAAE,OAAO,OAAO,CACjB;AAEH,UAAM;;;EAGX,CAAC;CAEF,MAAM,uBAAuB,EAAE,OAAO;EACpC,MAAM,EAAE,MAAM,oBAAoB,gBAAgB;EAClD,YAAY,EAAE,QAAQ,CAAC,UAAU;EAClC,CAAC;AAEF,SAAQ,MAAM;EACZ,QAAQ;EACR,KAAK;EACL,QAAQ;GACN,aAAa;GACb,MAAM,oBAAoB;GAC1B,UAAU;IACR,KAAK;IACL,OAAO;IACP,OAAO;IACR;GACF;EACD,SAAS,OAAO,KAAK,QAAQ;GAC3B,MAAM,SAAS,MAAM,KAAK,2BAA2B,iBAAiB;IACpE,GAAG,IAAI;IACP,gBAAgB,IAAI;IACrB,CAAC;AACF,OAAI,KAAK,OAAO;;EAEnB,CAAC;;;;AChGJ,MAAa,gBAER,eAAgB,SAAS,MAAM;AAClC,SAAQ,qBAAqB,kBAAkB;AAC/C,SAAQ,sBAAsB,mBAAmB;AACjD,SAAQ,gBAAgB,aAAa;AAErC,SAAQ,SAAS,cAAc,EAC7B,sBAAsB,KAAK,yBAC5B,CAAC;AAEF,SAAQ,SAAS,YAAY,EAC3B,oBAAoB,KAAK,yBAC1B,CAAC;AAEF,SAAQ,SAAS,eAAe,EAC9B,uBAAuB,KAAK,yBAC7B,CAAC;;AAGJ,MAAa,mBAGR,eAAgB,SAAS,MAAM;AAClC,SAAQ,qBAAqB,kBAAkB;AAC/C,SAAQ,sBAAsB,mBAAmB;AACjD,SAAQ,gBAAgB,aAAa;AAErC,SAAQ,SAASC,oBAAmB;EAClC,4BAA4B,KAAK;EACjC,oBAAoB,KAAK;EAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kopai/api",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Vladimir Adamic",
6
6
  "repository": {
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "fastify-type-provider-zod": "^6.1.0",
35
- "@kopai/core": "0.8.0"
35
+ "@kopai/core": "0.9.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@fastify/swagger": "^9.7.0",