lapeh 2.3.6 → 2.3.8

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 (243) hide show
  1. package/bin/index.js +39 -56
  2. package/dist/generated/prisma/browser.d.ts +80 -0
  3. package/dist/generated/prisma/browser.d.ts.map +1 -0
  4. package/dist/generated/prisma/browser.js +56 -0
  5. package/dist/generated/prisma/client.d.ts +97 -0
  6. package/dist/generated/prisma/client.d.ts.map +1 -0
  7. package/dist/generated/prisma/client.js +68 -0
  8. package/dist/generated/prisma/commonInputTypes.d.ts +486 -0
  9. package/dist/generated/prisma/commonInputTypes.d.ts.map +1 -0
  10. package/dist/generated/prisma/commonInputTypes.js +11 -0
  11. package/dist/generated/prisma/enums.d.ts +2 -0
  12. package/dist/generated/prisma/enums.d.ts.map +1 -0
  13. package/dist/generated/prisma/enums.js +11 -0
  14. package/dist/generated/prisma/internal/class.d.ts +281 -0
  15. package/dist/generated/prisma/internal/class.d.ts.map +1 -0
  16. package/dist/generated/prisma/internal/class.js +76 -0
  17. package/dist/generated/prisma/internal/prismaNamespace.d.ts +1734 -0
  18. package/dist/generated/prisma/internal/prismaNamespace.d.ts.map +1 -0
  19. package/dist/generated/prisma/internal/prismaNamespace.js +260 -0
  20. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +200 -0
  21. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts.map +1 -0
  22. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +231 -0
  23. package/dist/generated/prisma/models/cache.d.ts +986 -0
  24. package/dist/generated/prisma/models/cache.d.ts.map +1 -0
  25. package/dist/generated/prisma/models/cache.js +2 -0
  26. package/dist/generated/prisma/models/cache_locks.d.ts +976 -0
  27. package/dist/generated/prisma/models/cache_locks.d.ts.map +1 -0
  28. package/dist/generated/prisma/models/cache_locks.js +2 -0
  29. package/dist/generated/prisma/models/failed_jobs.d.ts +1098 -0
  30. package/dist/generated/prisma/models/failed_jobs.d.ts.map +1 -0
  31. package/dist/generated/prisma/models/failed_jobs.js +2 -0
  32. package/dist/generated/prisma/models/job_batches.d.ts +1212 -0
  33. package/dist/generated/prisma/models/job_batches.d.ts.map +1 -0
  34. package/dist/generated/prisma/models/job_batches.js +2 -0
  35. package/dist/generated/prisma/models/jobs.d.ts +1112 -0
  36. package/dist/generated/prisma/models/jobs.d.ts.map +1 -0
  37. package/dist/generated/prisma/models/jobs.js +2 -0
  38. package/dist/generated/prisma/models/migrations.d.ts +979 -0
  39. package/dist/generated/prisma/models/migrations.d.ts.map +1 -0
  40. package/dist/generated/prisma/models/migrations.js +2 -0
  41. package/dist/generated/prisma/models/password_reset_tokens.d.ts +941 -0
  42. package/dist/generated/prisma/models/password_reset_tokens.d.ts.map +1 -0
  43. package/dist/generated/prisma/models/password_reset_tokens.js +2 -0
  44. package/dist/generated/prisma/models/permissions.d.ts +1333 -0
  45. package/dist/generated/prisma/models/permissions.d.ts.map +1 -0
  46. package/dist/generated/prisma/models/permissions.js +2 -0
  47. package/dist/generated/prisma/models/personal_access_tokens.d.ts +1178 -0
  48. package/dist/generated/prisma/models/personal_access_tokens.d.ts.map +1 -0
  49. package/dist/generated/prisma/models/personal_access_tokens.js +2 -0
  50. package/dist/generated/prisma/models/role_permissions.d.ts +1291 -0
  51. package/dist/generated/prisma/models/role_permissions.d.ts.map +1 -0
  52. package/dist/generated/prisma/models/role_permissions.js +2 -0
  53. package/dist/generated/prisma/models/roles.d.ts +1333 -0
  54. package/dist/generated/prisma/models/roles.d.ts.map +1 -0
  55. package/dist/generated/prisma/models/roles.js +2 -0
  56. package/dist/generated/prisma/models/sessions.d.ts +1073 -0
  57. package/dist/generated/prisma/models/sessions.d.ts.map +1 -0
  58. package/dist/generated/prisma/models/sessions.js +2 -0
  59. package/dist/generated/prisma/models/user_permissions.d.ts +1291 -0
  60. package/dist/generated/prisma/models/user_permissions.d.ts.map +1 -0
  61. package/dist/generated/prisma/models/user_permissions.js +2 -0
  62. package/dist/generated/prisma/models/user_roles.d.ts +1291 -0
  63. package/dist/generated/prisma/models/user_roles.d.ts.map +1 -0
  64. package/dist/generated/prisma/models/user_roles.js +2 -0
  65. package/dist/generated/prisma/models/users.d.ts +1513 -0
  66. package/dist/generated/prisma/models/users.d.ts.map +1 -0
  67. package/dist/generated/prisma/models/users.js +2 -0
  68. package/dist/generated/prisma/models.d.ts +17 -0
  69. package/dist/generated/prisma/models.d.ts.map +1 -0
  70. package/dist/generated/prisma/models.js +2 -0
  71. package/dist/lib/bootstrap.d.ts +2 -0
  72. package/dist/lib/bootstrap.d.ts.map +1 -0
  73. package/dist/lib/bootstrap.js +133 -0
  74. package/dist/lib/core/database.d.ts +3 -0
  75. package/dist/lib/core/database.d.ts.map +1 -0
  76. package/dist/lib/core/database.js +34 -0
  77. package/dist/lib/core/realtime.d.ts +3 -0
  78. package/dist/lib/core/realtime.d.ts.map +1 -0
  79. package/dist/lib/core/realtime.js +36 -0
  80. package/dist/lib/core/redis.d.ts +8 -0
  81. package/dist/lib/core/redis.d.ts.map +1 -0
  82. package/dist/lib/core/redis.js +123 -0
  83. package/dist/lib/core/serializer.d.ts +43 -0
  84. package/dist/lib/core/serializer.d.ts.map +1 -0
  85. package/dist/lib/core/serializer.js +66 -0
  86. package/dist/lib/core/server.d.ts +2 -0
  87. package/dist/lib/core/server.d.ts.map +1 -0
  88. package/dist/lib/core/server.js +60 -0
  89. package/dist/lib/middleware/auth.d.ts +4 -0
  90. package/dist/lib/middleware/auth.d.ts.map +1 -0
  91. package/dist/lib/middleware/auth.js +55 -0
  92. package/dist/lib/middleware/error.d.ts +3 -0
  93. package/dist/lib/middleware/error.d.ts.map +1 -0
  94. package/dist/lib/middleware/error.js +60 -0
  95. package/dist/lib/middleware/multipart.d.ts +4 -0
  96. package/dist/lib/middleware/multipart.d.ts.map +1 -0
  97. package/dist/lib/middleware/multipart.js +17 -0
  98. package/dist/lib/middleware/rateLimit.d.ts +2 -0
  99. package/dist/lib/middleware/rateLimit.d.ts.map +1 -0
  100. package/dist/lib/middleware/rateLimit.js +19 -0
  101. package/dist/lib/middleware/requestLogger.d.ts +3 -0
  102. package/dist/lib/middleware/requestLogger.d.ts.map +1 -0
  103. package/dist/lib/middleware/requestLogger.js +22 -0
  104. package/dist/lib/middleware/visitor.d.ts +3 -0
  105. package/dist/lib/middleware/visitor.d.ts.map +1 -0
  106. package/dist/lib/middleware/visitor.js +144 -0
  107. package/dist/lib/utils/logger.d.ts +11 -0
  108. package/dist/lib/utils/logger.d.ts.map +1 -0
  109. package/dist/lib/utils/logger.js +81 -0
  110. package/dist/lib/utils/pagination.d.ts +19 -0
  111. package/dist/lib/utils/pagination.d.ts.map +1 -0
  112. package/dist/lib/utils/pagination.js +34 -0
  113. package/dist/lib/utils/response.d.ts +11 -0
  114. package/dist/lib/utils/response.d.ts.map +1 -0
  115. package/dist/lib/utils/response.js +57 -0
  116. package/dist/lib/utils/validator.d.ts +38 -0
  117. package/dist/lib/utils/validator.d.ts.map +1 -0
  118. package/dist/lib/utils/validator.js +369 -0
  119. package/dist/prisma/seed.d.ts +2 -0
  120. package/dist/prisma/seed.d.ts.map +1 -0
  121. package/dist/prisma/seed.js +381 -0
  122. package/dist/src/controllers/authController.d.ts +11 -0
  123. package/dist/src/controllers/authController.d.ts.map +1 -0
  124. package/dist/src/controllers/authController.js +414 -0
  125. package/dist/src/controllers/petController.d.ts +7 -0
  126. package/dist/src/controllers/petController.d.ts.map +1 -0
  127. package/dist/src/controllers/petController.js +163 -0
  128. package/dist/src/controllers/rbacController.d.ts +16 -0
  129. package/dist/src/controllers/rbacController.d.ts.map +1 -0
  130. package/dist/src/controllers/rbacController.js +437 -0
  131. package/dist/src/core/database.d.ts +3 -0
  132. package/dist/src/core/database.d.ts.map +1 -0
  133. package/dist/src/core/database.js +34 -0
  134. package/dist/src/core/realtime.d.ts +3 -0
  135. package/dist/src/core/realtime.d.ts.map +1 -0
  136. package/dist/src/core/realtime.js +36 -0
  137. package/dist/src/core/redis.d.ts +8 -0
  138. package/dist/src/core/redis.d.ts.map +1 -0
  139. package/dist/src/core/redis.js +123 -0
  140. package/dist/src/core/serializer.d.ts +43 -0
  141. package/dist/src/core/serializer.d.ts.map +1 -0
  142. package/dist/src/core/serializer.js +66 -0
  143. package/dist/src/core/server.d.ts +2 -0
  144. package/dist/src/core/server.d.ts.map +1 -0
  145. package/dist/src/core/server.js +60 -0
  146. package/dist/src/index.d.ts +2 -0
  147. package/dist/src/index.d.ts.map +1 -0
  148. package/dist/src/index.js +98 -0
  149. package/dist/src/middleware/auth.d.ts +4 -0
  150. package/dist/src/middleware/auth.d.ts.map +1 -0
  151. package/dist/src/middleware/auth.js +48 -0
  152. package/dist/src/middleware/error.d.ts +3 -0
  153. package/dist/src/middleware/error.d.ts.map +1 -0
  154. package/dist/src/middleware/error.js +60 -0
  155. package/dist/src/middleware/multipart.d.ts +4 -0
  156. package/dist/src/middleware/multipart.d.ts.map +1 -0
  157. package/dist/src/middleware/multipart.js +17 -0
  158. package/dist/src/middleware/rateLimit.d.ts +2 -0
  159. package/dist/src/middleware/rateLimit.d.ts.map +1 -0
  160. package/dist/src/middleware/rateLimit.js +19 -0
  161. package/dist/src/middleware/requestLogger.d.ts +3 -0
  162. package/dist/src/middleware/requestLogger.d.ts.map +1 -0
  163. package/dist/src/middleware/requestLogger.js +22 -0
  164. package/dist/src/middleware/visitor.d.ts +3 -0
  165. package/dist/src/middleware/visitor.d.ts.map +1 -0
  166. package/dist/src/middleware/visitor.js +144 -0
  167. package/dist/src/prisma.d.ts +3 -0
  168. package/dist/src/prisma.d.ts.map +1 -0
  169. package/dist/src/prisma.js +34 -0
  170. package/dist/src/realtime.d.ts +3 -0
  171. package/dist/src/realtime.d.ts.map +1 -0
  172. package/dist/src/realtime.js +36 -0
  173. package/dist/src/redis.d.ts +8 -0
  174. package/dist/src/redis.d.ts.map +1 -0
  175. package/dist/src/redis.js +122 -0
  176. package/dist/src/routes/auth.d.ts +2 -0
  177. package/dist/src/routes/auth.d.ts.map +1 -0
  178. package/dist/src/routes/auth.js +45 -0
  179. package/dist/src/routes/index.d.ts +2 -0
  180. package/dist/src/routes/index.d.ts.map +1 -0
  181. package/dist/src/routes/index.js +14 -0
  182. package/dist/src/routes/pets.d.ts +3 -0
  183. package/dist/src/routes/pets.d.ts.map +1 -0
  184. package/dist/src/routes/pets.js +45 -0
  185. package/dist/src/routes/rbac.d.ts +2 -0
  186. package/dist/src/routes/rbac.d.ts.map +1 -0
  187. package/dist/src/routes/rbac.js +23 -0
  188. package/dist/src/schema/auth-schema.d.ts +76 -0
  189. package/dist/src/schema/auth-schema.d.ts.map +1 -0
  190. package/dist/src/schema/auth-schema.js +63 -0
  191. package/dist/src/schema/pet-schema.d.ts +28 -0
  192. package/dist/src/schema/pet-schema.d.ts.map +1 -0
  193. package/dist/src/schema/pet-schema.js +14 -0
  194. package/dist/src/server.d.ts +2 -0
  195. package/dist/src/server.d.ts.map +1 -0
  196. package/dist/src/server.js +31 -0
  197. package/dist/src/utils/logger.d.ts +11 -0
  198. package/dist/src/utils/logger.d.ts.map +1 -0
  199. package/dist/src/utils/logger.js +81 -0
  200. package/dist/src/utils/pagination.d.ts +19 -0
  201. package/dist/src/utils/pagination.d.ts.map +1 -0
  202. package/dist/src/utils/pagination.js +34 -0
  203. package/dist/src/utils/response.d.ts +11 -0
  204. package/dist/src/utils/response.d.ts.map +1 -0
  205. package/dist/src/utils/response.js +57 -0
  206. package/dist/src/utils/validator.d.ts +38 -0
  207. package/dist/src/utils/validator.d.ts.map +1 -0
  208. package/dist/src/utils/validator.js +369 -0
  209. package/lib/bootstrap.ts +6 -0
  210. package/package.json +26 -14
  211. package/.env.example +0 -19
  212. package/doc/ARCHITECTURE_GUIDE.md +0 -73
  213. package/doc/CHANGELOG.md +0 -77
  214. package/doc/CHEATSHEET.md +0 -94
  215. package/doc/CLI.md +0 -139
  216. package/doc/CONTRIBUTING.md +0 -105
  217. package/doc/DEPLOYMENT.md +0 -122
  218. package/doc/FAQ.md +0 -81
  219. package/doc/FEATURES.md +0 -165
  220. package/doc/GETTING_STARTED.md +0 -108
  221. package/doc/INTRODUCTION.md +0 -60
  222. package/doc/PACKAGES.md +0 -66
  223. package/doc/PERFORMANCE.md +0 -91
  224. package/doc/ROADMAP.md +0 -93
  225. package/doc/SECURITY.md +0 -93
  226. package/doc/STRUCTURE.md +0 -90
  227. package/doc/TUTORIAL.md +0 -192
  228. package/docker-compose.yml +0 -24
  229. package/eslint.config.mjs +0 -26
  230. package/framework.md +0 -168
  231. package/nodemon.json +0 -6
  232. package/prisma.config.ts +0 -15
  233. package/src/controllers/authController.ts +0 -469
  234. package/src/controllers/petController.ts +0 -194
  235. package/src/controllers/rbacController.ts +0 -478
  236. package/src/models/core.prisma +0 -163
  237. package/src/models/pets.prisma +0 -9
  238. package/src/routes/auth.ts +0 -74
  239. package/src/routes/index.ts +0 -10
  240. package/src/routes/pets.ts +0 -13
  241. package/src/routes/rbac.ts +0 -42
  242. package/storage/logs/.gitkeep +0 -0
  243. package/tsconfig.json +0 -30
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/prisma.ts"],"names":[],"mappings":"AAOA,QAAA,IAAI,MAAM,EAAE,GAAG,CAAC;AAyBhB,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prisma = void 0;
4
+ const { PrismaClient } = require("@prisma/client");
5
+ const adapter_pg_1 = require("@prisma/adapter-pg");
6
+ const adapter_mariadb_1 = require("@prisma/adapter-mariadb");
7
+ const url = process.env.DATABASE_URL || "";
8
+ const provider = (process.env.DATABASE_PROVIDER || "").toLowerCase();
9
+ let prisma;
10
+ if (provider === "postgresql" || url.startsWith("postgres")) {
11
+ const adapter = new adapter_pg_1.PrismaPg({ connectionString: url });
12
+ exports.prisma = prisma = new PrismaClient({ adapter });
13
+ }
14
+ else {
15
+ if (provider === "mysql" || url.startsWith("mysql")) {
16
+ try {
17
+ const u = new URL(url);
18
+ const adapter = new adapter_mariadb_1.PrismaMariaDb({
19
+ host: u.hostname,
20
+ port: Number(u.port || "3306"),
21
+ user: decodeURIComponent(u.username),
22
+ password: decodeURIComponent(u.password),
23
+ database: u.pathname.replace("/", ""),
24
+ });
25
+ exports.prisma = prisma = new PrismaClient({ adapter });
26
+ }
27
+ catch {
28
+ exports.prisma = prisma = new PrismaClient({});
29
+ }
30
+ }
31
+ else {
32
+ exports.prisma = prisma = new PrismaClient({});
33
+ }
34
+ }
@@ -0,0 +1,3 @@
1
+ export declare function initRealtime(server: import("http").Server): void;
2
+ export declare function notifyUser(userId: string, event: string, payload: any): void;
3
+ //# sourceMappingURL=realtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/realtime.ts"],"names":[],"mappings":"AAKA,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,MAAM,QAuBzD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAGrE"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initRealtime = initRealtime;
7
+ exports.notifyUser = notifyUser;
8
+ const socket_io_1 = require("socket.io");
9
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
10
+ let io = null;
11
+ function initRealtime(server) {
12
+ io = new socket_io_1.Server(server, {
13
+ cors: { origin: "*", methods: ["GET", "POST", "PUT", "DELETE"] },
14
+ });
15
+ io.on("connection", (socket) => {
16
+ const token = socket.handshake.query?.token ||
17
+ socket.handshake.headers["authorization"]
18
+ ?.toString()
19
+ ?.replace("Bearer ", "") ||
20
+ "";
21
+ const secret = process.env.JWT_SECRET;
22
+ if (secret && token) {
23
+ try {
24
+ const payload = jsonwebtoken_1.default.verify(token, secret);
25
+ const room = `user:${payload.userId}`;
26
+ socket.join(room);
27
+ }
28
+ catch { }
29
+ }
30
+ });
31
+ }
32
+ function notifyUser(userId, event, payload) {
33
+ if (!io)
34
+ return;
35
+ io.to(`user:${userId}`).emit(event, payload);
36
+ }
@@ -0,0 +1,8 @@
1
+ import Redis from "ioredis";
2
+ export declare function initRedis(): Promise<void>;
3
+ declare const redisProxy: Redis;
4
+ export declare function getCache(key: string): Promise<any>;
5
+ export declare function setCache(key: string, value: any, ttlSeconds?: number): Promise<void>;
6
+ export declare function delCache(key: string): Promise<void>;
7
+ export { redisProxy as redis };
8
+ //# sourceMappingURL=redis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,SAAS,CAAC;AA4D5B,wBAAsB,SAAS,kBAoC9B;AAGD,QAAA,MAAM,UAAU,OAKd,CAAC;AAEH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,gBAOzC;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,SAAK,iBAItE;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,iBAIzC;AAGD,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,CAAC"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.redis = void 0;
7
+ exports.initRedis = initRedis;
8
+ exports.getCache = getCache;
9
+ exports.setCache = setCache;
10
+ exports.delCache = delCache;
11
+ const ioredis_1 = __importDefault(require("ioredis"));
12
+ // @ts-ignore
13
+ const ioredis_mock_1 = __importDefault(require("ioredis-mock"));
14
+ const redisUrl = process.env.REDIS_URL || "redis://localhost:6379";
15
+ // Create a wrapper to handle connection attempts
16
+ let redis;
17
+ let isRedisConnected = false;
18
+ // If explicitly disabled via env
19
+ if (process.env.NO_REDIS === "true") {
20
+ console.log("Redis disabled via NO_REDIS, using in-memory mock.");
21
+ redis = new ioredis_mock_1.default();
22
+ isRedisConnected = true;
23
+ }
24
+ else {
25
+ // Try to connect to real Redis
26
+ redis = new ioredis_1.default(redisUrl, {
27
+ lazyConnect: true,
28
+ maxRetriesPerRequest: 1,
29
+ retryStrategy: (times) => {
30
+ // Retry 3 times then give up
31
+ if (times > 3)
32
+ return null;
33
+ return 200;
34
+ },
35
+ });
36
+ }
37
+ redis.on("ready", () => {
38
+ isRedisConnected = true;
39
+ // console.log("Redis connected!");
40
+ });
41
+ redis.on("error", (err) => {
42
+ // If connection fails and we haven't switched to mock yet
43
+ if (!isRedisConnected && !(redis instanceof ioredis_mock_1.default)) {
44
+ // console.log("Redis connection failed, switching to in-memory mock...");
45
+ // Replace the global redis instance with mock
46
+ // Note: This is a runtime switch. Existing listeners might be lost if we don't handle carefully.
47
+ // However, for a simple fallback, we can just use the mock for future calls.
48
+ // Better approach: Since we exported 'redis' as a const (reference), we can't reassign it easily
49
+ // if other modules already imported it.
50
+ // BUT, ioredis instance itself is an EventEmitter.
51
+ // Strategy: We keep 'redis' as the main interface.
52
+ // If real redis fails, we just don't set isRedisConnected to true for the *real* one.
53
+ // But wait, the user wants 'bundle redis'.
54
+ // The best way is to detect failure during init and SWAP the implementation.
55
+ }
56
+ isRedisConnected = false;
57
+ });
58
+ // We need a way to seamlessly switch or just default to Mock if connect fails.
59
+ // Since 'redis' is exported immediately, we can't easily swap the object reference for importers.
60
+ // PROXY APPROACH:
61
+ // We export a Proxy that forwards to real redis OR mock redis.
62
+ const mockRedis = new ioredis_mock_1.default();
63
+ let activeRedis = redis; // Start with real redis attempt
64
+ // Custom init function to determine which one to use
65
+ async function initRedis() {
66
+ if (process.env.NO_REDIS === "true") {
67
+ activeRedis = mockRedis;
68
+ console.log("✅ Redis: Active (Source: Zero-Config Redis [NO_REDIS=true])");
69
+ if (process.env.NODE_ENV === "production") {
70
+ console.warn("⚠️ WARNING: Running in PRODUCTION with in-memory Redis mock. Data will be lost on restart and not shared between instances.");
71
+ }
72
+ return;
73
+ }
74
+ try {
75
+ await redis.connect();
76
+ activeRedis = redis; // Keep using real redis
77
+ isRedisConnected = true;
78
+ // Determine source label
79
+ const sourceLabel = process.env.REDIS_URL
80
+ ? redisUrl
81
+ : "Zero-Config Redis (Localhost)";
82
+ console.log(`✅ Redis: Active (Source: ${sourceLabel})`);
83
+ }
84
+ catch (err) {
85
+ // Connection failed, switch to mock
86
+ console.log(`⚠️ Redis: Connection failed to ${redisUrl}, switching to fallback (Source: Zero-Config Redis [Mock])`);
87
+ activeRedis = mockRedis;
88
+ isRedisConnected = true; // Mock is always "connected"
89
+ if (process.env.NODE_ENV === "production") {
90
+ console.warn("⚠️ WARNING: Redis connection failed in PRODUCTION. Switched to in-memory mock. Data will be lost on restart.");
91
+ }
92
+ }
93
+ }
94
+ // Proxy handler to forward all calls to activeRedis
95
+ const redisProxy = new Proxy({}, {
96
+ get: (target, prop) => {
97
+ // @ts-ignore
98
+ return activeRedis[prop];
99
+ },
100
+ });
101
+ exports.redis = redisProxy;
102
+ async function getCache(key) {
103
+ try {
104
+ const v = await activeRedis.get(key);
105
+ return v ? JSON.parse(v) : null;
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ }
111
+ async function setCache(key, value, ttlSeconds = 60) {
112
+ try {
113
+ await activeRedis.set(key, JSON.stringify(value), "EX", ttlSeconds);
114
+ }
115
+ catch { }
116
+ }
117
+ async function delCache(key) {
118
+ try {
119
+ await activeRedis.del(key);
120
+ }
121
+ catch { }
122
+ }
@@ -0,0 +1,2 @@
1
+ export declare const authRouter: import("express-serve-static-core").Router;
2
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/routes/auth.ts"],"names":[],"mappings":"AAoDA,eAAO,MAAM,UAAU,4CAAW,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.authRouter = void 0;
7
+ const express_1 = require("express");
8
+ const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
9
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
10
+ const multer = require("multer");
11
+ const path_1 = __importDefault(require("path"));
12
+ const fs_1 = __importDefault(require("fs"));
13
+ const authController_1 = require("../controllers/authController");
14
+ const auth_1 = require("../../lib/middleware/auth");
15
+ const authLimiter = (0, express_rate_limit_1.default)({
16
+ windowMs: 15 * 60 * 1000,
17
+ max: 50,
18
+ standardHeaders: true,
19
+ legacyHeaders: false,
20
+ });
21
+ const avatarUploadDir = process.env.AVATAR_UPLOAD_DIR || "uploads/avatars";
22
+ if (!fs_1.default.existsSync(avatarUploadDir)) {
23
+ fs_1.default.mkdirSync(avatarUploadDir, { recursive: true });
24
+ }
25
+ const storage = multer.diskStorage({
26
+ destination(_req, _file, cb) {
27
+ cb(null, avatarUploadDir);
28
+ },
29
+ filename(_req, file, cb) {
30
+ const ext = path_1.default.extname(file.originalname);
31
+ const base = path_1.default.basename(file.originalname, ext);
32
+ const unique = Date.now() + "-" + Math.round(Math.random() * 1e9);
33
+ cb(null, base + "-" + unique + ext);
34
+ },
35
+ });
36
+ const uploadAvatar = multer({ storage });
37
+ exports.authRouter = (0, express_1.Router)();
38
+ exports.authRouter.post("/register", authLimiter, authController_1.register);
39
+ exports.authRouter.post("/login", authLimiter, authController_1.login);
40
+ exports.authRouter.get("/me", auth_1.requireAuth, authController_1.me);
41
+ exports.authRouter.post("/logout", auth_1.requireAuth, authController_1.logout);
42
+ exports.authRouter.post("/refresh", authLimiter, authController_1.refreshToken);
43
+ exports.authRouter.put("/password", auth_1.requireAuth, authController_1.updatePassword);
44
+ exports.authRouter.put("/profile", auth_1.requireAuth, authController_1.updateProfile);
45
+ exports.authRouter.post("/avatar", auth_1.requireAuth, uploadAvatar.single("avatar"), authController_1.updateAvatar);
@@ -0,0 +1,2 @@
1
+ export declare const apiRouter: import("express-serve-static-core").Router;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,SAAS,4CAAW,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.apiRouter = void 0;
7
+ const express_1 = require("express");
8
+ const auth_1 = require("../routes/auth");
9
+ const rbac_1 = require("../routes/rbac");
10
+ const pets_1 = __importDefault(require("../routes/pets"));
11
+ exports.apiRouter = (0, express_1.Router)();
12
+ exports.apiRouter.use("/auth", auth_1.authRouter);
13
+ exports.apiRouter.use("/rbac", rbac_1.rbacRouter);
14
+ exports.apiRouter.use("/pets", pets_1.default);
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=pets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pets.d.ts","sourceRoot":"","sources":["../../../src/routes/pets.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAQxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const express_1 = require("express");
37
+ const PetController = __importStar(require("../controllers/petController"));
38
+ const multipart_1 = require("../../lib/middleware/multipart");
39
+ const router = (0, express_1.Router)();
40
+ router.get("/", PetController.index);
41
+ router.get("/:id", PetController.show);
42
+ router.post("/", multipart_1.parseMultipart, PetController.store);
43
+ router.put("/:id", multipart_1.parseMultipart, PetController.update);
44
+ router.delete("/:id", PetController.destroy);
45
+ exports.default = router;
@@ -0,0 +1,2 @@
1
+ export declare const rbacRouter: import("express-serve-static-core").Router;
2
+ //# sourceMappingURL=rbac.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.d.ts","sourceRoot":"","sources":["../../../src/routes/rbac.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,UAAU,4CAAW,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rbacRouter = void 0;
4
+ const express_1 = require("express");
5
+ const auth_1 = require("../../lib/middleware/auth");
6
+ const rbacController_1 = require("../controllers/rbacController");
7
+ exports.rbacRouter = (0, express_1.Router)();
8
+ exports.rbacRouter.use(auth_1.requireAuth);
9
+ exports.rbacRouter.use(auth_1.requireAdmin);
10
+ exports.rbacRouter.post("/roles", rbacController_1.createRole);
11
+ exports.rbacRouter.get("/roles", rbacController_1.listRoles);
12
+ exports.rbacRouter.put("/roles/:id", rbacController_1.updateRole);
13
+ exports.rbacRouter.delete("/roles/:id", rbacController_1.deleteRole);
14
+ exports.rbacRouter.post("/permissions", rbacController_1.createPermission);
15
+ exports.rbacRouter.get("/permissions", rbacController_1.listPermissions);
16
+ exports.rbacRouter.put("/permissions/:id", rbacController_1.updatePermission);
17
+ exports.rbacRouter.delete("/permissions/:id", rbacController_1.deletePermission);
18
+ exports.rbacRouter.post("/users/assign-role", rbacController_1.assignRoleToUser);
19
+ exports.rbacRouter.post("/users/remove-role", rbacController_1.removeRoleFromUser);
20
+ exports.rbacRouter.post("/roles/assign-permission", rbacController_1.assignPermissionToRole);
21
+ exports.rbacRouter.post("/roles/remove-permission", rbacController_1.removePermissionFromRole);
22
+ exports.rbacRouter.post("/users/assign-permission", rbacController_1.assignPermissionToUser);
23
+ exports.rbacRouter.post("/users/remove-permission", rbacController_1.removePermissionFromUser);
@@ -0,0 +1,76 @@
1
+ import z from "zod";
2
+ export declare const registerSchema: z.ZodEffects<z.ZodObject<{
3
+ email: z.ZodString;
4
+ name: z.ZodString;
5
+ password: z.ZodString;
6
+ confirmPassword: z.ZodString;
7
+ }, "strip", z.ZodTypeAny, {
8
+ email: string;
9
+ name: string;
10
+ password: string;
11
+ confirmPassword: string;
12
+ }, {
13
+ email: string;
14
+ name: string;
15
+ password: string;
16
+ confirmPassword: string;
17
+ }>, {
18
+ email: string;
19
+ name: string;
20
+ password: string;
21
+ confirmPassword: string;
22
+ }, {
23
+ email: string;
24
+ name: string;
25
+ password: string;
26
+ confirmPassword: string;
27
+ }>;
28
+ export declare const loginSchema: z.ZodObject<{
29
+ email: z.ZodString;
30
+ password: z.ZodString;
31
+ }, "strip", z.ZodTypeAny, {
32
+ email: string;
33
+ password: string;
34
+ }, {
35
+ email: string;
36
+ password: string;
37
+ }>;
38
+ export declare const refreshSchema: z.ZodObject<{
39
+ refreshToken: z.ZodString;
40
+ }, "strip", z.ZodTypeAny, {
41
+ refreshToken: string;
42
+ }, {
43
+ refreshToken: string;
44
+ }>;
45
+ export declare const updatePasswordSchema: z.ZodEffects<z.ZodObject<{
46
+ currentPassword: z.ZodString;
47
+ newPassword: z.ZodString;
48
+ confirmPassword: z.ZodString;
49
+ }, "strip", z.ZodTypeAny, {
50
+ confirmPassword: string;
51
+ currentPassword: string;
52
+ newPassword: string;
53
+ }, {
54
+ confirmPassword: string;
55
+ currentPassword: string;
56
+ newPassword: string;
57
+ }>, {
58
+ confirmPassword: string;
59
+ currentPassword: string;
60
+ newPassword: string;
61
+ }, {
62
+ confirmPassword: string;
63
+ currentPassword: string;
64
+ newPassword: string;
65
+ }>;
66
+ export declare const updateProfileSchema: z.ZodObject<{
67
+ name: z.ZodString;
68
+ email: z.ZodString;
69
+ }, "strip", z.ZodTypeAny, {
70
+ email: string;
71
+ name: string;
72
+ }, {
73
+ email: string;
74
+ name: string;
75
+ }>;
76
+ //# sourceMappingURL=auth-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-schema.d.ts","sourceRoot":"","sources":["../../../src/schema/auth-schema.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;EAkBvB,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;;;;;EAOtB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;EAIxB,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;EAe7B,CAAC;AAEL,eAAO,MAAM,mBAAmB;;;;;;;;;EAO9B,CAAC"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.updateProfileSchema = exports.updatePasswordSchema = exports.refreshSchema = exports.loginSchema = exports.registerSchema = void 0;
7
+ const zod_1 = __importDefault(require("zod"));
8
+ exports.registerSchema = zod_1.default
9
+ .object({
10
+ email: zod_1.default
11
+ .string({ required_error: "Email is required" })
12
+ .email("Invalid email format"),
13
+ name: zod_1.default
14
+ .string({ required_error: "Name is required" })
15
+ .min(1, "Name is required"),
16
+ password: zod_1.default
17
+ .string({ required_error: "Password is required" })
18
+ .min(4, "Password must be at least 4 characters"),
19
+ confirmPassword: zod_1.default
20
+ .string({ required_error: "Confirm password is required" })
21
+ .min(4, "Confirm password must be at least 4 characters"),
22
+ })
23
+ .refine((data) => data.password === data.confirmPassword, {
24
+ path: ["confirmPassword"],
25
+ message: "Confirm password does not match",
26
+ });
27
+ exports.loginSchema = zod_1.default.object({
28
+ email: zod_1.default
29
+ .string({ required_error: "Email is required" })
30
+ .email("Invalid email format"),
31
+ password: zod_1.default
32
+ .string({ required_error: "Password is required" })
33
+ .min(4, "Password must be at least 4 characters"),
34
+ });
35
+ exports.refreshSchema = zod_1.default.object({
36
+ refreshToken: zod_1.default
37
+ .string({ required_error: "Refresh token is required" })
38
+ .min(1, "Refresh token is required"),
39
+ });
40
+ exports.updatePasswordSchema = zod_1.default
41
+ .object({
42
+ currentPassword: zod_1.default
43
+ .string({ required_error: "Current password is required" })
44
+ .min(4, "Current password must be at least 4 characters"),
45
+ newPassword: zod_1.default
46
+ .string({ required_error: "New password is required" })
47
+ .min(4, "New password must be at least 4 characters"),
48
+ confirmPassword: zod_1.default
49
+ .string({ required_error: "Confirm password is required" })
50
+ .min(4, "Confirm password must be at least 4 characters"),
51
+ })
52
+ .refine((data) => data.newPassword === data.confirmPassword, {
53
+ path: ["confirmPassword"],
54
+ message: "Confirm password does not match",
55
+ });
56
+ exports.updateProfileSchema = zod_1.default.object({
57
+ name: zod_1.default
58
+ .string({ required_error: "Name is required" })
59
+ .min(1, "Name is required"),
60
+ email: zod_1.default
61
+ .string({ required_error: "Email is required" })
62
+ .email("Invalid email format"),
63
+ });
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ export declare const createPetSchema: z.ZodObject<{
3
+ name: z.ZodString;
4
+ species: z.ZodString;
5
+ age: z.ZodNumber;
6
+ }, "strip", z.ZodTypeAny, {
7
+ name: string;
8
+ species: string;
9
+ age: number;
10
+ }, {
11
+ name: string;
12
+ species: string;
13
+ age: number;
14
+ }>;
15
+ export declare const updatePetSchema: z.ZodObject<{
16
+ name: z.ZodOptional<z.ZodString>;
17
+ species: z.ZodOptional<z.ZodString>;
18
+ age: z.ZodOptional<z.ZodNumber>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ name?: string | undefined;
21
+ species?: string | undefined;
22
+ age?: number | undefined;
23
+ }, {
24
+ name?: string | undefined;
25
+ species?: string | undefined;
26
+ age?: number | undefined;
27
+ }>;
28
+ //# sourceMappingURL=pet-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pet-schema.d.ts","sourceRoot":"","sources":["../../../src/schema/pet-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,eAAe;;;;;;;;;;;;EAI1B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;EAI1B,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updatePetSchema = exports.createPetSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.createPetSchema = zod_1.z.object({
6
+ name: zod_1.z.string({ message: "Name is required" }),
7
+ species: zod_1.z.string({ message: "Species is required" }),
8
+ age: zod_1.z.number({ message: "Age is required" }).int().positive(),
9
+ });
10
+ exports.updatePetSchema = zod_1.z.object({
11
+ name: zod_1.z.string().optional(),
12
+ species: zod_1.z.string().optional(),
13
+ age: zod_1.z.number().int().positive().optional(),
14
+ });
@@ -0,0 +1,2 @@
1
+ export declare const app: import("express-serve-static-core").Express;
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,GAAG,6CAAY,CAAC"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.app = void 0;
7
+ const express_1 = __importDefault(require("express"));
8
+ const cors_1 = __importDefault(require("cors"));
9
+ const helmet_1 = __importDefault(require("helmet"));
10
+ const auth_1 = require("./routes/auth");
11
+ const rbac_1 = require("./routes/rbac");
12
+ const pets_1 = __importDefault(require("./routes/pets"));
13
+ const visitor_1 = require("./middleware/visitor");
14
+ const error_1 = require("./middleware/error");
15
+ exports.app = (0, express_1.default)();
16
+ exports.app.disable("x-powered-by");
17
+ exports.app.use((0, helmet_1.default)({
18
+ contentSecurityPolicy: false,
19
+ }));
20
+ const corsOrigin = process.env.CORS_ORIGIN || "*";
21
+ exports.app.use((0, cors_1.default)({
22
+ origin: corsOrigin,
23
+ credentials: true,
24
+ exposedHeaders: ["x-access-token", "x-access-expires-at"],
25
+ }));
26
+ exports.app.use(express_1.default.json({ limit: "1mb" }));
27
+ exports.app.use(visitor_1.visitorCounter);
28
+ exports.app.use("/api/auth", auth_1.authRouter);
29
+ exports.app.use("/api/rbac", rbac_1.rbacRouter);
30
+ exports.app.use("/api/pets", pets_1.default);
31
+ exports.app.use(error_1.errorHandler);
@@ -0,0 +1,11 @@
1
+ import winston from "winston";
2
+ import "winston-daily-rotate-file";
3
+ declare const logger: winston.Logger;
4
+ export declare class Log {
5
+ static info(message: string, meta?: any): void;
6
+ static error(message: string, meta?: any): void;
7
+ static warn(message: string, meta?: any): void;
8
+ static debug(message: string, meta?: any): void;
9
+ }
10
+ export default logger;
11
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,2BAA2B,CAAC;AAiDnC,QAAA,MAAM,MAAM,gBAgBV,CAAC;AAeH,qBAAa,GAAG;IACd,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;IAIvC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;IAIxC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;IAIvC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;CAGzC;AAED,eAAe,MAAM,CAAC"}