abhijanb 0.1.2 → 0.1.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.
Files changed (51) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +4 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/lib/hash.d.ts +11 -0
  6. package/dist/lib/hash.d.ts.map +1 -0
  7. package/dist/lib/hash.js +25 -0
  8. package/dist/lib/hash.js.map +1 -0
  9. package/dist/lib/index.d.ts +15 -0
  10. package/dist/lib/index.d.ts.map +1 -0
  11. package/dist/lib/index.js +13 -0
  12. package/dist/lib/index.js.map +1 -0
  13. package/{lib/rateLimiter.ts → dist/lib/rateLimiter.d.ts} +2 -9
  14. package/dist/lib/rateLimiter.d.ts.map +1 -0
  15. package/dist/lib/rateLimiter.js +19 -0
  16. package/dist/lib/rateLimiter.js.map +1 -0
  17. package/dist/lib/security.d.ts +23 -0
  18. package/dist/lib/security.d.ts.map +1 -0
  19. package/dist/lib/security.js +29 -0
  20. package/dist/lib/security.js.map +1 -0
  21. package/dist/lib/socket.d.ts +22 -0
  22. package/dist/lib/socket.d.ts.map +1 -0
  23. package/dist/lib/socket.js +44 -0
  24. package/dist/lib/socket.js.map +1 -0
  25. package/dist/util/asyncHandler.d.ts +7 -0
  26. package/dist/util/asyncHandler.d.ts.map +1 -0
  27. package/dist/util/asyncHandler.js +10 -0
  28. package/dist/util/asyncHandler.js.map +1 -0
  29. package/dist/util/index.d.ts +13 -0
  30. package/dist/util/index.d.ts.map +1 -0
  31. package/dist/util/index.js +11 -0
  32. package/dist/util/index.js.map +1 -0
  33. package/dist/util/response.d.ts +91 -0
  34. package/dist/util/response.d.ts.map +1 -0
  35. package/dist/util/response.js +92 -0
  36. package/dist/util/response.js.map +1 -0
  37. package/dist/util/validate.d.ts +19 -0
  38. package/dist/util/validate.d.ts.map +1 -0
  39. package/dist/util/validate.js +16 -0
  40. package/dist/util/validate.js.map +1 -0
  41. package/package.json +43 -12
  42. package/a/README.md +0 -15
  43. package/a/index.ts +0 -26
  44. package/a/package.json +0 -19
  45. package/index.ts +0 -3
  46. package/lib/auth.ts +0 -71
  47. package/lib/index.ts +0 -20
  48. package/lib/socket.ts +0 -17
  49. package/util/index.ts +0 -25
  50. package/util/response.ts +0 -116
  51. package/util/validate.ts +0 -27
@@ -0,0 +1,4 @@
1
+ /** Main entry point — re-exports everything from util/ and lib/ */
2
+ export * from "./util/index.js";
3
+ export * from "./lib/index.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ /** Main entry point — re-exports everything from util/ and lib/ */
2
+ export * from "./util/index.js";
3
+ export * from "./lib/index.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import bcrypt from "bcryptjs";
2
+ /** Hash a password with bcryptjs (cost 10 by default) */
3
+ export declare function hashPassword(password: string, rounds?: number): Promise<string>;
4
+ /** Hash synchronously */
5
+ export declare function hashPasswordSync(password: string, rounds?: number): string;
6
+ /** Compare plain password vs hash */
7
+ export declare function comparePassword(password: string, hash: string): Promise<boolean>;
8
+ /** Compare synchronously */
9
+ export declare function comparePasswordSync(password: string, hash: string): boolean;
10
+ export { bcrypt };
11
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../lib/hash.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,yDAAyD;AACzD,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAIjF;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM,CAItE;AAED,qCAAqC;AACrC,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEtF;AAED,4BAA4B;AAC5B,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3E;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import bcrypt from "bcryptjs";
2
+ /** Hash a password with bcryptjs (cost 10 by default) */
3
+ export async function hashPassword(password, rounds = 10) {
4
+ if (!password || password.length < 1)
5
+ throw new Error("password required");
6
+ const salt = await bcrypt.genSalt(rounds);
7
+ return bcrypt.hash(password, salt);
8
+ }
9
+ /** Hash synchronously */
10
+ export function hashPasswordSync(password, rounds = 10) {
11
+ if (!password || password.length < 1)
12
+ throw new Error("password required");
13
+ const salt = bcrypt.genSaltSync(rounds);
14
+ return bcrypt.hashSync(password, salt);
15
+ }
16
+ /** Compare plain password vs hash */
17
+ export async function comparePassword(password, hash) {
18
+ return bcrypt.compare(password, hash);
19
+ }
20
+ /** Compare synchronously */
21
+ export function comparePasswordSync(password, hash) {
22
+ return bcrypt.compareSync(password, hash);
23
+ }
24
+ export { bcrypt };
25
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../lib/hash.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,MAAM,GAAG,EAAE;IAC9D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,MAAM,GAAG,EAAE;IAC5D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,IAAY;IAClE,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,IAAY;IAChE,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ /** Start Socket.IO on an Express app: `startSocket(app)` → returns { server, io, socket } */
2
+ export { startSocket, io, socket } from "./socket.js";
3
+ /** Socket type — for typing event handlers */
4
+ export type { Socket } from "./socket.js";
5
+ /** Rate limiter factory: `app.use(limiter(5, 1000))` = 5min window, 1000 req/IP */
6
+ export { limiter } from "./rateLimiter.js";
7
+ /** Factory — create custom rate limiters: `rateLimit({ windowMs: 60000, max: 20 })` */
8
+ export { rateLimit } from "./rateLimiter.js";
9
+ /** Security & middleware: helmet, cors, compression, morgan, cookie-parser */
10
+ export { securityMiddleware, corsMiddleware, compressionMiddleware, cookieMiddleware, loggerMiddleware, helmet, cors, compression, morgan, cookieParser, } from "./security.js";
11
+ /** Password hashing via bcryptjs */
12
+ export { hashPassword, hashPasswordSync, comparePassword, comparePasswordSync, bcrypt } from "./hash.js";
13
+ /** Socket helpers */
14
+ export { getIO, getSocket } from "./socket.js";
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,8CAA8C;AAC9C,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,mFAAmF;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,uFAAuF;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,8EAA8E;AAC9E,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,MAAM,EACN,IAAI,EACJ,WAAW,EACX,MAAM,EACN,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,oCAAoC;AACpC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEzG,qBAAqB;AACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Start Socket.IO on an Express app: `startSocket(app)` → returns { server, io, socket } */
2
+ export { startSocket, io, socket } from "./socket.js";
3
+ /** Rate limiter factory: `app.use(limiter(5, 1000))` = 5min window, 1000 req/IP */
4
+ export { limiter } from "./rateLimiter.js";
5
+ /** Factory — create custom rate limiters: `rateLimit({ windowMs: 60000, max: 20 })` */
6
+ export { rateLimit } from "./rateLimiter.js";
7
+ /** Security & middleware: helmet, cors, compression, morgan, cookie-parser */
8
+ export { securityMiddleware, corsMiddleware, compressionMiddleware, cookieMiddleware, loggerMiddleware, helmet, cors, compression, morgan, cookieParser, } from "./security.js";
9
+ /** Password hashing via bcryptjs */
10
+ export { hashPassword, hashPasswordSync, comparePassword, comparePasswordSync, bcrypt } from "./hash.js";
11
+ /** Socket helpers */
12
+ export { getIO, getSocket } from "./socket.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAItD,mFAAmF;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,uFAAuF;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,8EAA8E;AAC9E,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,MAAM,EACN,IAAI,EACJ,WAAW,EACX,MAAM,EACN,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,oCAAoC;AACpC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEzG,qBAAqB;AACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -1,14 +1,7 @@
1
1
  import rateLimit from "express-rate-limit";
