@digitaldefiance/node-express-suite 1.3.28 → 2.1.6

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 (216) hide show
  1. package/README.md +482 -2
  2. package/package.json +9 -6
  3. package/src/application-base.d.ts +12 -2
  4. package/src/application-base.d.ts.map +1 -1
  5. package/src/application-base.js +15 -0
  6. package/src/application-base.js.map +1 -1
  7. package/src/application.d.ts +3 -2
  8. package/src/application.d.ts.map +1 -1
  9. package/src/application.js +5 -0
  10. package/src/application.js.map +1 -1
  11. package/src/backup-code.d.ts.map +1 -1
  12. package/src/backup-code.js +1 -1
  13. package/src/backup-code.js.map +1 -1
  14. package/src/builders/application-builder.d.ts +34 -0
  15. package/src/builders/application-builder.d.ts.map +1 -0
  16. package/src/builders/application-builder.js +64 -0
  17. package/src/builders/application-builder.js.map +1 -0
  18. package/src/builders/index.d.ts +2 -0
  19. package/src/builders/index.d.ts.map +1 -0
  20. package/src/builders/index.js +5 -0
  21. package/src/builders/index.js.map +1 -0
  22. package/src/container/index.d.ts +3 -0
  23. package/src/container/index.d.ts.map +1 -0
  24. package/src/container/index.js +6 -0
  25. package/src/container/index.js.map +1 -0
  26. package/src/container/service-container.d.ts +11 -0
  27. package/src/container/service-container.d.ts.map +1 -0
  28. package/src/container/service-container.js +38 -0
  29. package/src/container/service-container.js.map +1 -0
  30. package/src/container/service-definitions.d.ts +11 -0
  31. package/src/container/service-definitions.d.ts.map +1 -0
  32. package/src/container/service-definitions.js +13 -0
  33. package/src/container/service-definitions.js.map +1 -0
  34. package/src/controllers/base.d.ts +8 -5
  35. package/src/controllers/base.d.ts.map +1 -1
  36. package/src/controllers/base.js +38 -8
  37. package/src/controllers/base.js.map +1 -1
  38. package/src/controllers/user.d.ts +3 -5
  39. package/src/controllers/user.d.ts.map +1 -1
  40. package/src/controllers/user.js +222 -196
  41. package/src/controllers/user.js.map +1 -1
  42. package/src/database/database-initializer.d.ts +7 -0
  43. package/src/database/database-initializer.d.ts.map +1 -0
  44. package/src/database/database-initializer.js +3 -0
  45. package/src/database/database-initializer.js.map +1 -0
  46. package/src/database/index.d.ts +2 -0
  47. package/src/database/index.d.ts.map +1 -0
  48. package/src/database/index.js +5 -0
  49. package/src/database/index.js.map +1 -0
  50. package/src/decorators/base-controller.d.ts +1 -5
  51. package/src/decorators/base-controller.d.ts.map +1 -1
  52. package/src/decorators/base-controller.js +8 -2
  53. package/src/decorators/base-controller.js.map +1 -1
  54. package/src/decorators/controller.d.ts +8 -2
  55. package/src/decorators/controller.d.ts.map +1 -1
  56. package/src/decorators/controller.js.map +1 -1
  57. package/src/documents/user.d.ts +1 -2
  58. package/src/documents/user.d.ts.map +1 -1
  59. package/src/environment.d.ts +1 -2
  60. package/src/environment.d.ts.map +1 -1
  61. package/src/environment.js +6 -6
  62. package/src/environment.js.map +1 -1
  63. package/src/errors/express-validation.d.ts +2 -2
  64. package/src/errors/express-validation.d.ts.map +1 -1
  65. package/src/errors/express-validation.js +1 -1
  66. package/src/errors/express-validation.js.map +1 -1
  67. package/src/errors/symmetric.d.ts +1 -1
  68. package/src/errors/symmetric.d.ts.map +1 -1
  69. package/src/errors/symmetric.js +1 -2
  70. package/src/errors/symmetric.js.map +1 -1
  71. package/src/get-timezone.d.ts +1 -2
  72. package/src/get-timezone.d.ts.map +1 -1
  73. package/src/get-timezone.js +15 -7
  74. package/src/get-timezone.js.map +1 -1
  75. package/src/index.d.ts +13 -1
  76. package/src/index.d.ts.map +1 -1
  77. package/src/index.js +14 -1
  78. package/src/index.js.map +1 -1
  79. package/src/interfaces/application.d.ts +8 -5
  80. package/src/interfaces/application.d.ts.map +1 -1
  81. package/src/interfaces/constants.d.ts +0 -1
  82. package/src/interfaces/constants.d.ts.map +1 -1
  83. package/src/interfaces/controller-config.d.ts +21 -0
  84. package/src/interfaces/controller-config.d.ts.map +1 -0
  85. package/src/interfaces/controller-config.js +3 -0
  86. package/src/interfaces/controller-config.js.map +1 -0
  87. package/src/interfaces/environment.d.ts +1 -2
  88. package/src/interfaces/environment.d.ts.map +1 -1
  89. package/src/interfaces/index.d.ts +1 -0
  90. package/src/interfaces/index.d.ts.map +1 -1
  91. package/src/interfaces/index.js +1 -0
  92. package/src/interfaces/index.js.map +1 -1
  93. package/src/middlewares/authenticate-crypto.d.ts +1 -5
  94. package/src/middlewares/authenticate-crypto.d.ts.map +1 -1
  95. package/src/middlewares/authenticate-crypto.js +2 -17
  96. package/src/middlewares/authenticate-crypto.js.map +1 -1
  97. package/src/middlewares/authenticate-token.d.ts +1 -4
  98. package/src/middlewares/authenticate-token.d.ts.map +1 -1
  99. package/src/middlewares/authenticate-token.js +8 -2
  100. package/src/middlewares/authenticate-token.js.map +1 -1
  101. package/src/middlewares.d.ts.map +1 -1
  102. package/src/middlewares.js +2 -1
  103. package/src/middlewares.js.map +1 -1
  104. package/src/pipeline/index.d.ts +2 -0
  105. package/src/pipeline/index.d.ts.map +1 -0
  106. package/src/pipeline/index.js +5 -0
  107. package/src/pipeline/index.js.map +1 -0
  108. package/src/pipeline/pipeline-builder.d.ts +8 -0
  109. package/src/pipeline/pipeline-builder.d.ts.map +1 -0
  110. package/src/pipeline/pipeline-builder.js +18 -0
  111. package/src/pipeline/pipeline-builder.js.map +1 -0
  112. package/src/plugins/index.d.ts +3 -0
  113. package/src/plugins/index.d.ts.map +1 -0
  114. package/src/plugins/index.js +6 -0
  115. package/src/plugins/index.js.map +1 -0
  116. package/src/plugins/plugin-interface.d.ts +8 -0
  117. package/src/plugins/plugin-interface.d.ts.map +1 -0
  118. package/src/plugins/plugin-interface.js +3 -0
  119. package/src/plugins/plugin-interface.js.map +1 -0
  120. package/src/plugins/plugin-manager.d.ts +12 -0
  121. package/src/plugins/plugin-manager.d.ts.map +1 -0
  122. package/src/plugins/plugin-manager.js +37 -0
  123. package/src/plugins/plugin-manager.js.map +1 -0
  124. package/src/responses/index.d.ts +2 -0
  125. package/src/responses/index.d.ts.map +1 -0
  126. package/src/responses/index.js +5 -0
  127. package/src/responses/index.js.map +1 -0
  128. package/src/responses/response-builder.d.ts +24 -0
  129. package/src/responses/response-builder.d.ts.map +1 -0
  130. package/src/responses/response-builder.js +62 -0
  131. package/src/responses/response-builder.js.map +1 -0
  132. package/src/routers/api.d.ts +2 -1
  133. package/src/routers/api.d.ts.map +1 -1
  134. package/src/routers/api.js +43 -15
  135. package/src/routers/api.js.map +1 -1
  136. package/src/routers/app.d.ts +1 -5
  137. package/src/routers/app.d.ts.map +1 -1
  138. package/src/routers/app.js +2 -2
  139. package/src/routers/app.js.map +1 -1
  140. package/src/routers/base.d.ts +1 -5
  141. package/src/routers/base.d.ts.map +1 -1
  142. package/src/routers/base.js.map +1 -1
  143. package/src/routers/router-config.d.ts +18 -0
  144. package/src/routers/router-config.d.ts.map +1 -0
  145. package/src/routers/router-config.js +8 -0
  146. package/src/routers/router-config.js.map +1 -0
  147. package/src/routing/index.d.ts +2 -0
  148. package/src/routing/index.d.ts.map +1 -0
  149. package/src/routing/index.js +5 -0
  150. package/src/routing/index.js.map +1 -0
  151. package/src/routing/route-builder.d.ts +36 -0
  152. package/src/routing/route-builder.d.ts.map +1 -0
  153. package/src/routing/route-builder.js +86 -0
  154. package/src/routing/route-builder.js.map +1 -0
  155. package/src/schemas/user.d.ts +1 -1
  156. package/src/schemas/user.d.ts.map +1 -1
  157. package/src/schemas/user.js +1 -1
  158. package/src/schemas/user.js.map +1 -1
  159. package/src/services/backup-code.d.ts +2 -4
  160. package/src/services/backup-code.d.ts.map +1 -1
  161. package/src/services/backup-code.js.map +1 -1
  162. package/src/services/base.d.ts +2 -5
  163. package/src/services/base.d.ts.map +1 -1
  164. package/src/services/base.js.map +1 -1
  165. package/src/services/database-initialization.d.ts +4 -8
  166. package/src/services/database-initialization.d.ts.map +1 -1
  167. package/src/services/database-initialization.js +39 -39
  168. package/src/services/database-initialization.js.map +1 -1
  169. package/src/services/direct-login-token.d.ts +1 -4
  170. package/src/services/direct-login-token.d.ts.map +1 -1
  171. package/src/services/direct-login-token.js.map +1 -1
  172. package/src/services/jwt.d.ts +1 -4
  173. package/src/services/jwt.d.ts.map +1 -1
  174. package/src/services/jwt.js.map +1 -1
  175. package/src/services/role.d.ts +2 -4
  176. package/src/services/role.d.ts.map +1 -1
  177. package/src/services/role.js.map +1 -1
  178. package/src/services/system-user.js +1 -1
  179. package/src/services/system-user.js.map +1 -1
  180. package/src/services/user.d.ts +2 -2
  181. package/src/services/user.d.ts.map +1 -1
  182. package/src/services/user.js +3 -3
  183. package/src/services/user.js.map +1 -1
  184. package/src/transactions/index.d.ts +2 -0
  185. package/src/transactions/index.d.ts.map +1 -0
  186. package/src/transactions/index.js +5 -0
  187. package/src/transactions/index.js.map +1 -0
  188. package/src/transactions/transaction-manager.d.ts +12 -0
  189. package/src/transactions/transaction-manager.d.ts.map +1 -0
  190. package/src/transactions/transaction-manager.js +30 -0
  191. package/src/transactions/transaction-manager.js.map +1 -0
  192. package/src/types/app-config.d.ts +16 -0
  193. package/src/types/app-config.d.ts.map +1 -0
  194. package/src/types/app-config.js +3 -0
  195. package/src/types/app-config.js.map +1 -0
  196. package/src/types/controller-config.d.ts +14 -0
  197. package/src/types/controller-config.d.ts.map +1 -0
  198. package/src/types/controller-config.js +3 -0
  199. package/src/types/controller-config.js.map +1 -0
  200. package/src/types/index.d.ts +3 -0
  201. package/src/types/index.d.ts.map +1 -0
  202. package/src/types/index.js +6 -0
  203. package/src/types/index.js.map +1 -0
  204. package/src/types.d.ts +2 -0
  205. package/src/types.d.ts.map +1 -1
  206. package/src/types.js.map +1 -1
  207. package/src/utils.js +2 -2
  208. package/src/utils.js.map +1 -1
  209. package/src/validation/index.d.ts +2 -0
  210. package/src/validation/index.d.ts.map +1 -0
  211. package/src/validation/index.js +5 -0
  212. package/src/validation/index.js.map +1 -0
  213. package/src/validation/validation-builder.d.ts +32 -0
  214. package/src/validation/validation-builder.d.ts.map +1 -0
  215. package/src/validation/validation-builder.js +81 -0
  216. package/src/validation/validation-builder.js.map +1 -0
