@loomcore/api 0.0.11 → 0.0.13
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.
|
@@ -5,11 +5,13 @@ export declare class TestExpressApp {
|
|
|
5
5
|
private static mongoServer;
|
|
6
6
|
private static client;
|
|
7
7
|
private static db;
|
|
8
|
+
private static initPromise;
|
|
8
9
|
static init(): Promise<{
|
|
9
10
|
app: Application;
|
|
10
11
|
db: Db;
|
|
11
12
|
agent: any;
|
|
12
13
|
}>;
|
|
14
|
+
private static _performInit;
|
|
13
15
|
static setupErrorHandling(): Promise<void>;
|
|
14
16
|
static cleanup(): Promise<void>;
|
|
15
17
|
static clearCollections(): Promise<void>;
|
|
@@ -14,7 +14,15 @@ export class TestExpressApp {
|
|
|
14
14
|
static mongoServer;
|
|
15
15
|
static client;
|
|
16
16
|
static db;
|
|
17
|
+
static initPromise = null;
|
|
17
18
|
static async init() {
|
|
19
|
+
if (this.initPromise) {
|
|
20
|
+
return this.initPromise;
|
|
21
|
+
}
|
|
22
|
+
this.initPromise = this._performInit();
|
|
23
|
+
return this.initPromise;
|
|
24
|
+
}
|
|
25
|
+
static async _performInit() {
|
|
18
26
|
setBaseApiConfig({
|
|
19
27
|
env: 'test',
|
|
20
28
|
hostName: 'localhost',
|
|
@@ -45,7 +53,14 @@ export class TestExpressApp {
|
|
|
45
53
|
});
|
|
46
54
|
initializeTypeBox();
|
|
47
55
|
if (!this.db) {
|
|
48
|
-
this.mongoServer = await MongoMemoryServer.create(
|
|
56
|
+
this.mongoServer = await MongoMemoryServer.create({
|
|
57
|
+
instance: {
|
|
58
|
+
port: 0,
|
|
59
|
+
},
|
|
60
|
+
binary: {
|
|
61
|
+
downloadDir: process.env.HOME ? `${process.env.HOME}/.cache/mongodb-binaries` : undefined,
|
|
62
|
+
}
|
|
63
|
+
});
|
|
49
64
|
const uri = this.mongoServer.getUri();
|
|
50
65
|
this.client = await MongoClient.connect(uri);
|
|
51
66
|
this.db = this.client.db();
|
|
@@ -78,6 +93,11 @@ export class TestExpressApp {
|
|
|
78
93
|
if (this.mongoServer) {
|
|
79
94
|
await this.mongoServer.stop();
|
|
80
95
|
}
|
|
96
|
+
this.initPromise = null;
|
|
97
|
+
this.app = undefined;
|
|
98
|
+
this.db = undefined;
|
|
99
|
+
this.client = undefined;
|
|
100
|
+
this.mongoServer = undefined;
|
|
81
101
|
}
|
|
82
102
|
static async clearCollections() {
|
|
83
103
|
if (!this.db) {
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import { CustomError } from '@loomcore/common/errors';
|
|
2
2
|
import { apiUtils } from '../utils/index.js';
|
|
3
3
|
import { config } from '../config/base-api-config.js';
|
|
4
|
+
const SENSITIVE_FIELDS = [
|
|
5
|
+
'password',
|
|
6
|
+
'secret',
|
|
7
|
+
'ssn'
|
|
8
|
+
];
|
|
9
|
+
const sanitizeData = (data) => {
|
|
10
|
+
if (!data || typeof data !== 'object') {
|
|
11
|
+
return data;
|
|
12
|
+
}
|
|
13
|
+
if (Array.isArray(data)) {
|
|
14
|
+
return data.map(item => sanitizeData(item));
|
|
15
|
+
}
|
|
16
|
+
const sanitized = { ...data };
|
|
17
|
+
for (const key in sanitized) {
|
|
18
|
+
if (SENSITIVE_FIELDS.includes(key.toLowerCase())) {
|
|
19
|
+
sanitized[key] = '********';
|
|
20
|
+
}
|
|
21
|
+
else if (typeof sanitized[key] === 'object' && sanitized[key] !== null) {
|
|
22
|
+
sanitized[key] = sanitizeData(sanitized[key]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return sanitized;
|
|
26
|
+
};
|
|
4
27
|
export const errorHandler = (err, req, res, next) => {
|
|
5
28
|
if (config.debug?.showErrors || config.env !== 'test') {
|
|
6
29
|
console.error('API Error:', {
|
|
@@ -8,13 +31,13 @@ export const errorHandler = (err, req, res, next) => {
|
|
|
8
31
|
stack: err.stack,
|
|
9
32
|
path: req.path,
|
|
10
33
|
method: req.method,
|
|
11
|
-
body: req.body,
|
|
12
|
-
query: req.query,
|
|
13
|
-
params: req.params,
|
|
34
|
+
body: sanitizeData(req.body),
|
|
35
|
+
query: sanitizeData(req.query),
|
|
36
|
+
params: sanitizeData(req.params),
|
|
14
37
|
timestamp: new Date().toISOString(),
|
|
15
38
|
errorType: err.constructor.name,
|
|
16
39
|
isCustomError: err instanceof CustomError,
|
|
17
|
-
headers: req.headers
|
|
40
|
+
headers: sanitizeData(req.headers)
|
|
18
41
|
});
|
|
19
42
|
}
|
|
20
43
|
if (err instanceof CustomError) {
|
package/dist/utils/db.utils.js
CHANGED
|
@@ -152,10 +152,15 @@ function buildMongoMatchFromQueryOptions(queryOptions) {
|
|
|
152
152
|
for (const [key, value] of Object.entries(filters)) {
|
|
153
153
|
if (value) {
|
|
154
154
|
if (value.eq !== undefined) {
|
|
155
|
-
if (typeof value.eq === 'string'
|
|
156
|
-
&& key.endsWith('Id')
|
|
155
|
+
if (typeof value.eq === 'string'
|
|
156
|
+
&& key.endsWith('Id')
|
|
157
|
+
&& !PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key)
|
|
158
|
+
&& entityUtils.isValidObjectId(value.eq)) {
|
|
157
159
|
match[key] = new ObjectId(value.eq);
|
|
158
160
|
}
|
|
161
|
+
else if (typeof value.eq === 'string' && !isNaN(Number(value.eq))) {
|
|
162
|
+
match[key] = Number(value.eq);
|
|
163
|
+
}
|
|
159
164
|
else {
|
|
160
165
|
match[key] = value.eq;
|
|
161
166
|
}
|
|
@@ -170,7 +175,8 @@ function buildMongoMatchFromQueryOptions(queryOptions) {
|
|
|
170
175
|
}
|
|
171
176
|
}
|
|
172
177
|
else {
|
|
173
|
-
|
|
178
|
+
const convertedValues = value.in.map(val => typeof val === 'string' && !isNaN(Number(val)) ? Number(val) : val);
|
|
179
|
+
match[key] = { $in: convertedValues };
|
|
174
180
|
}
|
|
175
181
|
}
|
|
176
182
|
else if (value.gte !== undefined) {
|