2
-
3
2
  /** Factory — create a rate limiter: `app.use(limiter(5, 1000))` = 5min window, 1000 req/IP */
4
- const limiter = (minutes: number = 5, max: number = 100) =>
5
- rateLimit({
6
- windowMs: minutes * 60 * 1000,
7
- max,
8
- standardHeaders: true,
9
- legacyHeaders: false,
10
- });
11
-
3
+ declare const limiter: (minutes?: number, max?: number) => import("express-rate-limit").RateLimitRequestHandler;
12
4
  export { limiter };
13
5
  /** Low-level factory — create rate limiters with full config object */
14
6
  export { rateLimit };
7
+ //# sourceMappingURL=rateLimiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimiter.d.ts","sourceRoot":"","sources":["../../lib/rateLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAE3C,8FAA8F;AAC9F,QAAA,MAAM,OAAO,GAAI,UAAS,MAAU,EAAE,MAAK,MAAY,yDAUtD,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,uEAAuE;AACvE,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ import rateLimit from "express-rate-limit";
2
+ /** Factory — create a rate limiter: `app.use(limiter(5, 1000))` = 5min window, 1000 req/IP */
3
+ const limiter = (minutes = 5, max = 100) => {
4
+ if (!Number.isFinite(minutes) || minutes <= 0)
5
+ throw new RangeError("limiter: minutes must be > 0");
6
+ if (!Number.isFinite(max) || max <= 0)
7
+ throw new RangeError("limiter: max must be > 0");
8
+ return rateLimit({
9
+ windowMs: minutes * 60 * 1000,
10
+ max,
11
+ standardHeaders: true,
12
+ legacyHeaders: false,
13
+ message: { success: false, error: { code: "RATE_LIMITED", message: "Too many requests" } },
14
+ });
15
+ };
16
+ export { limiter };
17
+ /** Low-level factory — create rate limiters with full config object */
18
+ export { rateLimit };
19
+ //# sourceMappingURL=rateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../lib/rateLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAE3C,8FAA8F;AAC9F,MAAM,OAAO,GAAG,CAAC,UAAkB,CAAC,EAAE,MAAc,GAAG,EAAE,EAAE;IACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,8BAA8B,CAAC,CAAC;IACpG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,0BAA0B,CAAC,CAAC;IACxF,OAAO,SAAS,CAAC;QACf,QAAQ,EAAE,OAAO,GAAG,EAAE,GAAG,IAAI;QAC7B,GAAG;QACH,eAAe,EAAE,IAAI;QACrB,aAAa,EAAE,KAAK;QACpB,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,mBAAmB,EAAE,EAAE;KAC3F,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,uEAAuE;AACvE,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,23 @@
1
+ import helmet from "helmet";
2
+ import cors from "cors";
3
+ import compression from "compression";
4
+ import morgan from "morgan";
5
+ import cookieParser from "cookie-parser";
6
+ import type { CorsOptions } from "cors";
7
+ import type { HelmetOptions } from "helmet";
8
+ /** Helmet security headers with sane defaults */
9
+ export declare function securityMiddleware(options?: HelmetOptions): (req: import("http").IncomingMessage, res: import("http").ServerResponse, next: (err?: unknown) => void) => void;
10
+ /** CORS middleware — defaults to CORS_ORIGIN env or true (all origins) */
11
+ export declare function corsMiddleware(options?: CorsOptions): (req: cors.CorsRequest, res: {
12
+ statusCode?: number | undefined;
13
+ setHeader(key: string, value: string): any;
14
+ end(): any;
15
+ }, next: (err?: any) => any) => void;
16
+ /** Compression (gzip) */
17
+ export declare function compressionMiddleware(): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
18
+ /** Cookie parser — uses COOKIE_SECRET env if set */
19
+ export declare function cookieMiddleware(secret?: string): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
20
+ /** HTTP logger — dev uses 'dev', prod uses 'combined' */
21
+ export declare function loggerMiddleware(format?: string): (req: import("http").IncomingMessage, res: import("http").ServerResponse<import("http").IncomingMessage>, callback: (err?: Error) => void) => void;
22
+ export { helmet, cors, compression, morgan, cookieParser };
23
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../lib/security.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,WAAW,MAAM,aAAa,CAAC;AACtC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,iDAAiD;AACjD,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,aAAa,uFA2Bo3H,CAAC,4BAzB96H;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,WAAW;cAsB4H,CAAC;;;aAAmH,CAAC,uBAnBpS;AAED,yBAAyB;AACzB,wBAAgB,qBAAqB,iJAEpC;AAED,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,gJAE/C;AAED,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,2HAxBzC,CAAC,0BA2BP;AAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,29 @@
1
+ import helmet from "helmet";
2
+ import cors from "cors";
3
+ import compression from "compression";
4
+ import morgan from "morgan";
5
+ import cookieParser from "cookie-parser";
6
+ /** Helmet security headers with sane defaults */
7
+ export function securityMiddleware(options) {
8
+ return helmet(options);
9
+ }
10
+ /** CORS middleware — defaults to CORS_ORIGIN env or true (all origins) */
11
+ export function corsMiddleware(options) {
12
+ const origin = options?.origin ?? (process.env.CORS_ORIGIN?.split(",").map((s) => s.trim()) || true);
13
+ return cors({ origin: origin, credentials: true, ...options });
14
+ }
15
+ /** Compression (gzip) */
16
+ export function compressionMiddleware() {
17
+ return compression();
18
+ }
19
+ /** Cookie parser — uses COOKIE_SECRET env if set */
20
+ export function cookieMiddleware(secret) {
21
+ return cookieParser(secret || process.env.COOKIE_SECRET);
22
+ }
23
+ /** HTTP logger — dev uses 'dev', prod uses 'combined' */
24
+ export function loggerMiddleware(format) {
25
+ const fmt = format || (process.env.NODE_ENV === "production" ? "combined" : "dev");
26
+ return morgan(fmt);
27
+ }
28
+ export { helmet, cors, compression, morgan, cookieParser };
29
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../lib/security.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,WAAW,MAAM,aAAa,CAAC;AACtC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,YAAY,MAAM,eAAe,CAAC;AAIzC,iDAAiD;AACjD,MAAM,UAAU,kBAAkB,CAAC,OAAuB;IACxD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,OAAqB;IAClD,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC;IACrG,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,MAAa,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,qBAAqB;IACnC,OAAO,WAAW,EAAE,CAAC;AACvB,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,gBAAgB,CAAC,MAAe;IAC9C,OAAO,YAAY,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC3D,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,gBAAgB,CAAC,MAAe;IAC9C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnF,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,22 @@
1
+ import http from "http";
2
+ import { Server, type ServerOptions } from "socket.io";
3
+ import type { Express } from "express";
4
+ declare let io: Server | undefined;
5
+ declare let socket: Server | undefined;
6
+ /** Get initialized Socket.IO server — throws if startSocket() not called */
7
+ export declare function getIO(): Server;
8
+ /** Get initialized socket alias — throws if not initialized */
9
+ export declare function getSocket(): Server;
10
+ /**
11
+ * Start Socket.IO on an Express app
12
+ * @param app Express app
13
+ * @param opts Optional Socket.IO ServerOptions (cors merged with env)
14
+ */
15
+ export declare function startSocket(app: Express, opts?: Partial<ServerOptions>): {
16
+ server: http.Server;
17
+ io: Server;
18
+ socket: Server;
19
+ };
20
+ export { io, socket };
21
+ export type { Socket } from "socket.io";
22
+ //# sourceMappingURL=socket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../lib/socket.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,QAAA,IAAI,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;AAC3B,QAAA,IAAI,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;AAG/B,4EAA4E;AAC5E,wBAAgB,KAAK,IAAI,MAAM,CAG9B;AAED,+DAA+D;AAC/D,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAuBrD;AAED,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,44 @@
1
+ import http from "http";
2
+ import { Server } from "socket.io";
3
+ let io;
4
+ let socket;
5
+ let serverRef;
6
+ /** Get initialized Socket.IO server — throws if startSocket() not called */
7
+ export function getIO() {
8
+ if (!io)
9
+ throw new Error("Socket.IO not initialized. Call startSocket(app) first");
10
+ return io;
11
+ }
12
+ /** Get initialized socket alias — throws if not initialized */
13
+ export function getSocket() {
14
+ return getIO();
15
+ }
16
+ /**
17
+ * Start Socket.IO on an Express app
18
+ * @param app Express app
19
+ * @param opts Optional Socket.IO ServerOptions (cors merged with env)
20
+ */
21
+ export function startSocket(app, opts) {
22
+ if (io && serverRef) {
23
+ console.warn("[abhijanb] startSocket() called twice — returning existing instance");
24
+ return { server: serverRef, io, socket: io };
25
+ }
26
+ const server = http.createServer(app);
27
+ const corsOrigin = process.env.CORS_ORIGIN?.split(",").map((s) => s.trim()) || true;
28
+ io = new Server(server, {
29
+ cors: {
30
+ origin: corsOrigin,
31
+ credentials: true,
32
+ },
33
+ maxHttpBufferSize: 1e6,
34
+ ...opts,
35
+ });
36
+ socket = io;
37
+ serverRef = server;
38
+ server.on("error", (err) => {
39
+ console.error("[abhijanb] HTTP server error:", err);
40
+ });
41
+ return { server, io, socket };
42
+ }
43
+ export { io, socket };
44
+ //# sourceMappingURL=socket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket.js","sourceRoot":"","sources":["../../lib/socket.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAsB,MAAM,WAAW,CAAC;AAGvD,IAAI,EAAsB,CAAC;AAC3B,IAAI,MAA0B,CAAC;AAC/B,IAAI,SAAkC,CAAC;AAEvC,4EAA4E;AAC5E,MAAM,UAAU,KAAK;IACnB,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IACnF,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,SAAS;IACvB,OAAO,KAAK,EAAE,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,GAAY,EACZ,IAA6B;IAE7B,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;QACpF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC/C,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC;IACpF,EAAE,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE;QACtB,IAAI,EAAE;YACJ,MAAM,EAAE,UAAiB;YACzB,WAAW,EAAE,IAAI;SAClB;QACD,iBAAiB,EAAE,GAAG;QACtB,GAAG,IAAI;KACR,CAAC,CAAC;IACH,MAAM,GAAG,EAAE,CAAC;IACZ,SAAS,GAAG,MAAM,CAAC;IAEnB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;AAChC,CAAC;AAED,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Request, Response, NextFunction, RequestHandler } from "express";
2
+ /**
3
+ * Wrap async route handlers to forward errors to Express error handler
4
+ * (Not needed on Express 5 — kept for Express 4 compatibility)
5
+ */
6
+ export declare function asyncHandler(fn: (req: Request, res: Response, next: NextFunction) => Promise<any>): RequestHandler;
7
+ //# sourceMappingURL=asyncHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asyncHandler.d.ts","sourceRoot":"","sources":["../../util/asyncHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/E;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,GACpE,cAAc,CAIhB"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Wrap async route handlers to forward errors to Express error handler
3
+ * (Not needed on Express 5 — kept for Express 4 compatibility)
4
+ */
5
+ export function asyncHandler(fn) {
6
+ return (req, res, next) => {
7
+ Promise.resolve(fn(req, res, next)).catch(next);
8
+ };
9
+ }
10
+ //# sourceMappingURL=asyncHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asyncHandler.js","sourceRoot":"","sources":["../../util/asyncHandler.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,EAAqE;IAErE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Validate data against Zod schema: `validate(schema, data)` → { success, data, errors } */
2
+ export { validate } from "./validate.js";
3
+ export type { ValidateResult } from "./validate.js";
4
+ /** Response helpers: ok, created, badRequest, notFound, etc. */
5
+ export { ok, created, noContent, paginated, badRequest, unauthorized, forbidden, notFound, conflict, internalError, fail, } from "./response.js";
6
+ /** Response namespace: `response.ok(res, data)`, `response.created(res, data)` */
7
+ export { response } from "./response.js";
8
+ /** Status codes and error codes constants */
9
+ export { STATUS_CODE, ERROR_CODES } from "./response.js";
10
+ export type { StatusCode, ErrorCode, ApiResponse, ApiErrorResponse } from "./response.js";
11
+ /** Async handler wrapper for Express 4 compat */
12
+ export { asyncHandler } from "./asyncHandler.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../util/index.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,gEAAgE;AAChE,OAAO,EACL,EAAE,EACF,OAAO,EACP,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,IAAI,GACL,MAAO,eAAe,CAAC;AAExB,kFAAkF;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,6CAA6C;AAC7C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE1F,iDAAiD;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** Validate data against Zod schema: `validate(schema, data)` → { success, data, errors } */
2
+ export { validate } from "./validate.js";
3
+ /** Response helpers: ok, created, badRequest, notFound, etc. */
4
+ export { ok, created, noContent, paginated, badRequest, unauthorized, forbidden, notFound, conflict, internalError, fail, } from "./response.js";
5
+ /** Response namespace: `response.ok(res, data)`, `response.created(res, data)` */
6
+ export { response } from "./response.js";
7
+ /** Status codes and error codes constants */
8
+ export { STATUS_CODE, ERROR_CODES } from "./response.js";
9
+ /** Async handler wrapper for Express 4 compat */
10
+ export { asyncHandler } from "./asyncHandler.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../util/index.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,gEAAgE;AAChE,OAAO,EACL,EAAE,EACF,OAAO,EACP,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,IAAI,GACL,MAAO,eAAe,CAAC;AAExB,kFAAkF;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,6CAA6C;AAC7C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGzD,iDAAiD;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,91 @@
1
+ import type { Response } from "express";
2
+ declare const STATUS_CODE: {
3
+ readonly OK: 200;
4
+ readonly CREATED: 201;
5
+ readonly NO_CONTENT: 204;
6
+ readonly BAD_REQUEST: 400;
7
+ readonly UNAUTHORIZED: 401;
8
+ readonly FORBIDDEN: 403;
9
+ readonly NOT_FOUND: 404;
10
+ readonly CONFLICT: 409;
11
+ readonly INTERNAL_SERVER_ERROR: 500;
12
+ };
13
+ declare const ERROR_CODES: {
14
+ readonly BAD_REQUEST: "BAD_REQUEST";
15
+ readonly UNAUTHORIZED: "UNAUTHORIZED";
16
+ readonly FORBIDDEN: "FORBIDDEN";
17
+ readonly NOT_FOUND: "NOT_FOUND";
18
+ readonly CONFLICT: "CONFLICT";
19
+ readonly INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR";
20
+ };
21
+ type StatusCode = (typeof STATUS_CODE)[keyof typeof STATUS_CODE];
22
+ type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
23
+ type ApiResponse<T> = {
24
+ success: true;
25
+ data: T;
26
+ meta?: Record<string, unknown>;
27
+ };
28
+ type ApiErrorResponse = {
29
+ success: false;
30
+ error: {
31
+ code: ErrorCode;
32
+ message: string;
33
+ details?: unknown;
34
+ };
35
+ };
36
+ export declare function ok<T>(res: Response, data: T, meta?: Record<string, unknown>): void;
37
+ export declare function created<T>(res: Response, data: T): void;
38
+ export declare function noContent(res: Response): void;
39
+ export declare function paginated<T>(res: Response, items: T[], pagination: {
40
+ page: number;
41
+ limit: number;
42
+ totalItems: number;
43
+ }): void;
44
+ export declare function fail(res: Response, { status, code, message, details }: {
45
+ status: StatusCode;
46
+ code: ErrorCode;
47
+ message: string;
48
+ details?: unknown;
49
+ }): void;
50
+ export declare function badRequest(res: Response, message: string, details?: unknown): void;
51
+ export declare function unauthorized(res: Response, message: string, details?: unknown): void;
52
+ export declare function forbidden(res: Response, message: string, details?: unknown): void;
53
+ export declare function notFound(res: Response, message: string, details?: unknown): void;
54
+ export declare function conflict(res: Response, message: string, details?: unknown): void;
55
+ export declare function internalError(res: Response, message: string, details?: unknown): void;
56
+ export { STATUS_CODE, ERROR_CODES };
57
+ export type { StatusCode, ErrorCode, ApiResponse, ApiErrorResponse };
58
+ /** Response helper namespace: `response.ok(res, data)`, `response.created(res, data)` */
59
+ export declare const response: {
60
+ ok: typeof ok;
61
+ created: typeof created;
62
+ noContent: typeof noContent;
63
+ paginated: typeof paginated;
64
+ badRequest: typeof badRequest;
65
+ unauthorized: typeof unauthorized;
66
+ forbidden: typeof forbidden;
67
+ notFound: typeof notFound;
68
+ conflict: typeof conflict;
69
+ internalError: typeof internalError;
70
+ fail: typeof fail;
71
+ STATUS_CODE: {
72
+ readonly OK: 200;
73
+ readonly CREATED: 201;
74
+ readonly NO_CONTENT: 204;
75
+ readonly BAD_REQUEST: 400;
76
+ readonly UNAUTHORIZED: 401;
77
+ readonly FORBIDDEN: 403;
78
+ readonly NOT_FOUND: 404;
79
+ readonly CONFLICT: 409;
80
+ readonly INTERNAL_SERVER_ERROR: 500;
81
+ };
82
+ ERROR_CODES: {
83
+ readonly BAD_REQUEST: "BAD_REQUEST";
84
+ readonly UNAUTHORIZED: "UNAUTHORIZED";
85
+ readonly FORBIDDEN: "FORBIDDEN";
86
+ readonly NOT_FOUND: "NOT_FOUND";
87
+ readonly CONFLICT: "CONFLICT";
88
+ readonly INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR";
89
+ };
90
+ };
91
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../util/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,QAAA,MAAM,WAAW;;;;;;;;;;CAUP,CAAC;AAEX,QAAA,MAAM,WAAW;;;;;;;CAOP,CAAC;AAEX,KAAK,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AACjE,KAAK,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAEhE,KAAK,WAAW,CAAC,CAAC,IAAI;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AACjF,KAAK,gBAAgB,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,CAAC;AAU3G,wBAAgB,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAE3E;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAEhD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,QAEtC;AAED,wBAAgB,SAAS,CAAC,CAAC,EACzB,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,CAAC,EAAE,EACV,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,QAqBhE;AAED,wBAAgB,IAAI,CAClB,GAAG,EAAE,QAAQ,EACb,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,QAGhH;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,QAE3E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,QAE7E;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,QAE1E;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,QAEzE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,QAEzE;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,QAE9E;AAED,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACpC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC;AAErE,yFAAyF;AACzF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAcpB,CAAC"}
@@ -0,0 +1,92 @@
1
+ const STATUS_CODE = {
2
+ OK: 200,
3
+ CREATED: 201,
4
+ NO_CONTENT: 204,
5
+ BAD_REQUEST: 400,
6
+ UNAUTHORIZED: 401,
7
+ FORBIDDEN: 403,
8
+ NOT_FOUND: 404,
9
+ CONFLICT: 409,
10
+ INTERNAL_SERVER_ERROR: 500,
11
+ };
12
+ const ERROR_CODES = {
13
+ BAD_REQUEST: "BAD_REQUEST",
14
+ UNAUTHORIZED: "UNAUTHORIZED",
15
+ FORBIDDEN: "FORBIDDEN",
16
+ NOT_FOUND: "NOT_FOUND",
17
+ CONFLICT: "CONFLICT",
18
+ INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR",
19
+ };
20
+ function successResponse(data, meta) {
21
+ return { success: true, data, ...(meta && { meta }) };
22
+ }
23
+ function errorResponse(code, message, details) {
24
+ return { success: false, error: { code, message, details } };
25
+ }
26
+ export function ok(res, data, meta) {
27
+ res.status(STATUS_CODE.OK).json(successResponse(data, meta));
28
+ }
29
+ export function created(res, data) {
30
+ res.status(STATUS_CODE.CREATED).json(successResponse(data));
31
+ }
32
+ export function noContent(res) {
33
+ res.status(STATUS_CODE.NO_CONTENT).send();
34
+ }
35
+ export function paginated(res, items, pagination) {
36
+ if (!Number.isFinite(pagination.limit) || pagination.limit <= 0) {
37
+ throw new RangeError("paginated: limit must be > 0");
38
+ }
39
+ if (!Number.isFinite(pagination.page) || pagination.page <= 0) {
40
+ throw new RangeError("paginated: page must be > 0");
41
+ }
42
+ if (!Number.isFinite(pagination.totalItems) || pagination.totalItems < 0) {
43
+ throw new RangeError("paginated: totalItems must be >= 0");
44
+ }
45
+ res.status(STATUS_CODE.OK).json(successResponse(items, {
46
+ pagination: {
47
+ page: pagination.page,
48
+ limit: pagination.limit,
49
+ totalItems: pagination.totalItems,
50
+ totalPages: Math.ceil(pagination.totalItems / pagination.limit),
51
+ },
52
+ }));
53
+ }
54
+ export function fail(res, { status, code, message, details }) {
55
+ res.status(status).json(errorResponse(code, message, details));
56
+ }
57
+ export function badRequest(res, message, details) {
58
+ fail(res, { status: STATUS_CODE.BAD_REQUEST, code: ERROR_CODES.BAD_REQUEST, message, details });
59
+ }
60
+ export function unauthorized(res, message, details) {
61
+ fail(res, { status: STATUS_CODE.UNAUTHORIZED, code: ERROR_CODES.UNAUTHORIZED, message, details });
62
+ }
63
+ export function forbidden(res, message, details) {
64
+ fail(res, { status: STATUS_CODE.FORBIDDEN, code: ERROR_CODES.FORBIDDEN, message, details });
65
+ }
66
+ export function notFound(res, message, details) {
67
+ fail(res, { status: STATUS_CODE.NOT_FOUND, code: ERROR_CODES.NOT_FOUND, message, details });
68
+ }
69
+ export function conflict(res, message, details) {
70
+ fail(res, { status: STATUS_CODE.CONFLICT, code: ERROR_CODES.CONFLICT, message, details });
71
+ }
72
+ export function internalError(res, message, details) {
73
+ fail(res, { status: STATUS_CODE.INTERNAL_SERVER_ERROR, code: ERROR_CODES.INTERNAL_SERVER_ERROR, message, details });
74
+ }
75
+ export { STATUS_CODE, ERROR_CODES };
76
+ /** Response helper namespace: `response.ok(res, data)`, `response.created(res, data)` */
77
+ export const response = {
78
+ ok,
79
+ created,
80
+ noContent,
81
+ paginated,
82
+ badRequest,
83
+ unauthorized,
84
+ forbidden,
85
+ notFound,
86
+ conflict,
87
+ internalError,
88
+ fail,
89
+ STATUS_CODE,
90
+ ERROR_CODES,
91
+ };
92
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../util/response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ZodSchema } from "zod";
2
+ type FormattedError = {
3
+ field: string;
4
+ message: string;
5
+ code: string;
6
+ };
7
+ type ValidateResult<T> = {
8
+ success: true;
9
+ data: T;
10
+ errors: null;
11
+ } | {
12
+ success: false;
13
+ data: null;
14
+ errors: FormattedError[];
15
+ };
16
+ /** Validate data against Zod schema → { success, data, errors } */
17
+ export declare function validate<T>(schema: ZodSchema<T>, data: unknown): ValidateResult<T>;
18
+ export type { ValidateResult };
19
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../util/validate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,KAAK,CAAC;AAE/C,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,KAAK,cAAc,CAAC,CAAC,IACjB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,IAAI,CAAA;CAAE,GACxC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC;AAU7D,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAMlF;AAED,YAAY,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,16 @@
1
+ function formatZodErrors(error) {
2
+ return error.issues.map((issue) => ({
3
+ field: issue.path.length ? issue.path.join(".") : "root",
4
+ message: issue.message,
5
+ code: issue.code,
6
+ }));
7
+ }
8
+ /** Validate data against Zod schema → { success, data, errors } */
9
+ export function validate(schema, data) {
10
+ const result = schema.safeParse(data);
11
+ if (result.success) {
12
+ return { success: true, data: result.data, errors: null };
13
+ }
14
+ return { success: false, data: null, errors: formatZodErrors(result.error) };
15
+ }
16
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../util/validate.ts"],"names":[],"mappings":"AASA,SAAS,eAAe,CAAC,KAAe;IACtC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM;QACxD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,QAAQ,CAAI,MAAoB,EAAE,IAAa;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5D,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/E,CAAC"}
package/package.json CHANGED
@@ -1,27 +1,58 @@
1
1
  {
2
2
  "name": "abhijanb",
3
- "version": "0.1.2",
4
- "module": "index.ts",
3
+ "version": "0.1.3",
5
4
  "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
6
8
  "exports": {
7
- ".": "./index.ts",
8
- "./util": "./util/index.ts",
9
- "./lib": "./lib/index.ts"
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./util": {
14
+ "types": "./dist/util/index.d.ts",
15
+ "import": "./dist/util/index.js"
16
+ },
17
+ "./lib": {
18
+ "types": "./dist/lib/index.d.ts",
19
+ "import": "./dist/lib/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc -p tsconfig.build.json",
28
+ "prepublishOnly": "bun run build",
29
+ "dev": "bun --watch index.ts"
10
30
  },
11
- "types": "./index.ts",
12
31
  "dependencies": {
32
+ "bcryptjs": "^2.4.3",
33
+ "compression": "^1.8.0",
34
+ "cookie-parser": "^1.4.7",
35
+ "cors": "^2.8.5",
36
+ "express": "^5.2.1",
13
37
  "express-rate-limit": "^7.5.0",
14
- "jsonwebtoken": "^9.0.0",
38
+ "helmet": "^8.0.0",
39
+ "jsonwebtoken": "^9.0.2",
40
+ "morgan": "^1.10.0",
15
41
  "socket.io": "^4.8.0",
16
- "zod": "^3.22.0"
42
+ "zod": "^3.25.76"
17
43
  },
18
44
  "devDependencies": {
19
- "@types/bun": "latest",
20
- "@types/express": "^5.0.0",
21
- "@types/jsonwebtoken": "^9.0.0"
45
+ "@types/bun": "^1.4.0",
46
+ "@types/bcryptjs": "^2.4.6",
47
+ "@types/compression": "^1.7.5",
48
+ "@types/cookie-parser": "^1.4.8",
49
+ "@types/cors": "^2.8.19",
50
+ "@types/express": "^5.0.6",
51
+ "@types/jsonwebtoken": "^9.0.10",
52
+ "@types/morgan": "^1.9.9",
53
+ "@types/node": "^22.0.0"
22
54
  },
23
55
  "peerDependencies": {
24
- "express": "^4.21.0",
25
56
  "typescript": "^5"
26
57
  }
27
58
  }
