@angelps/prisma-query-builder 0.1.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.
Files changed (130) hide show
  1. package/README.md +709 -0
  2. package/dist/adapters/index.d.ts +3 -0
  3. package/dist/adapters/index.d.ts.map +1 -0
  4. package/dist/adapters/index.js +3 -0
  5. package/dist/adapters/index.js.map +1 -0
  6. package/dist/adapters/valibot.adapter.d.ts +14 -0
  7. package/dist/adapters/valibot.adapter.d.ts.map +1 -0
  8. package/dist/adapters/valibot.adapter.js +21 -0
  9. package/dist/adapters/valibot.adapter.js.map +1 -0
  10. package/dist/adapters/zod.adapter.d.ts +29 -0
  11. package/dist/adapters/zod.adapter.d.ts.map +1 -0
  12. package/dist/adapters/zod.adapter.js +42 -0
  13. package/dist/adapters/zod.adapter.js.map +1 -0
  14. package/dist/controllers/generic.controller.d.ts +79 -0
  15. package/dist/controllers/generic.controller.d.ts.map +1 -0
  16. package/dist/controllers/generic.controller.js +279 -0
  17. package/dist/controllers/generic.controller.js.map +1 -0
  18. package/dist/controllers/index.d.ts +2 -0
  19. package/dist/controllers/index.d.ts.map +1 -0
  20. package/dist/controllers/index.js +2 -0
  21. package/dist/controllers/index.js.map +1 -0
  22. package/dist/errors/app-errors.d.ts +17 -0
  23. package/dist/errors/app-errors.d.ts.map +1 -0
  24. package/dist/errors/app-errors.js +28 -0
  25. package/dist/errors/app-errors.js.map +1 -0
  26. package/dist/errors/error-messages.d.ts +80 -0
  27. package/dist/errors/error-messages.d.ts.map +1 -0
  28. package/dist/errors/error-messages.js +75 -0
  29. package/dist/errors/error-messages.js.map +1 -0
  30. package/dist/errors/index.d.ts +3 -0
  31. package/dist/errors/index.d.ts.map +1 -0
  32. package/dist/errors/index.js +3 -0
  33. package/dist/errors/index.js.map +1 -0
  34. package/dist/index.d.ts +9 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +9 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/query-builder/helpers/order-by.helper.d.ts +4 -0
  39. package/dist/query-builder/helpers/order-by.helper.d.ts.map +1 -0
  40. package/dist/query-builder/helpers/order-by.helper.js +24 -0
  41. package/dist/query-builder/helpers/order-by.helper.js.map +1 -0
  42. package/dist/query-builder/helpers/pagination.helper.d.ts +6 -0
  43. package/dist/query-builder/helpers/pagination.helper.d.ts.map +1 -0
  44. package/dist/query-builder/helpers/pagination.helper.js +9 -0
  45. package/dist/query-builder/helpers/pagination.helper.js.map +1 -0
  46. package/dist/query-builder/helpers/where.helper.d.ts +5 -0
  47. package/dist/query-builder/helpers/where.helper.d.ts.map +1 -0
  48. package/dist/query-builder/helpers/where.helper.js +356 -0
  49. package/dist/query-builder/helpers/where.helper.js.map +1 -0
  50. package/dist/query-builder/index.d.ts +3 -0
  51. package/dist/query-builder/index.d.ts.map +1 -0
  52. package/dist/query-builder/index.js +3 -0
  53. package/dist/query-builder/index.js.map +1 -0
  54. package/dist/query-builder/query-builder.d.ts +56 -0
  55. package/dist/query-builder/query-builder.d.ts.map +1 -0
  56. package/dist/query-builder/query-builder.js +149 -0
  57. package/dist/query-builder/query-builder.js.map +1 -0
  58. package/dist/query-builder/query-builder.types.d.ts +83 -0
  59. package/dist/query-builder/query-builder.types.d.ts.map +1 -0
  60. package/dist/query-builder/query-builder.types.js +2 -0
  61. package/dist/query-builder/query-builder.types.js.map +1 -0
  62. package/dist/repositories/crud.repository.prisma.d.ts +44 -0
  63. package/dist/repositories/crud.repository.prisma.d.ts.map +1 -0
  64. package/dist/repositories/crud.repository.prisma.js +246 -0
  65. package/dist/repositories/crud.repository.prisma.js.map +1 -0
  66. package/dist/repositories/index.d.ts +2 -0
  67. package/dist/repositories/index.d.ts.map +1 -0
  68. package/dist/repositories/index.js +2 -0
  69. package/dist/repositories/index.js.map +1 -0
  70. package/dist/services/audit.service.d.ts +32 -0
  71. package/dist/services/audit.service.d.ts.map +1 -0
  72. package/dist/services/audit.service.js +57 -0
  73. package/dist/services/audit.service.js.map +1 -0
  74. package/dist/services/error-handler.service.d.ts +34 -0
  75. package/dist/services/error-handler.service.d.ts.map +1 -0
  76. package/dist/services/error-handler.service.js +159 -0
  77. package/dist/services/error-handler.service.js.map +1 -0
  78. package/dist/services/index.d.ts +3 -0
  79. package/dist/services/index.d.ts.map +1 -0
  80. package/dist/services/index.js +3 -0
  81. package/dist/services/index.js.map +1 -0
  82. package/dist/types/crud-config.d.ts +20 -0
  83. package/dist/types/crud-config.d.ts.map +1 -0
  84. package/dist/types/crud-config.js +2 -0
  85. package/dist/types/crud-config.js.map +1 -0
  86. package/dist/types/generic-repository.d.ts +36 -0
  87. package/dist/types/generic-repository.d.ts.map +1 -0
  88. package/dist/types/generic-repository.js +2 -0
  89. package/dist/types/generic-repository.js.map +1 -0
  90. package/dist/types/index.d.ts +8 -0
  91. package/dist/types/index.d.ts.map +1 -0
  92. package/dist/types/index.js +8 -0
  93. package/dist/types/index.js.map +1 -0
  94. package/dist/types/logger.d.ts +17 -0
  95. package/dist/types/logger.d.ts.map +1 -0
  96. package/dist/types/logger.js +8 -0
  97. package/dist/types/logger.js.map +1 -0
  98. package/dist/types/pagination.d.ts +11 -0
  99. package/dist/types/pagination.d.ts.map +1 -0
  100. package/dist/types/pagination.js +2 -0
  101. package/dist/types/pagination.js.map +1 -0
  102. package/dist/types/prisma-delegate.types.d.ts +36 -0
  103. package/dist/types/prisma-delegate.types.d.ts.map +1 -0
  104. package/dist/types/prisma-delegate.types.js +15 -0
  105. package/dist/types/prisma-delegate.types.js.map +1 -0
  106. package/dist/types/query-params.d.ts +40 -0
  107. package/dist/types/query-params.d.ts.map +1 -0
  108. package/dist/types/query-params.js +2 -0
  109. package/dist/types/query-params.js.map +1 -0
  110. package/dist/types/schema-adapter.d.ts +19 -0
  111. package/dist/types/schema-adapter.d.ts.map +1 -0
  112. package/dist/types/schema-adapter.js +2 -0
  113. package/dist/types/schema-adapter.js.map +1 -0
  114. package/dist/utils/date.utils.d.ts +13 -0
  115. package/dist/utils/date.utils.d.ts.map +1 -0
  116. package/dist/utils/date.utils.js +75 -0
  117. package/dist/utils/date.utils.js.map +1 -0
  118. package/dist/utils/index.d.ts +4 -0
  119. package/dist/utils/index.d.ts.map +1 -0
  120. package/dist/utils/index.js +4 -0
  121. package/dist/utils/index.js.map +1 -0
  122. package/dist/utils/phone.utils.d.ts +7 -0
  123. package/dist/utils/phone.utils.d.ts.map +1 -0
  124. package/dist/utils/phone.utils.js +15 -0
  125. package/dist/utils/phone.utils.js.map +1 -0
  126. package/dist/utils/response.utils.d.ts +5 -0
  127. package/dist/utils/response.utils.d.ts.map +1 -0
  128. package/dist/utils/response.utils.js +13 -0
  129. package/dist/utils/response.utils.js.map +1 -0
  130. package/package.json +49 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ValibotAdapter, valibotAdapter } from './valibot.adapter.js';
