@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/README.md +113 -0
- package/dist/index.cjs +786 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +579 -7
- package/dist/index.d.ts +579 -7
- package/dist/index.js +775 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _nestjs_common from '@nestjs/common';
|
|
2
|
-
import { DynamicModule, OnModuleDestroy, OnModuleInit, CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { DynamicModule, OnModuleDestroy, OnModuleInit, Logger, CanActivate, ExecutionContext, ExceptionFilter, ArgumentsHost } from '@nestjs/common';
|
|
3
3
|
import { ConfigService } from '@nestjs/config';
|
|
4
4
|
import { Reflector } from '@nestjs/core';
|
|
5
5
|
import { JwtService } from '@nestjs/jwt';
|
|
@@ -376,6 +376,15 @@ declare class TenantDatabaseService implements OnModuleDestroy {
|
|
|
376
376
|
/** Cleanup interval timer */
|
|
377
377
|
private cleanupInterval?;
|
|
378
378
|
constructor(options: DatabaseModuleOptions, tenantContext: TenantContextService);
|
|
379
|
+
/**
|
|
380
|
+
* Get the Prisma client for the current tenant's database.
|
|
381
|
+
* This returns the tenant-scoped database client.
|
|
382
|
+
*
|
|
383
|
+
* @returns Tenant-scoped database client instance
|
|
384
|
+
* @throws UnauthorizedException if tenant context not set
|
|
385
|
+
* @throws InternalServerErrorException if connection fails
|
|
386
|
+
*/
|
|
387
|
+
get prismaClient(): any;
|
|
379
388
|
/**
|
|
380
389
|
* Get tenant-scoped database client for the current request/message
|
|
381
390
|
*
|
|
@@ -392,7 +401,7 @@ declare class TenantDatabaseService implements OnModuleDestroy {
|
|
|
392
401
|
* const dbClient = await tenantDatabase.getDbClient<PrismaClient>();
|
|
393
402
|
* const users = await dbClient.user.findMany();
|
|
394
403
|
*/
|
|
395
|
-
getDbClient
|
|
404
|
+
private getDbClient;
|
|
396
405
|
/**
|
|
397
406
|
* Create a new database client for the given tenant
|
|
398
407
|
*/
|
|
@@ -488,14 +497,13 @@ declare class PrimaryDatabaseService implements OnModuleInit, OnModuleDestroy {
|
|
|
488
497
|
*/
|
|
489
498
|
clearAllCaches(): void;
|
|
490
499
|
/**
|
|
491
|
-
* Get
|
|
492
|
-
*
|
|
493
|
-
* This is useful for platform admin operations (creating tenants, billing, etc.)
|
|
500
|
+
* Get the Prisma client for the primary database.
|
|
501
|
+
* This is a synchronous property that returns the initialized Prisma client.
|
|
494
502
|
*
|
|
495
503
|
* @returns Primary database client instance
|
|
496
504
|
* @throws Error if primary database client is not initialized
|
|
497
505
|
*/
|
|
498
|
-
|
|
506
|
+
get prismaClient(): any;
|
|
499
507
|
/**
|
|
500
508
|
* Decrypt database credentials
|
|
501
509
|
*
|
|
@@ -508,6 +516,503 @@ declare class PrimaryDatabaseService implements OnModuleInit, OnModuleDestroy {
|
|
|
508
516
|
onModuleDestroy(): Promise<void>;
|
|
509
517
|
}
|
|
510
518
|
|
|
519
|
+
/**
|
|
520
|
+
* Abstract base repository for primary database operations.
|
|
521
|
+
* Provides common CRUD operations with automatic logging.
|
|
522
|
+
*
|
|
523
|
+
* @template TModel - The Prisma model type
|
|
524
|
+
* @template TCreateDTO - DTO type for create operations
|
|
525
|
+
* @template TUpdateDTO - DTO type for update operations
|
|
526
|
+
*
|
|
527
|
+
* @example
|
|
528
|
+
* ```typescript
|
|
529
|
+
* // Using the model delegate pattern (RECOMMENDED)
|
|
530
|
+
* // Type-safe, IDE autocomplete, refactor-friendly
|
|
531
|
+
* @Injectable()
|
|
532
|
+
* export class UserRepository extends PrimaryBaseRepository<
|
|
533
|
+
* User,
|
|
534
|
+
* CreateUserDto,
|
|
535
|
+
* UpdateUserDto
|
|
536
|
+
* > {
|
|
537
|
+
* constructor(database: PrimaryDatabaseService) {
|
|
538
|
+
* super(database, (prisma) => prisma.user); // ✅ Type-safe with autocomplete!
|
|
539
|
+
* }
|
|
540
|
+
*
|
|
541
|
+
* // Add custom methods as needed
|
|
542
|
+
* async findByEmail(email: string): Promise<User | null> {
|
|
543
|
+
* return this.model.findUnique({ where: { email } });
|
|
544
|
+
* }
|
|
545
|
+
* }
|
|
546
|
+
*
|
|
547
|
+
* // Short syntax is also supported
|
|
548
|
+
* @Injectable()
|
|
549
|
+
* export class TenantRepository extends PrimaryBaseRepository<Tenant> {
|
|
550
|
+
* constructor(database: PrimaryDatabaseService) {
|
|
551
|
+
* super(database, (p) => p.tenant); // ✅ Concise!
|
|
552
|
+
* }
|
|
553
|
+
* }
|
|
554
|
+
*
|
|
555
|
+
* // Works with complex model names
|
|
556
|
+
* @Injectable()
|
|
557
|
+
* export class EmailVerificationRepository extends PrimaryBaseRepository<EmailVerification> {
|
|
558
|
+
* constructor(database: PrimaryDatabaseService) {
|
|
559
|
+
* super(database, (p) => p.emailVerification); // ✅ Matches Prisma naming
|
|
560
|
+
* }
|
|
561
|
+
* }
|
|
562
|
+
* ```
|
|
563
|
+
*/
|
|
564
|
+
declare abstract class PrimaryBaseRepository<TModel, TCreateDTO = any, TUpdateDTO = any> {
|
|
565
|
+
protected readonly database: PrimaryDatabaseService;
|
|
566
|
+
protected readonly logger: Logger;
|
|
567
|
+
private readonly modelGetter;
|
|
568
|
+
/**
|
|
569
|
+
* Lazy getter for Prisma client.
|
|
570
|
+
* Accesses the client from the database service only when needed,
|
|
571
|
+
* avoiding initialization timing issues with NestJS lifecycle.
|
|
572
|
+
*/
|
|
573
|
+
protected get prisma(): any;
|
|
574
|
+
/**
|
|
575
|
+
* Lazy getter for the Prisma model delegate.
|
|
576
|
+
* Returns the specific model (e.g., prisma.user, prisma.tenant) for this repository.
|
|
577
|
+
*/
|
|
578
|
+
protected get model(): any;
|
|
579
|
+
/**
|
|
580
|
+
* Create a new repository instance
|
|
581
|
+
*
|
|
582
|
+
* @param database - The primary database service
|
|
583
|
+
* @param getModel - Function that returns the Prisma model delegate from the client
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* ```typescript
|
|
587
|
+
* // Standard usage with full parameter name
|
|
588
|
+
* constructor(database: PrimaryDatabaseService) {
|
|
589
|
+
* super(database, (prisma) => prisma.user);
|
|
590
|
+
* }
|
|
591
|
+
*
|
|
592
|
+
* // Short syntax
|
|
593
|
+
* constructor(database: PrimaryDatabaseService) {
|
|
594
|
+
* super(database, (p) => p.user);
|
|
595
|
+
* }
|
|
596
|
+
*
|
|
597
|
+
* // Complex model names
|
|
598
|
+
* constructor(database: PrimaryDatabaseService) {
|
|
599
|
+
* super(database, (p) => p.emailVerification);
|
|
600
|
+
* }
|
|
601
|
+
* ```
|
|
602
|
+
*/
|
|
603
|
+
constructor(database: PrimaryDatabaseService, getModel: (prisma: any) => any);
|
|
604
|
+
/**
|
|
605
|
+
* Create a new record
|
|
606
|
+
*
|
|
607
|
+
* @param data - The data to create the record with
|
|
608
|
+
* @returns Promise resolving to the created record
|
|
609
|
+
*
|
|
610
|
+
* @example
|
|
611
|
+
* ```typescript
|
|
612
|
+
* const user = await userRepository.create({
|
|
613
|
+
* email: 'user@example.com',
|
|
614
|
+
* name: 'John Doe'
|
|
615
|
+
* });
|
|
616
|
+
* ```
|
|
617
|
+
*/
|
|
618
|
+
create(data: TCreateDTO): Promise<TModel>;
|
|
619
|
+
/**
|
|
620
|
+
* Find a single record by ID
|
|
621
|
+
*
|
|
622
|
+
* @param id - The record ID
|
|
623
|
+
* @returns Promise resolving to the record or null if not found
|
|
624
|
+
*
|
|
625
|
+
* @example
|
|
626
|
+
* ```typescript
|
|
627
|
+
* const user = await userRepository.findById('user-id-123');
|
|
628
|
+
* ```
|
|
629
|
+
*/
|
|
630
|
+
findById(id: string): Promise<TModel | null>;
|
|
631
|
+
/**
|
|
632
|
+
* Find a single record with custom where clause
|
|
633
|
+
*
|
|
634
|
+
* @param where - The where clause or findUnique args
|
|
635
|
+
* @returns Promise resolving to the record or null if not found
|
|
636
|
+
*
|
|
637
|
+
* @example
|
|
638
|
+
* ```typescript
|
|
639
|
+
* // Simple where clause
|
|
640
|
+
* const user = await userRepository.findOne({ email: 'user@example.com' });
|
|
641
|
+
*
|
|
642
|
+
* // With include
|
|
643
|
+
* const user = await userRepository.findOne({
|
|
644
|
+
* where: { email: 'user@example.com' },
|
|
645
|
+
* include: { posts: true }
|
|
646
|
+
* });
|
|
647
|
+
* ```
|
|
648
|
+
*/
|
|
649
|
+
findOne(where: any): Promise<TModel | null>;
|
|
650
|
+
/**
|
|
651
|
+
* Find multiple records
|
|
652
|
+
*
|
|
653
|
+
* @param args - Prisma findMany arguments (where, orderBy, take, skip, etc.)
|
|
654
|
+
* @returns Promise resolving to an array of records
|
|
655
|
+
*
|
|
656
|
+
* @example
|
|
657
|
+
* ```typescript
|
|
658
|
+
* // Find all users
|
|
659
|
+
* const users = await userRepository.findMany();
|
|
660
|
+
*
|
|
661
|
+
* // Find with filtering and pagination
|
|
662
|
+
* const users = await userRepository.findMany({
|
|
663
|
+
* where: { status: 'ACTIVE' },
|
|
664
|
+
* orderBy: { createdAt: 'desc' },
|
|
665
|
+
* take: 10,
|
|
666
|
+
* skip: 0
|
|
667
|
+
* });
|
|
668
|
+
* ```
|
|
669
|
+
*/
|
|
670
|
+
findMany(args?: any): Promise<TModel[]>;
|
|
671
|
+
/**
|
|
672
|
+
* Update a record by ID
|
|
673
|
+
*
|
|
674
|
+
* @param id - The record ID
|
|
675
|
+
* @param data - The data to update
|
|
676
|
+
* @returns Promise resolving to the updated record
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```typescript
|
|
680
|
+
* const user = await userRepository.update('user-id-123', {
|
|
681
|
+
* name: 'Jane Doe'
|
|
682
|
+
* });
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
685
|
+
update(id: string, data: TUpdateDTO): Promise<TModel>;
|
|
686
|
+
/**
|
|
687
|
+
* Update multiple records
|
|
688
|
+
*
|
|
689
|
+
* @param where - The where clause to match records
|
|
690
|
+
* @param data - The data to update
|
|
691
|
+
* @returns Promise resolving to the count of updated records
|
|
692
|
+
*
|
|
693
|
+
* @example
|
|
694
|
+
* ```typescript
|
|
695
|
+
* const result = await userRepository.updateMany(
|
|
696
|
+
* { status: 'PENDING' },
|
|
697
|
+
* { status: 'ACTIVE' }
|
|
698
|
+
* );
|
|
699
|
+
* console.log(`Updated ${result.count} users`);
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
updateMany(where: any, data: TUpdateDTO): Promise<{
|
|
703
|
+
count: number;
|
|
704
|
+
}>;
|
|
705
|
+
/**
|
|
706
|
+
* Delete a record by ID
|
|
707
|
+
*
|
|
708
|
+
* @param id - The record ID
|
|
709
|
+
* @returns Promise resolving to the deleted record
|
|
710
|
+
*
|
|
711
|
+
* @example
|
|
712
|
+
* ```typescript
|
|
713
|
+
* const user = await userRepository.delete('user-id-123');
|
|
714
|
+
* ```
|
|
715
|
+
*/
|
|
716
|
+
delete(id: string): Promise<TModel>;
|
|
717
|
+
/**
|
|
718
|
+
* Delete multiple records
|
|
719
|
+
*
|
|
720
|
+
* @param where - The where clause to match records
|
|
721
|
+
* @returns Promise resolving to the count of deleted records
|
|
722
|
+
*
|
|
723
|
+
* @example
|
|
724
|
+
* ```typescript
|
|
725
|
+
* const result = await userRepository.deleteMany({
|
|
726
|
+
* status: 'INACTIVE',
|
|
727
|
+
* createdAt: { lt: new Date('2020-01-01') }
|
|
728
|
+
* });
|
|
729
|
+
* console.log(`Deleted ${result.count} users`);
|
|
730
|
+
* ```
|
|
731
|
+
*/
|
|
732
|
+
deleteMany(where: any): Promise<{
|
|
733
|
+
count: number;
|
|
734
|
+
}>;
|
|
735
|
+
/**
|
|
736
|
+
* Count records
|
|
737
|
+
*
|
|
738
|
+
* @param where - Optional where clause to filter records
|
|
739
|
+
* @returns Promise resolving to the count of records
|
|
740
|
+
*
|
|
741
|
+
* @example
|
|
742
|
+
* ```typescript
|
|
743
|
+
* // Count all users
|
|
744
|
+
* const total = await userRepository.count();
|
|
745
|
+
*
|
|
746
|
+
* // Count active users
|
|
747
|
+
* const activeCount = await userRepository.count({ status: 'ACTIVE' });
|
|
748
|
+
* ```
|
|
749
|
+
*/
|
|
750
|
+
count(where?: any): Promise<number>;
|
|
751
|
+
/**
|
|
752
|
+
* Check if a record exists
|
|
753
|
+
*
|
|
754
|
+
* @param where - The where clause to match records
|
|
755
|
+
* @returns Promise resolving to true if at least one record exists, false otherwise
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* ```typescript
|
|
759
|
+
* const emailExists = await userRepository.exists({
|
|
760
|
+
* email: 'user@example.com'
|
|
761
|
+
* });
|
|
762
|
+
* ```
|
|
763
|
+
*/
|
|
764
|
+
exists(where: any): Promise<boolean>;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Abstract base repository for tenant-scoped database operations.
|
|
769
|
+
* All operations are automatically scoped to the current tenant.
|
|
770
|
+
*
|
|
771
|
+
* @template TModel - The Prisma model type
|
|
772
|
+
* @template TCreateDTO - DTO type for create operations
|
|
773
|
+
* @template TUpdateDTO - DTO type for update operations
|
|
774
|
+
*
|
|
775
|
+
* @example
|
|
776
|
+
* ```typescript
|
|
777
|
+
* // Using the model delegate pattern (RECOMMENDED)
|
|
778
|
+
* // Type-safe, IDE autocomplete, refactor-friendly
|
|
779
|
+
* @Injectable()
|
|
780
|
+
* export class ProductRepository extends TenantBaseRepository<
|
|
781
|
+
* Product,
|
|
782
|
+
* CreateProductDto,
|
|
783
|
+
* UpdateProductDto
|
|
784
|
+
* > {
|
|
785
|
+
* constructor(database: TenantDatabaseService) {
|
|
786
|
+
* super(database, (prisma) => prisma.product); // ✅ Type-safe with autocomplete!
|
|
787
|
+
* }
|
|
788
|
+
*
|
|
789
|
+
* // Add custom methods as needed
|
|
790
|
+
* async findBySku(sku: string): Promise<Product | null> {
|
|
791
|
+
* return this.model.findUnique({ where: { sku } });
|
|
792
|
+
* }
|
|
793
|
+
* }
|
|
794
|
+
*
|
|
795
|
+
* // Short syntax is also supported
|
|
796
|
+
* @Injectable()
|
|
797
|
+
* export class OrderRepository extends TenantBaseRepository<Order> {
|
|
798
|
+
* constructor(database: TenantDatabaseService) {
|
|
799
|
+
* super(database, (p) => p.order); // ✅ Concise!
|
|
800
|
+
* }
|
|
801
|
+
* }
|
|
802
|
+
*
|
|
803
|
+
* // Works with complex model names
|
|
804
|
+
* @Injectable()
|
|
805
|
+
* export class InventoryItemRepository extends TenantBaseRepository<InventoryItem> {
|
|
806
|
+
* constructor(database: TenantDatabaseService) {
|
|
807
|
+
* super(database, (p) => p.inventoryItem); // ✅ Matches Prisma naming
|
|
808
|
+
* }
|
|
809
|
+
* }
|
|
810
|
+
* ```
|
|
811
|
+
*/
|
|
812
|
+
declare abstract class TenantBaseRepository<TModel, TCreateDTO = any, TUpdateDTO = any> {
|
|
813
|
+
protected readonly database: TenantDatabaseService;
|
|
814
|
+
protected readonly logger: Logger;
|
|
815
|
+
private readonly modelGetter;
|
|
816
|
+
/**
|
|
817
|
+
* Lazy getter for Prisma client.
|
|
818
|
+
* Accesses the client from the database service only when needed,
|
|
819
|
+
* avoiding initialization timing issues with NestJS lifecycle.
|
|
820
|
+
*/
|
|
821
|
+
protected get prisma(): any;
|
|
822
|
+
/**
|
|
823
|
+
* Lazy getter for the Prisma model delegate.
|
|
824
|
+
* Returns the specific model (e.g., prisma.product, prisma.order) for this repository.
|
|
825
|
+
*/
|
|
826
|
+
protected get model(): any;
|
|
827
|
+
/**
|
|
828
|
+
* Create a new repository instance
|
|
829
|
+
*
|
|
830
|
+
* @param database - The tenant database service
|
|
831
|
+
* @param getModel - Function that returns the Prisma model delegate from the client
|
|
832
|
+
*
|
|
833
|
+
* @example
|
|
834
|
+
* ```typescript
|
|
835
|
+
* // Standard usage with full parameter name
|
|
836
|
+
* constructor(database: TenantDatabaseService) {
|
|
837
|
+
* super(database, (prisma) => prisma.product);
|
|
838
|
+
* }
|
|
839
|
+
*
|
|
840
|
+
* // Short syntax
|
|
841
|
+
* constructor(database: TenantDatabaseService) {
|
|
842
|
+
* super(database, (p) => p.product);
|
|
843
|
+
* }
|
|
844
|
+
*
|
|
845
|
+
* // Complex model names
|
|
846
|
+
* constructor(database: TenantDatabaseService) {
|
|
847
|
+
* super(database, (p) => p.inventoryItem);
|
|
848
|
+
* }
|
|
849
|
+
* ```
|
|
850
|
+
*/
|
|
851
|
+
constructor(database: TenantDatabaseService, getModel: (prisma: any) => any);
|
|
852
|
+
/**
|
|
853
|
+
* Create a new record
|
|
854
|
+
*
|
|
855
|
+
* @param data - The data to create the record with
|
|
856
|
+
* @returns Promise resolving to the created record
|
|
857
|
+
*
|
|
858
|
+
* @example
|
|
859
|
+
* ```typescript
|
|
860
|
+
* const product = await productRepository.create({
|
|
861
|
+
* name: 'Widget',
|
|
862
|
+
* sku: 'WDG-001',
|
|
863
|
+
* price: 9.99
|
|
864
|
+
* });
|
|
865
|
+
* ```
|
|
866
|
+
*/
|
|
867
|
+
create(data: TCreateDTO): Promise<TModel>;
|
|
868
|
+
/**
|
|
869
|
+
* Find a single record by ID
|
|
870
|
+
*
|
|
871
|
+
* @param id - The record ID
|
|
872
|
+
* @returns Promise resolving to the record or null if not found
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
875
|
+
* ```typescript
|
|
876
|
+
* const product = await productRepository.findById('product-id-123');
|
|
877
|
+
* ```
|
|
878
|
+
*/
|
|
879
|
+
findById(id: string): Promise<TModel | null>;
|
|
880
|
+
/**
|
|
881
|
+
* Find a single record with custom where clause
|
|
882
|
+
*
|
|
883
|
+
* @param where - The where clause or findUnique args
|
|
884
|
+
* @returns Promise resolving to the record or null if not found
|
|
885
|
+
*
|
|
886
|
+
* @example
|
|
887
|
+
* ```typescript
|
|
888
|
+
* // Simple where clause
|
|
889
|
+
* const product = await productRepository.findOne({ sku: 'WDG-001' });
|
|
890
|
+
*
|
|
891
|
+
* // With include
|
|
892
|
+
* const product = await productRepository.findOne({
|
|
893
|
+
* where: { sku: 'WDG-001' },
|
|
894
|
+
* include: { category: true }
|
|
895
|
+
* });
|
|
896
|
+
* ```
|
|
897
|
+
*/
|
|
898
|
+
findOne(where: any): Promise<TModel | null>;
|
|
899
|
+
/**
|
|
900
|
+
* Find multiple records
|
|
901
|
+
*
|
|
902
|
+
* @param args - Prisma findMany arguments (where, orderBy, take, skip, etc.)
|
|
903
|
+
* @returns Promise resolving to an array of records
|
|
904
|
+
*
|
|
905
|
+
* @example
|
|
906
|
+
* ```typescript
|
|
907
|
+
* // Find all products
|
|
908
|
+
* const products = await productRepository.findMany();
|
|
909
|
+
*
|
|
910
|
+
* // Find with filtering and pagination
|
|
911
|
+
* const products = await productRepository.findMany({
|
|
912
|
+
* where: { status: 'ACTIVE' },
|
|
913
|
+
* orderBy: { createdAt: 'desc' },
|
|
914
|
+
* take: 10,
|
|
915
|
+
* skip: 0
|
|
916
|
+
* });
|
|
917
|
+
* ```
|
|
918
|
+
*/
|
|
919
|
+
findMany(args?: any): Promise<TModel[]>;
|
|
920
|
+
/**
|
|
921
|
+
* Update a record by ID
|
|
922
|
+
*
|
|
923
|
+
* @param id - The record ID
|
|
924
|
+
* @param data - The data to update
|
|
925
|
+
* @returns Promise resolving to the updated record
|
|
926
|
+
*
|
|
927
|
+
* @example
|
|
928
|
+
* ```typescript
|
|
929
|
+
* const product = await productRepository.update('product-id-123', {
|
|
930
|
+
* price: 12.99
|
|
931
|
+
* });
|
|
932
|
+
* ```
|
|
933
|
+
*/
|
|
934
|
+
update(id: string, data: TUpdateDTO): Promise<TModel>;
|
|
935
|
+
/**
|
|
936
|
+
* Update multiple records
|
|
937
|
+
*
|
|
938
|
+
* @param where - The where clause to match records
|
|
939
|
+
* @param data - The data to update
|
|
940
|
+
* @returns Promise resolving to the count of updated records
|
|
941
|
+
*
|
|
942
|
+
* @example
|
|
943
|
+
* ```typescript
|
|
944
|
+
* const result = await productRepository.updateMany(
|
|
945
|
+
* { status: 'PENDING' },
|
|
946
|
+
* { status: 'ACTIVE' }
|
|
947
|
+
* );
|
|
948
|
+
* console.log(`Updated ${result.count} products`);
|
|
949
|
+
* ```
|
|
950
|
+
*/
|
|
951
|
+
updateMany(where: any, data: TUpdateDTO): Promise<{
|
|
952
|
+
count: number;
|
|
953
|
+
}>;
|
|
954
|
+
/**
|
|
955
|
+
* Delete a record by ID
|
|
956
|
+
*
|
|
957
|
+
* @param id - The record ID
|
|
958
|
+
* @returns Promise resolving to the deleted record
|
|
959
|
+
*
|
|
960
|
+
* @example
|
|
961
|
+
* ```typescript
|
|
962
|
+
* const product = await productRepository.delete('product-id-123');
|
|
963
|
+
* ```
|
|
964
|
+
*/
|
|
965
|
+
delete(id: string): Promise<TModel>;
|
|
966
|
+
/**
|
|
967
|
+
* Delete multiple records
|
|
968
|
+
*
|
|
969
|
+
* @param where - The where clause to match records
|
|
970
|
+
* @returns Promise resolving to the count of deleted records
|
|
971
|
+
*
|
|
972
|
+
* @example
|
|
973
|
+
* ```typescript
|
|
974
|
+
* const result = await productRepository.deleteMany({
|
|
975
|
+
* status: 'INACTIVE',
|
|
976
|
+
* createdAt: { lt: new Date('2020-01-01') }
|
|
977
|
+
* });
|
|
978
|
+
* console.log(`Deleted ${result.count} products`);
|
|
979
|
+
* ```
|
|
980
|
+
*/
|
|
981
|
+
deleteMany(where: any): Promise<{
|
|
982
|
+
count: number;
|
|
983
|
+
}>;
|
|
984
|
+
/**
|
|
985
|
+
* Count records
|
|
986
|
+
*
|
|
987
|
+
* @param where - Optional where clause to filter records
|
|
988
|
+
* @returns Promise resolving to the count of records
|
|
989
|
+
*
|
|
990
|
+
* @example
|
|
991
|
+
* ```typescript
|
|
992
|
+
* // Count all products
|
|
993
|
+
* const total = await productRepository.count();
|
|
994
|
+
*
|
|
995
|
+
* // Count active products
|
|
996
|
+
* const activeCount = await productRepository.count({ status: 'ACTIVE' });
|
|
997
|
+
* ```
|
|
998
|
+
*/
|
|
999
|
+
count(where?: any): Promise<number>;
|
|
1000
|
+
/**
|
|
1001
|
+
* Check if a record exists
|
|
1002
|
+
*
|
|
1003
|
+
* @param where - The where clause to match records
|
|
1004
|
+
* @returns Promise resolving to true if at least one record exists, false otherwise
|
|
1005
|
+
*
|
|
1006
|
+
* @example
|
|
1007
|
+
* ```typescript
|
|
1008
|
+
* const skuExists = await productRepository.exists({
|
|
1009
|
+
* sku: 'WDG-001'
|
|
1010
|
+
* });
|
|
1011
|
+
* ```
|
|
1012
|
+
*/
|
|
1013
|
+
exists(where: any): Promise<boolean>;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
511
1016
|
declare class RequestService {
|
|
512
1017
|
private readonly request;
|
|
513
1018
|
constructor(request: FastifyRequest);
|
|
@@ -753,4 +1258,71 @@ declare const Onboarding: () => _nestjs_common.CustomDecorator<string>;
|
|
|
753
1258
|
*/
|
|
754
1259
|
declare const Public: () => _nestjs_common.CustomDecorator<string>;
|
|
755
1260
|
|
|
756
|
-
|
|
1261
|
+
/**
|
|
1262
|
+
* HTTP Module
|
|
1263
|
+
*
|
|
1264
|
+
* Provides HTTP utilities including:
|
|
1265
|
+
* - CSRF Guard for request protection
|
|
1266
|
+
* - HTTP Exception Filter for standardized error responses
|
|
1267
|
+
*
|
|
1268
|
+
* Usage:
|
|
1269
|
+
* Import this module to access HTTP guards and filters.
|
|
1270
|
+
* Guards and filters are registered globally in the main application.
|
|
1271
|
+
*/
|
|
1272
|
+
declare class HttpModule {
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
/**
|
|
1276
|
+
* CSRF Guard
|
|
1277
|
+
*
|
|
1278
|
+
* Global guard that automatically protects all state-changing requests (POST, PUT, PATCH, DELETE)
|
|
1279
|
+
* from CSRF attacks using Fastify's csrf-protection plugin.
|
|
1280
|
+
*
|
|
1281
|
+
* Flow:
|
|
1282
|
+
* 1. Skip safe methods (GET, HEAD, OPTIONS)
|
|
1283
|
+
* 2. Skip endpoints marked with @Public()
|
|
1284
|
+
* 3. Validate CSRF token for all other requests
|
|
1285
|
+
*
|
|
1286
|
+
* Token Sources (in priority order by @fastify/csrf-protection):
|
|
1287
|
+
* 1. req.headers['csrf-token']
|
|
1288
|
+
* 2. req.headers['xsrf-token']
|
|
1289
|
+
* 3. req.headers['x-csrf-token']
|
|
1290
|
+
* 4. req.headers['x-xsrf-token']
|
|
1291
|
+
* 5. req.body._csrf
|
|
1292
|
+
*
|
|
1293
|
+
* This guard should be registered globally in main.ts after CSRF plugin registration.
|
|
1294
|
+
*/
|
|
1295
|
+
declare class CsrfGuard implements CanActivate {
|
|
1296
|
+
private reflector;
|
|
1297
|
+
private readonly logger;
|
|
1298
|
+
constructor(reflector: Reflector);
|
|
1299
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
/**
|
|
1303
|
+
* Global HTTP Exception Filter
|
|
1304
|
+
*
|
|
1305
|
+
* Standardizes all error responses in the format:
|
|
1306
|
+
* {
|
|
1307
|
+
* errors: [{ field: string, message: string }],
|
|
1308
|
+
* message?: string,
|
|
1309
|
+
* statusCode: number,
|
|
1310
|
+
* timestamp: string,
|
|
1311
|
+
* path: string
|
|
1312
|
+
* }
|
|
1313
|
+
*
|
|
1314
|
+
* Handles:
|
|
1315
|
+
* - Validation errors (class-validator) - Converts to field-specific errors
|
|
1316
|
+
* - HTTP exceptions - Maps to standardized format
|
|
1317
|
+
* - Unknown errors - Returns generic 500 error
|
|
1318
|
+
*/
|
|
1319
|
+
declare class HttpExceptionFilter implements ExceptionFilter {
|
|
1320
|
+
private readonly logger;
|
|
1321
|
+
catch(exception: unknown, host: ArgumentsHost): void;
|
|
1322
|
+
/**
|
|
1323
|
+
* Parse class-validator error messages into field-specific errors
|
|
1324
|
+
*/
|
|
1325
|
+
private parseValidationErrors;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
export { AuthConfigModule, CsrfGuard, DatabaseModule, type DatabaseModuleOptions, HttpExceptionFilter, HttpModule, Onboarding, PrimaryBaseRepository, PrimaryDatabaseService, type PrimaryDbConfig, Public, Tenant, TenantBaseRepository, TenantContextService, TenantDatabaseService, type TenantInfo, VrittiAuthGuard };
|