@almadar/server 2.0.9 → 2.1.1

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.
Files changed (105) hide show
  1. package/package.json +10 -4
  2. package/dist/contracts.d.ts +0 -174
  3. package/dist/contracts.d.ts.map +0 -1
  4. package/dist/deepagent/__tests__/memory.test.d.ts +0 -6
  5. package/dist/deepagent/__tests__/memory.test.d.ts.map +0 -1
  6. package/dist/deepagent/__tests__/session.test.d.ts +0 -6
  7. package/dist/deepagent/__tests__/session.test.d.ts.map +0 -1
  8. package/dist/deepagent/__tests__/skill-agent.test.d.ts +0 -6
  9. package/dist/deepagent/__tests__/skill-agent.test.d.ts.map +0 -1
  10. package/dist/deepagent/memory.d.ts +0 -17
  11. package/dist/deepagent/memory.d.ts.map +0 -1
  12. package/dist/deepagent/memory.js +0 -48
  13. package/dist/deepagent/memory.js.map +0 -1
  14. package/dist/deepagent/session.d.ts +0 -17
  15. package/dist/deepagent/session.d.ts.map +0 -1
  16. package/dist/deepagent/session.js +0 -68
  17. package/dist/deepagent/session.js.map +0 -1
  18. package/dist/deepagent/skill-agent.d.ts +0 -22
  19. package/dist/deepagent/skill-agent.d.ts.map +0 -1
  20. package/dist/deepagent/skill-agent.js +0 -114
  21. package/dist/deepagent/skill-agent.js.map +0 -1
  22. package/dist/index.d.ts +0 -42
  23. package/dist/index.d.ts.map +0 -1
  24. package/dist/index.js +0 -2460
  25. package/dist/index.js.map +0 -1
  26. package/dist/lib/db.d.ts +0 -36
  27. package/dist/lib/db.d.ts.map +0 -1
  28. package/dist/lib/debugRouter.d.ts +0 -21
  29. package/dist/lib/debugRouter.d.ts.map +0 -1
  30. package/dist/lib/env.d.ts +0 -16
  31. package/dist/lib/env.d.ts.map +0 -1
  32. package/dist/lib/eventBus.d.ts +0 -44
  33. package/dist/lib/eventBus.d.ts.map +0 -1
  34. package/dist/lib/eventBusTransport.d.ts +0 -143
  35. package/dist/lib/eventBusTransport.d.ts.map +0 -1
  36. package/dist/lib/eventPersistence.d.ts +0 -151
  37. package/dist/lib/eventPersistence.d.ts.map +0 -1
  38. package/dist/lib/index.d.ts +0 -6
  39. package/dist/lib/index.d.ts.map +0 -1
  40. package/dist/lib/index.js +0 -288
  41. package/dist/lib/index.js.map +0 -1
  42. package/dist/lib/logger.d.ts +0 -7
  43. package/dist/lib/logger.d.ts.map +0 -1
  44. package/dist/lib/serviceDiscovery.d.ts +0 -168
  45. package/dist/lib/serviceDiscovery.d.ts.map +0 -1
  46. package/dist/lib/websocket.d.ts +0 -41
  47. package/dist/lib/websocket.d.ts.map +0 -1
  48. package/dist/middleware/__tests__/multi-user.test.d.ts +0 -6
  49. package/dist/middleware/__tests__/multi-user.test.d.ts.map +0 -1
  50. package/dist/middleware/authenticateFirebase.d.ts +0 -4
  51. package/dist/middleware/authenticateFirebase.d.ts.map +0 -1
  52. package/dist/middleware/errorHandler.d.ts +0 -53
  53. package/dist/middleware/errorHandler.d.ts.map +0 -1
  54. package/dist/middleware/index.d.ts +0 -4
  55. package/dist/middleware/index.d.ts.map +0 -1
  56. package/dist/middleware/index.js +0 -284
  57. package/dist/middleware/index.js.map +0 -1
  58. package/dist/middleware/multi-user.d.ts +0 -34
  59. package/dist/middleware/multi-user.d.ts.map +0 -1
  60. package/dist/middleware/multi-user.js +0 -76
  61. package/dist/middleware/multi-user.js.map +0 -1
  62. package/dist/middleware/validation.d.ts +0 -15
  63. package/dist/middleware/validation.d.ts.map +0 -1
  64. package/dist/routes/__tests__/observability.test.d.ts +0 -6
  65. package/dist/routes/__tests__/observability.test.d.ts.map +0 -1
  66. package/dist/routes/observability.d.ts +0 -11
  67. package/dist/routes/observability.d.ts.map +0 -1
  68. package/dist/routes/observability.js +0 -62
  69. package/dist/routes/observability.js.map +0 -1
  70. package/dist/services/DataService.d.ts +0 -70
  71. package/dist/services/DataService.d.ts.map +0 -1
  72. package/dist/services/MockDataService.d.ts +0 -110
  73. package/dist/services/MockDataService.d.ts.map +0 -1
  74. package/dist/services/index.d.ts +0 -8
  75. package/dist/services/index.d.ts.map +0 -1
  76. package/dist/services/index.js +0 -735
  77. package/dist/services/index.js.map +0 -1
  78. package/dist/stores/ChangeSetStore.d.ts +0 -24
  79. package/dist/stores/ChangeSetStore.d.ts.map +0 -1
  80. package/dist/stores/SchemaProtectionService.d.ts +0 -23
  81. package/dist/stores/SchemaProtectionService.d.ts.map +0 -1
  82. package/dist/stores/SchemaStore.d.ts +0 -52
  83. package/dist/stores/SchemaStore.d.ts.map +0 -1
  84. package/dist/stores/SnapshotStore.d.ts +0 -26
  85. package/dist/stores/SnapshotStore.d.ts.map +0 -1
  86. package/dist/stores/ValidationStore.d.ts +0 -19
  87. package/dist/stores/ValidationStore.d.ts.map +0 -1
  88. package/dist/stores/firestoreFormat.d.ts +0 -21
  89. package/dist/stores/firestoreFormat.d.ts.map +0 -1
  90. package/dist/stores/index.d.ts +0 -14
  91. package/dist/stores/index.d.ts.map +0 -1
  92. package/dist/stores/index.js +0 -519
  93. package/dist/stores/index.js.map +0 -1
  94. package/dist/utils/index.d.ts +0 -9
  95. package/dist/utils/index.d.ts.map +0 -1
  96. package/dist/utils/index.js +0 -106
  97. package/dist/utils/index.js.map +0 -1
  98. package/dist/utils/queryFilters.d.ts +0 -87
  99. package/dist/utils/queryFilters.d.ts.map +0 -1
  100. package/dist/websocket/__tests__/state-sync.test.d.ts +0 -6
  101. package/dist/websocket/__tests__/state-sync.test.d.ts.map +0 -1
  102. package/dist/websocket/state-sync.d.ts +0 -39
  103. package/dist/websocket/state-sync.d.ts.map +0 -1
  104. package/dist/websocket/state-sync.js +0 -77
  105. package/dist/websocket/state-sync.js.map +0 -1
