@digitaldefiance/node-express-suite 4.22.2 → 4.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +173 -407
- package/package.json +1 -5
- package/src/__tests__/fixtures/index.d.ts +1 -1
- package/src/__tests__/fixtures/index.d.ts.map +1 -1
- package/src/__tests__/fixtures/index.js +1 -2
- package/src/__tests__/fixtures/index.js.map +1 -1
- package/src/__tests__/helpers/index.d.ts +1 -3
- package/src/__tests__/helpers/index.d.ts.map +1 -1
- package/src/__tests__/helpers/index.js +1 -4
- package/src/__tests__/helpers/index.js.map +1 -1
- package/src/__tests__/index.d.ts.map +1 -1
- package/src/__tests__/index.js +1 -0
- package/src/__tests__/index.js.map +1 -1
- package/src/application.d.ts +8 -11
- package/src/application.d.ts.map +1 -1
- package/src/application.js +8 -17
- package/src/application.js.map +1 -1
- package/src/branded-responses/branded-api-responses.d.ts +10 -2
- package/src/branded-responses/branded-api-responses.d.ts.map +1 -1
- package/src/branded-responses/branded-api-responses.js +5 -0
- package/src/branded-responses/branded-api-responses.js.map +1 -1
- package/src/branded-responses/serializers.d.ts +4 -1
- package/src/branded-responses/serializers.d.ts.map +1 -1
- package/src/builders/index.d.ts +1 -1
- package/src/builders/index.d.ts.map +1 -1
- package/src/builders/index.js +1 -2
- package/src/builders/index.js.map +1 -1
- package/src/controllers/base.d.ts +5 -18
- package/src/controllers/base.d.ts.map +1 -1
- package/src/controllers/base.js +7 -62
- package/src/controllers/base.js.map +1 -1
- package/src/controllers/index.d.ts +1 -1
- package/src/controllers/index.d.ts.map +1 -1
- package/src/controllers/index.js +2 -1
- package/src/controllers/index.js.map +1 -1
- package/src/controllers/openapi.d.ts +3 -3
- package/src/controllers/openapi.d.ts.map +1 -1
- package/src/controllers/openapi.js.map +1 -1
- package/src/enumerations/index.d.ts +0 -2
- package/src/enumerations/index.d.ts.map +1 -1
- package/src/enumerations/index.js +0 -2
- package/src/enumerations/index.js.map +1 -1
- package/src/environment.d.ts +4 -3
- package/src/environment.d.ts.map +1 -1
- package/src/environment.js +3 -1
- package/src/environment.js.map +1 -1
- package/src/errors/index.d.ts +0 -3
- package/src/errors/index.d.ts.map +1 -1
- package/src/errors/index.js +0 -3
- package/src/errors/index.js.map +1 -1
- package/src/index.d.ts +1 -8
- package/src/index.d.ts.map +1 -1
- package/src/index.js +1 -11
- package/src/index.js.map +1 -1
- package/src/interfaces/controller-config.d.ts +1 -2
- package/src/interfaces/controller-config.d.ts.map +1 -1
- package/src/interfaces/document-store.d.ts +3 -2
- package/src/interfaces/document-store.d.ts.map +1 -1
- package/src/interfaces/document-store.js +3 -3
- package/src/interfaces/document-store.js.map +1 -1
- package/src/interfaces/environment.d.ts +3 -2
- package/src/interfaces/environment.d.ts.map +1 -1
- package/src/interfaces/index.d.ts +0 -11
- package/src/interfaces/index.d.ts.map +1 -1
- package/src/interfaces/index.js +0 -11
- package/src/interfaces/index.js.map +1 -1
- package/src/plugins/database-plugin.d.ts +12 -0
- package/src/plugins/database-plugin.d.ts.map +1 -1
- package/src/plugins/index.d.ts +0 -1
- package/src/plugins/index.d.ts.map +1 -1
- package/src/plugins/index.js +0 -1
- package/src/plugins/index.js.map +1 -1
- package/src/routers/index.d.ts +0 -1
- package/src/routers/index.d.ts.map +1 -1
- package/src/routers/index.js +0 -1
- package/src/routers/index.js.map +1 -1
- package/src/services/base.d.ts +10 -13
- package/src/services/base.d.ts.map +1 -1
- package/src/services/base.js +7 -21
- package/src/services/base.js.map +1 -1
- package/src/services/index.d.ts +0 -15
- package/src/services/index.d.ts.map +1 -1
- package/src/services/index.js +0 -15
- package/src/services/index.js.map +1 -1
- package/src/testing.d.ts +1 -1
- package/src/testing.d.ts.map +1 -1
- package/src/testing.js +1 -1
- package/src/testing.js.map +1 -1
- package/src/types.d.ts +6 -17
- package/src/types.d.ts.map +1 -1
- package/src/types.js.map +1 -1
- package/src/utils.d.ts +5 -34
- package/src/utils.d.ts.map +1 -1
- package/src/utils.js +24 -165
- package/src/utils.js.map +1 -1
- package/src/__tests__/fixtures/model-mocks.mock.d.ts +0 -12
- package/src/__tests__/fixtures/model-mocks.mock.d.ts.map +0 -1
- package/src/__tests__/fixtures/model-mocks.mock.js +0 -102
- package/src/__tests__/fixtures/model-mocks.mock.js.map +0 -1
- package/src/__tests__/helpers/application.mock.d.ts +0 -8
- package/src/__tests__/helpers/application.mock.d.ts.map +0 -1
- package/src/__tests__/helpers/application.mock.js +0 -85
- package/src/__tests__/helpers/application.mock.js.map +0 -1
- package/src/__tests__/helpers/setup-test-env.d.ts +0 -13
- package/src/__tests__/helpers/setup-test-env.d.ts.map +0 -1
- package/src/__tests__/helpers/setup-test-env.js +0 -133
- package/src/__tests__/helpers/setup-test-env.js.map +0 -1
- package/src/builders/application-builder.d.ts +0 -53
- package/src/builders/application-builder.d.ts.map +0 -1
- package/src/builders/application-builder.js +0 -91
- package/src/builders/application-builder.js.map +0 -1
- package/src/controllers/user.d.ts +0 -66
- package/src/controllers/user.d.ts.map +0 -1
- package/src/controllers/user.js +0 -949
- package/src/controllers/user.js.map +0 -1
- package/src/documents/base.d.ts +0 -15
- package/src/documents/base.d.ts.map +0 -1
- package/src/documents/base.js +0 -8
- package/src/documents/base.js.map +0 -1
- package/src/documents/email-token.d.ts +0 -15
- package/src/documents/email-token.d.ts.map +0 -1
- package/src/documents/email-token.js +0 -8
- package/src/documents/email-token.js.map +0 -1
- package/src/documents/index.d.ts +0 -8
- package/src/documents/index.d.ts.map +0 -1
- package/src/documents/index.js +0 -3
- package/src/documents/index.js.map +0 -1
- package/src/documents/mnemonic.d.ts +0 -16
- package/src/documents/mnemonic.d.ts.map +0 -1
- package/src/documents/mnemonic.js +0 -8
- package/src/documents/mnemonic.js.map +0 -1
- package/src/documents/role.d.ts +0 -15
- package/src/documents/role.d.ts.map +0 -1
- package/src/documents/role.js +0 -8
- package/src/documents/role.js.map +0 -1
- package/src/documents/used-direct-login-token.d.ts +0 -16
- package/src/documents/used-direct-login-token.d.ts.map +0 -1
- package/src/documents/used-direct-login-token.js +0 -8
- package/src/documents/used-direct-login-token.js.map +0 -1
- package/src/documents/user-role.d.ts +0 -16
- package/src/documents/user-role.d.ts.map +0 -1
- package/src/documents/user-role.js +0 -8
- package/src/documents/user-role.js.map +0 -1
- package/src/documents/user.d.ts +0 -16
- package/src/documents/user.d.ts.map +0 -1
- package/src/documents/user.js +0 -8
- package/src/documents/user.js.map +0 -1
- package/src/enumerations/base-model-name.d.ts +0 -43
- package/src/enumerations/base-model-name.d.ts.map +0 -1
- package/src/enumerations/base-model-name.js +0 -39
- package/src/enumerations/base-model-name.js.map +0 -1
- package/src/enumerations/schema-collection.d.ts +0 -39
- package/src/enumerations/schema-collection.d.ts.map +0 -1
- package/src/enumerations/schema-collection.js +0 -43
- package/src/enumerations/schema-collection.js.map +0 -1
- package/src/errors/invalid-model.d.ts +0 -18
- package/src/errors/invalid-model.d.ts.map +0 -1
- package/src/errors/invalid-model.js +0 -26
- package/src/errors/invalid-model.js.map +0 -1
- package/src/errors/model-not-registered.d.ts +0 -18
- package/src/errors/model-not-registered.d.ts.map +0 -1
- package/src/errors/model-not-registered.js +0 -26
- package/src/errors/model-not-registered.js.map +0 -1
- package/src/errors/mongoose-validation.d.ts +0 -28
- package/src/errors/mongoose-validation.d.ts.map +0 -1
- package/src/errors/mongoose-validation.js +0 -33
- package/src/errors/mongoose-validation.js.map +0 -1
- package/src/interfaces/api-mongo-validation-error-response.d.ts +0 -16
- package/src/interfaces/api-mongo-validation-error-response.d.ts.map +0 -1
- package/src/interfaces/api-mongo-validation-error-response.js +0 -8
- package/src/interfaces/api-mongo-validation-error-response.js.map +0 -1
- package/src/interfaces/database-init-result-tx.d.ts +0 -27
- package/src/interfaces/database-init-result-tx.d.ts.map +0 -1
- package/src/interfaces/database-init-result-tx.js +0 -3
- package/src/interfaces/database-init-result-tx.js.map +0 -1
- package/src/interfaces/db-init-result.d.ts +0 -16
- package/src/interfaces/db-init-result.d.ts.map +0 -1
- package/src/interfaces/db-init-result.js +0 -8
- package/src/interfaces/db-init-result.js.map +0 -1
- package/src/interfaces/discriminator-collections.d.ts +0 -17
- package/src/interfaces/discriminator-collections.d.ts.map +0 -1
- package/src/interfaces/discriminator-collections.js +0 -8
- package/src/interfaces/discriminator-collections.js.map +0 -1
- package/src/interfaces/environment-mongo.d.ts +0 -86
- package/src/interfaces/environment-mongo.d.ts.map +0 -1
- package/src/interfaces/environment-mongo.js +0 -8
- package/src/interfaces/environment-mongo.js.map +0 -1
- package/src/interfaces/models/email-token.d.ts +0 -12
- package/src/interfaces/models/email-token.d.ts.map +0 -1
- package/src/interfaces/models/email-token.js +0 -8
- package/src/interfaces/models/email-token.js.map +0 -1
- package/src/interfaces/models/index.d.ts +0 -8
- package/src/interfaces/models/index.d.ts.map +0 -1
- package/src/interfaces/models/index.js +0 -11
- package/src/interfaces/models/index.js.map +0 -1
- package/src/interfaces/models/mnemonic.d.ts +0 -13
- package/src/interfaces/models/mnemonic.d.ts.map +0 -1
- package/src/interfaces/models/mnemonic.js +0 -8
- package/src/interfaces/models/mnemonic.js.map +0 -1
- package/src/interfaces/models/role.d.ts +0 -12
- package/src/interfaces/models/role.d.ts.map +0 -1
- package/src/interfaces/models/role.js +0 -8
- package/src/interfaces/models/role.js.map +0 -1
- package/src/interfaces/models/token-role.d.ts +0 -19
- package/src/interfaces/models/token-role.d.ts.map +0 -1
- package/src/interfaces/models/token-role.js +0 -8
- package/src/interfaces/models/token-role.js.map +0 -1
- package/src/interfaces/models/used-direct-login-token.d.ts +0 -19
- package/src/interfaces/models/used-direct-login-token.d.ts.map +0 -1
- package/src/interfaces/models/used-direct-login-token.js +0 -8
- package/src/interfaces/models/used-direct-login-token.js.map +0 -1
- package/src/interfaces/models/user-role.d.ts +0 -19
- package/src/interfaces/models/user-role.d.ts.map +0 -1
- package/src/interfaces/models/user-role.js +0 -8
- package/src/interfaces/models/user-role.js.map +0 -1
- package/src/interfaces/models/user.d.ts +0 -21
- package/src/interfaces/models/user.d.ts.map +0 -1
- package/src/interfaces/models/user.js +0 -8
- package/src/interfaces/models/user.js.map +0 -1
- package/src/interfaces/mongo-application.d.ts +0 -35
- package/src/interfaces/mongo-application.d.ts.map +0 -1
- package/src/interfaces/mongo-application.js +0 -10
- package/src/interfaces/mongo-application.js.map +0 -1
- package/src/interfaces/mongo-errors.d.ts +0 -13
- package/src/interfaces/mongo-errors.d.ts.map +0 -1
- package/src/interfaces/mongo-errors.js +0 -8
- package/src/interfaces/mongo-errors.js.map +0 -1
- package/src/interfaces/mongoose-document-store.d.ts +0 -42
- package/src/interfaces/mongoose-document-store.d.ts.map +0 -1
- package/src/interfaces/mongoose-document-store.js +0 -10
- package/src/interfaces/mongoose-document-store.js.map +0 -1
- package/src/interfaces/schema.d.ts +0 -37
- package/src/interfaces/schema.d.ts.map +0 -1
- package/src/interfaces/schema.js +0 -8
- package/src/interfaces/schema.js.map +0 -1
- package/src/interfaces/server-init-result.d.ts +0 -45
- package/src/interfaces/server-init-result.d.ts.map +0 -1
- package/src/interfaces/server-init-result.js +0 -8
- package/src/interfaces/server-init-result.js.map +0 -1
- package/src/interfaces/test-environment.d.ts +0 -22
- package/src/interfaces/test-environment.d.ts.map +0 -1
- package/src/interfaces/test-environment.js +0 -8
- package/src/interfaces/test-environment.js.map +0 -1
- package/src/model-registry.d.ts +0 -79
- package/src/model-registry.d.ts.map +0 -1
- package/src/model-registry.js +0 -97
- package/src/model-registry.js.map +0 -1
- package/src/models/email-token.d.ts +0 -24
- package/src/models/email-token.d.ts.map +0 -1
- package/src/models/email-token.js +0 -16
- package/src/models/email-token.js.map +0 -1
- package/src/models/index.d.ts +0 -7
- package/src/models/index.d.ts.map +0 -1
- package/src/models/index.js +0 -10
- package/src/models/index.js.map +0 -1
- package/src/models/mnemonic.d.ts +0 -24
- package/src/models/mnemonic.d.ts.map +0 -1
- package/src/models/mnemonic.js +0 -27
- package/src/models/mnemonic.js.map +0 -1
- package/src/models/role.d.ts +0 -24
- package/src/models/role.d.ts.map +0 -1
- package/src/models/role.js +0 -27
- package/src/models/role.js.map +0 -1
- package/src/models/used-direct-login-token.d.ts +0 -24
- package/src/models/used-direct-login-token.d.ts.map +0 -1
- package/src/models/used-direct-login-token.js +0 -16
- package/src/models/used-direct-login-token.js.map +0 -1
- package/src/models/user-role.d.ts +0 -23
- package/src/models/user-role.d.ts.map +0 -1
- package/src/models/user-role.js +0 -26
- package/src/models/user-role.js.map +0 -1
- package/src/models/user.d.ts +0 -24
- package/src/models/user.d.ts.map +0 -1
- package/src/models/user.js +0 -27
- package/src/models/user.js.map +0 -1
- package/src/mongo-application-concrete.d.ts +0 -32
- package/src/mongo-application-concrete.d.ts.map +0 -1
- package/src/mongo-application-concrete.js +0 -49
- package/src/mongo-application-concrete.js.map +0 -1
- package/src/plugins/mongo-database-plugin.d.ts +0 -115
- package/src/plugins/mongo-database-plugin.d.ts.map +0 -1
- package/src/plugins/mongo-database-plugin.js +0 -234
- package/src/plugins/mongo-database-plugin.js.map +0 -1
- package/src/routers/api.d.ts +0 -60
- package/src/routers/api.d.ts.map +0 -1
- package/src/routers/api.js +0 -116
- package/src/routers/api.js.map +0 -1
- package/src/schemas/email-token.d.ts +0 -65
- package/src/schemas/email-token.d.ts.map +0 -1
- package/src/schemas/email-token.js +0 -68
- package/src/schemas/email-token.js.map +0 -1
- package/src/schemas/index.d.ts +0 -8
- package/src/schemas/index.d.ts.map +0 -1
- package/src/schemas/index.js +0 -11
- package/src/schemas/index.js.map +0 -1
- package/src/schemas/mnemonic.d.ts +0 -37
- package/src/schemas/mnemonic.d.ts.map +0 -1
- package/src/schemas/mnemonic.js +0 -41
- package/src/schemas/mnemonic.js.map +0 -1
- package/src/schemas/role.d.ts +0 -57
- package/src/schemas/role.d.ts.map +0 -1
- package/src/schemas/role.js +0 -102
- package/src/schemas/role.js.map +0 -1
- package/src/schemas/schema.d.ts +0 -62
- package/src/schemas/schema.d.ts.map +0 -1
- package/src/schemas/schema.js +0 -81
- package/src/schemas/schema.js.map +0 -1
- package/src/schemas/used-direct-login-token.d.ts +0 -49
- package/src/schemas/used-direct-login-token.d.ts.map +0 -1
- package/src/schemas/used-direct-login-token.js +0 -35
- package/src/schemas/used-direct-login-token.js.map +0 -1
- package/src/schemas/user-role.d.ts +0 -52
- package/src/schemas/user-role.d.ts.map +0 -1
- package/src/schemas/user-role.js +0 -67
- package/src/schemas/user-role.js.map +0 -1
- package/src/schemas/user.d.ts +0 -43
- package/src/schemas/user.d.ts.map +0 -1
- package/src/schemas/user.js +0 -214
- package/src/schemas/user.js.map +0 -1
- package/src/services/backup-code.d.ts +0 -120
- package/src/services/backup-code.d.ts.map +0 -1
- package/src/services/backup-code.js +0 -323
- package/src/services/backup-code.js.map +0 -1
- package/src/services/database-initialization.d.ts +0 -138
- package/src/services/database-initialization.d.ts.map +0 -1
- package/src/services/database-initialization.js +0 -913
- package/src/services/database-initialization.js.map +0 -1
- package/src/services/db-init-cache.d.ts +0 -18
- package/src/services/db-init-cache.d.ts.map +0 -1
- package/src/services/db-init-cache.js +0 -7
- package/src/services/db-init-cache.js.map +0 -1
- package/src/services/direct-login-token.d.ts +0 -28
- package/src/services/direct-login-token.d.ts.map +0 -1
- package/src/services/direct-login-token.js +0 -62
- package/src/services/direct-login-token.js.map +0 -1
- package/src/services/jwt.d.ts +0 -45
- package/src/services/jwt.d.ts.map +0 -1
- package/src/services/jwt.js +0 -105
- package/src/services/jwt.js.map +0 -1
- package/src/services/mnemonic.d.ts +0 -68
- package/src/services/mnemonic.d.ts.map +0 -1
- package/src/services/mnemonic.js +0 -120
- package/src/services/mnemonic.js.map +0 -1
- package/src/services/mongo-authentication-provider.d.ts +0 -27
- package/src/services/mongo-authentication-provider.d.ts.map +0 -1
- package/src/services/mongo-authentication-provider.js +0 -84
- package/src/services/mongo-authentication-provider.js.map +0 -1
- package/src/services/mongo-backup-code-store.d.ts +0 -40
- package/src/services/mongo-backup-code-store.d.ts.map +0 -1
- package/src/services/mongo-backup-code-store.js +0 -104
- package/src/services/mongo-backup-code-store.js.map +0 -1
- package/src/services/mongo-base.d.ts +0 -24
- package/src/services/mongo-base.d.ts.map +0 -1
- package/src/services/mongo-base.js +0 -28
- package/src/services/mongo-base.js.map +0 -1
- package/src/services/mongoose-collection.d.ts +0 -52
- package/src/services/mongoose-collection.d.ts.map +0 -1
- package/src/services/mongoose-collection.js +0 -326
- package/src/services/mongoose-collection.js.map +0 -1
- package/src/services/mongoose-database.d.ts +0 -64
- package/src/services/mongoose-database.d.ts.map +0 -1
- package/src/services/mongoose-database.js +0 -121
- package/src/services/mongoose-database.js.map +0 -1
- package/src/services/mongoose-document-store.d.ts +0 -109
- package/src/services/mongoose-document-store.d.ts.map +0 -1
- package/src/services/mongoose-document-store.js +0 -264
- package/src/services/mongoose-document-store.js.map +0 -1
- package/src/services/mongoose-session-adapter.d.ts +0 -39
- package/src/services/mongoose-session-adapter.d.ts.map +0 -1
- package/src/services/mongoose-session-adapter.js +0 -63
- package/src/services/mongoose-session-adapter.js.map +0 -1
- package/src/services/request-user.d.ts +0 -45
- package/src/services/request-user.d.ts.map +0 -1
- package/src/services/request-user.js +0 -90
- package/src/services/request-user.js.map +0 -1
- package/src/services/role.d.ts +0 -97
- package/src/services/role.d.ts.map +0 -1
- package/src/services/role.js +0 -289
- package/src/services/role.js.map +0 -1
- package/src/services/user.d.ts +0 -368
- package/src/services/user.d.ts.map +0 -1
- package/src/services/user.js +0 -1495
- package/src/services/user.js.map +0 -1
- package/src/transactions/index.d.ts +0 -2
- package/src/transactions/index.d.ts.map +0 -1
- package/src/transactions/index.js +0 -5
- package/src/transactions/index.js.map +0 -1
- package/src/transactions/transaction-manager.d.ts +0 -37
- package/src/transactions/transaction-manager.d.ts.map +0 -1
- package/src/transactions/transaction-manager.js +0 -50
- package/src/transactions/transaction-manager.js.map +0 -1
- package/src/types/mongoose-helpers.d.ts +0 -16
- package/src/types/mongoose-helpers.d.ts.map +0 -1
- package/src/types/mongoose-helpers.js +0 -8
- package/src/types/mongoose-helpers.js.map +0 -1
- package/src/utils/default-mongo-uri-validator.d.ts +0 -15
- package/src/utils/default-mongo-uri-validator.d.ts.map +0 -1
- package/src/utils/default-mongo-uri-validator.js +0 -46
- package/src/utils/default-mongo-uri-validator.js.map +0 -1
package/README.md
CHANGED
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
An opinionated, secure, extensible Node.js/Express service framework built on Digital Defiance cryptography libraries, providing complete backend infrastructure for secure applications.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Node Express Suite forms the base of an 'out of the box' solution for websites using a specific recipe with 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.
|
|
11
|
+
|
|
12
|
+
Originally Node Express Suite was entirely Mongo based, but BrightChain evolved and developed its own [@brightchain/node-express-suite](https://www.npmjs.com/package/@brightchain/node-express-suite) that mirrored this package and the mongo components were moved to [@digitaldefiance/node-express-suite-mongo](https://www.npmjs.com/package/@digitaldefiance/node-express-suite-mongo). Now this package is database-agnostic and forms the base for both the Mongo package and [BrightStack](https://github.brightchain.org)'s version of node-express-suite.
|
|
13
|
+
|
|
14
|
+
> **Note:** Starting with v5.0, all MongoDB/Mongoose-specific code (documents, schemas, models, `MongoDatabasePlugin`, `DatabaseInitializationService`, `UserService`, `RoleService`, `ModelRegistry`, etc.) has been extracted into [`@digitaldefiance/node-express-suite-mongo`](https://www.npmjs.com/package/@digitaldefiance/node-express-suite-mongo). If your application uses MongoDB, install both packages. See [MONGO_SPLIT_MIGRATION.md](docs/MONGO_SPLIT_MIGRATION.md) for details.
|
|
11
15
|
|
|
12
16
|
Part of [Express Suite](https://github.com/Digital-Defiance/express-suite)
|
|
13
17
|
|
|
@@ -90,16 +94,16 @@ Part of [Express Suite](https://github.com/Digital-Defiance/express-suite)
|
|
|
90
94
|
- **🔑 PBKDF2 Key Derivation**: Secure password hashing with configurable profiles
|
|
91
95
|
- **👥 Role-Based Access Control (RBAC)**: Flexible permission system with user roles
|
|
92
96
|
- **🌍 Multi-Language i18n**: Plugin-based internationalization with 8+ languages
|
|
93
|
-
-
|
|
97
|
+
- **🔌 Plugin-Based Database**: Database-agnostic core with pluggable backends (see `node-express-suite-mongo` for MongoDB)
|
|
94
98
|
- **🔧 Runtime Configuration**: Override defaults at runtime for advanced use cases
|
|
95
99
|
- **🛡️ JWT Authentication**: Secure token-based authentication
|
|
96
100
|
- **📧 Email Token System**: Verification, password reset, and recovery workflows
|
|
97
|
-
- **💾 MongoDB Integration**: Full database layer with Mongoose schemas
|
|
98
101
|
- **🧪 Comprehensive Testing**: 100+ tests covering all major functionality
|
|
99
102
|
- **🏗️ Modern Architecture**: Service container, fluent builders, plugin system
|
|
100
103
|
- **⚡ Simplified Generics**: 87.5% reduction in type complexity
|
|
101
104
|
- **🔄 Automatic Transactions**: Decorator-based transaction management
|
|
102
105
|
- **🎨 Fluent APIs**: Validation, response, pipeline, and route builders
|
|
106
|
+
- **🎯 Decorator API**: Full decorator-based controller system with automatic OpenAPI generation
|
|
103
107
|
|
|
104
108
|
## Installation
|
|
105
109
|
|
|
@@ -111,249 +115,87 @@ yarn add @digitaldefiance/node-express-suite
|
|
|
111
115
|
|
|
112
116
|
## Quick Start
|
|
113
117
|
|
|
114
|
-
### Basic Server Setup
|
|
118
|
+
### Basic Server Setup (Database-Agnostic)
|
|
115
119
|
|
|
116
120
|
```typescript
|
|
117
|
-
import { Application,
|
|
121
|
+
import { Application, emailServiceRegistry } from '@digitaldefiance/node-express-suite';
|
|
118
122
|
import { LanguageCodes } from '@digitaldefiance/i18n-lib';
|
|
119
123
|
import { EmailService } from './services/email'; // Your concrete implementation
|
|
120
124
|
|
|
121
125
|
// Create application instance
|
|
122
|
-
const app = new Application(
|
|
123
|
-
port: 3000,
|
|
124
|
-
mongoUri: 'mongodb://localhost:27017/myapp',
|
|
125
|
-
jwtSecret: process.env.JWT_SECRET,
|
|
126
|
-
defaultLanguage: LanguageCodes.EN_US
|
|
127
|
-
});
|
|
126
|
+
const app = new Application(environment, apiRouterFactory);
|
|
128
127
|
|
|
129
128
|
// Configure email service (required before using middleware)
|
|
130
129
|
emailServiceRegistry.setService(new EmailService(app));
|
|
131
130
|
|
|
132
|
-
// Initialize database with default users and roles
|
|
133
|
-
const initResult = await DatabaseInitializationService.initUserDb(app);
|
|
134
|
-
|
|
135
131
|
// Start server
|
|
136
132
|
await app.start();
|
|
137
133
|
console.log(`Server running on port ${app.environment.port}`);
|
|
138
134
|
```
|
|
139
135
|
|
|
140
|
-
###
|
|
136
|
+
### With MongoDB (using the Mongo Package)
|
|
141
137
|
|
|
142
138
|
```typescript
|
|
143
|
-
import {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// Sign in user
|
|
150
|
-
const user = await userService.findByUsername('alice');
|
|
151
|
-
const { token, roles } = await jwtService.signToken(user, app.environment.jwtSecret);
|
|
152
|
-
|
|
153
|
-
// Verify token
|
|
154
|
-
const tokenUser = await jwtService.verifyToken(token);
|
|
155
|
-
console.log(`User ${tokenUser.userId} authenticated with roles:`, tokenUser.roles);
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## Core Components
|
|
159
|
-
|
|
160
|
-
### Dynamic Model Registry
|
|
161
|
-
|
|
162
|
-
The package uses a dynamic model registration system for extensibility:
|
|
139
|
+
import { Application } from '@digitaldefiance/node-express-suite';
|
|
140
|
+
import {
|
|
141
|
+
MongoDatabasePlugin,
|
|
142
|
+
DatabaseInitializationService,
|
|
143
|
+
getSchemaMap,
|
|
144
|
+
} from '@digitaldefiance/node-express-suite-mongo';
|
|
163
145
|
|
|
164
|
-
|
|
165
|
-
import { ModelRegistry } from '@digitaldefiance/node-express-suite';
|
|
146
|
+
const app = new Application(environment, apiRouterFactory);
|
|
166
147
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
148
|
+
const mongoPlugin = new MongoDatabasePlugin({
|
|
149
|
+
schemaMapFactory: getSchemaMap,
|
|
150
|
+
databaseInitFunction: DatabaseInitializationService.initUserDb.bind(DatabaseInitializationService),
|
|
151
|
+
initResultHashFunction: DatabaseInitializationService.serverInitResultHash.bind(DatabaseInitializationService),
|
|
152
|
+
environment,
|
|
153
|
+
constants,
|
|
173
154
|
});
|
|
174
155
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// Use the model
|
|
179
|
-
const org = await OrgModel.findById(orgId);
|
|
156
|
+
app.useDatabasePlugin(mongoPlugin);
|
|
157
|
+
await app.start();
|
|
180
158
|
```
|
|
181
159
|
|
|
182
|
-
###
|
|
183
|
-
|
|
184
|
-
The framework includes these pre-registered models:
|
|
185
|
-
|
|
186
|
-
- **User**: User accounts with authentication
|
|
187
|
-
- **Role**: Permission roles for RBAC
|
|
188
|
-
- **UserRole**: User-to-role associations
|
|
189
|
-
- **EmailToken**: Email verification and recovery tokens
|
|
190
|
-
- **Mnemonic**: Encrypted mnemonic storage
|
|
191
|
-
- **UsedDirectLoginToken**: One-time login token tracking
|
|
192
|
-
|
|
193
|
-
### Extending Models and Schemas
|
|
194
|
-
|
|
195
|
-
All model functions support generic type parameters for custom model names and collections:
|
|
160
|
+
### User Authentication
|
|
196
161
|
|
|
197
162
|
```typescript
|
|
198
|
-
import {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const defaultUserModel = UserModel(connection);
|
|
202
|
-
|
|
203
|
-
// Use with custom model names and collections
|
|
204
|
-
const customUserModel = UserModel(
|
|
205
|
-
connection,
|
|
206
|
-
'CustomUser',
|
|
207
|
-
'custom_users'
|
|
208
|
-
);
|
|
209
|
-
```
|
|
163
|
+
import { JwtService } from '@digitaldefiance/node-express-suite';
|
|
164
|
+
// UserService is in the mongo package if using MongoDB
|
|
165
|
+
import { UserService } from '@digitaldefiance/node-express-suite-mongo';
|
|
210
166
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
Clone and extend base schemas with additional fields:
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
import { EmailTokenSchema } from '@digitaldefiance/node-express-suite';
|
|
217
|
-
import { Schema } from 'mongoose';
|
|
167
|
+
const jwtService = new JwtService(app);
|
|
168
|
+
const userService = new UserService(app);
|
|
218
169
|
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
ExtendedEmailTokenSchema.add({
|
|
222
|
-
customField: { type: String, required: false },
|
|
223
|
-
metadata: { type: Schema.Types.Mixed, required: false },
|
|
224
|
-
});
|
|
170
|
+
const user = await userService.findByUsername('alice');
|
|
171
|
+
const { token, roles } = await jwtService.signToken(user, app.environment.jwtSecret);
|
|
225
172
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
'ExtendedEmailToken',
|
|
229
|
-
ExtendedEmailTokenSchema,
|
|
230
|
-
'extended_email_tokens'
|
|
231
|
-
);
|
|
173
|
+
const tokenUser = await jwtService.verifyToken(token);
|
|
174
|
+
console.log(`User ${tokenUser.userId} authenticated with roles:`, tokenUser.roles);
|
|
232
175
|
```
|
|
233
176
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
Create custom model functions that wrap extended schemas:
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
import { IEmailTokenDocument } from '@digitaldefiance/node-express-suite';
|
|
240
|
-
import { Connection, Model } from 'mongoose';
|
|
241
|
-
|
|
242
|
-
// Extend the document interface
|
|
243
|
-
interface IExtendedEmailTokenDocument extends IEmailTokenDocument {
|
|
244
|
-
customField?: string;
|
|
245
|
-
metadata?: any;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Create extended schema (as shown above)
|
|
249
|
-
const ExtendedEmailTokenSchema = EmailTokenSchema.clone();
|
|
250
|
-
ExtendedEmailTokenSchema.add({
|
|
251
|
-
customField: { type: String },
|
|
252
|
-
metadata: { type: Schema.Types.Mixed },
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
// Create custom model function
|
|
256
|
-
export function ExtendedEmailTokenModel<
|
|
257
|
-
TModelName extends string = 'ExtendedEmailToken',
|
|
258
|
-
TCollection extends string = 'extended_email_tokens'
|
|
259
|
-
>(
|
|
260
|
-
connection: Connection,
|
|
261
|
-
modelName: TModelName = 'ExtendedEmailToken' as TModelName,
|
|
262
|
-
collection: TCollection = 'extended_email_tokens' as TCollection,
|
|
263
|
-
): Model<IExtendedEmailTokenDocument> {
|
|
264
|
-
return connection.model<IExtendedEmailTokenDocument>(
|
|
265
|
-
modelName,
|
|
266
|
-
ExtendedEmailTokenSchema,
|
|
267
|
-
collection,
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Use the extended model
|
|
272
|
-
const model = ExtendedEmailTokenModel(connection);
|
|
273
|
-
const token = await model.create({
|
|
274
|
-
userId,
|
|
275
|
-
type: EmailTokenType.AccountVerification,
|
|
276
|
-
token: 'abc123',
|
|
277
|
-
email: 'user@example.com',
|
|
278
|
-
customField: 'custom value',
|
|
279
|
-
metadata: { source: 'api' },
|
|
280
|
-
});
|
|
281
|
-
```
|
|
177
|
+
## Core Components
|
|
282
178
|
|
|
283
|
-
|
|
179
|
+
### Plugin-Based Database Architecture
|
|
284
180
|
|
|
285
|
-
|
|
181
|
+
The framework uses a plugin-based architecture that separates database concerns from the core application. Any database backend can be used by implementing the `IDatabasePlugin` interface.
|
|
286
182
|
|
|
287
183
|
```typescript
|
|
288
|
-
import {
|
|
289
|
-
|
|
290
|
-
// Extend base enums
|
|
291
|
-
enum MyModelName {
|
|
292
|
-
User = BaseModelName.User,
|
|
293
|
-
Role = BaseModelName.Role,
|
|
294
|
-
Organization = 'Organization',
|
|
295
|
-
Project = 'Project',
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
enum MyCollection {
|
|
299
|
-
User = SchemaCollection.User,
|
|
300
|
-
Role = SchemaCollection.Role,
|
|
301
|
-
Organization = 'organizations',
|
|
302
|
-
Project = 'projects',
|
|
303
|
-
}
|
|
184
|
+
import { Application } from '@digitaldefiance/node-express-suite';
|
|
304
185
|
|
|
305
|
-
//
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
MyCollection.Organization
|
|
310
|
-
);
|
|
186
|
+
// Database-agnostic — plug in any backend
|
|
187
|
+
const app = new Application(environment, apiRouterFactory);
|
|
188
|
+
app.useDatabasePlugin(myDatabasePlugin);
|
|
189
|
+
await app.start();
|
|
311
190
|
```
|
|
312
191
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
Combining schemas, documents, and model functions:
|
|
316
|
-
|
|
317
|
-
```typescript
|
|
318
|
-
import { IUserDocument, UserSchema } from '@digitaldefiance/node-express-suite';
|
|
319
|
-
import { Connection, Model, Schema } from 'mongoose';
|
|
320
|
-
|
|
321
|
-
// 1. Extend document interface
|
|
322
|
-
interface IOrganizationUserDocument extends IUserDocument {
|
|
323
|
-
organizationId: string;
|
|
324
|
-
department?: string;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// 2. Extend schema
|
|
328
|
-
const OrganizationUserSchema = UserSchema.clone();
|
|
329
|
-
OrganizationUserSchema.add({
|
|
330
|
-
organizationId: { type: String, required: true },
|
|
331
|
-
department: { type: String },
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
// 3. Create model function
|
|
335
|
-
export function OrganizationUserModel(
|
|
336
|
-
connection: Connection,
|
|
337
|
-
): Model<IOrganizationUserDocument> {
|
|
338
|
-
return connection.model<IOrganizationUserDocument>(
|
|
339
|
-
'OrganizationUser',
|
|
340
|
-
OrganizationUserSchema,
|
|
341
|
-
'organization_users',
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// 4. Use in application
|
|
346
|
-
const model = OrganizationUserModel(connection);
|
|
347
|
-
const user = await model.create({
|
|
348
|
-
username: 'alice',
|
|
349
|
-
email: 'alice@example.com',
|
|
350
|
-
organizationId: 'org-123',
|
|
351
|
-
department: 'Engineering',
|
|
352
|
-
});
|
|
353
|
-
```
|
|
192
|
+
For MongoDB/Mongoose support, install `@digitaldefiance/node-express-suite-mongo` which provides `MongoDatabasePlugin`, `ModelRegistry`, documents, schemas, models, and all Mongoose-specific services. See that package's README for details on model registration, schema extension, and custom enumerations.
|
|
354
193
|
|
|
355
194
|
### Services
|
|
356
195
|
|
|
196
|
+
> **Note:** `UserService`, `RoleService`, `BackupCodeService`, and `DatabaseInitializationService` have moved to
|
|
197
|
+
> `@digitaldefiance/node-express-suite-mongo`. The services below remain in this package.
|
|
198
|
+
|
|
357
199
|
#### ECIESService
|
|
358
200
|
|
|
359
201
|
Encryption and key management:
|
|
@@ -405,10 +247,10 @@ const unwrapped = await keyWrapping.unwrapKey(
|
|
|
405
247
|
|
|
406
248
|
#### RoleService
|
|
407
249
|
|
|
408
|
-
|
|
250
|
+
> Available in `@digitaldefiance/node-express-suite-mongo`.
|
|
409
251
|
|
|
410
252
|
```typescript
|
|
411
|
-
import { RoleService } from '@digitaldefiance/node-express-suite';
|
|
253
|
+
import { RoleService } from '@digitaldefiance/node-express-suite-mongo';
|
|
412
254
|
|
|
413
255
|
const roleService = new RoleService(app);
|
|
414
256
|
|
|
@@ -428,10 +270,10 @@ const adminRole = await roleService.createRole({
|
|
|
428
270
|
|
|
429
271
|
#### BackupCodeService
|
|
430
272
|
|
|
431
|
-
|
|
273
|
+
> Available in `@digitaldefiance/node-express-suite-mongo`.
|
|
432
274
|
|
|
433
275
|
```typescript
|
|
434
|
-
import { BackupCodeService } from '@digitaldefiance/node-express-suite';
|
|
276
|
+
import { BackupCodeService } from '@digitaldefiance/node-express-suite-mongo';
|
|
435
277
|
|
|
436
278
|
const backupCodeService = new BackupCodeService(app);
|
|
437
279
|
|
|
@@ -447,10 +289,10 @@ await backupCodeService.useBackupCode(userId, userCode);
|
|
|
447
289
|
|
|
448
290
|
### Database Initialization
|
|
449
291
|
|
|
450
|
-
|
|
292
|
+
> Available in `@digitaldefiance/node-express-suite-mongo`.
|
|
451
293
|
|
|
452
294
|
```typescript
|
|
453
|
-
import { DatabaseInitializationService } from '@digitaldefiance/node-express-suite';
|
|
295
|
+
import { DatabaseInitializationService } from '@digitaldefiance/node-express-suite-mongo';
|
|
454
296
|
|
|
455
297
|
// Initialize with default admin, member, and system users
|
|
456
298
|
const result = await DatabaseInitializationService.initUserDb(app);
|
|
@@ -748,14 +590,7 @@ Let's Encrypt mode and the dev-certificate HTTPS mode (`HTTPS_DEV_CERT_ROOT`) ar
|
|
|
748
590
|
|
|
749
591
|
### Security
|
|
750
592
|
|
|
751
|
-
1. **Always use environment variables** for sensitive configuration
|
|
752
|
-
|
|
753
|
-
```typescript
|
|
754
|
-
const app = new Application({
|
|
755
|
-
jwtSecret: process.env.JWT_SECRET,
|
|
756
|
-
mongoUri: process.env.MONGO_URI,
|
|
757
|
-
});
|
|
758
|
-
```
|
|
593
|
+
1. **Always use environment variables** for sensitive configuration (JWT secrets, database URIs, API keys)
|
|
759
594
|
|
|
760
595
|
2. **Validate all user input** before processing:
|
|
761
596
|
|
|
@@ -798,83 +633,66 @@ Let's Encrypt mode and the dev-certificate HTTPS mode (`HTTPS_DEV_CERT_ROOT`) ar
|
|
|
798
633
|
}
|
|
799
634
|
```
|
|
800
635
|
|
|
801
|
-
3. **Use database indexes** for common queries
|
|
802
|
-
|
|
803
|
-
```typescript
|
|
804
|
-
userSchema.index({ email: 1 }, { unique: true });
|
|
805
|
-
userSchema.index({ username: 1 }, { unique: true });
|
|
806
|
-
```
|
|
636
|
+
3. **Use database indexes** for common queries (see your database plugin's documentation for index configuration)
|
|
807
637
|
|
|
808
638
|
## API Reference
|
|
809
639
|
|
|
810
640
|
### Application
|
|
811
641
|
|
|
812
|
-
- `new Application(
|
|
813
|
-
- `
|
|
814
|
-
- `
|
|
815
|
-
- `
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
- `
|
|
821
|
-
- `
|
|
822
|
-
- `
|
|
823
|
-
- `
|
|
824
|
-
- `
|
|
825
|
-
- `
|
|
826
|
-
- `
|
|
827
|
-
- `
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
- `
|
|
834
|
-
- `
|
|
642
|
+
- `new Application(environment, apiRouterFactory, ...)` — Create application instance
|
|
643
|
+
- `useDatabasePlugin(plugin)` — Register a database plugin
|
|
644
|
+
- `start()` — Start the Express server
|
|
645
|
+
- `stop()` — Stop the server gracefully
|
|
646
|
+
- `environment` — Access configuration
|
|
647
|
+
|
|
648
|
+
### Services (this package)
|
|
649
|
+
|
|
650
|
+
- `ECIESService` — Encryption and key management
|
|
651
|
+
- `KeyWrappingService` — Secure key storage
|
|
652
|
+
- `JwtService` — JWT token operations
|
|
653
|
+
- `ChecksumService` — CRC checksum operations
|
|
654
|
+
- `SymmetricService` — Symmetric encryption operations
|
|
655
|
+
- `XorService` — XOR cipher operations
|
|
656
|
+
- `FecService` — Forward error correction
|
|
657
|
+
- `DummyEmailService` — Test email service implementation
|
|
658
|
+
|
|
659
|
+
### Services (mongo package)
|
|
660
|
+
|
|
661
|
+
These services are available in `@digitaldefiance/node-express-suite-mongo`:
|
|
662
|
+
|
|
663
|
+
- `UserService` — User account operations
|
|
664
|
+
- `RoleService` — Role and permission management
|
|
665
|
+
- `BackupCodeService` — Backup code management
|
|
666
|
+
- `DatabaseInitializationService` — Database initialization with default users and roles
|
|
667
|
+
- `MnemonicService` — Mnemonic storage and retrieval
|
|
668
|
+
- `DirectLoginTokenService` — One-time login token management
|
|
669
|
+
- `RequestUserService` — Extract user from request context
|
|
670
|
+
- `MongoBaseService` — Mongoose-specific service base class
|
|
671
|
+
- `MongoAuthenticationProvider` — Mongoose-backed authentication
|
|
835
672
|
|
|
836
673
|
### Utilities
|
|
837
674
|
|
|
838
|
-
- `
|
|
839
|
-
- `
|
|
840
|
-
- `withTransaction()` - MongoDB transaction wrapper
|
|
675
|
+
- `debugLog()` — Conditional logging utility
|
|
676
|
+
- `withTransaction()` — Database-agnostic transaction wrapper (IDatabase overload)
|
|
841
677
|
|
|
842
678
|
## Testing
|
|
843
679
|
|
|
844
680
|
### Testing Approach
|
|
845
681
|
|
|
846
|
-
The node-express-suite package uses comprehensive testing
|
|
682
|
+
The node-express-suite package uses comprehensive testing covering all services, middleware, controllers, and core operations.
|
|
847
683
|
|
|
848
|
-
**Test Framework**: Jest with TypeScript support
|
|
849
|
-
**Property-Based Testing**: fast-check for validation properties
|
|
850
|
-
**Coverage**: 57.86% overall, 100% on critical paths
|
|
851
|
-
**Database**: MongoDB Memory Server for isolated testing
|
|
852
|
-
|
|
853
|
-
### Test Structure
|
|
854
|
-
|
|
855
|
-
```
|
|
856
|
-
tests/
|
|
857
|
-
├── unit/ # Unit tests for services and utilities
|
|
858
|
-
├── integration/ # Integration tests for multi-service flows
|
|
859
|
-
├── e2e/ # End-to-end API tests
|
|
860
|
-
├── middleware/ # Middleware tests
|
|
861
|
-
└── fixtures/ # Test data and mocks
|
|
862
|
-
```
|
|
684
|
+
**Test Framework**: Jest with TypeScript support
|
|
685
|
+
**Property-Based Testing**: fast-check for validation properties
|
|
686
|
+
**Coverage**: 57.86% overall, 100% on critical paths
|
|
863
687
|
|
|
864
688
|
### Running Tests
|
|
865
689
|
|
|
866
690
|
```bash
|
|
867
691
|
# Run all tests
|
|
868
|
-
|
|
692
|
+
yarn nx test digitaldefiance-node-express-suite
|
|
869
693
|
|
|
870
694
|
# Run with coverage
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
# Run specific test suite
|
|
874
|
-
npm test -- user-service.spec.ts
|
|
875
|
-
|
|
876
|
-
# Run in watch mode
|
|
877
|
-
npm test -- --watch
|
|
695
|
+
yarn nx test digitaldefiance-node-express-suite --coverage
|
|
878
696
|
```
|
|
879
697
|
|
|
880
698
|
### Test Patterns
|
|
@@ -882,33 +700,27 @@ npm test -- --watch
|
|
|
882
700
|
#### Testing Services
|
|
883
701
|
|
|
884
702
|
```typescript
|
|
885
|
-
import {
|
|
703
|
+
import { Application, JwtService } from '@digitaldefiance/node-express-suite';
|
|
886
704
|
|
|
887
|
-
describe('
|
|
705
|
+
describe('JwtService', () => {
|
|
888
706
|
let app: Application;
|
|
889
|
-
let
|
|
707
|
+
let jwtService: JwtService;
|
|
890
708
|
|
|
891
709
|
beforeAll(async () => {
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
jwtSecret: 'test-secret'
|
|
895
|
-
});
|
|
710
|
+
// Set up your application with appropriate database plugin
|
|
711
|
+
app = new Application(environment, apiRouterFactory);
|
|
896
712
|
await app.start();
|
|
897
|
-
|
|
713
|
+
jwtService = new JwtService(app);
|
|
898
714
|
});
|
|
899
715
|
|
|
900
716
|
afterAll(async () => {
|
|
901
717
|
await app.stop();
|
|
902
718
|
});
|
|
903
719
|
|
|
904
|
-
it('should
|
|
905
|
-
const
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
password: 'SecurePass123!'
|
|
909
|
-
});
|
|
910
|
-
|
|
911
|
-
expect(user.username).toBe('alice');
|
|
720
|
+
it('should sign and verify token', async () => {
|
|
721
|
+
const { token } = await jwtService.signToken(user, app.environment.jwtSecret);
|
|
722
|
+
const verified = await jwtService.verifyToken(token);
|
|
723
|
+
expect(verified.userId).toBeDefined();
|
|
912
724
|
});
|
|
913
725
|
});
|
|
914
726
|
```
|
|
@@ -939,66 +751,28 @@ describe('Auth Middleware', () => {
|
|
|
939
751
|
#### Testing Controllers
|
|
940
752
|
|
|
941
753
|
```typescript
|
|
942
|
-
import {
|
|
754
|
+
import { DecoratorBaseController } from '@digitaldefiance/node-express-suite';
|
|
943
755
|
|
|
944
|
-
describe('
|
|
945
|
-
it('should
|
|
946
|
-
|
|
947
|
-
const req = {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
email: 'alice@example.com',
|
|
951
|
-
password: 'SecurePass123!'
|
|
952
|
-
}
|
|
953
|
-
} as Request;
|
|
954
|
-
|
|
955
|
-
const result = await controller.register(req, res, next);
|
|
956
|
-
|
|
957
|
-
expect(result.statusCode).toBe(201);
|
|
958
|
-
expect(result.response.data.user).toBeDefined();
|
|
756
|
+
describe('MyController', () => {
|
|
757
|
+
it('should handle requests', async () => {
|
|
758
|
+
// Test your controller endpoints
|
|
759
|
+
const req = { body: { /* ... */ } } as Request;
|
|
760
|
+
const result = await controller.handleRequest(req, res, next);
|
|
761
|
+
expect(result.statusCode).toBe(200);
|
|
959
762
|
});
|
|
960
763
|
});
|
|
961
764
|
```
|
|
962
765
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
```typescript
|
|
966
|
-
import { connectMemoryDB, disconnectMemoryDB, clearMemoryDB } from '@digitaldefiance/express-suite-test-utils';
|
|
967
|
-
import { UserModel } from '@digitaldefiance/node-express-suite';
|
|
968
|
-
|
|
969
|
-
describe('User Model', () => {
|
|
970
|
-
beforeAll(async () => {
|
|
971
|
-
await connectMemoryDB();
|
|
972
|
-
});
|
|
973
|
-
|
|
974
|
-
afterAll(async () => {
|
|
975
|
-
await disconnectMemoryDB();
|
|
976
|
-
});
|
|
977
|
-
|
|
978
|
-
afterEach(async () => {
|
|
979
|
-
await clearMemoryDB();
|
|
980
|
-
});
|
|
981
|
-
|
|
982
|
-
it('should validate user schema', async () => {
|
|
983
|
-
const User = UserModel(connection);
|
|
984
|
-
const user = new User({
|
|
985
|
-
username: 'alice',
|
|
986
|
-
email: 'alice@example.com'
|
|
987
|
-
});
|
|
988
|
-
|
|
989
|
-
await expect(user.validate()).resolves.not.toThrow();
|
|
990
|
-
});
|
|
991
|
-
});
|
|
992
|
-
```
|
|
766
|
+
> For testing Mongo-specific controllers (e.g., `UserController`), database operations, and model validation,
|
|
767
|
+
> see the testing documentation in `@digitaldefiance/node-express-suite-mongo`.
|
|
993
768
|
|
|
994
769
|
### Testing Best Practices
|
|
995
770
|
|
|
996
|
-
1. **
|
|
997
|
-
2. **Test
|
|
998
|
-
3. **
|
|
999
|
-
4. **Test
|
|
1000
|
-
5. **
|
|
1001
|
-
6. **Test authentication** and authorization flows
|
|
771
|
+
1. **Mock external services** like email providers
|
|
772
|
+
2. **Test error conditions** and edge cases
|
|
773
|
+
3. **Test middleware** in isolation and integration
|
|
774
|
+
4. **Test authentication** and authorization flows
|
|
775
|
+
5. **Use property-based testing** for validation logic
|
|
1002
776
|
|
|
1003
777
|
### Cross-Package Testing
|
|
1004
778
|
|
|
@@ -1007,21 +781,15 @@ Testing integration with other Express Suite packages:
|
|
|
1007
781
|
```typescript
|
|
1008
782
|
import { Application } from '@digitaldefiance/node-express-suite';
|
|
1009
783
|
import { ECIESService } from '@digitaldefiance/node-ecies-lib';
|
|
1010
|
-
import { IBackendUser } from '@digitaldefiance/suite-core-lib';
|
|
1011
784
|
|
|
1012
785
|
describe('Cross-Package Integration', () => {
|
|
1013
|
-
it('should integrate ECIES with
|
|
1014
|
-
const app = new Application(
|
|
786
|
+
it('should integrate ECIES with application', async () => {
|
|
787
|
+
const app = new Application(environment, apiRouterFactory);
|
|
1015
788
|
const ecies = new ECIESService();
|
|
1016
789
|
|
|
1017
|
-
//
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
email: 'alice@example.com',
|
|
1021
|
-
// ... encrypted fields
|
|
1022
|
-
});
|
|
1023
|
-
|
|
1024
|
-
expect(user).toBeDefined();
|
|
790
|
+
// Test encryption/decryption within the application context
|
|
791
|
+
const mnemonic = ecies.generateNewMnemonic();
|
|
792
|
+
expect(mnemonic).toBeDefined();
|
|
1025
793
|
});
|
|
1026
794
|
});
|
|
1027
795
|
```
|
|
@@ -1041,7 +809,7 @@ The decorator API provides a declarative, type-safe approach to building Express
|
|
|
1041
809
|
| Validation | `@ValidateBody`, `@ValidateParams`, `@ValidateQuery` | Validate request data with Zod or express-validator |
|
|
1042
810
|
| Response | `@Returns`, `@ResponseDoc`, `@RawJson`, `@Paginated` | Document response types for OpenAPI |
|
|
1043
811
|
| Middleware | `@UseMiddleware`, `@CacheResponse`, `@RateLimit` | Attach middleware to routes |
|
|
1044
|
-
| Transaction | `@Transactional` | Wrap
|
|
812
|
+
| Transaction | `@Transactional` | Wrap handler in a database transaction |
|
|
1045
813
|
| OpenAPI | `@ApiOperation`, `@ApiTags`, `@ApiSummary`, `@ApiDescription`, `@Deprecated`, `@ApiOperationId`, `@ApiExample` | Add OpenAPI documentation |
|
|
1046
814
|
| OpenAPI Params | `@ApiParam`, `@ApiQuery`, `@ApiHeader`, `@ApiRequestBody` | Document parameters with full OpenAPI metadata |
|
|
1047
815
|
| Lifecycle | `@OnSuccess`, `@OnError`, `@Before`, `@After` | Hook into request lifecycle events |
|
|
@@ -1374,9 +1142,6 @@ async bulkCreate() {}
|
|
|
1374
1142
|
```
|
|
1375
1143
|
|
|
1376
1144
|
### OpenAPI Operation Decorators
|
|
1377
|
-
|
|
1378
|
-
```typescript
|
|
1379
|
-
// Full operation metadata
|
|
1380
1145
|
@ApiOperation({
|
|
1381
1146
|
summary: 'Get user by ID',
|
|
1382
1147
|
description: 'Retrieves a user by their unique identifier',
|
|
@@ -1736,14 +1501,13 @@ For detailed migration instructions, see [docs/DECORATOR_MIGRATION.md](./docs/DE
|
|
|
1736
1501
|
|
|
1737
1502
|
### Quick Links
|
|
1738
1503
|
|
|
1739
|
-
- **[📚 Documentation Index](./docs/INDEX.md)**
|
|
1740
|
-
- **[🏗️ Architecture](./docs/ARCHITECTURE.md)**
|
|
1741
|
-
- **[🎮 Controllers](./docs/CONTROLLERS.md)**
|
|
1742
|
-
- **[⚙️ Services](./docs/SERVICES.md)**
|
|
1743
|
-
- **[📊 Models](./docs/MODELS.md)**
|
|
1744
|
-
- **[🔌 Middleware](./docs/MIDDLEWARE.md)**
|
|
1745
|
-
- **[
|
|
1746
|
-
- **[🔧 Plugins](./docs/PLUGINS.md)** - Plugin system
|
|
1504
|
+
- **[📚 Documentation Index](./docs/INDEX.md)** — Complete documentation index
|
|
1505
|
+
- **[🏗️ Architecture](./docs/ARCHITECTURE.md)** — System design and architecture
|
|
1506
|
+
- **[🎮 Controllers](./docs/CONTROLLERS.md)** — Controller system and decorators
|
|
1507
|
+
- **[⚙️ Services](./docs/SERVICES.md)** — Business logic and service container
|
|
1508
|
+
- **[📊 Models](./docs/MODELS.md)** — Database plugin interface
|
|
1509
|
+
- **[🔌 Middleware](./docs/MIDDLEWARE.md)** — Request pipeline
|
|
1510
|
+
- **[� Mongo Split Migration](./docs/MONGO_SPLIT_MIGRATION.md)** — Migrating to the two-package architecture
|
|
1747
1511
|
|
|
1748
1512
|
See the [full documentation index](./docs/INDEX.md) for all available documentation.
|
|
1749
1513
|
|
|
@@ -1753,10 +1517,11 @@ MIT © Digital Defiance
|
|
|
1753
1517
|
|
|
1754
1518
|
## Related Packages
|
|
1755
1519
|
|
|
1756
|
-
- `@digitaldefiance/
|
|
1757
|
-
- `@digitaldefiance/
|
|
1758
|
-
- `@digitaldefiance/
|
|
1759
|
-
- `@digitaldefiance/
|
|
1520
|
+
- `@digitaldefiance/node-express-suite-mongo` — MongoDB/Mongoose plugin for this package
|
|
1521
|
+
- `@digitaldefiance/ecies-lib` — Core ECIES encryption library
|
|
1522
|
+
- `@digitaldefiance/node-ecies-lib` — Node.js ECIES implementation
|
|
1523
|
+
- `@digitaldefiance/i18n-lib` — Internationalization framework
|
|
1524
|
+
- `@digitaldefiance/suite-core-lib` — Core user management primitives
|
|
1760
1525
|
|
|
1761
1526
|
## Contributing
|
|
1762
1527
|
|
|
@@ -1781,9 +1546,9 @@ BaseApplication<TID> ← Database-agnostic base (accepts IDatabase)
|
|
|
1781
1546
|
└── useDatabasePlugin() ← Plug in any database backend
|
|
1782
1547
|
|
|
1783
1548
|
IDatabasePlugin<TID> ← Plugin interface for database backends
|
|
1784
|
-
└── MongoDatabasePlugin ← Mongoose/MongoDB implementation
|
|
1549
|
+
└── MongoDatabasePlugin ← Mongoose/MongoDB implementation (in node-express-suite-mongo)
|
|
1785
1550
|
|
|
1786
|
-
MongoApplicationConcrete ← Ready-to-use concrete class
|
|
1551
|
+
MongoApplicationConcrete ← Ready-to-use concrete class (in node-express-suite-mongo)
|
|
1787
1552
|
```
|
|
1788
1553
|
|
|
1789
1554
|
### Core Classes
|
|
@@ -1792,7 +1557,7 @@ MongoApplicationConcrete ← Ready-to-use concrete class for testing/dev
|
|
|
1792
1557
|
|-------|---------|
|
|
1793
1558
|
| `BaseApplication<TID>` | Database-agnostic base. Accepts an `IDatabase` instance and optional lifecycle hooks. Manages `PluginManager`, `ServiceContainer`, and environment. |
|
|
1794
1559
|
| `Application<TID>` | Extends `BaseApplication` with Express HTTP/HTTPS server, routing, CSP/Helmet config, and middleware. Database-agnostic — database backends are provided via `IDatabasePlugin`. |
|
|
1795
|
-
| `MongoApplicationConcrete<TID>` | Concrete `Application` subclass for testing/development. Wires up `MongoDatabasePlugin` with default configuration, schema maps, and a dummy email service.
|
|
1560
|
+
| `MongoApplicationConcrete<TID>` | Concrete `Application` subclass for testing/development (in `node-express-suite-mongo`). Wires up `MongoDatabasePlugin` with default configuration, schema maps, and a dummy email service. |
|
|
1796
1561
|
|
|
1797
1562
|
### IDatabasePlugin Interface
|
|
1798
1563
|
|
|
@@ -1816,10 +1581,12 @@ interface IDatabasePlugin<TID> extends IApplicationPlugin<TID> {
|
|
|
1816
1581
|
|
|
1817
1582
|
### MongoDatabasePlugin
|
|
1818
1583
|
|
|
1584
|
+
> Available in `@digitaldefiance/node-express-suite-mongo`.
|
|
1585
|
+
|
|
1819
1586
|
`MongoDatabasePlugin` implements `IDatabasePlugin` for MongoDB/Mongoose:
|
|
1820
1587
|
|
|
1821
1588
|
```typescript
|
|
1822
|
-
import { MongoDatabasePlugin } from '@digitaldefiance/node-express-suite';
|
|
1589
|
+
import { MongoDatabasePlugin } from '@digitaldefiance/node-express-suite-mongo';
|
|
1823
1590
|
|
|
1824
1591
|
const mongoPlugin = new MongoDatabasePlugin({
|
|
1825
1592
|
schemaMapFactory: getSchemaMap,
|
|
@@ -1859,6 +1626,9 @@ The `database` parameter is optional. When using a database plugin, the plugin's
|
|
|
1859
1626
|
Use `useDatabasePlugin()` to register a database plugin with the application:
|
|
1860
1627
|
|
|
1861
1628
|
```typescript
|
|
1629
|
+
import { Application } from '@digitaldefiance/node-express-suite';
|
|
1630
|
+
import { MongoDatabasePlugin } from '@digitaldefiance/node-express-suite-mongo';
|
|
1631
|
+
|
|
1862
1632
|
const app = new Application(environment, apiRouterFactory);
|
|
1863
1633
|
app.useDatabasePlugin(mongoPlugin);
|
|
1864
1634
|
await app.start();
|
|
@@ -1953,7 +1723,8 @@ await app.start();
|
|
|
1953
1723
|
|
|
1954
1724
|
```typescript
|
|
1955
1725
|
// New: Application is database-agnostic, MongoDatabasePlugin provides Mongo support
|
|
1956
|
-
import {
|
|
1726
|
+
import { Application } from '@digitaldefiance/node-express-suite';
|
|
1727
|
+
import { MongoApplicationConcrete } from '@digitaldefiance/node-express-suite-mongo';
|
|
1957
1728
|
|
|
1958
1729
|
// For testing/development (drop-in replacement for the old concrete class):
|
|
1959
1730
|
const app = new MongoApplicationConcrete(environment);
|
|
@@ -1963,7 +1734,12 @@ await app.start();
|
|
|
1963
1734
|
Or for custom wiring:
|
|
1964
1735
|
|
|
1965
1736
|
```typescript
|
|
1966
|
-
import { Application
|
|
1737
|
+
import { Application } from '@digitaldefiance/node-express-suite';
|
|
1738
|
+
import {
|
|
1739
|
+
MongoDatabasePlugin,
|
|
1740
|
+
DatabaseInitializationService,
|
|
1741
|
+
getSchemaMap,
|
|
1742
|
+
} from '@digitaldefiance/node-express-suite-mongo';
|
|
1967
1743
|
|
|
1968
1744
|
const app = new Application(environment, apiRouterFactory);
|
|
1969
1745
|
|
|
@@ -1983,14 +1759,14 @@ await app.start();
|
|
|
1983
1759
|
|
|
1984
1760
|
| Old Name | New Name | Notes |
|
|
1985
1761
|
|----------|----------|-------|
|
|
1986
|
-
| Old concrete class | `MongoApplicationConcrete` | Drop-in replacement for testing/dev |
|
|
1762
|
+
| Old concrete class | `MongoApplicationConcrete` (in `node-express-suite-mongo`) | Drop-in replacement for testing/dev |
|
|
1987
1763
|
| Old Mongo base class | *(removed)* | Functionality moved to `BaseApplication` + `MongoDatabasePlugin` |
|
|
1988
1764
|
| Old base file | `base-application.ts` | File renamed |
|
|
1989
1765
|
| Old concrete file | `mongo-application-concrete.ts` | File renamed |
|
|
1990
1766
|
|
|
1991
1767
|
### Migration Checklist
|
|
1992
1768
|
|
|
1993
|
-
- [ ] Replace the old concrete class with `MongoApplicationConcrete`
|
|
1769
|
+
- [ ] Replace the old concrete class with `MongoApplicationConcrete` (from `node-express-suite-mongo`)
|
|
1994
1770
|
- [ ] Replace any old Mongo base subclasses with `Application` + `useDatabasePlugin()`
|
|
1995
1771
|
- [ ] Update imports to use `base-application` (renamed from old base file)
|
|
1996
1772
|
- [ ] Update imports to use `mongo-application-concrete` (renamed from old concrete file)
|
|
@@ -2009,7 +1785,6 @@ await app.start();
|
|
|
2009
1785
|
```typescript
|
|
2010
1786
|
// Centralized dependency injection
|
|
2011
1787
|
const jwtService = app.services.get(ServiceKeys.JWT);
|
|
2012
|
-
const userService = app.services.get(ServiceKeys.USER);
|
|
2013
1788
|
```
|
|
2014
1789
|
|
|
2015
1790
|
#### Simplified Generics
|
|
@@ -2109,16 +1884,12 @@ class UserController<TConfig extends ControllerConfig, TLanguage>
|
|
|
2109
1884
|
|
|
2110
1885
|
```typescript
|
|
2111
1886
|
const jwtService = new JwtService(app);
|
|
2112
|
-
const userService = new UserService(app);
|
|
2113
|
-
const roleService = new RoleService(app);
|
|
2114
1887
|
```
|
|
2115
1888
|
|
|
2116
1889
|
**After (v2.0):**
|
|
2117
1890
|
|
|
2118
1891
|
```typescript
|
|
2119
1892
|
const jwtService = app.services.get(ServiceKeys.JWT);
|
|
2120
|
-
const userService = app.services.get(ServiceKeys.USER);
|
|
2121
|
-
const roleService = app.services.get(ServiceKeys.ROLE);
|
|
2122
1893
|
```
|
|
2123
1894
|
|
|
2124
1895
|
**Migration:**
|
|
@@ -2126,6 +1897,7 @@ const roleService = app.services.get(ServiceKeys.ROLE);
|
|
|
2126
1897
|
- Replace direct service instantiation with container access
|
|
2127
1898
|
- Services are now singletons managed by the container
|
|
2128
1899
|
- Import ServiceKeys enum for type-safe service access
|
|
1900
|
+
- Note: `UserService`, `RoleService`, and other Mongo-specific services are now in `@digitaldefiance/node-express-suite-mongo`
|
|
2129
1901
|
|
|
2130
1902
|
### Recommended Migrations (Non-Breaking)
|
|
2131
1903
|
|
|
@@ -2278,7 +2050,6 @@ yarn add @digitaldefiance/node-express-suite@^2.0.0
|
|
|
2278
2050
|
```typescript
|
|
2279
2051
|
const app = new Application<MyTypes, MyIds, MyResults, MyModels, MyDoc, MyEnv, MyConst, MyRouter>({
|
|
2280
2052
|
port: 3000,
|
|
2281
|
-
mongoUri: process.env.MONGO_URI,
|
|
2282
2053
|
jwtSecret: process.env.JWT_SECRET
|
|
2283
2054
|
});
|
|
2284
2055
|
```
|
|
@@ -2286,11 +2057,9 @@ const app = new Application<MyTypes, MyIds, MyResults, MyModels, MyDoc, MyEnv, M
|
|
|
2286
2057
|
**After:**
|
|
2287
2058
|
|
|
2288
2059
|
```typescript
|
|
2289
|
-
const app = new Application(
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
jwtSecret: process.env.JWT_SECRET
|
|
2293
|
-
});
|
|
2060
|
+
const app = new Application(environment, apiRouterFactory);
|
|
2061
|
+
// If using MongoDB, register the plugin from node-express-suite-mongo:
|
|
2062
|
+
// app.useDatabasePlugin(mongoPlugin);
|
|
2294
2063
|
```
|
|
2295
2064
|
|
|
2296
2065
|
#### Step 3: Update Service Access
|
|
@@ -2302,13 +2071,11 @@ Find and replace service instantiation:
|
|
|
2302
2071
|
new JwtService(app)
|
|
2303
2072
|
# Replace with
|
|
2304
2073
|
app.services.get(ServiceKeys.JWT)
|
|
2305
|
-
|
|
2306
|
-
# Find
|
|
2307
|
-
new UserService(app)
|
|
2308
|
-
# Replace with
|
|
2309
|
-
app.services.get(ServiceKeys.USER)
|
|
2310
2074
|
```
|
|
2311
2075
|
|
|
2076
|
+
> Note: `UserService`, `RoleService`, and other Mongo-specific services are now in
|
|
2077
|
+
> `@digitaldefiance/node-express-suite-mongo`. Update those imports accordingly.
|
|
2078
|
+
|
|
2312
2079
|
#### Step 4: Migrate Controllers (Gradual)
|
|
2313
2080
|
|
|
2314
2081
|
Start with high-traffic endpoints:
|
|
@@ -2322,13 +2089,13 @@ Start with high-traffic endpoints:
|
|
|
2322
2089
|
|
|
2323
2090
|
```bash
|
|
2324
2091
|
# Run full test suite
|
|
2325
|
-
|
|
2092
|
+
yarn nx test digitaldefiance-node-express-suite
|
|
2326
2093
|
|
|
2327
|
-
# Run specific
|
|
2328
|
-
|
|
2094
|
+
# Run specific test suites
|
|
2095
|
+
yarn nx test digitaldefiance-node-express-suite --testPathPatterns="jwt"
|
|
2329
2096
|
|
|
2330
2097
|
# Check for deprecation warnings
|
|
2331
|
-
DEBUG=*
|
|
2098
|
+
DEBUG=* yarn start
|
|
2332
2099
|
```
|
|
2333
2100
|
|
|
2334
2101
|
### Migration Checklist
|
|
@@ -2384,17 +2151,16 @@ The following v1.x patterns still work in v2.0:
|
|
|
2384
2151
|
|
|
2385
2152
|
### Getting Help
|
|
2386
2153
|
|
|
2387
|
-
- **Documentation**: See
|
|
2388
|
-
- **
|
|
2154
|
+
- **Documentation**: See [docs/INDEX.md](docs/INDEX.md) for the complete documentation index
|
|
2155
|
+
- **Migration**: See [docs/MONGO_SPLIT_MIGRATION.md](docs/MONGO_SPLIT_MIGRATION.md) for the package split migration
|
|
2389
2156
|
- **Issues**: Report bugs at GitHub Issues
|
|
2390
2157
|
- **Support**: Email <support@digitaldefiance.org>
|
|
2391
2158
|
|
|
2392
2159
|
### Additional Resources
|
|
2393
2160
|
|
|
2394
|
-
- [
|
|
2395
|
-
- [
|
|
2396
|
-
- [
|
|
2397
|
-
- [Architecture Plan](ARCHITECTURE_REFACTOR_PLAN.md)
|
|
2161
|
+
- [Mongo Split Migration](docs/MONGO_SPLIT_MIGRATION.md)
|
|
2162
|
+
- [Decorator Migration](docs/DECORATOR_MIGRATION.md)
|
|
2163
|
+
- [Architecture Overview](docs/ARCHITECTURE.md)
|
|
2398
2164
|
|
|
2399
2165
|
---
|
|
2400
2166
|
|
|
@@ -2672,7 +2438,7 @@ This release introduces a complete decorator-based API for defining controllers,
|
|
|
2672
2438
|
- `@RateLimit(options)` - Add rate limiting middleware (auto-adds 429 response)
|
|
2673
2439
|
|
|
2674
2440
|
*Transaction Decorator:*
|
|
2675
|
-
- `@Transactional(options?)` - Wrap handler in
|
|
2441
|
+
- `@Transactional(options?)` - Wrap handler in a database transaction with optional timeout
|
|
2676
2442
|
|
|
2677
2443
|
*OpenAPI Operation Decorators:*
|
|
2678
2444
|
- `@ApiOperation(metadata)` - Set full OpenAPI operation metadata
|
|
@@ -3108,7 +2874,7 @@ This release introduces a complete decorator-based API for defining controllers,
|
|
|
3108
2874
|
### Version 2.1.24
|
|
3109
2875
|
|
|
3110
2876
|
- Provide mocks/fixtures for use in testing
|
|
3111
|
-
- Provide concrete/runnable MongoApplicationConcrete class
|
|
2877
|
+
- Provide concrete/runnable MongoApplicationConcrete class (now in `node-express-suite-mongo`)
|
|
3112
2878
|
- Export DummyEmailService for testing
|
|
3113
2879
|
- Further streamline Application generics
|
|
3114
2880
|
|