karos 1.0.1 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -63
- package/dist/index.d.ts +47 -6
- package/dist/index.js +123 -4
- package/package.json +17 -6
package/README.md
CHANGED
|
@@ -1,103 +1,167 @@
|
|
|
1
|
-
|
|
2
|
-
=====
|
|
1
|
+
# Karos
|
|
3
2
|
|
|
4
3
|
**Opinionated, minimal API response & error standardization for Express.**
|
|
5
4
|
|
|
6
|
-
Karos enforces predictable JSON response
|
|
5
|
+
Karos enforces a single, predictable JSON response contract across your entire Node.js API — without adding business logic, configuration, or framework lock-in.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🚫 The Problem
|
|
10
10
|
|
|
11
11
|
In most Express backends:
|
|
12
|
+
- ❌ Every route formats responses differently
|
|
13
|
+
- ❌ Errors are sometimes strings, sometimes objects
|
|
14
|
+
- ❌ Status codes are inconsistent
|
|
15
|
+
- ❌ Frontend logic becomes fragile and conditional-heavy
|
|
16
|
+
- ❌ Teams rewrite the same response boilerplate in every project
|
|
17
|
+
|
|
18
|
+
**There is no enforced backend–frontend contract.**
|
|
19
|
+
|
|
20
|
+
## ✅ The Solution
|
|
21
|
+
|
|
22
|
+
Karos fixes exactly this problem — nothing more, nothing less. It enforces **one response contract** for your entire API.
|
|
23
|
+
|
|
24
|
+
### Success Response
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"success": true,
|
|
28
|
+
"data": {
|
|
29
|
+
"id": 123,
|
|
30
|
+
"name": "Alice"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Error Response
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"success": false,
|
|
39
|
+
"error": {
|
|
40
|
+
"code": "NOT_FOUND",
|
|
41
|
+
"message": "User not found"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
12
45
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* Errors are sometimes strings, sometimes objects
|
|
16
|
-
|
|
17
|
-
* Status codes are inconsistent
|
|
18
|
-
|
|
19
|
-
* Frontend logic becomes fragile and full of conditionals
|
|
20
|
-
|
|
21
|
-
* Teams re-implement the same response boilerplate in every project
|
|
22
|
-
|
|
46
|
+
No exceptions. No special cases.
|
|
23
47
|
|
|
24
|
-
|
|
48
|
+
---
|
|
25
49
|
|
|
26
|
-
|
|
27
|
-
-------------------
|
|
50
|
+
## 📦 Installation
|
|
28
51
|
|
|
29
|
-
|
|
52
|
+
```bash
|
|
53
|
+
npm install karos
|
|
54
|
+
```
|
|
30
55
|
|
|
31
|
-
|
|
32
|
-
-------
|
|
56
|
+
---
|
|
33
57
|
|
|
34
|
-
|
|
58
|
+
## 🚀 Quick Start (60 seconds)
|
|
35
59
|
|
|
36
|
-
|
|
37
|
-
-----
|
|
60
|
+
Karos replaces manual `try/catch` blocks and inconsistent response formatting.
|
|
38
61
|
|
|
39
|
-
|
|
62
|
+
### 1. Basic Setup
|
|
40
63
|
|
|
41
|
-
|
|
64
|
+
```js
|
|
65
|
+
const express = require('express');
|
|
66
|
+
const { ok, notFoundError, errorHandler } = require('karos');
|
|
67
|
+
|
|
68
|
+
const app = express();
|
|
69
|
+
app.use(express.json());
|
|
70
|
+
|
|
71
|
+
// --- Your Routes ---
|
|
72
|
+
|
|
73
|
+
app.get('/users/:id', async (req, res) => {
|
|
74
|
+
const user = await db.findUser(req.params.id);
|
|
75
|
+
|
|
76
|
+
if (!user) {
|
|
77
|
+
// Throws automatically -> Middleware catches it
|
|
78
|
+
notFoundError('User not found');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Returns standardized 200 OK
|
|
82
|
+
ok(res, user);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// --- ONE middleware catches everything ---
|
|
86
|
+
// Must be placed after all routes
|
|
87
|
+
app.use(errorHandler);
|
|
42
88
|
|
|
43
|
-
|
|
44
|
-
|
|
89
|
+
app.listen(3000, () => console.log('Server running on port 3000'));
|
|
90
|
+
```
|
|
45
91
|
|
|
46
|
-
|
|
92
|
+
**Zero try/catch needed.** If your DB crashes, Karos catches it and returns a clean 500 `INTERNAL_ERROR`.
|
|
47
93
|
|
|
48
|
-
|
|
94
|
+
---
|
|
49
95
|
|
|
50
|
-
|
|
96
|
+
## 📚 Core API
|
|
51
97
|
|
|
52
|
-
|
|
53
|
-
--------
|
|
98
|
+
### `ok(res, data, message?, meta?)`
|
|
54
99
|
|
|
55
|
-
|
|
100
|
+
Formats a successful response.
|
|
56
101
|
|
|
57
|
-
|
|
102
|
+
| Param | Type | Required | Description |
|
|
103
|
+
| :--- | :--- | :--- | :--- |
|
|
104
|
+
| `res` | `Response` | **Yes** | Express Response object |
|
|
105
|
+
| `data` | `any` | **Yes** | The payload (object, array, string) |
|
|
106
|
+
| `message` | `string` | No | Optional success message |
|
|
107
|
+
| `meta` | `object` | No | Optional metadata (e.g., pagination info) |
|
|
58
108
|
|
|
59
|
-
**
|
|
109
|
+
**Example:**
|
|
110
|
+
```js
|
|
111
|
+
ok(res, user);
|
|
112
|
+
ok(res, user, 'User fetched successfully');
|
|
113
|
+
```
|
|
60
114
|
|
|
61
|
-
|
|
115
|
+
---
|
|
62
116
|
|
|
63
|
-
|
|
117
|
+
### Error Helpers
|
|
64
118
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* Formats unknown errors as INTERNAL\_ERROR
|
|
68
|
-
|
|
69
|
-
* Preserves correct HTTP status codes
|
|
70
|
-
|
|
119
|
+
Prebuilt helpers that throw standardized errors. These stop execution immediately, so you don't need `return`.
|
|
71
120
|
|
|
72
|
-
|
|
121
|
+
| Helper Function | HTTP Status | Error Code |
|
|
122
|
+
| :--- | :--- | :--- |
|
|
123
|
+
| `notFoundError(msg)` | **404** | `NOT_FOUND` |
|
|
124
|
+
| `validationError(msg)` | **400** | `VALIDATION_FAILED` |
|
|
125
|
+
| `unauthorizedError(msg)` | **401** | `UNAUTHORIZED` |
|
|
126
|
+
| `forbiddenError(msg)` | **403** | `FORBIDDEN` |
|
|
127
|
+
| `conflictError(msg)` | **409** | `CONFLICT` |
|
|
128
|
+
| `internalError(msg)` | **500** | `INTERNAL_ERROR` |
|
|
73
129
|
|
|
74
|
-
|
|
75
|
-
|
|
130
|
+
**Example:**
|
|
131
|
+
```js
|
|
132
|
+
if (emailInvalid) validationError('Invalid email format');
|
|
133
|
+
if (!isAdmin) forbiddenError('Admin access required');
|
|
134
|
+
```
|
|
76
135
|
|
|
77
|
-
|
|
136
|
+
---
|
|
78
137
|
|
|
79
|
-
|
|
138
|
+
### `errorHandler`
|
|
80
139
|
|
|
81
|
-
|
|
82
|
-
|
|
140
|
+
Express middleware that:
|
|
141
|
+
1. Catches all thrown Karos errors.
|
|
142
|
+
2. Catches unexpected crashes (DB down, undefined variables).
|
|
143
|
+
3. Formats unknown errors as `INTERNAL_ERROR` (500).
|
|
83
144
|
|
|
84
|
-
|
|
145
|
+
```js
|
|
146
|
+
// Add this as the very last middleware in your app
|
|
147
|
+
app.use(errorHandler);
|
|
148
|
+
```
|
|
85
149
|
|
|
86
|
-
|
|
150
|
+
---
|
|
87
151
|
|
|
88
|
-
|
|
89
|
-
----------------------------------
|
|
152
|
+
## TypeScript Support
|
|
90
153
|
|
|
91
|
-
|
|
154
|
+
Karos is written in TypeScript and includes full type definitions out of the box.
|
|
92
155
|
|
|
93
|
-
|
|
156
|
+
- ✅ Full type safety
|
|
157
|
+
- ✅ Autocomplete-safe error codes
|
|
94
158
|
|
|
95
|
-
|
|
96
|
-
|
|
159
|
+
```ts
|
|
160
|
+
import { ok, ErrorCode } from 'karos';
|
|
161
|
+
```
|
|
97
162
|
|
|
98
|
-
|
|
163
|
+
---
|
|
99
164
|
|
|
100
|
-
License
|
|
101
|
-
-------
|
|
165
|
+
## License
|
|
102
166
|
|
|
103
|
-
MIT
|
|
167
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { Response, Request, NextFunction } from 'express';
|
|
1
|
+
import { Response as Response$1, Request, NextFunction } from 'express';
|
|
2
2
|
|
|
3
3
|
declare const ErrorCode: {
|
|
4
4
|
readonly VALIDATION_FAILED: "VALIDATION_FAILED";
|
|
5
|
+
readonly BAD_REQUEST: "BAD_REQUEST";
|
|
5
6
|
readonly UNAUTHORIZED: "UNAUTHORIZED";
|
|
6
|
-
readonly NOT_FOUND: "NOT_FOUND";
|
|
7
7
|
readonly FORBIDDEN: "FORBIDDEN";
|
|
8
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
8
9
|
readonly CONFLICT: "CONFLICT";
|
|
9
10
|
readonly INTERNAL_ERROR: "INTERNAL_ERROR";
|
|
11
|
+
readonly SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
|
|
10
12
|
};
|
|
11
13
|
type ErrorCodeType = typeof ErrorCode[keyof typeof ErrorCode];
|
|
12
14
|
interface ApiSuccessResponse<T = unknown> {
|
|
@@ -24,8 +26,8 @@ interface ApiErrorResponse {
|
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
declare function ok<T = unknown>(res: Response, data: T, message?: string, meta?: Record<string, unknown>): void;
|
|
28
|
-
declare function fail(res: Response, code: ErrorCodeType, message: string, status: number, errors?: Record<string, unknown>): void;
|
|
29
|
+
declare function ok<T = unknown>(res: Response$1, data: T, message?: string, meta?: Record<string, unknown>): void;
|
|
30
|
+
declare function fail(res: Response$1, code: ErrorCodeType, message: string, status: number, errors?: Record<string, unknown>): void;
|
|
29
31
|
|
|
30
32
|
declare class KarosError extends Error {
|
|
31
33
|
readonly code: ErrorCodeType;
|
|
@@ -33,12 +35,51 @@ declare class KarosError extends Error {
|
|
|
33
35
|
readonly errors?: Record<string, unknown>;
|
|
34
36
|
readonly isKarosError = true;
|
|
35
37
|
constructor(code: ErrorCodeType, message: string, status: number, errors?: Record<string, unknown>);
|
|
38
|
+
toJSON(): {
|
|
39
|
+
success: boolean;
|
|
40
|
+
error: {
|
|
41
|
+
code: ErrorCodeType;
|
|
42
|
+
message: string;
|
|
43
|
+
details: Record<string, unknown> | undefined;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
36
46
|
}
|
|
37
47
|
declare const notFoundError: (message?: string, errors?: Record<string, unknown>) => never;
|
|
38
48
|
declare const validationError: (message?: string, errors?: Record<string, unknown>) => never;
|
|
39
49
|
declare const unauthorizedError: (message?: string, errors?: Record<string, unknown>) => never;
|
|
50
|
+
declare const forbiddenError: (message?: string, errors?: Record<string, unknown>) => never;
|
|
51
|
+
declare const conflictError: (message?: string, errors?: Record<string, unknown>) => never;
|
|
52
|
+
declare const internalError: (message?: string, errors?: Record<string, unknown>) => never;
|
|
40
53
|
declare const httpError: (code: ErrorCodeType, message: string, status: number, errors?: Record<string, unknown>) => never;
|
|
41
54
|
|
|
42
|
-
declare function errorHandler(err: unknown, req: Request, res: Response, next: NextFunction): void;
|
|
55
|
+
declare function errorHandler(err: unknown, req: Request, res: Response$1, next: NextFunction): void;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Next.js / Web Standard Helper
|
|
59
|
+
* Returns a standardized SUCCESS Response object.
|
|
60
|
+
*/
|
|
61
|
+
declare function nextOk<T = unknown>(data: T, message?: string, status?: number, meta?: Record<string, unknown>): Response;
|
|
62
|
+
/**
|
|
63
|
+
* Next.js / Web Standard Helper
|
|
64
|
+
* Returns a standardized ERROR Response object.
|
|
65
|
+
*/
|
|
66
|
+
declare function nextFail(code: ErrorCodeType, message: string, status: number, errors?: Record<string, unknown>): Response;
|
|
67
|
+
/**
|
|
68
|
+
* Global Error Handler for Next.js App Router.
|
|
69
|
+
* Automatically detects:
|
|
70
|
+
* 1. KarosErrors (thrown manually)
|
|
71
|
+
* 2. Database Errors (Prisma, Mongo)
|
|
72
|
+
* 3. Unknown crashes (returns 500)
|
|
73
|
+
*
|
|
74
|
+
* Usage:
|
|
75
|
+
* try { ... } catch (err) { return handleNextError(err); }
|
|
76
|
+
*/
|
|
77
|
+
declare function handleNextError(err: any): Response;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Examines an error object and determines if it is a known database error.
|
|
81
|
+
* Supports: Prisma, Mongoose, MongoDB driver
|
|
82
|
+
*/
|
|
83
|
+
declare function resolveDbError(err: any): KarosError | null;
|
|
43
84
|
|
|
44
|
-
export { type ApiErrorResponse, type ApiSuccessResponse, ErrorCode, type ErrorCodeType, KarosError, errorHandler, fail, httpError, notFoundError, ok, unauthorizedError, validationError };
|
|
85
|
+
export { type ApiErrorResponse, type ApiSuccessResponse, ErrorCode, type ErrorCodeType, KarosError, conflictError, errorHandler, fail, forbiddenError, handleNextError, httpError, internalError, nextFail, nextOk, notFoundError, ok, resolveDbError, unauthorizedError, validationError };
|
package/dist/index.js
CHANGED
|
@@ -22,11 +22,18 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ErrorCode: () => ErrorCode,
|
|
24
24
|
KarosError: () => KarosError,
|
|
25
|
+
conflictError: () => conflictError,
|
|
25
26
|
errorHandler: () => errorHandler,
|
|
26
27
|
fail: () => fail,
|
|
28
|
+
forbiddenError: () => forbiddenError,
|
|
29
|
+
handleNextError: () => handleNextError,
|
|
27
30
|
httpError: () => httpError,
|
|
31
|
+
internalError: () => internalError,
|
|
32
|
+
nextFail: () => nextFail,
|
|
33
|
+
nextOk: () => nextOk,
|
|
28
34
|
notFoundError: () => notFoundError,
|
|
29
35
|
ok: () => ok,
|
|
36
|
+
resolveDbError: () => resolveDbError,
|
|
30
37
|
unauthorizedError: () => unauthorizedError,
|
|
31
38
|
validationError: () => validationError
|
|
32
39
|
});
|
|
@@ -35,11 +42,21 @@ module.exports = __toCommonJS(index_exports);
|
|
|
35
42
|
// src/types.ts
|
|
36
43
|
var ErrorCode = {
|
|
37
44
|
VALIDATION_FAILED: "VALIDATION_FAILED",
|
|
45
|
+
// 400
|
|
46
|
+
BAD_REQUEST: "BAD_REQUEST",
|
|
47
|
+
// 400 (Generic)
|
|
38
48
|
UNAUTHORIZED: "UNAUTHORIZED",
|
|
39
|
-
|
|
49
|
+
// 401
|
|
40
50
|
FORBIDDEN: "FORBIDDEN",
|
|
51
|
+
// 403
|
|
52
|
+
NOT_FOUND: "NOT_FOUND",
|
|
53
|
+
// 404
|
|
41
54
|
CONFLICT: "CONFLICT",
|
|
42
|
-
|
|
55
|
+
// 409
|
|
56
|
+
INTERNAL_ERROR: "INTERNAL_ERROR",
|
|
57
|
+
// 500
|
|
58
|
+
SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE"
|
|
59
|
+
// 503 (Optional, good for external API failures)
|
|
43
60
|
};
|
|
44
61
|
|
|
45
62
|
// src/responses.ts
|
|
@@ -68,10 +85,24 @@ var KarosError = class _KarosError extends Error {
|
|
|
68
85
|
this.code = code;
|
|
69
86
|
this.status = status;
|
|
70
87
|
this.errors = errors;
|
|
88
|
+
Object.setPrototypeOf(this, _KarosError.prototype);
|
|
71
89
|
if (Error.captureStackTrace) {
|
|
72
90
|
Error.captureStackTrace(this, _KarosError);
|
|
73
91
|
}
|
|
74
92
|
}
|
|
93
|
+
// ✅ New Helper: Converts error to standardized JSON format
|
|
94
|
+
// This will be reused by both Express Middleware and Next.js helpers
|
|
95
|
+
toJSON() {
|
|
96
|
+
return {
|
|
97
|
+
success: false,
|
|
98
|
+
error: {
|
|
99
|
+
code: this.code,
|
|
100
|
+
message: this.message,
|
|
101
|
+
details: this.errors || void 0
|
|
102
|
+
// Only show if exists
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
75
106
|
};
|
|
76
107
|
var notFoundError = (message = "Not found", errors) => {
|
|
77
108
|
throw new KarosError("NOT_FOUND", message, 404, errors);
|
|
@@ -82,10 +113,46 @@ var validationError = (message = "Validation failed", errors) => {
|
|
|
82
113
|
var unauthorizedError = (message = "Unauthorized", errors) => {
|
|
83
114
|
throw new KarosError("UNAUTHORIZED", message, 401, errors);
|
|
84
115
|
};
|
|
116
|
+
var forbiddenError = (message = "Forbidden", errors) => {
|
|
117
|
+
throw new KarosError("FORBIDDEN", message, 403, errors);
|
|
118
|
+
};
|
|
119
|
+
var conflictError = (message = "Conflict", errors) => {
|
|
120
|
+
throw new KarosError("CONFLICT", message, 409, errors);
|
|
121
|
+
};
|
|
122
|
+
var internalError = (message = "Internal Server Error", errors) => {
|
|
123
|
+
throw new KarosError("INTERNAL_ERROR", message, 500, errors);
|
|
124
|
+
};
|
|
85
125
|
var httpError = (code, message, status, errors) => {
|
|
86
126
|
throw new KarosError(code, message, status, errors);
|
|
87
127
|
};
|
|
88
128
|
|
|
129
|
+
// src/db-handler.ts
|
|
130
|
+
function resolveDbError(err) {
|
|
131
|
+
if (!err) return null;
|
|
132
|
+
if (err.code === "P2002") {
|
|
133
|
+
const target = err.meta?.target ? ` (${err.meta.target})` : "";
|
|
134
|
+
return new KarosError(
|
|
135
|
+
ErrorCode.CONFLICT,
|
|
136
|
+
`Duplicate entry: Resource already exists${target}`,
|
|
137
|
+
409
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
if (err.code === "P2025") {
|
|
141
|
+
return new KarosError(ErrorCode.NOT_FOUND, "Record not found", 404);
|
|
142
|
+
}
|
|
143
|
+
if (err.code === 11e3 || err.errorResponse && err.errorResponse.code === 11e3) {
|
|
144
|
+
return new KarosError(ErrorCode.CONFLICT, "Duplicate entry: Resource already exists", 409);
|
|
145
|
+
}
|
|
146
|
+
if (err.name === "ValidationError") {
|
|
147
|
+
const details = {};
|
|
148
|
+
for (const field in err.errors) {
|
|
149
|
+
details[field] = err.errors[field].message;
|
|
150
|
+
}
|
|
151
|
+
return new KarosError(ErrorCode.VALIDATION_FAILED, "Database validation failed", 400, details);
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
89
156
|
// src/middleware.ts
|
|
90
157
|
function isKarosError(err) {
|
|
91
158
|
return typeof err === "object" && err !== null && err.isKarosError === true;
|
|
@@ -94,19 +161,71 @@ function errorHandler(err, req, res, next) {
|
|
|
94
161
|
if (res.headersSent) return next(err);
|
|
95
162
|
if (isKarosError(err)) {
|
|
96
163
|
fail(res, err.code, err.message, err.status, err.errors);
|
|
97
|
-
|
|
98
|
-
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const dbError = resolveDbError(err);
|
|
167
|
+
if (dbError) {
|
|
168
|
+
fail(res, dbError.code, dbError.message, dbError.status, dbError.errors);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
console.error("[Karos] Unexpected Error:", err);
|
|
172
|
+
fail(res, ErrorCode.INTERNAL_ERROR, "Internal server error", 500);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/next.ts
|
|
176
|
+
function nextOk(data, message, status = 200, meta) {
|
|
177
|
+
const body = {
|
|
178
|
+
success: true,
|
|
179
|
+
data,
|
|
180
|
+
...message && { message },
|
|
181
|
+
...meta && { meta }
|
|
182
|
+
};
|
|
183
|
+
return new Response(JSON.stringify(body), {
|
|
184
|
+
status,
|
|
185
|
+
headers: { "Content-Type": "application/json" }
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function nextFail(code, message, status, errors) {
|
|
189
|
+
const body = {
|
|
190
|
+
success: false,
|
|
191
|
+
error: {
|
|
192
|
+
code,
|
|
193
|
+
message,
|
|
194
|
+
...errors && { errors }
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
return new Response(JSON.stringify(body), {
|
|
198
|
+
status,
|
|
199
|
+
headers: { "Content-Type": "application/json" }
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
function handleNextError(err) {
|
|
203
|
+
if (err && err.isKarosError) {
|
|
204
|
+
return nextFail(err.code, err.message, err.status, err.errors);
|
|
205
|
+
}
|
|
206
|
+
const dbErr = resolveDbError(err);
|
|
207
|
+
if (dbErr) {
|
|
208
|
+
return nextFail(dbErr.code, dbErr.message, dbErr.status, dbErr.errors);
|
|
99
209
|
}
|
|
210
|
+
console.error("[Karos Next] Unexpected Error:", err);
|
|
211
|
+
return nextFail(ErrorCode.INTERNAL_ERROR, "Internal Server Error", 500);
|
|
100
212
|
}
|
|
101
213
|
// Annotate the CommonJS export names for ESM import in node:
|
|
102
214
|
0 && (module.exports = {
|
|
103
215
|
ErrorCode,
|
|
104
216
|
KarosError,
|
|
217
|
+
conflictError,
|
|
105
218
|
errorHandler,
|
|
106
219
|
fail,
|
|
220
|
+
forbiddenError,
|
|
221
|
+
handleNextError,
|
|
107
222
|
httpError,
|
|
223
|
+
internalError,
|
|
224
|
+
nextFail,
|
|
225
|
+
nextOk,
|
|
108
226
|
notFoundError,
|
|
109
227
|
ok,
|
|
228
|
+
resolveDbError,
|
|
110
229
|
unauthorizedError,
|
|
111
230
|
validationError
|
|
112
231
|
});
|
package/package.json
CHANGED
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "karos",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Opinionated API response and error handling for Node.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
8
10
|
"scripts": {
|
|
9
11
|
"build": "tsup src/index.ts --format cjs --dts",
|
|
10
12
|
"dev": "tsup src/index.ts --format cjs --watch --dts",
|
|
11
13
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
14
|
},
|
|
13
|
-
"keywords": [
|
|
14
|
-
|
|
15
|
+
"keywords": [
|
|
16
|
+
"api",
|
|
17
|
+
"express",
|
|
18
|
+
"error-handling",
|
|
19
|
+
"node",
|
|
20
|
+
"backend",
|
|
21
|
+
"nextjs",
|
|
22
|
+
"node",
|
|
23
|
+
"error-structure"
|
|
24
|
+
],
|
|
25
|
+
"author": "Krishna Shrivastava",
|
|
15
26
|
"license": "MIT",
|
|
16
|
-
"repository": "https://github.com/Krishna-Shrivastava-1/Karos",
|
|
17
|
-
"bugs": "https://github.com/Krishna-Shrivastava-1/Karos/issues",
|
|
27
|
+
"repository": "https://github.com/Krishna-Shrivastava-1/Karos",
|
|
28
|
+
"bugs": "https://github.com/Krishna-Shrivastava-1/Karos/issues",
|
|
18
29
|
"type": "commonjs",
|
|
19
30
|
"devDependencies": {
|
|
20
31
|
"@types/express": "^5.0.6",
|