nestjs-exception-handler 1.0.0 → 3.0.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.
@@ -0,0 +1,10 @@
1
+ export interface ValidationError {
2
+ property: string;
3
+ constraints?: Record<string, string>;
4
+ children?: ValidationError[];
5
+ }
6
+ export interface ParsedValidationError {
7
+ path: string;
8
+ message: string;
9
+ }
10
+ export declare function parseValidationErrors(errors: ValidationError[]): ParsedValidationError[];
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseValidationErrors = parseValidationErrors;
4
+ function parseValidationErrors(errors) {
5
+ const result = [];
6
+ for (const error of errors) {
7
+ if (error.constraints && Object.keys(error.constraints).length > 0) {
8
+ const messages = Object.values(error.constraints).join(", ");
9
+ result.push({
10
+ path: error.property,
11
+ message: messages,
12
+ });
13
+ }
14
+ if (error.children && error.children.length > 0) {
15
+ result.push(...parseValidationErrors(error.children));
16
+ }
17
+ }
18
+ return result;
19
+ }
package/dist/index.d.ts CHANGED
@@ -1,96 +1,3 @@
1
- import { ExceptionFilter, ArgumentsHost, DynamicModule } from '@nestjs/common';
2
-
3
- interface ErrorMessage {
4
- path: string;
5
- message: string;
6
- }
7
- interface StandardErrorResponse {
8
- success: boolean;
9
- message: string;
10
- errorMessages: ErrorMessage[];
11
- }
12
-
13
- interface ExceptionFormatter {
14
- supports(exception: unknown): boolean;
15
- format(exception: unknown): ErrorMessage[];
16
- message(exception: unknown): string;
17
- }
18
-
19
- interface ExceptionHandlerConfig {
20
- enableLogging?: boolean;
21
- hideStackTrace?: boolean;
22
- }
23
-
24
- declare const DEFAULT_ERROR_MESSAGES: {
25
- UNKNOWN_ERROR: string;
26
- VALIDATION_ERROR: string;
27
- DATABASE_ERROR: string;
28
- NOT_FOUND: string;
29
- UNAUTHORIZED: string;
30
- FORBIDDEN: string;
31
- CONFLICT: string;
32
- BAD_REQUEST: string;
33
- };
34
- declare const PRISMA_ERROR_MESSAGES: Record<string, string>;
35
- declare const DEFAULT_PATH = "unknown";
36
-
37
- declare function isPrismaError(exception: unknown): boolean;
38
-
39
- declare class PrismaExceptionFormatter implements ExceptionFormatter {
40
- supports(exception: unknown): boolean;
41
- format(exception: unknown): ErrorMessage[];
42
- message(exception: unknown): string;
43
- }
44
-
45
- declare class DtoExceptionFormatter implements ExceptionFormatter {
46
- supports(exception: unknown): boolean;
47
- format(exception: unknown): ErrorMessage[];
48
- message(exception: unknown): string;
49
- private formatValidationErrors;
50
- private formatChildrenErrors;
51
- }
52
-
53
- declare class HttpExceptionFormatter implements ExceptionFormatter {
54
- supports(exception: unknown): boolean;
55
- format(exception: unknown): ErrorMessage[];
56
- message(exception: unknown): string;
57
- }
58
-
59
- declare class UnknownExceptionFormatter implements ExceptionFormatter {
60
- supports(_exception: unknown): boolean;
61
- format(_exception: unknown): ErrorMessage[];
62
- message(_exception: unknown): string;
63
- }
64
-
65
- declare class ExceptionHandlerService {
66
- private formatters;
67
- private defaultFormatter;
68
- constructor();
69
- registerFormatter(formatter: ExceptionFormatter): void;
70
- getFormatter(exception: unknown): ExceptionFormatter;
71
- formatException(exception: unknown): {
72
- errors: ErrorMessage[];
73
- message: string;
74
- };
75
- formatErrors(exception: unknown): ErrorMessage[];
76
- getErrorMessage(exception: unknown): string;
77
- getAllFormatters(): ExceptionFormatter[];
78
- }
79
-
80
- declare class GlobalExceptionFilter implements ExceptionFilter {
81
- private exceptionHandlerService;
82
- private readonly logger;
83
- private config;
84
- constructor(exceptionHandlerService: ExceptionHandlerService, config?: ExceptionHandlerConfig);
85
- catch(exception: unknown, host: ArgumentsHost): void;
86
- private getStatusCode;
87
- private logError;
88
- }
89
-
90
- declare class ExceptionHandlerModule {
91
- static forRoot(config?: ExceptionHandlerConfig): DynamicModule;
92
- static forFeature(config?: ExceptionHandlerConfig): DynamicModule;
93
- }
94
- declare function initializeFormatters(service: ExceptionHandlerService): void;
95
-
96
- export { DEFAULT_ERROR_MESSAGES, DEFAULT_PATH, DtoExceptionFormatter, ErrorMessage, ExceptionFormatter, ExceptionHandlerConfig, ExceptionHandlerModule, ExceptionHandlerService, GlobalExceptionFilter, HttpExceptionFormatter, PRISMA_ERROR_MESSAGES, PrismaExceptionFormatter, StandardErrorResponse, UnknownExceptionFormatter, initializeFormatters, isPrismaError };
1
+ export * from "./formatter";
2
+ export * from "./helpers";
3
+ export * from "./global-exception-filter";
package/dist/index.js CHANGED
@@ -1,384 +1,19 @@
1
1
  "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var __decorateClass = (decorators, target, key, kind) => {
