elseware-nodejs 1.11.0 → 1.11.1
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 +193 -180
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -45
- package/dist/index.d.ts +11 -45
- package/dist/index.js +194 -177
- 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
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var dotenv = require('dotenv');
|
|
4
3
|
var mongoose = require('mongoose');
|
|
5
4
|
var crypto = require('crypto');
|
|
6
5
|
var async_hooks = require('async_hooks');
|
|
@@ -16,7 +15,6 @@ var multer = require('multer');
|
|
|
16
15
|
|
|
17
16
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
17
|
|
|
19
|
-
var dotenv__default = /*#__PURE__*/_interopDefault(dotenv);
|
|
20
18
|
var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
|
|
21
19
|
var fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
22
20
|
var cloudinaryModule__default = /*#__PURE__*/_interopDefault(cloudinaryModule);
|
|
@@ -27,138 +25,6 @@ var juice__default = /*#__PURE__*/_interopDefault(juice);
|
|
|
27
25
|
var jwt__default = /*#__PURE__*/_interopDefault(jwt);
|
|
28
26
|
var multer__default = /*#__PURE__*/_interopDefault(multer);
|
|
29
27
|
|
|
30
|
-
// src/configs/env.ts
|
|
31
|
-
|
|
32
|
-
// src/utils/errorToString.ts
|
|
33
|
-
function errorToString(error) {
|
|
34
|
-
if (error instanceof Error) {
|
|
35
|
-
return `${error.name}: ${error.message}
|
|
36
|
-
${error.stack ?? ""}`;
|
|
37
|
-
}
|
|
38
|
-
if (typeof error === "object") {
|
|
39
|
-
try {
|
|
40
|
-
return JSON.stringify(error, null, 2);
|
|
41
|
-
} catch {
|
|
42
|
-
return "[Unserializable object]";
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return String(error);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// src/configs/logger.ts
|
|
49
|
-
var Logger = class {
|
|
50
|
-
timestamp = true;
|
|
51
|
-
enabled = true;
|
|
52
|
-
// Use to configure once at the root
|
|
53
|
-
configure(options = {}) {
|
|
54
|
-
this.timestamp = options.timestamp ?? this.timestamp;
|
|
55
|
-
this.enabled = options.enabled ?? this.enabled;
|
|
56
|
-
}
|
|
57
|
-
format(msg) {
|
|
58
|
-
if (!this.timestamp) return msg;
|
|
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}`);
|
|
68
|
-
}
|
|
69
|
-
info(msg) {
|
|
70
|
-
this.output(`\u{1F539} ${msg}`);
|
|
71
|
-
}
|
|
72
|
-
warning(msg) {
|
|
73
|
-
this.output(`\u26A0\uFE0F ${msg}`);
|
|
74
|
-
}
|
|
75
|
-
danger(message, error) {
|
|
76
|
-
if (error) {
|
|
77
|
-
this.output(`\u274C ${message}
|
|
78
|
-
${errorToString(error)}`);
|
|
79
|
-
} else {
|
|
80
|
-
this.output(`\u274C ${message}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
log(msg) {
|
|
84
|
-
this.output(`\u2022 ${msg}`);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
var logger = new Logger();
|
|
88
|
-
|
|
89
|
-
// src/configs/env.ts
|
|
90
|
-
dotenv__default.default.config({ quiet: true });
|
|
91
|
-
function loadEnv(options) {
|
|
92
|
-
const result = options.schema.safeParse(process.env);
|
|
93
|
-
if (!result.success) {
|
|
94
|
-
handleError(result.error);
|
|
95
|
-
}
|
|
96
|
-
logger.success("Env Configurations validated");
|
|
97
|
-
const env = result.data;
|
|
98
|
-
return options.transform ? options.transform(env) : env;
|
|
99
|
-
}
|
|
100
|
-
function handleError(error) {
|
|
101
|
-
logger.danger("Env validation failed");
|
|
102
|
-
const grouped = {};
|
|
103
|
-
error.issues.forEach((err) => {
|
|
104
|
-
const key = err.path.join(".") || "unknown";
|
|
105
|
-
const rawValue = key !== "unknown" ? process.env[key] : void 0;
|
|
106
|
-
const isSecret = key.toLowerCase().includes("secret");
|
|
107
|
-
const safeValue = isSecret ? "***" : rawValue;
|
|
108
|
-
const message = [
|
|
109
|
-
`message: ${err.message}`,
|
|
110
|
-
`code: ${err.code}`,
|
|
111
|
-
rawValue !== void 0 ? `value: ${JSON.stringify(safeValue)}` : null
|
|
112
|
-
].filter(Boolean).join(" | ");
|
|
113
|
-
if (!grouped[key]) grouped[key] = [];
|
|
114
|
-
grouped[key].push(message);
|
|
115
|
-
});
|
|
116
|
-
Object.entries(grouped).forEach(([key, messages]) => {
|
|
117
|
-
logger.info(key);
|
|
118
|
-
messages.forEach((msg) => logger.log(` - ${msg}`));
|
|
119
|
-
});
|
|
120
|
-
logger.danger("Application startup aborted!");
|
|
121
|
-
process.exit(1);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// src/configs/cors/allowedOrigins.ts
|
|
125
|
-
function createAllowedOrigins(options = {}) {
|
|
126
|
-
const { origins, defaults = ["http://localhost:3000"] } = options;
|
|
127
|
-
let allowedOrigins = [];
|
|
128
|
-
if (typeof origins === "string") {
|
|
129
|
-
allowedOrigins = origins.split(",").map((origin) => origin.trim()).filter(Boolean);
|
|
130
|
-
}
|
|
131
|
-
if (Array.isArray(origins)) {
|
|
132
|
-
allowedOrigins = origins.map((origin) => origin.trim()).filter(Boolean);
|
|
133
|
-
}
|
|
134
|
-
if (allowedOrigins.length === 0) {
|
|
135
|
-
allowedOrigins = [...defaults];
|
|
136
|
-
}
|
|
137
|
-
return allowedOrigins;
|
|
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
|
-
}
|
|
161
|
-
|
|
162
28
|
// src/data-structures/array/CircularArray.ts
|
|
163
29
|
var CircularArray = class {
|
|
164
30
|
capacity;
|
|
@@ -4841,7 +4707,147 @@ var SegmentTree = class {
|
|
|
4841
4707
|
}
|
|
4842
4708
|
};
|
|
4843
4709
|
|
|
4844
|
-
// src/
|
|
4710
|
+
// src/core/constants/defaultOrigins.ts
|
|
4711
|
+
var DEFAULT_ALLOWED_ORIGINS = ["http://localhost:3000"];
|
|
4712
|
+
|
|
4713
|
+
// src/infrastructure/cors/createAllowedOrigins.ts
|
|
4714
|
+
function createAllowedOrigins(options = {}) {
|
|
4715
|
+
const { origins, defaults = DEFAULT_ALLOWED_ORIGINS } = options;
|
|
4716
|
+
let allowedOrigins = [];
|
|
4717
|
+
if (typeof origins === "string") {
|
|
4718
|
+
allowedOrigins = origins.split(",").map((origin) => origin.trim()).filter(Boolean);
|
|
4719
|
+
}
|
|
4720
|
+
if (Array.isArray(origins)) {
|
|
4721
|
+
allowedOrigins = origins.map((origin) => origin.trim()).filter(Boolean);
|
|
4722
|
+
}
|
|
4723
|
+
if (allowedOrigins.length === 0) {
|
|
4724
|
+
allowedOrigins = [...defaults];
|
|
4725
|
+
}
|
|
4726
|
+
return allowedOrigins;
|
|
4727
|
+
}
|
|
4728
|
+
|
|
4729
|
+
// src/infrastructure/cors/createCorsOptions.ts
|
|
4730
|
+
function createCorsOptions(allowedOrigins) {
|
|
4731
|
+
return {
|
|
4732
|
+
origin(origin, callback) {
|
|
4733
|
+
if (!origin || allowedOrigins.includes(origin)) {
|
|
4734
|
+
return callback(null, true);
|
|
4735
|
+
}
|
|
4736
|
+
return callback(new Error(`CORS blocked: ${origin} is not allowed`));
|
|
4737
|
+
},
|
|
4738
|
+
credentials: true,
|
|
4739
|
+
methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
|
4740
|
+
allowedHeaders: [
|
|
4741
|
+
"Content-Type",
|
|
4742
|
+
"Authorization",
|
|
4743
|
+
"X-Requested-With",
|
|
4744
|
+
"Accept"
|
|
4745
|
+
],
|
|
4746
|
+
exposedHeaders: ["Set-Cookie"],
|
|
4747
|
+
optionsSuccessStatus: 204
|
|
4748
|
+
};
|
|
4749
|
+
}
|
|
4750
|
+
|
|
4751
|
+
// src/utils/errorToString.ts
|
|
4752
|
+
function errorToString(error) {
|
|
4753
|
+
if (error instanceof Error) {
|
|
4754
|
+
return `${error.name}: ${error.message}
|
|
4755
|
+
${error.stack ?? ""}`;
|
|
4756
|
+
}
|
|
4757
|
+
if (typeof error === "object") {
|
|
4758
|
+
try {
|
|
4759
|
+
return JSON.stringify(error, null, 2);
|
|
4760
|
+
} catch {
|
|
4761
|
+
return "[Unserializable object]";
|
|
4762
|
+
}
|
|
4763
|
+
}
|
|
4764
|
+
return String(error);
|
|
4765
|
+
}
|
|
4766
|
+
|
|
4767
|
+
// src/core/logger/colors.ts
|
|
4768
|
+
var colors = {
|
|
4769
|
+
reset: "\x1B[0m",
|
|
4770
|
+
blue: "\x1B[34m",
|
|
4771
|
+
yellow: "\x1B[33m",
|
|
4772
|
+
red: "\x1B[31m",
|
|
4773
|
+
cyan: "\x1B[36m"
|
|
4774
|
+
};
|
|
4775
|
+
|
|
4776
|
+
// src/core/logger/Logger.ts
|
|
4777
|
+
var Logger = class {
|
|
4778
|
+
enabled = true;
|
|
4779
|
+
timestamp = true;
|
|
4780
|
+
colorsEnabled = true;
|
|
4781
|
+
minimumLevel = "INFO" /* INFO */;
|
|
4782
|
+
configure(options = {}) {
|
|
4783
|
+
this.enabled = options.enabled ?? this.enabled;
|
|
4784
|
+
this.timestamp = options.timestamp ?? this.timestamp;
|
|
4785
|
+
this.colorsEnabled = options.colors ?? this.colorsEnabled;
|
|
4786
|
+
this.minimumLevel = options.level ?? this.minimumLevel;
|
|
4787
|
+
}
|
|
4788
|
+
levelWeight(level) {
|
|
4789
|
+
switch (level) {
|
|
4790
|
+
case "DEBUG" /* DEBUG */:
|
|
4791
|
+
return 10;
|
|
4792
|
+
case "INFO" /* INFO */:
|
|
4793
|
+
return 20;
|
|
4794
|
+
case "WARN" /* WARN */:
|
|
4795
|
+
return 30;
|
|
4796
|
+
case "ERROR" /* ERROR */:
|
|
4797
|
+
return 40;
|
|
4798
|
+
}
|
|
4799
|
+
}
|
|
4800
|
+
shouldLog(level) {
|
|
4801
|
+
return this.levelWeight(level) >= this.levelWeight(this.minimumLevel);
|
|
4802
|
+
}
|
|
4803
|
+
formatLevel(level) {
|
|
4804
|
+
if (!this.colorsEnabled) {
|
|
4805
|
+
return level;
|
|
4806
|
+
}
|
|
4807
|
+
switch (level) {
|
|
4808
|
+
case "DEBUG" /* DEBUG */:
|
|
4809
|
+
return `${colors.cyan}${level}${colors.reset}`;
|
|
4810
|
+
case "INFO" /* INFO */:
|
|
4811
|
+
return `${colors.blue}${level}${colors.reset}`;
|
|
4812
|
+
case "WARN" /* WARN */:
|
|
4813
|
+
return `${colors.yellow}${level}${colors.reset}`;
|
|
4814
|
+
case "ERROR" /* ERROR */:
|
|
4815
|
+
return `${colors.red}${level}${colors.reset}`;
|
|
4816
|
+
}
|
|
4817
|
+
}
|
|
4818
|
+
write(level, message) {
|
|
4819
|
+
if (!this.enabled) {
|
|
4820
|
+
return;
|
|
4821
|
+
}
|
|
4822
|
+
if (!this.shouldLog(level)) {
|
|
4823
|
+
return;
|
|
4824
|
+
}
|
|
4825
|
+
const timestamp = this.timestamp ? `[${(/* @__PURE__ */ new Date()).toISOString()}] ` : "";
|
|
4826
|
+
console.log(`${timestamp}[${this.formatLevel(level)}] ${message}`);
|
|
4827
|
+
}
|
|
4828
|
+
debug(message) {
|
|
4829
|
+
this.write("DEBUG" /* DEBUG */, message);
|
|
4830
|
+
}
|
|
4831
|
+
info(message) {
|
|
4832
|
+
this.write("INFO" /* INFO */, message);
|
|
4833
|
+
}
|
|
4834
|
+
warn(message) {
|
|
4835
|
+
this.write("WARN" /* WARN */, message);
|
|
4836
|
+
}
|
|
4837
|
+
error(message, error) {
|
|
4838
|
+
if (error) {
|
|
4839
|
+
this.write("ERROR" /* ERROR */, `${message}
|
|
4840
|
+
${errorToString(error)}`);
|
|
4841
|
+
return;
|
|
4842
|
+
}
|
|
4843
|
+
this.write("ERROR" /* ERROR */, message);
|
|
4844
|
+
}
|
|
4845
|
+
};
|
|
4846
|
+
|
|
4847
|
+
// src/core/logger/index.ts
|
|
4848
|
+
var logger = new Logger();
|
|
4849
|
+
|
|
4850
|
+
// src/infrastructure/database/DatabaseManager.ts
|
|
4845
4851
|
var DatabaseManager = class {
|
|
4846
4852
|
constructor(provider, options = {
|
|
4847
4853
|
enableShutdownHooks: true
|
|
@@ -4852,21 +4858,21 @@ var DatabaseManager = class {
|
|
|
4852
4858
|
async connect() {
|
|
4853
4859
|
try {
|
|
4854
4860
|
await this.provider.connect();
|
|
4855
|
-
logger.
|
|
4861
|
+
logger.info("Database connected");
|
|
4856
4862
|
if (this.options.enableShutdownHooks) {
|
|
4857
4863
|
this.registerShutdownHooks();
|
|
4858
4864
|
}
|
|
4859
4865
|
} catch (error) {
|
|
4860
|
-
logger.
|
|
4866
|
+
logger.error("Database connection failed", error);
|
|
4861
4867
|
throw error;
|
|
4862
4868
|
}
|
|
4863
4869
|
}
|
|
4864
4870
|
async disconnect() {
|
|
4865
4871
|
try {
|
|
4866
4872
|
await this.provider.disconnect();
|
|
4867
|
-
logger.
|
|
4873
|
+
logger.info("Database disconnected");
|
|
4868
4874
|
} catch (error) {
|
|
4869
|
-
logger.
|
|
4875
|
+
logger.error("Database disconnect failed", error);
|
|
4870
4876
|
throw error;
|
|
4871
4877
|
}
|
|
4872
4878
|
}
|
|
@@ -4878,12 +4884,20 @@ var DatabaseManager = class {
|
|
|
4878
4884
|
}
|
|
4879
4885
|
registerShutdownHooks() {
|
|
4880
4886
|
process.once("SIGINT", async () => {
|
|
4881
|
-
|
|
4882
|
-
|
|
4887
|
+
logger.info("SIGINT received, shutting down database connection");
|
|
4888
|
+
try {
|
|
4889
|
+
await this.disconnect();
|
|
4890
|
+
} finally {
|
|
4891
|
+
process.exit(0);
|
|
4892
|
+
}
|
|
4883
4893
|
});
|
|
4884
4894
|
process.once("SIGTERM", async () => {
|
|
4885
|
-
|
|
4886
|
-
|
|
4895
|
+
logger.info("SIGTERM received, shutting down database connection");
|
|
4896
|
+
try {
|
|
4897
|
+
await this.disconnect();
|
|
4898
|
+
} finally {
|
|
4899
|
+
process.exit(0);
|
|
4900
|
+
}
|
|
4887
4901
|
});
|
|
4888
4902
|
}
|
|
4889
4903
|
};
|
|
@@ -4917,7 +4931,7 @@ var MongoDatabaseProvider = class {
|
|
|
4917
4931
|
}
|
|
4918
4932
|
};
|
|
4919
4933
|
|
|
4920
|
-
// src/errors/
|
|
4934
|
+
// src/core/errors/AppError.ts
|
|
4921
4935
|
var AppError = class extends Error {
|
|
4922
4936
|
statusCode;
|
|
4923
4937
|
status;
|
|
@@ -4927,20 +4941,20 @@ var AppError = class extends Error {
|
|
|
4927
4941
|
constructor(message, statusCode = 500, options) {
|
|
4928
4942
|
super(message);
|
|
4929
4943
|
this.statusCode = statusCode;
|
|
4930
|
-
this.status =
|
|
4931
|
-
this.isOperational = true;
|
|
4944
|
+
this.status = statusCode >= 400 && statusCode < 500 ? "fail" : "error";
|
|
4945
|
+
this.isOperational = options?.isOperational ?? true;
|
|
4932
4946
|
this.code = options?.code;
|
|
4933
4947
|
this.details = options?.details;
|
|
4934
4948
|
Error.captureStackTrace(this, this.constructor);
|
|
4935
4949
|
}
|
|
4936
4950
|
};
|
|
4937
4951
|
|
|
4938
|
-
// src/http/handlers/AsyncHandler.ts
|
|
4952
|
+
// src/infrastructure/http/handlers/AsyncHandler.ts
|
|
4939
4953
|
var AsyncHandler = (fn) => (req, res, next) => {
|
|
4940
4954
|
Promise.resolve(fn(req, res, next)).catch(next);
|
|
4941
4955
|
};
|
|
4942
4956
|
|
|
4943
|
-
// src/http/query/QueryConstants.ts
|
|
4957
|
+
// src/infrastructure/http/query/QueryConstants.ts
|
|
4944
4958
|
var QUERY_RESERVED_FIELDS = [
|
|
4945
4959
|
"page",
|
|
4946
4960
|
"limit",
|
|
@@ -4965,7 +4979,7 @@ var SUPPORTED_OPERATORS = [
|
|
|
4965
4979
|
"endsWith"
|
|
4966
4980
|
];
|
|
4967
4981
|
|
|
4968
|
-
// src/http/query/ApiFeatures.ts
|
|
4982
|
+
// src/infrastructure/http/query/ApiFeatures.ts
|
|
4969
4983
|
var ApiFeatures = class {
|
|
4970
4984
|
static parse(query) {
|
|
4971
4985
|
return {
|
|
@@ -5043,7 +5057,7 @@ var ApiFeatures = class {
|
|
|
5043
5057
|
}
|
|
5044
5058
|
};
|
|
5045
5059
|
|
|
5046
|
-
// src/http/responses/ApiResponse.ts
|
|
5060
|
+
// src/infrastructure/http/responses/ApiResponse.ts
|
|
5047
5061
|
var ApiResponse = class _ApiResponse {
|
|
5048
5062
|
static send(res, options) {
|
|
5049
5063
|
const {
|
|
@@ -5117,7 +5131,7 @@ var ApiResponse = class _ApiResponse {
|
|
|
5117
5131
|
}
|
|
5118
5132
|
};
|
|
5119
5133
|
|
|
5120
|
-
// src/http/controllers/CrudControllerFactory.ts
|
|
5134
|
+
// src/infrastructure/http/controllers/CrudControllerFactory.ts
|
|
5121
5135
|
var CrudControllerFactory = class {
|
|
5122
5136
|
static create(repository, options = {}) {
|
|
5123
5137
|
const resourceName = options.resourceName ?? "Resource";
|
|
@@ -5219,12 +5233,12 @@ var CrudControllerFactory = class {
|
|
|
5219
5233
|
}
|
|
5220
5234
|
};
|
|
5221
5235
|
|
|
5222
|
-
// src/http/middleware/AuthMiddleware.ts
|
|
5236
|
+
// src/infrastructure/http/middleware/AuthMiddleware.ts
|
|
5223
5237
|
var authMiddleware = (_req, _res, next) => {
|
|
5224
5238
|
next();
|
|
5225
5239
|
};
|
|
5226
5240
|
|
|
5227
|
-
// src/http/middleware/ErrorMiddleware.ts
|
|
5241
|
+
// src/infrastructure/http/middleware/ErrorMiddleware.ts
|
|
5228
5242
|
var handleCastError = (err) => new AppError(`Invalid ${err.path}: ${err.value}`, 400, {
|
|
5229
5243
|
code: "INVALID_ID"
|
|
5230
5244
|
});
|
|
@@ -5254,11 +5268,13 @@ var ErrorMiddleware = (isProduction = false) => (err, _req, res, _next) => {
|
|
|
5254
5268
|
if (err instanceof AppError) {
|
|
5255
5269
|
error = err;
|
|
5256
5270
|
} else if (err instanceof Error) {
|
|
5257
|
-
error = new AppError(err.message, 500
|
|
5258
|
-
|
|
5271
|
+
error = new AppError(err.message, 500, {
|
|
5272
|
+
isOperational: false
|
|
5273
|
+
});
|
|
5259
5274
|
} else {
|
|
5260
|
-
error = new AppError("Internal Server Error", 500
|
|
5261
|
-
|
|
5275
|
+
error = new AppError("Internal Server Error", 500, {
|
|
5276
|
+
isOperational: false
|
|
5277
|
+
});
|
|
5262
5278
|
}
|
|
5263
5279
|
if (err && err.name === "CastError") {
|
|
5264
5280
|
error = handleCastError(err);
|
|
@@ -5278,9 +5294,9 @@ var ErrorMiddleware = (isProduction = false) => (err, _req, res, _next) => {
|
|
|
5278
5294
|
error = handleJWTExpiredError();
|
|
5279
5295
|
}
|
|
5280
5296
|
if (!error.isOperational) {
|
|
5281
|
-
logger.
|
|
5297
|
+
logger.error("Programming error", err);
|
|
5282
5298
|
} else {
|
|
5283
|
-
logger.
|
|
5299
|
+
logger.error("Operational error", {
|
|
5284
5300
|
message: error.message
|
|
5285
5301
|
});
|
|
5286
5302
|
}
|
|
@@ -5308,7 +5324,7 @@ var ErrorMiddleware = (isProduction = false) => (err, _req, res, _next) => {
|
|
|
5308
5324
|
});
|
|
5309
5325
|
};
|
|
5310
5326
|
|
|
5311
|
-
// src/http/validation/Validator.ts
|
|
5327
|
+
// src/infrastructure/http/validation/Validator.ts
|
|
5312
5328
|
var isJoiSchema = (schema) => {
|
|
5313
5329
|
return typeof schema === "object" && schema !== null && "validate" in schema;
|
|
5314
5330
|
};
|
|
@@ -5316,7 +5332,7 @@ var isZodSchema = (schema) => {
|
|
|
5316
5332
|
return typeof schema === "object" && schema !== null && "safeParse" in schema;
|
|
5317
5333
|
};
|
|
5318
5334
|
|
|
5319
|
-
// src/http/validation/JoiValidator.ts
|
|
5335
|
+
// src/infrastructure/http/validation/JoiValidator.ts
|
|
5320
5336
|
var JoiValidator = class {
|
|
5321
5337
|
constructor(schema) {
|
|
5322
5338
|
this.schema = schema;
|
|
@@ -5344,7 +5360,7 @@ var JoiValidator = class {
|
|
|
5344
5360
|
}
|
|
5345
5361
|
};
|
|
5346
5362
|
|
|
5347
|
-
// src/http/validation/ZodValidator.ts
|
|
5363
|
+
// src/infrastructure/http/validation/ZodValidator.ts
|
|
5348
5364
|
var ZodValidator = class {
|
|
5349
5365
|
constructor(schema) {
|
|
5350
5366
|
this.schema = schema;
|
|
@@ -5369,7 +5385,7 @@ var ZodValidator = class {
|
|
|
5369
5385
|
}
|
|
5370
5386
|
};
|
|
5371
5387
|
|
|
5372
|
-
// src/http/middleware/ValidationMiddleware.ts
|
|
5388
|
+
// src/infrastructure/http/middleware/ValidationMiddleware.ts
|
|
5373
5389
|
var validate = (schema) => (req, _res, next) => {
|
|
5374
5390
|
let result;
|
|
5375
5391
|
if (isJoiSchema(schema)) {
|
|
@@ -5391,7 +5407,7 @@ var validate = (schema) => (req, _res, next) => {
|
|
|
5391
5407
|
next();
|
|
5392
5408
|
};
|
|
5393
5409
|
|
|
5394
|
-
// src/http/utils/PickFields.ts
|
|
5410
|
+
// src/infrastructure/http/utils/PickFields.ts
|
|
5395
5411
|
function pickFields(obj, fields, options = {}) {
|
|
5396
5412
|
const removeUndefined = options.removeUndefined ?? false;
|
|
5397
5413
|
const removeNull = options.removeNull ?? false;
|
|
@@ -5453,7 +5469,7 @@ var RequestContext = class {
|
|
|
5453
5469
|
}
|
|
5454
5470
|
};
|
|
5455
5471
|
|
|
5456
|
-
// src/networking/middleware/RequestContextMiddleware.ts
|
|
5472
|
+
// src/infrastructure/networking/middleware/RequestContextMiddleware.ts
|
|
5457
5473
|
function createRequestContextMiddleware(options = {}) {
|
|
5458
5474
|
const {
|
|
5459
5475
|
correlationHeaderName = "X-Correlation-Id",
|
|
@@ -5473,7 +5489,7 @@ function createRequestContextMiddleware(options = {}) {
|
|
|
5473
5489
|
};
|
|
5474
5490
|
}
|
|
5475
5491
|
|
|
5476
|
-
// src/networking/observability/TracingHeaders.ts
|
|
5492
|
+
// src/infrastructure/networking/observability/TracingHeaders.ts
|
|
5477
5493
|
var TracingHeaders = class {
|
|
5478
5494
|
static build() {
|
|
5479
5495
|
const headers = {};
|
|
@@ -5497,7 +5513,7 @@ var TracingHeaders = class {
|
|
|
5497
5513
|
}
|
|
5498
5514
|
};
|
|
5499
5515
|
|
|
5500
|
-
// src/networking/resilience/ExponentialBackoffRetryPolicy.ts
|
|
5516
|
+
// src/infrastructure/networking/resilience/ExponentialBackoffRetryPolicy.ts
|
|
5501
5517
|
var ExponentialBackoffRetryPolicy = class {
|
|
5502
5518
|
retries;
|
|
5503
5519
|
baseDelay;
|
|
@@ -5516,7 +5532,7 @@ var ExponentialBackoffRetryPolicy = class {
|
|
|
5516
5532
|
}
|
|
5517
5533
|
};
|
|
5518
5534
|
|
|
5519
|
-
// src/networking/resilience/FixedRetryPolicy.ts
|
|
5535
|
+
// src/infrastructure/networking/resilience/FixedRetryPolicy.ts
|
|
5520
5536
|
var FixedRetryPolicy = class {
|
|
5521
5537
|
retries;
|
|
5522
5538
|
delay;
|
|
@@ -5532,7 +5548,7 @@ var FixedRetryPolicy = class {
|
|
|
5532
5548
|
}
|
|
5533
5549
|
};
|
|
5534
5550
|
|
|
5535
|
-
// src/networking/security/BearerTokenStrategy.ts
|
|
5551
|
+
// src/infrastructure/networking/security/BearerTokenStrategy.ts
|
|
5536
5552
|
var BearerTokenStrategy = class {
|
|
5537
5553
|
constructor(tokenProvider) {
|
|
5538
5554
|
this.tokenProvider = tokenProvider;
|
|
@@ -5545,7 +5561,7 @@ var BearerTokenStrategy = class {
|
|
|
5545
5561
|
}
|
|
5546
5562
|
};
|
|
5547
5563
|
|
|
5548
|
-
// src/networking/security/StaticTokenProvider.ts
|
|
5564
|
+
// src/infrastructure/networking/security/StaticTokenProvider.ts
|
|
5549
5565
|
var StaticTokenProvider = class {
|
|
5550
5566
|
constructor(token) {
|
|
5551
5567
|
this.token = token;
|
|
@@ -5555,7 +5571,7 @@ var StaticTokenProvider = class {
|
|
|
5555
5571
|
}
|
|
5556
5572
|
};
|
|
5557
5573
|
|
|
5558
|
-
// src/networking/transport/HttpClient.ts
|
|
5574
|
+
// src/infrastructure/networking/transport/HttpClient.ts
|
|
5559
5575
|
var HttpClient = class {
|
|
5560
5576
|
baseUrl;
|
|
5561
5577
|
timeout;
|
|
@@ -5633,7 +5649,7 @@ var HttpClient = class {
|
|
|
5633
5649
|
lastError = error;
|
|
5634
5650
|
if (this.retryPolicy.shouldRetry(attempt, error)) {
|
|
5635
5651
|
const delay = this.retryPolicy.getDelay(attempt, error);
|
|
5636
|
-
logger.
|
|
5652
|
+
logger.warn(
|
|
5637
5653
|
`[${this.serviceName}] retry ${attempt + 1} after ${delay}ms`
|
|
5638
5654
|
);
|
|
5639
5655
|
await this.sleep(delay);
|
|
@@ -5644,7 +5660,7 @@ var HttpClient = class {
|
|
|
5644
5660
|
}
|
|
5645
5661
|
}
|
|
5646
5662
|
const correlationId = RequestContext.getCorrelationId();
|
|
5647
|
-
logger.
|
|
5663
|
+
logger.error(
|
|
5648
5664
|
`[${this.serviceName}]` + (correlationId ? ` [${correlationId}]` : "") + ` request failed`,
|
|
5649
5665
|
lastError
|
|
5650
5666
|
);
|
|
@@ -5655,7 +5671,7 @@ var HttpClient = class {
|
|
|
5655
5671
|
}
|
|
5656
5672
|
};
|
|
5657
5673
|
|
|
5658
|
-
// src/networking/services/ServiceClient.ts
|
|
5674
|
+
// src/infrastructure/networking/services/ServiceClient.ts
|
|
5659
5675
|
var ServiceClient = class extends HttpClient {
|
|
5660
5676
|
async getData(path2) {
|
|
5661
5677
|
const response = await super.get(path2);
|
|
@@ -5679,7 +5695,7 @@ var ServiceClient = class extends HttpClient {
|
|
|
5679
5695
|
}
|
|
5680
5696
|
};
|
|
5681
5697
|
|
|
5682
|
-
// src/networking/services/InternalServiceClient.ts
|
|
5698
|
+
// src/infrastructure/networking/services/InternalServiceClient.ts
|
|
5683
5699
|
var InternalServiceClient = class extends ServiceClient {
|
|
5684
5700
|
constructor(baseUrl, serviceToken, serviceName) {
|
|
5685
5701
|
super(baseUrl, {
|
|
@@ -6118,7 +6134,7 @@ var JWTService = class {
|
|
|
6118
6134
|
try {
|
|
6119
6135
|
return jwt__default.default.verify(token, this.accessSecret);
|
|
6120
6136
|
} catch (err) {
|
|
6121
|
-
logger.
|
|
6137
|
+
logger.error("Access token verification failed:", err.message);
|
|
6122
6138
|
return null;
|
|
6123
6139
|
}
|
|
6124
6140
|
}
|
|
@@ -6126,7 +6142,7 @@ var JWTService = class {
|
|
|
6126
6142
|
try {
|
|
6127
6143
|
return jwt__default.default.verify(token, this.refreshSecret);
|
|
6128
6144
|
} catch (err) {
|
|
6129
|
-
logger.
|
|
6145
|
+
logger.error("Refresh token verification failed:", err.message);
|
|
6130
6146
|
return null;
|
|
6131
6147
|
}
|
|
6132
6148
|
}
|
|
@@ -6288,7 +6304,6 @@ exports.AdjacencyList = AdjacencyList;
|
|
|
6288
6304
|
exports.AdjacencyMatrix = AdjacencyMatrix;
|
|
6289
6305
|
exports.ApiFeatures = ApiFeatures;
|
|
6290
6306
|
exports.ApiResponse = ApiResponse;
|
|
6291
|
-
exports.AppError = AppError;
|
|
6292
6307
|
exports.AsyncHandler = AsyncHandler;
|
|
6293
6308
|
exports.AzureBlobStorageService = AzureBlobStorageService;
|
|
6294
6309
|
exports.BPlusTree = BPlusTree;
|
|
@@ -6381,8 +6396,6 @@ exports.errorToString = errorToString;
|
|
|
6381
6396
|
exports.hours = hours;
|
|
6382
6397
|
exports.isJoiSchema = isJoiSchema;
|
|
6383
6398
|
exports.isZodSchema = isZodSchema;
|
|
6384
|
-
exports.loadEnv = loadEnv;
|
|
6385
|
-
exports.logger = logger;
|
|
6386
6399
|
exports.milliseconds = milliseconds;
|
|
6387
6400
|
exports.minutes = minutes;
|
|
6388
6401
|
exports.pickFields = pickFields;
|