@frogfish/k2db 3.0.6 → 3.0.7

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 (2) hide show
  1. package/db.js +154 -21
  2. package/package.json +1 -1
package/db.js CHANGED
@@ -457,7 +457,23 @@ export class K2DB {
457
457
  const msg = err instanceof Error
458
458
  ? `Failed to connect to MongoDB: ${err.message}`
459
459
  : `Failed to connect to MongoDB: ${String(err)}`;
460
- throw wrap(err, ServiceError.SERVICE_UNAVAILABLE, "sys_mdb_init", msg);
460
+ // Preserve existing K2Error severity if already typed; otherwise map to SERVICE_UNAVAILABLE.
461
+ const sev = err instanceof K2Error ? undefined : ServiceError.SERVICE_UNAVAILABLE;
462
+ const k2 = chain(err, "sys_mdb_init", msg, sev, "k2db.init")
463
+ .setSensitive({
464
+ op: "init",
465
+ db: this.conf?.name,
466
+ // safeConnectUrl is already masked (no credentials)
467
+ connectUrl: safeConnectUrl,
468
+ options: summariseValueShape(options),
469
+ mongo: normaliseMongoError(err),
470
+ });
471
+ // Emit once (deduped per error instance)
472
+ emitDbError(k2, {
473
+ op: "init",
474
+ db: this.conf?.name,
475
+ });
476
+ throw k2;
461
477
  }
