arkos 0.7.0-beta.1 → 0.9.0-beta.1

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/cjs/modules/auth/__tests__/auth.controller.test.js +2 -0
  2. package/dist/cjs/modules/auth/__tests__/auth.controller.test.js.map +1 -0
  3. package/dist/cjs/modules/auth/auth.service.js +1 -1
  4. package/dist/cjs/modules/auth/auth.service.js.map +1 -1
  5. package/dist/cjs/modules/auth/utils/helpers/__tests__/auth.helpers.test.js +2 -0
  6. package/dist/cjs/modules/auth/utils/helpers/__tests__/auth.helpers.test.js.map +1 -0
  7. package/dist/cjs/modules/base/utils/helpers/__tests__/base.helpers.test.js +2 -0
  8. package/dist/cjs/modules/base/utils/helpers/__tests__/base.helpers.test.js.map +1 -0
  9. package/dist/cjs/utils/helpers/models.helpers.js +51 -18
  10. package/dist/cjs/utils/helpers/models.helpers.js.map +1 -1
  11. package/dist/cjs/utils/helpers/pluralize.helpers.js +0 -1
  12. package/dist/cjs/utils/helpers/prisma.helpers.js +34 -1
  13. package/dist/cjs/utils/helpers/prisma.helpers.js.map +1 -1
  14. package/dist/es2020/app.js +1 -1
  15. package/dist/es2020/app.js.map +1 -1
  16. package/dist/es2020/exports/auth/index.js +2 -5
  17. package/dist/es2020/exports/auth/index.js.map +1 -1
  18. package/dist/es2020/exports/error-handler/index.js +3 -10
  19. package/dist/es2020/exports/error-handler/index.js.map +1 -1
  20. package/dist/es2020/exports/index.js +3 -5
  21. package/dist/es2020/exports/index.js.map +1 -1
  22. package/dist/es2020/exports/prisma/index.js +1 -2
  23. package/dist/es2020/exports/services/index.js +8 -52
  24. package/dist/es2020/exports/services/index.js.map +1 -1
  25. package/dist/es2020/exports/utils/change-case.js +1 -17
  26. package/dist/es2020/exports/utils/change-case.js.map +1 -1
  27. package/dist/es2020/exports/utils/index.js +2 -5
  28. package/dist/es2020/exports/utils/index.js.map +1 -1
  29. package/dist/es2020/exports/validation/index.js +2 -8
  30. package/dist/es2020/exports/validation/index.js.map +1 -1
  31. package/dist/es2020/modules/auth/auth.controller.js +73 -71
  32. package/dist/es2020/modules/auth/auth.controller.js.map +1 -1
  33. package/dist/es2020/modules/auth/auth.router.js +64 -57
  34. package/dist/es2020/modules/auth/auth.router.js.map +1 -1
  35. package/dist/es2020/modules/auth/auth.service.js +93 -80
  36. package/dist/es2020/modules/auth/auth.service.js.map +1 -1
  37. package/dist/es2020/modules/auth/utils/helpers/auth.helpers.js +6 -10
  38. package/dist/es2020/modules/auth/utils/helpers/auth.helpers.js.map +1 -1
  39. package/dist/es2020/modules/base/base.controller.js +125 -118
  40. package/dist/es2020/modules/base/base.controller.js.map +1 -1
  41. package/dist/es2020/modules/base/base.middlewares.js +6 -16
  42. package/dist/es2020/modules/base/base.middlewares.js.map +1 -1
  43. package/dist/es2020/modules/base/base.router.js +59 -54
  44. package/dist/es2020/modules/base/base.router.js.map +1 -1
  45. package/dist/es2020/modules/base/base.service.js +138 -143
  46. package/dist/es2020/modules/base/base.service.js.map +1 -1
  47. package/dist/es2020/modules/base/utils/helpers/base.helpers.js +44 -41
  48. package/dist/es2020/modules/base/utils/helpers/base.helpers.js.map +1 -1
  49. package/dist/es2020/modules/email/email.service.js +24 -23
  50. package/dist/es2020/modules/email/email.service.js.map +1 -1
  51. package/dist/es2020/modules/error-handler/error-handler.controller.js +7 -42
  52. package/dist/es2020/modules/error-handler/error-handler.controller.js.map +1 -1
  53. package/dist/es2020/modules/error-handler/utils/app-error.js +1 -3
  54. package/dist/es2020/modules/error-handler/utils/app-error.js.map +1 -1
  55. package/dist/es2020/modules/error-handler/utils/catch-async.js +13 -6
  56. package/dist/es2020/modules/error-handler/utils/catch-async.js.map +1 -1
  57. package/dist/es2020/modules/error-handler/utils/error-handler.helpers.js +105 -131
  58. package/dist/es2020/modules/error-handler/utils/error-handler.helpers.js.map +1 -1
  59. package/dist/es2020/modules/file-uploader/file-uploader.controller.js +60 -56
  60. package/dist/es2020/modules/file-uploader/file-uploader.controller.js.map +1 -1
  61. package/dist/es2020/modules/file-uploader/file-uploader.router.js +19 -16
  62. package/dist/es2020/modules/file-uploader/file-uploader.router.js.map +1 -1
  63. package/dist/es2020/modules/file-uploader/file-uploader.service.js +35 -36
  64. package/dist/es2020/modules/file-uploader/file-uploader.service.js.map +1 -1
  65. package/dist/es2020/paths.js +1 -1
  66. package/dist/es2020/paths.js.map +1 -1
  67. package/dist/es2020/scripts/create-test.js +12 -17
  68. package/dist/es2020/scripts/create-test.js.map +1 -1
  69. package/dist/es2020/server.js +1 -1
  70. package/dist/es2020/server.js.map +1 -1
  71. package/dist/es2020/utils/arkos-env.js +1 -3
  72. package/dist/es2020/utils/arkos-env.js.map +1 -1
  73. package/dist/es2020/utils/features/api.features.js +60 -72
  74. package/dist/es2020/utils/features/api.features.js.map +1 -1
  75. package/dist/es2020/utils/features/change-case.features.js +12 -48
  76. package/dist/es2020/utils/features/change-case.features.js.map +1 -1
  77. package/dist/es2020/utils/helpers/api.features.helpers.js +3 -5
  78. package/dist/es2020/utils/helpers/api.features.helpers.js.map +1 -1
  79. package/dist/es2020/utils/helpers/base.controller.helpers.js +30 -24
  80. package/dist/es2020/utils/helpers/base.controller.helpers.js.map +1 -1
  81. package/dist/es2020/utils/helpers/change-case.helpers.js +48 -56
  82. package/dist/es2020/utils/helpers/change-case.helpers.js.map +1 -1
  83. package/dist/es2020/utils/helpers/deepmerge.helper.js +9 -7
  84. package/dist/es2020/utils/helpers/deepmerge.helper.js.map +1 -1
  85. package/dist/es2020/utils/helpers/fs.helpers.js +5 -7
  86. package/dist/es2020/utils/helpers/fs.helpers.js.map +1 -1
  87. package/dist/es2020/utils/helpers/models.helpers.js +151 -152
  88. package/dist/es2020/utils/helpers/models.helpers.js.map +1 -1
  89. package/dist/es2020/utils/helpers/pluralize.helpers.js +0 -1
  90. package/dist/es2020/utils/helpers/prisma.helpers.js +24 -23
  91. package/dist/es2020/utils/helpers/prisma.helpers.js.map +1 -1
  92. package/dist/es2020/utils/helpers/query-parser.helpers.js +5 -10
  93. package/dist/es2020/utils/helpers/query-parser.helpers.js.map +1 -1
  94. package/dist/es2020/utils/helpers/text.helpers.js +1 -4
  95. package/dist/es2020/utils/helpers/text.helpers.js.map +1 -1
  96. package/dist/es2020/utils/scripts/export-prisma-types.js +2 -37
  97. package/dist/es2020/utils/scripts/export-prisma-types.js.map +1 -1
  98. package/dist/es2020/utils/scripts/generate-zod-schemas.js +108 -100
  99. package/dist/es2020/utils/scripts/generate-zod-schemas.js.map +1 -1
  100. package/dist/es2020/utils/scripts/prisma-db-push.js +8 -13
  101. package/dist/es2020/utils/scripts/prisma-db-push.js.map +1 -1
  102. package/dist/es2020/utils/validate-dto.js +19 -14
  103. package/dist/es2020/utils/validate-dto.js.map +1 -1
  104. package/dist/es2020/utils/validate-schema.js +17 -12
  105. package/dist/es2020/utils/validate-schema.js.map +1 -1
  106. package/package.json +4 -5
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=auth.controller.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.controller.test.js","sourceRoot":"","sources":["../../../../../src/modules/auth/__tests__/auth.controller.test.ts"],"names":[],"mappings":"","sourcesContent":["// import { describe, it, expect, vi, beforeEach, afterEach } from \"vitest\";\n// import {\n// authControllerFactory,\n// defaultExcludedUserFields,\n// } from \"../auth.controller\";\n// import authService from \"../auth.service\";\n// import { getBaseServices } from \"../../base/base.service\";\n// import { getPrismaInstance } from \"../../../utils/helpers/prisma.helpers\";\n// import { importPrismaModelModules } from \"../../../utils/helpers/models.helpers\";\n// import { getInitConfigs } from \"../../../server\";\n\n// vi.mock(\"bcrypt\", () => ({\n// default: {\n// compare: vi.fn(),\n// hash: vi.fn(),\n// },\n// }));\n\n// // Mock dependencies\n// vi.mock(\"../auth.service\", () => ({\n// default: {\n// isCorrectPassword: vi.fn(),\n// signJwtToken: vi.fn(),\n// isPasswordStrong: vi.fn(),\n// hashPassword: vi.fn(),\n// authenticate: vi.fn(),\n// handleAuthenticationControl: vi.fn(),\n// handleActionAccessControl: vi.fn(),\n// },\n// }));\n\n// vi.mock(\"../../base/base.service\", () => ({\n// getBaseServices: vi.fn(),\n// }));\n\n// vi.mock(\"../../../utils/helpers/prisma.helpers\", () => ({\n// getPrismaInstance: vi.fn(),\n// }));\n\n// // In your auth.controller.test.ts file, update your mock for models.helpers.ts\n\n// vi.mock(\"../../../utils/helpers/models.helpers\", () => ({\n// importPrismaModelModules: vi.fn(),\n// getPrismaModelRelations: vi.fn(),\n// getModels: vi.fn(() => []),\n// getModelUniqueFields: vi.fn(() => []),\n// models: [],\n// prismaModelRelationFields: {},\n// }));\n\n// vi.mock(\"../../../server\", () => ({\n// getInitConfigs: vi.fn(),\n// close: vi.fn(),\n// }));\n\n// describe(\"Auth Controller Factory\", () => {\n// let req: any;\n// let res: any;\n// let next: any;\n// let mockPrisma: any;\n// let authController: any;\n// let userService: any;\n\n// beforeEach(async () => {\n// // Reset mocks\n// vi.resetAllMocks();\n\n// // Setup mocks\n// userService = {\n// findOne: vi.fn(),\n// createOne: vi.fn(),\n// };\n\n// mockPrisma = {\n// user: {\n// findUnique: vi.fn(),\n// update: vi.fn(),\n// },\n// };\n\n// // Setup mock implementations\n// (getBaseServices as any).mockReturnValue({\n// user: userService,\n// });\n\n// (getPrismaInstance as any).mockReturnValue(mockPrisma);\n// (importPrismaModelModules as any).mockResolvedValue({\n// prismaQueryOptions: {\n// queryOptions: {},\n// findOne: {},\n// },\n// });\n\n// (getInitConfigs as any).mockReturnValue({\n// authentication: {\n// usernameField: \"username\",\n// login: {\n// sendAccessTokenThrough: \"both\",\n// },\n// },\n// });\n\n// // Create request, response, and next function mocks\n// req = {\n// user: {\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// isVerified: true,\n// active: true,\n// },\n// body: {},\n// query: {},\n// secure: false,\n// headers: {},\n// };\n\n// res = {\n// status: vi.fn().mockReturnThis(),\n// json: vi.fn(),\n// cookie: vi.fn(),\n// send: vi.fn(),\n// };\n\n// next = vi.fn();\n\n// // Create the auth controller\n// authController = await authControllerFactory();\n// });\n\n// afterEach(() => {\n// vi.clearAllMocks();\n// });\n\n// describe(\"getMe\", () => {\n// it(\"should get the current user and return it\", async () => {\n// // Setup\n// userService.findOne.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// username: \"testuser\",\n// email: \"test@example.com\",\n// });\n\n// // Execute\n// await authController.getMe(req, res, next);\n\n// // Verify\n// expect(userService.findOne).toHaveBeenCalledWith(\n// { id: \"user-id-123\" },\n// expect.any(String)\n// );\n// expect(res.status).toHaveBeenCalledWith(200);\n// expect(res.json).toHaveBeenCalledWith(req.user);\n// });\n\n// it(\"should remove excluded fields from the user object\", async () => {\n// // Setup\n// const fullUser = {\n// id: \"user-id-123\",\n// username: \"testuser\",\n// email: \"test@example.com\",\n// password: \"hashedPassword\",\n// passwordChangedAt: new Date(),\n// active: true,\n// };\n\n// req.user = { ...fullUser };\n// userService.findOne.mockResolvedValueOnce(fullUser);\n\n// // Execute\n// await authController.getMe(req, res, next);\n\n// // Verify\n// Object.keys(defaultExcludedUserFields).forEach((field) => {\n// expect(req.user[field]).toBeUndefined();\n// });\n// });\n\n// it(\"should call next middleware when afterGetMe is provided\", async () => {\n// // Setup\n// const controllerWithMiddleware = await authControllerFactory({\n// afterGetMe: true,\n// });\n\n// userService.findOne.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// username: \"testuser\",\n// email: \"test@example.com\",\n// });\n\n// // Execute\n// await controllerWithMiddleware.getMe(req, res, next);\n\n// // Verify\n// expect(req.responseData).toBeDefined();\n// expect(req.responseStatus).toBe(200);\n// expect(next).toHaveBeenCalled();\n// expect(res.status).not.toHaveBeenCalled();\n// });\n// });\n\n// describe(\"logout\", () => {\n// it(\"should clear the access token cookie and return 204\", async () => {\n// // Execute\n// await authController.logout(req, res, next);\n\n// // Verify\n// expect(res.cookie).toHaveBeenCalledWith(\n// \"arkos_access_token\",\n// \"no-token\",\n// expect.objectContaining({\n// httpOnly: true,\n// })\n// );\n// expect(res.status).toHaveBeenCalledWith(204);\n// expect(res.json).toHaveBeenCalled();\n// });\n\n// it(\"should call next middleware when afterLogout is provided\", async () => {\n// // Setup\n// const controllerWithMiddleware = await authControllerFactory({\n// afterLogout: true,\n// });\n\n// // Execute\n// await controllerWithMiddleware.logout(req, res, next);\n\n// // Verify\n// expect(req.responseData).toBeNull();\n// expect(req.responseStatus).toBe(204);\n// expect(next).toHaveBeenCalled();\n// expect(res.status).not.toHaveBeenCalled();\n// });\n// });\n\n// describe(\"login\", () => {\n// it(\"should return 400 if username or password is missing\", async () => {\n// // Setup\n// req.body = { username: \"testuser\" }; // Missing password\n\n// // Execute\n// await authController.login(req, res, next);\n\n// // Verify\n// expect(next).toHaveBeenCalledWith(\n// expect.objectContaining({\n// statusCode: 400,\n// message: expect.stringContaining(\"username and password\"),\n// })\n// );\n// });\n\n// it(\"should use default username field from config when not specified in query\", async () => {\n// // Setup\n// req.body = { username: \"testuser\", password: \"Password123\" };\n\n// mockPrisma.user.findUnique.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// });\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.signJwtToken as any).mockReturnValue(\"jwt-token-123\");\n\n// // Execute\n// await authController.login(req, res, next);\n\n// // Verify\n// expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({\n// where: { username: \"testuser\" },\n// });\n// });\n\n// it(\"should use username field from query parameter when provided\", async () => {\n// // Setup\n// req.query.usernameField = \"email\";\n// req.body = { email: \"test@example.com\", password: \"Password123\" };\n\n// mockPrisma.user.findUnique.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// email: \"test@example.com\",\n// password: \"hashedPassword\",\n// });\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.signJwtToken as any).mockReturnValue(\"jwt-token-123\");\n\n// // Execute\n// await authController.login(req, res, next);\n\n// // Verify\n// expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({\n// where: { email: \"test@example.com\" },\n// });\n// });\n\n// it(\"should return 401 if user is not found\", async () => {\n// // Setup\n// req.body = { username: \"nonexistentuser\", password: \"Password123\" };\n// mockPrisma.user.findUnique.mockResolvedValueOnce(null);\n\n// // Execute\n// await authController.login(req, res, next);\n\n// // Verify\n// expect(next).toHaveBeenCalledWith(\n// expect.objectContaining({\n// statusCode: 401,\n// message: expect.stringContaining(\"Incorrect username or password\"),\n// })\n// );\n// });\n\n// it(\"should return 401 if password is incorrect\", async () => {\n// // Setup\n// req.body = { username: \"testuser\", password: \"WrongPassword123\" };\n\n// mockPrisma.user.findUnique.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// });\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(false);\n\n// // Execute\n// await authController.login(req, res, next);\n\n// // Verify\n// expect(next).toHaveBeenCalledWith(\n// expect.objectContaining({\n// statusCode: 401,\n// message: expect.stringContaining(\"Incorrect username or password\"),\n// })\n// );\n// });\n\n// it('should set cookie and return token in response when config is \"both\"', async () => {\n// // Setup\n// req.body = { username: \"testuser\", password: \"Password123\" };\n\n// mockPrisma.user.findUnique.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// });\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.signJwtToken as any).mockReturnValue(\"jwt-token-123\");\n\n// (getInitConfigs as any).mockReturnValue({\n// authentication: {\n// usernameField: \"username\",\n// login: {\n// sendAccessTokenThrough: \"both\",\n// },\n// },\n// });\n\n// // Execute\n// await authController.login(req, res, next);\n\n// // Verify\n// expect(res.cookie).toHaveBeenCalledWith(\n// \"arkos_access_token\",\n// \"jwt-token-123\",\n// expect.any(Object)\n// );\n// expect(res.status).toHaveBeenCalledWith(200);\n// expect(res.json).toHaveBeenCalledWith({\n// accessToken: \"jwt-token-123\",\n// });\n// });\n\n// it('should only set cookie when config is \"cookie-only\"', async () => {\n// // Setup\n// req.body = { username: \"testuser\", password: \"Password123\" };\n\n// mockPrisma.user.findUnique.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// });\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.signJwtToken as any).mockReturnValue(\"jwt-token-123\");\n\n// (getInitConfigs as any).mockReturnValue({\n// authentication: {\n// usernameField: \"username\",\n// login: {\n// sendAccessTokenThrough: \"cookie-only\",\n// },\n// },\n// });\n\n// // Execute\n// await authController.login(req, res, next);\n\n// // Verify\n// expect(res.cookie).toHaveBeenCalledWith(\n// \"arkos_access_token\",\n// \"jwt-token-123\",\n// expect.any(Object)\n// );\n// expect(res.status).toHaveBeenCalledWith(200);\n// expect(res.send).toHaveBeenCalled();\n// expect(res.json).not.toHaveBeenCalled();\n// });\n\n// it('should only return token in response when config is \"response-only\"', async () => {\n// // Setup\n// req.body = { username: \"testuser\", password: \"Password123\" };\n\n// mockPrisma.user.findUnique.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// });\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.signJwtToken as any).mockReturnValue(\"jwt-token-123\");\n\n// (getInitConfigs as any).mockReturnValue({\n// authentication: {\n// usernameField: \"username\",\n// login: {\n// sendAccessTokenThrough: \"response-only\",\n// },\n// },\n// });\n\n// // Execute\n// await authController.login(req, res, next);\n\n// // Verify\n// expect(res.cookie).not.toHaveBeenCalled();\n// expect(res.status).toHaveBeenCalledWith(200);\n// expect(res.json).toHaveBeenCalledWith({\n// accessToken: \"jwt-token-123\",\n// });\n// });\n\n// it(\"should call next middleware when afterLogin is provided\", async () => {\n// // Setup\n// const controllerWithMiddleware = await authControllerFactory({\n// afterLogin: true,\n// });\n\n// req.body = { username: \"testuser\", password: \"Password123\" };\n\n// mockPrisma.user.findUnique.mockResolvedValueOnce({\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// });\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.signJwtToken as any).mockReturnValue(\"jwt-token-123\");\n\n// // Execute\n// await controllerWithMiddleware.login(req, res, next);\n\n// // Verify\n// expect(req.responseData).toEqual({ accessToken: \"jwt-token-123\" });\n// expect(req.responseStatus).toBe(200);\n// expect(next).toHaveBeenCalled();\n// expect(res.status).not.toHaveBeenCalled();\n// });\n// });\n\n// describe(\"signup\", () => {\n// it(\"should create a new user and return 201\", async () => {\n// // Setup\n// req.body = {\n// username: \"newuser\",\n// email: \"newuser@example.com\",\n// password: \"Password123\",\n// };\n\n// const createdUser = {\n// id: \"new-user-id\",\n// username: \"newuser\",\n// email: \"newuser@example.com\",\n// password: \"hashedPassword\",\n// active: true,\n// };\n\n// userService.createOne.mockResolvedValueOnce({ ...createdUser });\n\n// // Execute\n// await authController.signup(req, res, next);\n\n// // Verify\n// expect(userService.createOne).toHaveBeenCalledWith(req.body);\n// expect(res.status).toHaveBeenCalledWith(201);\n\n// // Check that excluded fields are removed\n// const responseUser = res.json.mock.calls[0][0].data;\n// Object.keys(defaultExcludedUserFields).forEach((field) => {\n// expect(responseUser[field]).toBeUndefined();\n// });\n// });\n\n// it(\"should call next middleware when afterSignup is provided\", async () => {\n// // Setup\n// const controllerWithMiddleware = await authControllerFactory({\n// afterSignup: true,\n// });\n\n// req.body = {\n// username: \"newuser\",\n// email: \"newuser@example.com\",\n// password: \"Password123\",\n// };\n\n// const createdUser = {\n// id: \"new-user-id\",\n// username: \"newuser\",\n// email: \"newuser@example.com\",\n// password: \"hashedPassword\",\n// };\n\n// userService.createOne.mockResolvedValueOnce({ ...createdUser });\n\n// // Execute\n// await controllerWithMiddleware.signup(req, res, next);\n\n// // Verify\n// expect(req.responseData).toEqual({ data: createdUser });\n// expect(req.responseStatus).toBe(201);\n// expect(next).toHaveBeenCalled();\n// expect(res.status).not.toHaveBeenCalled();\n// });\n// });\n\n// describe(\"updatePassword\", () => {\n// it(\"should return 400 if currentPassword or newPassword is missing\", async () => {\n// // Setup - missing newPassword\n// req.body = { currentPassword: \"CurrentPassword123\" };\n\n// // Execute\n// await authController.updatePassword(req, res, next);\n\n// // Verify\n// expect(next).toHaveBeenCalledWith(\n// expect.objectContaining({\n// statusCode: 400,\n// message: expect.stringContaining(\n// \"currentPassword and newPassword are required\"\n// ),\n// })\n// );\n// });\n\n// it(\"should return 404 if user is not found or inactive\", async () => {\n// // Setup\n// req.user = null;\n// req.body = {\n// currentPassword: \"CurrentPassword123\",\n// newPassword: \"NewPassword123\",\n// };\n\n// // Execute\n// await authController.updatePassword(req, res, next);\n\n// // Verify\n// expect(next).toHaveBeenCalledWith(\n// expect.objectContaining({\n// statusCode: 404,\n// message: expect.stringContaining(\"User not found\"),\n// })\n// );\n// });\n\n// it(\"should return 423 if user is not verified\", async () => {\n// // Setup\n// req.user = {\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// isVerified: false,\n// };\n\n// req.body = {\n// currentPassword: \"CurrentPassword123\",\n// newPassword: \"NewPassword123\",\n// };\n\n// // Execute\n// await authController.updatePassword(req, res, next);\n\n// // Verify\n// expect(next).toHaveBeenCalledWith(\n// expect.objectContaining({\n// statusCode: 423,\n// message: expect.stringContaining(\"verify your account\"),\n// })\n// );\n// });\n\n// it(\"should return 400 if current password is incorrect\", async () => {\n// // Setup\n// req.user = {\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// isVerified: true,\n// };\n\n// req.body = {\n// currentPassword: \"WrongPassword123\",\n// newPassword: \"NewPassword123\",\n// };\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(false);\n\n// // Execute\n// await authController.updatePassword(req, res, next);\n\n// // Verify\n// expect(next).toHaveBeenCalledWith(\n// expect.objectContaining({\n// statusCode: 400,\n// message: expect.stringContaining(\"Current password is incorrect\"),\n// })\n// );\n// });\n\n// it(\"should return 400 if new password is not strong enough\", async () => {\n// // Setup\n// req.user = {\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// isVerified: true,\n// };\n\n// req.body = {\n// currentPassword: \"CurrentPassword123\",\n// newPassword: \"weakpassword\",\n// };\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.isPasswordStrong as any).mockReturnValue(false);\n\n// // Execute\n// await authController.updatePassword(req, res, next);\n\n// // Verify\n// expect(next).toHaveBeenCalledWith(\n// expect.objectContaining({\n// statusCode: 400,\n// message: expect.stringContaining(\"Password must contain\"),\n// })\n// );\n// });\n\n// it(\"should update password and return 200 on success\", async () => {\n// // Setup\n// req.user = {\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// isVerified: true,\n// };\n\n// req.body = {\n// currentPassword: \"CurrentPassword123\",\n// newPassword: \"NewPassword123\",\n// };\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.isPasswordStrong as any).mockReturnValue(true);\n// (authService.hashPassword as any).mockResolvedValueOnce(\n// \"newHashedPassword\"\n// );\n\n// // Execute\n// await authController.updatePassword(req, res, next);\n\n// // Verify\n// expect(mockPrisma.user.update).toHaveBeenCalledWith({\n// where: { id: \"user-id-123\" },\n// data: {\n// password: \"newHashedPassword\",\n// passwordChangedAt: expect.any(Date),\n// },\n// });\n\n// expect(res.status).toHaveBeenCalledWith(200);\n// expect(res.json).toHaveBeenCalledWith({\n// status: \"success\",\n// message: \"Password updated successfully!\",\n// });\n// });\n\n// it(\"should call next middleware when afterUpdatePassword is provided\", async () => {\n// // Setup\n// const controllerWithMiddleware = await authControllerFactory({\n// afterUpdatePassword: true,\n// });\n\n// req.user = {\n// id: \"user-id-123\",\n// username: \"testuser\",\n// password: \"hashedPassword\",\n// isVerified: true,\n// };\n\n// req.body = {\n// currentPassword: \"CurrentPassword123\",\n// newPassword: \"NewPassword123\",\n// };\n\n// (authService.isCorrectPassword as any).mockResolvedValueOnce(true);\n// (authService.isPasswordStrong as any).mockReturnValue(true);\n// (authService.hashPassword as any).mockResolvedValueOnce(\n// \"newHashedPassword123\"\n// );\n\n// // Execute\n// await controllerWithMiddleware.updatePassword(req, res, next);\n\n// // Verify\n// expect(req.responseData).toEqual({\n// status: \"success\",\n// message: \"Password updated successfully!\",\n// });\n// expect(req.responseStatus).toBe(200);\n// expect(req.additionalData).toEqual({\n// user: req.user,\n// });\n// expect(next).toHaveBeenCalled();\n// expect(res.status).not.toHaveBeenCalled();\n// });\n// });\n// });\n"]}
@@ -83,7 +83,7 @@ class AuthService {
83
83
  mode: "insensitive",
84
84
  },
