@loomcore/api 0.0.10 → 0.0.12

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,36 @@
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
+ 'token',
7
+ 'apiKey',
8
+ 'secret',
9
+ 'credit_card',
10
+ 'creditCard',
11
+ 'ssn',
12
+ 'email',
13
+ 'phone',
14
+ 'address'
15
+ ];
16
+ const sanitizeData = (data) => {
17
+ if (!data || typeof data !== 'object') {
18
+ return data;
19
+ }
20
+ if (Array.isArray(data)) {
21
+ return data.map(item => sanitizeData(item));
22
+ }
23
+ const sanitized = { ...data };
24
+ for (const key in sanitized) {
25
+ if (SENSITIVE_FIELDS.includes(key.toLowerCase())) {
26
+ sanitized[key] = '********';
27
+ }
28
+ else if (typeof sanitized[key] === 'object' && sanitized[key] !== null) {
29
+ sanitized[key] = sanitizeData(sanitized[key]);
30
+ }
31
+ }
32
+ return sanitized;
33
+ };
4
34
  export const errorHandler = (err, req, res, next) => {
5
35
  if (config.debug?.showErrors || config.env !== 'test') {
6
36
  console.error('API Error:', {
@@ -8,13 +38,13 @@ export const errorHandler = (err, req, res, next) => {
8
38
  stack: err.stack,
9
39
  path: req.path,
10
40
  method: req.method,
11
- body: req.body,
12
- query: req.query,
13
- params: req.params,
41
+ body: sanitizeData(req.body),
42
+ query: sanitizeData(req.query),
43
+ params: sanitizeData(req.params),
14
44
  timestamp: new Date().toISOString(),
15
45
  errorType: err.constructor.name,
16
46
  isCustomError: err instanceof CustomError,
17
- headers: req.headers
47
+ headers: sanitizeData(req.headers)
18
48
  });
19
49
  }
20
50
  if (err instanceof CustomError) {
@@ -7,30 +7,23 @@ import { errorHandler } from "../middleware/error-handler.js";
7
7
  import { ensureUserContext } from '../middleware/ensure-user-context.js';
8
8
  function setupExpressApp(db, config, setupRoutes) {
9
9
  const app = express();
10
- console.log(`config: `, config);
11
- console.log(`about to register health endpoint`);
12
10
  app.use((req, res, next) => {
13
11
  if (req.path !== '/api/health' && process.env.NODE_ENV !== 'test') {
14
12
  console.log(`[${new Date().toLocaleString('en-US', { timeZone: 'America/Chicago' })}] INCOMING REQUEST: ${req.method} ${req.path}`);
15
13
  }
16
14
  next();
17
15
  });
18
- console.log(`registering third party middleware`);
19
16
  app.use(bodyParser.json());
20
17
  app.use(cookieParser());
21
18
  app.use(cors({
22
19
  origin: config.corsAllowedOrigins,
23
20
  credentials: true
24
21
  }));
25
- console.log(`about to register ensureUserContext`);
26
22
  app.use(ensureUserContext);
27
- console.log(`about to call setupRoutes`);
28
23
  setupRoutes(app, db, config);
29
- console.log(`about to register * middleware for notfound paths`);
30
24
  app.use(async (req, res) => {
31
25
  throw new NotFoundError(`Requested path, ${req.path}, Not Found`);
32
26
  });
33
- console.log(`about to register errorHandler middleware`);
34
27
  app.use(errorHandler);
35
28
  return app;
36
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcore/api",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "private": false,
5
5
  "description": "Loom Core Api - An opinionated Node.js api using Typescript, Express, and MongoDb",
6
6
  "scripts": {