@naman_deep_singh/http-response 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.
Files changed (58) hide show
  1. package/README.md +189 -0
  2. package/dist/cjs/adapters/express/ExpressResponder.d.ts +18 -0
  3. package/dist/cjs/adapters/express/ExpressResponder.js +46 -0
  4. package/dist/cjs/constants/httpStatus.d.ts +54 -0
  5. package/dist/cjs/constants/httpStatus.js +34 -0
  6. package/dist/cjs/core/BaseResponder.d.ts +31 -0
  7. package/dist/cjs/core/BaseResponder.js +116 -0
  8. package/dist/cjs/core/config.d.ts +15 -0
  9. package/dist/cjs/core/config.js +15 -0
  10. package/dist/cjs/core/factory.d.ts +3 -0
  11. package/dist/cjs/core/factory.js +10 -0
  12. package/dist/cjs/core/types.d.ts +32 -0
  13. package/dist/cjs/core/types.js +2 -0
  14. package/dist/cjs/index.d.ts +8 -0
  15. package/dist/cjs/index.js +32 -0
  16. package/dist/cjs/legacy.d.ts +19 -0
  17. package/dist/cjs/legacy.js +23 -0
  18. package/dist/cjs/middleware/express/expressMiddleware.d.ts +3 -0
  19. package/dist/cjs/middleware/express/expressMiddleware.js +13 -0
  20. package/dist/esm/adapters/express/ExpressResponder.d.ts +18 -0
  21. package/dist/esm/adapters/express/ExpressResponder.js +42 -0
  22. package/dist/esm/constants/httpStatus.d.ts +54 -0
  23. package/dist/esm/constants/httpStatus.js +31 -0
  24. package/dist/esm/core/BaseResponder.d.ts +31 -0
  25. package/dist/esm/core/BaseResponder.js +112 -0
  26. package/dist/esm/core/config.d.ts +15 -0
  27. package/dist/esm/core/config.js +12 -0
  28. package/dist/esm/core/factory.d.ts +3 -0
  29. package/dist/esm/core/factory.js +6 -0
  30. package/dist/esm/core/types.d.ts +32 -0
  31. package/dist/esm/core/types.js +1 -0
  32. package/dist/esm/index.d.ts +8 -0
  33. package/dist/esm/index.js +10 -0
  34. package/dist/esm/legacy.d.ts +19 -0
  35. package/dist/esm/legacy.js +18 -0
  36. package/dist/esm/middleware/express/expressMiddleware.d.ts +3 -0
  37. package/dist/esm/middleware/express/expressMiddleware.js +9 -0
  38. package/dist/types/adapters/express/ExpressResponder.d.ts +18 -0
  39. package/dist/types/constants/httpStatus.d.ts +54 -0
  40. package/dist/types/core/BaseResponder.d.ts +31 -0
  41. package/dist/types/core/config.d.ts +15 -0
  42. package/dist/types/core/factory.d.ts +3 -0
  43. package/dist/types/core/types.d.ts +32 -0
  44. package/dist/types/index.d.ts +8 -0
  45. package/dist/types/legacy.d.ts +19 -0
  46. package/dist/types/middleware/express/expressMiddleware.d.ts +3 -0
  47. package/package.json +53 -0
  48. package/src/adapters/express/ExpressResponder.ts +64 -0
  49. package/src/constants/httpStatus.ts +42 -0
  50. package/src/core/BaseResponder.ts +198 -0
  51. package/src/core/config.ts +29 -0
  52. package/src/core/factory.ts +11 -0
  53. package/src/core/types.ts +34 -0
  54. package/src/index.ts +13 -0
  55. package/src/middleware/express/expressMiddleware.ts +14 -0
  56. package/tsconfig.base.json +11 -0
  57. package/tsconfig.cjs.json +9 -0
  58. package/tsconfig.esm.json +9 -0
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.responderMiddleware = void 0;
4
+ const factory_1 = require("../../core/factory");
5
+ const responderMiddleware = (cfg) => {
6
+ const factory = (0, factory_1.createResponderFactory)(cfg);
7
+ return (_req, res, next) => {
8
+ ;
9
+ res.responder = () => factory(res);
10
+ next();
11
+ };
12
+ };
13
+ exports.responderMiddleware = responderMiddleware;
@@ -0,0 +1,18 @@
1
+ import type { Response } from 'express';
2
+ import { BaseResponder } from '../../core/BaseResponder';
3
+ import type { ResponderConfig } from '../../core/config';
4
+ export declare class ExpressResponder<P = unknown> extends BaseResponder<P> {
5
+ private readonly res;
6
+ constructor(cfg: Partial<ResponderConfig> | undefined, res: Response);
7
+ okAndSend(data?: P, message?: string): void;
8
+ createdAndSend(data?: P, message?: string): void;
9
+ badRequestAndSend(message?: string, error?: unknown): void;
10
+ unauthorizedAndSend(message?: string): void;
11
+ forbiddenAndSend(message?: string): void;
12
+ notFoundAndSend(message?: string): void;
13
+ conflictAndSend(message?: string): void;
14
+ unprocessableEntityAndSend(message?: string, error?: unknown): void;
15
+ tooManyRequestsAndSend(message?: string): void;
16
+ serverErrorAndSend(message?: string, error?: unknown): void;
17
+ paginateAndSend(data: P[], page: number, limit: number, total: number, message?: string): void;
18
+ }
@@ -0,0 +1,42 @@
1
+ import { BaseResponder } from '../../core/BaseResponder';
2
+ export class ExpressResponder extends BaseResponder {
3
+ constructor(cfg, res) {
4
+ // attach sender which calls res.status().json()
5
+ super(cfg, (status, body) => res.status(status).json(body));
6
+ this.res = res;
7
+ }
8
+ // convenience methods that return void for middleware/controller ergonomics
9
+ okAndSend(data, message) {
10
+ void this.ok(data, message);
11
+ }
12
+ createdAndSend(data, message) {
13
+ void this.created(data, message);
14
+ }
15
+ badRequestAndSend(message, error) {
16
+ void this.badRequest(message, error);
17
+ }
18
+ unauthorizedAndSend(message) {
19
+ void this.unauthorized(message);
20
+ }
21
+ forbiddenAndSend(message) {
22
+ void this.forbidden(message);
23
+ }
24
+ notFoundAndSend(message) {
25
+ void this.notFound(message);
26
+ }
27
+ conflictAndSend(message) {
28
+ void this.conflict(message);
29
+ }
30
+ unprocessableEntityAndSend(message, error) {
31
+ void this.unprocessableEntity(message, error);
32
+ }
33
+ tooManyRequestsAndSend(message) {
34
+ void this.tooManyRequests(message);
35
+ }
36
+ serverErrorAndSend(message, error) {
37
+ void this.serverError(message, error);
38
+ }
39
+ paginateAndSend(data, page, limit, total, message) {
40
+ void this.paginate(data, page, limit, total, message);
41
+ }
42
+ }
@@ -0,0 +1,54 @@
1
+ declare const SUCCESS: Readonly<{
2
+ readonly OK: 200;
3
+ readonly CREATED: 201;
4
+ readonly ACCEPTED: 202;
5
+ readonly NO_CONTENT: 204;
6
+ }>;
7
+ declare const REDIRECTION: Readonly<{
8
+ readonly NOT_MODIFIED: 304;
9
+ }>;
10
+ declare const CLIENT_ERROR: Readonly<{
11
+ readonly BAD_REQUEST: 400;
12
+ readonly UNAUTHORIZED: 401;
13
+ readonly FORBIDDEN: 403;
14
+ readonly NOT_FOUND: 404;
15
+ readonly METHOD_NOT_ALLOWED: 405;
16
+ readonly CONFLICT: 409;
17
+ readonly UNPROCESSABLE_ENTITY: 422;
18
+ readonly TOO_MANY_REQUESTS: 429;
19
+ }>;
20
+ declare const SERVER_ERROR: Readonly<{
21
+ readonly INTERNAL_SERVER_ERROR: 500;
22
+ readonly NOT_IMPLEMENTED: 501;
23
+ readonly BAD_GATEWAY: 502;
24
+ readonly SERVICE_UNAVAILABLE: 503;
25
+ }>;
26
+ export declare const HTTP_STATUS: Readonly<{
27
+ readonly SUCCESS: Readonly<{
28
+ readonly OK: 200;
29
+ readonly CREATED: 201;
30
+ readonly ACCEPTED: 202;
31
+ readonly NO_CONTENT: 204;
32
+ }>;
33
+ readonly REDIRECTION: Readonly<{
34
+ readonly NOT_MODIFIED: 304;
35
+ }>;
36
+ readonly CLIENT_ERROR: Readonly<{
37
+ readonly BAD_REQUEST: 400;
38
+ readonly UNAUTHORIZED: 401;
39
+ readonly FORBIDDEN: 403;
40
+ readonly NOT_FOUND: 404;
41
+ readonly METHOD_NOT_ALLOWED: 405;
42
+ readonly CONFLICT: 409;
43
+ readonly UNPROCESSABLE_ENTITY: 422;
44
+ readonly TOO_MANY_REQUESTS: 429;
45
+ }>;
46
+ readonly SERVER_ERROR: Readonly<{
47
+ readonly INTERNAL_SERVER_ERROR: 500;
48
+ readonly NOT_IMPLEMENTED: 501;
49
+ readonly BAD_GATEWAY: 502;
50
+ readonly SERVICE_UNAVAILABLE: 503;
51
+ }>;
52
+ }>;
53
+ export type HttpStatusCode = (typeof SUCCESS)[keyof typeof SUCCESS] | (typeof REDIRECTION)[keyof typeof REDIRECTION] | (typeof CLIENT_ERROR)[keyof typeof CLIENT_ERROR] | (typeof SERVER_ERROR)[keyof typeof SERVER_ERROR];
54
+ export {};
@@ -0,0 +1,31 @@
1
+ const SUCCESS = Object.freeze({
2
+ OK: 200,
3
+ CREATED: 201,
4
+ ACCEPTED: 202,
5
+ NO_CONTENT: 204,
6
+ });
7
+ const REDIRECTION = Object.freeze({
8
+ NOT_MODIFIED: 304,
9
+ });
10
+ const CLIENT_ERROR = Object.freeze({
11
+ BAD_REQUEST: 400,
12
+ UNAUTHORIZED: 401,
13
+ FORBIDDEN: 403,
14
+ NOT_FOUND: 404,
15
+ METHOD_NOT_ALLOWED: 405,
16
+ CONFLICT: 409,
17
+ UNPROCESSABLE_ENTITY: 422,
18
+ TOO_MANY_REQUESTS: 429,
19
+ });
20
+ const SERVER_ERROR = Object.freeze({
21
+ INTERNAL_SERVER_ERROR: 500,
22
+ NOT_IMPLEMENTED: 501,
23
+ BAD_GATEWAY: 502,
24
+ SERVICE_UNAVAILABLE: 503,
25
+ });
26
+ export const HTTP_STATUS = Object.freeze({
27
+ SUCCESS,
28
+ REDIRECTION,
29
+ CLIENT_ERROR,
30
+ SERVER_ERROR,
31
+ });
@@ -0,0 +1,31 @@
1
+ import { type ResponderConfig } from './config';
2
+ import type { PaginationMeta, ResponseEnvelope, Sender } from './types';
3
+ export declare class BaseResponder<P = unknown, M = PaginationMeta> {
4
+ protected readonly cfg: ResponderConfig;
5
+ protected sender?: Sender;
6
+ constructor(cfg?: Partial<ResponderConfig>, sender?: Sender);
7
+ attachSender(sender: Sender): void;
8
+ protected normalizeError(err: unknown): {
9
+ message: string;
10
+ code?: string;
11
+ details?: unknown;
12
+ };
13
+ protected buildEnvelope(data?: P, message?: string, error?: unknown, meta?: M): ResponseEnvelope<P, M>;
14
+ protected send(status: number, envelope: ResponseEnvelope<P, M>): any;
15
+ /** -----------------------------
16
+ * Standard REST Response Helpers
17
+ * ----------------------------- */
18
+ ok(data?: P, message?: string): any;
19
+ created(data?: P, message?: string): any;
20
+ noContent(message?: string): any;
21
+ badRequest(message?: string, error?: unknown): any;
22
+ unauthorized(message?: string): any;
23
+ forbidden(message?: string): any;
24
+ notFound(message?: string): any;
25
+ conflict(message?: string): any;
26
+ unprocessableEntity(message?: string, error?: unknown): any;
27
+ tooManyRequests(message?: string): any;
28
+ serverError(message?: string, error?: unknown): any;
29
+ paginate(data: P[], page: number, limit: number, total: number, message?: string): any;
30
+ paginateOffset(data: P[], offset: number, limit: number, total: number, message?: string): any;
31
+ }
@@ -0,0 +1,112 @@
1
+ import { HTTP_STATUS } from '../constants/httpStatus';
2
+ import { defaultConfig } from './config';
3
+ export class BaseResponder {
4
+ constructor(cfg, sender) {
5
+ this.cfg = { ...defaultConfig, ...(cfg ?? {}) };
6
+ this.sender = sender;
7
+ }
8
+ attachSender(sender) {
9
+ this.sender = sender;
10
+ }
11
+ normalizeError(err) {
12
+ // errors-utils AppError compatibility
13
+ if (typeof err === 'object' && err !== null) {
14
+ const e = err;
15
+ if (typeof e.message === 'string') {
16
+ return {
17
+ message: e.message,
18
+ code: typeof e.code === 'string' ? e.code : undefined,
19
+ details: e.details,
20
+ };
21
+ }
22
+ }
23
+ if (err instanceof Error) {
24
+ return { message: err.message };
25
+ }
26
+ if (typeof err === 'string') {
27
+ return { message: err };
28
+ }
29
+ return {
30
+ message: 'Internal server error',
31
+ details: err,
32
+ };
33
+ }
34
+ buildEnvelope(data, message, error, meta) {
35
+ const env = {
36
+ success: !error,
37
+ message: message ?? (error ? 'Error' : undefined),
38
+ data: error ? undefined : data,
39
+ error: error ? this.normalizeError(error) : null,
40
+ meta: meta ?? null,
41
+ };
42
+ if (this.cfg.timestamp) {
43
+ env.meta = {
44
+ ...(env.meta ?? {}),
45
+ timestamp: new Date().toISOString(),
46
+ };
47
+ }
48
+ if (this.cfg.extra) {
49
+ Object.assign(env, this.cfg.extra);
50
+ }
51
+ return env;
52
+ }
53
+ send(status, envelope) {
54
+ if (!this.sender)
55
+ return { status, body: envelope };
56
+ return this.sender(status, envelope);
57
+ }
58
+ /** -----------------------------
59
+ * Standard REST Response Helpers
60
+ * ----------------------------- */
61
+ ok(data, message = 'Success') {
62
+ return this.send(HTTP_STATUS.SUCCESS.OK, this.buildEnvelope(data, message));
63
+ }
64
+ created(data, message = 'Created successfully') {
65
+ return this.send(HTTP_STATUS.SUCCESS.CREATED, this.buildEnvelope(data, message));
66
+ }
67
+ noContent(message = 'No Content') {
68
+ return this.send(HTTP_STATUS.SUCCESS.NO_CONTENT, this.buildEnvelope(undefined, message));
69
+ }
70
+ badRequest(message = 'Bad request', error) {
71
+ return this.send(HTTP_STATUS.CLIENT_ERROR.BAD_REQUEST, this.buildEnvelope(undefined, message, error));
72
+ }
73
+ unauthorized(message = 'Unauthorized') {
74
+ return this.send(HTTP_STATUS.CLIENT_ERROR.UNAUTHORIZED, this.buildEnvelope(undefined, message));
75
+ }
76
+ forbidden(message = 'Forbidden') {
77
+ return this.send(HTTP_STATUS.CLIENT_ERROR.FORBIDDEN, this.buildEnvelope(undefined, message));
78
+ }
79
+ notFound(message = 'Not found') {
80
+ return this.send(HTTP_STATUS.CLIENT_ERROR.NOT_FOUND, this.buildEnvelope(undefined, message));
81
+ }
82
+ conflict(message = 'Conflict') {
83
+ return this.send(HTTP_STATUS.CLIENT_ERROR.CONFLICT, this.buildEnvelope(undefined, message));
84
+ }
85
+ unprocessableEntity(message = 'Unprocessable Entity', error) {
86
+ return this.send(HTTP_STATUS.CLIENT_ERROR.UNPROCESSABLE_ENTITY, this.buildEnvelope(undefined, message, error));
87
+ }
88
+ tooManyRequests(message = 'Too Many Requests') {
89
+ return this.send(HTTP_STATUS.CLIENT_ERROR.TOO_MANY_REQUESTS, this.buildEnvelope(undefined, message));
90
+ }
91
+ serverError(message = 'Internal server error', error) {
92
+ return this.send(HTTP_STATUS.SERVER_ERROR.INTERNAL_SERVER_ERROR, this.buildEnvelope(undefined, message, error));
93
+ }
94
+ paginate(data, page, limit, total, message = 'Success') {
95
+ const totalPages = Math.max(1, Math.ceil(total / limit));
96
+ const offset = (page - 1) * limit;
97
+ const pagination = {
98
+ page,
99
+ limit,
100
+ total,
101
+ totalPages,
102
+ offset,
103
+ hasNext: page < totalPages,
104
+ hasPrev: page > 1,
105
+ };
106
+ return this.send(HTTP_STATUS.SUCCESS.OK, this.buildEnvelope(data, message, undefined, pagination));
107
+ }
108
+ paginateOffset(data, offset, limit, total, message = 'Success') {
109
+ const page = Math.floor(offset / limit) + 1;
110
+ return this.paginate(data, page, limit, total, message);
111
+ }
112
+ }
@@ -0,0 +1,15 @@
1
+ import type { PlainObject } from './types';
2
+ export type EnvelopeKeys = {
3
+ success?: string;
4
+ message?: string;
5
+ data?: string;
6
+ error?: string;
7
+ meta?: string;
8
+ };
9
+ export type ResponderConfig = {
10
+ envelopeKeys?: EnvelopeKeys;
11
+ defaultStatus?: number;
12
+ timestamp?: boolean;
13
+ extra?: PlainObject | null;
14
+ };
15
+ export declare const defaultConfig: ResponderConfig;
@@ -0,0 +1,12 @@
1
+ export const defaultConfig = {
2
+ envelopeKeys: {
3
+ success: 'success',
4
+ message: 'message',
5
+ data: 'data',
6
+ error: 'error',
7
+ meta: 'meta',
8
+ },
9
+ defaultStatus: 200,
10
+ timestamp: false,
11
+ extra: null,
12
+ };
@@ -0,0 +1,3 @@
1
+ import { ExpressResponder } from '../adapters/express/ExpressResponder';
2
+ import type { ResponderConfig } from './config';
3
+ export declare const createResponderFactory: (cfg?: Partial<ResponderConfig>) => <P = unknown, _M = Record<string, unknown>>(res: import("express").Response) => ExpressResponder<P>;
@@ -0,0 +1,6 @@
1
+ import { ExpressResponder } from '../adapters/express/ExpressResponder';
2
+ export const createResponderFactory = (cfg) => {
3
+ return (res) => {
4
+ return new ExpressResponder(cfg, res);
5
+ };
6
+ };
@@ -0,0 +1,32 @@
1
+ export type PlainObject = Record<string, unknown>;
2
+ export type ErrorShape = {
3
+ code?: string;
4
+ message: string;
5
+ details?: unknown;
6
+ };
7
+ export type ResponseEnvelope<T = unknown, M = PlainObject> = {
8
+ success: boolean;
9
+ message?: string;
10
+ data?: T;
11
+ error?: ErrorShape | null;
12
+ meta?: M | null;
13
+ };
14
+ export type TransportResult = {
15
+ status: number;
16
+ body: unknown;
17
+ };
18
+ export type Sender = (status: number, body: unknown) => Promise<any> | any;
19
+ export interface PaginationMeta {
20
+ page: number;
21
+ limit: number;
22
+ total: number;
23
+ totalPages: number;
24
+ hasNext?: boolean;
25
+ hasPrev?: boolean;
26
+ offset?: number;
27
+ links?: {
28
+ next?: string;
29
+ prev?: string;
30
+ self: string;
31
+ };
32
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export { BaseResponder } from './core/BaseResponder';
2
+ export { createResponderFactory } from './core/factory';
3
+ export * from './core/types';
4
+ export * from './core/config';
5
+ export { ExpressResponder } from './adapters/express/ExpressResponder';
6
+ export { responderMiddleware } from './middleware/express/expressMiddleware';
7
+ export { HTTP_STATUS } from './constants/httpStatus';
8
+ export type { HttpStatusCode } from './constants/httpStatus';
@@ -0,0 +1,10 @@
1
+ // Core Responders
2
+ export { BaseResponder } from './core/BaseResponder';
3
+ export { createResponderFactory } from './core/factory';
4
+ export * from './core/types';
5
+ export * from './core/config';
6
+ // Adapters (Express)
7
+ export { ExpressResponder } from './adapters/express/ExpressResponder';
8
+ export { responderMiddleware } from './middleware/express/expressMiddleware';
9
+ // HTTP Status Constants
10
+ export { HTTP_STATUS } from './constants/httpStatus';
@@ -0,0 +1,19 @@
1
+ export declare const success: <T>(data: T, message?: string, status?: number, res?: {
2
+ status: (code: number) => any;
3
+ json: (body: unknown) => any;
4
+ }) => any;
5
+ export declare const error: (message: string, status?: number, err?: string, res?: {
6
+ status: (code: number) => any;
7
+ json: (body: unknown) => any;
8
+ }) => any;
9
+ declare const _default: {
10
+ success: <T>(data: T, message?: string, status?: number, res?: {
11
+ status: (code: number) => any;
12
+ json: (body: unknown) => any;
13
+ }) => any;
14
+ error: (message: string, status?: number, err?: string, res?: {
15
+ status: (code: number) => any;
16
+ json: (body: unknown) => any;
17
+ }) => any;
18
+ };
19
+ export default _default;
@@ -0,0 +1,18 @@
1
+ export const success = (data, message = 'Success', status = 200, res) => {
2
+ if (res)
3
+ return res
4
+ .status(status)
5
+ .json({ success: true, message, data, statusCode: status });
6
+ return { success: true, message, data, statusCode: status };
7
+ };
8
+ export const error = (message, status = 500, err, res) => {
9
+ if (res)
10
+ return res
11
+ .status(status)
12
+ .json({ success: false, message, error: err, statusCode: status });
13
+ return { success: false, message, error: err, statusCode: status };
14
+ };
15
+ export default {
16
+ success,
17
+ error,
18
+ };
@@ -0,0 +1,3 @@
1
+ import type { RequestHandler } from 'express';
2
+ import type { ResponderConfig } from '../../core/config';
3
+ export declare const responderMiddleware: (cfg?: Partial<ResponderConfig>) => RequestHandler;
@@ -0,0 +1,9 @@
1
+ import { createResponderFactory } from '../../core/factory';
2
+ export const responderMiddleware = (cfg) => {
3
+ const factory = createResponderFactory(cfg);
4
+ return (_req, res, next) => {
5
+ ;
6
+ res.responder = () => factory(res);
7
+ next();
8
+ };
9
+ };
@@ -0,0 +1,18 @@
1
+ import type { Response } from 'express';
2
+ import { BaseResponder } from '../../core/BaseResponder';
3
+ import type { ResponderConfig } from '../../core/config';
4
+ export declare class ExpressResponder<P = unknown> extends BaseResponder<P> {
5
+ private readonly res;
6
+ constructor(cfg: Partial<ResponderConfig> | undefined, res: Response);
7
+ okAndSend(data?: P, message?: string): void;
8
+ createdAndSend(data?: P, message?: string): void;
9
+ badRequestAndSend(message?: string, error?: unknown): void;
10
+ unauthorizedAndSend(message?: string): void;
11
+ forbiddenAndSend(message?: string): void;
12
+ notFoundAndSend(message?: string): void;
13
+ conflictAndSend(message?: string): void;
14
+ unprocessableEntityAndSend(message?: string, error?: unknown): void;
15
+ tooManyRequestsAndSend(message?: string): void;
16
+ serverErrorAndSend(message?: string, error?: unknown): void;
17
+ paginateAndSend(data: P[], page: number, limit: number, total: number, message?: string): void;
18
+ }
@@ -0,0 +1,54 @@
1
+ declare const SUCCESS: Readonly<{
2
+ readonly OK: 200;
3
+ readonly CREATED: 201;
4
+ readonly ACCEPTED: 202;
5
+ readonly NO_CONTENT: 204;
6
+ }>;
7
+ declare const REDIRECTION: Readonly<{
8
+ readonly NOT_MODIFIED: 304;
9
+ }>;
10
+ declare const CLIENT_ERROR: Readonly<{
11
+ readonly BAD_REQUEST: 400;
12
+ readonly UNAUTHORIZED: 401;
13
+ readonly FORBIDDEN: 403;
14
+ readonly NOT_FOUND: 404;
15
+ readonly METHOD_NOT_ALLOWED: 405;
16
+ readonly CONFLICT: 409;
17
+ readonly UNPROCESSABLE_ENTITY: 422;
18
+ readonly TOO_MANY_REQUESTS: 429;
19
+ }>;
20
+ declare const SERVER_ERROR: Readonly<{
21
+ readonly INTERNAL_SERVER_ERROR: 500;
22
+ readonly NOT_IMPLEMENTED: 501;
23
+ readonly BAD_GATEWAY: 502;
24
+ readonly SERVICE_UNAVAILABLE: 503;
25
+ }>;
26
+ export declare const HTTP_STATUS: Readonly<{
27
+ readonly SUCCESS: Readonly<{
28
+ readonly OK: 200;
29
+ readonly CREATED: 201;
30
+ readonly ACCEPTED: 202;
31
+ readonly NO_CONTENT: 204;
32
+ }>;
33
+ readonly REDIRECTION: Readonly<{
34
+ readonly NOT_MODIFIED: 304;
35
+ }>;
36
+ readonly CLIENT_ERROR: Readonly<{
37
+ readonly BAD_REQUEST: 400;
38
+ readonly UNAUTHORIZED: 401;
39
+ readonly FORBIDDEN: 403;
40
+ readonly NOT_FOUND: 404;
41
+ readonly METHOD_NOT_ALLOWED: 405;
42
+ readonly CONFLICT: 409;
43
+ readonly UNPROCESSABLE_ENTITY: 422;
44
+ readonly TOO_MANY_REQUESTS: 429;
45
+ }>;
46
+ readonly SERVER_ERROR: Readonly<{
47
+ readonly INTERNAL_SERVER_ERROR: 500;
48
+ readonly NOT_IMPLEMENTED: 501;
49
+ readonly BAD_GATEWAY: 502;
50
+ readonly SERVICE_UNAVAILABLE: 503;
51
+ }>;
52
+ }>;
53
+ export type HttpStatusCode = (typeof SUCCESS)[keyof typeof SUCCESS] | (typeof REDIRECTION)[keyof typeof REDIRECTION] | (typeof CLIENT_ERROR)[keyof typeof CLIENT_ERROR] | (typeof SERVER_ERROR)[keyof typeof SERVER_ERROR];
54
+ export {};
@@ -0,0 +1,31 @@
1
+ import { type ResponderConfig } from './config';
2
+ import type { PaginationMeta, ResponseEnvelope, Sender } from './types';
3
+ export declare class BaseResponder<P = unknown, M = PaginationMeta> {
4
+ protected readonly cfg: ResponderConfig;
5
+ protected sender?: Sender;
6
+ constructor(cfg?: Partial<ResponderConfig>, sender?: Sender);
7
+ attachSender(sender: Sender): void;
8
+ protected normalizeError(err: unknown): {
9
+ message: string;
10
+ code?: string;
11
+ details?: unknown;
12
+ };
13
+ protected buildEnvelope(data?: P, message?: string, error?: unknown, meta?: M): ResponseEnvelope<P, M>;
14
+ protected send(status: number, envelope: ResponseEnvelope<P, M>): any;
15
+ /** -----------------------------
16
+ * Standard REST Response Helpers
17
+ * ----------------------------- */
18
+ ok(data?: P, message?: string): any;
19
+ created(data?: P, message?: string): any;
20
+ noContent(message?: string): any;
21
+ badRequest(message?: string, error?: unknown): any;
22
+ unauthorized(message?: string): any;
23
+ forbidden(message?: string): any;
24
+ notFound(message?: string): any;
25
+ conflict(message?: string): any;
26
+ unprocessableEntity(message?: string, error?: unknown): any;
27
+ tooManyRequests(message?: string): any;
28
+ serverError(message?: string, error?: unknown): any;
29
+ paginate(data: P[], page: number, limit: number, total: number, message?: string): any;
30
+ paginateOffset(data: P[], offset: number, limit: number, total: number, message?: string): any;
31
+ }
@@ -0,0 +1,15 @@
1
+ import type { PlainObject } from './types';
2
+ export type EnvelopeKeys = {
3
+ success?: string;
4
+ message?: string;
5
+ data?: string;
6
+ error?: string;
7
+ meta?: string;
8
+ };
9
+ export type ResponderConfig = {
10
+ envelopeKeys?: EnvelopeKeys;
11
+ defaultStatus?: number;
12
+ timestamp?: boolean;
13
+ extra?: PlainObject | null;
14
+ };
15
+ export declare const defaultConfig: ResponderConfig;
@@ -0,0 +1,3 @@
1
+ import { ExpressResponder } from '../adapters/express/ExpressResponder';
2
+ import type { ResponderConfig } from './config';
3
+ export declare const createResponderFactory: (cfg?: Partial<ResponderConfig>) => <P = unknown, _M = Record<string, unknown>>(res: import("express").Response) => ExpressResponder<P>;
@@ -0,0 +1,32 @@
1
+ export type PlainObject = Record<string, unknown>;
2
+ export type ErrorShape = {
3
+ code?: string;
4
+ message: string;
5
+ details?: unknown;
6
+ };
7
+ export type ResponseEnvelope<T = unknown, M = PlainObject> = {
8
+ success: boolean;
9
+ message?: string;
10
+ data?: T;
11
+ error?: ErrorShape | null;
12
+ meta?: M | null;
13
+ };
14
+ export type TransportResult = {
15
+ status: number;
16
+ body: unknown;
17
+ };
18
+ export type Sender = (status: number, body: unknown) => Promise<any> | any;
19
+ export interface PaginationMeta {
20
+ page: number;
21
+ limit: number;
22
+ total: number;
23
+ totalPages: number;
24
+ hasNext?: boolean;
25
+ hasPrev?: boolean;
26
+ offset?: number;
27
+ links?: {
28
+ next?: string;
29
+ prev?: string;
30
+ self: string;
31
+ };
32
+ }
@@ -0,0 +1,8 @@
1
+ export { BaseResponder } from './core/BaseResponder';
2
+ export { createResponderFactory } from './core/factory';
3
+ export * from './core/types';
4
+ export * from './core/config';
5
+ export { ExpressResponder } from './adapters/express/ExpressResponder';
6
+ export { responderMiddleware } from './middleware/express/expressMiddleware';
7
+ export { HTTP_STATUS } from './constants/httpStatus';
8
+ export type { HttpStatusCode } from './constants/httpStatus';
@@ -0,0 +1,19 @@
1
+ export declare const success: <T>(data: T, message?: string, status?: number, res?: {
2
+ status: (code: number) => any;
3
+ json: (body: unknown) => any;
4
+ }) => any;
5
+ export declare const error: (message: string, status?: number, err?: string, res?: {
6
+ status: (code: number) => any;
7
+ json: (body: unknown) => any;
8
+ }) => any;
9
+ declare const _default: {
10
+ success: <T>(data: T, message?: string, status?: number, res?: {
11
+ status: (code: number) => any;
12
+ json: (body: unknown) => any;
13
+ }) => any;
14
+ error: (message: string, status?: number, err?: string, res?: {
15
+ status: (code: number) => any;
16
+ json: (body: unknown) => any;
17
+ }) => any;
18
+ };
19
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import type { RequestHandler } from 'express';
2
+ import type { ResponderConfig } from '../../core/config';
3
+ export declare const responderMiddleware: (cfg?: Partial<ResponderConfig>) => RequestHandler;