package/README.md CHANGED
@@ -1,9 +1,18 @@
1
1
  # @digitaldefiance/node-express-suite
2
2
 
3
+ [![npm version](https://badge.fury.io/js/%40digitaldefiance%2Fnode-express-suite.svg)](https://badge.fury.io/js/%40digitaldefiance%2Fnode-express-suite)
4
+ [![Tests](https://img.shields.io/badge/tests-604%20passing-brightgreen)]()
5
+ [![Coverage](https://img.shields.io/badge/coverage-57.86%25-yellow)]()
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+
3
8
  An opinionated, secure, extensible Node.js/Express service framework built on Digital Defiance cryptography libraries, providing complete backend infrastructure for secure applications.
4
9
 
5
10
  It is an 'out of the box' solution with a specific recipe (Mongo, Express, React, Node, (MERN) stack) with ejs templating, JWT authentication, role-based access control, custom multi-language support via @digitaldefiance/i18n-lib, and a dynamic model registry system. You might either find it limiting or freeing, depending on your use case. It includes mnemonic authentication, ECIES encryption/decryption, PBKDF2 key derivation, email token workflows, and more.
6
11
 
12
+ ## What's New in v2.1
13
+
14
+ ✨ **Quality & Stability Release** - All dependencies upgraded, 604 tests passing, improved coverage and type safety throughout.
15
+
7
16
  ## Features
8
17
 
9
18
  - **🔐 ECIES Encryption/Decryption**: End-to-end encryption using elliptic curve cryptography
@@ -16,6 +25,10 @@ It is an 'out of the box' solution with a specific recipe (Mongo, Express, React
16
25
  - **📧 Email Token System**: Verification, password reset, and recovery workflows
17
26
  - **💾 MongoDB Integration**: Full database layer with Mongoose schemas
18
27
  - **🧪 Comprehensive Testing**: 100+ tests covering all major functionality
28
+ - **🏗️ Modern Architecture**: Service container, fluent builders, plugin system
29
+ - **⚡ Simplified Generics**: 87.5% reduction in type complexity
30
+ - **🔄 Automatic Transactions**: Decorator-based transaction management
31
+ - **🎨 Fluent APIs**: Validation, response, pipeline, and route builders
19
32
 
20
33
  ## Installation
21
34
 
@@ -537,7 +550,7 @@ try {
537
550
 
538
551
  ## Testing
539
552
 
540
- Comprehensive test suite with 100+ tests:
553
+ Comprehensive test suite with 604 passing tests:
541
554
 
542
555
  ```bash
543
556
  # Run all tests
@@ -552,6 +565,13 @@ npm test -- role.spec.ts
552
565
  npm test -- --coverage
553
566
  ```
554
567
 
568
+ ### Test Coverage (v2.1)
569
+
570
+ - **604 tests** passing (100% success rate)
571
+ - **57.86%** overall coverage
572
+ - **11 modules** at 100% coverage
573
+ - All critical paths tested (validation, auth, services)
574
+
555
575
  ## Best Practices
556
576
 
557
577
  ### Security
@@ -661,8 +681,468 @@ For issues and questions:
661
681
  - GitHub Issues: <https://github.com/Digital-Defiance/node-express-suite/issues>
662
682
  - Email: <support@digitaldefiance.org>
663
683
 
684
+ ## Architecture Refactor (2025)
685
+
686
+ **Major improvements with large complexity reduction:**
687
+
688
+ ### New Features
689
+
690
+ #### Service Container
691
+
692
+ ```typescript
693
+ // Centralized dependency injection
694
+ const jwtService = app.services.get(ServiceKeys.JWT);
695
+ const userService = app.services.get(ServiceKeys.USER);
696
+ ```
697
+
698
+ #### Simplified Generics
699
+
700
+ ```typescript
701
+ // Before: IApplication<T, I, TBaseDoc, TEnv, TConst, ...>
702
+ // After: IApplication
703
+ const app: IApplication = ...;
704
+ ```
705
+
706
+ #### Validation Builder
707
+
708
+ ```typescript
709
+ validation: function(lang) {
710
+ return ValidationBuilder.create(lang, this.constants)
711
+ .for('email').isEmail().withMessage(key)
712
+ .for('username').matches(c => c.UsernameRegex).withMessage(key)
713
+ .build();
714
+ }
715
+ ```
716
+
717
+ #### Transaction Decorator
718
+
719
+ ```typescript
720
+ @Post('/register', { transaction: true })
721
+ async register() {
722
+ // this.session available automatically
723
+ await this.userService.create(data, this.session);
724
+ }
725
+ ```
726
+
727
+ #### Response Builder
728
+
729
+ ```typescript
730
+ return Response.created()
731
+ .message(SuiteCoreStringKey.Registration_Success)
732
+ .data({ user, mnemonic })
733
+ .build();
734
+ ```
735
+
736
+ #### Plugin System
737
+
738
+ ```typescript
739
+ class MyPlugin implements IApplicationPlugin {
740
+ async init(app: IApplication) { /* setup */ }
741
+ async stop() { /* cleanup */ }
742
+ }
743
+ app.plugins.register(new MyPlugin());
744
+ ```
745
+
746
+ #### Route Builder DSL
747
+
748
+ ```typescript
749
+ RouteBuilder.create()
750
+ .post('/register')
751
+ .auth()
752
+ .validate(validation)
753
+ .transaction()
754
+ .handle(this.register);
755
+ ```
756
+
757
+ ---
758
+
759
+ ## Migration Guide (v1.x → v2.0)
760
+
761
+ ### Overview
762
+
763
+ Version 2.0 introduces a major architecture refactor with **50% complexity reduction** while maintaining backward compatibility where possible. This guide helps you migrate from v1.x to v2.0.
764
+
765
+ ### Breaking Changes
766
+
767
+ #### 1. Simplified Generic Parameters
768
+
769
+ **Before (v1.x):**
770
+
771
+ ```typescript
772
+ class Application<T, I, TInitResults, TModelDocs, TBaseDocument, TEnvironment, TConstants, TAppRouter>
773
+ class UserController<I, D, S, A, TUser, TTokenRole, TTokenUser, TApplication, TLanguage>
774
+ ```
775
+
776
+ **After (v2.0):**
777
+
778
+ ```typescript
779
+ class Application // No generic parameters
780
+ class UserController<TConfig extends ControllerConfig, TLanguage>
781
+ ```
782
+
783
+ **Migration:**
784
+
785
+ - Remove all generic type parameters from Application instantiation
786
+ - Update controller signatures to use ControllerConfig interface
787
+ - Type information now inferred from configuration objects
788
+
789
+ #### 2. Service Instantiation
790
+
791
+ **Before (v1.x):**
792
+
793
+ ```typescript
794
+ const jwtService = new JwtService(app);
795
+ const userService = new UserService(app);
796
+ const roleService = new RoleService(app);
797
+ ```
798
+
799
+ **After (v2.0):**
800
+
801
+ ```typescript
802
+ const jwtService = app.services.get(ServiceKeys.JWT);
803
+ const userService = app.services.get(ServiceKeys.USER);
804
+ const roleService = app.services.get(ServiceKeys.ROLE);
805
+ ```
806
+
807
+ **Migration:**
808
+
809
+ - Replace direct service instantiation with container access
810
+ - Services are now singletons managed by the container
811
+ - Import ServiceKeys enum for type-safe service access
812
+
813
+ ### Recommended Migrations (Non-Breaking)
814
+
815
+ #### 3. Transaction Handling
816
+
817
+ **Before (v1.x):**
818
+
819
+ ```typescript
820
+ async register(req: Request, res: Response, next: NextFunction) {
821
+ return await withTransaction(
822
+ this.application.db.connection,
823
+ this.application.environment.mongo.useTransactions,
824
+ undefined,
825
+ async (session) => {
826
+ const user = await this.userService.create(data, session);
827
+ const mnemonic = await this.mnemonicService.store(userId, session);
828
+ return { statusCode: 201, response: { user, mnemonic } };
829
+ }
830
+ );
831
+ }
832
+ ```
833
+
834
+ **After (v2.0):**
835
+
836
+ ```typescript
837
+ @Post('/register', { transaction: true })
838
+ async register(req: Request, res: Response, next: NextFunction) {
839
+ const user = await this.userService.create(data, this.session);
840
+ const mnemonic = await this.mnemonicService.store(userId, this.session);
841
+ return Response.created().data({ user, mnemonic }).build();
842
+ }
843
+ ```
844
+
845
+ **Benefits:**
846
+
847
+ - 70% reduction in transaction boilerplate
848
+ - Automatic session management
849
+ - Cleaner, more readable code
850
+
851
+ #### 4. Response Construction
852
+
853
+ **Before (v1.x):**
854
+
855
+ ```typescript
856
+ return {
857
+ statusCode: 201,
858
+ response: {
859
+ message: getSuiteCoreTranslation(SuiteCoreStringKey.Registration_Success, undefined, lang),
860
+ data: { user, mnemonic }
861
+ }
862
+ };
863
+ ```
864
+
865
+ **After (v2.0):**
866
+
867
+ ```typescript
868
+ return Response.created()
869
+ .message(SuiteCoreStringKey.Registration_Success)
870
+ .data({ user, mnemonic })
871
+ .build();
872
+ ```
873
+
874
+ **Benefits:**
875
+
876
+ - 40% reduction in response boilerplate
877
+ - Fluent, chainable API
878
+ - Automatic translation handling
879
+
880
+ #### 5. Validation
881
+
882
+ **Before (v1.x):**
883
+
884
+ ```typescript
885
+ protected getValidationRules(lang: TLanguage) {
886
+ return [
887
+ body('username')
888
+ .matches(this.constants.UsernameRegex)
889
+ .withMessage(getSuiteCoreTranslation(key, undefined, lang)),
890
+ body('email')
891
+ .isEmail()
892
+ .withMessage(getSuiteCoreTranslation(key, undefined, lang))
893
+ ];
894
+ }
895
+ ```
896
+
897
+ **After (v2.0):**
898
+
899
+ ```typescript
900
+ validation: function(lang: TLanguage) {
901
+ return ValidationBuilder.create(lang, this.constants)
902
+ .for('username').matches(c => c.UsernameRegex).withMessage(key)
903
+ .for('email').isEmail().withMessage(key)
904
+ .build();
905
+ }
906
+ ```
907
+
908
+ **Benefits:**
909
+
910
+ - 50% reduction in validation code
911
+ - Constants automatically injected
912
+ - Type-safe field access
913
+ - Cleaner syntax
914
+
915
+ #### 6. Middleware Composition
916
+
917
+ **Before (v1.x):**
918
+
919
+ ```typescript
920
+ router.post('/backup-codes',
921
+ authMiddleware,
922
+ authenticateCryptoMiddleware,
923
+ validateSchema(backupCodeSchema),
924
+ this.getBackupCodes.bind(this)
925
+ );
926
+ ```
927
+
928
+ **After (v2.0):**
929
+
930
+ ```typescript
931
+ @Post('/backup-codes', {
932
+ pipeline: Pipeline.create()
933
+ .use(Auth.token())
934
+ .use(Auth.crypto())
935
+ .use(Validate.schema(backupCodeSchema))
936
+ .build()
937
+ })
938
+ async getBackupCodes() { /* ... */ }
939
+ ```
940
+
941
+ **Benefits:**
942
+
943
+ - Explicit middleware ordering
944
+ - Reusable pipeline definitions
945
+ - Better readability
946
+
947
+ ### Step-by-Step Migration
948
+
949
+ #### Step 1: Update Dependencies
950
+
951
+ ```bash
952
+ npm install @digitaldefiance/node-express-suite@^2.0.0
953
+ # or
954
+ yarn add @digitaldefiance/node-express-suite@^2.0.0
955
+ ```
956
+
957
+ #### Step 2: Update Application Initialization
958
+
959
+ **Before:**
960
+
961
+ ```typescript
962
+ const app = new Application<MyTypes, MyIds, MyResults, MyModels, MyDoc, MyEnv, MyConst, MyRouter>({
963
+ port: 3000,
964
+ mongoUri: process.env.MONGO_URI,
965
+ jwtSecret: process.env.JWT_SECRET
966
+ });
967
+ ```
968
+
969
+ **After:**
970
+
971
+ ```typescript
972
+ const app = new Application({
973
+ port: 3000,
974
+ mongoUri: process.env.MONGO_URI,
975
+ jwtSecret: process.env.JWT_SECRET
976
+ });
977
+ ```
978
+
979
+ #### Step 3: Update Service Access
980
+
981
+ Find and replace service instantiation:
982
+
983
+ ```bash
984
+ # Find
985
+ new JwtService(app)
986
+ # Replace with
987
+ app.services.get(ServiceKeys.JWT)
988
+
989
+ # Find
990
+ new UserService(app)
991
+ # Replace with
992
+ app.services.get(ServiceKeys.USER)
993
+ ```
994
+
995
+ #### Step 4: Migrate Controllers (Gradual)
996
+
997
+ Start with high-traffic endpoints:
998
+
999
+ 1. Add transaction decorator to write operations
1000
+ 2. Replace response construction with Response builder
1001
+ 3. Update validation to use ValidationBuilder
1002
+ 4. Migrate middleware to Pipeline builder
1003
+
1004
+ #### Step 5: Test Thoroughly
1005
+
1006
+ ```bash
1007
+ # Run full test suite
1008
+ npm test
1009
+
1010
+ # Run specific controller tests
1011
+ npm test -- user-controller.spec.ts
1012
+
1013
+ # Check for deprecation warnings
1014
+ DEBUG=* npm start
1015
+ ```
1016
+
1017
+ ### Migration Checklist
1018
+
1019
+ - [ ] Update package to v2.0.0
1020
+ - [ ] Remove generic parameters from Application
1021
+ - [ ] Update service instantiation to use container
1022
+ - [ ] Migrate transaction handling (high-priority endpoints)
1023
+ - [ ] Migrate response construction (high-priority endpoints)
1024
+ - [ ] Update validation rules (new endpoints first)
1025
+ - [ ] Migrate middleware composition (optional)
1026
+ - [ ] Run full test suite
1027
+ - [ ] Check for deprecation warnings
1028
+ - [ ] Update documentation
1029
+ - [ ] Deploy to staging
1030
+ - [ ] Monitor for issues
1031
+ - [ ] Deploy to production
1032
+
1033
+ ### Backward Compatibility
1034
+
1035
+ The following v1.x patterns still work in v2.0:
1036
+
1037
+ ✅ Direct service instantiation (with deprecation warning)
1038
+ ✅ Manual transaction wrapping with withTransaction
1039
+ ✅ Manual response construction
1040
+ ✅ Traditional validation rules
1041
+ ✅ Direct middleware composition
1042
+
1043
+ ### Performance Considerations
1044
+
1045
+ - Service container adds negligible overhead (~0.1ms per request)
1046
+ - Transaction decorator has same performance as manual wrapping
1047
+ - Response builder is optimized for common cases
1048
+ - Validation builder compiles to same express-validator chains
1049
+
1050
+ ### Troubleshooting
1051
+
1052
+ #### Issue: Type errors after upgrade
1053
+
1054
+ **Solution:** Remove generic type parameters from Application and controller signatures.
1055
+
1056
+ #### Issue: Services not found in container
1057
+
1058
+ **Solution:** Ensure services are registered during application initialization. Check ServiceKeys enum.
1059
+
1060
+ #### Issue: Transaction session undefined
1061
+
1062
+ **Solution:** Add `{ transaction: true }` to route decorator options.
1063
+
1064
+ #### Issue: Validation not working
1065
+
1066
+ **Solution:** Ensure ValidationBuilder.create receives correct language and constants.
1067
+
1068
+ ### Getting Help
1069
+
1070
+ - **Documentation**: See REFACTOR_INDEX.md for complete refactor docs
1071
+ - **Examples**: See REFACTOR_EXAMPLES.md for code examples
1072
+ - **Issues**: Report bugs at GitHub Issues
1073
+ - **Support**: Email <support@digitaldefiance.org>
1074
+
1075
+ ### Additional Resources
1076
+
1077
+ - [Complete Refactor Summary](REFACTOR_COMPLETE_SUMMARY.md)
1078
+ - [Quick Start Guide](REFACTOR_QUICKSTART.md)
1079
+ - [Validation Examples](VALIDATION_BUILDER_EXAMPLES.md)
1080
+ - [Architecture Plan](ARCHITECTURE_REFACTOR_PLAN.md)
1081
+
1082
+ ---
1083
+
664
1084
  ## ChangeLog
665
1085
 
1086
+ ### Version 2.1.6
1087
+
1088
+ - Minor version bump from i18n/ecies
1089
+
1090
+ ### Version 2.1.5
1091
+
1092
+ - Minor version bump from i18n/ecies
1093
+
1094
+ ### Version 2.1.3 (January 2025)
1095
+
1096
+ **Test Suite Stabilization**
1097
+
1098
+ - **FIXED**: i18n initialization using correct `initSuiteCoreI18nEngine()` function
1099
+ - **FIXED**: Language registry duplicate registration errors in tests
1100
+ - **FIXED**: Validation builder chain initialization before `withMessage()`
1101
+ - **FIXED**: Translation mock signatures to match actual implementation
1102
+ - **FIXED**: Environment timezone type expectations
1103
+ - **ADDED**: 21 new tests for index exports coverage (604 total, 100% passing)
1104
+ - **IMPROVED**: Code coverage from 53.35% to 57.86% (+4.51%)
1105
+ - **IMPROVED**: 11 modules now at 100% coverage
1106
+ - **ENHANCED**: Clean test output with proper console mocking
1107
+
1108
+ ### Version 2.1.0 (November 2025)
1109
+
1110
+ **Quality & Stability Release**
1111
+
1112
+ - **UPGRADED**: All dependencies to latest stable versions
1113
+ - @digitaldefiance/suite-core-lib@2.1.3
1114
+ - @digitaldefiance/i18n-lib@2.1.1
1115
+ - @digitaldefiance/ecies-lib@2.1.3
1116
+ - @digitaldefiance/node-ecies-lib@2.1.3
1117
+ - **IMPROVED**: Test suite with 604 passing tests (100% success rate)
1118
+ - **IMPROVED**: Code coverage to 57.86% (+4.5% improvement)
1119
+ - **IMPROVED**: 11 modules at 100% coverage
1120
+ - **FIXED**: i18n initialization and language registry management
1121
+ - **FIXED**: Validation builder chain initialization
1122
+ - **FIXED**: Translation mock signatures in tests
1123
+ - **ENHANCED**: Type safety throughout the codebase
1124
+ - **ENHANCED**: Clean test output with proper console mocking
1125
+
1126
+ ### Version 2.0.0 (Architecture Refactor)
1127
+
1128
+ - **BREAKING**: Simplified IApplication interface (removed 5 generic parameters)
1129
+ - **NEW**: Service Container for centralized dependency injection
1130
+ - **NEW**: ValidationBuilder with fluent API and constants injection
1131
+ - **NEW**: Middleware Pipeline builder for explicit composition
1132
+ - **NEW**: Route Builder DSL as alternative to decorators
1133
+ - **NEW**: Automatic transaction management via decorators
1134
+ - **NEW**: Response Builder with fluent API
1135
+ - **NEW**: Application Builder for simplified construction
1136
+ - **NEW**: Plugin System for extensibility
1137
+ - **NEW**: Router Config separation
1138
+ - **NEW**: Database Initializer interface
1139
+ - **NEW**: Config Objects pattern throughout
1140
+ - **IMPROVED**: 50% overall complexity reduction
1141
+ - **IMPROVED**: 87.5% reduction in generic parameters
1142
+ - **IMPROVED**: 70% reduction in transaction boilerplate
1143
+ - **IMPROVED**: 40% reduction in response boilerplate
1144
+ - **IMPROVED**: Better IDE support and type inference
1145
+
666
1146
  ### Version 1.3.28
667
1147
 
668
1148
  - Bind this on controller validation
@@ -822,7 +1302,7 @@ For issues and questions:
822
1302
 
823
1303
  - Update ecies libs
824
1304
 
825
- ### Version 1.0.0 (Current)
1305
+ ### Version 1.0.0
826
1306
 
827
1307
  - Initial release with complete Express.js framework
828
1308
  - Dynamic model registry system
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@digitaldefiance/node-express-suite",
3
- "version": "1.3.28",
3
+ "version": "2.1.6",
4
4
  "description": "Generic express application and routing library with decorator support",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "npx nx build digitaldefiance-node-express-suite",
9
+ "build:stream": "npx nx build --outputStyle=stream digitaldefiance-node-express-suite",
10
+ "build:logged": "npx nx build --outputStyle=stream --skip-nx-cache digitaldefiance-node-express-suite 2>&1 | ansifilter -o build.log",
9
11
  "test": "npx nx test digitaldefiance-node-express-suite",
10
- "test:stream": "npx nx test digitaldefiance-node-express-suite --output-style=stream",
12
+ "test:stream": "npx nx test --outputStyle=stream digitaldefiance-node-express-suite",
13
+ "test:logged": "npx nx test --outputStyle=stream digitaldefiance-node-express-suite 2>&1 | ansifilter -o test.log",
11
14
  "lint": "npx nx lint digitaldefiance-node-express-suite",
12
15
  "lint:fix": "npx nx lint digitaldefiance-node-express-suite --fix",
13
16
  "prettier:check": "prettier --check 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}'",
@@ -18,10 +21,10 @@
18
21
  "publish:public": "npm publish --access public"
19
22
  },
20
23
  "dependencies": {
21
- "@digitaldefiance/ecies-lib": "1.3.27",
22
- "@digitaldefiance/i18n-lib": "1.3.27",
23
- "@digitaldefiance/node-ecies-lib": "1.3.27",
24
- "@digitaldefiance/suite-core-lib": "1.3.27",
24
+ "@digitaldefiance/ecies-lib": "2.1.6",
25
+ "@digitaldefiance/i18n-lib": "2.1.6",
26
+ "@digitaldefiance/node-ecies-lib": "2.1.6",
27
+ "@digitaldefiance/suite-core-lib": "2.1.6",
25
28
  "@subspace/reed-solomon-erasure.wasm": "^0.2.5",
26
29
  "argon2": "^0.40.1",
27
30
  "cors": "^2.8.5",
@@ -1,15 +1,17 @@
1
1
  import { MongoMemoryReplSet } from 'mongodb-memory-server';
2
- import mongoose, { Model, Types } from 'mongoose';
2
+ import mongoose, { Model } from 'mongoose';
3
3
  import { IBaseDocument } from './documents/base';
4
4
  import { Environment } from './environment';
5
5
  import { IApplication } from './interfaces/application';
6
6
  import { IConstants } from './interfaces/constants';
7
7
  import { IFailableResult } from './interfaces/failable-result';
8
8
  import { SchemaMap } from './types';
9
+ import { ServiceContainer } from './container';
10
+ import { PluginManager } from './plugins';
9
11
  /**
10
12
  * Base Application class with core functionality
11
13
  */
12
- export declare class BaseApplication<TModelDocs extends Record<string, IBaseDocument<any>>, TInitResults, TConstants extends IConstants = IConstants> implements IApplication<any, Types.ObjectId, IBaseDocument<any, Types.ObjectId>, Environment, IConstants> {
14
+ export declare class BaseApplication<TModelDocs extends Record<string, IBaseDocument<any>>, TInitResults, TConstants extends IConstants = IConstants> implements IApplication {
13
15
  /**
14
16
  * Application environment
15
17
  */
@@ -60,6 +62,14 @@ export declare class BaseApplication<TModelDocs extends Record<string, IBaseDocu
60
62
  * Flag indicating whether the application is ready to handle requests
61
63
  */
62
64
  protected _ready: boolean;
65
+ /**
66
+ * Service container for dependency injection
67
+ */
68
+ readonly services: ServiceContainer;
69
+ /**
70
+ * Plugin manager for extensibility
71
+ */
72
+ readonly plugins: PluginManager;
63
73
  /**
64
74
  * Get the connected MongoDB database instance
65
75
  */
@@ -1 +1 @@
1
- {"version":3,"file":"application-base.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-node-express-suite/src/application-base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"application-base.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-node-express-suite/src/application-base.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,8 @@ const path_1 = require("path");
10
10
  const environment_1 = require("./environment");
11
11
  const model_registry_1 = require("./model-registry");
12
12
  const utils_1 = require("./utils");
13
+ const container_1 = require("./container");
14
+ const plugins_1 = require("./plugins");
13
15
  /**
14
16
  * Base Application class with core functionality
15
17
  */
@@ -79,6 +81,14 @@ class BaseApplication {
79
81
  * Flag indicating whether the application is ready to handle requests
80
82
  */
81
83
  _ready;
84
+ /**
85
+ * Service container for dependency injection
86
+ */
87
+ services;
88
+ /**
89
+ * Plugin manager for extensibility
90
+ */
91
+ plugins;
82
92
  /**
83
93
  * Get the connected MongoDB database instance
84
94
  */
@@ -101,6 +111,8 @@ class BaseApplication {
101
111
  this._schemaMapFactory = schemaMapFactory;
102
112
  this._databaseInitFunction = databaseInitFunction;
103
113
  this._initResultHashFunction = initResultHashFunction;
114
+ this.services = new container_1.ServiceContainer();
115
+ this.plugins = new plugins_1.PluginManager();
104
116
  }
105
117
  /**
106
118
  * Validate MongoDB URI to prevent SSRF attacks
@@ -293,6 +305,8 @@ class BaseApplication {
293
305
  }
294
306
  try {
295
307
  await this.connectDatabase(mongoUri ?? this.environment.mongo.uri, this.environment.debug);
308
+ // Initialize plugins
309
+ await this.plugins.initAll(this);
296
310
  // Database initialization should be handled by the consuming application
297
311
  }
298
312
  catch (err) {
@@ -311,6 +325,7 @@ class BaseApplication {
311
325
  * Stop the application
312
326
  */
313
327
  async stop() {
328
+ await this.plugins.stopAll();
314
329
  await this.disconnectDatabase();
315
330
  if (this._devDatabase) {
316
331
  await this._devDatabase.stop();