85
85
  action: {
86
- equals: action,
86
+ contains: action,
87
87
  mode: "insensitive",
88
88
  },
89
89
  roleId: { in: user.roles.map((role) => role.roleId) },
@@ -1 +1 @@
1
- {"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../../../src/modules/auth/auth.service.ts"],"names":[],"mappings":"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","sourcesContent":["import jwt from \"jsonwebtoken\";\nimport bcrypt from \"bcryptjs\";\nimport { User, UserRole } from \"../../types\";\nimport catchAsync from \"../error-handler/utils/catch-async\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { callNext } from \"../base/base.middlewares\";\nimport { getInitConfigs } from \"../../server\";\nimport arkosEnv from \"../../utils/arkos-env\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport {\n ArkosRequest,\n ArkosResponse,\n ArkosNextFunction,\n ArkosRequestHandler,\n} from \"../../types\";\nimport {\n AuthConfigs,\n AuthJwtPayload,\n ControllerActions,\n} from \"../../types/auth\";\nimport { InitConfigsAuthenticationOptions } from \"../../types/app\";\n\n/**\n * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials.\n */\nclass AuthService {\n /**\n * Signs a JWT token for the user.\n *\n * @param {number | string} id - The unique identifier of the user to generate the token for.\n * @param {string | number} [expiresIn] - The expiration time for the token. Defaults to environment variable `JWT_EXPIRES_IN`.\n * @param {string} [secret] - The secret key used to sign the token. Defaults to environment variable `JWT_SECRET`.\n * @returns {string} The signed JWT token.\n */\n signJwtToken(\n id: number | string,\n expiresIn: string | number = process.env.JWT_EXPIRES_IN ||\n arkosEnv.JWT_EXPIRES_IN,\n secret: string = process.env.JWT_SECRET || arkosEnv.JWT_SECRET\n ): string {\n return jwt.sign({ id }, secret, {\n expiresIn: expiresIn as any,\n });\n }\n\n /**\n * Compares a candidate password with the stored user password to check if they match.\n *\n * @param {string} candidatePassword - The password provided by the user during login.\n * @param {string} userPassword - The password stored in the database.\n * @returns {Promise<boolean>} Returns true if the passwords match, otherwise false.\n */\n async isCorrectPassword(\n candidatePassword: string,\n userPassword: string\n ): Promise<boolean> {\n return await bcrypt.compare(candidatePassword, userPassword);\n }\n\n /**\n * Hashes a plain text password using bcrypt.\n *\n * @param {string} password - The password to be hashed.\n * @returns {Promise<string>} Returns the hashed password.\n */\n async hashPassword(password: string): Promise<string> {\n return await bcrypt.hash(password, 12);\n }\n\n /**\n * Checks if a password is strong, requiring uppercase, lowercase, and numeric characters as the default.\n *\n * **Note**: You can define it when calling arkos.init()\n * ```ts\n * arkos.init(app, {\n * authentication: {\n * passwordRegex: /your-desired-regex/\n * }\n * })\n * ```\n *\n * @param {string} password - The password to check.\n * @returns {boolean} Returns true if the password meets the strength criteria, otherwise false.\n */\n isPasswordStrong(password: string): boolean {\n const initAuthConfigs = getInitConfigs()\n ?.authentication as InitConfigsAuthenticationOptions;\n\n const strongPasswordRegex =\n initAuthConfigs.passwordRegex || /^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).+$/;\n return strongPasswordRegex.test(password);\n }\n\n /**\n * Checks if a user has changed their password after the JWT was issued.\n *\n * @param {User} user - The user object containing the passwordChangedAt field.\n * @param {number} JWTTimestamp - The timestamp when the JWT was issued.\n * @returns {boolean} Returns true if the user changed their password after the JWT was issued, otherwise false.\n */\n userChangedPasswordAfter(user: User, JWTTimestamp: number): boolean {\n if (user.passwordChangedAt) {\n const convertedTimestamp = parseInt(\n String(user.passwordChangedAt.getTime() / 1000),\n 10\n );\n\n return JWTTimestamp < convertedTimestamp;\n }\n return false;\n }\n\n /**\n * Verifies the authenticity of a JWT token.\n *\n * @param {string} token - The JWT token to verify.\n * @param {string} [secret] - The secret key used to verify the token. Defaults to environment variable `JWT_SECRET`.\n * @returns {Promise<AuthJwtPayload>} Returns the decoded JWT payload if the token is valid.\n * @throws {Error} Throws an error if the token is invalid or expired.\n */\n async verifyJwtToken(\n token: string,\n secret: string = process.env.JWT_SECRET || arkosEnv.JWT_SECRET\n ): Promise<AuthJwtPayload> {\n return new Promise((resolve, reject) => {\n jwt.verify(token, secret, (err, decoded) => {\n if (err) reject(err);\n else resolve(decoded as AuthJwtPayload);\n });\n });\n }\n\n /**\n * Middleware function to handle access control based on user roles and permissions.\n *\n * @param {AuthConfigs} authConfigs - The configuration object for authentication and access control.\n * @param {ControllerActions} action - The action being performed (e.g., create, update, delete, view).\n * @param {string} modelName - The model name that the action is being performed on (e.g., \"User\", \"Post\").\n * @returns {ArkosRequestHandler} The middleware function that checks if the user has permission to perform the action.\n */\n handleActionAccessControl(\n authConfigs: AuthConfigs,\n action: ControllerActions,\n modelName: string\n ): ArkosRequestHandler {\n return catchAsync(\n async (\n req: ArkosRequest,\n res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (req.user) {\n const user = req.user as any;\n const prisma = getPrismaInstance();\n\n const permissions = await (prisma as any).authPermission.count({\n where: {\n resource: {\n equals: modelName,\n mode: \"insensitive\",\n },\n action: {\n equals: action,\n mode: \"insensitive\",\n },\n roleId: { in: user.roles.map((role: UserRole) => role.roleId) },\n },\n });\n\n if (!permissions) {\n return next(\n new AppError(\n \"You do not have permission to perfom this action\",\n 403\n )\n );\n }\n }\n\n next();\n }\n );\n }\n\n /**\n * Processes the cookies or authoriation token and returns the user.\n * @param req\n * @returns {Promise<User | null>} - if authentication is turned off in initConfigs it returns null\n * @throws {AppError} Throws an error if the token is invalid or the user is not logged in.\n */\n async getAuthenticatedUser(req: ArkosRequest): Promise<User | null> {\n const initConfigs = getInitConfigs();\n if (initConfigs?.authentication === false) return null;\n\n const prisma = getPrismaInstance();\n\n let token: string | undefined;\n\n if (\n req?.headers?.authorization &&\n req?.headers?.authorization.startsWith(\"Bearer\")\n ) {\n token = req?.headers?.authorization.split(\" \")[1];\n } else if (req?.cookies?.arkos_access_token !== \"no-token\" && req.cookies) {\n token = req?.cookies?.arkos_access_token;\n }\n\n if (!token)\n throw new AppError(\n \"You are not logged in! please log in to get access\",\n 401\n );\n\n let decoded: AuthJwtPayload | undefined;\n try {\n decoded = await this.verifyJwtToken(token);\n } catch (err) {\n throw new AppError(\n \"Your auth token is invalid, please login again.\",\n 401\n );\n }\n\n if (!decoded?.id)\n throw new AppError(\n \"Your auth token is invalid, please login again.\",\n 401\n );\n\n const user: any | null = await (prisma as any).user.findUnique({\n where: { id: String(decoded.id) },\n include: {\n roles: {\n include: {\n role: {\n include: {\n permissions: true,\n },\n },\n },\n },\n },\n });\n\n if (!user)\n throw new AppError(\n \"The user belonging to this token does no longer exists\",\n 401\n );\n\n if (\n this.userChangedPasswordAfter(user, decoded.iat!) &&\n !req.path.includes(\"logout\")\n )\n throw new AppError(\n \"User recently changed password! Please log in again.\",\n 401\n );\n\n return user;\n }\n\n /**\n * Middleware function to authenticate the user based on the JWT token.\n *\n * @param {ArkosRequest} req - The request object.\n * @param {ArkosResponse} res - The response object.\n * @param {ArkosNextFunction} next - The next middleware function to be called.\n * @returns {void}\n */\n authenticate = catchAsync(\n async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n const initConfigs = getInitConfigs();\n if (initConfigs?.authentication === false) return next();\n\n req.user = (await this.getAuthenticatedUser(req)) as User;\n next();\n }\n );\n\n /**\n * Handles authentication control by checking the `authenticationControl` configuration in the `authConfigs`.\n *\n * @param {AuthConfigs | undefined} authConfigs - The authentication configuration object.\n * @param {ControllerActions} action - The action being performed (e.g., create, update, delete, view).\n * @param {string} modelName - The model name being affected by the action.\n * @returns {ArkosRequestHandler} The middleware function that checks if authentication is required.\n */\n handleAuthenticationControl(\n authConfigs: AuthConfigs | undefined,\n action: ControllerActions,\n modelName: string\n ): ArkosRequestHandler {\n const authenticationControl = authConfigs?.authenticationControl;\n\n if (authenticationControl && typeof authenticationControl === \"object\") {\n if (authenticationControl[action] === false) return callNext;\n else if (authenticationControl[action] === true) return this.authenticate;\n } else return this.authenticate;\n\n return this.authenticate;\n }\n}\n\n/**\n * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials.\n */\nconst authService = new AuthService();\n\nexport default authService;\n"]}
1
+ {"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../../../src/modules/auth/auth.service.ts"],"names":[],"mappings":"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","sourcesContent":["import jwt from \"jsonwebtoken\";\nimport bcrypt from \"bcryptjs\";\nimport { User, UserRole } from \"../../types\";\nimport catchAsync from \"../error-handler/utils/catch-async\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { callNext } from \"../base/base.middlewares\";\nimport { getInitConfigs } from \"../../server\";\nimport arkosEnv from \"../../utils/arkos-env\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport {\n ArkosRequest,\n ArkosResponse,\n ArkosNextFunction,\n ArkosRequestHandler,\n} from \"../../types\";\nimport {\n AuthConfigs,\n AuthJwtPayload,\n ControllerActions,\n} from \"../../types/auth\";\nimport { InitConfigsAuthenticationOptions } from \"../../types/app\";\n\n/**\n * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials.\n */\nclass AuthService {\n /**\n * Signs a JWT token for the user.\n *\n * @param {number | string} id - The unique identifier of the user to generate the token for.\n * @param {string | number} [expiresIn] - The expiration time for the token. Defaults to environment variable `JWT_EXPIRES_IN`.\n * @param {string} [secret] - The secret key used to sign the token. Defaults to environment variable `JWT_SECRET`.\n * @returns {string} The signed JWT token.\n */\n signJwtToken(\n id: number | string,\n expiresIn: string | number = process.env.JWT_EXPIRES_IN ||\n arkosEnv.JWT_EXPIRES_IN,\n secret: string = process.env.JWT_SECRET || arkosEnv.JWT_SECRET\n ): string {\n return jwt.sign({ id }, secret, {\n expiresIn: expiresIn as any,\n });\n }\n\n /**\n * Compares a candidate password with the stored user password to check if they match.\n *\n * @param {string} candidatePassword - The password provided by the user during login.\n * @param {string} userPassword - The password stored in the database.\n * @returns {Promise<boolean>} Returns true if the passwords match, otherwise false.\n */\n async isCorrectPassword(\n candidatePassword: string,\n userPassword: string\n ): Promise<boolean> {\n return await bcrypt.compare(candidatePassword, userPassword);\n }\n\n /**\n * Hashes a plain text password using bcrypt.\n *\n * @param {string} password - The password to be hashed.\n * @returns {Promise<string>} Returns the hashed password.\n */\n async hashPassword(password: string): Promise<string> {\n return await bcrypt.hash(password, 12);\n }\n\n /**\n * Checks if a password is strong, requiring uppercase, lowercase, and numeric characters as the default.\n *\n * **Note**: You can define it when calling arkos.init()\n * ```ts\n * arkos.init(app, {\n * authentication: {\n * passwordRegex: /your-desired-regex/\n * }\n * })\n * ```\n *\n * @param {string} password - The password to check.\n * @returns {boolean} Returns true if the password meets the strength criteria, otherwise false.\n */\n isPasswordStrong(password: string): boolean {\n const initAuthConfigs = getInitConfigs()\n ?.authentication as InitConfigsAuthenticationOptions;\n\n const strongPasswordRegex =\n initAuthConfigs.passwordRegex || /^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).+$/;\n return strongPasswordRegex.test(password);\n }\n\n /**\n * Checks if a user has changed their password after the JWT was issued.\n *\n * @param {User} user - The user object containing the passwordChangedAt field.\n * @param {number} JWTTimestamp - The timestamp when the JWT was issued.\n * @returns {boolean} Returns true if the user changed their password after the JWT was issued, otherwise false.\n */\n userChangedPasswordAfter(user: User, JWTTimestamp: number): boolean {\n if (user.passwordChangedAt) {\n const convertedTimestamp = parseInt(\n String(user.passwordChangedAt.getTime() / 1000),\n 10\n );\n\n return JWTTimestamp < convertedTimestamp;\n }\n return false;\n }\n\n /**\n * Verifies the authenticity of a JWT token.\n *\n * @param {string} token - The JWT token to verify.\n * @param {string} [secret] - The secret key used to verify the token. Defaults to environment variable `JWT_SECRET`.\n * @returns {Promise<AuthJwtPayload>} Returns the decoded JWT payload if the token is valid.\n * @throws {Error} Throws an error if the token is invalid or expired.\n */\n async verifyJwtToken(\n token: string,\n secret: string = process.env.JWT_SECRET || arkosEnv.JWT_SECRET\n ): Promise<AuthJwtPayload> {\n return new Promise((resolve, reject) => {\n jwt.verify(token, secret, (err, decoded) => {\n if (err) reject(err);\n else resolve(decoded as AuthJwtPayload);\n });\n });\n }\n\n /**\n * Middleware function to handle access control based on user roles and permissions.\n *\n * @param {AuthConfigs} authConfigs - The configuration object for authentication and access control.\n * @param {ControllerActions} action - The action being performed (e.g., create, update, delete, view).\n * @param {string} modelName - The model name that the action is being performed on (e.g., \"User\", \"Post\").\n * @returns {ArkosRequestHandler} The middleware function that checks if the user has permission to perform the action.\n */\n handleActionAccessControl(\n authConfigs: AuthConfigs,\n action: ControllerActions,\n modelName: string\n ): ArkosRequestHandler {\n return catchAsync(\n async (\n req: ArkosRequest,\n res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (req.user) {\n const user = req.user as any;\n const prisma = getPrismaInstance();\n\n const permissions = await (prisma as any).authPermission.count({\n where: {\n resource: {\n equals: modelName,\n mode: \"insensitive\",\n },\n action: {\n contains: action,\n mode: \"insensitive\",\n },\n roleId: { in: user.roles.map((role: UserRole) => role.roleId) },\n },\n });\n\n if (!permissions) {\n return next(\n new AppError(\n \"You do not have permission to perfom this action\",\n 403\n )\n );\n }\n }\n\n next();\n }\n );\n }\n\n /**\n * Processes the cookies or authoriation token and returns the user.\n * @param req\n * @returns {Promise<User | null>} - if authentication is turned off in initConfigs it returns null\n * @throws {AppError} Throws an error if the token is invalid or the user is not logged in.\n */\n async getAuthenticatedUser(req: ArkosRequest): Promise<User | null> {\n const initConfigs = getInitConfigs();\n if (initConfigs?.authentication === false) return null;\n\n const prisma = getPrismaInstance();\n\n let token: string | undefined;\n\n if (\n req?.headers?.authorization &&\n req?.headers?.authorization.startsWith(\"Bearer\")\n ) {\n token = req?.headers?.authorization.split(\" \")[1];\n } else if (req?.cookies?.arkos_access_token !== \"no-token\" && req.cookies) {\n token = req?.cookies?.arkos_access_token;\n }\n\n if (!token)\n throw new AppError(\n \"You are not logged in! please log in to get access\",\n 401\n );\n\n let decoded: AuthJwtPayload | undefined;\n try {\n decoded = await this.verifyJwtToken(token);\n } catch (err) {\n throw new AppError(\n \"Your auth token is invalid, please login again.\",\n 401\n );\n }\n\n if (!decoded?.id)\n throw new AppError(\n \"Your auth token is invalid, please login again.\",\n 401\n );\n\n const user: any | null = await (prisma as any).user.findUnique({\n where: { id: String(decoded.id) },\n include: {\n roles: {\n include: {\n role: {\n include: {\n permissions: true,\n },\n },\n },\n },\n },\n });\n\n if (!user)\n throw new AppError(\n \"The user belonging to this token does no longer exists\",\n 401\n );\n\n if (\n this.userChangedPasswordAfter(user, decoded.iat!) &&\n !req.path.includes(\"logout\")\n )\n throw new AppError(\n \"User recently changed password! Please log in again.\",\n 401\n );\n\n return user;\n }\n\n /**\n * Middleware function to authenticate the user based on the JWT token.\n *\n * @param {ArkosRequest} req - The request object.\n * @param {ArkosResponse} res - The response object.\n * @param {ArkosNextFunction} next - The next middleware function to be called.\n * @returns {void}\n */\n authenticate = catchAsync(\n async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n const initConfigs = getInitConfigs();\n if (initConfigs?.authentication === false) return next();\n\n req.user = (await this.getAuthenticatedUser(req)) as User;\n next();\n }\n );\n\n /**\n * Handles authentication control by checking the `authenticationControl` configuration in the `authConfigs`.\n *\n * @param {AuthConfigs | undefined} authConfigs - The authentication configuration object.\n * @param {ControllerActions} action - The action being performed (e.g., create, update, delete, view).\n * @param {string} modelName - The model name being affected by the action.\n * @returns {ArkosRequestHandler} The middleware function that checks if authentication is required.\n */\n handleAuthenticationControl(\n authConfigs: AuthConfigs | undefined,\n action: ControllerActions,\n modelName: string\n ): ArkosRequestHandler {\n const authenticationControl = authConfigs?.authenticationControl;\n\n if (authenticationControl && typeof authenticationControl === \"object\") {\n if (authenticationControl[action] === false) return callNext;\n else if (authenticationControl[action] === true) return this.authenticate;\n } else return this.authenticate;\n\n return this.authenticate;\n }\n}\n\n/**\n * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials.\n */\nconst authService = new AuthService();\n\nexport default authService;\n"]}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=auth.helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.helpers.test.js","sourceRoot":"","sources":["../../../../../../../src/modules/auth/utils/helpers/__tests__/auth.helpers.test.ts"],"names":[],"mappings":"","sourcesContent":["// import { expect, vi } from \"vitest\";\n// import { getInitConfigs } from \"../../../../../server\";\n// import { describe, it } from \"vitest\";\n// import { determineUsernameField } from \"../auth.helpers\";\n\n// vi.mock(\"../../../../../server\", () => ({\n// getInitConfigs: vi.fn(),\n// close: vi.fn(),\n// }));\n\n// vi.mock(\"fs\", () => ({\n// default: {\n// ...vi.importActual(\"fs\"),\n// readdirSync: vi.fn(() => [\"test.prisma\"]),\n// statSync: vi.fn(() => ({\n// isFile: vi.fn(),\n// })),\n// existsSync: vi.fn(() => false),\n// mkdirSync: vi.fn(),\n// unlink: vi.fn(),\n// access: vi.fn(),\n// },\n// }));\n\n// describe(\"determineUsernameField\", () => {\n// it(\"should use query parameter usernameField when provided\", async () => {\n// const testReq = {\n// query: { usernameField: \"email\" },\n// };\n\n// expect(determineUsernameField(testReq as any)).toBe(\"email\");\n// });\n\n// it(\"should use configuration value when query parameter is not provided\", async () => {\n// const testReq = { query: {} };\n\n// (getInitConfigs as any).mockReturnValueOnce({\n// authentication: {\n// usernameField: \"phoneNumber\",\n// },\n// });\n\n// expect(determineUsernameField(testReq as any)).toBe(\"phoneNumber\");\n// });\n\n// it('should default to \"username\" when neither query nor config specify a field', async () => {\n// expect(determineUsernameField({ query: {} } as any)).toBe(\"username\");\n// });\n// });\n"]}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=base.helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.helpers.test.js","sourceRoot":"","sources":["../../../../../../../src/modules/base/utils/helpers/__tests__/base.helpers.test.ts"],"names":[],"mappings":"","sourcesContent":["// import { describe, it, expect, vi, beforeEach } from \"vitest\";\n// import {\n// handleRelationFieldsInBody,\n// canBeUsedToConnect,\n// isListFieldAnArray,\n// } from \"../base.helpers\"; // Update this path\n\n// // Mock the required helpers\n// vi.mock(\"../../../../../utils/helpers/models.helpers\", () => ({\n// getPrismaModelRelations: vi.fn((type) => {\n// if (type === \"Post\") {\n// return {\n// singular: [{ name: \"category\", type: \"Category\" }],\n// list: [\n// { name: \"tags\", type: \"Tag\" },\n// { name: \"comments\", type: \"Comment\" },\n// ],\n// };\n// }\n// if (type === \"User\") {\n// return {\n// singular: [{ name: \"profile\", type: \"Profile\" }],\n// list: [{ name: \"posts\", type: \"Post\" }],\n// };\n// }\n// if (type === \"Comment\") {\n// return {\n// singular: [{ name: \"author\", type: \"User\" }],\n// };\n// }\n// return null;\n// }),\n// getModelUniqueFields: vi.fn((modelName) => {\n// if (modelName === \"Category\") {\n// return [{ name: \"name\" }];\n// }\n// if (modelName === \"Tag\") {\n// return [{ name: \"name\" }];\n// }\n// if (modelName === \"User\") {\n// return [{ name: \"email\" }, { name: \"username\" }];\n// }\n// return [];\n// }),\n// RelationField: {}, // Add this to satisfy TypeScript if needed\n// RelationFields: {}, // Add this to satisfy TypeScript if needed\n// }));\n\n// describe(\"handleRelationFieldsInBody\", () => {\n// describe(\"Singular Relations\", () => {\n// it(\"should handle create operation for singular relation without id\", () => {\n// const body = {\n// name: \"John Doe\",\n// profile: {\n// bio: \"Software Engineer\",\n// avatarUrl: \"https://example.com/avatar.jpg\",\n// },\n// };\n\n// const relationFields = {\n// singular: [{ name: \"profile\", type: \"Profile\" }],\n// list: [],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// profile: {\n// create: {\n// bio: \"Software Engineer\",\n// avatarUrl: \"https://example.com/avatar.jpg\",\n// },\n// },\n// });\n// });\n\n// it(\"should handle connect operation for singular relation with only id\", () => {\n// const body = {\n// name: \"John Doe\",\n// profile: {\n// id: \"123\",\n// },\n// };\n\n// const relationFields = {\n// singular: [{ name: \"profile\", type: \"Profile\" }],\n// list: [],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// profile: {\n// connect: {\n// id: \"123\",\n// },\n// },\n// });\n// });\n\n// it(\"should handle connect operation for singular relation with unique field\", () => {\n// const body = {\n// name: \"John Doe\",\n// category: {\n// name: \"Technology\",\n// },\n// };\n\n// const relationFields = {\n// singular: [\n// {\n// name: \"category\",\n// type: \"Category\",\n// },\n// ],\n// list: [],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// category: {\n// connect: {\n// name: \"Technology\",\n// },\n// },\n// });\n// });\n\n// it(\"should handle update operation for singular relation with id and other fields\", () => {\n// const body = {\n// name: \"John Doe\",\n// profile: {\n// id: \"123\",\n// bio: \"Updated Bio\",\n// avatarUrl: \"https://example.com/new-avatar.jpg\",\n// },\n// };\n\n// const relationFields = {\n// singular: [{ name: \"profile\", type: \"Profile\" }],\n// list: [],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// profile: {\n// update: {\n// data: {\n// bio: \"Updated Bio\",\n// avatarUrl: \"https://example.com/new-avatar.jpg\",\n// },\n// },\n// },\n// });\n// });\n\n// it(\"should handle explicit connect operation with apiAction\", () => {\n// const body = {\n// name: \"John Doe\",\n// profile: {\n// id: \"123\",\n// apiAction: \"connect\",\n// },\n// };\n\n// const relationFields = {\n// singular: [{ name: \"profile\", type: \"Profile\" }],\n// list: [],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// profile: {\n// connect: {\n// id: \"123\",\n// },\n// },\n// });\n// });\n// });\n\n// describe(\"List Relations\", () => {\n// it(\"should handle create operation for list relation items without ids\", () => {\n// const body = {\n// title: \"My Post\",\n// tags: [\n// { name: \"JavaScript\", apiAction: \"create\" },\n// { name: \"TypeScript\", apiAction: \"create\" },\n// ],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"tags\", type: \"Tag\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// title: \"My Post\",\n// tags: {\n// create: [{ name: \"JavaScript\" }, { name: \"TypeScript\" }],\n// },\n// });\n// });\n\n// it(\"should handle connect operation for list relation items with only ids\", () => {\n// const body = {\n// title: \"My Post\",\n// tags: [{ id: \"1\" }, { id: \"2\" }],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"tags\", type: \"Tag\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// title: \"My Post\",\n// tags: {\n// connect: [{ id: \"1\" }, { id: \"2\" }],\n// },\n// });\n// });\n\n// it(\"should handle connect operation for list relation items with unique fields\", () => {\n// const body = {\n// title: \"My Post\",\n// tags: [{ name: \"JavaScript\" }, { name: \"TypeScript\" }],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"tags\", type: \"Tag\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// title: \"My Post\",\n// tags: {\n// connect: [{ name: \"JavaScript\" }, { name: \"TypeScript\" }],\n// },\n// });\n// });\n\n// it(\"should handle update operation for list relation items with ids and other fields\", () => {\n// const body = {\n// title: \"My Post\",\n// tags: [\n// { id: \"1\", name: \"Updated JavaScript\" },\n// { id: \"2\", name: \"Updated TypeScript\" },\n// ],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"tags\", type: \"Tag\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// title: \"My Post\",\n// tags: {\n// update: [\n// { where: { id: \"1\" }, data: { name: \"Updated JavaScript\" } },\n// { where: { id: \"2\" }, data: { name: \"Updated TypeScript\" } },\n// ],\n// },\n// });\n// });\n\n// it('should handle deleteMany operation for list relation items with apiAction: \"delete\"', () => {\n// const body = {\n// title: \"My Post\",\n// tags: [\n// { id: \"1\", apiAction: \"delete\" },\n// { id: \"2\", apiAction: \"delete\" },\n// ],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"tags\", type: \"Tag\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// title: \"My Post\",\n// tags: {\n// deleteMany: {\n// id: { in: [\"1\", \"2\"] },\n// },\n// },\n// });\n// });\n\n// it('should handle disconnect operation for list relation items with apiAction: \"disconnect\"', () => {\n// const body = {\n// title: \"My Post\",\n// tags: [\n// { id: \"1\", apiAction: \"disconnect\" },\n// { id: \"2\", apiAction: \"disconnect\" },\n// ],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"tags\", type: \"Tag\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// title: \"My Post\",\n// tags: {\n// disconnect: [{ id: \"1\" }, { id: \"2\" }],\n// },\n// });\n// });\n\n// it(\"should handle mixed operations for list relation items\", () => {\n// const body = {\n// title: \"My Post\",\n// tags: [\n// { name: \"New Tag\", apiAction: \"create\" }, // create\n// { id: \"1\" }, // connect\n// { id: \"2\", name: \"Updated Tag\" }, // update\n// { id: \"3\", apiAction: \"delete\" }, // delete\n// { id: \"4\", apiAction: \"disconnect\" }, // disconnect\n// ],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"tags\", type: \"Tag\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// title: \"My Post\",\n// tags: {\n// create: [{ name: \"New Tag\" }],\n// connect: [{ id: \"1\" }],\n// update: [{ where: { id: \"2\" }, data: { name: \"Updated Tag\" } }],\n// disconnect: [{ id: \"4\" }],\n// deleteMany: { id: { in: [\"3\"] } },\n// },\n// });\n// });\n// });\n\n// describe(\"Nested Relations\", () => {\n// it(\"should handle nested relations recursively\", () => {\n// const body = {\n// name: \"John Doe\",\n// posts: [\n// {\n// title: \"My First Post\",\n// category: { name: \"Technology\" },\n// tags: [{ name: \"JavaScript\" }],\n// },\n// ],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"posts\", type: \"Post\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// posts: {\n// create: [\n// {\n// title: \"My First Post\",\n// category: {\n// connect: { name: \"Technology\" },\n// },\n// tags: {\n// connect: [{ name: \"JavaScript\" }],\n// },\n// },\n// ],\n// },\n// });\n// });\n\n// it(\"should handle deep nested relations\", () => {\n// const body = {\n// name: \"John Doe\",\n// posts: [\n// {\n// title: \"My First Post\",\n// comments: [\n// {\n// content: \"Great post!\",\n// author: { email: \"user@example.com\", apiAction: \"create\" },\n// },\n// ],\n// },\n// ],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"posts\", type: \"Post\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// posts: {\n// create: [\n// {\n// title: \"My First Post\",\n// comments: {\n// create: [\n// {\n// content: \"Great post!\",\n// author: { create: { email: \"user@example.com\" } },\n// },\n// ],\n// },\n// },\n// ],\n// },\n// });\n// });\n// });\n\n// describe(\"Edge Cases\", () => {\n// it(\"should handle empty arrays for list relation fields\", () => {\n// const body = {\n// name: \"John Doe\",\n// posts: [],\n// };\n\n// const relationFields = {\n// singular: [],\n// list: [{ name: \"posts\", type: \"Post\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// posts: {},\n// });\n// });\n\n// it(\"should handle null values for relation fields\", () => {\n// const body = {\n// name: \"John Doe\",\n// profile: null,\n// posts: null,\n// };\n\n// const relationFields = {\n// singular: [{ name: \"profile\", type: \"Profile\" }],\n// list: [{ name: \"posts\", type: \"Post\" }],\n// };\n\n// const result = handleRelationFieldsInBody(body, relationFields);\n\n// expect(result).toEqual({\n// name: \"John Doe\",\n// profile: null,\n// posts: null,\n// });\n// });\n// });\n// });\n\n// describe(\"canBeUsedToConnect\", () => {\n// it(\"should return true for objects with only an id\", () => {\n// const modelName = \"User\";\n// const bodyField = { id: \"123\" };\n\n// expect(canBeUsedToConnect(modelName, bodyField)).toBe(true);\n// });\n\n// it(\"should return true for objects with a single unique field\", () => {\n// const modelName = \"User\";\n// const bodyField = { email: \"test@example.com\" };\n\n// expect(canBeUsedToConnect(modelName, bodyField)).toBe(true);\n// });\n\n// it(\"should return true for objects with a single field from uniqueFields list\", () => {\n// const modelName = \"User\";\n// const bodyField = { username: \"testuser\" };\n\n// expect(canBeUsedToConnect(modelName, bodyField)).toBe(true);\n// });\n\n// it(\"should return true for objects with apiAction set to connect\", () => {\n// const modelName = \"User\";\n// const bodyField = { id: \"123\", apiAction: \"connect\" };\n\n// expect(canBeUsedToConnect(modelName, bodyField)).toBe(true);\n// });\n\n// it(\"should return false for objects with multiple fields\", () => {\n// const modelName = \"User\";\n// const bodyField = { id: \"123\", name: \"John\" };\n\n// expect(canBeUsedToConnect(modelName, bodyField)).toBe(false);\n// });\n\n// it(\"should return false for objects with a single field that is not unique\", () => {\n// const modelName = \"User\";\n// const bodyField = { name: \"John\" }; // assuming name is not a unique field\n\n// expect(canBeUsedToConnect(modelName, bodyField)).toBe(false);\n// });\n\n// it(\"should return false for objects with apiAction set to something other than connect\", () => {\n// const modelName = \"User\";\n// const bodyField = { id: \"123\", apiAction: \"delete\" };\n\n// expect(canBeUsedToConnect(modelName, bodyField)).toBe(false);\n// });\n\n// it(\"should return false for null or undefined values\", () => {\n// const modelName = \"User\";\n\n// expect(canBeUsedToConnect(modelName, null)).toBe(false);\n// expect(canBeUsedToConnect(modelName, undefined)).toBe(false);\n// });\n// });\n\n// describe(\"isListFieldAnArray\", () => {\n// it(\"should return true for arrays\", () => {\n// expect(isListFieldAnArray([])).toBe(true);\n// expect(isListFieldAnArray([1, 2, 3])).toBe(true);\n// expect(isListFieldAnArray(new Array())).toBe(true);\n// });\n\n// it(\"should return false for non-arrays\", () => {\n// expect(isListFieldAnArray({})).toBe(false);\n// expect(isListFieldAnArray(\"array\")).toBe(false);\n// expect(isListFieldAnArray(123)).toBe(false);\n// expect(isListFieldAnArray(null)).toBe(false);\n// expect(isListFieldAnArray(undefined)).toBe(false);\n// });\n// });\n"]}
@@ -1,4 +1,37 @@
1
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
+ })();
2
35
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
36
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
37
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -20,16 +53,16 @@ exports.getModels = getModels;
20
53
  exports.getModelUniqueFields = getModelUniqueFields;