package/a/README.md DELETED
@@ -1,15 +0,0 @@
1
- # a
2
-
3
- To install dependencies:
4
-
5
- ```bash
6
- bun install
7
- ```
8
-
9
- To run:
10
-
11
- ```bash
12
- bun run index.ts
13
- ```
14
-
15
- This project was created using `bun init` in bun v1.3.14. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
package/a/index.ts DELETED
@@ -1,26 +0,0 @@
1
- import { startSocket, validate } from 'abhijanb';
2
- import express from 'express';
3
- import z from 'zod';
4
- const app = express();
5
- const {server} = startSocket(app);
6
-
7
-
8
- const schema = z.object({
9
- name: z.string(),
10
- age: z.number().int().positive(),
11
- });
12
-
13
- app.use(express.json());
14
-
15
- app.post('/validate', (req, res) => {
16
- const result = validate(schema, req.body);
17
- if (result.success) {
18
- res.json({ message: 'Validation successful', data: result.data });
19
- } else {
20
- res.status(400).json({ message: 'Validation failed', errors: result.errors });
21
- }
22
- });
23
-
24
- server.listen(3000, () => {
25
- console.log('Server is running on port 3000');
26
- });
package/a/package.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "name": "a",
3
- "module": "index.ts",
4
- "type": "module",
5
- "private": true,
6
- "scripts": {
7
- "dev": "bun --watch index.ts"
8
-
9
- },
10
- "devDependencies": {
11
- "@types/bun": "latest"
12
- },
13
- "peerDependencies": {
14
- "typescript": "^5"
15
- },
16
- "dependencies": {
17
- "abhijanb": "^0.1.1"
18
- }
19
- }
package/index.ts DELETED
@@ -1,3 +0,0 @@
1
- /** Main entry point — re-exports everything from util/ and lib/ */
2
- export * from "./util";
3
- export * from "./lib";
package/lib/auth.ts DELETED
@@ -1,71 +0,0 @@
1
- import jwt from "jsonwebtoken";
2
- import type { Request, Response, NextFunction } from "express";
3
-
4
- const ACCESS_SECRET = process.env.JWT_ACCESS_SECRET || "access-secret";
5
- const REFRESH_SECRET = process.env.JWT_REFRESH_SECRET || "refresh-secret";
6
- const ACCESS_EXPIRY = "30m";
7
- const REFRESH_EXPIRY = "30d";
8
-
9
- /** Sign an access token */
10
- export function signToken(
11
- payload: object,
12
- options?: { secret?: string; expiresIn?: string }
13
- ): string {
14
- return jwt.sign(payload, options?.secret || ACCESS_SECRET, {
15
- expiresIn: options?.expiresIn || ACCESS_EXPIRY,
16
- });
17
- }
18
-
19
- /** Sign a refresh token */
20
- export function signRefreshToken(
21
- payload: object,
22
- options?: { secret?: string; expiresIn?: string }
23
- ): string {
24
- return jwt.sign(payload, options?.secret || REFRESH_SECRET, {
25
- expiresIn: options?.expiresIn || REFRESH_EXPIRY,
26
- });
27
- }
28
-
29
- /** Verify and decode a token */
30
- export function verifyToken<T = any>(
31
- token: string,
32
- options?: { secret?: string }
33
- ): T {
34
- return jwt.verify(token, options?.secret || ACCESS_SECRET) as T;
35
- }
36
-
37
- /** Refresh: verify refresh token → return new access token */
38
- export function refreshToken(
39
- token: string,
40
- options?: { accessSecret?: string; refreshSecret?: string }
41
- ): string {
42
- const decoded = jwt.verify(
43
- token,
44
- options?.refreshSecret || REFRESH_SECRET
45
- ) as jwt.JwtPayload;
46
-
47
- const { iat, exp, ...payload } = decoded;
48
- return signToken(payload, { secret: options?.accessSecret });
49
- }
50
-
51
- /** Express middleware — verifies Bearer token, attaches decoded payload to `req.user` */
52
- export function authMiddleware(options?: { secret?: string }) {
53
- return (req: Request, res: Response, next: NextFunction) => {
54
- const header = req.headers.authorization;
55
-
56
- if (!header || !header.startsWith("Bearer ")) {
57
- res.status(401).json({ error: "Missing or invalid Authorization header" });
58
- return;
59
- }
60
-
61
- const token = header.split(" ")[1];
62
-
63
- try {
64
- const decoded = jwt.verify(token, options?.secret || ACCESS_SECRET);
65
- (req as any).user = decoded;
66
- next();
67
- } catch {
68
- res.status(401).json({ error: "Invalid or expired token" });
69
- }
70
- };
71
- }
package/lib/index.ts DELETED
@@ -1,20 +0,0 @@
1
- /** Start Socket.IO on an Express app: `startSocket(app)` → returns { server, io, socket } */
2
- export { startSocket, io, socket } from "./socket";
3
- /** Socket type — for typing event handlers */
4
- export type { Socket } from "./socket";
5
-
6
- /** Rate limiter factory: `app.use(limiter(5, 1000))` = 5min window, 1000 req/IP */
7
- export { limiter } from "./rateLimiter";
8
- /** Factory — create custom rate limiters: `rateLimit({ windowMs: 60000, max: 20 })` */
9
- export { rateLimit } from "./rateLimiter";
10
-
11
- /** JWT middleware — verifies Bearer token, attaches decoded payload to `req.user` */
12
- export { authMiddleware } from "./auth";
13
- /** Sign an access token: `signToken({ userId: 1 })` */
14
- export { signToken } from "./auth";
15
- /** Sign a refresh token: `signRefreshToken({ userId: 1 })` */
16
- export { signRefreshToken } from "./auth";
17
- /** Verify and decode a token: `verifyToken<T>(token)` */
18
- export { verifyToken } from "./auth";
19
- /** Refresh: verify refresh token → return new access token */
20
- export { refreshToken } from "./auth";
package/lib/socket.ts DELETED
@@ -1,17 +0,0 @@
1
- import http from "http";
2
- import { Server } from "socket.io";
3
- import type { Express } from "express";
4
-
5
- let io: Server;
6
- let socket: Server;
7
-
8
- /** Start Socket.IO on an Express app: `startSocket(app)` → returns { server, io, socket } */
9
- export function startSocket(app: Express) {
10
- const server = http.createServer(app);
11
- io = new Server(server);
12
- socket = io;
13
- return { server, io, socket };
14
- }
15
-
16
- export { io, socket };
17
- export type { Socket } from "socket.io";
package/util/index.ts DELETED
@@ -1,25 +0,0 @@
1
- /** Validate data against Zod schema: `validate(schema, data)` → { success, data, errors } */
2
- export { validate } from "./validate";
3
- export type { ValidateResult } from "./validate";
4
-
5
- /** Response helpers: ok, created, badRequest, notFound, etc. */
6
- export {
7
- ok,
8
- created,
9
- noContent,
10
- paginated,
11
- badRequest,
12
- unauthorized,
13
- forbidden,
14
- notFound,
15
- conflict,
16
- internalError,
17
- fail,
18
- } from "./response";
19
-
20
- /** Response namespace: `response.ok(res, data)`, `response.created(res, data)` */
21
- export { response } from "./response";
22
-
23
- /** Status codes and error codes constants */
24
- export { STATUS_CODE, ERROR_CODES } from "./response";
25
- export type { StatusCode, ErrorCode, ApiResponse, ApiErrorResponse } from "./response";
package/util/response.ts DELETED
@@ -1,116 +0,0 @@
1
- import type { Response } from "express";
2
-
3
- const STATUS_CODE = {
4
- OK: 200,
5
- CREATED: 201,
6
- NO_CONTENT: 204,
7
- BAD_REQUEST: 400,
8
- UNAUTHORIZED: 401,
9
- FORBIDDEN: 403,
10
- NOT_FOUND: 404,
11
- CONFLICT: 409,
12
- INTERNAL_SERVER_ERROR: 500,
13
- } as const;
14
-
15
- const ERROR_CODES = {
16
- BAD_REQUEST: "BAD_REQUEST",
17
- UNAUTHORIZED: "UNAUTHORIZED",
18
- FORBIDDEN: "FORBIDDEN",
19
- NOT_FOUND: "NOT_FOUND",
20
- CONFLICT: "CONFLICT",
21
- INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR",
22
- } as const;
23
-
24
- type StatusCode = (typeof STATUS_CODE)[keyof typeof STATUS_CODE];
25
- type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
26
-
27
- type ApiResponse<T> = { success: true; data: T; meta?: Record<string, unknown> };
28
- type ApiErrorResponse = { success: false; error: { code: ErrorCode; message: string; details?: unknown } };
29
-
30
- function successResponse<T>(data: T, meta?: Record<string, unknown>): ApiResponse<T> {
31
- return { success: true, data, ...(meta && { meta }) };
32
- }
33
-
34
- function errorResponse(code: ErrorCode, message: string, details?: unknown): ApiErrorResponse {
35
- return { success: false, error: { code, message, details } };
36
- }
37
-
38
- export function ok<T>(res: Response, data: T, meta?: Record<string, unknown>) {
39
- res.status(STATUS_CODE.OK).json(successResponse(data, meta));
40
- }
41
-
42
- export function created<T>(res: Response, data: T) {
43
- res.status(STATUS_CODE.CREATED).json(successResponse(data));
44
- }
45
-
46
- export function noContent(res: Response) {
47
- res.status(STATUS_CODE.NO_CONTENT).send();
48
- }
49
-
50
- export function paginated<T>(
51
- res: Response,
52
- items: T[],
53
- pagination: { page: number; limit: number; totalItems: number }
54
- ) {
55
- res.status(STATUS_CODE.OK).json(
56
- successResponse(items, {
57
- pagination: {
58
- page: pagination.page,
59
- limit: pagination.limit,
60
- totalItems: pagination.totalItems,
61
- totalPages: Math.ceil(pagination.totalItems / pagination.limit),
62
- },
63
- })
64
- );
65
- }
66
-
67
- export function fail(
68
- res: Response,
69
- { status, code, message, details }: { status: StatusCode; code: ErrorCode; message: string; details?: unknown }
70
- ) {
71
- res.status(status).json(errorResponse(code, message, details));
72
- }
73
-
74
- export function badRequest(res: Response, message: string, details?: unknown) {
75
- fail(res, { status: STATUS_CODE.BAD_REQUEST, code: ERROR_CODES.BAD_REQUEST, message, details });
76
- }
77
-
78
- export function unauthorized(res: Response, message: string, details?: unknown) {
79
- fail(res, { status: STATUS_CODE.UNAUTHORIZED, code: ERROR_CODES.UNAUTHORIZED, message, details });
80
- }
81
-
82
- export function forbidden(res: Response, message: string, details?: unknown) {
83
- fail(res, { status: STATUS_CODE.FORBIDDEN, code: ERROR_CODES.FORBIDDEN, message, details });
84
- }
85
-
86
- export function notFound(res: Response, message: string, details?: unknown) {
87
- fail(res, { status: STATUS_CODE.NOT_FOUND, code: ERROR_CODES.NOT_FOUND, message, details });
88
- }
89
-
90
- export function conflict(res: Response, message: string, details?: unknown) {
91
- fail(res, { status: STATUS_CODE.CONFLICT, code: ERROR_CODES.CONFLICT, message, details });
92
- }
93
-
94
- export function internalError(res: Response, message: string, details?: unknown) {
95
- fail(res, { status: STATUS_CODE.INTERNAL_SERVER_ERROR, code: ERROR_CODES.INTERNAL_SERVER_ERROR, message, details });
96
- }
97
-
98
- export { STATUS_CODE, ERROR_CODES };
99
- export type { StatusCode, ErrorCode, ApiResponse, ApiErrorResponse };
100
-
101
- /** Response helper namespace: `response.ok(res, data)`, `response.created(res, data)` */
102
- export const response = {
103
- ok,
104
- created,
105
- noContent,
106
- paginated,
107
- badRequest,
108
- unauthorized,
109
- forbidden,
110
- notFound,
111
- conflict,
112
- internalError,
113
- fail,
114
- STATUS_CODE,
115
- ERROR_CODES,
116
- };
package/util/validate.ts DELETED
@@ -1,27 +0,0 @@
1
- import { z } from "zod";
2
- import type { ZodSchema, ZodError } from "zod";
3
-
4
- type FormattedError = { field: string; message: string; code: string };
5
-
6
- type ValidateResult<T> =
7
- | { success: true; data: T; errors: null }
8
- | { success: false; data: null; errors: FormattedError[] };
9
-
10
- function formatZodErrors(error: ZodError): FormattedError[] {
11
- return error.issues.map((issue) => ({
12
- field: issue.path.length ? issue.path.join(".") : "root",
13
- message: issue.message,
14
- code: issue.code,
15
- }));
16
- }
17
-
18
- /** Validate data against Zod schema → { success, data, errors } */
19
- export function validate<T>(schema: ZodSchema<T>, data: unknown): ValidateResult<T> {
20
- const result = schema.safeParse(data);
21
- if (result.success) {
22
- return { success: true, data: result.data, errors: null };
23
- }
24
- return { success: false, data: null, errors: formatZodErrors(result.error) };
25
- }
26
-
27
- export type { ValidateResult };