elseware-nodejs 1.11.0 → 1.11.2
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/LICENSE +21 -0
- package/README.md +49 -0
- package/dist/index.cjs +192 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -32
- package/dist/index.d.ts +53 -32
- package/dist/index.js +191 -139
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 elseware Technology
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1 +1,50 @@
|
|
|
1
1
|
# elseware-nodejs
|
|
2
|
+
|
|
3
|
+
A modern Node.js utility and application framework powering the Elseware ecosystem.
|
|
4
|
+
|
|
5
|
+
`elseware-nodejs` provides a collection of reusable components, utilities, middleware, abstractions, and development patterns for building scalable Node.js applications and microservices.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- TypeScript-first development
|
|
10
|
+
- Express.js integration
|
|
11
|
+
- Repository pattern abstractions
|
|
12
|
+
- Service layer architecture
|
|
13
|
+
- Request context management
|
|
14
|
+
- Structured error handling
|
|
15
|
+
- Validation utilities
|
|
16
|
+
- Logging and observability support
|
|
17
|
+
- Microservice-friendly design
|
|
18
|
+
- Reusable application building blocks
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install elseware-nodejs
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { AppError } from "elseware-nodejs";
|
|
30
|
+
|
|
31
|
+
throw new AppError("Something went wrong");
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Documentation
|
|
35
|
+
|
|
36
|
+
Documentation, guides, and usage examples are available in the official repository.
|
|
37
|
+
|
|
38
|
+
## About elseware Technology
|
|
39
|
+
|
|
40
|
+
elseware Technology builds tools, frameworks, and solutions for software engineering, cloud computing, game development, and developer productivity.
|
|
41
|
+
|
|
42
|
+
## Contributing
|
|
43
|
+
|
|
44
|
+
Contributions, issues, and feature requests are welcome.
|
|
45
|
+
|
|
46
|
+
## License
|
|
47
|
+
|
|
48
|
+
This project is licensed under the MIT License.
|
|
49
|
+
|
|
50
|
+
Copyright © 2026 elseware Technology.
|
package/dist/index.cjs
CHANGED
|
@@ -27,7 +27,8 @@ var juice__default = /*#__PURE__*/_interopDefault(juice);
|
|
|
27
27
|
var jwt__default = /*#__PURE__*/_interopDefault(jwt);
|
|
28
28
|
var multer__default = /*#__PURE__*/_interopDefault(multer);
|
|
29
29
|
|
|
30
|
-
// src/
|
|
30
|
+
// src/core/constants/defaultOrigins.ts
|
|
31
|
+
var DEFAULT_ALLOWED_ORIGINS = ["http://localhost:3000"];
|
|
31
32
|
|
|
32
33
|
// src/utils/errorToString.ts
|
|
33
34
|
function errorToString(error) {
|
|
@@ -45,119 +46,140 @@ ${error.stack ?? ""}`;
|
|
|
45
46
|
return String(error);
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
// src/
|
|
49
|
+
// src/core/logger/colors.ts
|
|
50
|
+
var colors = {
|
|
51
|
+
reset: "\x1B[0m",
|
|
52
|
+
blue: "\x1B[34m",
|
|
53
|
+
yellow: "\x1B[33m",
|
|
54
|
+
red: "\x1B[31m",
|
|
55
|
+
cyan: "\x1B[36m"
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/core/logger/Logger.ts
|
|
49
59
|
var Logger = class {
|
|
50
|
-
timestamp = true;
|
|
51
60
|
enabled = true;
|
|
52
|
-
|
|
61
|
+
timestamp = true;
|
|
62
|
+
colorsEnabled = true;
|
|
63
|
+
minimumLevel = "INFO" /* INFO */;
|
|
53
64
|
configure(options = {}) {
|
|
54
|
-
this.timestamp = options.timestamp ?? this.timestamp;
|
|
55
65
|
this.enabled = options.enabled ?? this.enabled;
|
|
66
|
+
this.timestamp = options.timestamp ?? this.timestamp;
|
|
67
|
+
this.colorsEnabled = options.colors ?? this.colorsEnabled;
|
|
68
|
+
this.minimumLevel = options.level ?? this.minimumLevel;
|
|
69
|
+
}
|
|
70
|
+
levelWeight(level) {
|
|
71
|
+
switch (level) {
|
|
72
|
+
case "DEBUG" /* DEBUG */:
|
|
73
|
+
return 10;
|
|
74
|
+
case "INFO" /* INFO */:
|
|
75
|
+
return 20;
|
|
76
|
+
case "WARN" /* WARN */:
|
|
77
|
+
return 30;
|
|
78
|
+
case "ERROR" /* ERROR */:
|
|
79
|
+
return 40;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
shouldLog(level) {
|
|
83
|
+
return this.levelWeight(level) >= this.levelWeight(this.minimumLevel);
|
|
84
|
+
}
|
|
85
|
+
formatLevel(level) {
|
|
86
|
+
if (!this.colorsEnabled) {
|
|
87
|
+
return level;
|
|
88
|
+
}
|
|
89
|
+
switch (level) {
|
|
90
|
+
case "DEBUG" /* DEBUG */:
|
|
91
|
+
return `${colors.cyan}${level}${colors.reset}`;
|
|
92
|
+
case "INFO" /* INFO */:
|
|
93
|
+
return `${colors.blue}${level}${colors.reset}`;
|
|
94
|
+
case "WARN" /* WARN */:
|
|
95
|
+
return `${colors.yellow}${level}${colors.reset}`;
|
|
96
|
+
case "ERROR" /* ERROR */:
|
|
97
|
+
return `${colors.red}${level}${colors.reset}`;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
write(level, message) {
|
|
101
|
+
if (!this.enabled) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (!this.shouldLog(level)) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const timestamp = this.timestamp ? `[${(/* @__PURE__ */ new Date()).toISOString()}] ` : "";
|
|
108
|
+
console.log(`${timestamp}[${this.formatLevel(level)}] ${message}`);
|
|
56
109
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}`;
|
|
60
|
-
}
|
|
61
|
-
output(msg) {
|
|
62
|
-
if (!this.enabled) return;
|
|
63
|
-
console.log(this.format(msg));
|
|
64
|
-
}
|
|
65
|
-
// Log Levels
|
|
66
|
-
success(msg) {
|
|
67
|
-
this.output(`\u2705 ${msg}`);
|
|
110
|
+
debug(message) {
|
|
111
|
+
this.write("DEBUG" /* DEBUG */, message);
|
|
68
112
|
}
|
|
69
|
-
info(
|
|
70
|
-
this.
|
|
113
|
+
info(message) {
|
|
114
|
+
this.write("INFO" /* INFO */, message);
|
|
71
115
|
}
|
|
72
|
-
|
|
73
|
-
this.
|
|
116
|
+
warn(message) {
|
|
117
|
+
this.write("WARN" /* WARN */, message);
|
|
74
118
|
}
|
|
75
|
-
|
|
119
|
+
error(message, error) {
|
|
76
120
|
if (error) {
|
|
77
|
-
this.
|
|
121
|
+
this.write("ERROR" /* ERROR */, `${message}
|
|
78
122
|
${errorToString(error)}`);
|
|
79
|
-
|
|
80
|
-
this.output(`\u274C ${message}`);
|
|
123
|
+
return;
|
|
81
124
|
}
|
|
82
|
-
|
|
83
|
-
log(msg) {
|
|
84
|
-
this.output(`\u2022 ${msg}`);
|
|
125
|
+
this.write("ERROR" /* ERROR */, message);
|
|
85
126
|
}
|
|
86
127
|
};
|
|
128
|
+
|
|
129
|
+
// src/core/logger/index.ts
|
|
87
130
|
var logger = new Logger();
|
|
88
131
|
|
|
89
|
-
// src/
|
|
132
|
+
// src/core/environment/loadEnv.ts
|
|
90
133
|
dotenv__default.default.config({ quiet: true });
|
|
91
134
|
function loadEnv(options) {
|
|
92
135
|
const result = options.schema.safeParse(process.env);
|
|
93
136
|
if (!result.success) {
|
|
94
|
-
|
|
137
|
+
handleValidationError(result.error);
|
|
95
138
|
}
|
|
96
|
-
logger.
|
|
139
|
+
logger.info("Environment variables validated");
|
|
97
140
|
const env = result.data;
|
|
98
141
|
return options.transform ? options.transform(env) : env;
|
|
99
142
|
}
|
|
100
|
-
function
|
|
101
|
-
logger.
|
|
143
|
+
function handleValidationError(error) {
|
|
144
|
+
logger.error("Environment validation failed");
|
|
102
145
|
const grouped = {};
|
|
103
|
-
error.issues.forEach((
|
|
104
|
-
const key =
|
|
146
|
+
error.issues.forEach((issue) => {
|
|
147
|
+
const key = issue.path.join(".") || "unknown";
|
|
105
148
|
const rawValue = key !== "unknown" ? process.env[key] : void 0;
|
|
106
|
-
const
|
|
107
|
-
const safeValue = isSecret ? "***" : rawValue;
|
|
149
|
+
const safeValue = key.toLowerCase().includes("secret") ? "***" : rawValue;
|
|
108
150
|
const message = [
|
|
109
|
-
`message: ${
|
|
110
|
-
`code: ${
|
|
151
|
+
`message: ${issue.message}`,
|
|
152
|
+
`code: ${issue.code}`,
|
|
111
153
|
rawValue !== void 0 ? `value: ${JSON.stringify(safeValue)}` : null
|
|
112
154
|
].filter(Boolean).join(" | ");
|
|
113
|
-
|
|
155
|
+
grouped[key] ??= [];
|
|
114
156
|
grouped[key].push(message);
|
|
115
157
|
});
|
|
116
158
|
Object.entries(grouped).forEach(([key, messages]) => {
|
|
117
|
-
logger.
|
|
118
|
-
messages.forEach((
|
|
159
|
+
logger.error(`ENV: ${key}`);
|
|
160
|
+
messages.forEach((message) => logger.error(` - ${message}`));
|
|
119
161
|
});
|
|
120
|
-
logger.
|
|
162
|
+
logger.error("Application startup aborted");
|
|
121
163
|
process.exit(1);
|
|
122
164
|
}
|
|
123
165
|
|
|
124
|
-
// src/
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
166
|
+
// src/core/errors/AppError.ts
|
|
167
|
+
var AppError = class extends Error {
|
|
168
|
+
statusCode;
|
|
169
|
+
status;
|
|
170
|
+
isOperational;
|
|
171
|
+
code;
|
|
172
|
+
details;
|
|
173
|
+
constructor(message, statusCode = 500, options) {
|
|
174
|
+
super(message);
|
|
175
|
+
this.statusCode = statusCode;
|
|
176
|
+
this.status = statusCode >= 400 && statusCode < 500 ? "fail" : "error";
|
|
177
|
+
this.isOperational = options?.isOperational ?? true;
|
|
178
|
+
this.code = options?.code;
|
|
179
|
+
this.details = options?.details;
|
|
180
|
+
Error.captureStackTrace(this, this.constructor);
|
|
136
181
|
}
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// src/configs/cors/corsOptions.ts
|
|
141
|
-
function createCorsOptions(allowedOrigins) {
|
|
142
|
-
return {
|
|
143
|
-
origin(origin, callback) {
|
|
144
|
-
if (!origin || allowedOrigins.includes(origin)) {
|
|
145
|
-
return callback(null, true);
|
|
146
|
-
}
|
|
147
|
-
return callback(new Error(`CORS blocked: ${origin} is not allowed`));
|
|
148
|
-
},
|
|
149
|
-
credentials: true,
|
|
150
|
-
methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
|
151
|
-
allowedHeaders: [
|
|
152
|
-
"Content-Type",
|
|
153
|
-
"Authorization",
|
|
154
|
-
"X-Requested-With",
|
|
155
|
-
"Accept"
|
|
156
|
-
],
|
|
157
|
-
exposedHeaders: ["Set-Cookie"],
|
|
158
|
-
optionsSuccessStatus: 204
|
|
159
|
-
};
|
|
160
|
-
}
|
|
182
|
+
};
|
|
161
183
|
|
|
162
184
|
// src/data-structures/array/CircularArray.ts
|
|
163
185
|
var CircularArray = class {
|
|
@@ -4841,7 +4863,45 @@ var SegmentTree = class {
|
|
|
4841
4863
|
}
|
|
4842
4864
|
};
|
|
4843
4865
|
|
|
4844
|
-
// src/
|
|
4866
|
+
// src/infrastructure/cors/createAllowedOrigins.ts
|
|
4867
|
+
function createAllowedOrigins(options = {}) {
|
|
4868
|
+
const { origins, defaults = DEFAULT_ALLOWED_ORIGINS } = options;
|
|
4869
|
+
let allowedOrigins = [];
|
|
4870
|
+
if (typeof origins === "string") {
|
|
4871
|
+
allowedOrigins = origins.split(",").map((origin) => origin.trim()).filter(Boolean);
|
|
4872
|
+
}
|
|
4873
|
+
if (Array.isArray(origins)) {
|
|
4874
|
+
allowedOrigins = origins.map((origin) => origin.trim()).filter(Boolean);
|
|
4875
|
+
}
|
|
4876
|
+
if (allowedOrigins.length === 0) {
|
|
4877
|
+
allowedOrigins = [...defaults];
|
|
4878
|
+
}
|
|
4879
|
+
return allowedOrigins;
|
|
4880
|
+
}
|
|
4881
|
+
|
|
4882
|
+
// src/infrastructure/cors/createCorsOptions.ts
|
|
4883
|
+
function createCorsOptions(allowedOrigins) {
|
|
4884
|
+
return {
|
|
4885
|
+
origin(origin, callback) {
|
|
4886
|
+
if (!origin || allowedOrigins.includes(origin)) {
|
|
4887
|
+
return callback(null, true);
|
|
4888
|
+
}
|
|
4889
|
+
return callback(new Error(`CORS blocked: ${origin} is not allowed`));
|
|
4890
|
+
},
|
|
4891
|
+
credentials: true,
|
|
4892
|
+
methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
|
4893
|
+
allowedHeaders: [
|
|
4894
|
+
"Content-Type",
|
|
4895
|
+
"Authorization",
|
|
4896
|
+
"X-Requested-With",
|
|
4897
|
+
"Accept"
|
|
4898
|
+
],
|
|
4899
|
+
exposedHeaders: ["Set-Cookie"],
|
|
4900
|
+
optionsSuccessStatus: 204
|
|
4901
|
+
};
|
|
4902
|
+
}
|
|
4903
|
+
|
|
4904
|
+
// src/infrastructure/database/DatabaseManager.ts
|
|
4845
4905
|
var DatabaseManager = class {
|
|
4846
4906
|
constructor(provider, options = {
|
|
4847
4907
|
enableShutdownHooks: true
|
|
@@ -4852,21 +4912,21 @@ var DatabaseManager = class {
|
|
|
4852
4912
|
async connect() {
|
|
4853
4913
|
try {
|
|
4854
4914
|
await this.provider.connect();
|
|
4855
|
-
logger.
|
|
4915
|
+
logger.info("Database connected");
|
|
4856
4916
|
if (this.options.enableShutdownHooks) {
|
|
4857
4917
|
this.registerShutdownHooks();
|
|
4858
4918
|
}
|
|
4859
4919
|
} catch (error) {
|
|
4860
|
-
logger.
|
|
4920
|
+
logger.error("Database connection failed", error);
|
|
4861
4921
|
throw error;
|
|
4862
4922
|
}
|
|
4863
4923
|
}
|
|
4864
4924
|
async disconnect() {
|
|
4865
4925
|
try {
|
|
4866
4926
|
await this.provider.disconnect();
|
|
4867
|
-
logger.
|
|
4927
|
+
logger.info("Database disconnected");
|
|
4868
4928
|
} catch (error) {
|
|
4869
|
-
logger.
|
|
4929
|
+
logger.error("Database disconnect failed", error);
|
|
4870
4930
|
throw error;
|
|
4871
4931
|
}
|
|
4872
4932
|
}
|
|
@@ -4878,12 +4938,20 @@ var DatabaseManager = class {
|
|
|
4878
4938
|
}
|
|
4879
4939
|
registerShutdownHooks() {
|
|
4880
4940
|
process.once("SIGINT", async () => {
|
|
4881
|
-
|
|
4882
|
-
|
|
4941
|
+
logger.info("SIGINT received, shutting down database connection");
|
|
4942
|
+
try {
|
|
4943
|
+
await this.disconnect();
|
|
4944
|
+
} finally {
|
|
4945
|
+
process.exit(0);
|
|
4946
|
+
}
|
|
4883
4947
|
});
|
|
4884
4948
|
process.once("SIGTERM", async () => {
|
|
4885
|
-
|
|
4886
|
-
|
|
4949
|
+
logger.info("SIGTERM received, shutting down database connection");
|
|
4950
|
+
try {
|
|
4951
|
+
await this.disconnect();
|
|
4952
|
+
} finally {
|
|
4953
|
+
process.exit(0);
|
|
4954
|
+
}
|
|
4887
4955
|
});
|
|
4888
4956
|
}
|
|
4889
4957
|
};
|
|
@@ -4917,30 +4985,12 @@ var MongoDatabaseProvider = class {
|
|
|
4917
4985
|
}
|
|
4918
4986
|
};
|
|
4919
4987
|
|
|
4920
|
-
// src/
|
|
4921
|
-
var AppError = class extends Error {
|
|
4922
|
-
statusCode;
|
|
4923
|
-
status;
|
|
4924
|
-
isOperational;
|
|
4925
|
-
code;
|
|
4926
|
-
details;
|
|
4927
|
-
constructor(message, statusCode = 500, options) {
|
|
4928
|
-
super(message);
|
|
4929
|
-
this.statusCode = statusCode;
|
|
4930
|
-
this.status = `${statusCode}`.startsWith("4") ? "fail" : "error";
|
|
4931
|
-
this.isOperational = true;
|
|
4932
|
-
this.code = options?.code;
|
|
4933
|
-
this.details = options?.details;
|
|
4934
|
-
Error.captureStackTrace(this, this.constructor);
|
|
4935
|
-
}
|
|
4936
|
-
};
|
|
4937
|
-
|
|
4938
|
-
// src/http/handlers/AsyncHandler.ts
|
|
4988
|
+
// src/infrastructure/http/handlers/AsyncHandler.ts
|
|
4939
4989
|
var AsyncHandler = (fn) => (req, res, next) => {
|
|
4940
4990
|
Promise.resolve(fn(req, res, next)).catch(next);
|
|
4941
4991
|
};
|
|
4942
4992
|
|
|
4943
|
-
// src/http/query/QueryConstants.ts
|
|
4993
|
+
// src/infrastructure/http/query/QueryConstants.ts
|
|
4944
4994
|
var QUERY_RESERVED_FIELDS = [
|
|
4945
4995
|
"page",
|
|
4946
4996
|
"limit",
|
|
@@ -4965,7 +5015,7 @@ var SUPPORTED_OPERATORS = [
|
|
|
4965
5015
|
"endsWith"
|
|
4966
5016
|
];
|
|
4967
5017
|
|
|
4968
|
-
// src/http/query/ApiFeatures.ts
|
|
5018
|
+
// src/infrastructure/http/query/ApiFeatures.ts
|
|
4969
5019
|
var ApiFeatures = class {
|
|
4970
5020
|
static parse(query) {
|
|
4971
5021
|
return {
|
|
@@ -5043,7 +5093,7 @@ var ApiFeatures = class {
|
|
|
5043
5093
|
}
|
|
5044
5094
|
};
|
|
5045
5095
|
|
|
5046
|
-
// src/http/responses/ApiResponse.ts
|
|
5096
|
+
// src/infrastructure/http/responses/ApiResponse.ts
|
|
5047
5097
|
var ApiResponse = class _ApiResponse {
|
|
5048
5098
|
static send(res, options) {
|
|
5049
5099
|
const {
|
|
@@ -5117,7 +5167,7 @@ var ApiResponse = class _ApiResponse {
|
|
|
5117
5167
|
}
|
|
5118
5168
|
};
|
|
5119
5169
|
|
|
5120
|
-
// src/http/controllers/CrudControllerFactory.ts
|
|
5170
|
+
// src/infrastructure/http/controllers/CrudControllerFactory.ts
|
|
5121
5171
|
var CrudControllerFactory = class {
|
|
5122
5172
|
static create(repository, options = {}) {
|
|
5123
5173
|
const resourceName = options.resourceName ?? "Resource";
|
|
@@ -5219,12 +5269,12 @@ var CrudControllerFactory = class {
|
|
|
5219
5269
|
}
|
|
5220
5270
|
};
|
|
5221
5271
|
|
|
5222
|
-
// src/http/middleware/AuthMiddleware.ts
|
|
5272
|
+
// src/infrastructure/http/middleware/AuthMiddleware.ts
|
|
5223
5273
|
var authMiddleware = (_req, _res, next) => {
|
|
5224
5274
|
next();
|
|
5225
5275
|
};
|
|
5226
5276
|
|
|
5227
|
-
// src/http/middleware/ErrorMiddleware.ts
|
|
5277
|
+
// src/infrastructure/http/middleware/ErrorMiddleware.ts
|
|
5228
5278
|
var handleCastError = (err) => new AppError(`Invalid ${err.path}: ${err.value}`, 400, {
|
|
5229
5279
|
code: "INVALID_ID"
|
|
5230
5280
|
});
|
|
@@ -5234,7 +5284,7 @@ var handleDuplicateKey = (err) => {
|
|
|
5234
5284
|
code: "DUPLICATE_FIELD"
|
|
5235
5285
|
});
|
|
5236
5286
|
};
|
|
5237
|
-
var
|
|
5287
|
+
var handleValidationError2 = (err) => {
|
|
5238
5288
|
const errors = Object.entries(err.errors).reduce(
|
|
5239
5289
|
(acc, [key, value]) => {
|
|
5240
5290
|
acc[key] = value.message;
|
|
@@ -5254,11 +5304,13 @@ var ErrorMiddleware = (isProduction = false) => (err, _req, res, _next) => {
|
|
|
5254
5304
|
if (err instanceof AppError) {
|
|
5255
5305
|
error = err;
|
|
5256
5306
|
} else if (err instanceof Error) {
|
|
5257
|
-
error = new AppError(err.message, 500
|
|
5258
|
-
|
|
5307
|
+
error = new AppError(err.message, 500, {
|
|
5308
|
+
isOperational: false
|
|
5309
|
+
});
|
|
5259
5310
|
} else {
|
|
5260
|
-
error = new AppError("Internal Server Error", 500
|
|
5261
|
-
|
|
5311
|
+
error = new AppError("Internal Server Error", 500, {
|
|
5312
|
+
isOperational: false
|
|
5313
|
+
});
|
|
5262
5314
|
}
|
|
5263
5315
|
if (err && err.name === "CastError") {
|
|
5264
5316
|
error = handleCastError(err);
|
|
@@ -5269,7 +5321,7 @@ var ErrorMiddleware = (isProduction = false) => (err, _req, res, _next) => {
|
|
|
5269
5321
|
);
|
|
5270
5322
|
}
|
|
5271
5323
|
if (err && err.name === "ValidationError") {
|
|
5272
|
-
error =
|
|
5324
|
+
error = handleValidationError2(err);
|
|
5273
5325
|
}
|
|
5274
5326
|
if (err?.name === "JsonWebTokenError") {
|
|
5275
5327
|
error = handleJWTError();
|
|
@@ -5278,9 +5330,9 @@ var ErrorMiddleware = (isProduction = false) => (err, _req, res, _next) => {
|
|
|
5278
5330
|
error = handleJWTExpiredError();
|
|
5279
5331
|
}
|
|
5280
5332
|
if (!error.isOperational) {
|
|
5281
|
-
logger.
|
|
5333
|
+
logger.error("Programming error", err);
|
|
5282
5334
|
} else {
|
|
5283
|
-
logger.
|
|
5335
|
+
logger.error("Operational error", {
|
|
5284
5336
|
message: error.message
|
|
5285
5337
|
});
|
|
5286
5338
|
}
|
|
@@ -5308,7 +5360,7 @@ var ErrorMiddleware = (isProduction = false) => (err, _req, res, _next) => {
|
|
|
5308
5360
|
});
|
|
5309
5361
|
};
|
|
5310
5362
|
|
|
5311
|
-
// src/http/validation/Validator.ts
|
|
5363
|
+
// src/infrastructure/http/validation/Validator.ts
|
|
5312
5364
|
var isJoiSchema = (schema) => {
|
|
5313
5365
|
return typeof schema === "object" && schema !== null && "validate" in schema;
|
|
5314
5366
|
};
|
|
@@ -5316,7 +5368,7 @@ var isZodSchema = (schema) => {
|
|
|
5316
5368
|
return typeof schema === "object" && schema !== null && "safeParse" in schema;
|
|
5317
5369
|
};
|
|
5318
5370
|
|
|
5319
|
-
// src/http/validation/JoiValidator.ts
|
|
5371
|
+
// src/infrastructure/http/validation/JoiValidator.ts
|
|
5320
5372
|
var JoiValidator = class {
|
|
5321
5373
|
constructor(schema) {
|
|
5322
5374
|
this.schema = schema;
|
|
@@ -5344,7 +5396,7 @@ var JoiValidator = class {
|
|
|
5344
5396
|
}
|
|
5345
5397
|
};
|
|
5346
5398
|
|
|
5347
|
-
// src/http/validation/ZodValidator.ts
|
|
5399
|
+
// src/infrastructure/http/validation/ZodValidator.ts
|
|
5348
5400
|
var ZodValidator = class {
|
|
5349
5401
|
constructor(schema) {
|
|
5350
5402
|
this.schema = schema;
|
|
@@ -5369,7 +5421,7 @@ var ZodValidator = class {
|
|
|
5369
5421
|
}
|
|
5370
5422
|
};
|
|
5371
5423
|
|
|
5372
|
-
// src/http/middleware/ValidationMiddleware.ts
|
|
5424
|
+
// src/infrastructure/http/middleware/ValidationMiddleware.ts
|
|
5373
5425
|
var validate = (schema) => (req, _res, next) => {
|
|
5374
5426
|
let result;
|
|
5375
5427
|
if (isJoiSchema(schema)) {
|
|
@@ -5391,7 +5443,7 @@ var validate = (schema) => (req, _res, next) => {
|
|
|
5391
5443
|
next();
|
|
5392
5444
|
};
|
|
5393
5445
|
|
|
5394
|
-
// src/http/utils/PickFields.ts
|
|
5446
|
+
// src/infrastructure/http/utils/PickFields.ts
|
|
5395
5447
|
function pickFields(obj, fields, options = {}) {
|
|
5396
5448
|
const removeUndefined = options.removeUndefined ?? false;
|
|
5397
5449
|
const removeNull = options.removeNull ?? false;
|
|
@@ -5453,7 +5505,7 @@ var RequestContext = class {
|
|
|
5453
5505
|
}
|
|
5454
5506
|
};
|
|
5455
5507
|
|
|
5456
|
-
// src/networking/middleware/RequestContextMiddleware.ts
|
|
5508
|
+
// src/infrastructure/networking/middleware/RequestContextMiddleware.ts
|
|
5457
5509
|
function createRequestContextMiddleware(options = {}) {
|
|
5458
5510
|
const {
|
|
5459
5511
|
correlationHeaderName = "X-Correlation-Id",
|
|
@@ -5473,7 +5525,7 @@ function createRequestContextMiddleware(options = {}) {
|
|
|
5473
5525
|
};
|
|
5474
5526
|
}
|
|
5475
5527
|
|
|
5476
|
-
// src/networking/observability/TracingHeaders.ts
|
|
5528
|
+
// src/infrastructure/networking/observability/TracingHeaders.ts
|
|
5477
5529
|
var TracingHeaders = class {
|
|
5478
5530
|
static build() {
|
|
5479
5531
|
const headers = {};
|
|
@@ -5497,7 +5549,7 @@ var TracingHeaders = class {
|
|
|
5497
5549
|
}
|
|
5498
5550
|
};
|
|
5499
5551
|
|
|
5500
|
-
// src/networking/resilience/ExponentialBackoffRetryPolicy.ts
|
|
5552
|
+
// src/infrastructure/networking/resilience/ExponentialBackoffRetryPolicy.ts
|
|
5501
5553
|
var ExponentialBackoffRetryPolicy = class {
|
|
5502
5554
|
retries;
|
|
5503
5555
|
baseDelay;
|
|
@@ -5516,7 +5568,7 @@ var ExponentialBackoffRetryPolicy = class {
|
|
|
5516
5568
|
}
|
|
5517
5569
|
};
|
|
5518
5570
|
|
|
5519
|
-
// src/networking/resilience/FixedRetryPolicy.ts
|
|
5571
|
+
// src/infrastructure/networking/resilience/FixedRetryPolicy.ts
|
|
5520
5572
|
var FixedRetryPolicy = class {
|
|
5521
5573
|
retries;
|
|
5522
5574
|
delay;
|
|
@@ -5532,7 +5584,7 @@ var FixedRetryPolicy = class {
|
|
|
5532
5584
|
}
|
|
5533
5585
|
};
|
|
5534
5586
|
|
|
5535
|
-
// src/networking/security/BearerTokenStrategy.ts
|
|
5587
|
+
// src/infrastructure/networking/security/BearerTokenStrategy.ts
|
|
5536
5588
|
var BearerTokenStrategy = class {
|
|
5537
5589
|
constructor(tokenProvider) {
|
|
5538
5590
|
this.tokenProvider = tokenProvider;
|
|
@@ -5545,7 +5597,7 @@ var BearerTokenStrategy = class {
|
|
|
5545
5597
|
}
|
|
5546
5598
|
};
|
|
5547
5599
|
|
|
5548
|
-
// src/networking/security/StaticTokenProvider.ts
|
|
5600
|
+
// src/infrastructure/networking/security/StaticTokenProvider.ts
|
|
5549
5601
|
var StaticTokenProvider = class {
|
|
5550
5602
|
constructor(token) {
|
|
5551
5603
|
this.token = token;
|
|
@@ -5555,7 +5607,7 @@ var StaticTokenProvider = class {
|
|
|
5555
5607
|
}
|
|
5556
5608
|
};
|
|
5557
5609
|
|
|
5558
|
-
// src/networking/transport/HttpClient.ts
|
|
5610
|
+
// src/infrastructure/networking/transport/HttpClient.ts
|
|
5559
5611
|
var HttpClient = class {
|
|
5560
5612
|
baseUrl;
|
|
5561
5613
|
timeout;
|
|
@@ -5633,7 +5685,7 @@ var HttpClient = class {
|
|
|
5633
5685
|
lastError = error;
|
|
5634
5686
|
if (this.retryPolicy.shouldRetry(attempt, error)) {
|
|
5635
5687
|
const delay = this.retryPolicy.getDelay(attempt, error);
|
|
5636
|
-
logger.
|
|
5688
|
+
logger.warn(
|
|
5637
5689
|
`[${this.serviceName}] retry ${attempt + 1} after ${delay}ms`
|
|
5638
5690
|
);
|
|
5639
5691
|
await this.sleep(delay);
|
|
@@ -5644,7 +5696,7 @@ var HttpClient = class {
|
|
|
5644
5696
|
}
|
|
5645
5697
|
}
|
|
5646
5698
|
const correlationId = RequestContext.getCorrelationId();
|
|
5647
|
-
logger.
|
|
5699
|
+
logger.error(
|
|
5648
5700
|
`[${this.serviceName}]` + (correlationId ? ` [${correlationId}]` : "") + ` request failed`,
|
|
5649
5701
|
lastError
|
|
5650
5702
|
);
|
|
@@ -5655,7 +5707,7 @@ var HttpClient = class {
|
|
|
5655
5707
|
}
|
|
5656
5708
|
};
|
|
5657
5709
|
|
|
5658
|
-
// src/networking/services/ServiceClient.ts
|
|
5710
|
+
// src/infrastructure/networking/services/ServiceClient.ts
|
|
5659
5711
|
var ServiceClient = class extends HttpClient {
|
|
5660
5712
|
async getData(path2) {
|
|
5661
5713
|
const response = await super.get(path2);
|
|
@@ -5679,7 +5731,7 @@ var ServiceClient = class extends HttpClient {
|
|
|
5679
5731
|
}
|
|
5680
5732
|
};
|
|
5681
5733
|
|
|
5682
|
-
// src/networking/services/InternalServiceClient.ts
|
|
5734
|
+
// src/infrastructure/networking/services/InternalServiceClient.ts
|
|
5683
5735
|
var InternalServiceClient = class extends ServiceClient {
|
|
5684
5736
|
constructor(baseUrl, serviceToken, serviceName) {
|
|
5685
5737
|
super(baseUrl, {
|
|
@@ -6118,7 +6170,7 @@ var JWTService = class {
|
|
|
6118
6170
|
try {
|
|
6119
6171
|
return jwt__default.default.verify(token, this.accessSecret);
|
|
6120
6172
|
} catch (err) {
|
|
6121
|
-
logger.
|
|
6173
|
+
logger.error("Access token verification failed:", err.message);
|
|
6122
6174
|
return null;
|
|
6123
6175
|
}
|
|
6124
6176
|
}
|
|
@@ -6126,7 +6178,7 @@ var JWTService = class {
|
|
|
6126
6178
|
try {
|
|
6127
6179
|
return jwt__default.default.verify(token, this.refreshSecret);
|
|
6128
6180
|
} catch (err) {
|
|
6129
|
-
logger.
|
|
6181
|
+
logger.error("Refresh token verification failed:", err.message);
|
|
6130
6182
|
return null;
|
|
6131
6183
|
}
|
|
6132
6184
|
}
|
|
@@ -6306,6 +6358,7 @@ exports.ConsistentHash = ConsistentHash;
|
|
|
6306
6358
|
exports.CorrelationId = CorrelationId;
|
|
6307
6359
|
exports.CountMinSketch = CountMinSketch;
|
|
6308
6360
|
exports.CrudControllerFactory = CrudControllerFactory;
|
|
6361
|
+
exports.DEFAULT_ALLOWED_ORIGINS = DEFAULT_ALLOWED_ORIGINS;
|
|
6309
6362
|
exports.DEFAULT_LIMIT = DEFAULT_LIMIT;
|
|
6310
6363
|
exports.DEFAULT_PAGE = DEFAULT_PAGE;
|
|
6311
6364
|
exports.DEFAULT_SORT_DIRECTION = DEFAULT_SORT_DIRECTION;
|
|
@@ -6334,6 +6387,7 @@ exports.JoiValidator = JoiValidator;
|
|
|
6334
6387
|
exports.KDTree = KDTree;
|
|
6335
6388
|
exports.LFUCache = LFUCache;
|
|
6336
6389
|
exports.LRUCache = LRUCache;
|
|
6390
|
+
exports.Logger = Logger;
|
|
6337
6391
|
exports.MaxHeap = MaxHeap;
|
|
6338
6392
|
exports.MaxStack = MaxStack;
|
|
6339
6393
|
exports.MinHeap = MinHeap;
|