@vritti/api-sdk 0.0.3 → 0.0.5

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
@@ -32,11 +32,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  var index_exports = {};
33
33
  __export(index_exports, {
34
34
  AuthConfigModule: () => AuthConfigModule,
35
+ CsrfGuard: () => CsrfGuard,
35
36
  DatabaseModule: () => DatabaseModule,
37
+ HttpExceptionFilter: () => HttpExceptionFilter,
38
+ HttpModule: () => HttpModule,
36
39
  Onboarding: () => Onboarding,
40
+ PrimaryBaseRepository: () => PrimaryBaseRepository,
37
41
  PrimaryDatabaseService: () => PrimaryDatabaseService,
38
42
  Public: () => Public,
39
43
  Tenant: () => Tenant,
44
+ TenantBaseRepository: () => TenantBaseRepository,
40
45
  TenantContextService: () => TenantContextService,
41
46
  TenantDatabaseService: () => TenantDatabaseService,
42
47
  VrittiAuthGuard: () => VrittiAuthGuard
@@ -376,16 +381,15 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
376
381
  this.logger.log(`Cleared ${size} cached tenant configs`);
377
382
  }
378
383
  /**
379
- * Get primary database client for direct database access
380
- *
381
- * This is useful for platform admin operations (creating tenants, billing, etc.)
384
+ * Get the Prisma client for the primary database.
385
+ * This is a synchronous property that returns the initialized Prisma client.
382
386
  *
383
387
  * @returns Primary database client instance
384
388
  * @throws Error if primary database client is not initialized
385
389
  */
386
- getPrimaryDbClient() {
390
+ get prismaClient() {
387
391
  if (!this.primaryDbClient) {
388
- throw new Error("Primary database client not initialized. Are you in gateway mode?");
392
+ throw new Error("Primary database client not initialized");
389
393
  }
390
394
  return this.primaryDbClient;
391
395
  }
@@ -971,6 +975,17 @@ var TenantDatabaseService = class _TenantDatabaseService {
971
975
  this.startConnectionCleaner();
972
976
  }
973
977
  /**
978
+ * Get the Prisma client for the current tenant's database.
979
+ * This returns the tenant-scoped database client.
980
+ *
981
+ * @returns Tenant-scoped database client instance
982
+ * @throws UnauthorizedException if tenant context not set
983
+ * @throws InternalServerErrorException if connection fails
984
+ */
985
+ get prismaClient() {
986
+ return this.getDbClient();
987
+ }
988
+ /**
974
989
  * Get tenant-scoped database client for the current request/message
975
990
  *
976
991
  * This method:
@@ -1164,7 +1179,7 @@ var DatabaseModule = class _DatabaseModule {
1164
1179
  * })
1165
1180
  */
1166
1181
  static forServer(options) {
1167
- return this.createDynamicModule(options, "gateway");
1182
+ return this.createDynamicModule(options, "server");
1168
1183
  }
1169
1184
  /**
1170
1185
  * Configure DatabaseModule for Microservice/Messaging mode (RabbitMQ workers)
@@ -1207,7 +1222,7 @@ var DatabaseModule = class _DatabaseModule {
1207
1222
  PrimaryDatabaseService,
1208
1223
  TenantDatabaseService
1209
1224
  ];
1210
- if (mode === "gateway") {
1225
+ if (mode === "server") {
1211
1226
  providers.push({
1212
1227
  provide: import_core4.APP_INTERCEPTOR,
1213
1228
  useClass: TenantContextInterceptor
@@ -1238,9 +1253,548 @@ DatabaseModule = _ts_decorate10([
1238
1253
  (0, import_common10.Module)({})
1239
1254
  ], DatabaseModule);
1240
1255
 
1241
- // src/database/decorators/tenant.decorator.ts
1256
+ // src/database/repositories/primary-base.repository.ts
1242
1257
  var import_common11 = require("@nestjs/common");
1243
- var Tenant = (0, import_common11.createParamDecorator)((data, ctx) => {
1258
+ var PrimaryBaseRepository = class {
1259
+ static {
1260
+ __name(this, "PrimaryBaseRepository");
1261
+ }
1262
+ database;
1263
+ logger;
1264
+ modelGetter;
1265
+ /**
1266
+ * Lazy getter for Prisma client.
1267
+ * Accesses the client from the database service only when needed,
1268
+ * avoiding initialization timing issues with NestJS lifecycle.
1269
+ */
1270
+ get prisma() {
1271
+ return this.database.prismaClient;
1272
+ }
1273
+ /**
1274
+ * Lazy getter for the Prisma model delegate.
1275
+ * Returns the specific model (e.g., prisma.user, prisma.tenant) for this repository.
1276
+ */
1277
+ get model() {
1278
+ return this.modelGetter(this.prisma);
1279
+ }
1280
+ /**
1281
+ * Create a new repository instance
1282
+ *
1283
+ * @param database - The primary database service
1284
+ * @param getModel - Function that returns the Prisma model delegate from the client
1285
+ *
1286
+ * @example
1287
+ * ```typescript
1288
+ * // Standard usage with full parameter name
1289
+ * constructor(database: PrimaryDatabaseService) {
1290
+ * super(database, (prisma) => prisma.user);
1291
+ * }
1292
+ *
1293
+ * // Short syntax
1294
+ * constructor(database: PrimaryDatabaseService) {
1295
+ * super(database, (p) => p.user);
1296
+ * }
1297
+ *
1298
+ * // Complex model names
1299
+ * constructor(database: PrimaryDatabaseService) {
1300
+ * super(database, (p) => p.emailVerification);
1301
+ * }
1302
+ * ```
1303
+ */
1304
+ constructor(database, getModel) {
1305
+ this.database = database;
1306
+ this.logger = new import_common11.Logger(this.constructor.name);
1307
+ this.modelGetter = getModel;
1308
+ this.logger.debug(`Initialized ${this.constructor.name}`);
1309
+ }
1310
+ /**
1311
+ * Create a new record
1312
+ *
1313
+ * @param data - The data to create the record with
1314
+ * @returns Promise resolving to the created record
1315
+ *
1316
+ * @example
1317
+ * ```typescript
1318
+ * const user = await userRepository.create({
1319
+ * email: 'user@example.com',
1320
+ * name: 'John Doe'
1321
+ * });
1322
+ * ```
1323
+ */
1324
+ async create(data) {
1325
+ this.logger.log("Creating record");
1326
+ return await this.model.create({
1327
+ data
1328
+ });
1329
+ }
1330
+ /**
1331
+ * Find a single record by ID
1332
+ *
1333
+ * @param id - The record ID
1334
+ * @returns Promise resolving to the record or null if not found
1335
+ *
1336
+ * @example
1337
+ * ```typescript
1338
+ * const user = await userRepository.findById('user-id-123');
1339
+ * ```
1340
+ */
1341
+ async findById(id) {
1342
+ this.logger.debug(`Finding record by ID: ${id}`);
1343
+ return await this.model.findUnique({
1344
+ where: {
1345
+ id
1346
+ }
1347
+ });
1348
+ }
1349
+ /**
1350
+ * Find a single record with custom where clause
1351
+ *
1352
+ * @param where - The where clause or findUnique args
1353
+ * @returns Promise resolving to the record or null if not found
1354
+ *
1355
+ * @example
1356
+ * ```typescript
1357
+ * // Simple where clause
1358
+ * const user = await userRepository.findOne({ email: 'user@example.com' });
1359
+ *
1360
+ * // With include
1361
+ * const user = await userRepository.findOne({
1362
+ * where: { email: 'user@example.com' },
1363
+ * include: { posts: true }
1364
+ * });
1365
+ * ```
1366
+ */
1367
+ async findOne(where) {
1368
+ this.logger.debug("Finding record with custom query");
1369
+ return await this.model.findUnique(typeof where === "object" && "where" in where ? where : {
1370
+ where
1371
+ });
1372
+ }
1373
+ /**
1374
+ * Find multiple records
1375
+ *
1376
+ * @param args - Prisma findMany arguments (where, orderBy, take, skip, etc.)
1377
+ * @returns Promise resolving to an array of records
1378
+ *
1379
+ * @example
1380
+ * ```typescript
1381
+ * // Find all users
1382
+ * const users = await userRepository.findMany();
1383
+ *
1384
+ * // Find with filtering and pagination
1385
+ * const users = await userRepository.findMany({
1386
+ * where: { status: 'ACTIVE' },
1387
+ * orderBy: { createdAt: 'desc' },
1388
+ * take: 10,
1389
+ * skip: 0
1390
+ * });
1391
+ * ```
1392
+ */
1393
+ async findMany(args) {
1394
+ this.logger.debug("Finding multiple records");
1395
+ return await this.model.findMany(args);
1396
+ }
1397
+ /**
1398
+ * Update a record by ID
1399
+ *
1400
+ * @param id - The record ID
1401
+ * @param data - The data to update
1402
+ * @returns Promise resolving to the updated record
1403
+ *
1404
+ * @example
1405
+ * ```typescript
1406
+ * const user = await userRepository.update('user-id-123', {
1407
+ * name: 'Jane Doe'
1408
+ * });
1409
+ * ```
1410
+ */
1411
+ async update(id, data) {
1412
+ this.logger.log(`Updating record with ID: ${id}`);
1413
+ return await this.model.update({
1414
+ where: {
1415
+ id
1416
+ },
1417
+ data
1418
+ });
1419
+ }
1420
+ /**
1421
+ * Update multiple records
1422
+ *
1423
+ * @param where - The where clause to match records
1424
+ * @param data - The data to update
1425
+ * @returns Promise resolving to the count of updated records
1426
+ *
1427
+ * @example
1428
+ * ```typescript
1429
+ * const result = await userRepository.updateMany(
1430
+ * { status: 'PENDING' },
1431
+ * { status: 'ACTIVE' }
1432
+ * );
1433
+ * console.log(`Updated ${result.count} users`);
1434
+ * ```
1435
+ */
1436
+ async updateMany(where, data) {
1437
+ this.logger.log("Updating multiple records");
1438
+ return await this.model.updateMany({
1439
+ where,
1440
+ data
1441
+ });
1442
+ }
1443
+ /**
1444
+ * Delete a record by ID
1445
+ *
1446
+ * @param id - The record ID
1447
+ * @returns Promise resolving to the deleted record
1448
+ *
1449
+ * @example
1450
+ * ```typescript
1451
+ * const user = await userRepository.delete('user-id-123');
1452
+ * ```
1453
+ */
1454
+ async delete(id) {
1455
+ this.logger.log(`Deleting record with ID: ${id}`);
1456
+ return await this.model.delete({
1457
+ where: {
1458
+ id
1459
+ }
1460
+ });
1461
+ }
1462
+ /**
1463
+ * Delete multiple records
1464
+ *
1465
+ * @param where - The where clause to match records
1466
+ * @returns Promise resolving to the count of deleted records
1467
+ *
1468
+ * @example
1469
+ * ```typescript
1470
+ * const result = await userRepository.deleteMany({
1471
+ * status: 'INACTIVE',
1472
+ * createdAt: { lt: new Date('2020-01-01') }
1473
+ * });
1474
+ * console.log(`Deleted ${result.count} users`);
1475
+ * ```
1476
+ */
1477
+ async deleteMany(where) {
1478
+ this.logger.log("Deleting multiple records");
1479
+ return await this.model.deleteMany({
1480
+ where
1481
+ });
1482
+ }
1483
+ /**
1484
+ * Count records
1485
+ *
1486
+ * @param where - Optional where clause to filter records
1487
+ * @returns Promise resolving to the count of records
1488
+ *
1489
+ * @example
1490
+ * ```typescript
1491
+ * // Count all users
1492
+ * const total = await userRepository.count();
1493
+ *
1494
+ * // Count active users
1495
+ * const activeCount = await userRepository.count({ status: 'ACTIVE' });
1496
+ * ```
1497
+ */
1498
+ async count(where) {
1499
+ this.logger.debug("Counting records");
1500
+ return await this.model.count({
1501
+ where
1502
+ });
1503
+ }
1504
+ /**
1505
+ * Check if a record exists
1506
+ *
1507
+ * @param where - The where clause to match records
1508
+ * @returns Promise resolving to true if at least one record exists, false otherwise
1509
+ *
1510
+ * @example
1511
+ * ```typescript
1512
+ * const emailExists = await userRepository.exists({
1513
+ * email: 'user@example.com'
1514
+ * });
1515
+ * ```
1516
+ */
1517
+ async exists(where) {
1518
+ const count = await this.model.count({
1519
+ where
1520
+ });
1521
+ return count > 0;
1522
+ }
1523
+ };
1524
+
1525
+ // src/database/repositories/tenant-base.repository.ts
1526
+ var import_common12 = require("@nestjs/common");
1527
+ var TenantBaseRepository = class {
1528
+ static {
1529
+ __name(this, "TenantBaseRepository");
1530
+ }
1531
+ database;
1532
+ logger;
1533
+ modelGetter;
1534
+ /**
1535
+ * Lazy getter for Prisma client.
1536
+ * Accesses the client from the database service only when needed,
1537
+ * avoiding initialization timing issues with NestJS lifecycle.
1538
+ */
1539
+ get prisma() {
1540
+ return this.database.prismaClient;
1541
+ }
1542
+ /**
1543
+ * Lazy getter for the Prisma model delegate.
1544
+ * Returns the specific model (e.g., prisma.product, prisma.order) for this repository.
1545
+ */
1546
+ get model() {
1547
+ return this.modelGetter(this.prisma);
1548
+ }
1549
+ /**
1550
+ * Create a new repository instance
1551
+ *
1552
+ * @param database - The tenant database service
1553
+ * @param getModel - Function that returns the Prisma model delegate from the client
1554
+ *
1555
+ * @example
1556
+ * ```typescript
1557
+ * // Standard usage with full parameter name
1558
+ * constructor(database: TenantDatabaseService) {
1559
+ * super(database, (prisma) => prisma.product);
1560
+ * }
1561
+ *
1562
+ * // Short syntax
1563
+ * constructor(database: TenantDatabaseService) {
1564
+ * super(database, (p) => p.product);
1565
+ * }
1566
+ *
1567
+ * // Complex model names
1568
+ * constructor(database: TenantDatabaseService) {
1569
+ * super(database, (p) => p.inventoryItem);
1570
+ * }
1571
+ * ```
1572
+ */
1573
+ constructor(database, getModel) {
1574
+ this.database = database;
1575
+ this.logger = new import_common12.Logger(this.constructor.name);
1576
+ this.modelGetter = getModel;
1577
+ this.logger.debug(`Initialized ${this.constructor.name}`);
1578
+ }
1579
+ /**
1580
+ * Create a new record
1581
+ *
1582
+ * @param data - The data to create the record with
1583
+ * @returns Promise resolving to the created record
1584
+ *
1585
+ * @example
1586
+ * ```typescript
1587
+ * const product = await productRepository.create({
1588
+ * name: 'Widget',
1589
+ * sku: 'WDG-001',
1590
+ * price: 9.99
1591
+ * });
1592
+ * ```
1593
+ */
1594
+ async create(data) {
1595
+ this.logger.log("Creating record");
1596
+ return await this.model.create({
1597
+ data
1598
+ });
1599
+ }
1600
+ /**
1601
+ * Find a single record by ID
1602
+ *
1603
+ * @param id - The record ID
1604
+ * @returns Promise resolving to the record or null if not found
1605
+ *
1606
+ * @example
1607
+ * ```typescript
1608
+ * const product = await productRepository.findById('product-id-123');
1609
+ * ```
1610
+ */
1611
+ async findById(id) {
1612
+ this.logger.debug(`Finding record by ID: ${id}`);
1613
+ return await this.model.findUnique({
1614
+ where: {
1615
+ id
1616
+ }
1617
+ });
1618
+ }
1619
+ /**
1620
+ * Find a single record with custom where clause
1621
+ *
1622
+ * @param where - The where clause or findUnique args
1623
+ * @returns Promise resolving to the record or null if not found
1624
+ *
1625
+ * @example
1626
+ * ```typescript
1627
+ * // Simple where clause
1628
+ * const product = await productRepository.findOne({ sku: 'WDG-001' });
1629
+ *
1630
+ * // With include
1631
+ * const product = await productRepository.findOne({
1632
+ * where: { sku: 'WDG-001' },
1633
+ * include: { category: true }
1634
+ * });
1635
+ * ```
1636
+ */
1637
+ async findOne(where) {
1638
+ this.logger.debug("Finding record with custom query");
1639
+ return await this.model.findUnique(typeof where === "object" && "where" in where ? where : {
1640
+ where
1641
+ });
1642
+ }
1643
+ /**
1644
+ * Find multiple records
1645
+ *
1646
+ * @param args - Prisma findMany arguments (where, orderBy, take, skip, etc.)
1647
+ * @returns Promise resolving to an array of records
1648
+ *
1649
+ * @example
1650
+ * ```typescript
1651
+ * // Find all products
1652
+ * const products = await productRepository.findMany();
1653
+ *
1654
+ * // Find with filtering and pagination
1655
+ * const products = await productRepository.findMany({
1656
+ * where: { status: 'ACTIVE' },
1657
+ * orderBy: { createdAt: 'desc' },
1658
+ * take: 10,
1659
+ * skip: 0
1660
+ * });
1661
+ * ```
1662
+ */
1663
+ async findMany(args) {
1664
+ this.logger.debug("Finding multiple records");
1665
+ return await this.model.findMany(args);
1666
+ }
1667
+ /**
1668
+ * Update a record by ID
1669
+ *
1670
+ * @param id - The record ID
1671
+ * @param data - The data to update
1672
+ * @returns Promise resolving to the updated record
1673
+ *
1674
+ * @example
1675
+ * ```typescript
1676
+ * const product = await productRepository.update('product-id-123', {
1677
+ * price: 12.99
1678
+ * });
1679
+ * ```
1680
+ */
1681
+ async update(id, data) {
1682
+ this.logger.log(`Updating record with ID: ${id}`);
1683
+ return await this.model.update({
1684
+ where: {
1685
+ id
1686
+ },
1687
+ data
1688
+ });
1689
+ }
1690
+ /**
1691
+ * Update multiple records
1692
+ *
1693
+ * @param where - The where clause to match records
1694
+ * @param data - The data to update
1695
+ * @returns Promise resolving to the count of updated records
1696
+ *
1697
+ * @example
1698
+ * ```typescript
1699
+ * const result = await productRepository.updateMany(
1700
+ * { status: 'PENDING' },
1701
+ * { status: 'ACTIVE' }
1702
+ * );
1703
+ * console.log(`Updated ${result.count} products`);
1704
+ * ```
1705
+ */
1706
+ async updateMany(where, data) {
1707
+ this.logger.log("Updating multiple records");
1708
+ return await this.model.updateMany({
1709
+ where,
1710
+ data
1711
+ });
1712
+ }
1713
+ /**
1714
+ * Delete a record by ID
1715
+ *
1716
+ * @param id - The record ID
1717
+ * @returns Promise resolving to the deleted record
1718
+ *
1719
+ * @example
1720
+ * ```typescript
1721
+ * const product = await productRepository.delete('product-id-123');
1722
+ * ```
1723
+ */
1724
+ async delete(id) {
1725
+ this.logger.log(`Deleting record with ID: ${id}`);
1726
+ return await this.model.delete({
1727
+ where: {
1728
+ id
1729
+ }
1730
+ });
1731
+ }
1732
+ /**
1733
+ * Delete multiple records
1734
+ *
1735
+ * @param where - The where clause to match records
1736
+ * @returns Promise resolving to the count of deleted records
1737
+ *
1738
+ * @example
1739
+ * ```typescript
1740
+ * const result = await productRepository.deleteMany({
1741
+ * status: 'INACTIVE',
1742
+ * createdAt: { lt: new Date('2020-01-01') }
1743
+ * });
1744
+ * console.log(`Deleted ${result.count} products`);
1745
+ * ```
1746
+ */
1747
+ async deleteMany(where) {
1748
+ this.logger.log("Deleting multiple records");
1749
+ return await this.model.deleteMany({
1750
+ where
1751
+ });
1752
+ }
1753
+ /**
1754
+ * Count records
1755
+ *
1756
+ * @param where - Optional where clause to filter records
1757
+ * @returns Promise resolving to the count of records
1758
+ *
1759
+ * @example
1760
+ * ```typescript
1761
+ * // Count all products
1762
+ * const total = await productRepository.count();
1763
+ *
1764
+ * // Count active products
1765
+ * const activeCount = await productRepository.count({ status: 'ACTIVE' });
1766
+ * ```
1767
+ */
1768
+ async count(where) {
1769
+ this.logger.debug("Counting records");
1770
+ return await this.model.count({
1771
+ where
1772
+ });
1773
+ }
1774
+ /**
1775
+ * Check if a record exists
1776
+ *
1777
+ * @param where - The where clause to match records
1778
+ * @returns Promise resolving to true if at least one record exists, false otherwise
1779
+ *
1780
+ * @example
1781
+ * ```typescript
1782
+ * const skuExists = await productRepository.exists({
1783
+ * sku: 'WDG-001'
1784
+ * });
1785
+ * ```
1786
+ */
1787
+ async exists(where) {
1788
+ const count = await this.model.count({
1789
+ where
1790
+ });
1791
+ return count > 0;
1792
+ }
1793
+ };
1794
+
1795
+ // src/database/decorators/tenant.decorator.ts
1796
+ var import_common13 = require("@nestjs/common");
1797
+ var Tenant = (0, import_common13.createParamDecorator)((data, ctx) => {
1244
1798
  const request = ctx.switchToHttp().getRequest();
1245
1799
  const tenantContext = request.app?.get?.(TenantContextService);
1246
1800
  if (!tenantContext) {
@@ -1250,20 +1804,239 @@ var Tenant = (0, import_common11.createParamDecorator)((data, ctx) => {
1250
1804
  });
1251
1805
 
1252
1806
  // src/auth/decorators/onboarding.decorator.ts
1253
- var import_common12 = require("@nestjs/common");
1254
- var Onboarding = /* @__PURE__ */ __name(() => (0, import_common12.SetMetadata)("isOnboarding", true), "Onboarding");
1807
+ var import_common14 = require("@nestjs/common");
1808
+ var Onboarding = /* @__PURE__ */ __name(() => (0, import_common14.SetMetadata)("isOnboarding", true), "Onboarding");
1255
1809
 
1256
1810
  // src/auth/decorators/public.decorator.ts
1257
- var import_common13 = require("@nestjs/common");
1258
- var Public = /* @__PURE__ */ __name(() => (0, import_common13.SetMetadata)("isPublic", true), "Public");
1811
+ var import_common15 = require("@nestjs/common");
1812
+ var Public = /* @__PURE__ */ __name(() => (0, import_common15.SetMetadata)("isPublic", true), "Public");
1813
+
1814
+ // src/http/http.module.ts
1815
+ var import_common17 = require("@nestjs/common");
1816
+
1817
+ // src/http/guards/csrf.guard.ts
1818
+ var import_common16 = require("@nestjs/common");
1819
+ var import_core5 = require("@nestjs/core");
1820
+ function _ts_decorate11(decorators, target, key, desc) {
1821
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1822
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1823
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1824
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1825
+ }
1826
+ __name(_ts_decorate11, "_ts_decorate");
1827
+ function _ts_metadata7(k, v) {
1828
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1829
+ }
1830
+ __name(_ts_metadata7, "_ts_metadata");
1831
+ var CsrfGuard = class _CsrfGuard {
1832
+ static {
1833
+ __name(this, "CsrfGuard");
1834
+ }
1835
+ reflector;
1836
+ logger = new import_common16.Logger(_CsrfGuard.name);
1837
+ constructor(reflector) {
1838
+ this.reflector = reflector;
1839
+ }
1840
+ async canActivate(context) {
1841
+ const request = context.switchToHttp().getRequest();
1842
+ const reply = context.switchToHttp().getResponse();
1843
+ const safeMethods = [
1844
+ "GET",
1845
+ "HEAD",
1846
+ "OPTIONS"
1847
+ ];
1848
+ if (safeMethods.includes(request.method)) {
1849
+ return true;
1850
+ }
1851
+ try {
1852
+ const fastifyInstance = request.server;
1853
+ if (!fastifyInstance.csrfProtection) {
1854
+ this.logger.error("CSRF protection plugin not found. Ensure @fastify/csrf-protection is registered.");
1855
+ throw new import_common16.ForbiddenException("CSRF protection not configured");
1856
+ }
1857
+ await new Promise((resolve, reject) => {
1858
+ fastifyInstance.csrfProtection(request, reply, (err) => {
1859
+ if (err) {
1860
+ reject(err);
1861
+ } else {
1862
+ resolve();
1863
+ }
1864
+ });
1865
+ });
1866
+ this.logger.debug(`CSRF validation successful for ${request.method} ${request.url}`);
1867
+ return true;
1868
+ } catch (error) {
1869
+ this.logger.warn(`CSRF validation failed for ${request.method} ${request.url}: ${error instanceof Error ? error.message : "Unknown error"}`);
1870
+ throw new import_common16.ForbiddenException({
1871
+ errors: [
1872
+ {
1873
+ field: "csrf",
1874
+ message: "Invalid or missing CSRF token"
1875
+ }
1876
+ ],
1877
+ message: "CSRF validation failed"
1878
+ });
1879
+ }
1880
+ }
1881
+ };
1882
+ CsrfGuard = _ts_decorate11([
1883
+ (0, import_common16.Injectable)(),
1884
+ _ts_metadata7("design:type", Function),
1885
+ _ts_metadata7("design:paramtypes", [
1886
+ typeof import_core5.Reflector === "undefined" ? Object : import_core5.Reflector
1887
+ ])
1888
+ ], CsrfGuard);
1889
+
1890
+ // src/http/http.module.ts
1891
+ function _ts_decorate12(decorators, target, key, desc) {
1892
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1893
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1894
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1895
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1896
+ }
1897
+ __name(_ts_decorate12, "_ts_decorate");
1898
+ var HttpModule = class {
1899
+ static {
1900
+ __name(this, "HttpModule");
1901
+ }
1902
+ };
1903
+ HttpModule = _ts_decorate12([
1904
+ (0, import_common17.Module)({
1905
+ providers: [
1906
+ CsrfGuard
1907
+ ],
1908
+ exports: [
1909
+ CsrfGuard
1910
+ ]
1911
+ })
1912
+ ], HttpModule);
1913
+
1914
+ // src/http/filters/http-exception.filter.ts
1915
+ var import_common18 = require("@nestjs/common");
1916
+ function _ts_decorate13(decorators, target, key, desc) {
1917
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1918
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1919
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1920
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1921
+ }
1922
+ __name(_ts_decorate13, "_ts_decorate");
1923
+ var HttpExceptionFilter = class _HttpExceptionFilter {
1924
+ static {
1925
+ __name(this, "HttpExceptionFilter");
1926
+ }
1927
+ logger = new import_common18.Logger(_HttpExceptionFilter.name);
1928
+ catch(exception, host) {
1929
+ const ctx = host.switchToHttp();
1930
+ const reply = ctx.getResponse();
1931
+ const request = ctx.getRequest();
1932
+ let status = import_common18.HttpStatus.INTERNAL_SERVER_ERROR;
1933
+ let errors = [];
1934
+ let message;
1935
+ if (exception instanceof import_common18.HttpException) {
1936
+ status = exception.getStatus();
1937
+ const exceptionResponse = exception.getResponse();
1938
+ if (typeof exceptionResponse === "object" && exceptionResponse !== null) {
1939
+ const responseObj = exceptionResponse;
1940
+ if (Array.isArray(responseObj.message)) {
1941
+ errors = this.parseValidationErrors(responseObj.message);
1942
+ message = "Validation failed";
1943
+ } else if (responseObj.message) {
1944
+ errors = [
1945
+ {
1946
+ field: "general",
1947
+ message: responseObj.message
1948
+ }
1949
+ ];
1950
+ message = responseObj.message;
1951
+ }
1952
+ } else if (typeof exceptionResponse === "string") {
1953
+ errors = [
1954
+ {
1955
+ field: "general",
1956
+ message: exceptionResponse
1957
+ }
1958
+ ];
1959
+ message = exceptionResponse;
1960
+ }
1961
+ } else if (exception instanceof Error) {
1962
+ this.logger.error(`Unhandled error: ${exception.message}`, exception.stack);
1963
+ errors = [
1964
+ {
1965
+ field: "general",
1966
+ message: "Internal server error"
1967
+ }
1968
+ ];
1969
+ message = "An unexpected error occurred";
1970
+ } else {
1971
+ this.logger.error("Unknown exception type", exception);
1972
+ errors = [
1973
+ {
1974
+ field: "general",
1975
+ message: "Internal server error"
1976
+ }
1977
+ ];
1978
+ message = "An unexpected error occurred";
1979
+ }
1980
+ const errorResponse = {
1981
+ errors,
1982
+ message,
1983
+ statusCode: status,
1984
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1985
+ path: request.url
1986
+ };
1987
+ if (status >= 500) {
1988
+ this.logger.error(`HTTP ${status} Error: ${JSON.stringify(errorResponse)}`, exception instanceof Error ? exception.stack : void 0);
1989
+ } else {
1990
+ this.logger.warn(`HTTP ${status} Error: ${JSON.stringify(errorResponse)}`);
1991
+ }
1992
+ reply.status(status).send(errorResponse);
1993
+ }
1994
+ /**
1995
+ * Parse class-validator error messages into field-specific errors
1996
+ */
1997
+ parseValidationErrors(messages) {
1998
+ const errors = [];
1999
+ for (const msg of messages) {
2000
+ if (typeof msg === "string") {
2001
+ errors.push({
2002
+ field: "general",
2003
+ message: msg
2004
+ });
2005
+ } else if (typeof msg === "object" && msg.property && msg.constraints) {
2006
+ const field = msg.property;
2007
+ const constraintMessages = Object.values(msg.constraints);
2008
+ for (const constraintMsg of constraintMessages) {
2009
+ errors.push({
2010
+ field,
2011
+ message: constraintMsg
2012
+ });
2013
+ }
2014
+ }
2015
+ }
2016
+ return errors.length > 0 ? errors : [
2017
+ {
2018
+ field: "general",
2019
+ message: "Validation failed"
2020
+ }
2021
+ ];
2022
+ }
2023
+ };
2024
+ HttpExceptionFilter = _ts_decorate13([
2025
+ (0, import_common18.Catch)()
2026
+ ], HttpExceptionFilter);
1259
2027
  // Annotate the CommonJS export names for ESM import in node:
1260
2028
  0 && (module.exports = {
1261
2029
  AuthConfigModule,
2030
+ CsrfGuard,
1262
2031
  DatabaseModule,
2032
+ HttpExceptionFilter,
2033
+ HttpModule,
1263
2034
  Onboarding,
2035
+ PrimaryBaseRepository,
1264
2036
  PrimaryDatabaseService,
1265
2037
  Public,
1266
2038
  Tenant,
2039
+ TenantBaseRepository,
1267
2040
  TenantContextService,
1268
2041
  TenantDatabaseService,
1269
2042
  VrittiAuthGuard