@kemets/response 1.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.
package/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # @kemet/response
2
+
3
+ Standardized JSON API response helpers for Node.js backends (Express.js and compatible frameworks).
4
+
5
+ Every response shares the same shape so clients can parse success and error payloads predictably.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @kemet/response
11
+ ```
12
+
13
+ ## Response formats
14
+
15
+ ### Success
16
+
17
+ ```json
18
+ {
19
+ "success": true,
20
+ "status": 200,
21
+ "message": "OK",
22
+ "data": {}
23
+ }
24
+ ```
25
+
26
+ ### Error
27
+
28
+ ```json
29
+ {
30
+ "success": false,
31
+ "status": 404,
32
+ "message": "Resource not found",
33
+ "error": {}
34
+ }
35
+ ```
36
+
37
+ ## Quick start (Express)
38
+
39
+ ```javascript
40
+ const express = require('express');
41
+ const {
42
+ OK,
43
+ CREATED,
44
+ NOT_FOUND,
45
+ BAD_REQUEST,
46
+ VALIDATION_ERROR,
47
+ INTERNAL_SERVER_ERROR,
48
+ } = require('@kemet/response');
49
+
50
+ const app = express();
51
+ app.use(express.json());
52
+
53
+ app.get('/users/:id', (req, res) => {
54
+ const user = findUser(req.params.id);
55
+
56
+ if (!user) {
57
+ return NOT_FOUND(res, 'User not found');
58
+ }
59
+
60
+ return OK(res, user, 'User retrieved');
61
+ });
62
+
63
+ app.post('/users', (req, res) => {
64
+ const { error, value } = validateUser(req.body);
65
+
66
+ if (error) {
67
+ return VALIDATION_ERROR(res, error.details);
68
+ }
69
+
70
+ const user = createUser(value);
71
+ return CREATED(res, user, 'User created');
72
+ });
73
+
74
+ app.use((err, req, res, next) => {
75
+ INTERNAL_SERVER_ERROR(res, { message: err.message });
76
+ });
77
+
78
+ app.listen(3000);
79
+ ```
80
+
81
+ ## API reference
82
+
83
+ ### Success helpers
84
+
85
+ | Function | Status | Description |
86
+ |----------|--------|-------------|
87
+ | `OK(res, data?, message?)` | 200 | Standard success response |
88
+ | `CREATED(res, data?, message?)` | 201 | Resource created |
89
+
90
+ ### Error helpers
91
+
92
+ | Function | Status | Description |
93
+ |----------|--------|-------------|
94
+ | `BAD_REQUEST(res, message?, errors?)` | 400 | Invalid client request |
95
+ | `UNAUTHORIZED(res, message?)` | 401 | Authentication required |
96
+ | `FORBIDDEN(res, message?)` | 403 | Access denied |
97
+ | `NOT_FOUND(res, message?)` | 404 | Resource not found |
98
+ | `VALIDATION_ERROR(res, errors?)` | 422 | Validation failed |
99
+ | `TOO_MANY_REQUESTS(res, message?)` | 429 | Rate limit exceeded |
100
+ | `INTERNAL_SERVER_ERROR(res, error?)` | 500 | Server error |
101
+
102
+ Omitted `message` arguments use built-in defaults (for example, `"Resource not found"` for 404).
103
+
104
+ ### Builders (framework-agnostic)
105
+
106
+ Use these when you are not using Express, or when you need the payload object without sending it:
107
+
108
+ ```javascript
109
+ const { buildSuccessResponse, buildErrorResponse } = require('@kemet/response');
110
+
111
+ const body = buildSuccessResponse(200, 'OK', { id: 1 });
112
+ // { success: true, status: 200, message: 'OK', data: { id: 1 } }
113
+
114
+ const errBody = buildErrorResponse(400, 'Invalid input', { field: 'email' });
115
+ // { success: false, status: 400, message: 'Invalid input', error: { field: 'email' } }
116
+ ```
117
+
118
+ ### Constants
119
+
120
+ ```javascript
121
+ const { STATUS_CODES, DEFAULT_MESSAGES } = require('@kemet/response');
122
+
123
+ console.log(STATUS_CODES.NOT_FOUND); // 404
124
+ console.log(DEFAULT_MESSAGES[404]); // 'Resource not found'
125
+ ```
126
+
127
+ ## Project structure
128
+
129
+ ```
130
+ .
131
+ ├── index.js # Public entry point
132
+ ├── package.json
133
+ ├── README.md
134
+ └── response/
135
+ ├── constants/ # Status codes and default messages
136
+ ├── utilities/ # Builders and senders
137
+ ├── success/ # 2xx helpers
138
+ └── error/ # 4xx / 5xx helpers
139
+ ```
140
+
141
+ ## Publishing to npm
142
+
143
+ 1. Log in: `npm login`
144
+ 2. For scoped packages, publish with public access:
145
+
146
+ ```bash
147
+ npm publish --access public
148
+ ```
149
+
150
+ ## License
151
+
152
+ MIT
package/index.js ADDED
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ const { STATUS_CODES, DEFAULT_MESSAGES } = require('./response/constants');
4
+ const {
5
+ buildSuccessResponse,
6
+ buildErrorResponse,
7
+ sendSuccess,
8
+ sendError,
9
+ } = require('./response/utilities');
10
+ const { OK, CREATED } = require('./response/success');
11
+ const {
12
+ BAD_REQUEST,
13
+ UNAUTHORIZED,
14
+ FORBIDDEN,
15
+ NOT_FOUND,
16
+ VALIDATION_ERROR,
17
+ TOO_MANY_REQUESTS,
18
+ INTERNAL_SERVER_ERROR,
19
+ } = require('./response/error');
20
+
21
+ module.exports = {
22
+ // Success helpers
23
+ OK,
24
+ CREATED,
25
+
26
+ // Error helpers
27
+ BAD_REQUEST,
28
+ UNAUTHORIZED,
29
+ FORBIDDEN,
30
+ NOT_FOUND,
31
+ VALIDATION_ERROR,
32
+ TOO_MANY_REQUESTS,
33
+ INTERNAL_SERVER_ERROR,
34
+
35
+ // Response builders (use without Express)
36
+ buildSuccessResponse,
37
+ buildErrorResponse,
38
+
39
+ // Low-level senders
40
+ sendSuccess,
41
+ sendError,
42
+
43
+ // Constants
44
+ STATUS_CODES,
45
+ DEFAULT_MESSAGES,
46
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@kemets/response",
3
+ "version": "1.0.0",
4
+ "description": "Standardized API response helpers for Express.js and Node.js backends",
5
+ "main": "index.js",
6
+ "files": [
7
+ "index.js",
8
+ "response"
9
+ ],
10
+ "scripts": {
11
+ "test": "node --test"
12
+ },
13
+ "keywords": [
14
+ "express",
15
+ "api",
16
+ "response",
17
+ "http",
18
+ "rest",
19
+ "json"
20
+ ],
21
+ "author": "",
22
+ "license": "MIT",
23
+ "engines": {
24
+ "node": ">=14.0.0"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": ""
29
+ }
30
+ }
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ const STATUS_CODES = require('./statusCodes');
4
+ const DEFAULT_MESSAGES = require('./messages');
5
+
6
+ module.exports = {
7
+ STATUS_CODES,
8
+ DEFAULT_MESSAGES,
9
+ };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ const STATUS_CODES = require('./statusCodes');
4
+
5
+ const DEFAULT_MESSAGES = Object.freeze({
6
+ [STATUS_CODES.OK]: 'OK',
7
+ [STATUS_CODES.CREATED]: 'Created',
8
+ [STATUS_CODES.BAD_REQUEST]: 'Bad request',
9
+ [STATUS_CODES.UNAUTHORIZED]: 'Unauthorized',
10
+ [STATUS_CODES.FORBIDDEN]: 'Forbidden',
11
+ [STATUS_CODES.NOT_FOUND]: 'Resource not found',
12
+ [STATUS_CODES.VALIDATION_ERROR]: 'Validation failed',
13
+ [STATUS_CODES.TOO_MANY_REQUESTS]: 'Too many requests',
14
+ [STATUS_CODES.INTERNAL_SERVER_ERROR]: 'Internal server error',
15
+ });
16
+
17
+ module.exports = DEFAULT_MESSAGES;
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ const STATUS_CODES = Object.freeze({
4
+ OK: 200,
5
+ CREATED: 201,
6
+ BAD_REQUEST: 400,
7
+ UNAUTHORIZED: 401,
8
+ FORBIDDEN: 403,
9
+ NOT_FOUND: 404,
10
+ VALIDATION_ERROR: 422,
11
+ TOO_MANY_REQUESTS: 429,
12
+ INTERNAL_SERVER_ERROR: 500,
13
+ });
14
+
15
+ module.exports = STATUS_CODES;
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ const { STATUS_CODES } = require('../constants');
4
+ const { sendError } = require('../utilities');
5
+
6
+ /**
7
+ * 400 Bad Request — client sent an invalid request.
8
+ *
9
+ * @param {import('express').Response} res
10
+ * @param {string} [message]
11
+ * @param {*} [errors]
12
+ */
13
+ function BAD_REQUEST(res, message, errors) {
14
+ return sendError(res, STATUS_CODES.BAD_REQUEST, message, errors);
15
+ }
16
+
17
+ /**
18
+ * 401 Unauthorized — authentication is required or failed.
19
+ *
20
+ * @param {import('express').Response} res
21
+ * @param {string} [message]
22
+ */
23
+ function UNAUTHORIZED(res, message) {
24
+ return sendError(res, STATUS_CODES.UNAUTHORIZED, message);
25
+ }
26
+
27
+ /**
28
+ * 403 Forbidden — authenticated but not permitted.
29
+ *
30
+ * @param {import('express').Response} res
31
+ * @param {string} [message]
32
+ */
33
+ function FORBIDDEN(res, message) {
34
+ return sendError(res, STATUS_CODES.FORBIDDEN, message);
35
+ }
36
+
37
+ /**
38
+ * 404 Not Found — requested resource does not exist.
39
+ *
40
+ * @param {import('express').Response} res
41
+ * @param {string} [message]
42
+ */
43
+ function NOT_FOUND(res, message) {
44
+ return sendError(res, STATUS_CODES.NOT_FOUND, message);
45
+ }
46
+
47
+ /**
48
+ * 422 Validation Error — request body or params failed validation.
49
+ *
50
+ * @param {import('express').Response} res
51
+ * @param {*} [errors]
52
+ */
53
+ function VALIDATION_ERROR(res, errors) {
54
+ return sendError(res, STATUS_CODES.VALIDATION_ERROR, undefined, errors);
55
+ }
56
+
57
+ /**
58
+ * 429 Too Many Requests — rate limit exceeded.
59
+ *
60
+ * @param {import('express').Response} res
61
+ * @param {string} [message]
62
+ */
63
+ function TOO_MANY_REQUESTS(res, message) {
64
+ return sendError(res, STATUS_CODES.TOO_MANY_REQUESTS, message);
65
+ }
66
+
67
+ /**
68
+ * 500 Internal Server Error — unexpected server failure.
69
+ *
70
+ * @param {import('express').Response} res
71
+ * @param {*} [error]
72
+ */
73
+ function INTERNAL_SERVER_ERROR(res, error) {
74
+ return sendError(res, STATUS_CODES.INTERNAL_SERVER_ERROR, undefined, error);
75
+ }
76
+
77
+ module.exports = {
78
+ BAD_REQUEST,
79
+ UNAUTHORIZED,
80
+ FORBIDDEN,
81
+ NOT_FOUND,
82
+ VALIDATION_ERROR,
83
+ TOO_MANY_REQUESTS,
84
+ INTERNAL_SERVER_ERROR,
85
+ };
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ const { STATUS_CODES } = require('../constants');
4
+ const { sendSuccess } = require('../utilities');
5
+
6
+ /**
7
+ * 200 OK — successful request with optional data payload.
8
+ *
9
+ * @param {import('express').Response} res
10
+ * @param {*} [data]
11
+ * @param {string} [message]
12
+ */
13
+ function OK(res, data, message) {
14
+ return sendSuccess(res, STATUS_CODES.OK, data, message);
15
+ }
16
+
17
+ /**
18
+ * 201 Created — resource successfully created.
19
+ *
20
+ * @param {import('express').Response} res
21
+ * @param {*} [data]
22
+ * @param {string} [message]
23
+ */
24
+ function CREATED(res, data, message) {
25
+ return sendSuccess(res, STATUS_CODES.CREATED, data, message);
26
+ }
27
+
28
+ module.exports = {
29
+ OK,
30
+ CREATED,
31
+ };
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const { DEFAULT_MESSAGES } = require('../constants');
4
+
5
+ /**
6
+ * Builds a standardized success response payload.
7
+ *
8
+ * @param {number} status - HTTP status code
9
+ * @param {string} [message] - Human-readable message
10
+ * @param {*} [data] - Response payload
11
+ * @returns {object}
12
+ */
13
+ function buildSuccessResponse(status, message, data) {
14
+ return {
15
+ success: true,
16
+ status,
17
+ message: message ?? DEFAULT_MESSAGES[status] ?? 'OK',
18
+ data: data !== undefined && data !== null ? data : {},
19
+ };
20
+ }
21
+
22
+ /**
23
+ * Builds a standardized error response payload.
24
+ *
25
+ * @param {number} status - HTTP status code
26
+ * @param {string} [message] - Human-readable message
27
+ * @param {*} [error] - Error details (validation errors, stack info, etc.)
28
+ * @returns {object}
29
+ */
30
+ function buildErrorResponse(status, message, error) {
31
+ return {
32
+ success: false,
33
+ status,
34
+ message: message ?? DEFAULT_MESSAGES[status] ?? 'Error',
35
+ error: error !== undefined && error !== null ? error : {},
36
+ };
37
+ }
38
+
39
+ module.exports = {
40
+ buildSuccessResponse,
41
+ buildErrorResponse,
42
+ };
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ const { buildSuccessResponse, buildErrorResponse } = require('./builder');
4
+ const { sendSuccess, sendError } = require('./sender');
5
+
6
+ module.exports = {
7
+ buildSuccessResponse,
8
+ buildErrorResponse,
9
+ sendSuccess,
10
+ sendError,
11
+ };
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ const { buildSuccessResponse, buildErrorResponse } = require('./builder');
4
+
5
+ /**
6
+ * Sends a standardized success JSON response.
7
+ *
8
+ * @param {import('express').Response} res - Express response object
9
+ * @param {number} status - HTTP status code
10
+ * @param {*} [data] - Response payload
11
+ * @param {string} [message] - Human-readable message
12
+ * @returns {import('express').Response}
13
+ */
14
+ function sendSuccess(res, status, data, message) {
15
+ const payload = buildSuccessResponse(status, message, data);
16
+ return res.status(status).json(payload);
17
+ }
18
+
19
+ /**
20
+ * Sends a standardized error JSON response.
21
+ *
22
+ * @param {import('express').Response} res - Express response object
23
+ * @param {number} status - HTTP status code
24
+ * @param {string} [message] - Human-readable message
25
+ * @param {*} [error] - Error details
26
+ * @returns {import('express').Response}
27
+ */
28
+ function sendError(res, status, message, error) {
29
+ const payload = buildErrorResponse(status, message, error);
30
+ return res.status(status).json(payload);
31
+ }
32
+
33
+ module.exports = {
34
+ sendSuccess,
35
+ sendError,
36
+ };