@koalarx/nest 1.19.0 → 3.0.1
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/CHANGELOG.md +15 -0
- package/package.json +5 -37
- package/src/core/backgroud-services/cron-service/cron-job.handler.base.ts +66 -0
- package/src/core/backgroud-services/cron-service/cron-job.handler.spec.ts +38 -0
- package/src/core/backgroud-services/event-service/event-class.ts +5 -0
- package/src/core/backgroud-services/event-service/event-handler.base.ts +17 -0
- package/src/core/backgroud-services/event-service/event-is-trigger.ts +3 -0
- package/src/core/backgroud-services/event-service/event-job.ts +28 -0
- package/src/core/backgroud-services/event-service/event-queue.spec.ts +47 -0
- package/src/core/backgroud-services/event-service/event-queue.ts +107 -0
- package/src/core/constants/query-params.ts +7 -0
- package/src/core/controllers/base.controller.ts +9 -0
- package/src/core/controllers/controller.decorator.ts +10 -0
- package/src/core/controllers/created-registre-response.base.ts +17 -0
- package/src/core/controllers/list-response.base.ts +8 -0
- package/src/core/controllers/pagination.request.ts +41 -0
- package/src/core/controllers/router-config.base.ts +14 -0
- package/src/core/controllers/schemas/boolean.schema.ts +10 -0
- package/src/core/controllers/schemas/document-number.schema.ts +23 -0
- package/src/core/controllers/schemas/email.schema.ts +13 -0
- package/src/core/controllers/schemas/list-query.schema.ts +17 -0
- package/src/core/controllers/schemas/native-enum.schema.ts +34 -0
- package/src/core/controllers/schemas/set-mask-document-number.schema.ts +13 -0
- package/src/core/database/entity.base.ts +95 -0
- package/src/core/database/entity.decorator.spec.ts +71 -0
- package/src/core/database/entity.decorator.ts +39 -0
- package/src/core/database/prisma-client-with-custom-transaction.interface.ts +13 -0
- package/src/core/database/prisma-resolver.ts +99 -0
- package/src/core/database/prisma-transactional-client.ts +43 -0
- package/src/core/database/prisma.service.ts +136 -0
- package/src/core/database/repository.base.ts +548 -0
- package/src/core/dtos/pagination.dto.ts +35 -0
- package/src/core/errors/bad-request.error.ts +8 -0
- package/src/core/errors/conflict.error.ts +7 -0
- package/src/core/errors/error.base.ts +5 -0
- package/src/core/errors/no-content.error.ts +8 -0
- package/src/core/errors/not-allowed.error.ts +8 -0
- package/src/core/errors/resource-not-found.error.ts +8 -0
- package/{core/errors/use-case-error.d.ts → src/core/errors/use-case-error.ts} +1 -1
- package/src/core/errors/user-already-exist.error.ts +7 -0
- package/src/core/errors/wrong-credentials.error.ts +7 -0
- package/src/core/health-check/health-check.controller.ts +13 -0
- package/src/core/health-check/health-check.module.ts +7 -0
- package/src/core/index.ts +56 -0
- package/src/core/koala-app.ts +379 -0
- package/src/core/koala-global-vars.ts +8 -0
- package/src/core/koala-nest-database.module.ts +65 -0
- package/src/core/koala-nest-http.module.ts +44 -0
- package/src/core/koala-nest.module.ts +67 -0
- package/src/core/mapping/auto-mapping-class-context.ts +28 -0
- package/src/core/mapping/auto-mapping-context.ts +26 -0
- package/src/core/mapping/auto-mapping-list.ts +154 -0
- package/src/core/mapping/auto-mapping-profile.ts +3 -0
- package/src/core/mapping/auto-mapping.decorator.ts +54 -0
- package/src/core/mapping/auto-mapping.module.ts +17 -0
- package/src/core/mapping/auto-mapping.service.ts +187 -0
- package/src/core/mapping/create-map.ts +11 -0
- package/src/core/mapping/for-member.ts +16 -0
- package/src/core/request-overflow/request-handler.base.ts +8 -0
- package/src/core/request-overflow/request-result.spec.ts +23 -0
- package/src/core/request-overflow/request-result.ts +41 -0
- package/src/core/request-overflow/request-validator.base.ts +33 -0
- package/src/core/security/strategies/api-key.strategy.ts +45 -0
- package/src/core/utils/assing-object.ts +9 -0
- package/src/core/utils/env.config.ts +17 -0
- package/src/core/utils/filter-request-params.ts +23 -0
- package/src/core/utils/find-on-list.ts +18 -0
- package/src/core/utils/get-type-by-prop.ts +9 -0
- package/src/core/utils/instanciate-class-with-dependencies-injection.ts +12 -0
- package/src/core/utils/interfaces/icomparable.ts +6 -0
- package/src/core/utils/list.spec.ts +81 -0
- package/src/core/utils/list.ts +223 -0
- package/src/core/utils/promise-all.ts +24 -0
- package/src/core/utils/set-mask-document-number.ts +13 -0
- package/src/core/validators/file-validator.ts +113 -0
- package/src/decorators/api-exclude-endpoint-diff-develop.decorator.ts +15 -0
- package/src/decorators/api-property-enum.decorator.ts +58 -0
- package/src/decorators/api-property-only-develop.decorator.ts +6 -0
- package/src/decorators/cookies.decorator.ts +8 -0
- package/src/decorators/is-public.decorator.ts +5 -0
- package/src/decorators/upload.decorator.ts +31 -0
- package/src/env/env.module.ts +8 -0
- package/src/env/env.service.ts +12 -0
- package/src/env/env.ts +14 -0
- package/src/filters/domain-errors.filter.ts +97 -0
- package/src/filters/global-exception.filter.ts +60 -0
- package/src/filters/prisma-validation-exception.filter.ts +73 -0
- package/src/filters/zod-errors.filter.ts +48 -0
- package/src/services/logging/ilogging.service.ts +17 -0
- package/src/services/logging/logging.service.ts +10 -0
- package/src/services/redis/iredis.service.ts +11 -0
- package/src/services/redis/redis.service.ts +70 -0
- package/src/services/redlock/ired-lock.service.ts +4 -0
- package/src/services/redlock/red-lock.service.ts +36 -0
- package/src/test/koala-app-test-dependencies.ts +15 -0
- package/src/test/koala-app-test.ts +103 -0
- package/src/test/repositories/in-memory-base.repository.ts +90 -0
- package/src/test/services/fake-logging.service.ts +7 -0
- package/src/test/services/fake-red-lock.service.ts +11 -0
- package/src/test/utils/create-e2e-database.ts +55 -0
- package/src/test/utils/drop-e2e-database.ts +36 -0
- package/src/test/utils/wait-for.ts +31 -0
- package/tsconfig.lib.json +11 -0
- package/LICENSE +0 -21
- package/README.md +0 -499
- package/core/backgroud-services/cron-service/cron-job.handler.base.d.ts +0 -16
- package/core/backgroud-services/cron-service/cron-job.handler.base.js +0 -49
- package/core/backgroud-services/event-service/event-class.d.ts +0 -5
- package/core/backgroud-services/event-service/event-class.js +0 -11
- package/core/backgroud-services/event-service/event-handler.base.d.ts +0 -8
- package/core/backgroud-services/event-service/event-handler.base.js +0 -14
- package/core/backgroud-services/event-service/event-is-trigger.d.ts +0 -3
- package/core/backgroud-services/event-service/event-is-trigger.js +0 -7
- package/core/backgroud-services/event-service/event-job.d.ts +0 -13
- package/core/backgroud-services/event-service/event-job.js +0 -21
- package/core/backgroud-services/event-service/event-queue.d.ts +0 -17
- package/core/backgroud-services/event-service/event-queue.js +0 -62
- package/core/constants/query-params.d.ts +0 -6
- package/core/constants/query-params.js +0 -8
- package/core/controllers/base.controller.d.ts +0 -4
- package/core/controllers/base.controller.js +0 -6
- package/core/controllers/controller.decorator.d.ts +0 -2
- package/core/controllers/controller.decorator.js +0 -11
- package/core/controllers/created-registre-response.base.d.ts +0 -10
- package/core/controllers/created-registre-response.base.js +0 -35
- package/core/controllers/list-response.base.d.ts +0 -4
- package/core/controllers/list-response.base.js +0 -21
- package/core/controllers/pagination.request.d.ts +0 -10
- package/core/controllers/pagination.request.js +0 -56
- package/core/controllers/router-config.base.d.ts +0 -7
- package/core/controllers/router-config.base.js +0 -18
- package/core/controllers/schemas/boolean.schema.d.ts +0 -2
- package/core/controllers/schemas/boolean.schema.js +0 -12
- package/core/controllers/schemas/document-number.schema.d.ts +0 -1
- package/core/controllers/schemas/document-number.schema.js +0 -26
- package/core/controllers/schemas/email.schema.d.ts +0 -1
- package/core/controllers/schemas/email.schema.js +0 -13
- package/core/controllers/schemas/list-query.schema.d.ts +0 -17
- package/core/controllers/schemas/list-query.schema.js +0 -19
- package/core/controllers/schemas/native-enum.schema.d.ts +0 -7
- package/core/controllers/schemas/native-enum.schema.js +0 -28
- package/core/controllers/schemas/set-mask-document-number.schema.d.ts +0 -1
- package/core/controllers/schemas/set-mask-document-number.schema.js +0 -13
- package/core/database/entity.base.d.ts +0 -20
- package/core/database/entity.base.js +0 -71
- package/core/database/entity.decorator.d.ts +0 -13
- package/core/database/entity.decorator.js +0 -23
- package/core/database/prisma-client-with-custom-transaction.interface.d.ts +0 -8
- package/core/database/prisma-client-with-custom-transaction.interface.js +0 -2
- package/core/database/prisma-resolver.d.ts +0 -2
- package/core/database/prisma-resolver.js +0 -74
- package/core/database/prisma-transactional-client.d.ts +0 -11
- package/core/database/prisma-transactional-client.js +0 -25
- package/core/database/prisma.service.d.ts +0 -24
- package/core/database/prisma.service.js +0 -104
- package/core/database/repository.base.d.ts +0 -44
- package/core/database/repository.base.js +0 -360
- package/core/dtos/pagination.dto.d.ts +0 -9
- package/core/dtos/pagination.dto.js +0 -49
- package/core/errors/bad-request.error.d.ts +0 -5
- package/core/errors/bad-request.error.js +0 -10
- package/core/errors/conflict.error.d.ts +0 -4
- package/core/errors/conflict.error.js +0 -10
- package/core/errors/error.base.d.ts +0 -4
- package/core/errors/error.base.js +0 -11
- package/core/errors/no-content.error.d.ts +0 -5
- package/core/errors/no-content.error.js +0 -10
- package/core/errors/not-allowed.error.d.ts +0 -5
- package/core/errors/not-allowed.error.js +0 -10
- package/core/errors/resource-not-found.error.d.ts +0 -5
- package/core/errors/resource-not-found.error.js +0 -10
- package/core/errors/use-case-error.js +0 -2
- package/core/errors/user-already-exist.error.d.ts +0 -4
- package/core/errors/user-already-exist.error.js +0 -10
- package/core/errors/wrong-credentials.error.d.ts +0 -4
- package/core/errors/wrong-credentials.error.js +0 -10
- package/core/health-check/health-check.controller.d.ts +0 -5
- package/core/health-check/health-check.controller.js +0 -32
- package/core/health-check/health-check.module.d.ts +0 -2
- package/core/health-check/health-check.module.js +0 -19
- package/core/index.d.ts +0 -18
- package/core/index.js +0 -7
- package/core/koala-app.d.ts +0 -64
- package/core/koala-app.js +0 -252
- package/core/koala-global-vars.d.ts +0 -7
- package/core/koala-global-vars.js +0 -9
- package/core/koala-nest-database.module.d.ts +0 -16
- package/core/koala-nest-database.module.js +0 -52
- package/core/koala-nest-http.module.d.ts +0 -13
- package/core/koala-nest-http.module.js +0 -37
- package/core/koala-nest.module.d.ts +0 -17
- package/core/koala-nest.module.js +0 -66
- package/core/mapping/auto-mapping-class-context.d.ts +0 -16
- package/core/mapping/auto-mapping-class-context.js +0 -18
- package/core/mapping/auto-mapping-context.d.ts +0 -11
- package/core/mapping/auto-mapping-context.js +0 -24
- package/core/mapping/auto-mapping-list.d.ts +0 -27
- package/core/mapping/auto-mapping-list.js +0 -94
- package/core/mapping/auto-mapping-profile.d.ts +0 -3
- package/core/mapping/auto-mapping-profile.js +0 -6
- package/core/mapping/auto-mapping.decorator.d.ts +0 -9
- package/core/mapping/auto-mapping.decorator.js +0 -27
- package/core/mapping/auto-mapping.module.d.ts +0 -5
- package/core/mapping/auto-mapping.module.js +0 -29
- package/core/mapping/auto-mapping.service.d.ts +0 -14
- package/core/mapping/auto-mapping.service.js +0 -140
- package/core/mapping/create-map.d.ts +0 -3
- package/core/mapping/create-map.js +0 -7
- package/core/mapping/for-member.d.ts +0 -5
- package/core/mapping/for-member.js +0 -8
- package/core/request-overflow/request-handler.base.d.ts +0 -4
- package/core/request-overflow/request-handler.base.js +0 -6
- package/core/request-overflow/request-result.d.ts +0 -15
- package/core/request-overflow/request-result.js +0 -37
- package/core/request-overflow/request-validator.base.d.ts +0 -7
- package/core/request-overflow/request-validator.base.js +0 -26
- package/core/security/strategies/api-key.strategy.d.ts +0 -16
- package/core/security/strategies/api-key.strategy.js +0 -31
- package/core/utils/assing-object.d.ts +0 -5
- package/core/utils/assing-object.js +0 -6
- package/core/utils/env.config.d.ts +0 -6
- package/core/utils/env.config.js +0 -18
- package/core/utils/filter-request-params.d.ts +0 -13
- package/core/utils/filter-request-params.js +0 -22
- package/core/utils/find-on-list.d.ts +0 -2
- package/core/utils/find-on-list.js +0 -13
- package/core/utils/get-type-by-prop.d.ts +0 -2
- package/core/utils/get-type-by-prop.js +0 -11
- package/core/utils/instanciate-class-with-dependencies-injection.d.ts +0 -2
- package/core/utils/instanciate-class-with-dependencies-injection.js +0 -10
- package/core/utils/interfaces/icomparable.d.ts +0 -5
- package/core/utils/interfaces/icomparable.js +0 -6
- package/core/utils/list.d.ts +0 -39
- package/core/utils/list.js +0 -168
- package/core/utils/promise-all.d.ts +0 -7
- package/core/utils/promise-all.js +0 -19
- package/core/utils/set-mask-document-number.d.ts +0 -1
- package/core/utils/set-mask-document-number.js +0 -13
- package/core/validators/file-validator.d.ts +0 -27
- package/core/validators/file-validator.js +0 -94
- package/decorators/api-exclude-endpoint-diff-develop.decorator.d.ts +0 -1
- package/decorators/api-exclude-endpoint-diff-develop.decorator.js +0 -9
- package/decorators/api-property-enum.decorator.d.ts +0 -8
- package/decorators/api-property-enum.decorator.js +0 -21
- package/decorators/api-property-only-develop.decorator.d.ts +0 -2
- package/decorators/api-property-only-develop.decorator.js +0 -9
- package/decorators/cookies.decorator.d.ts +0 -1
- package/decorators/cookies.decorator.js +0 -8
- package/decorators/is-public.decorator.d.ts +0 -2
- package/decorators/is-public.decorator.js +0 -7
- package/decorators/upload.decorator.d.ts +0 -1
- package/decorators/upload.decorator.js +0 -18
- package/docs/00-cli-reference.md +0 -201
- package/docs/01-guia-instalacao.md +0 -113
- package/docs/02-configuracao-inicial.md +0 -176
- package/docs/04-tratamento-erros.md +0 -303
- package/docs/05-features-avancadas.md +0 -969
- package/docs/06-decoradores.md +0 -220
- package/docs/07-guia-bun.md +0 -176
- package/docs/08-prisma-client.md +0 -487
- package/docs/09-mcp-vscode-extension.md +0 -437
- package/docs/EXAMPLE.md +0 -1671
- package/docs/README.md +0 -59
- package/env/env.d.ts +0 -25
- package/env/env.js +0 -14
- package/env/env.module.d.ts +0 -2
- package/env/env.module.js +0 -20
- package/env/env.service.d.ts +0 -7
- package/env/env.service.js +0 -28
- package/filters/domain-errors.filter.d.ts +0 -18
- package/filters/domain-errors.filter.js +0 -92
- package/filters/global-exception.filter.d.ts +0 -8
- package/filters/global-exception.filter.js +0 -68
- package/filters/prisma-validation-exception.filter.d.ts +0 -10
- package/filters/prisma-validation-exception.filter.js +0 -82
- package/filters/zod-errors.filter.d.ts +0 -9
- package/filters/zod-errors.filter.js +0 -60
- package/mcp-server/mcp.json.example +0 -27
- package/mcp-server/server.d.ts +0 -2
- package/mcp-server/server.d.ts.map +0 -1
- package/mcp-server/server.js +0 -248
- package/mcp-server/server.js.map +0 -1
- package/services/logging/ilogging.service.d.ts +0 -16
- package/services/logging/ilogging.service.js +0 -6
- package/services/logging/logging.service.d.ts +0 -4
- package/services/logging/logging.service.js +0 -20
- package/services/redis/iredis.service.d.ts +0 -6
- package/services/redis/iredis.service.js +0 -6
- package/services/redis/redis.service.d.ts +0 -14
- package/services/redis/redis.service.js +0 -65
- package/services/redlock/ired-lock.service.d.ts +0 -4
- package/services/redlock/ired-lock.service.js +0 -6
- package/services/redlock/red-lock.service.d.ts +0 -9
- package/services/redlock/red-lock.service.js +0 -46
- package/test/koala-app-test-dependencies.d.ts +0 -10
- package/test/koala-app-test-dependencies.js +0 -13
- package/test/koala-app-test.d.ts +0 -22
- package/test/koala-app-test.js +0 -77
- package/test/repositories/in-memory-base.repository.d.ts +0 -17
- package/test/repositories/in-memory-base.repository.js +0 -65
- package/test/services/fake-logging.service.d.ts +0 -4
- package/test/services/fake-logging.service.js +0 -9
- package/test/services/fake-red-lock.service.d.ts +0 -5
- package/test/services/fake-red-lock.service.js +0 -11
- package/test/utils/create-e2e-database.d.ts +0 -2
- package/test/utils/create-e2e-database.js +0 -47
- package/test/utils/drop-e2e-database.d.ts +0 -2
- package/test/utils/drop-e2e-database.js +0 -33
- package/test/utils/wait-for.d.ts +0 -1
- package/test/utils/wait-for.js +0 -21
- package/tsconfig.lib.tsbuildinfo +0 -1
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { ArgumentsHost, Catch, HttpStatus } from '@nestjs/common'
|
|
2
|
+
import { BaseExceptionFilter } from '@nestjs/core'
|
|
3
|
+
import { BadRequestError } from '../core/errors/bad-request.error'
|
|
4
|
+
import { ConflictError } from '../core/errors/conflict.error'
|
|
5
|
+
import { NoContentError } from '../core/errors/no-content.error'
|
|
6
|
+
import { NotAllowedError } from '../core/errors/not-allowed.error'
|
|
7
|
+
import { ResourceNotFoundError } from '../core/errors/resource-not-found.error'
|
|
8
|
+
import { UserAlreadyExist } from '../core/errors/user-already-exist.error'
|
|
9
|
+
import { WrongCredentialsError } from '../core/errors/wrong-credentials.error'
|
|
10
|
+
import { KoalaGlobalVars } from '../core/koala-global-vars'
|
|
11
|
+
import { EnvConfig } from '../core/utils/env.config'
|
|
12
|
+
import { FilterRequestParams } from '../core/utils/filter-request-params'
|
|
13
|
+
import { ILoggingService } from '../services/logging/ilogging.service'
|
|
14
|
+
|
|
15
|
+
type DomainErrors =
|
|
16
|
+
| NotAllowedError
|
|
17
|
+
| ResourceNotFoundError
|
|
18
|
+
| UserAlreadyExist
|
|
19
|
+
| WrongCredentialsError
|
|
20
|
+
| ConflictError
|
|
21
|
+
| BadRequestError
|
|
22
|
+
| NoContentError
|
|
23
|
+
|
|
24
|
+
@Catch(
|
|
25
|
+
NotAllowedError,
|
|
26
|
+
ResourceNotFoundError,
|
|
27
|
+
UserAlreadyExist,
|
|
28
|
+
WrongCredentialsError,
|
|
29
|
+
ConflictError,
|
|
30
|
+
BadRequestError,
|
|
31
|
+
NoContentError,
|
|
32
|
+
)
|
|
33
|
+
export class DomainErrorsFilter extends BaseExceptionFilter {
|
|
34
|
+
constructor(private readonly loggingService: ILoggingService) {
|
|
35
|
+
super()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public catch(exception: DomainErrors, host: ArgumentsHost) {
|
|
39
|
+
const mappedException = this.map(exception)
|
|
40
|
+
const filterRequestParams = FilterRequestParams.get(host)
|
|
41
|
+
|
|
42
|
+
if (mappedException.statusCode !== HttpStatus.UNAUTHORIZED) {
|
|
43
|
+
if (!EnvConfig.isEnvTest) {
|
|
44
|
+
this.loggingService
|
|
45
|
+
.report({
|
|
46
|
+
error: exception,
|
|
47
|
+
packageName: KoalaGlobalVars.appName,
|
|
48
|
+
loggedUsername: filterRequestParams.loggedUserName,
|
|
49
|
+
httpRequest: {
|
|
50
|
+
...filterRequestParams.filterParams,
|
|
51
|
+
statusCode: mappedException.statusCode,
|
|
52
|
+
response: mappedException,
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
.catch((err) => console.error(err))
|
|
56
|
+
} else {
|
|
57
|
+
console.error(exception)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return filterRequestParams.response
|
|
62
|
+
.status(mappedException.statusCode)
|
|
63
|
+
.json(mappedException)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private map(exception: DomainErrors) {
|
|
67
|
+
const mappedException = {
|
|
68
|
+
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
69
|
+
message: exception.message,
|
|
70
|
+
data: exception.data,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
switch (exception.constructor) {
|
|
74
|
+
case UserAlreadyExist:
|
|
75
|
+
case NotAllowedError:
|
|
76
|
+
case BadRequestError:
|
|
77
|
+
mappedException.statusCode = HttpStatus.BAD_REQUEST
|
|
78
|
+
break
|
|
79
|
+
case ResourceNotFoundError:
|
|
80
|
+
mappedException.statusCode = HttpStatus.NOT_FOUND
|
|
81
|
+
break
|
|
82
|
+
case WrongCredentialsError:
|
|
83
|
+
mappedException.statusCode = HttpStatus.UNAUTHORIZED
|
|
84
|
+
break
|
|
85
|
+
case ConflictError:
|
|
86
|
+
mappedException.statusCode = HttpStatus.CONFLICT
|
|
87
|
+
break
|
|
88
|
+
case NoContentError:
|
|
89
|
+
mappedException.statusCode = HttpStatus.NO_CONTENT
|
|
90
|
+
break
|
|
91
|
+
default:
|
|
92
|
+
console.error(exception)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return mappedException
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ArgumentsHost, Catch, HttpException, HttpStatus } from '@nestjs/common'
|
|
2
|
+
import { BaseExceptionFilter } from '@nestjs/core'
|
|
3
|
+
import { IncomingMessage } from 'node:http'
|
|
4
|
+
import { KoalaGlobalVars } from '../core/koala-global-vars'
|
|
5
|
+
import { EnvConfig } from '../core/utils/env.config'
|
|
6
|
+
import { FilterRequestParams } from '../core/utils/filter-request-params'
|
|
7
|
+
import { ILoggingService } from '../services/logging/ilogging.service'
|
|
8
|
+
|
|
9
|
+
@Catch()
|
|
10
|
+
export class GlobalExceptionsFilter extends BaseExceptionFilter {
|
|
11
|
+
constructor(private readonly loggingService: ILoggingService) {
|
|
12
|
+
super()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
catch(exception: Error, host: ArgumentsHost) {
|
|
16
|
+
const filterRequestParams = FilterRequestParams.get(host)
|
|
17
|
+
const request: IncomingMessage | null =
|
|
18
|
+
host.getArgs().find((arg) => arg instanceof IncomingMessage) ?? null
|
|
19
|
+
|
|
20
|
+
const statusCode =
|
|
21
|
+
exception instanceof HttpException
|
|
22
|
+
? exception.getStatus()
|
|
23
|
+
: HttpStatus.INTERNAL_SERVER_ERROR
|
|
24
|
+
|
|
25
|
+
const responseBody =
|
|
26
|
+
exception instanceof HttpException
|
|
27
|
+
? exception.getResponse()
|
|
28
|
+
: {
|
|
29
|
+
statusCode,
|
|
30
|
+
timestamp: new Date().toISOString(),
|
|
31
|
+
path: filterRequestParams.filterParams.endpoint,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (
|
|
35
|
+
!exception.message?.includes('Cannot GET /socket.io') &&
|
|
36
|
+
!exception.message?.includes('Cannot GET /favicon.ico') &&
|
|
37
|
+
!['/'].includes(request?.url ?? '') &&
|
|
38
|
+
statusCode !== HttpStatus.UNAUTHORIZED
|
|
39
|
+
) {
|
|
40
|
+
if (!EnvConfig.isEnvTest) {
|
|
41
|
+
this.loggingService
|
|
42
|
+
.report({
|
|
43
|
+
error: exception,
|
|
44
|
+
packageName: KoalaGlobalVars.appName,
|
|
45
|
+
loggedUsername: filterRequestParams.loggedUserName,
|
|
46
|
+
httpRequest: {
|
|
47
|
+
...filterRequestParams.filterParams,
|
|
48
|
+
statusCode,
|
|
49
|
+
response: responseBody as any,
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
.catch((err) => console.error(err))
|
|
53
|
+
} else {
|
|
54
|
+
console.error(exception)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return filterRequestParams.response.status(statusCode).json(responseBody)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ArgumentsHost, Catch, HttpStatus } from '@nestjs/common'
|
|
2
|
+
import { BaseExceptionFilter } from '@nestjs/core'
|
|
3
|
+
import { Prisma } from 'prisma/generated/client'
|
|
4
|
+
import { KoalaGlobalVars } from '../core/koala-global-vars'
|
|
5
|
+
import { EnvConfig } from '../core/utils/env.config'
|
|
6
|
+
import { FilterRequestParams } from '../core/utils/filter-request-params'
|
|
7
|
+
import { ILoggingService } from '../services/logging/ilogging.service'
|
|
8
|
+
|
|
9
|
+
@Catch(Prisma.PrismaClientKnownRequestError)
|
|
10
|
+
export class PrismaValidationExceptionFilter extends BaseExceptionFilter {
|
|
11
|
+
constructor(private readonly loggingService: ILoggingService) {
|
|
12
|
+
super()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public catch(
|
|
16
|
+
exception: Prisma.PrismaClientKnownRequestError,
|
|
17
|
+
host: ArgumentsHost,
|
|
18
|
+
) {
|
|
19
|
+
const translatedResponse = this.translate(exception)
|
|
20
|
+
const filterRequestParams = FilterRequestParams.get(host)
|
|
21
|
+
|
|
22
|
+
if (translatedResponse.statusCode !== HttpStatus.UNAUTHORIZED) {
|
|
23
|
+
if (!EnvConfig.isEnvTest) {
|
|
24
|
+
this.loggingService
|
|
25
|
+
.report({
|
|
26
|
+
error: exception,
|
|
27
|
+
packageName: KoalaGlobalVars.appName,
|
|
28
|
+
loggedUsername: filterRequestParams.loggedUserName,
|
|
29
|
+
httpRequest: {
|
|
30
|
+
...filterRequestParams.filterParams,
|
|
31
|
+
statusCode: translatedResponse.statusCode,
|
|
32
|
+
response: translatedResponse,
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
.catch((err) => console.error(err))
|
|
36
|
+
} else {
|
|
37
|
+
console.error(exception)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return filterRequestParams.response
|
|
42
|
+
.status(translatedResponse.statusCode)
|
|
43
|
+
.json(translatedResponse)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private translate(exception: Prisma.PrismaClientKnownRequestError) {
|
|
47
|
+
switch (exception.code) {
|
|
48
|
+
case 'P2002':
|
|
49
|
+
return {
|
|
50
|
+
statusCode: HttpStatus.CONFLICT,
|
|
51
|
+
message: 'Registro já existente.',
|
|
52
|
+
}
|
|
53
|
+
case 'P2003':
|
|
54
|
+
return {
|
|
55
|
+
statusCode: HttpStatus.BAD_REQUEST,
|
|
56
|
+
message:
|
|
57
|
+
'Falha devido a relacionamento. Verifique se o relacionamento existe ou é valido.',
|
|
58
|
+
}
|
|
59
|
+
case 'P2025':
|
|
60
|
+
return {
|
|
61
|
+
statusCode: HttpStatus.NOT_FOUND,
|
|
62
|
+
message: 'Registro não encontrado.',
|
|
63
|
+
}
|
|
64
|
+
default:
|
|
65
|
+
console.error(exception)
|
|
66
|
+
return {
|
|
67
|
+
statusCode: HttpStatus.BAD_REQUEST,
|
|
68
|
+
message:
|
|
69
|
+
'Ocorreu um erro desconhecido relacionado aos dados enviados.',
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ArgumentsHost, Catch, HttpStatus } from '@nestjs/common'
|
|
2
|
+
import { BaseExceptionFilter } from '@nestjs/core'
|
|
3
|
+
import { ZodError } from 'zod'
|
|
4
|
+
import { fromZodError } from 'zod-validation-error'
|
|
5
|
+
import { KoalaGlobalVars } from '../core/koala-global-vars'
|
|
6
|
+
import { EnvConfig } from '../core/utils/env.config'
|
|
7
|
+
import { FilterRequestParams } from '../core/utils/filter-request-params'
|
|
8
|
+
import { ILoggingService } from '../services/logging/ilogging.service'
|
|
9
|
+
|
|
10
|
+
@Catch(ZodError)
|
|
11
|
+
export class ZodErrorsFilter extends BaseExceptionFilter {
|
|
12
|
+
constructor(private readonly loggingService: ILoggingService) {
|
|
13
|
+
super()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public catch(exception: ZodError, host: ArgumentsHost) {
|
|
17
|
+
const filterRequestParams = FilterRequestParams.get(host)
|
|
18
|
+
|
|
19
|
+
const zodResponse = {
|
|
20
|
+
errors: fromZodError(exception).details.map(
|
|
21
|
+
(detail) => `${detail.path} ${detail.message.toLowerCase()}`,
|
|
22
|
+
),
|
|
23
|
+
statusCode: HttpStatus.BAD_REQUEST,
|
|
24
|
+
message: 'Dados enviados inválidos',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!EnvConfig.isEnvTest) {
|
|
28
|
+
this.loggingService
|
|
29
|
+
.report({
|
|
30
|
+
error: exception,
|
|
31
|
+
packageName: KoalaGlobalVars.appName,
|
|
32
|
+
loggedUsername: filterRequestParams.loggedUserName,
|
|
33
|
+
httpRequest: {
|
|
34
|
+
...filterRequestParams.filterParams,
|
|
35
|
+
statusCode: HttpStatus.BAD_REQUEST,
|
|
36
|
+
response: zodResponse,
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
.catch((err) => console.error(err))
|
|
40
|
+
} else {
|
|
41
|
+
console.error(exception)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return filterRequestParams.response
|
|
45
|
+
.status(HttpStatus.BAD_REQUEST)
|
|
46
|
+
.send(zodResponse)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface LoggingReportProps {
|
|
2
|
+
loggedUsername: string
|
|
3
|
+
packageName: string
|
|
4
|
+
error: Error
|
|
5
|
+
httpRequest?: {
|
|
6
|
+
method: string
|
|
7
|
+
endpoint: string
|
|
8
|
+
queryParams?: string
|
|
9
|
+
payload?: object
|
|
10
|
+
statusCode: number
|
|
11
|
+
response?: object
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export abstract class ILoggingService {
|
|
16
|
+
abstract report(data: LoggingReportProps): Promise<void>
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common'
|
|
2
|
+
import { ILoggingService, LoggingReportProps } from './ilogging.service'
|
|
3
|
+
import consola from 'consola'
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class LoggingService implements ILoggingService {
|
|
7
|
+
async report(data: LoggingReportProps): Promise<void> {
|
|
8
|
+
consola.error(data.error)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export abstract class IRedisService {
|
|
2
|
+
abstract isConnected: boolean
|
|
3
|
+
abstract getCache(key: string): Promise<string | null>
|
|
4
|
+
abstract setCache(
|
|
5
|
+
key: string,
|
|
6
|
+
ttlSecondsCache: number,
|
|
7
|
+
payload: any,
|
|
8
|
+
): Promise<void>
|
|
9
|
+
|
|
10
|
+
abstract deleteCache(key: string): Promise<void>
|
|
11
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Injectable, OnModuleDestroy } from '@nestjs/common'
|
|
2
|
+
import Redis from 'ioredis'
|
|
3
|
+
import { EnvConfig } from '../../core/utils/env.config'
|
|
4
|
+
import { EnvService } from '../../env/env.service'
|
|
5
|
+
import { IRedisService } from './iredis.service'
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class RedisService implements IRedisService, OnModuleDestroy {
|
|
9
|
+
private readonly redisClient: Redis
|
|
10
|
+
private readonly environment: string
|
|
11
|
+
|
|
12
|
+
get isConnected(): boolean {
|
|
13
|
+
return !!this.redisClient
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
constructor(env: EnvService) {
|
|
17
|
+
if (!EnvConfig.isEnvTest) {
|
|
18
|
+
const redisUrl = env.get('REDIS_CONNECTION_STRING')
|
|
19
|
+
|
|
20
|
+
if (redisUrl) {
|
|
21
|
+
const url = new URL(redisUrl)
|
|
22
|
+
this.environment = env.get('NODE_ENV')
|
|
23
|
+
|
|
24
|
+
this.redisClient = new Redis({
|
|
25
|
+
host: url.hostname,
|
|
26
|
+
port: Number(url.port),
|
|
27
|
+
password: url.password,
|
|
28
|
+
username: url.username,
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
onModuleDestroy() {
|
|
35
|
+
this.redisClient.disconnect()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async getCache(key: string): Promise<string | null> {
|
|
39
|
+
if (EnvConfig.isEnvTest) {
|
|
40
|
+
return ''
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return await this.redisClient.get(this.getKeyCache(key))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async setCache(
|
|
47
|
+
key: string,
|
|
48
|
+
ttlSecondsCache: number,
|
|
49
|
+
payload: any,
|
|
50
|
+
): Promise<void> {
|
|
51
|
+
if (!EnvConfig.isEnvTest) {
|
|
52
|
+
await this.redisClient.set(
|
|
53
|
+
this.getKeyCache(key),
|
|
54
|
+
JSON.stringify(payload),
|
|
55
|
+
'EX',
|
|
56
|
+
ttlSecondsCache,
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async deleteCache(key: string): Promise<void> {
|
|
62
|
+
if (!EnvConfig.isEnvTest) {
|
|
63
|
+
await this.redisClient.del(this.getKeyCache(key))
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private getKeyCache(key: string) {
|
|
68
|
+
return `${this.environment}:app:${key}`
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common'
|
|
2
|
+
import { EnvConfig } from '../../core/utils/env.config'
|
|
3
|
+
import { IRedisService } from '../redis/iredis.service'
|
|
4
|
+
import { IRedLockService } from './ired-lock.service'
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class RedLockService implements IRedLockService {
|
|
8
|
+
constructor(private readonly redisService: IRedisService) {}
|
|
9
|
+
|
|
10
|
+
async acquiredLock(key: string, ttlSecondsLock: number): Promise<boolean> {
|
|
11
|
+
if (EnvConfig.isEnvTest || !this.redisService.isConnected) {
|
|
12
|
+
return true
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const lockKey = this.getLockKey(key)
|
|
16
|
+
const canLock = await this.redisService.getCache(lockKey)
|
|
17
|
+
|
|
18
|
+
if (canLock) {
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
await this.redisService.setCache(lockKey, ttlSecondsLock, 'RedLockService')
|
|
23
|
+
|
|
24
|
+
return true
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async releaseLock(key: string): Promise<void> {
|
|
28
|
+
if (!EnvConfig.isEnvTest && this.redisService.isConnected) {
|
|
29
|
+
await this.redisService.deleteCache(this.getLockKey(key))
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private getLockKey(key: string) {
|
|
34
|
+
return `redLock:${key}`
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Type } from '@nestjs/common'
|
|
2
|
+
|
|
3
|
+
interface KoalaAppTestDependenciesConfig {
|
|
4
|
+
dependencies: any[]
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export class KoalaAppTestDependencies {
|
|
8
|
+
constructor(private readonly _config: KoalaAppTestDependenciesConfig) {}
|
|
9
|
+
|
|
10
|
+
get<T>(objectType: Type<T>): T {
|
|
11
|
+
return this._config.dependencies.find(
|
|
12
|
+
(dependency) => dependency instanceof objectType,
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { CanActivate, INestApplication, Type } from '@nestjs/common'
|
|
2
|
+
import { BaseExceptionFilter } from '@nestjs/core'
|
|
3
|
+
import { PrismaTransactionalClient } from '../core/database/prisma-transactional-client'
|
|
4
|
+
import { KoalaGlobalVars } from '../core/koala-global-vars'
|
|
5
|
+
import { instanciateClassWithDependenciesInjection } from '../core/utils/instanciate-class-with-dependencies-injection'
|
|
6
|
+
import { DomainErrorsFilter } from '../filters/domain-errors.filter'
|
|
7
|
+
import { GlobalExceptionsFilter } from '../filters/global-exception.filter'
|
|
8
|
+
import { PrismaValidationExceptionFilter } from '../filters/prisma-validation-exception.filter'
|
|
9
|
+
import { ZodErrorsFilter } from '../filters/zod-errors.filter'
|
|
10
|
+
import { ILoggingService } from '../services/logging/ilogging.service'
|
|
11
|
+
|
|
12
|
+
export class KoalaAppTest {
|
|
13
|
+
private _guards: CanActivate[] = []
|
|
14
|
+
private _globalExceptionFilter: BaseExceptionFilter
|
|
15
|
+
private _prismaValidationExceptionFilter: BaseExceptionFilter
|
|
16
|
+
private _domainExceptionFilter: BaseExceptionFilter
|
|
17
|
+
private _zodExceptionFilter: BaseExceptionFilter
|
|
18
|
+
|
|
19
|
+
constructor(private readonly app: INestApplication<any>) {
|
|
20
|
+
let loggingService = app.get(ILoggingService)
|
|
21
|
+
|
|
22
|
+
if (!loggingService.report) {
|
|
23
|
+
loggingService = instanciateClassWithDependenciesInjection(
|
|
24
|
+
this.app,
|
|
25
|
+
loggingService,
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this._globalExceptionFilter = new GlobalExceptionsFilter(loggingService)
|
|
30
|
+
this._prismaValidationExceptionFilter = new PrismaValidationExceptionFilter(
|
|
31
|
+
loggingService,
|
|
32
|
+
)
|
|
33
|
+
this._domainExceptionFilter = new DomainErrorsFilter(loggingService)
|
|
34
|
+
this._zodExceptionFilter = new ZodErrorsFilter(loggingService)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
addGlobalGuard(Guard: Type<CanActivate>) {
|
|
38
|
+
this._guards.push(
|
|
39
|
+
instanciateClassWithDependenciesInjection(this.app, Guard),
|
|
40
|
+
)
|
|
41
|
+
return this
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
addCustomGlobalExceptionFilter(filter: BaseExceptionFilter) {
|
|
45
|
+
this._globalExceptionFilter = filter
|
|
46
|
+
return this
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
addCustomPrismaValidationExceptionFilter(filter: BaseExceptionFilter) {
|
|
50
|
+
this._prismaValidationExceptionFilter = filter
|
|
51
|
+
return this
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
addCustomDomainExceptionFilter(filter: BaseExceptionFilter) {
|
|
55
|
+
this._domainExceptionFilter = filter
|
|
56
|
+
return this
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
addCustomZodExceptionFilter(filter: BaseExceptionFilter) {
|
|
60
|
+
this._zodExceptionFilter = filter
|
|
61
|
+
return this
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
enableCors() {
|
|
65
|
+
this.app.enableCors({
|
|
66
|
+
credentials: true,
|
|
67
|
+
origin: true,
|
|
68
|
+
optionsSuccessStatus: 200,
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
return this
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
setAppName(name: string) {
|
|
75
|
+
KoalaGlobalVars.appName = name
|
|
76
|
+
return this
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
setInternalUserName(name: string) {
|
|
80
|
+
KoalaGlobalVars.internalUserName = name
|
|
81
|
+
return this
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
setDbTransactionContext(transactionContext: Type<PrismaTransactionalClient>) {
|
|
85
|
+
KoalaGlobalVars.dbTransactionContext = transactionContext
|
|
86
|
+
return this
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
build() {
|
|
90
|
+
this.app.useGlobalFilters(
|
|
91
|
+
this._globalExceptionFilter,
|
|
92
|
+
this._prismaValidationExceptionFilter,
|
|
93
|
+
this._domainExceptionFilter,
|
|
94
|
+
this._zodExceptionFilter,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
for (const guard of this._guards) {
|
|
98
|
+
this.app.useGlobalGuards(guard)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return this.app
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { QUERY_FILTER_PARAMS } from '@koalarx/nest/core/constants/query-params'
|
|
2
|
+
import { PaginationDto } from '@koalarx/nest/core/dtos/pagination.dto'
|
|
3
|
+
import { KlArray } from '@koalarx/utils/KlArray'
|
|
4
|
+
import { randomUUID } from 'node:crypto'
|
|
5
|
+
import { ListResponseBase } from '../../core/controllers/list-response.base'
|
|
6
|
+
import { EntityActionType, EntityBase } from '../../core/database/entity.base'
|
|
7
|
+
import { IComparableId } from '../../core/utils/interfaces/icomparable'
|
|
8
|
+
|
|
9
|
+
export abstract class InMemoryBaseRepository<TClass extends EntityBase<any>> {
|
|
10
|
+
protected items: TClass[] = []
|
|
11
|
+
|
|
12
|
+
constructor(private readonly typeId: 'number' | 'string' = 'number') {}
|
|
13
|
+
|
|
14
|
+
protected async findById(id: IComparableId): Promise<TClass | null> {
|
|
15
|
+
const entity = this.items.find((item) => item._id === id) ?? null
|
|
16
|
+
|
|
17
|
+
if (entity) {
|
|
18
|
+
entity._action = EntityActionType.update
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return entity
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
protected async findMany<T extends PaginationDto>(
|
|
25
|
+
query: T,
|
|
26
|
+
predicate?: (value: TClass, index: number, array: TClass[]) => unknown,
|
|
27
|
+
) {
|
|
28
|
+
const page = query.page ?? QUERY_FILTER_PARAMS.page
|
|
29
|
+
const limit = query.limit ?? QUERY_FILTER_PARAMS.limit
|
|
30
|
+
|
|
31
|
+
return new KlArray(predicate ? this.items.filter(predicate) : this.items)
|
|
32
|
+
.orderBy(query.orderBy ?? '', query.direction)
|
|
33
|
+
.slice(page * limit, (page + 1) * limit)
|
|
34
|
+
.map((item) => {
|
|
35
|
+
item._action = EntityActionType.update
|
|
36
|
+
return item
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
protected async findManyAndCount<T extends PaginationDto>(
|
|
41
|
+
query: T,
|
|
42
|
+
predicate?: (value: TClass, index: number, array: TClass[]) => unknown,
|
|
43
|
+
): Promise<ListResponseBase<TClass>> {
|
|
44
|
+
const items = await this.findMany(query, predicate)
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
items,
|
|
48
|
+
count: items.length,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected async saveChanges(
|
|
53
|
+
item: TClass,
|
|
54
|
+
updateWhere?: (item: TClass) => boolean,
|
|
55
|
+
) {
|
|
56
|
+
if (item._action === EntityActionType.create) {
|
|
57
|
+
const id = this.typeId === 'number' ? this.getNewId() : randomUUID()
|
|
58
|
+
|
|
59
|
+
item.automap({ ...item, id })
|
|
60
|
+
|
|
61
|
+
this.items.push(item)
|
|
62
|
+
|
|
63
|
+
return { id: item._id }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const predicate = updateWhere ?? ((itemDB) => itemDB.equals(item))
|
|
67
|
+
const itemIndex = this.items.findIndex(predicate)
|
|
68
|
+
|
|
69
|
+
if (itemIndex > -1) {
|
|
70
|
+
this.items[itemIndex] = item
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
protected async remove(
|
|
75
|
+
predicate: (value: TClass, index: number, obj: TClass[]) => unknown,
|
|
76
|
+
) {
|
|
77
|
+
const itemIndex = this.items.findIndex(predicate)
|
|
78
|
+
|
|
79
|
+
if (itemIndex > -1) {
|
|
80
|
+
this.items.splice(itemIndex, 1)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private getNewId(): IComparableId {
|
|
85
|
+
return this.typeId === 'number'
|
|
86
|
+
? (new KlArray(this.items).orderBy('_id', 'desc')[0]?._id as number) ??
|
|
87
|
+
0 + 1
|
|
88
|
+
: randomUUID()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IRedLockService } from '../../services/redlock/ired-lock.service'
|
|
2
|
+
|
|
3
|
+
export class FakeRedLockService implements IRedLockService {
|
|
4
|
+
async acquiredLock(key: string, ttlSecondsLock: number): Promise<boolean> {
|
|
5
|
+
return true
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async releaseLock(key: string): Promise<void> {
|
|
9
|
+
//
|
|
10
|
+
}
|
|
11
|
+
}
|