21
54
  const path_1 = __importDefault(require("path"));
22
55
  const fs_1 = __importDefault(require("fs"));
23
- const change_case_all_1 = require("change-case-all");
56
+ const change_case_helpers_1 = require("../../utils/helpers/change-case.helpers");
24
57
  const arkos_env_1 = __importDefault(require("../arkos-env"));
25
58
  const fs_helpers_1 = require("./fs.helpers");
26
59
  const globalPrismaModelsModules = {};
27
60
  function getModelModules(modelName) {
28
- return globalPrismaModelsModules[(0, change_case_all_1.kebabCase)(modelName)];
61
+ return globalPrismaModelsModules[(0, change_case_helpers_1.kebabCase)(modelName)];
29
62
  }
30
63
  function importPrismaModelModules(modelName) {
31
64
  return __awaiter(this, void 0, void 0, function* () {
32
- const kebabModelName = (0, change_case_all_1.kebabCase)(modelName);
65
+ const kebabModelName = (0, change_case_helpers_1.kebabCase)(modelName);
33
66
  const lowerModelName = modelName.toLowerCase();
34
67
  const moduleDir = path_1.default.resolve(process.cwd(), "src", "modules", modelName);
35
68
  const dtosDir = path_1.default.join(moduleDir, "dtos");
@@ -51,7 +84,7 @@ function importPrismaModelModules(modelName) {
51
84
  };
52
85
  try {
53
86
  if (fs_1.default.existsSync(middlewaresFile)) {
54
- const middlewareModule = yield import(middlewaresFile);
87
+ const middlewareModule = yield Promise.resolve(`${middlewaresFile}`).then(s => __importStar(require(s)));
55
88
  result.middlewares = middlewareModule;
56
89
  }
57
90
  }
@@ -60,7 +93,7 @@ function importPrismaModelModules(modelName) {
60
93
  }
61
94
  try {
62
95
  if (fs_1.default.existsSync(authConfigsFile)) {
63
- const authConfigsModule = yield import(authConfigsFile);
96
+ const authConfigsModule = yield Promise.resolve(`${authConfigsFile}`).then(s => __importStar(require(s)));
64
97
  result.authConfigs = authConfigsModule.default || authConfigsModule;
65
98
  }
66
99
  }
@@ -69,7 +102,7 @@ function importPrismaModelModules(modelName) {
69
102
  }
70
103
  try {
71
104
  if (fs_1.default.existsSync(prismaQueryOptionsFile)) {
72
- const prismaQueryOptionsModule = yield import(prismaQueryOptionsFile);
105
+ const prismaQueryOptionsModule = yield Promise.resolve(`${prismaQueryOptionsFile}`).then(s => __importStar(require(s)));
73
106
  result.prismaQueryOptions =
74
107
  prismaQueryOptionsModule.default || prismaQueryOptionsModule;
75
108
  }
@@ -77,10 +110,10 @@ function importPrismaModelModules(modelName) {
77
110
  catch (error) {
78
111
  console.error(`Error importing prisma query options for model "${modelName}":`, error);
79
112
  }
80
- const pascalModelName = (0, change_case_all_1.pascalCase)(modelName);
113
+ const pascalModelName = (0, change_case_helpers_1.pascalCase)(modelName);
81
114
  try {
82
115
  if (fs_1.default.existsSync(modelDtoFile)) {
83
- const modelDtoModule = yield import(modelDtoFile);
116
+ const modelDtoModule = yield Promise.resolve(`${modelDtoFile}`).then(s => __importStar(require(s)));
84
117
  result.dtos.model =
85
118
  modelDtoModule.default || modelDtoModule[`${pascalModelName}Dto`];
86
119
  }
@@ -90,7 +123,7 @@ function importPrismaModelModules(modelName) {
90
123
  }
91
124
  try {
92
125
  if (fs_1.default.existsSync(createDtoFile)) {
93
- const createDtoModule = yield import(createDtoFile);
126
+ const createDtoModule = yield Promise.resolve(`${createDtoFile}`).then(s => __importStar(require(s)));
94
127
  result.dtos.create =
95
128
  createDtoModule.default ||
96
129
  createDtoModule[`Create${pascalModelName}Dto`];
@@ -101,7 +134,7 @@ function importPrismaModelModules(modelName) {
101
134
  }
102
135
  try {
103
136
  if (fs_1.default.existsSync(updateDtoFile)) {
104
- const updateDtoModule = yield import(updateDtoFile);
137
+ const updateDtoModule = yield Promise.resolve(`${updateDtoFile}`).then(s => __importStar(require(s)));
105
138
  result.dtos.update =
106
139
  updateDtoModule.default ||
107
140
  updateDtoModule[`Update${pascalModelName}Dto`];
@@ -112,7 +145,7 @@ function importPrismaModelModules(modelName) {
112
145
  }
113
146
  try {
114
147
  if (fs_1.default.existsSync(queryDtoFile)) {
115
- const queryDtoModule = yield import(queryDtoFile);
148
+ const queryDtoModule = yield Promise.resolve(`${queryDtoFile}`).then(s => __importStar(require(s)));
116
149
  result.dtos.query =
117
150
  queryDtoModule.default || queryDtoModule[`Query${pascalModelName}Dto`];
118
151
  }
@@ -122,7 +155,7 @@ function importPrismaModelModules(modelName) {
122
155
  }
123
156
  try {
124
157
  if (fs_1.default.existsSync(createSchemaFile)) {
125
- const createSchemaModule = yield import(createSchemaFile);
158
+ const createSchemaModule = yield Promise.resolve(`${createSchemaFile}`).then(s => __importStar(require(s)));
126
159
  result.dtos.create =
127
160
  createSchemaModule.default ||
128
161
  createSchemaModule[`Create${pascalModelName}Schema`];
@@ -133,7 +166,7 @@ function importPrismaModelModules(modelName) {
133
166
  }
134
167
  try {
135
168
  if (fs_1.default.existsSync(updateSchemaFile)) {
136
- const updateSchemaModule = yield import(updateSchemaFile);
169
+ const updateSchemaModule = yield Promise.resolve(`${updateSchemaFile}`).then(s => __importStar(require(s)));
137
170
  result.dtos.update =
138
171
  updateSchemaModule.default ||
139
172
  updateSchemaModule[`Update${pascalModelName}Schema`];
@@ -144,7 +177,7 @@ function importPrismaModelModules(modelName) {
144
177
  }
145
178
  try {
146
179
  if (fs_1.default.existsSync(querySchemaFile)) {
147
- const querySchemaModule = yield import(querySchemaFile);
180
+ const querySchemaModule = yield Promise.resolve(`${querySchemaFile}`).then(s => __importStar(require(s)));
148
181
  result.dtos.query =
149
182
  querySchemaModule.default ||
150
183
  querySchemaModule[`Query${pascalModelName}Schema`];
@@ -178,11 +211,11 @@ exports.models = models;
178
211
  const prismaModelsUniqueFields = [];
179
212
  prismaContent.join("\n").replace(modelRegex, (_, modelName) => {
180
213
  if (!models.includes(modelName))
181
- models.push((0, change_case_all_1.camelCase)(modelName.trim()));
214
+ models.push((0, change_case_helpers_1.camelCase)(modelName.trim()));
182
215
  return modelName;
183
216
  });
184
217
  for (const model of models) {
185
- const modelName = (0, change_case_all_1.pascalCase)(model);
218
+ const modelName = (0, change_case_helpers_1.pascalCase)(model);
186
219
  let modelFile;
187
220
  for (const file of files) {
188
221
  const filePath = path_1.default.join(schemaFolderPath, file);
@@ -224,7 +257,7 @@ for (const model of models) {
224
257
  const cleanType = type === null || type === void 0 ? void 0 : type.replace("[]", "").replace("?", "");
225
258
  if (trimmedLine.includes("@relation") ||
226
259
  trimmedLine.match(/\s+\w+(\[\])?(\s+@|$)/) ||
227
- models.includes((0, change_case_all_1.camelCase)(cleanType || ""))) {
260
+ models.includes((0, change_case_helpers_1.camelCase)(cleanType || ""))) {
228
261
  const modelStart = content.indexOf(`enum ${cleanType} {`);
229
262
  if (!cleanType ||
230
263
  modelStart >= 0 ||
@@ -256,7 +289,7 @@ for (const model of models) {
256
289
  }
257
290
  }
258
291
  function getPrismaModelRelations(modelName) {
259
- modelName = (0, change_case_all_1.pascalCase)(modelName);
292
+ modelName = (0, change_case_helpers_1.pascalCase)(modelName);
260
293
  if (!(modelName in prismaModelRelationFields))
261
294
  return;
262
295
  return prismaModelRelationFields[modelName];
@@ -1 +1 @@
1
- {"version":3,"file":"models.helpers.js","sourceRoot":"","sources":["../../../../src/utils/helpers/models.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\nimport fs from \"fs\";\nimport { camelCase, kebabCase, pascalCase } from \"change-case-all\";\nimport arkosEnv from \"../arkos-env\";\nimport { userFileExtension } from \"./fs.helpers\";\n\nconst globalPrismaModelsModules: Record<\n string,\n Awaited<ReturnType<typeof importPrismaModelModules>>\n> = {};\n\nexport function getModelModules(modelName: string) {\n return globalPrismaModelsModules[kebabCase(modelName)];\n}\n\n/**\n * Dynamically imports model-specific modules like middlewares, auth configurations,\n * prisma query options, and DTOs for a given model.\n *\n * @param {string} modelName - The name of the model (e.g., \"User\", \"Post\").\n * @returns {Promise<Object>} An object containing the imported modules: `middlewares`, `authConfigs`, `prismaQueryOptions`, and `dtos`.\n */\nexport async function importPrismaModelModules(modelName: string) {\n const kebabModelName = kebabCase(modelName);\n const lowerModelName = modelName.toLowerCase();\n\n const moduleDir = path.resolve(process.cwd(), \"src\", \"modules\", modelName);\n const dtosDir = path.join(moduleDir, \"dtos\");\n const schemasDir = path.join(moduleDir, \"schemas\");\n\n const middlewaresFile = path.join(\n moduleDir,\n `${kebabModelName}.middlewares.${userFileExtension}`\n );\n const authConfigsFile = path.join(\n moduleDir,\n `${kebabModelName}.auth-configs.${userFileExtension}`\n );\n const prismaQueryOptionsFile = path.join(\n moduleDir,\n `${kebabModelName}.prisma-query-options.${userFileExtension}`\n );\n\n // Define DTO file paths\n const modelDtoFile = path.join(\n dtosDir,\n `${lowerModelName}.dto.${userFileExtension}`\n );\n const createDtoFile = path.join(\n dtosDir,\n `create-${lowerModelName}.dto.${userFileExtension}`\n );\n const updateDtoFile = path.join(\n dtosDir,\n `update-${lowerModelName}.dto.${userFileExtension}`\n );\n const queryDtoFile = path.join(\n dtosDir,\n `query-${lowerModelName}.dto.${userFileExtension}`\n );\n\n const modelSchemaFile = path.join(\n schemasDir,\n `${lowerModelName}.schema.${userFileExtension}`\n );\n const createSchemaFile = path.join(\n schemasDir,\n `create-${lowerModelName}.schema.${userFileExtension}`\n );\n const updateSchemaFile = path.join(\n schemasDir,\n `update-${lowerModelName}.schema.${userFileExtension}`\n );\n const querySchemaFile = path.join(\n schemasDir,\n `query-${lowerModelName}.schema.${userFileExtension}`\n );\n\n const result: {\n middlewares?: any;\n authConfigs?: any;\n prismaQueryOptions?: any;\n dtos: {\n create?: any;\n update?: any;\n query?: any;\n model?: any;\n };\n schemas: {\n create?: any;\n update?: any;\n query?: any;\n model?: any;\n };\n } = {\n dtos: {},\n schemas: {},\n };\n\n try {\n if (fs.existsSync(middlewaresFile)) {\n const middlewareModule = await import(middlewaresFile);\n result.middlewares = middlewareModule;\n }\n } catch (error) {\n console.error(\n `Error importing middlewares for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(authConfigsFile)) {\n const authConfigsModule = await import(authConfigsFile);\n result.authConfigs = authConfigsModule.default || authConfigsModule;\n }\n } catch (error) {\n console.error(\n `Error importing auth configs for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(prismaQueryOptionsFile)) {\n const prismaQueryOptionsModule = await import(prismaQueryOptionsFile);\n result.prismaQueryOptions =\n prismaQueryOptionsModule.default || prismaQueryOptionsModule;\n }\n } catch (error) {\n console.error(\n `Error importing prisma query options for model \"${modelName}\":`,\n error\n );\n }\n\n // Import DTOs\n const pascalModelName = pascalCase(modelName);\n try {\n if (fs.existsSync(modelDtoFile)) {\n const modelDtoModule = await import(modelDtoFile);\n result.dtos.model =\n modelDtoModule.default || modelDtoModule[`${pascalModelName}Dto`];\n }\n } catch (error) {\n console.error(\n `Error importing model main DTO for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(createDtoFile)) {\n const createDtoModule = await import(createDtoFile);\n result.dtos.create =\n createDtoModule.default ||\n createDtoModule[`Create${pascalModelName}Dto`];\n }\n } catch (error) {\n console.error(\n `Error importing create DTO for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(updateDtoFile)) {\n const updateDtoModule = await import(updateDtoFile);\n result.dtos.update =\n updateDtoModule.default ||\n updateDtoModule[`Update${pascalModelName}Dto`];\n }\n } catch (error) {\n console.error(\n `Error importing update DTO for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(queryDtoFile)) {\n const queryDtoModule = await import(queryDtoFile);\n result.dtos.query =\n queryDtoModule.default || queryDtoModule[`Query${pascalModelName}Dto`];\n }\n } catch (error) {\n console.error(`Error importing query DTO for model \"${modelName}\":`, error);\n }\n\n try {\n if (fs.existsSync(createSchemaFile)) {\n const createSchemaModule = await import(createSchemaFile);\n result.dtos.create =\n createSchemaModule.default ||\n createSchemaModule[`Create${pascalModelName}Schema`];\n }\n } catch (error) {\n console.error(\n `Error importing create Schema for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(updateSchemaFile)) {\n const updateSchemaModule = await import(updateSchemaFile);\n result.dtos.update =\n updateSchemaModule.default ||\n updateSchemaModule[`Update${pascalModelName}Schema`];\n }\n } catch (error) {\n console.error(\n `Error importing update Schema for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(querySchemaFile)) {\n const querySchemaModule = await import(querySchemaFile);\n result.dtos.query =\n querySchemaModule.default ||\n querySchemaModule[`Query${pascalModelName}Schema`];\n }\n } catch (error) {\n console.error(\n `Error importing query Schema for model \"${modelName}\":`,\n error\n );\n }\n\n globalPrismaModelsModules[modelName] = result;\n\n return result;\n}\n\nexport type ModelFieldDefition = {\n name: string;\n type: string;\n isUnique: boolean;\n};\n\n/**\n * Represents the structure of relation fields for Prisma models.\n * It includes both singular (one-to-one) and list (one-to-many) relationships.\n *\n * @typedef {Object} RelationFields\n * @property {Array<{name: string, type: string}>} singular - List of singular relationships.\n * @property {Array<{name: string, type: string}>} list - List of list relationships.\n */\nexport type RelationFields = {\n singular: Omit<ModelFieldDefition, \"isUnique\">[];\n list: Omit<ModelFieldDefition, \"isUnique\">[];\n};\n\nconst schemaFolderPath =\n process.env.PRISMA_SCHEMA_PATH || arkosEnv.PRISMA_SCHEMA_PATH;\n\n/**\n * Reads the Prisma schema files and extracts all model definitions,\n * identifying their relations (one-to-one and one-to-many).\n */\nconst prismaModelRelationFields: Record<string, RelationFields> = {};\n\nconst prismaContent = [];\n\nconst files = fs\n .readdirSync(schemaFolderPath)\n .filter((file) => file.endsWith(\".prisma\"));\n\nfor (const file of files) {\n const filePath = path.join(schemaFolderPath, file);\n const stats = fs.statSync(filePath);\n\n if (stats.isFile()) {\n const content = fs.readFileSync(filePath, \"utf-8\");\n prismaContent.push(content);\n }\n}\n\nconst modelRegex = /model\\s+(\\w+)\\s*{/g;\nconst models: string[] = [];\nconst prismaModelsUniqueFields: Record<string, ModelFieldDefition[]> =\n [] as any;\n\nprismaContent.join(\"\\n\").replace(modelRegex, (_, modelName) => {\n if (!models.includes(modelName)) models.push(camelCase(modelName.trim()));\n return modelName;\n});\n\nfor (const model of models) {\n const modelName = pascalCase(model);\n\n let modelFile;\n for (const file of files) {\n const filePath = path.join(schemaFolderPath, file);\n const stats = fs.statSync(filePath);\n\n if (stats.isFile()) {\n const content = fs.readFileSync(filePath, \"utf-8\");\n prismaContent.push(content);\n if (content.includes(`model ${modelName} {`)) {\n modelFile = file;\n break;\n }\n }\n }\n\n if (!modelFile) {\n throw new Error(`Model ${modelName} not found`);\n }\n\n const content = fs.readFileSync(\n path.join(schemaFolderPath, modelFile),\n \"utf-8\"\n );\n\n const modelStart = content.indexOf(`model ${modelName} {`);\n const modelEnd = content.indexOf(\"}\", modelStart);\n const modelDefinition = content.slice(modelStart, modelEnd);\n\n const relations: RelationFields = {\n singular: [],\n list: [],\n };\n const lines = modelDefinition.split(\"\\n\");\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n\n if (\n !trimmedLine ||\n trimmedLine.startsWith(\"model\") ||\n trimmedLine.startsWith(\"//\")\n )\n continue;\n\n const [fieldName, type] = trimmedLine.split(/\\s+/);\n const isUnique = trimmedLine.includes(\"@unique\");\n\n if (isUnique)\n prismaModelsUniqueFields[model] = [\n ...(prismaModelsUniqueFields[model] || []),\n { name: fieldName, type, isUnique },\n ];\n\n const cleanType = type?.replace(\"[]\", \"\").replace(\"?\", \"\");\n\n if (\n trimmedLine.includes(\"@relation\") ||\n trimmedLine.match(/\\s+\\w+(\\[\\])?(\\s+@|$)/) ||\n models.includes(camelCase(cleanType || \"\"))\n ) {\n const modelStart = content.indexOf(`enum ${cleanType} {`);\n\n if (\n !cleanType ||\n modelStart >= 0 ||\n cleanType === \"String\" ||\n cleanType === \"Int\" ||\n cleanType === \"Float\" ||\n cleanType === \"Boolean\" ||\n cleanType === \"DateTime\" ||\n cleanType === \"Bytes\" ||\n cleanType === \"Decimal\" ||\n cleanType === \"BigInt\" ||\n cleanType === \"Json\"\n ) {\n continue;\n }\n\n if (!type?.includes(\"[]\")) {\n relations.singular.push({\n name: fieldName,\n type: cleanType,\n });\n } else {\n relations.list.push({\n name: fieldName,\n type: cleanType,\n });\n }\n }\n\n prismaModelRelationFields[modelName] = relations;\n }\n}\n\n/**\n * Retrieves the relations for a given Prisma model.\n *\n * @param {string} modelName - The name of the model (e.g., \"User\").\n * @returns {RelationFields|undefined} The relation fields for the model, or `undefined` if no relations are found.\n */\nexport function getPrismaModelRelations(modelName: string) {\n modelName = pascalCase(modelName);\n if (!(modelName in prismaModelRelationFields)) return;\n return prismaModelRelationFields[modelName];\n}\n\n/**\n * Retrieves all the model names from the Prisma schema.\n *\n * @returns {string[]} An array of model names (e.g., [\"User\", \"Post\"]).\n */\nfunction getModels() {\n return models;\n}\n\n/** Retuns a given model unique fields\n * @param {string} modelName - The name of model in PascalCase\n * @returns {string[]} An array of all unique fields,\n */\nfunction getModelUniqueFields(modelName: string) {\n return prismaModelsUniqueFields[modelName];\n}\n\nexport { models, getModels, getModelUniqueFields, prismaModelRelationFields };\n"]}
1
+ {"version":3,"file":"models.helpers.js","sourceRoot":"","sources":["../../../../src/utils/helpers/models.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\nimport fs from \"fs\";\nimport {\n camelCase,\n kebabCase,\n pascalCase,\n} from \"../../utils/helpers/change-case.helpers\";\nimport arkosEnv from \"../arkos-env\";\nimport { userFileExtension } from \"./fs.helpers\";\n\nconst globalPrismaModelsModules: Record<\n string,\n Awaited<ReturnType<typeof importPrismaModelModules>>\n> = {};\n\nexport function getModelModules(modelName: string) {\n return globalPrismaModelsModules[kebabCase(modelName)];\n}\n\n/**\n * Dynamically imports model-specific modules like middlewares, auth configurations,\n * prisma query options, and DTOs for a given model.\n *\n * @param {string} modelName - The name of the model (e.g., \"User\", \"Post\").\n * @returns {Promise<Object>} An object containing the imported modules: `middlewares`, `authConfigs`, `prismaQueryOptions`, and `dtos`.\n */\nexport async function importPrismaModelModules(modelName: string) {\n const kebabModelName = kebabCase(modelName);\n const lowerModelName = modelName.toLowerCase();\n\n const moduleDir = path.resolve(process.cwd(), \"src\", \"modules\", modelName);\n const dtosDir = path.join(moduleDir, \"dtos\");\n const schemasDir = path.join(moduleDir, \"schemas\");\n\n const middlewaresFile = path.join(\n moduleDir,\n `${kebabModelName}.middlewares.${userFileExtension}`\n );\n const authConfigsFile = path.join(\n moduleDir,\n `${kebabModelName}.auth-configs.${userFileExtension}`\n );\n const prismaQueryOptionsFile = path.join(\n moduleDir,\n `${kebabModelName}.prisma-query-options.${userFileExtension}`\n );\n\n // Define DTO file paths\n const modelDtoFile = path.join(\n dtosDir,\n `${lowerModelName}.dto.${userFileExtension}`\n );\n const createDtoFile = path.join(\n dtosDir,\n `create-${lowerModelName}.dto.${userFileExtension}`\n );\n const updateDtoFile = path.join(\n dtosDir,\n `update-${lowerModelName}.dto.${userFileExtension}`\n );\n const queryDtoFile = path.join(\n dtosDir,\n `query-${lowerModelName}.dto.${userFileExtension}`\n );\n\n const modelSchemaFile = path.join(\n schemasDir,\n `${lowerModelName}.schema.${userFileExtension}`\n );\n const createSchemaFile = path.join(\n schemasDir,\n `create-${lowerModelName}.schema.${userFileExtension}`\n );\n const updateSchemaFile = path.join(\n schemasDir,\n `update-${lowerModelName}.schema.${userFileExtension}`\n );\n const querySchemaFile = path.join(\n schemasDir,\n `query-${lowerModelName}.schema.${userFileExtension}`\n );\n\n const result: {\n middlewares?: any;\n authConfigs?: any;\n prismaQueryOptions?: any;\n dtos: {\n create?: any;\n update?: any;\n query?: any;\n model?: any;\n };\n schemas: {\n create?: any;\n update?: any;\n query?: any;\n model?: any;\n };\n } = {\n dtos: {},\n schemas: {},\n };\n\n try {\n if (fs.existsSync(middlewaresFile)) {\n const middlewareModule = await import(middlewaresFile);\n result.middlewares = middlewareModule;\n }\n } catch (error) {\n console.error(\n `Error importing middlewares for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(authConfigsFile)) {\n const authConfigsModule = await import(authConfigsFile);\n result.authConfigs = authConfigsModule.default || authConfigsModule;\n }\n } catch (error) {\n console.error(\n `Error importing auth configs for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(prismaQueryOptionsFile)) {\n const prismaQueryOptionsModule = await import(prismaQueryOptionsFile);\n result.prismaQueryOptions =\n prismaQueryOptionsModule.default || prismaQueryOptionsModule;\n }\n } catch (error) {\n console.error(\n `Error importing prisma query options for model \"${modelName}\":`,\n error\n );\n }\n\n // Import DTOs\n const pascalModelName = pascalCase(modelName);\n try {\n if (fs.existsSync(modelDtoFile)) {\n const modelDtoModule = await import(modelDtoFile);\n result.dtos.model =\n modelDtoModule.default || modelDtoModule[`${pascalModelName}Dto`];\n }\n } catch (error) {\n console.error(\n `Error importing model main DTO for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(createDtoFile)) {\n const createDtoModule = await import(createDtoFile);\n result.dtos.create =\n createDtoModule.default ||\n createDtoModule[`Create${pascalModelName}Dto`];\n }\n } catch (error) {\n console.error(\n `Error importing create DTO for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(updateDtoFile)) {\n const updateDtoModule = await import(updateDtoFile);\n result.dtos.update =\n updateDtoModule.default ||\n updateDtoModule[`Update${pascalModelName}Dto`];\n }\n } catch (error) {\n console.error(\n `Error importing update DTO for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(queryDtoFile)) {\n const queryDtoModule = await import(queryDtoFile);\n result.dtos.query =\n queryDtoModule.default || queryDtoModule[`Query${pascalModelName}Dto`];\n }\n } catch (error) {\n console.error(`Error importing query DTO for model \"${modelName}\":`, error);\n }\n\n try {\n if (fs.existsSync(createSchemaFile)) {\n const createSchemaModule = await import(createSchemaFile);\n result.dtos.create =\n createSchemaModule.default ||\n createSchemaModule[`Create${pascalModelName}Schema`];\n }\n } catch (error) {\n console.error(\n `Error importing create Schema for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(updateSchemaFile)) {\n const updateSchemaModule = await import(updateSchemaFile);\n result.dtos.update =\n updateSchemaModule.default ||\n updateSchemaModule[`Update${pascalModelName}Schema`];\n }\n } catch (error) {\n console.error(\n `Error importing update Schema for model \"${modelName}\":`,\n error\n );\n }\n\n try {\n if (fs.existsSync(querySchemaFile)) {\n const querySchemaModule = await import(querySchemaFile);\n result.dtos.query =\n querySchemaModule.default ||\n querySchemaModule[`Query${pascalModelName}Schema`];\n }\n } catch (error) {\n console.error(\n `Error importing query Schema for model \"${modelName}\":`,\n error\n );\n }\n\n globalPrismaModelsModules[modelName] = result;\n\n return result;\n}\n\nexport type ModelFieldDefition = {\n name: string;\n type: string;\n isUnique: boolean;\n};\n\n/**\n * Represents the structure of relation fields for Prisma models.\n * It includes both singular (one-to-one) and list (one-to-many) relationships.\n *\n * @typedef {Object} RelationFields\n * @property {Array<{name: string, type: string}>} singular - List of singular relationships.\n * @property {Array<{name: string, type: string}>} list - List of list relationships.\n */\nexport type RelationFields = {\n singular: Omit<ModelFieldDefition, \"isUnique\">[];\n list: Omit<ModelFieldDefition, \"isUnique\">[];\n};\n\nconst schemaFolderPath =\n process.env.PRISMA_SCHEMA_PATH || arkosEnv.PRISMA_SCHEMA_PATH;\n\n/**\n * Reads the Prisma schema files and extracts all model definitions,\n * identifying their relations (one-to-one and one-to-many).\n */\nconst prismaModelRelationFields: Record<string, RelationFields> = {};\n\nconst prismaContent: string[] = [];\n\nconst files = fs\n .readdirSync(schemaFolderPath)\n .filter((file) => file.endsWith(\".prisma\"));\n\nfor (const file of files) {\n const filePath = path.join(schemaFolderPath, file);\n const stats = fs.statSync(filePath);\n\n if (stats.isFile()) {\n const content = fs.readFileSync(filePath, \"utf-8\");\n prismaContent.push(content);\n }\n}\n\nconst modelRegex = /model\\s+(\\w+)\\s*{/g;\nconst models: string[] = [];\nconst prismaModelsUniqueFields: Record<string, ModelFieldDefition[]> =\n [] as any;\n\nprismaContent.join(\"\\n\").replace(modelRegex, (_, modelName) => {\n if (!models.includes(modelName)) models.push(camelCase(modelName.trim()));\n return modelName;\n});\n\nfor (const model of models) {\n const modelName = pascalCase(model);\n\n let modelFile;\n for (const file of files) {\n const filePath = path.join(schemaFolderPath, file);\n const stats = fs.statSync(filePath);\n\n if (stats.isFile()) {\n const content = fs.readFileSync(filePath, \"utf-8\");\n prismaContent.push(content);\n if (content.includes(`model ${modelName} {`)) {\n modelFile = file;\n break;\n }\n }\n }\n\n if (!modelFile) {\n throw new Error(`Model ${modelName} not found`);\n }\n\n const content = fs.readFileSync(\n path.join(schemaFolderPath, modelFile),\n \"utf-8\"\n );\n\n const modelStart = content.indexOf(`model ${modelName} {`);\n const modelEnd = content.indexOf(\"}\", modelStart);\n const modelDefinition = content.slice(modelStart, modelEnd);\n\n const relations: RelationFields = {\n singular: [],\n list: [],\n };\n const lines = modelDefinition.split(\"\\n\");\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n\n if (\n !trimmedLine ||\n trimmedLine.startsWith(\"model\") ||\n trimmedLine.startsWith(\"//\")\n )\n continue;\n\n const [fieldName, type] = trimmedLine.split(/\\s+/);\n const isUnique = trimmedLine.includes(\"@unique\");\n\n if (isUnique)\n prismaModelsUniqueFields[model] = [\n ...(prismaModelsUniqueFields[model] || []),\n { name: fieldName, type, isUnique },\n ];\n\n const cleanType = type?.replace(\"[]\", \"\").replace(\"?\", \"\");\n\n if (\n trimmedLine.includes(\"@relation\") ||\n trimmedLine.match(/\\s+\\w+(\\[\\])?(\\s+@|$)/) ||\n models.includes(camelCase(cleanType || \"\"))\n ) {\n const modelStart = content.indexOf(`enum ${cleanType} {`);\n\n if (\n !cleanType ||\n modelStart >= 0 ||\n cleanType === \"String\" ||\n cleanType === \"Int\" ||\n cleanType === \"Float\" ||\n cleanType === \"Boolean\" ||\n cleanType === \"DateTime\" ||\n cleanType === \"Bytes\" ||\n cleanType === \"Decimal\" ||\n cleanType === \"BigInt\" ||\n cleanType === \"Json\"\n ) {\n continue;\n }\n\n if (!type?.includes(\"[]\")) {\n relations.singular.push({\n name: fieldName,\n type: cleanType,\n });\n } else {\n relations.list.push({\n name: fieldName,\n type: cleanType,\n });\n }\n }\n\n prismaModelRelationFields[modelName] = relations;\n }\n}\n\n/**\n * Retrieves the relations for a given Prisma model.\n *\n * @param {string} modelName - The name of the model (e.g., \"User\").\n * @returns {RelationFields|undefined} The relation fields for the model, or `undefined` if no relations are found.\n */\nexport function getPrismaModelRelations(modelName: string) {\n modelName = pascalCase(modelName);\n if (!(modelName in prismaModelRelationFields)) return;\n return prismaModelRelationFields[modelName];\n}\n\n/**\n * Retrieves all the model names from the Prisma schema.\n *\n * @returns {string[]} An array of model names (e.g., [\"User\", \"Post\"]).\n */\nfunction getModels() {\n return models;\n}\n\n/** Retuns a given model unique fields\n * @param {string} modelName - The name of model in PascalCase\n * @returns {string[]} An array of all unique fields,\n */\nfunction getModelUniqueFields(modelName: string) {\n return prismaModelsUniqueFields[modelName];\n}\n\nexport { models, getModels, getModelUniqueFields, prismaModelRelationFields };\n"]}
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
2
  //# sourceMappingURL=pluralize.helpers.js.map
@@ -1,4 +1,37 @@
1
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
+ })();
2
35
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
36
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
37
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -26,7 +59,7 @@ const loadPrismaModule = () => __awaiter(void 0, void 0, void 0, function* () {
26
59
  if (!fs_1.default.existsSync(prismaPath)) {
27
60
  prismaPath = `${process.cwd()}/src/utils/prisma.${fs_helpers_1.userFileExtension}`;
28
61
  }
29
- const prismaModule = yield import(prismaPath);
62
+ const prismaModule = yield Promise.resolve(`${prismaPath}`).then(s => __importStar(require(s)));
30
63
  prismaInstance = prismaModule.default || prismaModule.prisma;
31
64
  }
32
65
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.helpers.js","sourceRoot":"","sources":["../../../../src/utils/helpers/prisma.helpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AA2BA,8CAEC;AA7BD,4CAAoB;AAEpB,gGAAuE;AACvE,4FAAmE;AACnE,6CAAiD;AAEjD,IAAI,cAAc,GAAQ,IAAI,CAAC;AAExB,MAAM,gBAAgB,GAAG,GAAS,EAAE;IACzC,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,IAAI,UAAU,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,2BAA2B,8BAAiB,EAAE,CAAC;YAEhF,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,UAAU,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,qBAAqB,8BAAiB,EAAE,CAAC;YACxE,CAAC;YAED,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;YAC9C,cAAc,GAAG,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC,CAAA,CAAC;AAjBW,QAAA,gBAAgB,oBAiB3B;AAEF,SAAgB,iBAAiB;IAC/B,OAAO,cAAc,CAAC;AACxB,CAAC;AAEY,QAAA,uBAAuB,GAAG,IAAA,qBAAU,EAC/C,CAAO,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxD,MAAM,MAAM,GAAG,MAAM,IAAA,wBAAgB,GAAE,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC;IACT,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,mBAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IACzC,CAAC;AACH,CAAC,CAAA,CACF,CAAC","sourcesContent":["import fs from \"fs\";\nimport { Request, Response, NextFunction } from \"express\";\nimport catchAsync from \"../../modules/error-handler/utils/catch-async\";\nimport AppError from \"../../modules/error-handler/utils/app-error\";\nimport { userFileExtension } from \"./fs.helpers\";\n\nlet prismaInstance: any = null;\n\nexport const loadPrismaModule = async () => {\n if (!prismaInstance) {\n try {\n let prismaPath = `${process.cwd()}/src/utils/prisma/index.${userFileExtension}`;\n\n if (!fs.existsSync(prismaPath)) {\n prismaPath = `${process.cwd()}/src/utils/prisma.${userFileExtension}`;\n }\n\n const prismaModule = await import(prismaPath);\n prismaInstance = prismaModule.default || prismaModule.prisma;\n } catch (error) {\n console.error(\"Failed to load prisma.ts:\", error);\n throw new Error(\"Could not initialize Prisma module.\");\n }\n }\n return prismaInstance;\n};\n\nexport function getPrismaInstance() {\n return prismaInstance;\n}\n\nexport const checkDatabaseConnection = catchAsync(\n async (req: Request, res: Response, next: NextFunction) => {\n const prisma = await loadPrismaModule();\n try {\n await prisma.$connect();\n next();\n } catch (error: any) {\n console.error(\"Database connection error\", error.message);\n next(new AppError(error.message, 503));\n }\n }\n);\n"]}
1
+ {"version":3,"file":"prisma.helpers.js","sourceRoot":"","sources":["../../../../src/utils/helpers/prisma.helpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,8CAEC;AA7BD,4CAAoB;AAEpB,gGAAuE;AACvE,4FAAmE;AACnE,6CAAiD;AAEjD,IAAI,cAAc,GAAQ,IAAI,CAAC;AAExB,MAAM,gBAAgB,GAAG,GAAS,EAAE;IACzC,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,IAAI,UAAU,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,2BAA2B,8BAAiB,EAAE,CAAC;YAEhF,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,UAAU,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,qBAAqB,8BAAiB,EAAE,CAAC;YACxE,CAAC;YAED,MAAM,YAAY,GAAG,yBAAa,UAAU,uCAAC,CAAC;YAC9C,cAAc,GAAG,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC,CAAA,CAAC;AAjBW,QAAA,gBAAgB,oBAiB3B;AAEF,SAAgB,iBAAiB;IAC/B,OAAO,cAAc,CAAC;AACxB,CAAC;AAEY,QAAA,uBAAuB,GAAG,IAAA,qBAAU,EAC/C,CAAO,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxD,MAAM,MAAM,GAAG,MAAM,IAAA,wBAAgB,GAAE,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC;IACT,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,mBAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IACzC,CAAC;AACH,CAAC,CAAA,CACF,CAAC","sourcesContent":["import fs from \"fs\";\nimport { Request, Response, NextFunction } from \"express\";\nimport catchAsync from \"../../modules/error-handler/utils/catch-async\";\nimport AppError from \"../../modules/error-handler/utils/app-error\";\nimport { userFileExtension } from \"./fs.helpers\";\n\nlet prismaInstance: any = null;\n\nexport const loadPrismaModule = async () => {\n if (!prismaInstance) {\n try {\n let prismaPath = `${process.cwd()}/src/utils/prisma/index.${userFileExtension}`;\n\n if (!fs.existsSync(prismaPath)) {\n prismaPath = `${process.cwd()}/src/utils/prisma.${userFileExtension}`;\n }\n\n const prismaModule = await import(prismaPath);\n prismaInstance = prismaModule.default || prismaModule.prisma;\n } catch (error) {\n console.error(\"Failed to load prisma.ts:\", error);\n throw new Error(\"Could not initialize Prisma module.\");\n }\n }\n return prismaInstance;\n};\n\nexport function getPrismaInstance() {\n return prismaInstance;\n}\n\nexport const checkDatabaseConnection = catchAsync(\n async (req: Request, res: Response, next: NextFunction) => {\n const prisma = await loadPrismaModule();\n try {\n await prisma.$connect();\n next();\n } catch (error: any) {\n console.error(\"Database connection error\", error.message);\n next(new AppError(error.message, 503));\n }\n }\n);\n"]}