nexus-backend 1.0.2 → 1.0.3
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/dist/index.d.mts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +100 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import NodeCache from 'node-cache';
|
|
2
3
|
|
|
3
4
|
interface SuccessResponse<T = any> {
|
|
4
5
|
success: true;
|
|
@@ -60,4 +61,25 @@ declare const errorHandler: [
|
|
|
60
61
|
(err: any, req: Request, res: Response, next: NextFunction) => void
|
|
61
62
|
];
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
type CacheValue = unknown;
|
|
65
|
+
type ComputeFn<T> = () => Promise<T> | T;
|
|
66
|
+
declare class Cache extends NodeCache {
|
|
67
|
+
private namespaces;
|
|
68
|
+
private tagMap;
|
|
69
|
+
constructor(options?: NodeCache.Options);
|
|
70
|
+
private getKey;
|
|
71
|
+
private removeKeyFromTags;
|
|
72
|
+
setItem(key: string, value: CacheValue, ttl?: number, namespace?: string, tags?: string[]): void;
|
|
73
|
+
getItem<T = unknown>(key: string, namespace?: string): T | undefined;
|
|
74
|
+
getOrSetItem<T>(key: string, computeFn: ComputeFn<T>, ttl?: number, namespace?: string, tags?: string[]): Promise<T>;
|
|
75
|
+
deleteItem(key: string, namespace?: string): number;
|
|
76
|
+
clearNamespace(namespace?: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* Delete all keys associated with a tag
|
|
79
|
+
*/
|
|
80
|
+
clearTag(tag: string): void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
declare const cacheMemory: Cache;
|
|
84
|
+
|
|
85
|
+
export { ApiError, BadRequestError, Cache, type ErrorResponse, ForbiddenError, type MongoConfig, NotFoundError, type SuccessResponse, UnauthorizedError, ValidationError, cacheMemory, connectMongoDb, errorHandler as errorMiddleware, errorResponse, requiredEnv, successResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import NodeCache from 'node-cache';
|
|
2
3
|
|
|
3
4
|
interface SuccessResponse<T = any> {
|
|
4
5
|
success: true;
|
|
@@ -60,4 +61,25 @@ declare const errorHandler: [
|
|
|
60
61
|
(err: any, req: Request, res: Response, next: NextFunction) => void
|
|
61
62
|
];
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
type CacheValue = unknown;
|
|
65
|
+
type ComputeFn<T> = () => Promise<T> | T;
|
|
66
|
+
declare class Cache extends NodeCache {
|
|
67
|
+
private namespaces;
|
|
68
|
+
private tagMap;
|
|
69
|
+
constructor(options?: NodeCache.Options);
|
|
70
|
+
private getKey;
|
|
71
|
+
private removeKeyFromTags;
|
|
72
|
+
setItem(key: string, value: CacheValue, ttl?: number, namespace?: string, tags?: string[]): void;
|
|
73
|
+
getItem<T = unknown>(key: string, namespace?: string): T | undefined;
|
|
74
|
+
getOrSetItem<T>(key: string, computeFn: ComputeFn<T>, ttl?: number, namespace?: string, tags?: string[]): Promise<T>;
|
|
75
|
+
deleteItem(key: string, namespace?: string): number;
|
|
76
|
+
clearNamespace(namespace?: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* Delete all keys associated with a tag
|
|
79
|
+
*/
|
|
80
|
+
clearTag(tag: string): void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
declare const cacheMemory: Cache;
|
|
84
|
+
|
|
85
|
+
export { ApiError, BadRequestError, Cache, type ErrorResponse, ForbiddenError, type MongoConfig, NotFoundError, type SuccessResponse, UnauthorizedError, ValidationError, cacheMemory, connectMongoDb, errorHandler as errorMiddleware, errorResponse, requiredEnv, successResponse };
|
package/dist/index.js
CHANGED
|
@@ -32,10 +32,12 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
ApiError: () => ApiError,
|
|
34
34
|
BadRequestError: () => BadRequestError,
|
|
35
|
+
Cache: () => Cache,
|
|
35
36
|
ForbiddenError: () => ForbiddenError,
|
|
36
37
|
NotFoundError: () => NotFoundError,
|
|
37
38
|
UnauthorizedError: () => UnauthorizedError,
|
|
38
39
|
ValidationError: () => ValidationError,
|
|
40
|
+
cacheMemory: () => cacheMemory_default,
|
|
39
41
|
connectMongoDb: () => connectMongoDb,
|
|
40
42
|
errorMiddleware: () => errorHandler_default,
|
|
41
43
|
errorResponse: () => errorResponse,
|
|
@@ -160,14 +162,114 @@ var globalErrorHandler = (err, req, res, next) => {
|
|
|
160
162
|
};
|
|
161
163
|
var errorHandler = [routeNotFoundHandler, globalErrorHandler];
|
|
162
164
|
var errorHandler_default = errorHandler;
|
|
165
|
+
|
|
166
|
+
// src/utils/cache.ts
|
|
167
|
+
var import_node_cache = __toESM(require("node-cache"));
|
|
168
|
+
var Cache = class extends import_node_cache.default {
|
|
169
|
+
constructor(options = {}) {
|
|
170
|
+
const defaults = {
|
|
171
|
+
stdTTL: 60,
|
|
172
|
+
checkperiod: 120
|
|
173
|
+
};
|
|
174
|
+
super({ ...defaults, ...options });
|
|
175
|
+
this.namespaces = /* @__PURE__ */ new Set();
|
|
176
|
+
this.tagMap = /* @__PURE__ */ new Map();
|
|
177
|
+
this.on("expired", (key, value) => {
|
|
178
|
+
console.log(`[Cache] Key expired: ${key} ->`, value);
|
|
179
|
+
this.removeKeyFromTags(key);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
getKey(key, namespace) {
|
|
183
|
+
return namespace ? `${namespace}:${key}` : key;
|
|
184
|
+
}
|
|
185
|
+
removeKeyFromTags(key) {
|
|
186
|
+
for (const [tag, keys] of this.tagMap.entries()) {
|
|
187
|
+
if (keys.has(key)) {
|
|
188
|
+
keys.delete(key);
|
|
189
|
+
if (keys.size === 0) {
|
|
190
|
+
this.tagMap.delete(tag);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
setItem(key, value, ttl = 60, namespace, tags = []) {
|
|
196
|
+
const fullKey = this.getKey(key, namespace);
|
|
197
|
+
if (namespace) {
|
|
198
|
+
this.namespaces.add(namespace);
|
|
199
|
+
}
|
|
200
|
+
const storedValue = typeof value === "string" ? value : JSON.stringify(value);
|
|
201
|
+
this.set(fullKey, storedValue, ttl);
|
|
202
|
+
for (const tag of tags) {
|
|
203
|
+
if (!this.tagMap.has(tag)) {
|
|
204
|
+
this.tagMap.set(tag, /* @__PURE__ */ new Set());
|
|
205
|
+
}
|
|
206
|
+
this.tagMap.get(tag).add(fullKey);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
getItem(key, namespace) {
|
|
210
|
+
const fullKey = this.getKey(key, namespace);
|
|
211
|
+
const value = this.get(fullKey);
|
|
212
|
+
if (value === void 0) return void 0;
|
|
213
|
+
try {
|
|
214
|
+
return JSON.parse(value);
|
|
215
|
+
} catch {
|
|
216
|
+
return value;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async getOrSetItem(key, computeFn, ttl, namespace, tags = []) {
|
|
220
|
+
let value = this.getItem(key, namespace);
|
|
221
|
+
if (value === void 0) {
|
|
222
|
+
value = await computeFn();
|
|
223
|
+
this.setItem(key, value, ttl, namespace, tags);
|
|
224
|
+
}
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
deleteItem(key, namespace) {
|
|
228
|
+
const fullKey = this.getKey(key, namespace);
|
|
229
|
+
this.removeKeyFromTags(fullKey);
|
|
230
|
+
return this.del(fullKey);
|
|
231
|
+
}
|
|
232
|
+
clearNamespace(namespace) {
|
|
233
|
+
if (!namespace) {
|
|
234
|
+
this.flushAll();
|
|
235
|
+
this.tagMap.clear();
|
|
236
|
+
console.log("[Cache] All keys cleared");
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
for (const key of this.keys()) {
|
|
240
|
+
if (key.startsWith(`${namespace}:`)) {
|
|
241
|
+
this.deleteItem(key);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
console.log(`[Cache] Namespace "${namespace}" cleared`);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Delete all keys associated with a tag
|
|
248
|
+
*/
|
|
249
|
+
clearTag(tag) {
|
|
250
|
+
const keys = this.tagMap.get(tag);
|
|
251
|
+
if (!keys) return;
|
|
252
|
+
for (const key of keys) {
|
|
253
|
+
this.del(key);
|
|
254
|
+
}
|
|
255
|
+
this.tagMap.delete(tag);
|
|
256
|
+
console.log(`[Cache] All keys with tag "${tag}" cleared`);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// src/utils/cacheMemory.ts
|
|
261
|
+
var cacheMemory = new Cache();
|
|
262
|
+
var cacheMemory_default = cacheMemory;
|
|
163
263
|
// Annotate the CommonJS export names for ESM import in node:
|
|
164
264
|
0 && (module.exports = {
|
|
165
265
|
ApiError,
|
|
166
266
|
BadRequestError,
|
|
267
|
+
Cache,
|
|
167
268
|
ForbiddenError,
|
|
168
269
|
NotFoundError,
|
|
169
270
|
UnauthorizedError,
|
|
170
271
|
ValidationError,
|
|
272
|
+
cacheMemory,
|
|
171
273
|
connectMongoDb,
|
|
172
274
|
errorMiddleware,
|
|
173
275
|
errorResponse,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/responses/successResponse.ts","../src/responses/errorResponse.ts","../src/utils/envManager.ts","../src/config/mongoConfig.ts","../src/errors/ApiError.ts","../src/errors/BadRequestError.ts","../src/errors/UnauthorisedError.ts","../src/errors/ForbiddenError.ts","../src/errors/NotFoundError.ts","../src/errors/ValidationError.ts","../src/handlers/errorHandler.ts"],"sourcesContent":["export { successResponse } from \"./responses/successResponse\";\nexport { errorResponse } from \"./responses/errorResponse\";\nexport { requiredEnv } from \"./utils/envManager\";\nexport { connectMongoDb } from \"./config/mongoConfig\";\nexport { default as ApiError } from \"./errors/ApiError\";\nexport { default as BadRequestError } from \"./errors/BadRequestError\";\nexport { default as UnauthorizedError } from \"./errors/UnauthorisedError\";\nexport { default as ForbiddenError } from \"./errors/ForbiddenError\";\nexport { default as NotFoundError } from \"./errors/NotFoundError\";\nexport { default as ValidationError } from \"./errors/ValidationError\";\nexport { default as errorMiddleware } from \"./handlers/errorHandler\";\n\nexport type { SuccessResponse, ErrorResponse } from \"./types/response.types\";\nexport { type MongoConfig } from \"./types/mongoConfig.types\";","import { SuccessResponse } from \"../types/response.types\";\n\nexport const successResponse = <T>(\n data: T,\n message?: string\n): SuccessResponse<T> => ({\n success: true,\n data,\n message,\n});","import { ErrorResponse } from \"../types/response.types\";\n\nexport const errorResponse = (\n message: string,\n errors?: any,\n stack?: string\n): ErrorResponse => ({\n success: false,\n message,\n errors,\n stack,\n});","export const requiredEnv = (value: string | undefined, key: string): string => {\n if (!value) {\n throw new Error(`Missing required environment variable: ${key}`);\n }\n return value;\n};","import mongoose from \"mongoose\";\n\nimport type { MongoConfig } from \"../types/mongoConfig.types\";\n\nexport const connectMongoDb = async (config: MongoConfig) => {\n const { subDomain, userName, password, cluster, dbName } = config;\n // Primary +srv URL\n const srvURL = `mongodb+srv://${userName}:${password}@${cluster.toLowerCase()}.${subDomain}.mongodb.net/${dbName}?retryWrites=true&w=majority&appName=${cluster.toLowerCase()}`;\n // Fallback standard mongodb:// URL (you need to adjust hostnames from Atlas)\n const fallbackURL = `mongodb://${userName}:${password}@ac-hkntio7-shard-00-00.${subDomain}.mongodb.net:27017,ac-hkntio7-shard-00-01.${subDomain}.mongodb.net:27017,ac-hkntio7-shard-00-02.${subDomain}.mongodb.net:27017/${dbName}?ssl=true&replicaSet=atlas-cji6jk-shard-0&authSource=admin&appName=${cluster}`;\n try {\n console.log(\"Trying primary +srv connection...\");\n await mongoose.connect(srvURL);\n console.log(\"Connected to MongoDB Atlas via +srv URL\");\n return true;\n } catch (err: any) {\n console.warn(\"+srv connection failed:\", err.message);\n console.log(\"Trying fallback standard connection...\");\n try {\n await mongoose.connect(fallbackURL);\n console.log(\"Connected to MongoDB Atlas via fallback URL\");\n return true;\n } catch (fallbackErr: any) {\n console.error(\"Fallback connection failed:\", fallbackErr.message);\n return false;\n }\n }\n};","export default class ApiError extends Error {\n statusCode: number;\n isOperational: boolean;\n errors?: any;\n\n constructor(\n message: string,\n statusCode = 500,\n errors?: any,\n isOperational = true\n ) {\n super(message);\n\n this.statusCode = statusCode;\n this.errors = errors;\n this.isOperational = isOperational;\n\n Error.captureStackTrace(this, this.constructor);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class BadRequestError extends ApiError {\n constructor(message = \"Bad Request\", errors?: any) {\n super(message, 400, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class UnauthorizedError extends ApiError {\n constructor(message = \"Unauthorized\", errors?: any) {\n super(message, 401, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class ForbiddenError extends ApiError {\n constructor(message = \"Forbidden\", errors?: any) {\n super(message, 403, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class NotFoundError extends ApiError {\n constructor(message = \"Resource Not Found\", errors?: any) {\n super(message, 404, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class ValidationError extends ApiError {\n constructor(message = \"Validation Failed\", errors?: any) {\n super(message, 422, errors);\n }\n}","// errorHandler.ts\nimport { Request, Response, NextFunction } from \"express\";\nimport ApiError from \"../errors/ApiError\";\nimport { errorResponse } from \"../responses/errorResponse\";\n\nconst routeNotFoundHandler = (req: Request, _: Response, next: NextFunction) => {\n next(new ApiError(`Route ${req.originalUrl} not found`, 404));\n};\n\nconst globalErrorHandler = (err: any, req: Request, res: Response, next: NextFunction) => {\n console.error(\"Error:\", err);\n let statusCode = 500;\n let message = \"Internal Server Error\";\n let errors = undefined;\n let stack = undefined;\n\n if (err instanceof ApiError) {\n statusCode = err.statusCode;\n message = err.message;\n errors = err.errors;\n }\n\n if (process.env.NODE_ENV === \"development\") {\n stack = err.stack;\n }\n\n return res.status(statusCode).json(errorResponse(message, errors, stack));\n};\n\n// Export as a tuple with explicit types so spread works correctly\nconst errorHandler: [\n (req: Request, res: Response, next: NextFunction) => void,\n (err: any, req: Request, res: Response, next: NextFunction) => void\n] = [routeNotFoundHandler, globalErrorHandler];\n\nexport default errorHandler;"],"mappings":"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","names":["mongoose"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/responses/successResponse.ts","../src/responses/errorResponse.ts","../src/utils/envManager.ts","../src/config/mongoConfig.ts","../src/errors/ApiError.ts","../src/errors/BadRequestError.ts","../src/errors/UnauthorisedError.ts","../src/errors/ForbiddenError.ts","../src/errors/NotFoundError.ts","../src/errors/ValidationError.ts","../src/handlers/errorHandler.ts","../src/utils/cache.ts","../src/utils/cacheMemory.ts"],"sourcesContent":["export { successResponse } from \"./responses/successResponse\";\nexport { errorResponse } from \"./responses/errorResponse\";\nexport { requiredEnv } from \"./utils/envManager\";\nexport { connectMongoDb } from \"./config/mongoConfig\";\nexport { default as ApiError } from \"./errors/ApiError\";\nexport { default as BadRequestError } from \"./errors/BadRequestError\";\nexport { default as UnauthorizedError } from \"./errors/UnauthorisedError\";\nexport { default as ForbiddenError } from \"./errors/ForbiddenError\";\nexport { default as NotFoundError } from \"./errors/NotFoundError\";\nexport { default as ValidationError } from \"./errors/ValidationError\";\nexport { default as errorMiddleware } from \"./handlers/errorHandler\";\nexport { Cache } from \"./utils/cache\";\nexport { default as cacheMemory } from \"./utils/cacheMemory\";\nexport type { SuccessResponse, ErrorResponse } from \"./types/response.types\";\nexport { type MongoConfig } from \"./types/mongoConfig.types\";\n","import { SuccessResponse } from \"../types/response.types\";\n\nexport const successResponse = <T>(\n data: T,\n message?: string\n): SuccessResponse<T> => ({\n success: true,\n data,\n message,\n});","import { ErrorResponse } from \"../types/response.types\";\n\nexport const errorResponse = (\n message: string,\n errors?: any,\n stack?: string\n): ErrorResponse => ({\n success: false,\n message,\n errors,\n stack,\n});","export const requiredEnv = (value: string | undefined, key: string): string => {\n if (!value) {\n throw new Error(`Missing required environment variable: ${key}`);\n }\n return value;\n};","import mongoose from \"mongoose\";\n\nimport type { MongoConfig } from \"../types/mongoConfig.types\";\n\nexport const connectMongoDb = async (config: MongoConfig) => {\n const { subDomain, userName, password, cluster, dbName } = config;\n // Primary +srv URL\n const srvURL = `mongodb+srv://${userName}:${password}@${cluster.toLowerCase()}.${subDomain}.mongodb.net/${dbName}?retryWrites=true&w=majority&appName=${cluster.toLowerCase()}`;\n // Fallback standard mongodb:// URL (you need to adjust hostnames from Atlas)\n const fallbackURL = `mongodb://${userName}:${password}@ac-hkntio7-shard-00-00.${subDomain}.mongodb.net:27017,ac-hkntio7-shard-00-01.${subDomain}.mongodb.net:27017,ac-hkntio7-shard-00-02.${subDomain}.mongodb.net:27017/${dbName}?ssl=true&replicaSet=atlas-cji6jk-shard-0&authSource=admin&appName=${cluster}`;\n try {\n console.log(\"Trying primary +srv connection...\");\n await mongoose.connect(srvURL);\n console.log(\"Connected to MongoDB Atlas via +srv URL\");\n return true;\n } catch (err: any) {\n console.warn(\"+srv connection failed:\", err.message);\n console.log(\"Trying fallback standard connection...\");\n try {\n await mongoose.connect(fallbackURL);\n console.log(\"Connected to MongoDB Atlas via fallback URL\");\n return true;\n } catch (fallbackErr: any) {\n console.error(\"Fallback connection failed:\", fallbackErr.message);\n return false;\n }\n }\n};","export default class ApiError extends Error {\n statusCode: number;\n isOperational: boolean;\n errors?: any;\n\n constructor(\n message: string,\n statusCode = 500,\n errors?: any,\n isOperational = true\n ) {\n super(message);\n\n this.statusCode = statusCode;\n this.errors = errors;\n this.isOperational = isOperational;\n\n Error.captureStackTrace(this, this.constructor);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class BadRequestError extends ApiError {\n constructor(message = \"Bad Request\", errors?: any) {\n super(message, 400, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class UnauthorizedError extends ApiError {\n constructor(message = \"Unauthorized\", errors?: any) {\n super(message, 401, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class ForbiddenError extends ApiError {\n constructor(message = \"Forbidden\", errors?: any) {\n super(message, 403, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class NotFoundError extends ApiError {\n constructor(message = \"Resource Not Found\", errors?: any) {\n super(message, 404, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class ValidationError extends ApiError {\n constructor(message = \"Validation Failed\", errors?: any) {\n super(message, 422, errors);\n }\n}","// errorHandler.ts\nimport { Request, Response, NextFunction } from \"express\";\nimport ApiError from \"../errors/ApiError\";\nimport { errorResponse } from \"../responses/errorResponse\";\n\nconst routeNotFoundHandler = (req: Request, _: Response, next: NextFunction) => {\n next(new ApiError(`Route ${req.originalUrl} not found`, 404));\n};\n\nconst globalErrorHandler = (err: any, req: Request, res: Response, next: NextFunction) => {\n console.error(\"Error:\", err);\n let statusCode = 500;\n let message = \"Internal Server Error\";\n let errors = undefined;\n let stack = undefined;\n\n if (err instanceof ApiError) {\n statusCode = err.statusCode;\n message = err.message;\n errors = err.errors;\n }\n\n if (process.env.NODE_ENV === \"development\") {\n stack = err.stack;\n }\n\n return res.status(statusCode).json(errorResponse(message, errors, stack));\n};\n\n// Export as a tuple with explicit types so spread works correctly\nconst errorHandler: [\n (req: Request, res: Response, next: NextFunction) => void,\n (err: any, req: Request, res: Response, next: NextFunction) => void\n] = [routeNotFoundHandler, globalErrorHandler];\n\nexport default errorHandler;","import NodeCache from \"node-cache\";\n\ntype CacheValue = unknown;\ntype ComputeFn<T> = () => Promise<T> | T;\n\nexport class Cache extends NodeCache {\n private namespaces: Set<string>;\n private tagMap: Map<string, Set<string>>;\n\n constructor(options: NodeCache.Options = {}) {\n const defaults: NodeCache.Options = {\n stdTTL: 60,\n checkperiod: 120,\n };\n\n super({ ...defaults, ...options });\n\n this.namespaces = new Set<string>();\n this.tagMap = new Map<string, Set<string>>();\n\n this.on(\"expired\", (key: string, value: unknown) => {\n console.log(`[Cache] Key expired: ${key} ->`, value);\n this.removeKeyFromTags(key);\n });\n }\n\n private getKey(key: string, namespace?: string): string {\n return namespace ? `${namespace}:${key}` : key;\n }\n\n private removeKeyFromTags(key: string): void {\n for (const [tag, keys] of this.tagMap.entries()) {\n if (keys.has(key)) {\n keys.delete(key);\n if (keys.size === 0) {\n this.tagMap.delete(tag);\n }\n }\n }\n }\n\n setItem(\n key: string,\n value: CacheValue,\n ttl: number =60,\n namespace?: string,\n tags: string[] = []\n ): void {\n const fullKey = this.getKey(key, namespace);\n\n if (namespace) {\n this.namespaces.add(namespace);\n }\n\n const storedValue =\n typeof value === \"string\" ? value : JSON.stringify(value);\n\n this.set(fullKey, storedValue, ttl);\n\n for (const tag of tags) {\n if (!this.tagMap.has(tag)) {\n this.tagMap.set(tag, new Set<string>());\n }\n this.tagMap.get(tag)!.add(fullKey);\n }\n }\n\n getItem<T = unknown>(key: string, namespace?: string): T | undefined {\n const fullKey = this.getKey(key, namespace);\n const value = this.get(fullKey);\n\n if (value === undefined) return undefined;\n\n try {\n return JSON.parse(value as string) as T;\n } catch {\n return value as T;\n }\n }\n\n async getOrSetItem<T>(\n key: string,\n computeFn: ComputeFn<T>,\n ttl?: number,\n namespace?: string,\n tags: string[] = []\n ): Promise<T> {\n let value = this.getItem<T>(key, namespace);\n\n if (value === undefined) {\n value = await computeFn();\n this.setItem(key, value, ttl, namespace, tags);\n }\n\n return value;\n }\n\n deleteItem(key: string, namespace?: string): number {\n const fullKey = this.getKey(key, namespace);\n this.removeKeyFromTags(fullKey);\n return this.del(fullKey);\n }\n\n clearNamespace(namespace?: string): void {\n if (!namespace) {\n this.flushAll();\n this.tagMap.clear();\n console.log(\"[Cache] All keys cleared\");\n return;\n }\n\n for (const key of this.keys()) {\n if (key.startsWith(`${namespace}:`)) {\n this.deleteItem(key);\n }\n }\n\n console.log(`[Cache] Namespace \"${namespace}\" cleared`);\n }\n\n /**\n * Delete all keys associated with a tag\n */\n clearTag(tag: string): void {\n const keys = this.tagMap.get(tag);\n if (!keys) return;\n\n for (const key of keys) {\n this.del(key);\n }\n\n this.tagMap.delete(tag);\n console.log(`[Cache] All keys with tag \"${tag}\" cleared`);\n }\n}\n","import { Cache } from \"./cache\";\n\nconst cacheMemory = new Cache();\n\nexport default cacheMemory;\n"],"mappings":"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","names":["mongoose","NodeCache"]}
|
package/dist/index.mjs
CHANGED
|
@@ -114,13 +114,113 @@ var globalErrorHandler = (err, req, res, next) => {
|
|
|
114
114
|
};
|
|
115
115
|
var errorHandler = [routeNotFoundHandler, globalErrorHandler];
|
|
116
116
|
var errorHandler_default = errorHandler;
|
|
117
|
+
|
|
118
|
+
// src/utils/cache.ts
|
|
119
|
+
import NodeCache from "node-cache";
|
|
120
|
+
var Cache = class extends NodeCache {
|
|
121
|
+
constructor(options = {}) {
|
|
122
|
+
const defaults = {
|
|
123
|
+
stdTTL: 60,
|
|
124
|
+
checkperiod: 120
|
|
125
|
+
};
|
|
126
|
+
super({ ...defaults, ...options });
|
|
127
|
+
this.namespaces = /* @__PURE__ */ new Set();
|
|
128
|
+
this.tagMap = /* @__PURE__ */ new Map();
|
|
129
|
+
this.on("expired", (key, value) => {
|
|
130
|
+
console.log(`[Cache] Key expired: ${key} ->`, value);
|
|
131
|
+
this.removeKeyFromTags(key);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
getKey(key, namespace) {
|
|
135
|
+
return namespace ? `${namespace}:${key}` : key;
|
|
136
|
+
}
|
|
137
|
+
removeKeyFromTags(key) {
|
|
138
|
+
for (const [tag, keys] of this.tagMap.entries()) {
|
|
139
|
+
if (keys.has(key)) {
|
|
140
|
+
keys.delete(key);
|
|
141
|
+
if (keys.size === 0) {
|
|
142
|
+
this.tagMap.delete(tag);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
setItem(key, value, ttl = 60, namespace, tags = []) {
|
|
148
|
+
const fullKey = this.getKey(key, namespace);
|
|
149
|
+
if (namespace) {
|
|
150
|
+
this.namespaces.add(namespace);
|
|
151
|
+
}
|
|
152
|
+
const storedValue = typeof value === "string" ? value : JSON.stringify(value);
|
|
153
|
+
this.set(fullKey, storedValue, ttl);
|
|
154
|
+
for (const tag of tags) {
|
|
155
|
+
if (!this.tagMap.has(tag)) {
|
|
156
|
+
this.tagMap.set(tag, /* @__PURE__ */ new Set());
|
|
157
|
+
}
|
|
158
|
+
this.tagMap.get(tag).add(fullKey);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
getItem(key, namespace) {
|
|
162
|
+
const fullKey = this.getKey(key, namespace);
|
|
163
|
+
const value = this.get(fullKey);
|
|
164
|
+
if (value === void 0) return void 0;
|
|
165
|
+
try {
|
|
166
|
+
return JSON.parse(value);
|
|
167
|
+
} catch {
|
|
168
|
+
return value;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async getOrSetItem(key, computeFn, ttl, namespace, tags = []) {
|
|
172
|
+
let value = this.getItem(key, namespace);
|
|
173
|
+
if (value === void 0) {
|
|
174
|
+
value = await computeFn();
|
|
175
|
+
this.setItem(key, value, ttl, namespace, tags);
|
|
176
|
+
}
|
|
177
|
+
return value;
|
|
178
|
+
}
|
|
179
|
+
deleteItem(key, namespace) {
|
|
180
|
+
const fullKey = this.getKey(key, namespace);
|
|
181
|
+
this.removeKeyFromTags(fullKey);
|
|
182
|
+
return this.del(fullKey);
|
|
183
|
+
}
|
|
184
|
+
clearNamespace(namespace) {
|
|
185
|
+
if (!namespace) {
|
|
186
|
+
this.flushAll();
|
|
187
|
+
this.tagMap.clear();
|
|
188
|
+
console.log("[Cache] All keys cleared");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
for (const key of this.keys()) {
|
|
192
|
+
if (key.startsWith(`${namespace}:`)) {
|
|
193
|
+
this.deleteItem(key);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
console.log(`[Cache] Namespace "${namespace}" cleared`);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Delete all keys associated with a tag
|
|
200
|
+
*/
|
|
201
|
+
clearTag(tag) {
|
|
202
|
+
const keys = this.tagMap.get(tag);
|
|
203
|
+
if (!keys) return;
|
|
204
|
+
for (const key of keys) {
|
|
205
|
+
this.del(key);
|
|
206
|
+
}
|
|
207
|
+
this.tagMap.delete(tag);
|
|
208
|
+
console.log(`[Cache] All keys with tag "${tag}" cleared`);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
// src/utils/cacheMemory.ts
|
|
213
|
+
var cacheMemory = new Cache();
|
|
214
|
+
var cacheMemory_default = cacheMemory;
|
|
117
215
|
export {
|
|
118
216
|
ApiError,
|
|
119
217
|
BadRequestError,
|
|
218
|
+
Cache,
|
|
120
219
|
ForbiddenError,
|
|
121
220
|
NotFoundError,
|
|
122
221
|
UnauthorizedError,
|
|
123
222
|
ValidationError,
|
|
223
|
+
cacheMemory_default as cacheMemory,
|
|
124
224
|
connectMongoDb,
|
|
125
225
|
errorHandler_default as errorMiddleware,
|
|
126
226
|
errorResponse,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/responses/successResponse.ts","../src/responses/errorResponse.ts","../src/utils/envManager.ts","../src/config/mongoConfig.ts","../src/errors/ApiError.ts","../src/errors/BadRequestError.ts","../src/errors/UnauthorisedError.ts","../src/errors/ForbiddenError.ts","../src/errors/NotFoundError.ts","../src/errors/ValidationError.ts","../src/handlers/errorHandler.ts"],"sourcesContent":["import { SuccessResponse } from \"../types/response.types\";\n\nexport const successResponse = <T>(\n data: T,\n message?: string\n): SuccessResponse<T> => ({\n success: true,\n data,\n message,\n});","import { ErrorResponse } from \"../types/response.types\";\n\nexport const errorResponse = (\n message: string,\n errors?: any,\n stack?: string\n): ErrorResponse => ({\n success: false,\n message,\n errors,\n stack,\n});","export const requiredEnv = (value: string | undefined, key: string): string => {\n if (!value) {\n throw new Error(`Missing required environment variable: ${key}`);\n }\n return value;\n};","import mongoose from \"mongoose\";\n\nimport type { MongoConfig } from \"../types/mongoConfig.types\";\n\nexport const connectMongoDb = async (config: MongoConfig) => {\n const { subDomain, userName, password, cluster, dbName } = config;\n // Primary +srv URL\n const srvURL = `mongodb+srv://${userName}:${password}@${cluster.toLowerCase()}.${subDomain}.mongodb.net/${dbName}?retryWrites=true&w=majority&appName=${cluster.toLowerCase()}`;\n // Fallback standard mongodb:// URL (you need to adjust hostnames from Atlas)\n const fallbackURL = `mongodb://${userName}:${password}@ac-hkntio7-shard-00-00.${subDomain}.mongodb.net:27017,ac-hkntio7-shard-00-01.${subDomain}.mongodb.net:27017,ac-hkntio7-shard-00-02.${subDomain}.mongodb.net:27017/${dbName}?ssl=true&replicaSet=atlas-cji6jk-shard-0&authSource=admin&appName=${cluster}`;\n try {\n console.log(\"Trying primary +srv connection...\");\n await mongoose.connect(srvURL);\n console.log(\"Connected to MongoDB Atlas via +srv URL\");\n return true;\n } catch (err: any) {\n console.warn(\"+srv connection failed:\", err.message);\n console.log(\"Trying fallback standard connection...\");\n try {\n await mongoose.connect(fallbackURL);\n console.log(\"Connected to MongoDB Atlas via fallback URL\");\n return true;\n } catch (fallbackErr: any) {\n console.error(\"Fallback connection failed:\", fallbackErr.message);\n return false;\n }\n }\n};","export default class ApiError extends Error {\n statusCode: number;\n isOperational: boolean;\n errors?: any;\n\n constructor(\n message: string,\n statusCode = 500,\n errors?: any,\n isOperational = true\n ) {\n super(message);\n\n this.statusCode = statusCode;\n this.errors = errors;\n this.isOperational = isOperational;\n\n Error.captureStackTrace(this, this.constructor);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class BadRequestError extends ApiError {\n constructor(message = \"Bad Request\", errors?: any) {\n super(message, 400, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class UnauthorizedError extends ApiError {\n constructor(message = \"Unauthorized\", errors?: any) {\n super(message, 401, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class ForbiddenError extends ApiError {\n constructor(message = \"Forbidden\", errors?: any) {\n super(message, 403, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class NotFoundError extends ApiError {\n constructor(message = \"Resource Not Found\", errors?: any) {\n super(message, 404, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class ValidationError extends ApiError {\n constructor(message = \"Validation Failed\", errors?: any) {\n super(message, 422, errors);\n }\n}","// errorHandler.ts\nimport { Request, Response, NextFunction } from \"express\";\nimport ApiError from \"../errors/ApiError\";\nimport { errorResponse } from \"../responses/errorResponse\";\n\nconst routeNotFoundHandler = (req: Request, _: Response, next: NextFunction) => {\n next(new ApiError(`Route ${req.originalUrl} not found`, 404));\n};\n\nconst globalErrorHandler = (err: any, req: Request, res: Response, next: NextFunction) => {\n console.error(\"Error:\", err);\n let statusCode = 500;\n let message = \"Internal Server Error\";\n let errors = undefined;\n let stack = undefined;\n\n if (err instanceof ApiError) {\n statusCode = err.statusCode;\n message = err.message;\n errors = err.errors;\n }\n\n if (process.env.NODE_ENV === \"development\") {\n stack = err.stack;\n }\n\n return res.status(statusCode).json(errorResponse(message, errors, stack));\n};\n\n// Export as a tuple with explicit types so spread works correctly\nconst errorHandler: [\n (req: Request, res: Response, next: NextFunction) => void,\n (err: any, req: Request, res: Response, next: NextFunction) => void\n] = [routeNotFoundHandler, globalErrorHandler];\n\nexport default errorHandler;"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/responses/successResponse.ts","../src/responses/errorResponse.ts","../src/utils/envManager.ts","../src/config/mongoConfig.ts","../src/errors/ApiError.ts","../src/errors/BadRequestError.ts","../src/errors/UnauthorisedError.ts","../src/errors/ForbiddenError.ts","../src/errors/NotFoundError.ts","../src/errors/ValidationError.ts","../src/handlers/errorHandler.ts","../src/utils/cache.ts","../src/utils/cacheMemory.ts"],"sourcesContent":["import { SuccessResponse } from \"../types/response.types\";\n\nexport const successResponse = <T>(\n data: T,\n message?: string\n): SuccessResponse<T> => ({\n success: true,\n data,\n message,\n});","import { ErrorResponse } from \"../types/response.types\";\n\nexport const errorResponse = (\n message: string,\n errors?: any,\n stack?: string\n): ErrorResponse => ({\n success: false,\n message,\n errors,\n stack,\n});","export const requiredEnv = (value: string | undefined, key: string): string => {\n if (!value) {\n throw new Error(`Missing required environment variable: ${key}`);\n }\n return value;\n};","import mongoose from \"mongoose\";\n\nimport type { MongoConfig } from \"../types/mongoConfig.types\";\n\nexport const connectMongoDb = async (config: MongoConfig) => {\n const { subDomain, userName, password, cluster, dbName } = config;\n // Primary +srv URL\n const srvURL = `mongodb+srv://${userName}:${password}@${cluster.toLowerCase()}.${subDomain}.mongodb.net/${dbName}?retryWrites=true&w=majority&appName=${cluster.toLowerCase()}`;\n // Fallback standard mongodb:// URL (you need to adjust hostnames from Atlas)\n const fallbackURL = `mongodb://${userName}:${password}@ac-hkntio7-shard-00-00.${subDomain}.mongodb.net:27017,ac-hkntio7-shard-00-01.${subDomain}.mongodb.net:27017,ac-hkntio7-shard-00-02.${subDomain}.mongodb.net:27017/${dbName}?ssl=true&replicaSet=atlas-cji6jk-shard-0&authSource=admin&appName=${cluster}`;\n try {\n console.log(\"Trying primary +srv connection...\");\n await mongoose.connect(srvURL);\n console.log(\"Connected to MongoDB Atlas via +srv URL\");\n return true;\n } catch (err: any) {\n console.warn(\"+srv connection failed:\", err.message);\n console.log(\"Trying fallback standard connection...\");\n try {\n await mongoose.connect(fallbackURL);\n console.log(\"Connected to MongoDB Atlas via fallback URL\");\n return true;\n } catch (fallbackErr: any) {\n console.error(\"Fallback connection failed:\", fallbackErr.message);\n return false;\n }\n }\n};","export default class ApiError extends Error {\n statusCode: number;\n isOperational: boolean;\n errors?: any;\n\n constructor(\n message: string,\n statusCode = 500,\n errors?: any,\n isOperational = true\n ) {\n super(message);\n\n this.statusCode = statusCode;\n this.errors = errors;\n this.isOperational = isOperational;\n\n Error.captureStackTrace(this, this.constructor);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class BadRequestError extends ApiError {\n constructor(message = \"Bad Request\", errors?: any) {\n super(message, 400, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class UnauthorizedError extends ApiError {\n constructor(message = \"Unauthorized\", errors?: any) {\n super(message, 401, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class ForbiddenError extends ApiError {\n constructor(message = \"Forbidden\", errors?: any) {\n super(message, 403, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class NotFoundError extends ApiError {\n constructor(message = \"Resource Not Found\", errors?: any) {\n super(message, 404, errors);\n }\n}","import ApiError from \"./ApiError\";\n\nexport default class ValidationError extends ApiError {\n constructor(message = \"Validation Failed\", errors?: any) {\n super(message, 422, errors);\n }\n}","// errorHandler.ts\nimport { Request, Response, NextFunction } from \"express\";\nimport ApiError from \"../errors/ApiError\";\nimport { errorResponse } from \"../responses/errorResponse\";\n\nconst routeNotFoundHandler = (req: Request, _: Response, next: NextFunction) => {\n next(new ApiError(`Route ${req.originalUrl} not found`, 404));\n};\n\nconst globalErrorHandler = (err: any, req: Request, res: Response, next: NextFunction) => {\n console.error(\"Error:\", err);\n let statusCode = 500;\n let message = \"Internal Server Error\";\n let errors = undefined;\n let stack = undefined;\n\n if (err instanceof ApiError) {\n statusCode = err.statusCode;\n message = err.message;\n errors = err.errors;\n }\n\n if (process.env.NODE_ENV === \"development\") {\n stack = err.stack;\n }\n\n return res.status(statusCode).json(errorResponse(message, errors, stack));\n};\n\n// Export as a tuple with explicit types so spread works correctly\nconst errorHandler: [\n (req: Request, res: Response, next: NextFunction) => void,\n (err: any, req: Request, res: Response, next: NextFunction) => void\n] = [routeNotFoundHandler, globalErrorHandler];\n\nexport default errorHandler;","import NodeCache from \"node-cache\";\n\ntype CacheValue = unknown;\ntype ComputeFn<T> = () => Promise<T> | T;\n\nexport class Cache extends NodeCache {\n private namespaces: Set<string>;\n private tagMap: Map<string, Set<string>>;\n\n constructor(options: NodeCache.Options = {}) {\n const defaults: NodeCache.Options = {\n stdTTL: 60,\n checkperiod: 120,\n };\n\n super({ ...defaults, ...options });\n\n this.namespaces = new Set<string>();\n this.tagMap = new Map<string, Set<string>>();\n\n this.on(\"expired\", (key: string, value: unknown) => {\n console.log(`[Cache] Key expired: ${key} ->`, value);\n this.removeKeyFromTags(key);\n });\n }\n\n private getKey(key: string, namespace?: string): string {\n return namespace ? `${namespace}:${key}` : key;\n }\n\n private removeKeyFromTags(key: string): void {\n for (const [tag, keys] of this.tagMap.entries()) {\n if (keys.has(key)) {\n keys.delete(key);\n if (keys.size === 0) {\n this.tagMap.delete(tag);\n }\n }\n }\n }\n\n setItem(\n key: string,\n value: CacheValue,\n ttl: number =60,\n namespace?: string,\n tags: string[] = []\n ): void {\n const fullKey = this.getKey(key, namespace);\n\n if (namespace) {\n this.namespaces.add(namespace);\n }\n\n const storedValue =\n typeof value === \"string\" ? value : JSON.stringify(value);\n\n this.set(fullKey, storedValue, ttl);\n\n for (const tag of tags) {\n if (!this.tagMap.has(tag)) {\n this.tagMap.set(tag, new Set<string>());\n }\n this.tagMap.get(tag)!.add(fullKey);\n }\n }\n\n getItem<T = unknown>(key: string, namespace?: string): T | undefined {\n const fullKey = this.getKey(key, namespace);\n const value = this.get(fullKey);\n\n if (value === undefined) return undefined;\n\n try {\n return JSON.parse(value as string) as T;\n } catch {\n return value as T;\n }\n }\n\n async getOrSetItem<T>(\n key: string,\n computeFn: ComputeFn<T>,\n ttl?: number,\n namespace?: string,\n tags: string[] = []\n ): Promise<T> {\n let value = this.getItem<T>(key, namespace);\n\n if (value === undefined) {\n value = await computeFn();\n this.setItem(key, value, ttl, namespace, tags);\n }\n\n return value;\n }\n\n deleteItem(key: string, namespace?: string): number {\n const fullKey = this.getKey(key, namespace);\n this.removeKeyFromTags(fullKey);\n return this.del(fullKey);\n }\n\n clearNamespace(namespace?: string): void {\n if (!namespace) {\n this.flushAll();\n this.tagMap.clear();\n console.log(\"[Cache] All keys cleared\");\n return;\n }\n\n for (const key of this.keys()) {\n if (key.startsWith(`${namespace}:`)) {\n this.deleteItem(key);\n }\n }\n\n console.log(`[Cache] Namespace \"${namespace}\" cleared`);\n }\n\n /**\n * Delete all keys associated with a tag\n */\n clearTag(tag: string): void {\n const keys = this.tagMap.get(tag);\n if (!keys) return;\n\n for (const key of keys) {\n this.del(key);\n }\n\n this.tagMap.delete(tag);\n console.log(`[Cache] All keys with tag \"${tag}\" cleared`);\n }\n}\n","import { Cache } from \"./cache\";\n\nconst cacheMemory = new Cache();\n\nexport default cacheMemory;\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexus-backend",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Backend utility library for Express.js",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"helmet": "^8.1.0",
|
|
20
20
|
"mongoose": "^9.6.2",
|
|
21
21
|
"morgan": "^1.10.1",
|
|
22
|
-
"socket.io": "^4.8.3"
|
|
22
|
+
"socket.io": "^4.8.3",
|
|
23
|
+
"node-cache": "5.1.2"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@types/cookie-parser": "^1.4.10",
|