@xrystal/dto 26.6.27-v12
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 +724 -0
- package/dist/adapters/elysia.cjs +820 -0
- package/dist/adapters/elysia.d.ts +138 -0
- package/dist/adapters/elysia.js +816 -0
- package/dist/adapters/express.cjs +789 -0
- package/dist/adapters/express.d.ts +49 -0
- package/dist/adapters/express.js +785 -0
- package/dist/adapters/index.d.ts +7 -0
- package/dist/adapters/node.cjs +790 -0
- package/dist/adapters/node.d.ts +27 -0
- package/dist/adapters/node.js +786 -0
- package/dist/adapters/shared.d.ts +11 -0
- package/dist/adapters/socketio.cjs +767 -0
- package/dist/adapters/socketio.d.ts +31 -0
- package/dist/adapters/socketio.js +763 -0
- package/dist/adapters/websocket.cjs +759 -0
- package/dist/adapters/websocket.d.ts +31 -0
- package/dist/adapters/websocket.js +754 -0
- package/dist/core/assemble-log.d.ts +1 -0
- package/dist/core/assemble-queue.d.ts +1 -0
- package/dist/core/assemble.d.ts +9 -0
- package/dist/core/builder.d.ts +49 -0
- package/dist/core/config.d.ts +10 -0
- package/dist/core/context.d.ts +5 -0
- package/dist/core/hooks.d.ts +8 -0
- package/dist/core/index.cjs +1002 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.js +986 -0
- package/dist/core/log-dto.d.ts +1 -0
- package/dist/core/metadata.d.ts +6 -0
- package/dist/core/plugins.d.ts +10 -0
- package/dist/core/presets.d.ts +32 -0
- package/dist/core/queue-dto.d.ts +1 -0
- package/dist/core/response-dto.d.ts +1 -0
- package/dist/core/schema-utils.d.ts +1 -0
- package/dist/dto/index.cjs +909 -0
- package/dist/dto/index.d.ts +6 -0
- package/dist/dto/index.js +898 -0
- package/dist/dto/log/assemble.d.ts +3 -0
- package/dist/dto/log/builder.d.ts +41 -0
- package/dist/dto/log/index.cjs +152 -0
- package/dist/dto/log/index.d.ts +3 -0
- package/dist/dto/log/index.js +149 -0
- package/dist/dto/log/types.d.ts +26 -0
- package/dist/dto/queue/assemble.d.ts +2 -0
- package/dist/dto/queue/builder.d.ts +35 -0
- package/dist/dto/queue/index.cjs +154 -0
- package/dist/dto/queue/index.d.ts +3 -0
- package/dist/dto/queue/index.js +151 -0
- package/dist/dto/queue/types.d.ts +34 -0
- package/dist/dto/response/assemble.d.ts +1 -0
- package/dist/dto/response/dto.d.ts +39 -0
- package/dist/dto/response/index.cjs +179 -0
- package/dist/dto/response/index.d.ts +2 -0
- package/dist/dto/response/index.js +176 -0
- package/dist/dto/runtime/dto.cjs +1318 -0
- package/dist/dto/runtime/dto.d.ts +64 -0
- package/dist/dto/runtime/dto.js +1315 -0
- package/dist/dto/shared/base-dto.d.ts +12 -0
- package/dist/dto/shared/schema-utils.d.ts +1 -0
- package/dist/enums/node-env.d.ts +5 -0
- package/dist/errors/codes.d.ts +15 -0
- package/dist/errors/error.d.ts +32 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/index.cjs +1482 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +1433 -0
- package/dist/types/builder.d.ts +15 -0
- package/dist/types/codes.d.ts +7 -0
- package/dist/types/context.d.ts +16 -0
- package/dist/types/hooks.d.ts +7 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/log.d.ts +1 -0
- package/dist/types/metadata.d.ts +7 -0
- package/dist/types/options.d.ts +24 -0
- package/dist/types/plugin.d.ts +35 -0
- package/dist/types/queue.d.ts +1 -0
- package/dist/types/response.d.ts +43 -0
- package/dist/utils/constants/http.d.ts +2 -0
- package/dist/utils/constants/index.d.ts +3 -0
- package/dist/utils/constants/security-headers.d.ts +1 -0
- package/dist/utils/constants/status-codes.d.ts +35 -0
- package/dist/utils/helpers/index.d.ts +2 -0
- package/dist/utils/helpers/request-id.d.ts +3 -0
- package/dist/utils/helpers/uuid.d.ts +2 -0
- package/dist/utils/index.d.ts +2 -0
- package/package.json +130 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// src/dto/queue/assemble.ts
|
|
2
|
+
function assembleQueueMessage(metadata, payload) {
|
|
3
|
+
const orderedMetadata = {
|
|
4
|
+
source: metadata.source,
|
|
5
|
+
eventType: metadata.eventType,
|
|
6
|
+
timestamp: metadata.timestamp,
|
|
7
|
+
correlationId: metadata.correlationId
|
|
8
|
+
};
|
|
9
|
+
if (metadata.userId !== void 0) {
|
|
10
|
+
orderedMetadata.userId = metadata.userId;
|
|
11
|
+
}
|
|
12
|
+
if (metadata.extraData !== void 0) {
|
|
13
|
+
orderedMetadata.extraData = metadata.extraData;
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
metadata: orderedMetadata,
|
|
17
|
+
payload
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/utils/helpers/uuid.ts
|
|
22
|
+
function generateUUID() {
|
|
23
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
24
|
+
return crypto.randomUUID();
|
|
25
|
+
}
|
|
26
|
+
const bytes = new Uint8Array(16);
|
|
27
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
28
|
+
crypto.getRandomValues(bytes);
|
|
29
|
+
} else {
|
|
30
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
31
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
35
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
36
|
+
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
37
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/dto/shared/schema-utils.ts
|
|
41
|
+
function assertRequiredFields(input, fields, label = "Missing required fields") {
|
|
42
|
+
const missing = fields.filter((field) => {
|
|
43
|
+
const value = input[field];
|
|
44
|
+
return value === void 0 || value === null || value === "";
|
|
45
|
+
});
|
|
46
|
+
if (missing.length > 0) {
|
|
47
|
+
throw new Error(`${label}: ${missing.join(", ")}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/dto/shared/base-dto.ts
|
|
52
|
+
var BaseDTO = class {
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// src/dto/queue/builder.ts
|
|
56
|
+
var QueueDTO = class _QueueDTO extends BaseDTO {
|
|
57
|
+
_source;
|
|
58
|
+
_eventType;
|
|
59
|
+
_userId;
|
|
60
|
+
_correlationId;
|
|
61
|
+
_extraData;
|
|
62
|
+
_payload;
|
|
63
|
+
_timestamp;
|
|
64
|
+
static source(value) {
|
|
65
|
+
return new _QueueDTO().source(value);
|
|
66
|
+
}
|
|
67
|
+
static eventType(value) {
|
|
68
|
+
return new _QueueDTO().eventType(value);
|
|
69
|
+
}
|
|
70
|
+
static userId(value) {
|
|
71
|
+
return new _QueueDTO().userId(value);
|
|
72
|
+
}
|
|
73
|
+
static correlationId(value) {
|
|
74
|
+
return new _QueueDTO().correlationId(value);
|
|
75
|
+
}
|
|
76
|
+
static extraData(value) {
|
|
77
|
+
return new _QueueDTO().extraData(value);
|
|
78
|
+
}
|
|
79
|
+
static timestamp(value) {
|
|
80
|
+
return new _QueueDTO().timestamp(value);
|
|
81
|
+
}
|
|
82
|
+
static payload(value) {
|
|
83
|
+
return new _QueueDTO().payload(value);
|
|
84
|
+
}
|
|
85
|
+
static schema(input = {}) {
|
|
86
|
+
return new _QueueDTO().schema(input);
|
|
87
|
+
}
|
|
88
|
+
source(value) {
|
|
89
|
+
this._source = value;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
eventType(value) {
|
|
93
|
+
this._eventType = value;
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
userId(value) {
|
|
97
|
+
this._userId = value;
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
correlationId(value) {
|
|
101
|
+
this._correlationId = value;
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
extraData(value) {
|
|
105
|
+
this._extraData = value;
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
timestamp(value) {
|
|
109
|
+
this._timestamp = value;
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
payload(value) {
|
|
113
|
+
this._payload = value;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
schema(input = {}) {
|
|
117
|
+
const { metadata, payload } = input;
|
|
118
|
+
if (metadata?.source !== void 0) this.source(metadata.source);
|
|
119
|
+
if (metadata?.eventType !== void 0) this.eventType(metadata.eventType);
|
|
120
|
+
if (metadata?.userId !== void 0) this.userId(metadata.userId);
|
|
121
|
+
if (metadata?.correlationId !== void 0) this.correlationId(metadata.correlationId);
|
|
122
|
+
if (metadata?.extraData !== void 0) this.extraData(metadata.extraData);
|
|
123
|
+
if (payload !== void 0) {
|
|
124
|
+
this._payload = payload;
|
|
125
|
+
}
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
build() {
|
|
129
|
+
assertRequiredFields(
|
|
130
|
+
{
|
|
131
|
+
source: this._source,
|
|
132
|
+
eventType: this._eventType
|
|
133
|
+
},
|
|
134
|
+
["source", "eventType"],
|
|
135
|
+
"Missing queue metadata fields"
|
|
136
|
+
);
|
|
137
|
+
return assembleQueueMessage(
|
|
138
|
+
{
|
|
139
|
+
source: this._source,
|
|
140
|
+
eventType: this._eventType,
|
|
141
|
+
timestamp: this._timestamp ?? Date.now(),
|
|
142
|
+
correlationId: this._correlationId ?? generateUUID(),
|
|
143
|
+
userId: this._userId,
|
|
144
|
+
extraData: this._extraData
|
|
145
|
+
},
|
|
146
|
+
this._payload
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export { QueueDTO, assembleQueueMessage };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface QueueMetadata<E = unknown> {
|
|
2
|
+
source: string;
|
|
3
|
+
eventType: string;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
correlationId: string;
|
|
6
|
+
userId?: string;
|
|
7
|
+
extraData?: E;
|
|
8
|
+
}
|
|
9
|
+
export interface QueueMessageInput<P = unknown, E = unknown> {
|
|
10
|
+
metadata: {
|
|
11
|
+
source: string;
|
|
12
|
+
eventType: string;
|
|
13
|
+
userId?: string;
|
|
14
|
+
correlationId?: string;
|
|
15
|
+
extraData?: E;
|
|
16
|
+
};
|
|
17
|
+
payload: P;
|
|
18
|
+
}
|
|
19
|
+
export type QueueSchemaInput<P = unknown, E = unknown> = {
|
|
20
|
+
metadata?: {
|
|
21
|
+
source?: string;
|
|
22
|
+
eventType?: string;
|
|
23
|
+
userId?: string;
|
|
24
|
+
correlationId?: string;
|
|
25
|
+
extraData?: E;
|
|
26
|
+
};
|
|
27
|
+
payload?: P;
|
|
28
|
+
};
|
|
29
|
+
export type IMetadata<E = unknown> = QueueMetadata<E>;
|
|
30
|
+
export type IMessageInput<P = unknown, E = unknown> = QueueMessageInput<P, E>;
|
|
31
|
+
export interface QueueMessage<P = unknown, E = unknown> {
|
|
32
|
+
metadata: QueueMetadata<E>;
|
|
33
|
+
payload: P;
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { assembleResponseBody, type AssembleInput } from '../../core/assemble.js';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CodeMap } from '../../types/codes.js';
|
|
2
|
+
import type { Payload, ResponseBody, SchemaInput } from '../../types/response.js';
|
|
3
|
+
import { BaseDTO } from '../shared/base-dto.js';
|
|
4
|
+
export interface ResponseBuildOptions {
|
|
5
|
+
codes?: CodeMap;
|
|
6
|
+
withDefaultBody?: boolean;
|
|
7
|
+
/** Used to infer `code` when it was not set on the chain (Builder passes HTTP status). */
|
|
8
|
+
httpStatusCode?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Response body DTO — JSON only (`status → message → payload? → code`).
|
|
12
|
+
* Transport (HTTP status, headers, cookies) lives on {@link Builder}.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ResponseDTO<T = unknown> extends BaseDTO<ResponseBody<T>, SchemaInput<T>> {
|
|
15
|
+
private _status?;
|
|
16
|
+
private _message?;
|
|
17
|
+
private _code?;
|
|
18
|
+
private _payload;
|
|
19
|
+
static status(value: boolean): ResponseDTO;
|
|
20
|
+
static message(value: string): ResponseDTO;
|
|
21
|
+
static code(value: number): ResponseDTO;
|
|
22
|
+
static data(data: unknown): ResponseDTO;
|
|
23
|
+
static payload(partial: Payload<unknown>): ResponseDTO;
|
|
24
|
+
static schema(input?: SchemaInput, codes?: CodeMap): ResponseDTO;
|
|
25
|
+
status(value: boolean): this;
|
|
26
|
+
message(msg: string): this;
|
|
27
|
+
code(code: number): this;
|
|
28
|
+
data(data: T | undefined): this;
|
|
29
|
+
payload(partial: Payload<T>): this;
|
|
30
|
+
setMeta(meta: Record<string, unknown>): this;
|
|
31
|
+
paginate(total: number, page: number, limit: number): this;
|
|
32
|
+
schema(input?: SchemaInput<T>, codes?: CodeMap): this;
|
|
33
|
+
getCode(): number | undefined;
|
|
34
|
+
getMessage(): string | undefined;
|
|
35
|
+
setCodeFromHttpStatus(httpStatusCode: number, codes: CodeMap): this;
|
|
36
|
+
transformData<U>(fn: (data: T) => U): ResponseDTO<U>;
|
|
37
|
+
build(options?: ResponseBuildOptions): ResponseBody<T>;
|
|
38
|
+
private buildPayload;
|
|
39
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/core/assemble.ts
|
|
4
|
+
function assembleResponseBody(input) {
|
|
5
|
+
const ordered = {
|
|
6
|
+
status: input.status,
|
|
7
|
+
message: input.message
|
|
8
|
+
};
|
|
9
|
+
if (input.payload !== void 0 && Object.keys(input.payload).length > 0) {
|
|
10
|
+
ordered.payload = input.payload;
|
|
11
|
+
}
|
|
12
|
+
ordered.code = input.code;
|
|
13
|
+
return ordered;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/errors/codes.ts
|
|
17
|
+
var DefaultCodes = {
|
|
18
|
+
SUCCESS: 0,
|
|
19
|
+
CLIENT: 1,
|
|
20
|
+
SERVER: 2,
|
|
21
|
+
VALIDATION: 3
|
|
22
|
+
};
|
|
23
|
+
function isSuccessCode(code, codes) {
|
|
24
|
+
return code === codes.SUCCESS;
|
|
25
|
+
}
|
|
26
|
+
function resolveCodeFromHttpStatus(statusCode, codes) {
|
|
27
|
+
if (statusCode >= 200 && statusCode < 300) return codes.SUCCESS;
|
|
28
|
+
if (statusCode === 422) return codes.VALIDATION;
|
|
29
|
+
if (statusCode >= 400 && statusCode < 500) return codes.CLIENT;
|
|
30
|
+
if (statusCode >= 500) return codes.SERVER;
|
|
31
|
+
if (statusCode >= 300 && statusCode < 400) return codes.SUCCESS;
|
|
32
|
+
return codes.CLIENT;
|
|
33
|
+
}
|
|
34
|
+
function defaultMessageForCode(code, codes) {
|
|
35
|
+
if (code === codes.SUCCESS) return "Operation successful";
|
|
36
|
+
if (code === codes.CLIENT) return "Client error";
|
|
37
|
+
if (code === codes.SERVER) return "Internal server error";
|
|
38
|
+
if (code === codes.VALIDATION) return "Validation failed";
|
|
39
|
+
return "Operation failed";
|
|
40
|
+
}
|
|
41
|
+
function resolveStatusFromCode(code, codes) {
|
|
42
|
+
return isSuccessCode(code, codes);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/dto/shared/base-dto.ts
|
|
46
|
+
var BaseDTO = class {
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// src/dto/response/dto.ts
|
|
50
|
+
var ResponseDTO = class _ResponseDTO extends BaseDTO {
|
|
51
|
+
_status;
|
|
52
|
+
_message;
|
|
53
|
+
_code;
|
|
54
|
+
_payload = {};
|
|
55
|
+
static status(value) {
|
|
56
|
+
return new _ResponseDTO().status(value);
|
|
57
|
+
}
|
|
58
|
+
static message(value) {
|
|
59
|
+
return new _ResponseDTO().message(value);
|
|
60
|
+
}
|
|
61
|
+
static code(value) {
|
|
62
|
+
return new _ResponseDTO().code(value);
|
|
63
|
+
}
|
|
64
|
+
static data(data) {
|
|
65
|
+
return new _ResponseDTO().data(data);
|
|
66
|
+
}
|
|
67
|
+
static payload(partial) {
|
|
68
|
+
return new _ResponseDTO().payload(partial);
|
|
69
|
+
}
|
|
70
|
+
static schema(input = {}, codes = DefaultCodes) {
|
|
71
|
+
return new _ResponseDTO().schema(input, codes);
|
|
72
|
+
}
|
|
73
|
+
status(value) {
|
|
74
|
+
this._status = value;
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
message(msg) {
|
|
78
|
+
this._message = msg;
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
code(code) {
|
|
82
|
+
this._code = code;
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
data(data) {
|
|
86
|
+
if (data === void 0) {
|
|
87
|
+
delete this._payload.data;
|
|
88
|
+
} else {
|
|
89
|
+
this._payload.data = data;
|
|
90
|
+
}
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
payload(partial) {
|
|
94
|
+
this._payload = { ...this._payload, ...partial };
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
setMeta(meta) {
|
|
98
|
+
this._payload.meta = { ...this._payload.meta ?? {}, ...meta };
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
paginate(total, page, limit) {
|
|
102
|
+
if (limit <= 0) {
|
|
103
|
+
throw new Error("ResponseDTO.paginate: limit must be greater than 0");
|
|
104
|
+
}
|
|
105
|
+
this._payload.pagination = {
|
|
106
|
+
total,
|
|
107
|
+
page,
|
|
108
|
+
limit,
|
|
109
|
+
totalPages: Math.ceil(total / limit),
|
|
110
|
+
hasNext: page * limit < total
|
|
111
|
+
};
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
schema(input = {}, codes = DefaultCodes) {
|
|
115
|
+
const { status, message, code, payload } = input;
|
|
116
|
+
if (code !== void 0) {
|
|
117
|
+
this.code(code);
|
|
118
|
+
}
|
|
119
|
+
if (status !== void 0) {
|
|
120
|
+
this.status(status);
|
|
121
|
+
} else if (code !== void 0) {
|
|
122
|
+
this.status(resolveStatusFromCode(code, codes));
|
|
123
|
+
}
|
|
124
|
+
if (message !== void 0) {
|
|
125
|
+
this.message(message);
|
|
126
|
+
}
|
|
127
|
+
if (payload !== void 0) {
|
|
128
|
+
this._payload = { ...payload };
|
|
129
|
+
}
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
getCode() {
|
|
133
|
+
return this._code;
|
|
134
|
+
}
|
|
135
|
+
getMessage() {
|
|
136
|
+
return this._message;
|
|
137
|
+
}
|
|
138
|
+
setCodeFromHttpStatus(httpStatusCode, codes) {
|
|
139
|
+
if (this._code === void 0) {
|
|
140
|
+
this._code = resolveCodeFromHttpStatus(httpStatusCode, codes);
|
|
141
|
+
}
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
transformData(fn) {
|
|
145
|
+
const next = new _ResponseDTO();
|
|
146
|
+
next._status = this._status;
|
|
147
|
+
next._message = this._message;
|
|
148
|
+
next._code = this._code;
|
|
149
|
+
next._payload = { ...this._payload };
|
|
150
|
+
if (this._payload.data !== void 0) {
|
|
151
|
+
next._payload.data = fn(this._payload.data);
|
|
152
|
+
}
|
|
153
|
+
return next;
|
|
154
|
+
}
|
|
155
|
+
build(options = {}) {
|
|
156
|
+
const codes = options.codes ?? DefaultCodes;
|
|
157
|
+
const code = this._code ?? (options.httpStatusCode !== void 0 ? resolveCodeFromHttpStatus(options.httpStatusCode, codes) : codes.SUCCESS);
|
|
158
|
+
const status = this._status ?? isSuccessCode(code, codes);
|
|
159
|
+
const message = this._message ?? defaultMessageForCode(code, codes);
|
|
160
|
+
if (options.withDefaultBody === false) {
|
|
161
|
+
return assembleResponseBody({ status, message, code });
|
|
162
|
+
}
|
|
163
|
+
const payload = this.buildPayload();
|
|
164
|
+
return assembleResponseBody({
|
|
165
|
+
status,
|
|
166
|
+
message,
|
|
167
|
+
payload,
|
|
168
|
+
code
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
buildPayload() {
|
|
172
|
+
const entries = Object.entries(this._payload).filter(([, value]) => value !== void 0);
|
|
173
|
+
if (entries.length === 0) return void 0;
|
|
174
|
+
return Object.fromEntries(entries);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
exports.ResponseDTO = ResponseDTO;
|
|
179
|
+
exports.assembleResponseBody = assembleResponseBody;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// src/core/assemble.ts
|
|
2
|
+
function assembleResponseBody(input) {
|
|
3
|
+
const ordered = {
|
|
4
|
+
status: input.status,
|
|
5
|
+
message: input.message
|
|
6
|
+
};
|
|
7
|
+
if (input.payload !== void 0 && Object.keys(input.payload).length > 0) {
|
|
8
|
+
ordered.payload = input.payload;
|
|
9
|
+
}
|
|
10
|
+
ordered.code = input.code;
|
|
11
|
+
return ordered;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/errors/codes.ts
|
|
15
|
+
var DefaultCodes = {
|
|
16
|
+
SUCCESS: 0,
|
|
17
|
+
CLIENT: 1,
|
|
18
|
+
SERVER: 2,
|
|
19
|
+
VALIDATION: 3
|
|
20
|
+
};
|
|
21
|
+
function isSuccessCode(code, codes) {
|
|
22
|
+
return code === codes.SUCCESS;
|
|
23
|
+
}
|
|
24
|
+
function resolveCodeFromHttpStatus(statusCode, codes) {
|
|
25
|
+
if (statusCode >= 200 && statusCode < 300) return codes.SUCCESS;
|
|
26
|
+
if (statusCode === 422) return codes.VALIDATION;
|
|
27
|
+
if (statusCode >= 400 && statusCode < 500) return codes.CLIENT;
|
|
28
|
+
if (statusCode >= 500) return codes.SERVER;
|
|
29
|
+
if (statusCode >= 300 && statusCode < 400) return codes.SUCCESS;
|
|
30
|
+
return codes.CLIENT;
|
|
31
|
+
}
|
|
32
|
+
function defaultMessageForCode(code, codes) {
|
|
33
|
+
if (code === codes.SUCCESS) return "Operation successful";
|
|
34
|
+
if (code === codes.CLIENT) return "Client error";
|
|
35
|
+
if (code === codes.SERVER) return "Internal server error";
|
|
36
|
+
if (code === codes.VALIDATION) return "Validation failed";
|
|
37
|
+
return "Operation failed";
|
|
38
|
+
}
|
|
39
|
+
function resolveStatusFromCode(code, codes) {
|
|
40
|
+
return isSuccessCode(code, codes);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/dto/shared/base-dto.ts
|
|
44
|
+
var BaseDTO = class {
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/dto/response/dto.ts
|
|
48
|
+
var ResponseDTO = class _ResponseDTO extends BaseDTO {
|
|
49
|
+
_status;
|
|
50
|
+
_message;
|
|
51
|
+
_code;
|
|
52
|
+
_payload = {};
|
|
53
|
+
static status(value) {
|
|
54
|
+
return new _ResponseDTO().status(value);
|
|
55
|
+
}
|
|
56
|
+
static message(value) {
|
|
57
|
+
return new _ResponseDTO().message(value);
|
|
58
|
+
}
|
|
59
|
+
static code(value) {
|
|
60
|
+
return new _ResponseDTO().code(value);
|
|
61
|
+
}
|
|
62
|
+
static data(data) {
|
|
63
|
+
return new _ResponseDTO().data(data);
|
|
64
|
+
}
|
|
65
|
+
static payload(partial) {
|
|
66
|
+
return new _ResponseDTO().payload(partial);
|
|
67
|
+
}
|
|
68
|
+
static schema(input = {}, codes = DefaultCodes) {
|
|
69
|
+
return new _ResponseDTO().schema(input, codes);
|
|
70
|
+
}
|
|
71
|
+
status(value) {
|
|
72
|
+
this._status = value;
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
message(msg) {
|
|
76
|
+
this._message = msg;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
code(code) {
|
|
80
|
+
this._code = code;
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
data(data) {
|
|
84
|
+
if (data === void 0) {
|
|
85
|
+
delete this._payload.data;
|
|
86
|
+
} else {
|
|
87
|
+
this._payload.data = data;
|
|
88
|
+
}
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
payload(partial) {
|
|
92
|
+
this._payload = { ...this._payload, ...partial };
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
setMeta(meta) {
|
|
96
|
+
this._payload.meta = { ...this._payload.meta ?? {}, ...meta };
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
paginate(total, page, limit) {
|
|
100
|
+
if (limit <= 0) {
|
|
101
|
+
throw new Error("ResponseDTO.paginate: limit must be greater than 0");
|
|
102
|
+
}
|
|
103
|
+
this._payload.pagination = {
|
|
104
|
+
total,
|
|
105
|
+
page,
|
|
106
|
+
limit,
|
|
107
|
+
totalPages: Math.ceil(total / limit),
|
|
108
|
+
hasNext: page * limit < total
|
|
109
|
+
};
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
schema(input = {}, codes = DefaultCodes) {
|
|
113
|
+
const { status, message, code, payload } = input;
|
|
114
|
+
if (code !== void 0) {
|
|
115
|
+
this.code(code);
|
|
116
|
+
}
|
|
117
|
+
if (status !== void 0) {
|
|
118
|
+
this.status(status);
|
|
119
|
+
} else if (code !== void 0) {
|
|
120
|
+
this.status(resolveStatusFromCode(code, codes));
|
|
121
|
+
}
|
|
122
|
+
if (message !== void 0) {
|
|
123
|
+
this.message(message);
|
|
124
|
+
}
|
|
125
|
+
if (payload !== void 0) {
|
|
126
|
+
this._payload = { ...payload };
|
|
127
|
+
}
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
getCode() {
|
|
131
|
+
return this._code;
|
|
132
|
+
}
|
|
133
|
+
getMessage() {
|
|
134
|
+
return this._message;
|
|
135
|
+
}
|
|
136
|
+
setCodeFromHttpStatus(httpStatusCode, codes) {
|
|
137
|
+
if (this._code === void 0) {
|
|
138
|
+
this._code = resolveCodeFromHttpStatus(httpStatusCode, codes);
|
|
139
|
+
}
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
transformData(fn) {
|
|
143
|
+
const next = new _ResponseDTO();
|
|
144
|
+
next._status = this._status;
|
|
145
|
+
next._message = this._message;
|
|
146
|
+
next._code = this._code;
|
|
147
|
+
next._payload = { ...this._payload };
|
|
148
|
+
if (this._payload.data !== void 0) {
|
|
149
|
+
next._payload.data = fn(this._payload.data);
|
|
150
|
+
}
|
|
151
|
+
return next;
|
|
152
|
+
}
|
|
153
|
+
build(options = {}) {
|
|
154
|
+
const codes = options.codes ?? DefaultCodes;
|
|
155
|
+
const code = this._code ?? (options.httpStatusCode !== void 0 ? resolveCodeFromHttpStatus(options.httpStatusCode, codes) : codes.SUCCESS);
|
|
156
|
+
const status = this._status ?? isSuccessCode(code, codes);
|
|
157
|
+
const message = this._message ?? defaultMessageForCode(code, codes);
|
|
158
|
+
if (options.withDefaultBody === false) {
|
|
159
|
+
return assembleResponseBody({ status, message, code });
|
|
160
|
+
}
|
|
161
|
+
const payload = this.buildPayload();
|
|
162
|
+
return assembleResponseBody({
|
|
163
|
+
status,
|
|
164
|
+
message,
|
|
165
|
+
payload,
|
|
166
|
+
code
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
buildPayload() {
|
|
170
|
+
const entries = Object.entries(this._payload).filter(([, value]) => value !== void 0);
|
|
171
|
+
if (entries.length === 0) return void 0;
|
|
172
|
+
return Object.fromEntries(entries);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export { ResponseDTO, assembleResponseBody };
|