462
478
  })().finally(() => {
463
479
  // Allow retry after failure; once initialized, subsequent calls return early.
@@ -540,12 +556,16 @@ export class K2DB {
540
556
  }
541
557
  catch (err) {
542
558
  const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
543
- throw chain(err, "sys_mdb_gc", `Error getting collection: ${collectionName}`, sev, "k2db.getCollection")
544
- .setSensitive({
559
+ const k2 = chain(err, "sys_mdb_gc", `Error getting collection: ${collectionName}`, sev, "k2db.getCollection").setSensitive({
545
560
  op: "getCollection",
546
561
  collection: collectionName,
547
562
  mongo: normaliseMongoError(err),
548
563
  });
564
+ emitDbError(k2, {
565
+ op: "getCollection",
566
+ collection: collectionName,
567
+ });
568
+ throw k2;
549
569
  }
550
570
  }
551
571
  /**
@@ -557,10 +577,35 @@ export class K2DB {
557
577
  async get(collectionName, uuid, scope) {
558
578
  const id = K2DB.normalizeId(uuid);
559
579
  // Note: findOne() decrypts secure-prefixed fields for single-record reads when encryption is enabled.
560
- const res = await this.findOne(collectionName, {
561
- _uuid: id,
562
- _deleted: { $ne: true },
563
- }, undefined, scope);
580
+ let res;
581
+ try {
582
+ res = await this.findOne(collectionName, {
583
+ _uuid: id,
584
+ _deleted: { $ne: true },
585
+ }, undefined, scope);
586
+ }
587
+ catch (err) {
588
+ const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
589
+ const k2 = chain(err, "sys_mdb_get", "Error getting document", sev, "k2db.get");
590
+ // Merge/attach sensitive diagnostics without stomping any existing sensitive payload.
591
+ const prevSensitive = k2.sensitive;
592
+ const mergedSensitive = prevSensitive && typeof prevSensitive === "object" ? { ...prevSensitive } : {};
593
+ Object.assign(mergedSensitive, {
594
+ op: "get",
595
+ collection: collectionName,
596
+ uuid: id,
597
+ scope,
598
+ mongo: normaliseMongoError(err),
599
+ });
600
+ k2.setSensitive?.(mergedSensitive);
601
+ // Emit once (deduped per error instance)
602
+ emitDbError(k2, {
603
+ op: "get",
604
+ collection: collectionName,
605
+ uuid: id,
606
+ });
607
+ throw k2;
608
+ }
564
609
  if (!res) {
565
610
  throw new K2Error(ServiceError.NOT_FOUND, "Document not found", "sys_mdb_get_not_found");
566
611
  }
@@ -628,8 +673,11 @@ export class K2DB {
628
673
  }
629
674
  catch (err) {
630
675
  const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
631
- throw chain(err, "sys_mdb_fo", "Error finding document", sev, "k2db.findOne")
632
- .setSensitive({
676
+ const k2 = chain(err, "sys_mdb_fo", "Error finding document", sev, "k2db.findOne");
677
+ // Merge/attach sensitive diagnostics without stomping any existing sensitive payload.
678
+ const prevSensitive = k2.sensitive;
679
+ const mergedSensitive = prevSensitive && typeof prevSensitive === "object" ? { ...prevSensitive } : {};
680
+ Object.assign(mergedSensitive, {
633
681
  op: "findOne",
634
682
  collection: collectionName,
635
683
  scope,
@@ -640,6 +688,12 @@ export class K2DB {
640
688
  projectionPreview: redactShallowSecrets(projection),
641
689
  mongo: normaliseMongoError(err),
642
690
  });
691
+ k2.setSensitive?.(mergedSensitive);
692
+ emitDbError(k2, {
693
+ op: "findOne",
694
+ collection: collectionName,
695
+ });
696
+ throw k2;
643
697
  }
644
698
  }
645
699
  /**
@@ -720,7 +774,7 @@ export class K2DB {
720
774
  }
721
775
  catch (err) {
722
776
  const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
723
- throw chain(err, "sys_mdb_find_error", "Error executing find query", sev, "k2db.find")
777
+ const k2 = chain(err, "sys_mdb_find_error", "Error executing find query", sev, "k2db.find")
724
778
  .setSensitive({
725
779
  op: "find",
726
780
  collection: collectionName,
@@ -736,6 +790,13 @@ export class K2DB {
736
790
  projectionPreview: redactShallowSecrets(projection),
737
791
  mongo: normaliseMongoError(err),
738
792
  });
793
+ emitDbError(k2, {
794
+ op: "find",
795
+ collection: collectionName,
796
+ skip,
797
+ limit,
798
+ });
799
+ throw k2;
739
800
  }
740
801
  }
741
802
  /**
@@ -1385,7 +1446,7 @@ export class K2DB {
1385
1446
  throw new K2Error(ServiceError.ALREADY_EXISTS, `A document with _uuid ${document._uuid} already exists.`, "sys_mdb_crv3");
1386
1447
  }
1387
1448
  const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
1388
- throw chain(err, "sys_mdb_sav", "Error saving object to database", sev, "k2db.create")
1449
+ const k2 = chain(err, "sys_mdb_sav", "Error saving object to database", sev, "k2db.create")
1389
1450
  .setSensitive({
1390
1451
  op: "insertOne",
1391
1452
  collection: collectionName,
@@ -1395,6 +1456,12 @@ export class K2DB {
1395
1456
  userFieldPreview: redactShallowSecrets(safeData),
1396
1457
  mongo: normaliseMongoError(err),
1397
1458
  });
1459
+ emitDbError(k2, {
1460
+ op: "create",
1461
+ collection: collectionName,
1462
+ uuid: document._uuid,
1463
+ });
1464
+ throw k2;
1398
1465
  }
1399
1466
  }
1400
1467
  /**
@@ -1438,7 +1505,7 @@ export class K2DB {
1438
1505
  }
1439
1506
  catch (err) {
1440
1507
  const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
1441
- throw chain(err, "sys_mdb_update1", `Error updating ${collectionName}`, sev, "k2db.updateAll")
1508
+ const k2 = chain(err, "sys_mdb_update1", `Error updating ${collectionName}`, sev, "k2db.updateAll")
1442
1509
  .setSensitive({
1443
1510
  op: "updateMany",
1444
1511
  collection: collectionName,
@@ -1450,6 +1517,11 @@ export class K2DB {
1450
1517
  valuesPreview: redactShallowSecrets(values),
1451
1518
  mongo: normaliseMongoError(err),
1452
1519
  });
1520
+ emitDbError(k2, {
1521
+ op: "updateAll",
1522
+ collection: collectionName,
1523
+ });
1524
+ throw k2;
1453
1525
  }
1454
1526
  }
1455
1527
  /**
@@ -1506,7 +1578,7 @@ export class K2DB {
1506
1578
  }
1507
1579
  catch (err) {
1508
1580
  const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
1509
- throw chain(err, "sys_mdb_update_error", `Error updating ${collectionName}`, sev, "k2db.update")
1581
+ const k2 = chain(err, "sys_mdb_update_error", `Error updating ${collectionName}`, sev, "k2db.update")
1510
1582
  .setSensitive({
1511
1583
  op: replace ? "replaceOne" : "updateOne",
1512
1584
  collection: collectionName,
@@ -1517,6 +1589,13 @@ export class K2DB {
1517
1589
  dataPreview: redactShallowSecrets(data),
1518
1590
  mongo: normaliseMongoError(err),
1519
1591
  });
1592
+ emitDbError(k2, {
1593
+ op: "update",
1594
+ collection: collectionName,
1595
+ uuid: id,
1596
+ replace,
1597
+ });
1598
+ throw k2;
1520
1599
  }
1521
1600
  }
1522
1601
  /**
@@ -1535,8 +1614,7 @@ export class K2DB {
1535
1614
  }
1536
1615
  catch (err) {
1537
1616
  const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
1538
- throw chain(err, "sys_mdb_deleteall_update", `Error deleting from ${collectionName}`, sev, "k2db.deleteAll")
1539
- .setSensitive({
1617
+ const k2 = chain(err, "sys_mdb_deleteall_update", `Error deleting from ${collectionName}`, sev, "k2db.deleteAll").setSensitive({
1540
1618
  op: "softDeleteMany",
1541
1619
  collection: collectionName,
1542
1620
  scope,
@@ -1544,6 +1622,11 @@ export class K2DB {
1544
1622
  criteriaPreview: redactShallowSecrets(criteria),
1545
1623
  mongo: normaliseMongoError(err),
1546
1624
  });
1625
+ emitDbError(k2, {
1626
+ op: "deleteAll",
1627
+ collection: collectionName,
1628
+ });
1629
+ throw k2;
1547
1630
  }
1548
1631
  }
1549
1632
  /**
@@ -1573,14 +1656,19 @@ export class K2DB {
1573
1656
  }
1574
1657
  catch (err) {
1575
1658
  const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
1576
- throw chain(err, "sys_mdb_remove_upd", "Error removing object from collection", sev, "k2db.delete")
1577
- .setSensitive({
1659
+ const k2 = chain(err, "sys_mdb_remove_upd", "Error removing object from collection", sev, "k2db.delete").setSensitive({
1578
1660
  op: "softDeleteOne",
1579
1661
  collection: collectionName,
1580
1662
  uuid: id,
1581
1663
  scope,
1582
1664
  mongo: normaliseMongoError(err),
1583
1665
  });
1666
+ emitDbError(k2, {
1667
+ op: "delete",
1668
+ collection: collectionName,
1669
+ uuid: id,
1670
+ });
1671
+ throw k2;
1584
1672
  }
1585
1673
  }
1586
1674
  /**
@@ -1641,8 +1729,9 @@ export class K2DB {
1641
1729
  }
1642
1730
  const collection = await this.getCollection(collectionName);
1643
1731
  const cutoff = Date.now() - olderThanMs;
1732
+ let delFilter;
1644
1733
  try {
1645
- const delFilter = this.applyScopeToCriteria({
1734
+ delFilter = this.applyScopeToCriteria({
1646
1735
  _deleted: true,
1647
1736
  _updated: { $lte: cutoff },
1648
1737
  }, scope);
@@ -1650,7 +1739,23 @@ export class K2DB {
1650
1739
  return { purged: res.deletedCount ?? 0 };
1651
1740
  }
1652
1741
  catch (err) {
1653
- throw wrap(err, ServiceError.SYSTEM_ERROR, 'sys_mdb_purge_older', 'Error purging deleted items by age');
1742
+ const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
1743
+ const k2 = chain(err, 'sys_mdb_purge_older', 'Error purging deleted items by age', sev, 'k2db.purgeDeletedOlderThan').setSensitive({
1744
+ op: 'purgeDeletedOlderThan',
1745
+ collection: collectionName,
1746
+ scope,
1747
+ olderThanMs,
1748
+ cutoff,
1749
+ delFilterShape: summariseValueShape(delFilter),
1750
+ delFilterPreview: redactShallowSecrets(delFilter),
1751
+ mongo: normaliseMongoError(err),
1752
+ });
1753
+ emitDbError(k2, {
1754
+ op: 'purgeDeletedOlderThan',
1755
+ collection: collectionName,
1756
+ olderThanMs,
1757
+ });
1758
+ throw k2;
1654
1759
  }
1655
1760
  }
1656
1761
  /**
@@ -1672,7 +1777,23 @@ export class K2DB {
1672
1777
  return { status: "restored", modified: res.modifiedCount };
1673
1778
  }
1674
1779
  catch (err) {
1675
- throw wrap(err, ServiceError.SYSTEM_ERROR, "sys_mdb_pres", "Error restoring a deleted item");
1780
+ const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
1781
+ const k2 = chain(err, "sys_mdb_pres", "Error restoring a deleted item", sev, "k2db.restore")
1782
+ .setSensitive({
1783
+ op: "restore",
1784
+ collection: collectionName,
1785
+ scope,
1786
+ criteriaShape: summariseValueShape(crit),
1787
+ criteriaPreview: redactShallowSecrets(crit),
1788
+ queryShape: summariseValueShape(query),
1789
+ queryPreview: redactShallowSecrets(query),
1790
+ mongo: normaliseMongoError(err),
1791
+ });
1792
+ emitDbError(k2, {
1793
+ op: "restore",
1794
+ collection: collectionName,
1795
+ });
1796
+ throw k2;
1676
1797
  }
1677
1798
  }
1678
1799
  /**
@@ -1735,7 +1856,19 @@ export class K2DB {
1735
1856
  return { status: "ok" };
1736
1857
  }
1737
1858
  catch (err) {
1738
- throw wrap(err, ServiceError.SYSTEM_ERROR, "sys_mdb_drop", "Error dropping collection");
1859
+ const sev = err instanceof K2Error ? undefined : ServiceError.SYSTEM_ERROR;
1860
+ const k2 = chain(err, "sys_mdb_drop", "Error dropping collection", sev, "k2db.drop").setSensitive({
1861
+ op: "drop",
1862
+ collection: collectionName,
1863
+ scope,
1864
+ normalizedScope,
1865
+ mongo: normaliseMongoError(err),
1866
+ });
1867
+ emitDbError(k2, {
1868
+ op: "drop",
1869
+ collection: collectionName,
1870
+ });
1871
+ throw k2;
1739
1872
  }
1740
1873
  }
1741
1874
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frogfish/k2db",
3
- "version": "3.0.6",
3
+ "version": "3.0.7",
4
4
  "description": "A data handling library for K2 applications.",
5
5
  "type": "module",
6
6
  "main": "data.js",