@almadar/server 2.1.5 → 2.2.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.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Almadar Structured Logger (Server copy)
3
+ *
4
+ * Namespace-based logging with level gating.
5
+ * Duplicated from @almadar/ui/lib/logger because @almadar/server
6
+ * does not depend on @almadar/ui.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ export interface Logger {
11
+ debug: (msg: string, data?: Record<string, unknown>) => void;
12
+ info: (msg: string, data?: Record<string, unknown>) => void;
13
+ warn: (msg: string, data?: Record<string, unknown>) => void;
14
+ error: (msg: string, data?: Record<string, unknown>) => void;
15
+ }
16
+ export declare function createLogger(namespace: string): Logger;
17
+ //# sourceMappingURL=almadarLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"almadarLogger.d.ts","sourceRoot":"","sources":["../src/almadarLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0BH,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC7D,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC5D,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC5D,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC9D;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAuBtD"}
package/dist/index.js CHANGED
@@ -861,6 +861,50 @@ var EventPersistence = class {
861
861
 
862
862
  // src/services/DataService.ts
863
863
  init_db();
864
+
865
+ // src/almadarLogger.ts
866
+ var LEVEL_PRIORITY = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3 };
867
+ var ENV = typeof process !== "undefined" && process.env ? process.env : {};
868
+ var NODE_ENV = ENV.NODE_ENV ?? "development";
869
+ var CONFIGURED_LEVEL = (ENV.LOG_LEVEL ?? (NODE_ENV === "production" ? "info" : "debug")).toUpperCase();
870
+ var MIN_PRIORITY = LEVEL_PRIORITY[CONFIGURED_LEVEL] ?? 0;
871
+ var DEBUG_FILTER = (ENV.ALMADAR_DEBUG ?? "").split(",").map((s) => s.trim()).filter(Boolean);
872
+ function matchesNamespace(namespace) {
873
+ if (DEBUG_FILTER.length === 0) return true;
874
+ return DEBUG_FILTER.some((pattern) => {
875
+ if (pattern === "*" || pattern === "almadar:*") return true;
876
+ if (pattern.endsWith(":*")) return namespace.startsWith(pattern.slice(0, -1));
877
+ return namespace === pattern;
878
+ });
879
+ }
880
+ function createLogger(namespace) {
881
+ const nsAllowed = matchesNamespace(namespace);
882
+ const log = (level, message, data) => {
883
+ if (LEVEL_PRIORITY[level] < MIN_PRIORITY) return;
884
+ if (level === "DEBUG" && !nsAllowed) return;
885
+ const prefix = `[${namespace}]`;
886
+ switch (level) {
887
+ case "DEBUG":
888
+ console.debug(prefix, message, data ?? "");
889
+ break;
890
+ case "INFO":
891
+ console.info(prefix, message, data ?? "");
892
+ break;
893
+ case "WARN":
894
+ console.warn(prefix, message, data ?? "");
895
+ break;
896
+ case "ERROR":
897
+ console.error(prefix, message, data ?? "");
898
+ break;
899
+ }
900
+ };
901
+ return {
902
+ debug: (msg, data) => log("DEBUG", msg, data),
903
+ info: (msg, data) => log("INFO", msg, data),
904
+ warn: (msg, data) => log("WARN", msg, data),
905
+ error: (msg, data) => log("ERROR", msg, data)
906
+ };
907
+ }
864
908
  var MockDataService = class {
865
909
  stores = /* @__PURE__ */ new Map();
866
910
  schemas = /* @__PURE__ */ new Map();
@@ -1274,6 +1318,7 @@ function extractPaginationParams(query, defaults = {}) {
1274
1318
  }
1275
1319
 
1276
1320
  // src/services/DataService.ts
1321
+ var dataLog = createLogger("almadar:server:data");
1277
1322
  function applyFilterCondition(value, operator, filterValue) {
1278
1323
  if (value === null || value === void 0) {
1279
1324
  return operator === "!=" ? filterValue !== null : false;
@@ -1305,7 +1350,9 @@ function applyFilterCondition(value, operator, filterValue) {
1305
1350
  }
1306
1351
  var MockDataServiceAdapter = class {
1307
1352
  async list(collection) {
1308
- return getMockDataService().list(collection);
1353
+ const result = getMockDataService().list(collection);
1354
+ dataLog.debug("list", { entity: collection, count: result.length });
1355
+ return result;
1309
1356
  }
1310
1357
  async listPaginated(collection, options = {}) {
1311
1358
  const {
@@ -1357,16 +1404,24 @@ var MockDataServiceAdapter = class {
1357
1404
  return { data, total, page, pageSize, totalPages };
1358
1405
  }
1359
1406
  async getById(collection, id) {
1360
- return getMockDataService().getById(collection, id);
1407
+ const result = getMockDataService().getById(collection, id);
1408
+ dataLog.debug("getById", { entity: collection, id, found: result !== null });
1409
+ return result;
1361
1410
  }
1362
1411
  async create(collection, data) {
1363
- return getMockDataService().create(collection, data);
1412
+ const result = getMockDataService().create(collection, data);
1413
+ dataLog.info("create", { entity: collection, id: result.id });
1414
+ return result;
1364
1415
  }
1365
1416
  async update(collection, id, data) {
1366
- return getMockDataService().update(collection, id, data);
1417
+ const result = getMockDataService().update(collection, id, data);
1418
+ dataLog.info("update", { entity: collection, id, found: result !== null });
1419
+ return result;
1367
1420
  }
1368
1421
  async delete(collection, id) {
1369
- return getMockDataService().delete(collection, id);
1422
+ const result = getMockDataService().delete(collection, id);
1423
+ dataLog.info("delete", { entity: collection, id, success: result });
1424
+ return result;
1370
1425
  }
1371
1426
  async query(collection, filters) {
1372
1427
  let items = getMockDataService().list(collection);
@@ -1404,10 +1459,12 @@ var MockDataServiceAdapter = class {
1404
1459
  var FirebaseDataService = class {
1405
1460
  async list(collection) {
1406
1461
  const snapshot = await db.collection(collection).get();
1407
- return snapshot.docs.map((doc) => ({
1462
+ const items = snapshot.docs.map((doc) => ({
1408
1463
  id: doc.id,
1409
1464
  ...doc.data()
1410
1465
  }));
1466
+ dataLog.debug("list", { entity: collection, count: items.length });
1467
+ return items;
1411
1468
  }
1412
1469
  async listPaginated(collection, options = {}) {
1413
1470
  const {
@@ -1462,6 +1519,7 @@ var FirebaseDataService = class {
1462
1519
  }
1463
1520
  async getById(collection, id) {
1464
1521
  const doc = await db.collection(collection).doc(id).get();
1522
+ dataLog.debug("getById", { entity: collection, id, found: doc.exists });
1465
1523
  if (!doc.exists) {
1466
1524
  return null;
1467
1525
  }
@@ -1474,6 +1532,7 @@ var FirebaseDataService = class {
1474
1532
  createdAt: now,
1475
1533
  updatedAt: now
1476
1534
  });
1535
+ dataLog.info("create", { entity: collection, id: docRef.id });
1477
1536
  return {
1478
1537
  ...data,
1479
1538
  id: docRef.id,
@@ -1492,6 +1551,7 @@ var FirebaseDataService = class {
1492
1551
  ...data,
1493
1552
  updatedAt: now
1494
1553
  });
1554
+ dataLog.info("update", { entity: collection, id });
1495
1555
  return {
1496
1556
  ...doc.data(),
1497
1557
  ...data,
@@ -1503,9 +1563,11 @@ var FirebaseDataService = class {
1503
1563
  const docRef = db.collection(collection).doc(id);
1504
1564
  const doc = await docRef.get();
1505
1565
  if (!doc.exists) {
1566
+ dataLog.debug("delete", { entity: collection, id, found: false });
1506
1567
  return false;
1507
1568
  }
1508
1569
  await docRef.delete();
1570
+ dataLog.info("delete", { entity: collection, id, success: true });
1509
1571
  return true;
1510
1572
  }
1511
1573
  async query(collection, filters) {
@@ -1851,6 +1913,7 @@ var validateParams = (schema) => async (req, res, next) => {
1851
1913
 
1852
1914
  // src/middleware/authenticateFirebase.ts
1853
1915
  init_db();
1916
+ var authLog = createLogger("almadar:server:auth");
1854
1917
  var BEARER_PREFIX = "Bearer ";
1855
1918
  var DEV_USER = {
1856
1919
  uid: "dev-user-001",
@@ -1870,6 +1933,7 @@ var DEV_USER = {
1870
1933
  async function authenticateFirebase(req, res, next) {
1871
1934
  const authorization = req.headers.authorization;
1872
1935
  if (env.NODE_ENV === "development" && (!authorization || !authorization.startsWith(BEARER_PREFIX))) {
1936
+ authLog.debug("auth:devBypass", { uid: DEV_USER.uid });
1873
1937
  req.firebaseUser = DEV_USER;
1874
1938
  res.locals.firebaseUser = DEV_USER;
1875
1939
  return next();
@@ -1880,10 +1944,12 @@ async function authenticateFirebase(req, res, next) {
1880
1944
  }
1881
1945
  const token = authorization.slice(BEARER_PREFIX.length);
1882
1946
  const decodedToken = await getAuth().verifyIdToken(token);
1947
+ authLog.info("auth:verified", { uid: decodedToken.uid, email: decodedToken.email });
1883
1948
  req.firebaseUser = decodedToken;
1884
1949
  res.locals.firebaseUser = decodedToken;
1885
1950
  return next();
1886
1951
  } catch (error) {
1952
+ authLog.warn("auth:failed", { error: error instanceof Error ? error.message : String(error) });
1887
1953
  console.error("Firebase authentication failed:", error);
1888
1954
  return res.status(401).json({ error: "Unauthorized" });
1889
1955
  }