2
+ export { ZodAdapter, zodAdapter } from './zod.adapter.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { SchemaAdapter } from '../types/schema-adapter.js';
2
+ /**
3
+ * Valibot schema adapter — default validation strategy.
4
+ *
5
+ * Wraps Valibot's `parse()` so that CrudRepository doesn't import
6
+ * valibot directly, making validation pluggable.
7
+ */
8
+ export declare class ValibotAdapter implements SchemaAdapter {
9
+ parse<T = unknown>(schema: unknown, data: unknown): T;
10
+ isValidSchema(schema: unknown): boolean;
11
+ }
12
+ /** Singleton instance for convenience. */
13
+ export declare const valibotAdapter: ValibotAdapter;
14
+ //# sourceMappingURL=valibot.adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valibot.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/valibot.adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC;IAIrD,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAQxC;AAED,0CAA0C;AAC1C,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { parse } from 'valibot';
2
+ /**
3
+ * Valibot schema adapter — default validation strategy.
4
+ *
5
+ * Wraps Valibot's `parse()` so that CrudRepository doesn't import
6
+ * valibot directly, making validation pluggable.
7
+ */
8
+ export class ValibotAdapter {
9
+ parse(schema, data) {
10
+ return parse(schema, data);
11
+ }
12
+ isValidSchema(schema) {
13
+ return (!!schema &&
14
+ typeof schema === 'object' &&
15
+ 'type' in schema &&
16
+ typeof schema['type'] === 'string');
17
+ }
18
+ }
19
+ /** Singleton instance for convenience. */
20
+ export const valibotAdapter = new ValibotAdapter();
21
+ //# sourceMappingURL=valibot.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valibot.adapter.js","sourceRoot":"","sources":["../../src/adapters/valibot.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACzB,KAAK,CAAc,MAAe,EAAE,IAAa;QAC/C,OAAO,KAAK,CAAC,MAAa,EAAE,IAAI,CAAM,CAAC;IACzC,CAAC;IAED,aAAa,CAAC,MAAe;QAC3B,OAAO,CACL,CAAC,CAAC,MAAM;YACR,OAAO,MAAM,KAAK,QAAQ;YAC1B,MAAM,IAAK,MAAiB;YAC5B,OAAQ,MAAkC,CAAC,MAAM,CAAC,KAAK,QAAQ,CAChE,CAAC;IACJ,CAAC;CACF;AAED,0CAA0C;AAC1C,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { SchemaAdapter } from '../types/schema-adapter.js';
2
+ /**
3
+ * Zod schema adapter.
4
+ *
5
+ * Allows consumers using Zod instead of Valibot to pass their schemas
6
+ * to CrudRepository without changing the repository code.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { z } from 'zod';
11
+ * import { ZodAdapter } from '@angelps/prisma-query-builder';
12
+ *
13
+ * class UserRepo extends CrudRepository<typeof prisma.user> {
14
+ * createSchema = z.object({ name: z.string().min(2), email: z.string().email() });
15
+ * updateSchema = z.object({ name: z.string().min(2) });
16
+ *
17
+ * constructor() {
18
+ * super(prisma.user, config, options, { schemaAdapter: new ZodAdapter() });
19
+ * }
20
+ * }
21
+ * ```
22
+ */
23
+ export declare class ZodAdapter implements SchemaAdapter {
24
+ parse<T = unknown>(schema: unknown, data: unknown): T;
25
+ isValidSchema(schema: unknown): boolean;
26
+ }
27
+ /** Singleton instance for convenience. */
28
+ export declare const zodAdapter: ZodAdapter;
29
+ //# sourceMappingURL=zod.adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/zod.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,UAAW,YAAW,aAAa;IAC9C,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC;IAarD,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAQxC;AAED,0CAA0C;AAC1C,eAAO,MAAM,UAAU,YAAmB,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Zod schema adapter.
3
+ *
4
+ * Allows consumers using Zod instead of Valibot to pass their schemas
5
+ * to CrudRepository without changing the repository code.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { z } from 'zod';
10
+ * import { ZodAdapter } from '@angelps/prisma-query-builder';
11
+ *
12
+ * class UserRepo extends CrudRepository<typeof prisma.user> {
13
+ * createSchema = z.object({ name: z.string().min(2), email: z.string().email() });
14
+ * updateSchema = z.object({ name: z.string().min(2) });
15
+ *
16
+ * constructor() {
17
+ * super(prisma.user, config, options, { schemaAdapter: new ZodAdapter() });
18
+ * }
19
+ * }
20
+ * ```
21
+ */
22
+ export class ZodAdapter {
23
+ parse(schema, data) {
24
+ // Zod schemas have a `.parse()` method
25
+ if (schema &&
26
+ typeof schema === 'object' &&
27
+ 'parse' in schema &&
28
+ typeof schema['parse'] === 'function') {
29
+ return schema.parse(data);
30
+ }
31
+ throw new Error('ZodAdapter: provided schema does not have a .parse() method');
32
+ }
33
+ isValidSchema(schema) {
34
+ return (!!schema &&
35
+ typeof schema === 'object' &&
36
+ 'parse' in schema &&
37
+ typeof schema['parse'] === 'function');
38
+ }
39
+ }
40
+ /** Singleton instance for convenience. */
41
+ export const zodAdapter = new ZodAdapter();
42
+ //# sourceMappingURL=zod.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.adapter.js","sourceRoot":"","sources":["../../src/adapters/zod.adapter.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,UAAU;IACrB,KAAK,CAAc,MAAe,EAAE,IAAa;QAC/C,uCAAuC;QACvC,IACE,MAAM;YACN,OAAO,MAAM,KAAK,QAAQ;YAC1B,OAAO,IAAI,MAAM;YACjB,OAAQ,MAAkC,CAAC,OAAO,CAAC,KAAK,UAAU,EAClE,CAAC;YACD,OAAQ,MAAsC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,aAAa,CAAC,MAAe;QAC3B,OAAO,CACL,CAAC,CAAC,MAAM;YACR,OAAO,MAAM,KAAK,QAAQ;YAC1B,OAAO,IAAK,MAAiB;YAC7B,OAAQ,MAAkC,CAAC,OAAO,CAAC,KAAK,UAAU,CACnE,CAAC;IACJ,CAAC;CACF;AAED,0CAA0C;AAC1C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC"}
@@ -0,0 +1,79 @@
1
+ import type { NextFunction, Request, Response } from 'express';
2
+ import type { QueryParams } from '../types/query-params.js';
3
+ import { ErrorHandlerService } from '../services/error-handler.service.js';
4
+ import type { IAuditService } from '../services/audit.service.js';
5
+ import type { IGenericRepository, RepositoryOptions } from '../types/generic-repository.js';
6
+ /** Maps a field from `req.user` to a query param field. */
7
+ export type UserFieldInjection = {
8
+ /** Field path on `req.user` (e.g. "branchIds", "companyIds", "tenantId") */
9
+ userField: string;
10
+ /** Field name to inject into query params (e.g. "branchId", "companyId") */
11
+ queryField: string;
12
+ };
13
+ /** Lifecycle hooks for controller operations. */
14
+ export type ControllerHooks<T = any> = {
15
+ beforeCreate?: (req: Request, data: unknown) => unknown | Promise<unknown>;
16
+ afterCreate?: (req: Request, result: T) => void | Promise<void>;
17
+ beforeUpdate?: (req: Request, id: number, data: unknown) => unknown | Promise<unknown>;
18
+ afterUpdate?: (req: Request, id: number) => void | Promise<void>;
19
+ beforeDelete?: (req: Request, id: number) => void | Promise<void>;
20
+ afterDelete?: (req: Request, id: number) => void | Promise<void>;
21
+ };
22
+ export type GenericControllerConfig<T = any> = {
23
+ entityName?: string;
24
+ audit?: boolean;
25
+ auditService?: IAuditService;
26
+ /**
27
+ * Configurable field injection from `req.user` into query params.
28
+ *
29
+ * Replaces the hardcoded `filterByUserBranch` / `filterByUserCompany` flags.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * {
34
+ * injectFromUser: [
35
+ * { userField: 'branchIds', queryField: 'branchId' },
36
+ * { userField: 'companyIds', queryField: 'companyId' },
37
+ * { userField: 'tenantId', queryField: 'tenantId' },
38
+ * ]
39
+ * }
40
+ * ```
41
+ */
42
+ injectFromUser?: UserFieldInjection[];
43
+ /** Lifecycle hooks executed before/after CRUD operations. */
44
+ hooks?: ControllerHooks<T>;
45
+ /**
46
+ * @deprecated Use `injectFromUser: [{ userField: 'branchIds', queryField: 'branchId' }]` instead.
47
+ */
48
+ filterByUserBranch?: boolean;
49
+ /**
50
+ * @deprecated Use `injectFromUser: [{ userField: 'companyIds', queryField: 'companyId' }]` instead.
51
+ */
52
+ filterByUserCompany?: boolean;
53
+ };
54
+ export declare class GenericController<T> {
55
+ protected readonly repository: IGenericRepository<T>;
56
+ protected readonly entity: string;
57
+ protected readonly auditEnabled: boolean;
58
+ protected readonly auditSvc?: IAuditService;
59
+ protected readonly injections: UserFieldInjection[];
60
+ protected readonly hooks: ControllerHooks<T>;
61
+ errorHandlerService: ErrorHandlerService;
62
+ constructor(repository: IGenericRepository<T>, entity: string, config?: GenericControllerConfig<T>);
63
+ protected getRepoOptions(req: Request): RepositoryOptions;
64
+ /**
65
+ * Inject user fields into query params based on the configured injections.
66
+ */
67
+ protected injectUserFields(req: Request, queryParams: QueryParams): QueryParams;
68
+ getAll(req: Request, res: Response, next: NextFunction): Promise<void>;
69
+ getById(req: Request, res: Response, next: NextFunction): Promise<void>;
70
+ create(req: Request, res: Response, next: NextFunction): Promise<void>;
71
+ update(req: Request, res: Response, next: NextFunction): Promise<void>;
72
+ delete(req: Request, res: Response, next: NextFunction): Promise<void>;
73
+ protected validateIfResourceExists(id: number, options?: RepositoryOptions): Promise<void>;
74
+ /**
75
+ * Método genérico para ejecutar operaciones con auditoría automática
76
+ */
77
+ protected executeWithAudit(req: Request, res: Response, next: NextFunction, operation: (id: number, options?: RepositoryOptions) => Promise<void>, action: 'UPDATE' | 'DELETE' | 'CREATE', successMessage?: string, statusCode?: number): Promise<void>;
78
+ }
79
+ //# sourceMappingURL=generic.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/generic.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,279 @@
1
+ import { ErrorMessages } from '../errors/error-messages.js';
2
+ import { ErrorHandlerService } from '../services/error-handler.service.js';
3
+ import { apiResponse, apiPaginationResponse } from '../utils/response.utils.js';
4
+ export class GenericController {
5
+ repository;
6
+ entity;
7
+ auditEnabled;
8
+ auditSvc;
9
+ injections;
10
+ hooks;
11
+ errorHandlerService = new ErrorHandlerService();
12
+ constructor(repository, entity, config = {}) {
13
+ this.repository = repository;
14
+ this.entity = config.entityName ?? entity;
15
+ this.auditEnabled = config.audit ?? false;
16
+ this.auditSvc = config.auditService;
17
+ this.hooks = config.hooks ?? {};
18
+ // Build injections list — merge explicit config with deprecated flags
19
+ const injections = [...(config.injectFromUser ?? [])];
20
+ // Backwards compat: translate deprecated flags into injections
21
+ if (config.filterByUserBranch) {
22
+ const alreadyHas = injections.some((i) => i.queryField === 'branchId');
23
+ if (!alreadyHas) {
24
+ injections.push({ userField: 'branchIds', queryField: 'branchId' });
25
+ }
26
+ }
27
+ if (config.filterByUserCompany) {
28
+ const alreadyHas = injections.some((i) => i.queryField === 'companyId');
29
+ if (!alreadyHas) {
30
+ injections.push({ userField: 'companyIds', queryField: 'companyId' });
31
+ }
32
+ }
33
+ this.injections = injections;
34
+ }
35
+ getRepoOptions(req) {
36
+ const userId = req.user?.id;
37
+ const audit = req.audit;
38
+ return {
39
+ ...(typeof userId === 'number' ? { userId } : {}),
40
+ ...(audit?.requestId ? { requestId: audit.requestId } : {}),
41
+ ...(audit?.ip ? { ip: audit.ip } : {}),
42
+ ...(audit?.userAgent ? { userAgent: audit.userAgent } : {}),
43
+ ...(audit?.path ? { path: audit.path } : {}),
44
+ ...(audit?.method ? { method: audit.method } : {}),
45
+ };
46
+ }
47
+ /**
48
+ * Inject user fields into query params based on the configured injections.
49
+ */
50
+ injectUserFields(req, queryParams) {
51
+ if (this.injections.length === 0)
52
+ return queryParams;
53
+ const result = { ...queryParams };
54
+ const user = req.user;
55
+ if (!user)
56
+ return result;
57
+ for (const { userField, queryField } of this.injections) {
58
+ const value = user[userField];
59
+ if (value !== undefined) {
60
+ result[queryField] = value;
61
+ }
62
+ }
63
+ return result;
64
+ }
65
+ async getAll(req, res, next) {
66
+ try {
67
+ const queryParams = req.query;
68
+ const options = this.getRepoOptions(req);
69
+ const enrichedParams = this.injectUserFields(req, queryParams);
70
+ const data = await this.repository.findAll(enrichedParams, options);
71
+ apiPaginationResponse(res, data, 'Resources retrieved successfully', 200);
72
+ }
73
+ catch (error) {
74
+ this.errorHandlerService.genericErrorHandler({
75
+ error: error,
76
+ res,
77
+ next,
78
+ entity: this.entity,
79
+ });
80
+ }
81
+ }
82
+ async getById(req, res, next) {
83
+ try {
84
+ const id = Number(req.params.id);
85
+ if (Number.isNaN(id)) {
86
+ apiResponse(res, null, 'Invalid id', 400);
87
+ return;
88
+ }
89
+ const options = this.getRepoOptions(req);
90
+ const data = await this.repository.findById(id, options);
91
+ if (!data)
92
+ throw new Error(ErrorMessages.RESOURCE_NOT_FOUND.message);
93
+ apiResponse(res, data, 'Resource retrieved successfully', 200);
94
+ }
95
+ catch (error) {
96
+ this.errorHandlerService.genericErrorHandler({
97
+ error: error,
98
+ res,
99
+ next,
100
+ entity: this.entity,
101
+ });
102
+ }
103
+ }
104
+ async create(req, res, next) {
105
+ try {
106
+ const options = this.getRepoOptions(req);
107
+ // Lifecycle hook: beforeCreate
108
+ let data = req.body;
109
+ if (this.hooks.beforeCreate) {
110
+ data = await this.hooks.beforeCreate(req, data);
111
+ }
112
+ const created = await this.repository.create(data, options);
113
+ // Lifecycle hook: afterCreate
114
+ if (this.hooks.afterCreate) {
115
+ await this.hooks.afterCreate(req, created);
116
+ }
117
+ if (this.auditEnabled && this.auditSvc) {
118
+ await this.auditSvc.log({
119
+ action: 'CREATE',
120
+ entity: this.entity,
121
+ entityId: created?.id ?? null,
122
+ after: created,
123
+ metadata: { source: 'generic-controller' },
124
+ options,
125
+ });
126
+ }
127
+ apiResponse(res, created, `${this.entity} created successfully`, 201);
128
+ }
129
+ catch (error) {
130
+ this.errorHandlerService.genericErrorHandler({
131
+ error: error,
132
+ res,
133
+ next,
134
+ entity: this.entity,
135
+ });
136
+ }
137
+ }
138
+ async update(req, res, next) {
139
+ try {
140
+ const id = Number(req.params.id);
141
+ if (Number.isNaN(id)) {
142
+ apiResponse(res, null, 'Invalid id', 400);
143
+ return;
144
+ }
145
+ const options = this.getRepoOptions(req);
146
+ // Always validate existence; capture snapshot only for audit
147
+ const existing = await this.repository.findById(id, options);
148
+ if (!existing) {
149
+ throw new Error(ErrorMessages.RESOURCE_NOT_FOUND.message);
150
+ }
151
+ const before = this.auditEnabled ? existing : null;
152
+ // Lifecycle hook: beforeUpdate
153
+ let data = req.body;
154
+ if (this.hooks.beforeUpdate) {
155
+ data = await this.hooks.beforeUpdate(req, id, data);
156
+ }
157
+ await this.repository.update(id, data, options);
158
+ // Lifecycle hook: afterUpdate
159
+ if (this.hooks.afterUpdate) {
160
+ await this.hooks.afterUpdate(req, id);
161
+ }
162
+ const after = this.auditEnabled
163
+ ? await this.repository.findById(id, options)
164
+ : null;
165
+ if (this.auditEnabled && this.auditSvc) {
166
+ await this.auditSvc.log({
167
+ action: 'UPDATE',
168
+ entity: this.entity,
169
+ entityId: id,
170
+ before,
171
+ after,
172
+ metadata: { source: 'generic-controller' },
173
+ options,
174
+ });
175
+ }
176
+ apiResponse(res, null, `${this.entity} updated successfully`, 204);
177
+ }
178
+ catch (error) {
179
+ this.errorHandlerService.genericErrorHandler({
180
+ error: error,
181
+ res,
182
+ next,
183
+ entity: this.entity,
184
+ });
185
+ }
186
+ }
187
+ async delete(req, res, next) {
188
+ try {
189
+ const id = Number(req.params.id);
190
+ if (Number.isNaN(id)) {
191
+ apiResponse(res, null, 'Invalid id', 400);
192
+ return;
193
+ }
194
+ const options = this.getRepoOptions(req);
195
+ const before = this.auditEnabled
196
+ ? await this.repository.findById(id, options)
197
+ : null;
198
+ await this.validateIfResourceExists(id, options);
199
+ // Lifecycle hook: beforeDelete
200
+ if (this.hooks.beforeDelete) {
201
+ await this.hooks.beforeDelete(req, id);
202
+ }
203
+ await this.repository.delete(id, options);
204
+ // Lifecycle hook: afterDelete
205
+ if (this.hooks.afterDelete) {
206
+ await this.hooks.afterDelete(req, id);
207
+ }
208
+ if (this.auditEnabled && this.auditSvc) {
209
+ await this.auditSvc.log({
210
+ action: 'DELETE',
211
+ entity: this.entity,
212
+ entityId: id,
213
+ before,
214
+ metadata: { source: 'generic-controller', softDelete: true },
215
+ options,
216
+ });
217
+ }
218
+ apiResponse(res, null, undefined, 204);
219
+ }
220
+ catch (error) {
221
+ this.errorHandlerService.genericErrorHandler({
222
+ error: error,
223
+ res,
224
+ next,
225
+ entity: this.entity,
226
+ });
227
+ }
228
+ }
229
+ async validateIfResourceExists(id, options) {
230
+ const item = await this.repository.findById(id, options);
231
+ if (!item)
232
+ throw new Error(ErrorMessages.RESOURCE_NOT_FOUND.message);
233
+ }
234
+ /**
235
+ * Método genérico para ejecutar operaciones con auditoría automática
236
+ */
237
+ async executeWithAudit(req, res, next, operation, action, successMessage, statusCode = 200) {
238
+ try {
239
+ const id = Number(req.params.id);
240
+ if (Number.isNaN(id)) {
241
+ apiResponse(res, null, 'Invalid id', 400);
242
+ return;
243
+ }
244
+ const options = this.getRepoOptions(req);
245
+ const before = this.auditEnabled
246
+ ? await this.repository.findById(id, options)
247
+ : null;
248
+ if (!before && (action === 'UPDATE' || action === 'DELETE')) {
249
+ throw new Error(ErrorMessages.RESOURCE_NOT_FOUND.message);
250
+ }
251
+ await operation(id, options);
252
+ const after = this.auditEnabled
253
+ ? await this.repository.findById(id, options)
254
+ : null;
255
+ if (this.auditEnabled && this.auditSvc) {
256
+ await this.auditSvc.log({
257
+ action,
258
+ entity: this.entity,
259
+ entityId: id,
260
+ before,
261
+ after,
262
+ metadata: { source: 'generic-controller' },
263
+ options,
264
+ });
265
+ }
266
+ apiResponse(res, null, successMessage ??
267
+ `${this.entity} ${action.toLocaleLowerCase()} successfully`, statusCode);
268
+ }
269
+ catch (error) {
270
+ this.errorHandlerService.genericErrorHandler({
271
+ error: error,
272
+ res,
273
+ next,
274
+ entity: this.entity,
275
+ });
276
+ }
277
+ }
278
+ }
279
+ //# sourceMappingURL=generic.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.controller.js","sourceRoot":"","sources":["../../src/controllers/generic.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './generic.controller.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/controllers/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './generic.controller.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/controllers/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,17 @@
1
+ export declare class AppError extends Error {
2
+ readonly statusCode: number;
3
+ constructor(message: string, statusCode: number);
4
+ }
5
+ /** 409 Conflict — el recurso ya existe o el slot está ocupado */
6
+ export declare class ConflictError extends AppError {
7
+ constructor(message: string);
8
+ }
9
+ /** 400 Bad Request — regla de negocio inválida */
10
+ export declare class BadRequestError extends AppError {
11
+ constructor(message: string);
12
+ }
13
+ /** 404 Not Found */
14
+ export declare class NotFoundError extends AppError {
15
+ constructor(message: string);
16
+ }
17
+ //# sourceMappingURL=app-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-errors.d.ts","sourceRoot":"","sources":["../../src/errors/app-errors.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAS,SAAQ,KAAK;aAGf,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM;CAMrC;AAED,iEAAiE;AACjE,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,EAAE,MAAM;CAG5B;AAED,kDAAkD;AAClD,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM;CAG5B;AAED,oBAAoB;AACpB,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,EAAE,MAAM;CAG5B"}
@@ -0,0 +1,28 @@
1
+ export class AppError extends Error {
2
+ statusCode;
3
+ constructor(message, statusCode) {
4
+ super(message);
5
+ this.statusCode = statusCode;
6
+ this.name = this.constructor.name;
7
+ Object.setPrototypeOf(this, new.target.prototype);
8
+ }
9
+ }
10
+ /** 409 Conflict — el recurso ya existe o el slot está ocupado */
11
+ export class ConflictError extends AppError {
12
+ constructor(message) {
13
+ super(message, 409);
14
+ }
15
+ }
16
+ /** 400 Bad Request — regla de negocio inválida */
17
+ export class BadRequestError extends AppError {
18
+ constructor(message) {
19
+ super(message, 400);
20
+ }
21
+ }
22
+ /** 404 Not Found */
23
+ export class NotFoundError extends AppError {
24
+ constructor(message) {
25
+ super(message, 404);
26
+ }
27
+ }
28
+ //# sourceMappingURL=app-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-errors.js","sourceRoot":"","sources":["../../src/errors/app-errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGf;IAFlB,YACE,OAAe,EACC,UAAkB;QAElC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,eAAU,GAAV,UAAU,CAAQ;QAGlC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC;CACF;AAED,kDAAkD;AAClD,MAAM,OAAO,eAAgB,SAAQ,QAAQ;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC;CACF;AAED,oBAAoB;AACpB,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC;CACF"}