20
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
- if (decorator = decorators[i])
23
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
- if (kind && result)
25
- __defProp(target, key, result);
26
- return result;
27
- };
28
-
29
- // src/index.ts
30
- var src_exports = {};
31
- __export(src_exports, {
32
- DEFAULT_ERROR_MESSAGES: () => DEFAULT_ERROR_MESSAGES,
33
- DEFAULT_PATH: () => DEFAULT_PATH,
34
- DtoExceptionFormatter: () => DtoExceptionFormatter,
35
- ExceptionHandlerModule: () => ExceptionHandlerModule,
36
- ExceptionHandlerService: () => ExceptionHandlerService,
37
- GlobalExceptionFilter: () => GlobalExceptionFilter,
38
- HttpExceptionFormatter: () => HttpExceptionFormatter,
39
- PRISMA_ERROR_MESSAGES: () => PRISMA_ERROR_MESSAGES,
40
- PrismaExceptionFormatter: () => PrismaExceptionFormatter,
41
- UnknownExceptionFormatter: () => UnknownExceptionFormatter,
42
- initializeFormatters: () => initializeFormatters,
43
- isPrismaError: () => isPrismaError
44
- });
45
- module.exports = __toCommonJS(src_exports);
46
-
47
- // src/constants/default-messages.ts
48
- var DEFAULT_ERROR_MESSAGES = {
49
- UNKNOWN_ERROR: "An unexpected error occurred",
50
- VALIDATION_ERROR: "Validation failed",
51
- DATABASE_ERROR: "Database error",
52
- NOT_FOUND: "Resource not found",
53
- UNAUTHORIZED: "Unauthorized access",
54
- FORBIDDEN: "Access forbidden",
55
- CONFLICT: "Conflict occurred",
56
- BAD_REQUEST: "Bad request"
57
- };
58
- var PRISMA_ERROR_MESSAGES = {
59
- P2002: "A record with this {field} already exists.",
60
- P2003: "This {field} does not exist.",
61
- P2005: "Invalid value for {field}.",
62
- P2006: "Invalid format for {field}.",
63
- P2025: "Record not found."
64
- };
65
- var DEFAULT_PATH = "unknown";
66
-
67
- // src/utils/is-prisma-error.ts
68
- function isPrismaError(exception) {
69
- if (!exception || typeof exception !== "object") {
70
- return false;
71
- }
72
- const error = exception;
73
- const hasErrorCode = typeof error.code === "string";
74
- const hasClientVersion = typeof error.clientVersion === "string";
75
- const hasMeta = typeof error.meta === "object";
76
- return hasErrorCode && (hasClientVersion || hasMeta);
77
- }
78
-
79
- // src/formatters/prisma-exception.formatter.ts
80
- var PrismaExceptionFormatter = class {
81
- supports(exception) {
82
- return isPrismaError(exception);
83
- }
84
- format(exception) {
85
- const error = exception;
86
- const code = error.code;
87
- const meta = error.meta;
88
- const target = error.target;
89
- const messageTemplate = PRISMA_ERROR_MESSAGES[code] || "Database operation failed";
90
- let path = "unknown";
91
- let message = messageTemplate;
92
- if (code === "P2002" && target && target.length > 0) {
93
- path = target[0];
94
- message = messageTemplate.replace("{field}", path);
95
- } else if (code === "P2003" && meta?.field_name) {
96
- path = meta.field_name;
97
- message = messageTemplate.replace("{field}", path);
98
- } else if (code === "P2005" && meta?.field_name) {
99
- path = meta.field_name;
100
- message = messageTemplate.replace("{field}", path);
101
- } else if (code === "P2006" && meta?.field_name) {
102
- path = meta.field_name;
103
- message = messageTemplate.replace("{field}", path);
104
- } else if (code === "P2025") {
105
- path = "record";
106
- message = messageTemplate;
107
- }
108
- return [{ path, message }];
109
- }
110
- message(exception) {
111
- const error = exception;
112
- const code = error.code;
113
- return PRISMA_ERROR_MESSAGES[code] || "Database error";
114
- }
115
- };
116
-
117
- // src/formatters/dto-exception.formatter.ts
118
- var DtoExceptionFormatter = class {
119
- supports(exception) {
120
- if (!exception || typeof exception !== "object") {
121
- return false;
122
- }
123
- const error = exception;
124
- return Array.isArray(error.validationErrors) || Array.isArray(error.children) && error.constraints !== void 0;
125
- }
126
- format(exception) {
127
- const error = exception;
128
- const validationErrors = error.validationErrors;
129
- const children = error.children;
130
- if (validationErrors) {
131
- return this.formatValidationErrors(validationErrors);
132
- }
133
- if (children) {
134
- return this.formatChildrenErrors(children);
135
- }
136
- return [{ path: "unknown", message: "Validation failed" }];
137
- }
138
- message(exception) {
139
- const error = exception;
140
- const validationErrors = error.validationErrors;
141
- const children = error.children;
142
- if (validationErrors && validationErrors.length > 0) {
143
- const firstError = validationErrors[0];
144
- const constraints = firstError.constraints;
145
- if (constraints) {
146
- return Object.values(constraints)[0];
147
- }
148
- }
149
- if (children && children.length > 0) {
150
- return "Validation failed for nested fields";
151
- }
152
- return "Validation failed";
153
- }
154
- formatValidationErrors(errors) {
155
- return errors.flatMap((error) => {
156
- const constraints = error.constraints;
157
- if (constraints) {
158
- return Object.entries(constraints).map(([, value]) => ({
159
- path: error.property,
160
- message: value
161
- }));
162
- }
163
- return [];
164
- });
165
- }
166
- formatChildrenErrors(children) {
167
- return children.flatMap((child) => {
168
- const constraints = child.constraints;
169
- if (constraints) {
170
- return Object.entries(constraints).map(([, value]) => ({
171
- path: child.property,
172
- message: value
173
- }));
174
- }
175
- return [];
176
- });
177
- }
178
- };
179
-
180
- // src/formatters/http-exception.formatter.ts
181
- var import_common = require("@nestjs/common");
182
- var HttpExceptionFormatter = class {
183
- supports(exception) {
184
- return exception instanceof import_common.HttpException;
185
- }
186
- format(exception) {
187
- const httpException = exception;
188
- const response = httpException.getResponse();
189
- if (typeof response === "string") {
190
- return [{ path: "unknown", message: response }];
191
- }
192
- if (typeof response === "object" && response !== null) {
193
- const responseObj = response;
194
- if (responseObj.message && Array.isArray(responseObj.message)) {
195
- return responseObj.message.map((msg) => ({
196
- path: "unknown",
197
- message: msg
198
- }));
199
- }
200
- if (responseObj.message && typeof responseObj.message === "string") {
201
- return [{ path: "unknown", message: responseObj.message }];
202
- }
203
- if (responseObj.error && typeof responseObj.error === "string") {
204
- return [{ path: "unknown", message: responseObj.error }];
205
- }
206
- }
207
- return [{ path: "unknown", message: "An error occurred" }];
208
- }
209
- message(exception) {
210
- const httpException = exception;
211
- const response = httpException.getResponse();
212
- if (typeof response === "string") {
213
- return response;
214
- }
215
- if (typeof response === "object" && response !== null) {
216
- const responseObj = response;
217
- if (responseObj.message && typeof responseObj.message === "string") {
218
- return responseObj.message;
219
- }
220
- if (responseObj.error && typeof responseObj.error === "string") {
221
- return responseObj.error;
222
- }
223
- }
224
- return "An error occurred";
225
- }
226
- };
227
-
228
- // src/formatters/unknown-exception.formatter.ts
229
- var UnknownExceptionFormatter = class {
230
- supports(_exception) {
231
- return true;
232
- }
233
- format(_exception) {
234
- return [
235
- {
236
- path: DEFAULT_PATH,
237
- message: "Internal server error"
238
- }
239
- ];
240
- }
241
- message(_exception) {
242
- return "Internal server error";
243
- }
244
- };
245
-
246
- // src/services/exception-handler.service.ts
247
- var import_common2 = require("@nestjs/common");
248
- var ExceptionHandlerService = class {
249
- constructor() {
250
- this.formatters = [];
251
- this.defaultFormatter = new UnknownExceptionFormatter();
252
- }
253
- registerFormatter(formatter) {
254
- this.formatters.push(formatter);
255
- }
256
- getFormatter(exception) {
257
- for (const formatter of this.formatters) {
258
- if (formatter.supports(exception)) {
259
- return formatter;
260
- }
261
- }
262
- return this.defaultFormatter;
263
- }
264
- formatException(exception) {
265
- const formatter = this.getFormatter(exception);
266
- const errors = formatter.format(exception);
267
- const message = formatter.message(exception);
268
- return { errors, message };
269
- }
270
- formatErrors(exception) {
271
- const formatter = this.getFormatter(exception);
272
- return formatter.format(exception);
273
- }
274
- getErrorMessage(exception) {
275
- const formatter = this.getFormatter(exception);
276
- return formatter.message(exception);
277
- }
278
- getAllFormatters() {
279
- return [...this.formatters];
280
- }
281
- };
282
- ExceptionHandlerService = __decorateClass([
283
- (0, import_common2.Injectable)()
284
- ], ExceptionHandlerService);
285
-
286
- // src/filter/global-exception.filter.ts
287
- var import_common3 = require("@nestjs/common");
288
- var GlobalExceptionFilter = class {
289
- constructor(exceptionHandlerService, config) {
290
- this.exceptionHandlerService = exceptionHandlerService;
291
- this.logger = new import_common3.Logger(GlobalExceptionFilter.name);
292
- this.config = config || { enableLogging: true, hideStackTrace: false };
293
- }
294
- catch(exception, host) {
295
- const ctx = host.switchToHttp();
296
- const response = ctx.getResponse();
297
- const request = ctx.getRequest();
298
- const { errors, message } = this.exceptionHandlerService.formatException(exception);
299
- const status = this.getStatusCode(exception);
300
- const errorResponse = {
301
- success: false,
302
- message,
303
- errorMessages: errors
304
- };
305
- if (this.config.enableLogging) {
306
- this.logError(request, status, errors, exception);
307
- }
308
- response.status(status).json(errorResponse);
309
- }
310
- getStatusCode(exception) {
311
- if (exception instanceof import_common3.HttpException) {
312
- return exception.getStatus();
313
- }
314
- return import_common3.HttpStatus.INTERNAL_SERVER_ERROR;
315
- }
316
- logError(request, status, errorMessages, exception) {
317
- const method = request.method;
318
- const url = request.url;
319
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
320
- const logData = {
321
- timestamp,
322
- method,
323
- url,
324
- status,
325
- errorMessages,
326
- stack: this.config.hideStackTrace ? void 0 : exception?.stack
327
- };
328
- this.logger.error(`${method} ${url} - ${status}`, JSON.stringify(logData));
329
- }
330
- };
331
- GlobalExceptionFilter = __decorateClass([
332
- (0, import_common3.Catch)()
333
- ], GlobalExceptionFilter);
334
-
335
- // src/module/exception-handler.module.ts
336
- var import_common4 = require("@nestjs/common");
337
- var ExceptionHandlerModule = class {
338
- static forRoot(config) {
339
- const providers = [
340
- ExceptionHandlerService,
341
- {
342
- provide: GlobalExceptionFilter,
343
- useFactory: (service) => {
344
- return new GlobalExceptionFilter(service, config);
345
- },
346
- inject: [ExceptionHandlerService]
347
- }
348
- ];
349
- return {
350
- module: ExceptionHandlerModule,
351
- providers,
352
- exports: [ExceptionHandlerService, GlobalExceptionFilter],
353
- global: true
354
- };
355
- }
356
- static forFeature(config) {
357
- return this.forRoot(config);
358
- }
359
- };
360
- ExceptionHandlerModule = __decorateClass([
361
- (0, import_common4.Module)({})
362
- ], ExceptionHandlerModule);
363
- function initializeFormatters(service) {
364
- service.registerFormatter(new PrismaExceptionFormatter());
365
- service.registerFormatter(new DtoExceptionFormatter());
366
- service.registerFormatter(new HttpExceptionFormatter());
367
- service.registerFormatter(new UnknownExceptionFormatter());
368
- }
369
- // Annotate the CommonJS export names for ESM import in node:
370
- 0 && (module.exports = {
371
- DEFAULT_ERROR_MESSAGES,
372
- DEFAULT_PATH,
373
- DtoExceptionFormatter,
374
- ExceptionHandlerModule,
375
- ExceptionHandlerService,
376
- GlobalExceptionFilter,
377
- HttpExceptionFormatter,
378
- PRISMA_ERROR_MESSAGES,
379
- PrismaExceptionFormatter,
380
- UnknownExceptionFormatter,
381
- initializeFormatters,
382
- isPrismaError
383
- });
384
- //# sourceMappingURL=index.js.map
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./formatter"), exports);
18
+ __exportStar(require("./helpers"), exports);
19
+ __exportStar(require("./global-exception-filter"), exports);
package/package.json CHANGED
@@ -1,72 +1,75 @@
1
1
  {
2
2
  "name": "nestjs-exception-handler",
3
- "version": "1.0.0",
4
- "description": "A production-grade global exception handling system for NestJS applications",
3
+ "version": "3.0.0",
4
+ "description": "A comprehensive global exception filter for NestJS that handles all common NestJS, Prisma, and Node.js exceptions with formatted error responses.",
5
5
  "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
6
  "types": "dist/index.d.ts",
8
7
  "exports": {
9
8
  ".": {
10
- "import": "./dist/index.mjs",
9
+ "import": "./dist/index.js",
11
10
  "require": "./dist/index.js",
12
11
  "types": "./dist/index.d.ts"
13
12
  }
14
13
  },
15
14
  "files": [
16
- "dist"
15
+ "dist",
16
+ "README.md"
17
17
  ],
18
18
  "scripts": {
19
- "build": "tsup",
20
- "lint": "eslint src --ext .ts",
21
- "format": "prettier --write \"src/**/*.ts\"",
22
- "test": "jest",
23
- "test:watch": "jest --watch",
24
- "test:cov": "jest --coverage",
25
- "prepublishOnly": "npm run build"
19
+ "build": "tsc",
20
+ "prepublishOnly": "npm run build",
21
+ "test": "echo \"No tests specified\" && exit 0"
26
22
  },
27
23
  "keywords": [
28
24
  "nestjs",
29
25
  "exception",
30
- "handler",
31
26
  "filter",
32
27
  "error",
28
+ "handler",
33
29
  "prisma",
34
- "validation"
30
+ "error-handler",
31
+ "exception-filter",
32
+ "global-exception-filter",
33
+ "nestjs-exception",
34
+ "nestjs-error",
35
+ "validation",
36
+ "class-validator"
35
37
  ],
36
- "author": "Nurul Islam Rimon",
38
+ "author": "Nurul Islam Rimon <nurulislamrimon@gmail.com>",
37
39
  "license": "MIT",
38
40
  "repository": {
39
41
  "type": "git",
40
42
  "url": "https://github.com/nurulislamrimon/nestjs-exception-handler.git"
41
43
  },
44
+ "bugs": {
45
+ "url": "https://github.com/nurulislamrimon/nestjs-exception-handler/issues"
46
+ },
47
+ "homepage": "https://github.com/nurulislamrimon/nestjs-exception-handler#readme",
48
+ "engines": {
49
+ "node": ">=16"
50
+ },
42
51
  "peerDependencies": {
43
52
  "@nestjs/common": "^10.0.0",
44
53
  "@nestjs/core": "^10.0.0",
45
- "@prisma/client": "^5.0.0",
46
- "reflect-metadata": "^0.1.13",
47
- "rxjs": "^7.8.0"
54
+ "@prisma/client": ">=4.0.0"
55
+ },
56
+ "peerDependenciesMeta": {
57
+ "@nestjs/common": {
58
+ "optional": true
59
+ },
60
+ "@nestjs/core": {
61
+ "optional": true
62
+ },
63
+ "@prisma/client": {
64
+ "optional": true
65
+ }
48
66
  },
49
67
  "devDependencies": {
50
68
  "@nestjs/common": "^10.0.0",
51
69
  "@nestjs/core": "^10.0.0",
52
- "@nestjs/testing": "^10.4.22",
53
- "@prisma/client": "^5.0.0",
54
- "@types/express": "^4.17.17",
55
- "@types/jest": "^29.5.0",
56
- "@types/node": "^20.0.0",
57
- "@typescript-eslint/eslint-plugin": "^6.0.0",
58
- "@typescript-eslint/parser": "^6.0.0",
59
- "eslint": "^8.0.0",
60
- "eslint-config-prettier": "^10.1.8",
61
- "eslint-plugin-prettier": "^5.5.5",
62
- "jest": "^29.5.0",
63
- "prettier": "^3.0.0",
64
- "reflect-metadata": "^0.1.13",
65
- "rxjs": "^7.8.0",
66
- "ts-jest": "^29.1.0",
67
- "ts-node": "^10.9.2",
68
- "tsup": "^7.0.0",
69
- "typescript": "^5.0.0"
70
- },
71
- "dependencies": {}
70
+ "@prisma/client": "^6.9.0",
71
+ "@types/express": "^5.0.0",
72
+ "@types/node": "^24.0.2",
73
+ "typescript": "^5.8.3"
74
+ }
72
75
  }