@pick2me/shared 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.
Files changed (106) hide show
  1. package/dist/auth/auth.d.ts +9 -0
  2. package/dist/auth/auth.d.ts.map +1 -0
  3. package/dist/auth/auth.js +82 -0
  4. package/dist/auth/index.d.ts +4 -0
  5. package/dist/auth/index.d.ts.map +1 -0
  6. package/dist/auth/index.js +2 -0
  7. package/dist/auth/verifyGatewayJwt.d.ts +14 -0
  8. package/dist/auth/verifyGatewayJwt.d.ts.map +1 -0
  9. package/dist/auth/verifyGatewayJwt.js +47 -0
  10. package/dist/constants/index.d.ts +2 -0
  11. package/dist/constants/index.d.ts.map +1 -0
  12. package/dist/constants/index.js +1 -0
  13. package/dist/constants/redis-keys.d.ts +10 -0
  14. package/dist/constants/redis-keys.d.ts.map +1 -0
  15. package/dist/constants/redis-keys.js +14 -0
  16. package/dist/errors/HttpError.d.ts +17 -0
  17. package/dist/errors/HttpError.d.ts.map +1 -0
  18. package/dist/errors/HttpError.js +17 -0
  19. package/dist/errors/errorHandler.d.ts +3 -0
  20. package/dist/errors/errorHandler.d.ts.map +1 -0
  21. package/dist/errors/errorHandler.js +37 -0
  22. package/dist/errors/index.d.ts +10 -0
  23. package/dist/errors/index.d.ts.map +1 -0
  24. package/dist/errors/index.js +9 -0
  25. package/dist/interfaces/common-response.d.ts +14 -0
  26. package/dist/interfaces/common-response.d.ts.map +1 -0
  27. package/dist/interfaces/common-response.js +1 -0
  28. package/dist/interfaces/common-types.d.ts +39 -0
  29. package/dist/interfaces/common-types.d.ts.map +1 -0
  30. package/dist/interfaces/common-types.js +1 -0
  31. package/dist/interfaces/index.d.ts +5 -0
  32. package/dist/interfaces/index.d.ts.map +1 -0
  33. package/dist/interfaces/index.js +4 -0
  34. package/dist/interfaces/rabbit-event-types.d.ts +6 -0
  35. package/dist/interfaces/rabbit-event-types.d.ts.map +1 -0
  36. package/dist/interfaces/rabbit-event-types.js +1 -0
  37. package/dist/interfaces/status-code.d.ts +66 -0
  38. package/dist/interfaces/status-code.d.ts.map +1 -0
  39. package/dist/interfaces/status-code.js +66 -0
  40. package/dist/messaging/index.d.ts +4 -0
  41. package/dist/messaging/index.d.ts.map +1 -0
  42. package/dist/messaging/index.js +3 -0
  43. package/dist/messaging/rabbitmq.config.d.ts +35 -0
  44. package/dist/messaging/rabbitmq.config.d.ts.map +1 -0
  45. package/dist/messaging/rabbitmq.config.js +43 -0
  46. package/dist/messaging/rabbitmq.d.ts +20 -0
  47. package/dist/messaging/rabbitmq.d.ts.map +1 -0
  48. package/dist/messaging/rabbitmq.js +65 -0
  49. package/dist/messaging/rabbitmq.utils.d.ts +3 -0
  50. package/dist/messaging/rabbitmq.utils.d.ts.map +1 -0
  51. package/dist/messaging/rabbitmq.utils.js +30 -0
  52. package/dist/mongo/connection.d.ts +2 -0
  53. package/dist/mongo/connection.d.ts.map +1 -0
  54. package/dist/mongo/connection.js +13 -0
  55. package/dist/mongo/i-mongo-base-repository.d.ts +16 -0
  56. package/dist/mongo/i-mongo-base-repository.d.ts.map +1 -0
  57. package/dist/mongo/i-mongo-base-repository.js +1 -0
  58. package/dist/mongo/index.d.ts +4 -0
  59. package/dist/mongo/index.d.ts.map +1 -0
  60. package/dist/mongo/index.js +3 -0
  61. package/dist/mongo/mongo-base-repository.d.ts +19 -0
  62. package/dist/mongo/mongo-base-repository.d.ts.map +1 -0
  63. package/dist/mongo/mongo-base-repository.js +114 -0
  64. package/dist/protos/booking.proto +22 -0
  65. package/dist/protos/driver.proto +450 -0
  66. package/dist/protos/index.d.ts +12 -0
  67. package/dist/protos/index.d.ts.map +1 -0
  68. package/dist/protos/index.js +30 -0
  69. package/dist/protos/index.ts +36 -0
  70. package/dist/protos/payment.proto +37 -0
  71. package/dist/protos/realtime.proto +19 -0
  72. package/dist/protos/user.proto +18 -0
  73. package/dist/redis/RedisService.d.ts +37 -0
  74. package/dist/redis/RedisService.d.ts.map +1 -0
  75. package/dist/redis/RedisService.js +203 -0
  76. package/dist/redis/client.d.ts +4 -0
  77. package/dist/redis/client.d.ts.map +1 -0
  78. package/dist/redis/client.js +7 -0
  79. package/dist/redis/index.d.ts +3 -0
  80. package/dist/redis/index.d.ts.map +1 -0
  81. package/dist/redis/index.js +2 -0
  82. package/dist/sql/i-sql-base-repository.d.ts +10 -0
  83. package/dist/sql/i-sql-base-repository.d.ts.map +1 -0
  84. package/dist/sql/i-sql-base-repository.js +1 -0
  85. package/dist/sql/index.d.ts +3 -0
  86. package/dist/sql/index.d.ts.map +1 -0
  87. package/dist/sql/index.js +2 -0
  88. package/dist/sql/sql-base-repository.d.ts +15 -0
  89. package/dist/sql/sql-base-repository.d.ts.map +1 -0
  90. package/dist/sql/sql-base-repository.js +74 -0
  91. package/dist/utils/asyncHandler.d.ts +3 -0
  92. package/dist/utils/asyncHandler.d.ts.map +1 -0
  93. package/dist/utils/asyncHandler.js +5 -0
  94. package/dist/utils/bcrypt.d.ts +5 -0
  95. package/dist/utils/bcrypt.d.ts.map +1 -0
  96. package/dist/utils/bcrypt.js +9 -0
  97. package/dist/utils/catchAsync.d.ts +3 -0
  98. package/dist/utils/catchAsync.d.ts.map +1 -0
  99. package/dist/utils/catchAsync.js +3 -0
  100. package/dist/utils/envChecker.d.ts +10 -0
  101. package/dist/utils/envChecker.d.ts.map +1 -0
  102. package/dist/utils/envChecker.js +26 -0
  103. package/dist/utils/index.d.ts +4 -0
  104. package/dist/utils/index.d.ts.map +1 -0
  105. package/dist/utils/index.js +3 -0
  106. package/package.json +119 -0