@@ -1,284 +0,0 @@
1
- import { z, ZodError } from 'zod';
2
- import dotenv from 'dotenv';
3
- import admin from 'firebase-admin';
4
-
5
- // src/middleware/errorHandler.ts
6
- dotenv.config();
7
- var envSchema = z.object({
8
- NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
9
- PORT: z.string().default("3030").transform((val) => parseInt(val, 10)),
10
- CORS_ORIGIN: z.string().default("http://localhost:5173").transform((val) => val.includes(",") ? val.split(",").map((s) => s.trim()) : val),
11
- // Database (Prisma/SQL) - optional
12
- DATABASE_URL: z.string().optional(),
13
- // Firebase/Firestore configuration
14
- FIREBASE_PROJECT_ID: z.string().optional(),
15
- FIREBASE_CLIENT_EMAIL: z.string().optional(),
16
- FIREBASE_PRIVATE_KEY: z.string().optional(),
17
- FIREBASE_SERVICE_ACCOUNT_PATH: z.string().optional(),
18
- FIRESTORE_EMULATOR_HOST: z.string().optional(),
19
- FIREBASE_AUTH_EMULATOR_HOST: z.string().optional(),
20
- // API configuration
21
- API_PREFIX: z.string().default("/api"),
22
- // Mock data configuration
23
- USE_MOCK_DATA: z.string().default("true").transform((v) => v === "true"),
24
- MOCK_SEED: z.string().optional().transform((v) => v ? parseInt(v, 10) : void 0)
25
- });
26
- var parsed = envSchema.safeParse(process.env);
27
- if (!parsed.success) {
28
- console.error("\u274C Invalid environment variables:", parsed.error.flatten().fieldErrors);
29
- throw new Error("Invalid environment variables");
30
- }
31
- var env = parsed.data;
32
-
33
- // src/lib/logger.ts
34
- var colors = {
35
- debug: "\x1B[36m",
36
- // Cyan
37
- info: "\x1B[32m",
38
- // Green
39
- warn: "\x1B[33m",
40
- // Yellow
41
- error: "\x1B[31m",
42
- // Red
43
- reset: "\x1B[0m"
44
- };
45
- var shouldLog = (level) => {
46
- const levels = ["debug", "info", "warn", "error"];
47
- const minLevel = env.NODE_ENV === "production" ? "info" : "debug";
48
- return levels.indexOf(level) >= levels.indexOf(minLevel);
49
- };
50
- var formatMessage = (level, message, meta) => {
51
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
52
- const color = colors[level];
53
- const prefix = `${color}[${level.toUpperCase()}]${colors.reset}`;
54
- const metaStr = meta ? ` ${JSON.stringify(meta)}` : "";
55
- return `${timestamp} ${prefix} ${message}${metaStr}`;
56
- };
57
- var logger = {
58
- debug: (message, meta) => {
59
- if (shouldLog("debug")) {
60
- console.log(formatMessage("debug", message, meta));
61
- }
62
- },
63
- info: (message, meta) => {
64
- if (shouldLog("info")) {
65
- console.log(formatMessage("info", message, meta));
66
- }
67
- },
68
- warn: (message, meta) => {
69
- if (shouldLog("warn")) {
70
- console.warn(formatMessage("warn", message, meta));
71
- }
72
- },
73
- error: (message, meta) => {
74
- if (shouldLog("error")) {
75
- console.error(formatMessage("error", message, meta));
76
- }
77
- }
78
- };
79
-
80
- // src/middleware/errorHandler.ts
81
- var AppError = class extends Error {
82
- constructor(statusCode, message, code) {
83
- super(message);
84
- this.statusCode = statusCode;
85
- this.message = message;
86
- this.code = code;
87
- this.name = "AppError";
88
- }
89
- };
90
- var NotFoundError = class extends AppError {
91
- constructor(message = "Resource not found") {
92
- super(404, message, "NOT_FOUND");
93
- }
94
- };
95
- var ValidationError = class extends AppError {
96
- constructor(message = "Validation failed") {
97
- super(400, message, "VALIDATION_ERROR");
98
- }
99
- };
100
- var UnauthorizedError = class extends AppError {
101
- constructor(message = "Unauthorized") {
102
- super(401, message, "UNAUTHORIZED");
103
- }
104
- };
105
- var ForbiddenError = class extends AppError {
106
- constructor(message = "Forbidden") {
107
- super(403, message, "FORBIDDEN");
108
- }
109
- };
110
- var ConflictError = class extends AppError {
111
- constructor(message = "Resource conflict") {
112
- super(409, message, "CONFLICT");
113
- }
114
- };
115
- var errorHandler = (err, _req, res, _next) => {
116
- logger.error("Error:", { name: err.name, message: err.message, stack: err.stack });
117
- if (err instanceof ZodError) {
118
- res.status(400).json({
119
- success: false,
120
- error: "Validation failed",
121
- code: "VALIDATION_ERROR",
122
- details: err.errors.map((e) => ({
123
- path: e.path.join("."),
124
- message: e.message
125
- }))
126
- });
127
- return;
128
- }
129
- if (err instanceof AppError) {
130
- res.status(err.statusCode).json({
131
- success: false,
132
- error: err.message,
133
- code: err.code
134
- });
135
- return;
136
- }
137
- if (err.name === "FirebaseError" || err.name === "FirestoreError") {
138
- res.status(500).json({
139
- success: false,
140
- error: "Database error",
141
- code: "DATABASE_ERROR"
142
- });
143
- return;
144
- }
145
- res.status(500).json({
146
- success: false,
147
- error: "Internal server error",
148
- code: "INTERNAL_ERROR"
149
- });
150
- };
151
- var asyncHandler = (fn) => (req, res, next) => {
152
- Promise.resolve(fn(req, res, next)).catch(next);
153
- };
154
- var notFoundHandler = (req, res) => {
155
- res.status(404).json({
156
- success: false,
157
- error: `Route ${req.method} ${req.path} not found`,
158
- code: "ROUTE_NOT_FOUND"
159
- });
160
- };
161
- var validateBody = (schema) => async (req, res, next) => {
162
- try {
163
- req.body = await schema.parseAsync(req.body);
164
- next();
165
- } catch (error) {
166
- if (error instanceof ZodError) {
167
- res.status(400).json({
168
- success: false,
169
- error: "Validation failed",
170
- code: "VALIDATION_ERROR",
171
- details: error.errors.map((e) => ({
172
- path: e.path.join("."),
173
- message: e.message
174
- }))
175
- });
176
- return;
177
- }
178
- next(error);
179
- }
180
- };
181
- var validateQuery = (schema) => async (req, res, next) => {
182
- try {
183
- req.query = await schema.parseAsync(req.query);
184
- next();
185
- } catch (error) {
186
- if (error instanceof ZodError) {
187
- res.status(400).json({
188
- success: false,
189
- error: "Invalid query parameters",
190
- code: "VALIDATION_ERROR",
191
- details: error.errors.map((e) => ({
192
- path: e.path.join("."),
193
- message: e.message
194
- }))
195
- });
196
- return;
197
- }
198
- next(error);
199
- }
200
- };
201
- var validateParams = (schema) => async (req, res, next) => {
202
- try {
203
- req.params = await schema.parseAsync(req.params);
204
- next();
205
- } catch (error) {
206
- if (error instanceof ZodError) {
207
- res.status(400).json({
208
- success: false,
209
- error: "Invalid path parameters",
210
- code: "VALIDATION_ERROR",
211
- details: error.errors.map((e) => ({
212
- path: e.path.join("."),
213
- message: e.message
214
- }))
215
- });
216
- return;
217
- }
218
- next(error);
219
- }
220
- };
221
- function getApp() {
222
- if (admin.apps.length === 0) {
223
- throw new Error(
224
- "@almadar/server: Firebase Admin SDK is not initialized. Call initializeFirebase() or admin.initializeApp() before using @almadar/server."
225
- );
226
- }
227
- return admin.app();
228
- }
229
- function getFirestore() {
230
- return getApp().firestore();
231
- }
232
- function getAuth() {
233
- return getApp().auth();
234
- }
235
- new Proxy({}, {
236
- get(_target, prop, receiver) {
237
- const firestore = getFirestore();
238
- const value = Reflect.get(firestore, prop, receiver);
239
- return typeof value === "function" ? value.bind(firestore) : value;
240
- }
241
- });
242
-
243
- // src/middleware/authenticateFirebase.ts
244
- var BEARER_PREFIX = "Bearer ";
245
- var DEV_USER = {
246
- uid: "dev-user-001",
247
- email: "dev@localhost",
248
- email_verified: true,
249
- aud: "dev-project",
250
- auth_time: Math.floor(Date.now() / 1e3),
251
- exp: Math.floor(Date.now() / 1e3) + 3600,
252
- iat: Math.floor(Date.now() / 1e3),
253
- iss: "https://securetoken.google.com/dev-project",
254
- sub: "dev-user-001",
255
- firebase: {
256
- identities: {},
257
- sign_in_provider: "custom"
258
- }
259
- };
260
- async function authenticateFirebase(req, res, next) {
261
- const authorization = req.headers.authorization;
262
- if (env.NODE_ENV === "development" && (!authorization || !authorization.startsWith(BEARER_PREFIX))) {
263
- req.firebaseUser = DEV_USER;
264
- res.locals.firebaseUser = DEV_USER;
265
- return next();
266
- }
267
- try {
268
- if (!authorization || !authorization.startsWith(BEARER_PREFIX)) {
269
- return res.status(401).json({ error: "Authorization header missing or malformed" });
270
- }
271
- const token = authorization.slice(BEARER_PREFIX.length);
272
- const decodedToken = await getAuth().verifyIdToken(token);
273
- req.firebaseUser = decodedToken;
274
- res.locals.firebaseUser = decodedToken;
275
- return next();
276
- } catch (error) {
277
- console.error("Firebase authentication failed:", error);
278
- return res.status(401).json({ error: "Unauthorized" });
279
- }
280
- }
281
-
282
- export { AppError, ConflictError, ForbiddenError, NotFoundError, UnauthorizedError, ValidationError, asyncHandler, authenticateFirebase, errorHandler, notFoundHandler, validateBody, validateParams, validateQuery };
283
- //# sourceMappingURL=index.js.map
284
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/lib/env.ts","../../src/lib/logger.ts","../../src/middleware/errorHandler.ts","../../src/middleware/validation.ts","../../src/lib/db.ts","../../src/middleware/authenticateFirebase.ts"],"names":["ZodError"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\nimport dotenv from 'dotenv';\n\n// Load environment variables\ndotenv.config();\n\nconst envSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z\n .string()\n .default('3030')\n .transform((val) => parseInt(val, 10)),\n CORS_ORIGIN: z\n .string()\n .default('http://localhost:5173')\n .transform((val) => (val.includes(',') ? val.split(',').map((s) => s.trim()) : val)),\n \n // Database (Prisma/SQL) - optional\n DATABASE_URL: z.string().optional(),\n \n // Firebase/Firestore configuration\n FIREBASE_PROJECT_ID: z.string().optional(),\n FIREBASE_CLIENT_EMAIL: z.string().optional(),\n FIREBASE_PRIVATE_KEY: z.string().optional(),\n FIREBASE_SERVICE_ACCOUNT_PATH: z.string().optional(),\n FIRESTORE_EMULATOR_HOST: z.string().optional(),\n FIREBASE_AUTH_EMULATOR_HOST: z.string().optional(),\n \n // API configuration\n API_PREFIX: z.string().default('/api'),\n\n // Mock data configuration\n USE_MOCK_DATA: z.string().default('true').transform((v) => v === 'true'),\n MOCK_SEED: z\n .string()\n .optional()\n .transform((v) => (v ? parseInt(v, 10) : undefined)),\n});\n\nconst parsed = envSchema.safeParse(process.env);\n\nif (!parsed.success) {\n console.error('❌ Invalid environment variables:', parsed.error.flatten().fieldErrors);\n throw new Error('Invalid environment variables');\n}\n\nexport const env = parsed.data;\n","import { env } from './env.js';\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst colors = {\n debug: '\\x1b[36m', // Cyan\n info: '\\x1b[32m', // Green\n warn: '\\x1b[33m', // Yellow\n error: '\\x1b[31m', // Red\n reset: '\\x1b[0m',\n};\n\nconst shouldLog = (level: LogLevel): boolean => {\n const levels: LogLevel[] = ['debug', 'info', 'warn', 'error'];\n const minLevel = env.NODE_ENV === 'production' ? 'info' : 'debug';\n return levels.indexOf(level) >= levels.indexOf(minLevel);\n};\n\nconst formatMessage = (level: LogLevel, message: string, meta?: unknown): string => {\n const timestamp = new Date().toISOString();\n const color = colors[level];\n const prefix = `${color}[${level.toUpperCase()}]${colors.reset}`;\n const metaStr = meta ? ` ${JSON.stringify(meta)}` : '';\n return `${timestamp} ${prefix} ${message}${metaStr}`;\n};\n\nexport const logger = {\n debug: (message: string, meta?: unknown) => {\n if (shouldLog('debug')) {\n console.log(formatMessage('debug', message, meta));\n }\n },\n info: (message: string, meta?: unknown) => {\n if (shouldLog('info')) {\n console.log(formatMessage('info', message, meta));\n }\n },\n warn: (message: string, meta?: unknown) => {\n if (shouldLog('warn')) {\n console.warn(formatMessage('warn', message, meta));\n }\n },\n error: (message: string, meta?: unknown) => {\n if (shouldLog('error')) {\n console.error(formatMessage('error', message, meta));\n }\n },\n};\n","import { Request, Response, NextFunction } from 'express';\nimport { ZodError } from 'zod';\nimport { logger } from '../lib/logger.js';\n\n/**\n * Base application error class\n */\nexport class AppError extends Error {\n constructor(\n public statusCode: number,\n public message: string,\n public code?: string\n ) {\n super(message);\n this.name = 'AppError';\n }\n}\n\n/**\n * 404 Not Found error\n */\nexport class NotFoundError extends AppError {\n constructor(message: string = 'Resource not found') {\n super(404, message, 'NOT_FOUND');\n }\n}\n\n/**\n * 400 Bad Request / Validation error\n */\nexport class ValidationError extends AppError {\n constructor(message: string = 'Validation failed') {\n super(400, message, 'VALIDATION_ERROR');\n }\n}\n\n/**\n * 401 Unauthorized error\n */\nexport class UnauthorizedError extends AppError {\n constructor(message: string = 'Unauthorized') {\n super(401, message, 'UNAUTHORIZED');\n }\n}\n\n/**\n * 403 Forbidden error\n */\nexport class ForbiddenError extends AppError {\n constructor(message: string = 'Forbidden') {\n super(403, message, 'FORBIDDEN');\n }\n}\n\n/**\n * 409 Conflict error\n */\nexport class ConflictError extends AppError {\n constructor(message: string = 'Resource conflict') {\n super(409, message, 'CONFLICT');\n }\n}\n\n/**\n * Global error handler middleware\n */\nexport const errorHandler = (\n err: Error,\n _req: Request,\n res: Response,\n _next: NextFunction\n): void => {\n logger.error('Error:', { name: err.name, message: err.message, stack: err.stack });\n\n // Zod validation errors\n if (err instanceof ZodError) {\n res.status(400).json({\n success: false,\n error: 'Validation failed',\n code: 'VALIDATION_ERROR',\n details: err.errors.map((e) => ({\n path: e.path.join('.'),\n message: e.message,\n })),\n });\n return;\n }\n\n // Custom application errors\n if (err instanceof AppError) {\n res.status(err.statusCode).json({\n success: false,\n error: err.message,\n code: err.code,\n });\n return;\n }\n\n // Firebase/Firestore errors\n if (err.name === 'FirebaseError' || err.name === 'FirestoreError') {\n res.status(500).json({\n success: false,\n error: 'Database error',\n code: 'DATABASE_ERROR',\n });\n return;\n }\n\n // Unknown errors\n res.status(500).json({\n success: false,\n error: 'Internal server error',\n code: 'INTERNAL_ERROR',\n });\n};\n\n/**\n * Async handler wrapper to catch errors in async route handlers\n */\nexport const asyncHandler =\n (fn: (req: Request, res: Response, next: NextFunction) => Promise<unknown>) =>\n (req: Request, res: Response, next: NextFunction) => {\n Promise.resolve(fn(req, res, next)).catch(next);\n };\n\n/**\n * 404 handler for unmatched routes\n */\nexport const notFoundHandler = (req: Request, res: Response): void => {\n res.status(404).json({\n success: false,\n error: `Route ${req.method} ${req.path} not found`,\n code: 'ROUTE_NOT_FOUND',\n });\n};\n","import { Request, Response, NextFunction } from 'express';\nimport { AnyZodObject, ZodError } from 'zod';\n\n/**\n * Middleware to validate request body against a Zod schema\n */\nexport const validateBody =\n (schema: AnyZodObject) => async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n req.body = await schema.parseAsync(req.body);\n next();\n } catch (error) {\n if (error instanceof ZodError) {\n res.status(400).json({\n success: false,\n error: 'Validation failed',\n code: 'VALIDATION_ERROR',\n details: error.errors.map((e) => ({\n path: e.path.join('.'),\n message: e.message,\n })),\n });\n return;\n }\n next(error);\n }\n };\n\n/**\n * Middleware to validate request query parameters against a Zod schema\n */\nexport const validateQuery =\n (schema: AnyZodObject) => async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n req.query = await schema.parseAsync(req.query);\n next();\n } catch (error) {\n if (error instanceof ZodError) {\n res.status(400).json({\n success: false,\n error: 'Invalid query parameters',\n code: 'VALIDATION_ERROR',\n details: error.errors.map((e) => ({\n path: e.path.join('.'),\n message: e.message,\n })),\n });\n return;\n }\n next(error);\n }\n };\n\n/**\n * Middleware to validate request params against a Zod schema\n */\nexport const validateParams =\n (schema: AnyZodObject) => async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n req.params = await schema.parseAsync(req.params);\n next();\n } catch (error) {\n if (error instanceof ZodError) {\n res.status(400).json({\n success: false,\n error: 'Invalid path parameters',\n code: 'VALIDATION_ERROR',\n details: error.errors.map((e) => ({\n path: e.path.join('.'),\n message: e.message,\n })),\n });\n return;\n }\n next(error);\n }\n };\n","/**\n * Database Accessors & Initialization\n *\n * This module provides:\n * - `initializeFirebase()` — convenience function to init Firebase from env vars\n * - `getFirestore()`, `getAuth()` — accessors for Firebase services\n * - `db` — lazy Firestore proxy (no eager initialization)\n *\n * The consuming application MUST call `initializeFirebase()` or\n * `admin.initializeApp()` before using any Firebase-dependent features.\n */\n\nimport admin from 'firebase-admin';\n\n/**\n * Initialize Firebase Admin SDK from environment variables.\n *\n * Reads: FIREBASE_PROJECT_ID, FIREBASE_CLIENT_EMAIL, FIREBASE_PRIVATE_KEY,\n * FIREBASE_SERVICE_ACCOUNT_PATH, FIRESTORE_EMULATOR_HOST\n *\n * Safe to call multiple times — returns existing app if already initialized.\n */\nexport function initializeFirebase(): admin.app.App {\n // Already initialized — return existing app\n if (admin.apps.length > 0) {\n return admin.app();\n }\n\n const projectId = process.env.FIREBASE_PROJECT_ID;\n const emulatorHost = process.env.FIRESTORE_EMULATOR_HOST;\n\n // Emulator mode — no credentials needed\n if (emulatorHost) {\n const app = admin.initializeApp({\n projectId: projectId || 'demo-project',\n });\n console.log(`Firebase Admin initialized for emulator: ${emulatorHost}`);\n return app;\n }\n\n // Service account file\n const serviceAccountPath = process.env.FIREBASE_SERVICE_ACCOUNT_PATH;\n if (serviceAccountPath) {\n // Dynamic require for JSON service account file at runtime\n const serviceAccount = require(serviceAccountPath) as Record<string, unknown>;\n return admin.initializeApp({\n credential: admin.credential.cert(serviceAccount),\n projectId,\n });\n }\n\n // Inline credentials\n const clientEmail = process.env.FIREBASE_CLIENT_EMAIL;\n const privateKey = process.env.FIREBASE_PRIVATE_KEY;\n if (projectId && clientEmail && privateKey) {\n return admin.initializeApp({\n credential: admin.credential.cert({\n projectId,\n clientEmail,\n privateKey: privateKey.replace(/\\\\n/g, '\\n'),\n }),\n projectId,\n });\n }\n\n // Application default credentials (Cloud Run, etc.)\n if (projectId) {\n return admin.initializeApp({\n credential: admin.credential.applicationDefault(),\n projectId,\n });\n }\n\n throw new Error(\n '@almadar/server: Cannot initialize Firebase — no credentials found. ' +\n 'Set FIREBASE_PROJECT_ID + FIREBASE_CLIENT_EMAIL + FIREBASE_PRIVATE_KEY, ' +\n 'or FIREBASE_SERVICE_ACCOUNT_PATH, or FIRESTORE_EMULATOR_HOST.'\n );\n}\n\n/**\n * Get the initialized Firebase app.\n * Throws if Firebase Admin SDK has not been initialized.\n */\nfunction getApp(): admin.app.App {\n if (admin.apps.length === 0) {\n throw new Error(\n '@almadar/server: Firebase Admin SDK is not initialized. ' +\n 'Call initializeFirebase() or admin.initializeApp() before using @almadar/server.'\n );\n }\n return admin.app();\n}\n\n/**\n * Get Firestore instance from the pre-initialized Firebase app.\n */\nexport function getFirestore(): admin.firestore.Firestore {\n return getApp().firestore();\n}\n\n/**\n * Get Firebase Auth instance from the pre-initialized Firebase app.\n */\nexport function getAuth(): admin.auth.Auth {\n return getApp().auth();\n}\n\n// Re-export admin for convenience\nexport { admin };\n\n/**\n * Lazy Firestore proxy — resolves on first property access, not at import time.\n * This prevents the \"Firebase not initialized\" error during module loading.\n */\nexport const db = new Proxy({} as admin.firestore.Firestore, {\n get(_target, prop, receiver) {\n const firestore = getFirestore();\n const value = Reflect.get(firestore, prop, receiver);\n return typeof value === 'function' ? value.bind(firestore) : value;\n },\n});\n","import { NextFunction, Request, Response } from 'express';\nimport type { DecodedIdToken } from 'firebase-admin/auth';\nimport { getAuth } from '../lib/db.js';\nimport { env } from '../lib/env.js';\n\nconst BEARER_PREFIX = 'Bearer ';\n\n/** Fake dev user injected when NODE_ENV=development and no auth header is present */\nconst DEV_USER: DecodedIdToken = {\n uid: 'dev-user-001',\n email: 'dev@localhost',\n email_verified: true,\n aud: 'dev-project',\n auth_time: Math.floor(Date.now() / 1000),\n exp: Math.floor(Date.now() / 1000) + 3600,\n iat: Math.floor(Date.now() / 1000),\n iss: 'https://securetoken.google.com/dev-project',\n sub: 'dev-user-001',\n firebase: {\n identities: {},\n sign_in_provider: 'custom',\n },\n};\n\nexport async function authenticateFirebase(req: Request, res: Response, next: NextFunction) {\n const authorization = req.headers.authorization;\n\n // Dev bypass: in development mode, skip auth if no token is provided\n if (env.NODE_ENV === 'development' && (!authorization || !authorization.startsWith(BEARER_PREFIX))) {\n req.firebaseUser = DEV_USER;\n res.locals.firebaseUser = DEV_USER;\n return next();\n }\n\n try {\n if (!authorization || !authorization.startsWith(BEARER_PREFIX)) {\n return res.status(401).json({ error: 'Authorization header missing or malformed' });\n }\n\n const token = authorization.slice(BEARER_PREFIX.length);\n const decodedToken = await getAuth().verifyIdToken(token);\n\n req.firebaseUser = decodedToken;\n res.locals.firebaseUser = decodedToken;\n\n return next();\n } catch (error) {\n console.error('Firebase authentication failed:', error);\n return res.status(401).json({ error: 'Unauthorized' });\n }\n}\n\nexport default authenticateFirebase;\n\n\n"]}
@@ -1,34 +0,0 @@
1
- /**
2
- * Multi-User Middleware
3
- *
4
- * Provides user isolation and session ownership using Firebase Auth.
5
- *
6
- * @packageDocumentation
7
- */
8
- import type { Request, Response, NextFunction } from 'express';
9
- declare global {
10
- namespace Express {
11
- interface Request {
12
- user?: {
13
- uid: string;
14
- email?: string;
15
- roles?: string[];
16
- orgId?: string;
17
- };
18
- userContext?: {
19
- userId: string;
20
- orgId?: string;
21
- roles?: string[];
22
- };
23
- }
24
- }
25
- }
26
- /**
27
- * Middleware to set up user context from Firebase Auth
28
- */
29
- export declare function multiUserMiddleware(req: Request, res: Response, next: NextFunction): Promise<void>;
30
- /**
31
- * Verify Firebase Auth token from Authorization header
32
- */
33
- export declare function verifyFirebaseAuth(req: Request, res: Response, next: NextFunction): Promise<void>;
34
- //# sourceMappingURL=multi-user.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"multi-user.d.ts","sourceRoot":"","sources":["../../src/middleware/multi-user.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,IAAI,CAAC,EAAE;gBACL,GAAG,EAAE,MAAM,CAAC;gBACZ,KAAK,CAAC,EAAE,MAAM,CAAC;gBACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;gBACjB,KAAK,CAAC,EAAE,MAAM,CAAC;aAChB,CAAC;YACF,WAAW,CAAC,EAAE;gBACZ,MAAM,EAAE,MAAM,CAAC;gBACf,KAAK,CAAC,EAAE,MAAM,CAAC;gBACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;aAClB,CAAC;SACH;KACF;CACF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
@@ -1,76 +0,0 @@
1
- import { createUserContext, getMultiUserManager } from '@almadar/agent';
2
- import admin from 'firebase-admin';
3
-
4
- // src/middleware/multi-user.ts
5
- function getApp() {
6
- if (admin.apps.length === 0) {
7
- throw new Error(
8
- "@almadar/server: Firebase Admin SDK is not initialized. Call initializeFirebase() or admin.initializeApp() before using @almadar/server."
9
- );
10
- }
11
- return admin.app();
12
- }
13
- function getFirestore() {
14
- return getApp().firestore();
15
- }
16
- function getAuth() {
17
- return getApp().auth();
18
- }
19
- new Proxy({}, {
20
- get(_target, prop, receiver) {
21
- const firestore = getFirestore();
22
- const value = Reflect.get(firestore, prop, receiver);
23
- return typeof value === "function" ? value.bind(firestore) : value;
24
- }
25
- });
26
-
27
- // src/middleware/multi-user.ts
28
- async function multiUserMiddleware(req, res, next) {
29
- const userId = req.user?.uid;
30
- if (!userId) {
31
- res.status(401).json({ error: "Authentication required" });
32
- return;
33
- }
34
- req.userContext = createUserContext(userId, {
35
- orgId: req.user?.orgId,
36
- roles: req.user?.roles ?? ["user"]
37
- });
38
- const originalJson = res.json.bind(res);
39
- res.json = (body) => {
40
- if (body && typeof body === "object" && "threadId" in body) {
41
- const multiUser = getMultiUserManager();
42
- multiUser.assignSessionOwnership(
43
- body.threadId,
44
- userId
45
- );
46
- }
47
- return originalJson(body);
48
- };
49
- next();
50
- }
51
- async function verifyFirebaseAuth(req, res, next) {
52
- const authHeader = req.headers.authorization;
53
- if (!authHeader?.startsWith("Bearer ")) {
54
- res.status(401).json({ error: "No token provided" });
55
- return;
56
- }
57
- const token = authHeader.split("Bearer ")[1];
58
- try {
59
- const decodedToken = await getAuth().verifyIdToken(token);
60
- const user = await getAuth().getUser(decodedToken.uid);
61
- req.user = {
62
- uid: decodedToken.uid,
63
- email: decodedToken.email,
64
- roles: user.customClaims?.roles ?? ["user"],
65
- orgId: user.customClaims?.orgId
66
- };
67
- next();
68
- } catch (error) {
69
- console.error("Token verification failed:", error);
70
- res.status(401).json({ error: "Invalid token" });
71
- }
72
- }
73
-
74
- export { multiUserMiddleware, verifyFirebaseAuth };
75
- //# sourceMappingURL=multi-user.js.map
76
- //# sourceMappingURL=multi-user.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/lib/db.ts","../../src/middleware/multi-user.ts"],"names":[],"mappings":"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","file":"multi-user.js","sourcesContent":["/**\n * Database Accessors & Initialization\n *\n * This module provides:\n * - `initializeFirebase()` — convenience function to init Firebase from env vars\n * - `getFirestore()`, `getAuth()` — accessors for Firebase services\n * - `db` — lazy Firestore proxy (no eager initialization)\n *\n * The consuming application MUST call `initializeFirebase()` or\n * `admin.initializeApp()` before using any Firebase-dependent features.\n */\n\nimport admin from 'firebase-admin';\n\n/**\n * Initialize Firebase Admin SDK from environment variables.\n *\n * Reads: FIREBASE_PROJECT_ID, FIREBASE_CLIENT_EMAIL, FIREBASE_PRIVATE_KEY,\n * FIREBASE_SERVICE_ACCOUNT_PATH, FIRESTORE_EMULATOR_HOST\n *\n * Safe to call multiple times — returns existing app if already initialized.\n */\nexport function initializeFirebase(): admin.app.App {\n // Already initialized — return existing app\n if (admin.apps.length > 0) {\n return admin.app();\n }\n\n const projectId = process.env.FIREBASE_PROJECT_ID;\n const emulatorHost = process.env.FIRESTORE_EMULATOR_HOST;\n\n // Emulator mode — no credentials needed\n if (emulatorHost) {\n const app = admin.initializeApp({\n projectId: projectId || 'demo-project',\n });\n console.log(`Firebase Admin initialized for emulator: ${emulatorHost}`);\n return app;\n }\n\n // Service account file\n const serviceAccountPath = process.env.FIREBASE_SERVICE_ACCOUNT_PATH;\n if (serviceAccountPath) {\n // Dynamic require for JSON service account file at runtime\n const serviceAccount = require(serviceAccountPath) as Record<string, unknown>;\n return admin.initializeApp({\n credential: admin.credential.cert(serviceAccount),\n projectId,\n });\n }\n\n // Inline credentials\n const clientEmail = process.env.FIREBASE_CLIENT_EMAIL;\n const privateKey = process.env.FIREBASE_PRIVATE_KEY;\n if (projectId && clientEmail && privateKey) {\n return admin.initializeApp({\n credential: admin.credential.cert({\n projectId,\n clientEmail,\n privateKey: privateKey.replace(/\\\\n/g, '\\n'),\n }),\n projectId,\n });\n }\n\n // Application default credentials (Cloud Run, etc.)\n if (projectId) {\n return admin.initializeApp({\n credential: admin.credential.applicationDefault(),\n projectId,\n });\n }\n\n throw new Error(\n '@almadar/server: Cannot initialize Firebase — no credentials found. ' +\n 'Set FIREBASE_PROJECT_ID + FIREBASE_CLIENT_EMAIL + FIREBASE_PRIVATE_KEY, ' +\n 'or FIREBASE_SERVICE_ACCOUNT_PATH, or FIRESTORE_EMULATOR_HOST.'\n );\n}\n\n/**\n * Get the initialized Firebase app.\n * Throws if Firebase Admin SDK has not been initialized.\n */\nfunction getApp(): admin.app.App {\n if (admin.apps.length === 0) {\n throw new Error(\n '@almadar/server: Firebase Admin SDK is not initialized. ' +\n 'Call initializeFirebase() or admin.initializeApp() before using @almadar/server.'\n );\n }\n return admin.app();\n}\n\n/**\n * Get Firestore instance from the pre-initialized Firebase app.\n */\nexport function getFirestore(): admin.firestore.Firestore {\n return getApp().firestore();\n}\n\n/**\n * Get Firebase Auth instance from the pre-initialized Firebase app.\n */\nexport function getAuth(): admin.auth.Auth {\n return getApp().auth();\n}\n\n// Re-export admin for convenience\nexport { admin };\n\n/**\n * Lazy Firestore proxy — resolves on first property access, not at import time.\n * This prevents the \"Firebase not initialized\" error during module loading.\n */\nexport const db = new Proxy({} as admin.firestore.Firestore, {\n get(_target, prop, receiver) {\n const firestore = getFirestore();\n const value = Reflect.get(firestore, prop, receiver);\n return typeof value === 'function' ? value.bind(firestore) : value;\n },\n});\n","/**\n * Multi-User Middleware\n *\n * Provides user isolation and session ownership using Firebase Auth.\n *\n * @packageDocumentation\n */\n\nimport { getMultiUserManager, createUserContext } from '@almadar/agent';\nimport { getAuth } from '../lib/db.js';\nimport type { Request, Response, NextFunction } from 'express';\n\n// Extend Express Request to include Firebase user\ndeclare global {\n namespace Express {\n interface Request {\n user?: {\n uid: string;\n email?: string;\n roles?: string[];\n orgId?: string;\n };\n userContext?: {\n userId: string;\n orgId?: string;\n roles?: string[];\n };\n }\n }\n}\n\n/**\n * Middleware to set up user context from Firebase Auth\n */\nexport async function multiUserMiddleware(\n req: Request,\n res: Response,\n next: NextFunction,\n): Promise<void> {\n const userId = req.user?.uid;\n\n if (!userId) {\n res.status(401).json({ error: 'Authentication required' });\n return;\n }\n\n // Create user context\n req.userContext = createUserContext(userId, {\n orgId: req.user?.orgId,\n roles: req.user?.roles ?? ['user'],\n });\n\n // Assign session ownership when creating new sessions\n const originalJson = res.json.bind(res);\n res.json = (body: unknown) => {\n if (body && typeof body === 'object' && 'threadId' in body) {\n const multiUser = getMultiUserManager();\n multiUser.assignSessionOwnership(\n (body as { threadId: string }).threadId,\n userId,\n );\n }\n return originalJson(body);\n };\n\n next();\n}\n\n/**\n * Verify Firebase Auth token from Authorization header\n */\nexport async function verifyFirebaseAuth(\n req: Request,\n res: Response,\n next: NextFunction,\n): Promise<void> {\n const authHeader = req.headers.authorization;\n\n if (!authHeader?.startsWith('Bearer ')) {\n res.status(401).json({ error: 'No token provided' });\n return;\n }\n\n const token = authHeader.split('Bearer ')[1];\n\n try {\n const decodedToken = await getAuth().verifyIdToken(token);\n\n // Get custom claims for roles/org\n const user = await getAuth().getUser(decodedToken.uid);\n\n req.user = {\n uid: decodedToken.uid,\n email: decodedToken.email,\n roles: (user.customClaims?.roles as string[]) ?? ['user'],\n orgId: user.customClaims?.orgId as string,\n };\n\n next();\n } catch (error) {\n console.error('Token verification failed:', error);\n res.status(401).json({ error: 'Invalid token' });\n }\n}\n"]}
@@ -1,15 +0,0 @@
1
- import { Request, Response, NextFunction } from 'express';
2
- import { AnyZodObject } from 'zod';
3
- /**
4
- * Middleware to validate request body against a Zod schema
5
- */
6
- export declare const validateBody: (schema: AnyZodObject) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
7
- /**
8
- * Middleware to validate request query parameters against a Zod schema
9
- */
10
- export declare const validateQuery: (schema: AnyZodObject) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
11
- /**
12
- * Middleware to validate request params against a Zod schema
13
- */
14
- export declare const validateParams: (schema: AnyZodObject) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
15
- //# sourceMappingURL=validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/middleware/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAY,MAAM,KAAK,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,YAAY,GACtB,QAAQ,YAAY,MAAY,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,OAAO,CAAC,IAAI,CAmB9F,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,aAAa,GACvB,QAAQ,YAAY,MAAY,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,OAAO,CAAC,IAAI,CAmB9F,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,cAAc,GACxB,QAAQ,YAAY,MAAY,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,OAAO,CAAC,IAAI,CAmB9F,CAAC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * @fileoverview Unit tests for observability routes
3
- * @module @almadar/server/routes/observability.test
4
- */
5
- export {};
6
- //# sourceMappingURL=observability.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"observability.test.d.ts","sourceRoot":"","sources":["../../../src/routes/__tests__/observability.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -1,11 +0,0 @@
1
- /**
2
- * Observability Routes
3
- *
4
- * Provides endpoints for metrics, health checks, and telemetry.
5
- *
6
- * @packageDocumentation
7
- */
8
- import { Router } from 'express';
9
- declare const router: ReturnType<typeof Router>;
10
- export default router;
11
- //# sourceMappingURL=observability.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../src/routes/observability.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,QAAA,MAAM,MAAM,EAAE,UAAU,CAAC,OAAO,MAAM,CAAY,CAAC;AAyEnD,eAAe,MAAM,CAAC"}
@@ -1,62 +0,0 @@
1
- import { Router } from 'express';
2
- import { getObservabilityCollector } from '@almadar/agent';
3
-
4
- // src/routes/observability.ts
5
- var router = Router();
6
- router.get("/metrics", async (req, res) => {
7
- try {
8
- const collector = getObservabilityCollector();
9
- const snapshot = collector.getPerformanceSnapshot();
10
- res.json(snapshot);
11
- } catch (error) {
12
- console.error("Metrics error:", error);
13
- res.status(500).json({ error: "Failed to get metrics" });
14
- }
15
- });
16
- router.get("/health", async (req, res) => {
17
- try {
18
- const collector = getObservabilityCollector();
19
- const health = await collector.healthCheck();
20
- const allHealthy = health.every((h) => h.status === "healthy");
21
- res.status(allHealthy ? 200 : 503).json({
22
- status: allHealthy ? "healthy" : "degraded",
23
- timestamp: Date.now(),
24
- checks: health
25
- });
26
- } catch (error) {
27
- console.error("Health check error:", error);
28
- res.status(500).json({
29
- status: "unhealthy",
30
- error: "Health check failed"
31
- });
32
- }
33
- });
34
- router.get("/sessions/:threadId/telemetry", async (req, res) => {
35
- try {
36
- const collector = getObservabilityCollector();
37
- const telemetry = collector.getSessionTelemetry(req.params.threadId);
38
- if (!telemetry) {
39
- res.status(404).json({ error: "Session not found" });
40
- return;
41
- }
42
- res.json(telemetry);
43
- } catch (error) {
44
- console.error("Telemetry error:", error);
45
- res.status(500).json({ error: "Failed to get telemetry" });
46
- }
47
- });
48
- router.get("/active-sessions", async (req, res) => {
49
- try {
50
- const collector = getObservabilityCollector();
51
- const sessions = collector.getActiveSessions();
52
- res.json(sessions);
53
- } catch (error) {
54
- console.error("Active sessions error:", error);
55
- res.status(500).json({ error: "Failed to get active sessions" });
56
- }
57
- });
58
- var observability_default = router;
59
-
60
- export { observability_default as default };
61
- //# sourceMappingURL=observability.js.map
62
- //# sourceMappingURL=observability.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/routes/observability.ts"],"names":[],"mappings":";;;;AAWA,IAAM,SAAoC,MAAA,EAAO;AAKjD,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,OAAO,GAAA,EAAK,GAAA,KAAQ;AACzC,EAAA,IAAI;AACF,IAAA,MAAM,YAAY,yBAAA,EAA0B;AAC5C,IAAA,MAAM,QAAA,GAAW,UAAU,sBAAA,EAAuB;AAClD,IAAA,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,EACnB,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,kBAAkB,KAAK,CAAA;AACrC,IAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,yBAAyB,CAAA;AAAA,EACzD;AACF,CAAC,CAAA;AAKD,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,OAAO,GAAA,EAAK,GAAA,KAAQ;AACxC,EAAA,IAAI;AACF,IAAA,MAAM,YAAY,yBAAA,EAA0B;AAC5C,IAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU,WAAA,EAAY;AAC3C,IAAA,MAAM,aAAa,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,SAAS,CAAA;AAE7D,IAAA,GAAA,CAAI,MAAA,CAAO,UAAA,GAAa,GAAA,GAAM,GAAG,EAAE,IAAA,CAAK;AAAA,MACtC,MAAA,EAAQ,aAAa,SAAA,GAAY,UAAA;AAAA,MACjC,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,MAAA,EAAQ;AAAA,KACT,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,uBAAuB,KAAK,CAAA;AAC1C,IAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,MACnB,MAAA,EAAQ,WAAA;AAAA,MACR,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AACF,CAAC,CAAA;AAKD,MAAA,CAAO,GAAA,CAAI,+BAAA,EAAiC,OAAO,GAAA,EAAK,GAAA,KAAQ;AAC9D,EAAA,IAAI;AACF,IAAA,MAAM,YAAY,yBAAA,EAA0B;AAC5C,IAAA,MAAM,SAAA,GAAY,SAAA,CAAU,mBAAA,CAAoB,GAAA,CAAI,OAAO,QAAQ,CAAA;AAEnE,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,qBAAqB,CAAA;AACnD,MAAA;AAAA,IACF;AAEA,IAAA,GAAA,CAAI,KAAK,SAAS,CAAA;AAAA,EACpB,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,oBAAoB,KAAK,CAAA;AACvC,IAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,2BAA2B,CAAA;AAAA,EAC3D;AACF,CAAC,CAAA;AAKD,MAAA,CAAO,GAAA,CAAI,kBAAA,EAAoB,OAAO,GAAA,EAAK,GAAA,KAAQ;AACjD,EAAA,IAAI;AACF,IAAA,MAAM,YAAY,yBAAA,EAA0B;AAC5C,IAAA,MAAM,QAAA,GAAW,UAAU,iBAAA,EAAkB;AAC7C,IAAA,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,EACnB,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,0BAA0B,KAAK,CAAA;AAC7C,IAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,iCAAiC,CAAA;AAAA,EACjE;AACF,CAAC,CAAA;AAED,IAAO,qBAAA,GAAQ","file":"observability.js","sourcesContent":["/**\n * Observability Routes\n *\n * Provides endpoints for metrics, health checks, and telemetry.\n *\n * @packageDocumentation\n */\n\nimport { Router } from 'express';\nimport { getObservabilityCollector } from '@almadar/agent';\n\nconst router: ReturnType<typeof Router> = Router();\n\n/**\n * GET /metrics - Get performance snapshot\n */\nrouter.get('/metrics', async (req, res) => {\n try {\n const collector = getObservabilityCollector();\n const snapshot = collector.getPerformanceSnapshot();\n res.json(snapshot);\n } catch (error) {\n console.error('Metrics error:', error);\n res.status(500).json({ error: 'Failed to get metrics' });\n }\n});\n\n/**\n * GET /health - Get health check\n */\nrouter.get('/health', async (req, res) => {\n try {\n const collector = getObservabilityCollector();\n const health = await collector.healthCheck();\n const allHealthy = health.every((h) => h.status === 'healthy');\n\n res.status(allHealthy ? 200 : 503).json({\n status: allHealthy ? 'healthy' : 'degraded',\n timestamp: Date.now(),\n checks: health,\n });\n } catch (error) {\n console.error('Health check error:', error);\n res.status(500).json({\n status: 'unhealthy',\n error: 'Health check failed',\n });\n }\n});\n\n/**\n * GET /sessions/:threadId/telemetry - Get session telemetry\n */\nrouter.get('/sessions/:threadId/telemetry', async (req, res) => {\n try {\n const collector = getObservabilityCollector();\n const telemetry = collector.getSessionTelemetry(req.params.threadId);\n\n if (!telemetry) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n\n res.json(telemetry);\n } catch (error) {\n console.error('Telemetry error:', error);\n res.status(500).json({ error: 'Failed to get telemetry' });\n }\n});\n\n/**\n * GET /active-sessions - Get active sessions\n */\nrouter.get('/active-sessions', async (req, res) => {\n try {\n const collector = getObservabilityCollector();\n const sessions = collector.getActiveSessions();\n res.json(sessions);\n } catch (error) {\n console.error('Active sessions error:', error);\n res.status(500).json({ error: 'Failed to get active sessions' });\n }\n});\n\nexport default router;\n"]}