@@ -0,0 +1,9 @@
1
+ import jwt from "jsonwebtoken";
2
+ import type { JwtPayload } from "jsonwebtoken";
3
+ export type AccessPayload = JwtPayload & {
4
+ id: string;
5
+ role: "User" | "Driver" | "Admin";
6
+ };
7
+ export declare function generateJwtToken(payload: AccessPayload, secret: jwt.Secret, duration?: jwt.SignOptions["expiresIn"]): string;
8
+ export declare function verifyToken(token: string, secret: jwt.Secret): jwt.JwtPayload;
9
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACnC,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,GAAG,CAAC,MAAM,EAClB,QAAQ,GAAE,GAAG,CAAC,WAAW,CAAC,WAAW,CAAQ,GAC5C,MAAM,CAMR;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,kBAS5D"}
@@ -0,0 +1,82 @@
1
+ import jwt from "jsonwebtoken";
2
+ import { InternalError } from "../errors";
3
+ export function generateJwtToken(payload, secret, duration = "1h") {
4
+ const token = jwt.sign({ id: payload.id, role: payload.role }, secret, {
5
+ expiresIn: duration,
6
+ });
7
+ return token;
8
+ }
9
+ export function verifyToken(token, secret) {
10
+ try {
11
+ if (!secret)
12
+ throw InternalError("JWT secret key not provided");
13
+ return jwt.verify(token, secret);
14
+ }
15
+ catch (err) {
16
+ throw err;
17
+ }
18
+ }
19
+ // export function verifyAccessToken(secret: string): RequestHandler {
20
+ // if (!secret) {
21
+ // throw new Error(
22
+ // "JWT access token secret missing. Call verifyAccessToken(secret) with a secret or set JWT_ACCESS_TOKEN_SECRET in env."
23
+ // );
24
+ // }
25
+ // return async (req, res, next) => {
26
+ // try {
27
+ // // const token = req.headers.authorization?.split(" ")[1];
28
+ // const token = (req as any).cookies?.accessToken;
29
+ // if (!token) {
30
+ // console.log("No token provided");
31
+ // res.status(StatusCode.Forbidden).json({
32
+ // success: false,
33
+ // message: "No token provided",
34
+ // });
35
+ // return;
36
+ // }
37
+ // const decoded = jwt.verify(token, secret) as JwtPayload;
38
+ // if (decoded.role !== req.headers["x-user-role"]) {
39
+ // return res
40
+ // .status(StatusCode.Unauthorized)
41
+ // .json({ error: "Unauthorized access" });
42
+ // }
43
+ // const redisClient = RedisService.getInstance();
44
+ // const isBlacklisted = await redisClient.checkBlacklistedToken(decoded.id);
45
+ // console.log("isBlacklisted", isBlacklisted, "id", decoded.id);
46
+ // if (isBlacklisted) {
47
+ // console.log("blacklisted");
48
+ // res.clearCookie("refreshToken");
49
+ // res.clearCookie("accessToken");
50
+ // await redisClient.removeBlacklistedToken(decoded.id);
51
+ // return res
52
+ // .status(StatusCode.Forbidden)
53
+ // .json({ message: "Token is blacklisted" });
54
+ // }
55
+ // const payload = {
56
+ // id: decoded.id,
57
+ // role: decoded.role,
58
+ // };
59
+ // req.headers["x-user-payload"] = JSON.stringify(payload);
60
+ // const signed = jwt.sign(payload, secret!, {
61
+ // algorithm: "HS256",
62
+ // expiresIn: "30s",
63
+ // issuer: "api-gateway",
64
+ // });
65
+ // req.headers["x-gateway-jwt"] = signed;
66
+ // return next();
67
+ // } catch (err: unknown) {
68
+ // if (err instanceof jwt.TokenExpiredError) {
69
+ // console.log("token expired");
70
+ // res
71
+ // .status(StatusCode.Forbidden)
72
+ // .json({ message: "token expired", reason: "token_expired" });
73
+ // return
74
+ // }
75
+ // console.log("invalid expired");
76
+ // res
77
+ // .status(StatusCode.Forbidden)
78
+ // .json({ message: "Invalid token", reason: "invalid_token" });
79
+ // return
80
+ // }
81
+ // };
82
+ // }
@@ -0,0 +1,4 @@
1
+ export * from "./verifyGatewayJwt";
2
+ export type { AccessPayload } from "./types";
3
+ export * from "./auth";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./verifyGatewayJwt";
2
+ export * from "./auth";
@@ -0,0 +1,14 @@
1
+ import { RequestHandler } from "express";
2
+ import { AccessPayload } from "./types";
3
+ import { IRole } from "../interfaces/common-types";
4
+ declare global {
5
+ namespace Express {
6
+ interface Request {
7
+ gatewayUser?: AccessPayload | null;
8
+ }
9
+ }
10
+ }
11
+ export declare function verifyGatewayJwt(strict: boolean | undefined, GATEWAY_SECRET: string, options?: {
12
+ role?: IRole | IRole[];
13
+ }): RequestHandler;
14
+ //# sourceMappingURL=verifyGatewayJwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyGatewayJwt.d.ts","sourceRoot":"","sources":["../../src/auth/verifyGatewayJwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAEnD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;SACpC;KACF;CACF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,qBAAO,EAAE,cAAc,EAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,CAAA;CAAE,GAAG,cAAc,CAgD3H"}
@@ -0,0 +1,47 @@
1
+ import jwt from "jsonwebtoken";
2
+ export function verifyGatewayJwt(strict = true, GATEWAY_SECRET, options) {
3
+ if (!GATEWAY_SECRET) {
4
+ console.warn("GATEWAY_SHARED_SECRET is not set. Gateway JWT verification will fail.");
5
+ }
6
+ return (req, res, next) => {
7
+ const raw = req.headers["x-gateway-jwt"] ?? null;
8
+ if (!raw) {
9
+ if (strict)
10
+ return res.status(401).json({ message: "Missing gateway token" });
11
+ req.gatewayUser = null;
12
+ return next();
13
+ }
14
+ try {
15
+ const decoded = jwt.verify(raw, GATEWAY_SECRET, { issuer: "api-gateway" });
16
+ if (!decoded || typeof decoded !== "object" || !decoded.id || !decoded.role) {
17
+ if (strict)
18
+ return res.status(401).json({ message: "Invalid gateway token (claims missing)" });
19
+ req.gatewayUser = null;
20
+ return next();
21
+ }
22
+ const gatewayUser = {
23
+ id: String(decoded.id),
24
+ role: String(decoded.role),
25
+ };
26
+ // optional role check
27
+ if (options?.role) {
28
+ const required = Array.isArray(options.role) ? options.role : [options.role];
29
+ if (!required.includes(gatewayUser.role)) {
30
+ if (strict)
31
+ return res.status(403).json({ message: "Forbidden: role mismatch" });
32
+ req.gatewayUser = null;
33
+ return next();
34
+ }
35
+ }
36
+ req.gatewayUser = gatewayUser;
37
+ return next();
38
+ }
39
+ catch (err) {
40
+ const message = err.message || "Invalid gateway token";
41
+ if (strict)
42
+ return res.status(401).json({ message: `Invalid gateway token: ${message}` });
43
+ req.gatewayUser = null;
44
+ return next();
45
+ }
46
+ };
47
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./redis-keys";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./redis-keys";
@@ -0,0 +1,10 @@
1
+ export declare const GEO_KEY = "onlineDrivers:geo:";
2
+ export declare const GEO_KEY_RIDE = "rideDrivers:geo:";
3
+ export declare const HEARTBEAT_PREFIX = "driver:heartbeat:";
4
+ export declare const ONLINE_DRIVER_DETAILS_PREFIX = ":onlineDriver:details:";
5
+ export declare const IN_RIDE_HEARTBEAT_PREFIX = "driver:inride:heartbeat:";
6
+ export declare const IN_RIDE_HEARTBEAT_PREFIX_DATA = "driver:inride:heartbeat:data:";
7
+ export declare const SOCKET_PREFIX = "socket:user:";
8
+ export declare const RIDE_QUEUE_PREFIX = "ride:queue:";
9
+ export declare const RIDE_OFFER_PREFIX = "ride:offer:";
10
+ //# sourceMappingURL=redis-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-keys.d.ts","sourceRoot":"","sources":["../../src/constants/redis-keys.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,uBAAuB,CAAC;AAC5C,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AACpD,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AACrE,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,6BAA6B,kCAAkC,CAAA;AAM5E,eAAO,MAAM,aAAa,iBAAiB,CAAA;AAE3C,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAC/C,eAAO,MAAM,iBAAiB,gBAAgB,CAAC"}
@@ -0,0 +1,14 @@
1
+ export const GEO_KEY = "onlineDrivers:geo:";
2
+ export const GEO_KEY_RIDE = "rideDrivers:geo:";
3
+ export const HEARTBEAT_PREFIX = "driver:heartbeat:";
4
+ export const ONLINE_DRIVER_DETAILS_PREFIX = ":onlineDriver:details:";
5
+ export const IN_RIDE_HEARTBEAT_PREFIX = 'driver:inride:heartbeat:';
6
+ export const IN_RIDE_HEARTBEAT_PREFIX_DATA = 'driver:inride:heartbeat:data:';
7
+ // export const RIDE_DRIVER_DETAILS_PREFIX = ":rideDriver:details:";
8
+ // export const BOOKING_REQUEST_PREFIX = "booking:request:";
9
+ // export const DRIVER_REQUEST_PREFIX = "driver:request:";
10
+ // export const PROCESSED_PREFIX = "processed:";
11
+ // export const LOCK_PREFIX = "lock:booking:";
12
+ export const SOCKET_PREFIX = "socket:user:";
13
+ export const RIDE_QUEUE_PREFIX = 'ride:queue:';
14
+ export const RIDE_OFFER_PREFIX = 'ride:offer:';
@@ -0,0 +1,17 @@
1
+ export interface ErrorDetails {
2
+ [key: string]: any;
3
+ }
4
+ export declare class HttpError extends Error {
5
+ readonly status: number;
6
+ readonly code: string;
7
+ readonly details?: ErrorDetails;
8
+ readonly navigate?: string;
9
+ readonly safe: boolean;
10
+ constructor(status?: number, message?: string, options?: {
11
+ code?: string;
12
+ details?: ErrorDetails;
13
+ navigate?: string;
14
+ safe?: boolean;
15
+ });
16
+ }
17
+ //# sourceMappingURL=HttpError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpError.d.ts","sourceRoot":"","sources":["../../src/errors/HttpError.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE;AAEpD,qBAAa,SAAU,SAAQ,KAAK;IAClC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvC,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClC,SAAgB,IAAI,EAAE,OAAO,CAAC;gBAG5B,MAAM,SAAM,EACZ,OAAO,SAA0B,EACjC,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB;CAWJ"}
@@ -0,0 +1,17 @@
1
+ export class HttpError extends Error {
2
+ status;
3
+ code;
4
+ details;
5
+ navigate;
6
+ safe;
7
+ constructor(status = 500, message = "Internal server error", options) {
8
+ super(message);
9
+ this.name = "HttpError";
10
+ this.status = status;
11
+ this.code = options?.code ?? `ERR_${status}`;
12
+ this.details = options?.details;
13
+ this.navigate = options?.navigate;
14
+ this.safe = options?.safe ?? (status < 500);
15
+ Error.captureStackTrace?.(this, this.constructor);
16
+ }
17
+ }
@@ -0,0 +1,3 @@
1
+ import { ErrorRequestHandler } from "express";
2
+ export declare const errorHandler: ErrorRequestHandler;
3
+ //# sourceMappingURL=errorHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/errors/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAG/E,eAAO,MAAM,YAAY,EAAE,mBAyC1B,CAAA"}
@@ -0,0 +1,37 @@
1
+ import { HttpError } from "../errors/HttpError";
2
+ export const errorHandler = (err, req, res, next) => {
3
+ if (err instanceof HttpError) {
4
+ const payload = {
5
+ status: err.status,
6
+ code: err.code,
7
+ message: err.safe ? err.message : "Internal server error",
8
+ details: err.details ?? null,
9
+ navigate: err.navigate ?? null,
10
+ };
11
+ console.error(`[HttpError] ${req.method} ${req.url} ->`, {
12
+ message: err.message,
13
+ status: err.status,
14
+ code: err.code,
15
+ details: err.details,
16
+ stack: process.env.NODE_ENV === "production" ? undefined : err.stack,
17
+ });
18
+ return res.status(err.status).json(payload);
19
+ }
20
+ // handle known runtime errors
21
+ const anyErr = err;
22
+ if (anyErr && anyErr.name === "ValidationError" && anyErr.errors) {
23
+ const details = {};
24
+ for (const k of Object.keys(anyErr.errors)) {
25
+ details[k] = anyErr.errors[k].message || anyErr.errors[k].toString();
26
+ }
27
+ const he = new HttpError(400, "Validation failed", { code: "VALIDATION_ERROR", details });
28
+ return errorHandler(he, req, res, next);
29
+ }
30
+ if (anyErr && anyErr.code && typeof anyErr.code === "string" && anyErr.code.startsWith("LIMIT_")) {
31
+ const he = new HttpError(400, anyErr.message || "File upload error", { code: "UPLOAD_ERROR", details: anyErr });
32
+ return errorHandler(he, req, res, next);
33
+ }
34
+ console.error("[UnhandledError]", req.method, req.url, anyErr);
35
+ const he = new HttpError(500, "Internal server error", { code: "INTERNAL_ERROR", safe: false });
36
+ return errorHandler(he, req, res, next);
37
+ };
@@ -0,0 +1,10 @@
1
+ import { HttpError } from './HttpError';
2
+ export * from './HttpError';
3
+ export * from './errorHandler';
4
+ export declare const BadRequestError: (message?: string, opts?: any) => HttpError;
5
+ export declare const NotFoundError: (message?: string, opts?: any) => HttpError;
6
+ export declare const UnauthorizedError: (message?: string, opts?: any) => HttpError;
7
+ export declare const ForbiddenError: (message?: string, opts?: any) => HttpError;
8
+ export declare const InternalError: (message?: string, opts?: any) => HttpError;
9
+ export declare const ConflictError: (message?: string, opts?: any) => HttpError;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAE/B,eAAO,MAAM,eAAe,GAAI,gBAAuB,EAAE,OAAO,GAAG,cACJ,CAAC;AAChE,eAAO,MAAM,aAAa,GAAI,gBAAqB,EAAE,OAAO,GAAG,cACF,CAAC;AAC9D,eAAO,MAAM,iBAAiB,GAAI,gBAAwB,EAAE,OAAO,GAAG,cACN,CAAC;AACjE,eAAO,MAAM,cAAc,GAAI,gBAAqB,EAAE,OAAO,GAAG,cACH,CAAC;AAC9D,eAAO,MAAM,aAAa,GAAI,gBAAiC,EAAE,OAAO,GAAG,cACI,CAAC;AAChF,eAAO,MAAM,aAAa,GAAI,gBAA0B,EAAE,OAAO,GAAG,cACF,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { HttpError } from './HttpError';
2
+ export * from './HttpError';
3
+ export * from './errorHandler';
4
+ export const BadRequestError = (message = 'Bad request', opts) => new HttpError(400, message, { code: 'BAD_REQUEST', ...opts });
5
+ export const NotFoundError = (message = 'Not found', opts) => new HttpError(404, message, { code: 'NOT_FOUND', ...opts });
6
+ export const UnauthorizedError = (message = 'Unauthorized', opts) => new HttpError(401, message, { code: 'UNAUTHORIZED', ...opts });
7
+ export const ForbiddenError = (message = 'Forbidden', opts) => new HttpError(403, message, { code: 'FORBIDDEN', ...opts });
8
+ export const InternalError = (message = 'Internal server error', opts) => new HttpError(500, message, { code: 'INTERNAL_ERROR', safe: false, ...opts });
9
+ export const ConflictError = (message = 'Conflict Error', opts) => new HttpError(409, message, { code: 'CONFLICT_ERROR', ...opts });
@@ -0,0 +1,14 @@
1
+ import { StatusCode } from "./status-code";
2
+ export interface commonRes {
3
+ status: StatusCode;
4
+ message: string;
5
+ id?: string;
6
+ navigate?: string;
7
+ }
8
+ export interface IResponse<T> {
9
+ status: StatusCode;
10
+ message: string;
11
+ navigate?: string | number;
12
+ data?: T | null | [] | boolean;
13
+ }
14
+ //# sourceMappingURL=common-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common-response.d.ts","sourceRoot":"","sources":["../../src/interfaces/common-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,WAAW,SAAS;IACxB,MAAM,EAAC,UAAU,CAAC;IAClB,OAAO,EAAC,MAAM,CAAC;IACf,EAAE,CAAC,EAAC,MAAM,CAAC;IACX,QAAQ,CAAC,EAAC,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,EAAE,GAAG,OAAO,CAAC;CAChC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,39 @@
1
+ export interface Coordinates {
2
+ latitude: number;
3
+ longitude: number;
4
+ }
5
+ export interface LocationCoordinates {
6
+ address: string;
7
+ latitude: number;
8
+ longitude: number;
9
+ }
10
+ export interface OnlineDriverDetails {
11
+ driverId: string;
12
+ driverNumber: string;
13
+ name: string;
14
+ cancelledRides: number;
15
+ rating: number;
16
+ vehicleModel: string;
17
+ driverPhoto: string;
18
+ vehicleNumber: string;
19
+ stripeId?: string;
20
+ stripeLinkUrl?: string;
21
+ sessionStart?: number;
22
+ lastSeen?: number;
23
+ }
24
+ export interface NearbyDriver {
25
+ driverId: string;
26
+ distanceKm: number;
27
+ latitude: number;
28
+ longitude: number;
29
+ }
30
+ export interface OnlineDriverPreview {
31
+ driverId: string;
32
+ lat: number;
33
+ lng: number;
34
+ vehicleModel?: string;
35
+ distanceKm: number;
36
+ name?: string;
37
+ }
38
+ export type IRole = "User" | "Admin" | "Driver";
39
+ //# sourceMappingURL=common-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common-types.d.ts","sourceRoot":"","sources":["../../src/interfaces/common-types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAC,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,KAAK,GAAG,MAAM,GAAC,OAAO,GAAE,QAAQ,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export * from "./common-response";
2
+ export * from "./common-types";
3
+ export * from "./status-code";
4
+ export * from "./rabbit-event-types";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from "./common-response";
2
+ export * from "./common-types";
3
+ export * from "./status-code";
4
+ export * from "./rabbit-event-types";
@@ -0,0 +1,6 @@
1
+ export type UserRegisteredEvent = {
2
+ userId: string;
3
+ email: string;
4
+ createdAt: string;
5
+ };
6
+ //# sourceMappingURL=rabbit-event-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rabbit-event-types.d.ts","sourceRoot":"","sources":["../../src/interfaces/rabbit-event-types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ export declare enum StatusCode {
2
+ Continue = 100,
3
+ SwitchingProtocols = 101,
4
+ Processing = 102,
5
+ EarlyHints = 103,
6
+ OK = 200,
7
+ Created = 201,
8
+ Accepted = 202,
9
+ NonAuthoritativeInformation = 203,
10
+ NoContent = 204,
11
+ ResetContent = 205,
12
+ PartialContent = 206,
13
+ MultiStatus = 207,
14
+ AlreadyReported = 208,
15
+ IMUsed = 226,
16
+ MultipleChoices = 300,
17
+ MovedPermanently = 301,
18
+ Found = 302,
19
+ SeeOther = 303,
20
+ NotModified = 304,
21
+ UseProxy = 305,
22
+ TemporaryRedirect = 307,
23
+ PermanentRedirect = 308,
24
+ BadRequest = 400,
25
+ Unauthorized = 401,
26
+ PaymentRequired = 402,
27
+ Forbidden = 403,
28
+ NotFound = 404,
29
+ MethodNotAllowed = 405,
30
+ NotAcceptable = 406,
31
+ ProxyAuthenticationRequired = 407,
32
+ RequestTimeout = 408,
33
+ Conflict = 409,
34
+ Gone = 410,
35
+ LengthRequired = 411,
36
+ PreconditionFailed = 412,
37
+ PayloadTooLarge = 413,
38
+ URITooLong = 414,
39
+ UnsupportedMediaType = 415,
40
+ RangeNotSatisfiable = 416,
41
+ ExpectationFailed = 417,
42
+ ImATeapot = 418,
43
+ MisdirectedRequest = 421,
44
+ UnprocessableEntity = 422,
45
+ Locked = 423,
46
+ FailedDependency = 424,
47
+ TooEarly = 425,
48
+ UpgradeRequired = 426,
49
+ PreconditionRequired = 428,
50
+ TooManyRequests = 429,
51
+ RequestHeaderFieldsTooLarge = 431,
52
+ UnavailableForLegalReasons = 451,
53
+ InternalServerError = 500,
54
+ NotImplemented = 501,
55
+ BadGateway = 502,
56
+ ServiceUnavailable = 503,
57
+ GatewayTimeout = 504,
58
+ HTTPVersionNotSupported = 505,
59
+ VariantAlsoNegotiates = 506,
60
+ InsufficientStorage = 507,
61
+ LoopDetected = 508,
62
+ NotExtended = 510,
63
+ NetworkAuthenticationRequired = 511,
64
+ payment_status = "paid"
65
+ }
66
+ //# sourceMappingURL=status-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-code.d.ts","sourceRoot":"","sources":["../../src/interfaces/status-code.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IAClB,QAAQ,MAAM;IACd,kBAAkB,MAAM;IACxB,UAAU,MAAM;IAChB,UAAU,MAAM;IAChB,EAAE,MAAM;IACR,OAAO,MAAM;IACb,QAAQ,MAAM;IACd,2BAA2B,MAAM;IACjC,SAAS,MAAM;IACf,YAAY,MAAM;IAClB,cAAc,MAAM;IACpB,WAAW,MAAM;IACjB,eAAe,MAAM;IACrB,MAAM,MAAM;IACZ,eAAe,MAAM;IACrB,gBAAgB,MAAM;IACtB,KAAK,MAAM;IACX,QAAQ,MAAM;IACd,WAAW,MAAM;IACjB,QAAQ,MAAM;IACd,iBAAiB,MAAM;IACvB,iBAAiB,MAAM;IACvB,UAAU,MAAM;IAChB,YAAY,MAAM;IAClB,eAAe,MAAM;IACrB,SAAS,MAAM;IACf,QAAQ,MAAM;IACd,gBAAgB,MAAM;IACtB,aAAa,MAAM;IACnB,2BAA2B,MAAM;IACjC,cAAc,MAAM;IACpB,QAAQ,MAAM;IACd,IAAI,MAAM;IACV,cAAc,MAAM;IACpB,kBAAkB,MAAM;IACxB,eAAe,MAAM;IACrB,UAAU,MAAM;IAChB,oBAAoB,MAAM;IAC1B,mBAAmB,MAAM;IACzB,iBAAiB,MAAM;IACvB,SAAS,MAAM;IACf,kBAAkB,MAAM;IACxB,mBAAmB,MAAM;IACzB,MAAM,MAAM;IACZ,gBAAgB,MAAM;IACtB,QAAQ,MAAM;IACd,eAAe,MAAM;IACrB,oBAAoB,MAAM;IAC1B,eAAe,MAAM;IACrB,2BAA2B,MAAM;IACjC,0BAA0B,MAAM;IAChC,mBAAmB,MAAM;IACzB,cAAc,MAAM;IACpB,UAAU,MAAM;IAChB,kBAAkB,MAAM;IACxB,cAAc,MAAM;IACpB,uBAAuB,MAAM;IAC7B,qBAAqB,MAAM;IAC3B,mBAAmB,MAAM;IACzB,YAAY,MAAM;IAClB,WAAW,MAAM;IACjB,6BAA6B,MAAM;IACnC,cAAc,SAAS;CAC1B"}
@@ -0,0 +1,66 @@
1
+ export var StatusCode;
2
+ (function (StatusCode) {
3
+ StatusCode[StatusCode["Continue"] = 100] = "Continue";
4
+ StatusCode[StatusCode["SwitchingProtocols"] = 101] = "SwitchingProtocols";
5
+ StatusCode[StatusCode["Processing"] = 102] = "Processing";
6
+ StatusCode[StatusCode["EarlyHints"] = 103] = "EarlyHints";
7
+ StatusCode[StatusCode["OK"] = 200] = "OK";
8
+ StatusCode[StatusCode["Created"] = 201] = "Created";
9
+ StatusCode[StatusCode["Accepted"] = 202] = "Accepted";
10
+ StatusCode[StatusCode["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
11
+ StatusCode[StatusCode["NoContent"] = 204] = "NoContent";
12
+ StatusCode[StatusCode["ResetContent"] = 205] = "ResetContent";
13
+ StatusCode[StatusCode["PartialContent"] = 206] = "PartialContent";
14
+ StatusCode[StatusCode["MultiStatus"] = 207] = "MultiStatus";
15
+ StatusCode[StatusCode["AlreadyReported"] = 208] = "AlreadyReported";
16
+ StatusCode[StatusCode["IMUsed"] = 226] = "IMUsed";
17
+ StatusCode[StatusCode["MultipleChoices"] = 300] = "MultipleChoices";
18
+ StatusCode[StatusCode["MovedPermanently"] = 301] = "MovedPermanently";
19
+ StatusCode[StatusCode["Found"] = 302] = "Found";
20
+ StatusCode[StatusCode["SeeOther"] = 303] = "SeeOther";
21
+ StatusCode[StatusCode["NotModified"] = 304] = "NotModified";
22
+ StatusCode[StatusCode["UseProxy"] = 305] = "UseProxy";
23
+ StatusCode[StatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
24
+ StatusCode[StatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
25
+ StatusCode[StatusCode["BadRequest"] = 400] = "BadRequest";
26
+ StatusCode[StatusCode["Unauthorized"] = 401] = "Unauthorized";
27
+ StatusCode[StatusCode["PaymentRequired"] = 402] = "PaymentRequired";
28
+ StatusCode[StatusCode["Forbidden"] = 403] = "Forbidden";
29
+ StatusCode[StatusCode["NotFound"] = 404] = "NotFound";
30
+ StatusCode[StatusCode["MethodNotAllowed"] = 405] = "MethodNotAllowed";
31
+ StatusCode[StatusCode["NotAcceptable"] = 406] = "NotAcceptable";
32
+ StatusCode[StatusCode["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
33
+ StatusCode[StatusCode["RequestTimeout"] = 408] = "RequestTimeout";
34
+ StatusCode[StatusCode["Conflict"] = 409] = "Conflict";
35
+ StatusCode[StatusCode["Gone"] = 410] = "Gone";
36
+ StatusCode[StatusCode["LengthRequired"] = 411] = "LengthRequired";
37
+ StatusCode[StatusCode["PreconditionFailed"] = 412] = "PreconditionFailed";
38
+ StatusCode[StatusCode["PayloadTooLarge"] = 413] = "PayloadTooLarge";
39
+ StatusCode[StatusCode["URITooLong"] = 414] = "URITooLong";
40
+ StatusCode[StatusCode["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
41
+ StatusCode[StatusCode["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
42
+ StatusCode[StatusCode["ExpectationFailed"] = 417] = "ExpectationFailed";
43
+ StatusCode[StatusCode["ImATeapot"] = 418] = "ImATeapot";
44
+ StatusCode[StatusCode["MisdirectedRequest"] = 421] = "MisdirectedRequest";
45
+ StatusCode[StatusCode["UnprocessableEntity"] = 422] = "UnprocessableEntity";
46
+ StatusCode[StatusCode["Locked"] = 423] = "Locked";
47
+ StatusCode[StatusCode["FailedDependency"] = 424] = "FailedDependency";
48
+ StatusCode[StatusCode["TooEarly"] = 425] = "TooEarly";
49
+ StatusCode[StatusCode["UpgradeRequired"] = 426] = "UpgradeRequired";
50
+ StatusCode[StatusCode["PreconditionRequired"] = 428] = "PreconditionRequired";
51
+ StatusCode[StatusCode["TooManyRequests"] = 429] = "TooManyRequests";
52
+ StatusCode[StatusCode["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
53
+ StatusCode[StatusCode["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
54
+ StatusCode[StatusCode["InternalServerError"] = 500] = "InternalServerError";
55
+ StatusCode[StatusCode["NotImplemented"] = 501] = "NotImplemented";
56
+ StatusCode[StatusCode["BadGateway"] = 502] = "BadGateway";
57
+ StatusCode[StatusCode["ServiceUnavailable"] = 503] = "ServiceUnavailable";
58
+ StatusCode[StatusCode["GatewayTimeout"] = 504] = "GatewayTimeout";
59
+ StatusCode[StatusCode["HTTPVersionNotSupported"] = 505] = "HTTPVersionNotSupported";
60
+ StatusCode[StatusCode["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
61
+ StatusCode[StatusCode["InsufficientStorage"] = 507] = "InsufficientStorage";
62
+ StatusCode[StatusCode["LoopDetected"] = 508] = "LoopDetected";
63
+ StatusCode[StatusCode["NotExtended"] = 510] = "NotExtended";
64
+ StatusCode[StatusCode["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
65
+ StatusCode["payment_status"] = "paid";
66
+ })(StatusCode || (StatusCode = {}));
@@ -0,0 +1,4 @@
1
+ export * from "./rabbitmq.config";
2
+ export * from "./rabbitmq.utils";
3
+ export * from "./rabbitmq";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messaging/index.ts"],"names":[],"mappings":"AAEA,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from "./rabbitmq.config";
2
+ export * from "./rabbitmq.utils";
3
+ export * from "./rabbitmq";
@@ -0,0 +1,35 @@
1
+ export declare const EXCHANGES: {
2
+ readonly BOOKING: "booking.exchange";
3
+ readonly PAYMENT: "payment.exchange";
4
+ readonly DRIVER: "driver.exchange";
5
+ readonly USER: "user.exchange";
6
+ readonly NOTIFICATION: "notification.exchange";
7
+ };
8
+ export declare const ROUTING_KEYS: {
9
+ readonly RIDE_ACCEPTED: "realtime-booking.ride.accepted";
10
+ readonly RIDE_COMPLETED: "booking-realtime.ride.completed";
11
+ readonly CANCEL_RIDE: "realtime-booking.ride.status.cancel";
12
+ readonly UPDATE_DRIVER_RIDE_COUNT: "realtime-driver.ride.status.update";
13
+ readonly NOTIFY_BOOK_RIDE_DRIVER: "booking-realtime.booked.ride";
14
+ readonly NOTIFY_RIDE_COMPLETED: "booking-realtime.ride.completed";
15
+ readonly NOTIFY_RIDE_START: "booking-realtime.ride.start";
16
+ readonly MARK_PAYMENT_COMPLETED: "payment-booking.payment.completed";
17
+ readonly UPDATE_DRIVER_EARNINGS: "payment-driver.payment.completed";
18
+ readonly NOTIFY_DOCUMENT_EXPIRE: "driver-realtime.document.expire";
19
+ readonly USER_WALLET_CREATE: "user-payment.wallet.create";
20
+ readonly USER_ADDED_REWARD_AMOUNT: "user-payment.added.reward.amount";
21
+ };
22
+ export declare const QUEUES: {
23
+ readonly BOOKING_QUEUE: "booking.queue";
24
+ readonly PAYMENT_QUEUE: "payment.queue";
25
+ readonly DRIVER_QUEUE: "driver.queue";
26
+ readonly REALTIME_QUEUE: "realtime.queue";
27
+ };
28
+ export declare const DLQ_SUFFIX = ".dlq";
29
+ export declare const RETRY_SUFFIX = ".retry";
30
+ export declare function buildQueueNames(base: string): {
31
+ main: string;
32
+ retry: string;
33
+ dlq: string;
34
+ };
35
+ //# sourceMappingURL=rabbitmq.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rabbitmq.config.d.ts","sourceRoot":"","sources":["../../src/messaging/rabbitmq.config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;;;CAMZ,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;;;;;;;CAsBf,CAAC;AAEX,eAAO,MAAM,MAAM;;;;;CAKT,CAAC;AAGX,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,YAAY,WAAW,CAAC;AAGrC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM;;;;EAM3C"}