nestforge-generator 0.1.0

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 (326) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +371 -0
  3. package/README.pt-BR.md +370 -0
  4. package/dist/features/auth-strategy.js +19 -0
  5. package/dist/features/auth-strategy.js.map +1 -0
  6. package/dist/features/database.js +59 -0
  7. package/dist/features/database.js.map +1 -0
  8. package/dist/features/dependencies.js +57 -0
  9. package/dist/features/dependencies.js.map +1 -0
  10. package/dist/features/language.js +172 -0
  11. package/dist/features/language.js.map +1 -0
  12. package/dist/features/markers.js +116 -0
  13. package/dist/features/markers.js.map +1 -0
  14. package/dist/generator.js +120 -0
  15. package/dist/generator.js.map +1 -0
  16. package/dist/index.js +59 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/prompts.js +137 -0
  19. package/dist/prompts.js.map +1 -0
  20. package/package.json +76 -0
  21. package/templates/drizzle/.env.example +45 -0
  22. package/templates/drizzle/.env.test +38 -0
  23. package/templates/drizzle/.github/workflows/ci.yml +119 -0
  24. package/templates/drizzle/ARCHITECTURE.md +227 -0
  25. package/templates/drizzle/ARCHITECTURE.pt-BR.md +225 -0
  26. package/templates/drizzle/CODE_OF_CONDUCT.md +29 -0
  27. package/templates/drizzle/CODE_OF_CONDUCT.pt-BR.md +27 -0
  28. package/templates/drizzle/CONTRIBUTING.md +57 -0
  29. package/templates/drizzle/CONTRIBUTING.pt-BR.md +54 -0
  30. package/templates/drizzle/Dockerfile +43 -0
  31. package/templates/drizzle/LICENSE +21 -0
  32. package/templates/drizzle/README.md +257 -0
  33. package/templates/drizzle/README.pt-BR.md +257 -0
  34. package/templates/drizzle/ROADMAP.md +143 -0
  35. package/templates/drizzle/ROADMAP.pt-BR.md +143 -0
  36. package/templates/drizzle/TESTING.md +136 -0
  37. package/templates/drizzle/TESTING.pt-BR.md +136 -0
  38. package/templates/drizzle/docker-compose.yml +82 -0
  39. package/templates/drizzle/docs/adding-a-module.md +585 -0
  40. package/templates/drizzle/docs/features-markers.md +457 -0
  41. package/templates/drizzle/drizzle.config.ts +49 -0
  42. package/templates/drizzle/nest-cli.json +8 -0
  43. package/templates/drizzle/package.json +96 -0
  44. package/templates/drizzle/src/app.module.ts +72 -0
  45. package/templates/drizzle/src/auth/auth.controller.ts +283 -0
  46. package/templates/drizzle/src/auth/auth.module.ts +81 -0
  47. package/templates/drizzle/src/auth/auth.service.spec.ts +111 -0
  48. package/templates/drizzle/src/auth/auth.service.ts +631 -0
  49. package/templates/drizzle/src/auth/drizzle-session.store.ts +263 -0
  50. package/templates/drizzle/src/auth/dto/forgot-password.dto.ts +9 -0
  51. package/templates/drizzle/src/auth/dto/login.dto.ts +10 -0
  52. package/templates/drizzle/src/auth/dto/refresh-token.dto.ts +9 -0
  53. package/templates/drizzle/src/auth/dto/register.dto.ts +11 -0
  54. package/templates/drizzle/src/auth/dto/reset-password.dto.ts +10 -0
  55. package/templates/drizzle/src/auth/guards/github-auth.guard.ts +10 -0
  56. package/templates/drizzle/src/auth/guards/google-auth.guard.ts +10 -0
  57. package/templates/drizzle/src/auth/guards/jwt-auth.guard.ts +25 -0
  58. package/templates/drizzle/src/auth/guards/session-auth.guard.spec.ts +77 -0
  59. package/templates/drizzle/src/auth/guards/session-auth.guard.ts +37 -0
  60. package/templates/drizzle/src/auth/session.service.spec.ts +74 -0
  61. package/templates/drizzle/src/auth/session.service.ts +96 -0
  62. package/templates/drizzle/src/auth/strategies/github.strategy.ts +41 -0
  63. package/templates/drizzle/src/auth/strategies/google.strategy.ts +43 -0
  64. package/templates/drizzle/src/auth/strategies/jwt.strategy.ts +25 -0
  65. package/templates/drizzle/src/auth/token.service.ts +175 -0
  66. package/templates/drizzle/src/common/constants/permissions.ts +8 -0
  67. package/templates/drizzle/src/common/constants/role-permissions.ts +9 -0
  68. package/templates/drizzle/src/common/constants/role.enum.ts +5 -0
  69. package/templates/drizzle/src/common/decorators/current-user.decorator.ts +8 -0
  70. package/templates/drizzle/src/common/decorators/permissions.decorator.ts +7 -0
  71. package/templates/drizzle/src/common/decorators/public.decorator.ts +4 -0
  72. package/templates/drizzle/src/common/decorators/roles.decorator.ts +6 -0
  73. package/templates/drizzle/src/common/filters/http-exception.filter.ts +34 -0
  74. package/templates/drizzle/src/common/guards/permissions.guard.spec.ts +54 -0
  75. package/templates/drizzle/src/common/guards/permissions.guard.ts +28 -0
  76. package/templates/drizzle/src/common/guards/roles.guard.spec.ts +37 -0
  77. package/templates/drizzle/src/common/guards/roles.guard.ts +24 -0
  78. package/templates/drizzle/src/common/interceptors/logging.interceptor.ts +23 -0
  79. package/templates/drizzle/src/common/middleware/csrf.middleware.spec.ts +97 -0
  80. package/templates/drizzle/src/common/middleware/csrf.middleware.ts +46 -0
  81. package/templates/drizzle/src/common/utils/avatar-storage.util.ts +32 -0
  82. package/templates/drizzle/src/common/utils/hash.util.ts +5 -0
  83. package/templates/drizzle/src/config/env.validation.ts +50 -0
  84. package/templates/drizzle/src/database/database-lifecycle.service.ts +30 -0
  85. package/templates/drizzle/src/database/database.constants.ts +2 -0
  86. package/templates/drizzle/src/database/database.decorators.ts +5 -0
  87. package/templates/drizzle/src/database/database.module.ts +96 -0
  88. package/templates/drizzle/src/database/database.types.ts +28 -0
  89. package/templates/drizzle/src/database/schema/index.ts +11 -0
  90. package/templates/drizzle/src/database/schema/mysql.schema.ts +215 -0
  91. package/templates/drizzle/src/database/schema/postgres.schema.ts +218 -0
  92. package/templates/drizzle/src/database/schema/sqlite.schema.ts +190 -0
  93. package/templates/drizzle/src/database/seed.ts +152 -0
  94. package/templates/drizzle/src/health/health.controller.ts +49 -0
  95. package/templates/drizzle/src/health/health.module.ts +19 -0
  96. package/templates/drizzle/src/health/indicators/drizzle-health.indicator.spec.ts +71 -0
  97. package/templates/drizzle/src/health/indicators/drizzle-health.indicator.ts +52 -0
  98. package/templates/drizzle/src/health/indicators/redis-health.indicator.spec.ts +54 -0
  99. package/templates/drizzle/src/health/indicators/redis-health.indicator.ts +33 -0
  100. package/templates/drizzle/src/mail/mail.module.ts +12 -0
  101. package/templates/drizzle/src/mail/mail.processor.ts +48 -0
  102. package/templates/drizzle/src/mail/mail.service.ts +24 -0
  103. package/templates/drizzle/src/mail/templates/email-templates.ts +28 -0
  104. package/templates/drizzle/src/main.ts +145 -0
  105. package/templates/drizzle/src/metrics/metrics.controller.ts +22 -0
  106. package/templates/drizzle/src/metrics/metrics.interceptor.ts +30 -0
  107. package/templates/drizzle/src/metrics/metrics.module.ts +12 -0
  108. package/templates/drizzle/src/metrics/metrics.service.ts +34 -0
  109. package/templates/drizzle/src/types/express-session.d.ts +13 -0
  110. package/templates/drizzle/src/users/dto/create-user.dto.ts +12 -0
  111. package/templates/drizzle/src/users/dto/find-users-query.dto.ts +12 -0
  112. package/templates/drizzle/src/users/dto/update-user.dto.ts +6 -0
  113. package/templates/drizzle/src/users/entities/user.entity.ts +23 -0
  114. package/templates/drizzle/src/users/users.controller.ts +165 -0
  115. package/templates/drizzle/src/users/users.module.ts +10 -0
  116. package/templates/drizzle/src/users/users.service.spec.ts +301 -0
  117. package/templates/drizzle/src/users/users.service.ts +213 -0
  118. package/templates/drizzle/test/auth.e2e-spec.ts +114 -0
  119. package/templates/drizzle/test/session-auth.e2e-spec.ts +163 -0
  120. package/templates/drizzle/test/users.e2e-spec.ts +212 -0
  121. package/templates/drizzle/test/utils/clean-database.ts +104 -0
  122. package/templates/drizzle/test/utils/e2e-setup.ts +77 -0
  123. package/templates/drizzle/tsconfig.build.json +4 -0
  124. package/templates/drizzle/tsconfig.json +25 -0
  125. package/templates/drizzle/vitest.config.ts +20 -0
  126. package/templates/drizzle/vitest.e2e.config.ts +19 -0
  127. package/templates/prisma/.env.example +44 -0
  128. package/templates/prisma/.env.test +37 -0
  129. package/templates/prisma/.github/workflows/ci.yml +109 -0
  130. package/templates/prisma/ARCHITECTURE.md +70 -0
  131. package/templates/prisma/ARCHITECTURE.pt-BR.md +63 -0
  132. package/templates/prisma/CODE_OF_CONDUCT.md +29 -0
  133. package/templates/prisma/CODE_OF_CONDUCT.pt-BR.md +27 -0
  134. package/templates/prisma/CONTRIBUTING.md +57 -0
  135. package/templates/prisma/CONTRIBUTING.pt-BR.md +54 -0
  136. package/templates/prisma/Dockerfile +33 -0
  137. package/templates/prisma/LICENSE +21 -0
  138. package/templates/prisma/README.md +267 -0
  139. package/templates/prisma/README.pt-BR.md +267 -0
  140. package/templates/prisma/ROADMAP.md +75 -0
  141. package/templates/prisma/ROADMAP.pt-BR.md +65 -0
  142. package/templates/prisma/TESTING.md +123 -0
  143. package/templates/prisma/TESTING.pt-BR.md +123 -0
  144. package/templates/prisma/docker-compose.yml +78 -0
  145. package/templates/prisma/docs/adding-a-module.md +230 -0
  146. package/templates/prisma/docs/features-markers.md +50 -0
  147. package/templates/prisma/nest-cli.json +8 -0
  148. package/templates/prisma/package.json +95 -0
  149. package/templates/prisma/prisma/schema.prisma +105 -0
  150. package/templates/prisma/prisma/seed.ts +46 -0
  151. package/templates/prisma/src/app.module.ts +72 -0
  152. package/templates/prisma/src/auth/auth.controller.ts +283 -0
  153. package/templates/prisma/src/auth/auth.module.ts +59 -0
  154. package/templates/prisma/src/auth/auth.service.spec.ts +53 -0
  155. package/templates/prisma/src/auth/auth.service.ts +224 -0
  156. package/templates/prisma/src/auth/dto/forgot-password.dto.ts +9 -0
  157. package/templates/prisma/src/auth/dto/login.dto.ts +10 -0
  158. package/templates/prisma/src/auth/dto/refresh-token.dto.ts +9 -0
  159. package/templates/prisma/src/auth/dto/register.dto.ts +11 -0
  160. package/templates/prisma/src/auth/dto/reset-password.dto.ts +10 -0
  161. package/templates/prisma/src/auth/guards/github-auth.guard.ts +10 -0
  162. package/templates/prisma/src/auth/guards/google-auth.guard.ts +10 -0
  163. package/templates/prisma/src/auth/guards/jwt-auth.guard.ts +25 -0
  164. package/templates/prisma/src/auth/guards/session-auth.guard.spec.ts +77 -0
  165. package/templates/prisma/src/auth/guards/session-auth.guard.ts +37 -0
  166. package/templates/prisma/src/auth/session.service.spec.ts +74 -0
  167. package/templates/prisma/src/auth/session.service.ts +96 -0
  168. package/templates/prisma/src/auth/strategies/github.strategy.ts +41 -0
  169. package/templates/prisma/src/auth/strategies/google.strategy.ts +43 -0
  170. package/templates/prisma/src/auth/strategies/jwt.strategy.ts +25 -0
  171. package/templates/prisma/src/auth/token.service.ts +84 -0
  172. package/templates/prisma/src/common/constants/permissions.ts +8 -0
  173. package/templates/prisma/src/common/constants/role-permissions.ts +9 -0
  174. package/templates/prisma/src/common/decorators/current-user.decorator.ts +8 -0
  175. package/templates/prisma/src/common/decorators/permissions.decorator.ts +7 -0
  176. package/templates/prisma/src/common/decorators/public.decorator.ts +4 -0
  177. package/templates/prisma/src/common/decorators/roles.decorator.ts +6 -0
  178. package/templates/prisma/src/common/filters/http-exception.filter.ts +34 -0
  179. package/templates/prisma/src/common/guards/permissions.guard.spec.ts +54 -0
  180. package/templates/prisma/src/common/guards/permissions.guard.ts +28 -0
  181. package/templates/prisma/src/common/guards/roles.guard.spec.ts +37 -0
  182. package/templates/prisma/src/common/guards/roles.guard.ts +24 -0
  183. package/templates/prisma/src/common/interceptors/logging.interceptor.ts +23 -0
  184. package/templates/prisma/src/common/middleware/csrf.middleware.spec.ts +97 -0
  185. package/templates/prisma/src/common/middleware/csrf.middleware.ts +46 -0
  186. package/templates/prisma/src/common/utils/avatar-storage.util.ts +32 -0
  187. package/templates/prisma/src/common/utils/hash.util.ts +5 -0
  188. package/templates/prisma/src/config/env.validation.ts +49 -0
  189. package/templates/prisma/src/database/prisma.module.ts +9 -0
  190. package/templates/prisma/src/database/prisma.service.ts +13 -0
  191. package/templates/prisma/src/health/health.controller.ts +49 -0
  192. package/templates/prisma/src/health/health.module.ts +19 -0
  193. package/templates/prisma/src/health/indicators/prisma-health.indicator.spec.ts +22 -0
  194. package/templates/prisma/src/health/indicators/prisma-health.indicator.ts +19 -0
  195. package/templates/prisma/src/health/indicators/redis-health.indicator.spec.ts +54 -0
  196. package/templates/prisma/src/health/indicators/redis-health.indicator.ts +33 -0
  197. package/templates/prisma/src/mail/mail.module.ts +12 -0
  198. package/templates/prisma/src/mail/mail.processor.ts +48 -0
  199. package/templates/prisma/src/mail/mail.service.ts +24 -0
  200. package/templates/prisma/src/mail/templates/email-templates.ts +28 -0
  201. package/templates/prisma/src/main.ts +92 -0
  202. package/templates/prisma/src/metrics/metrics.controller.ts +22 -0
  203. package/templates/prisma/src/metrics/metrics.interceptor.ts +30 -0
  204. package/templates/prisma/src/metrics/metrics.module.ts +12 -0
  205. package/templates/prisma/src/metrics/metrics.service.ts +34 -0
  206. package/templates/prisma/src/types/express-session.d.ts +13 -0
  207. package/templates/prisma/src/users/dto/create-user.dto.ts +12 -0
  208. package/templates/prisma/src/users/dto/find-users-query.dto.ts +12 -0
  209. package/templates/prisma/src/users/dto/update-user.dto.ts +6 -0
  210. package/templates/prisma/src/users/entities/user.entity.ts +20 -0
  211. package/templates/prisma/src/users/users.controller.ts +165 -0
  212. package/templates/prisma/src/users/users.module.ts +10 -0
  213. package/templates/prisma/src/users/users.service.spec.ts +104 -0
  214. package/templates/prisma/src/users/users.service.ts +114 -0
  215. package/templates/prisma/test/auth.e2e-spec.ts +75 -0
  216. package/templates/prisma/test/session-auth.e2e-spec.ts +163 -0
  217. package/templates/prisma/test/users.e2e-spec.ts +106 -0
  218. package/templates/prisma/test/utils/clean-database.ts +14 -0
  219. package/templates/prisma/test/utils/e2e-setup.ts +58 -0
  220. package/templates/prisma/tsconfig.build.json +4 -0
  221. package/templates/prisma/tsconfig.json +25 -0
  222. package/templates/prisma/vitest.config.ts +20 -0
  223. package/templates/prisma/vitest.e2e.config.ts +19 -0
  224. package/templates/typeorm/.env.example +45 -0
  225. package/templates/typeorm/.env.test +38 -0
  226. package/templates/typeorm/.github/workflows/ci.yml +116 -0
  227. package/templates/typeorm/ARCHITECTURE.md +158 -0
  228. package/templates/typeorm/ARCHITECTURE.pt-BR.md +156 -0
  229. package/templates/typeorm/CODE_OF_CONDUCT.md +29 -0
  230. package/templates/typeorm/CODE_OF_CONDUCT.pt-BR.md +27 -0
  231. package/templates/typeorm/CONTRIBUTING.md +57 -0
  232. package/templates/typeorm/CONTRIBUTING.pt-BR.md +54 -0
  233. package/templates/typeorm/Dockerfile +43 -0
  234. package/templates/typeorm/LICENSE +21 -0
  235. package/templates/typeorm/README.md +266 -0
  236. package/templates/typeorm/README.pt-BR.md +266 -0
  237. package/templates/typeorm/ROADMAP.md +79 -0
  238. package/templates/typeorm/ROADMAP.pt-BR.md +67 -0
  239. package/templates/typeorm/TESTING.md +114 -0
  240. package/templates/typeorm/TESTING.pt-BR.md +114 -0
  241. package/templates/typeorm/docker-compose.yml +78 -0
  242. package/templates/typeorm/docs/adding-a-module.md +369 -0
  243. package/templates/typeorm/docs/features-markers.md +50 -0
  244. package/templates/typeorm/nest-cli.json +8 -0
  245. package/templates/typeorm/package.json +98 -0
  246. package/templates/typeorm/src/app.module.ts +72 -0
  247. package/templates/typeorm/src/auth/auth.controller.ts +283 -0
  248. package/templates/typeorm/src/auth/auth.module.ts +86 -0
  249. package/templates/typeorm/src/auth/auth.service.spec.ts +111 -0
  250. package/templates/typeorm/src/auth/auth.service.ts +346 -0
  251. package/templates/typeorm/src/auth/dto/forgot-password.dto.ts +9 -0
  252. package/templates/typeorm/src/auth/dto/login.dto.ts +10 -0
  253. package/templates/typeorm/src/auth/dto/refresh-token.dto.ts +9 -0
  254. package/templates/typeorm/src/auth/dto/register.dto.ts +11 -0
  255. package/templates/typeorm/src/auth/dto/reset-password.dto.ts +10 -0
  256. package/templates/typeorm/src/auth/entities/email-verification-token.entity.ts +69 -0
  257. package/templates/typeorm/src/auth/entities/oauth-account.entity.ts +50 -0
  258. package/templates/typeorm/src/auth/entities/password-reset-token.entity.ts +69 -0
  259. package/templates/typeorm/src/auth/entities/refresh-token.entity.ts +69 -0
  260. package/templates/typeorm/src/auth/entities/session.entity.ts +50 -0
  261. package/templates/typeorm/src/auth/guards/github-auth.guard.ts +10 -0
  262. package/templates/typeorm/src/auth/guards/google-auth.guard.ts +10 -0
  263. package/templates/typeorm/src/auth/guards/jwt-auth.guard.ts +25 -0
  264. package/templates/typeorm/src/auth/guards/session-auth.guard.spec.ts +77 -0
  265. package/templates/typeorm/src/auth/guards/session-auth.guard.ts +37 -0
  266. package/templates/typeorm/src/auth/session.service.spec.ts +74 -0
  267. package/templates/typeorm/src/auth/session.service.ts +96 -0
  268. package/templates/typeorm/src/auth/strategies/github.strategy.ts +41 -0
  269. package/templates/typeorm/src/auth/strategies/google.strategy.ts +43 -0
  270. package/templates/typeorm/src/auth/strategies/jwt.strategy.ts +25 -0
  271. package/templates/typeorm/src/auth/token.service.ts +115 -0
  272. package/templates/typeorm/src/common/constants/permissions.ts +8 -0
  273. package/templates/typeorm/src/common/constants/role-permissions.ts +9 -0
  274. package/templates/typeorm/src/common/constants/role.enum.ts +5 -0
  275. package/templates/typeorm/src/common/decorators/current-user.decorator.ts +8 -0
  276. package/templates/typeorm/src/common/decorators/permissions.decorator.ts +7 -0
  277. package/templates/typeorm/src/common/decorators/public.decorator.ts +4 -0
  278. package/templates/typeorm/src/common/decorators/roles.decorator.ts +6 -0
  279. package/templates/typeorm/src/common/filters/http-exception.filter.ts +34 -0
  280. package/templates/typeorm/src/common/guards/permissions.guard.spec.ts +54 -0
  281. package/templates/typeorm/src/common/guards/permissions.guard.ts +28 -0
  282. package/templates/typeorm/src/common/guards/roles.guard.spec.ts +37 -0
  283. package/templates/typeorm/src/common/guards/roles.guard.ts +24 -0
  284. package/templates/typeorm/src/common/interceptors/logging.interceptor.ts +23 -0
  285. package/templates/typeorm/src/common/middleware/csrf.middleware.spec.ts +97 -0
  286. package/templates/typeorm/src/common/middleware/csrf.middleware.ts +46 -0
  287. package/templates/typeorm/src/common/utils/avatar-storage.util.ts +32 -0
  288. package/templates/typeorm/src/common/utils/hash.util.ts +5 -0
  289. package/templates/typeorm/src/config/env.validation.ts +50 -0
  290. package/templates/typeorm/src/database/data-source.ts +20 -0
  291. package/templates/typeorm/src/database/database.module.ts +39 -0
  292. package/templates/typeorm/src/database/seed.ts +81 -0
  293. package/templates/typeorm/src/database/typeorm-options.ts +49 -0
  294. package/templates/typeorm/src/health/health.controller.ts +49 -0
  295. package/templates/typeorm/src/health/health.module.ts +19 -0
  296. package/templates/typeorm/src/health/indicators/redis-health.indicator.spec.ts +54 -0
  297. package/templates/typeorm/src/health/indicators/redis-health.indicator.ts +33 -0
  298. package/templates/typeorm/src/health/indicators/typeorm-health.indicator.spec.ts +49 -0
  299. package/templates/typeorm/src/health/indicators/typeorm-health.indicator.ts +37 -0
  300. package/templates/typeorm/src/mail/mail.module.ts +12 -0
  301. package/templates/typeorm/src/mail/mail.processor.ts +48 -0
  302. package/templates/typeorm/src/mail/mail.service.ts +24 -0
  303. package/templates/typeorm/src/mail/templates/email-templates.ts +28 -0
  304. package/templates/typeorm/src/main.ts +107 -0
  305. package/templates/typeorm/src/metrics/metrics.controller.ts +22 -0
  306. package/templates/typeorm/src/metrics/metrics.interceptor.ts +30 -0
  307. package/templates/typeorm/src/metrics/metrics.module.ts +12 -0
  308. package/templates/typeorm/src/metrics/metrics.service.ts +34 -0
  309. package/templates/typeorm/src/types/express-session.d.ts +13 -0
  310. package/templates/typeorm/src/users/dto/create-user.dto.ts +12 -0
  311. package/templates/typeorm/src/users/dto/find-users-query.dto.ts +12 -0
  312. package/templates/typeorm/src/users/dto/update-user.dto.ts +6 -0
  313. package/templates/typeorm/src/users/entities/user.entity.ts +113 -0
  314. package/templates/typeorm/src/users/users.controller.ts +165 -0
  315. package/templates/typeorm/src/users/users.module.ts +13 -0
  316. package/templates/typeorm/src/users/users.service.spec.ts +183 -0
  317. package/templates/typeorm/src/users/users.service.ts +124 -0
  318. package/templates/typeorm/test/auth.e2e-spec.ts +111 -0
  319. package/templates/typeorm/test/session-auth.e2e-spec.ts +159 -0
  320. package/templates/typeorm/test/users.e2e-spec.ts +183 -0
  321. package/templates/typeorm/test/utils/clean-database.ts +65 -0
  322. package/templates/typeorm/test/utils/e2e-setup.ts +77 -0
  323. package/templates/typeorm/tsconfig.build.json +4 -0
  324. package/templates/typeorm/tsconfig.json +25 -0
  325. package/templates/typeorm/vitest.config.ts +20 -0
  326. package/templates/typeorm/vitest.e2e.config.ts +19 -0
@@ -0,0 +1,283 @@
1
+ import { Body, Controller, Get, HttpCode, HttpStatus, Post, Query, Req, UseGuards } from '@nestjs/common';
2
+ // nestforge:feature:swagger
3
+ import { ApiExcludeEndpoint, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
4
+ // nestforge:feature:swagger:end
5
+ import { Request } from 'express';
6
+ import { AuthService } from './auth.service';
7
+ // nestforge:feature:auth:password
8
+ import { RegisterDto } from './dto/register.dto';
9
+ import { LoginDto } from './dto/login.dto';
10
+ // nestforge:feature:auth:password:end
11
+ // nestforge:feature:auth:token
12
+ import { RefreshTokenDto } from './dto/refresh-token.dto';
13
+ // nestforge:feature:auth:token:end
14
+ // nestforge:feature:redis,auth:password
15
+ import { ForgotPasswordDto } from './dto/forgot-password.dto';
16
+ import { ResetPasswordDto } from './dto/reset-password.dto';
17
+ // nestforge:feature:redis,auth:password:end
18
+ import { Public } from '../common/decorators/public.decorator';
19
+ import { GoogleAuthGuard } from './guards/google-auth.guard';
20
+ import { GithubAuthGuard } from './guards/github-auth.guard';
21
+ import { OAuthProfile } from './strategies/google.strategy';
22
+ // nestforge:feature:auth:token
23
+ import { TokenService } from './token.service';
24
+ // nestforge:feature:auth:token:end
25
+ // nestforge:feature:auth:session
26
+ import { SessionService } from './session.service';
27
+ // nestforge:feature:auth:session:end
28
+
29
+ // nestforge:feature:swagger,auth:token
30
+ const TOKENS_EXAMPLE = {
31
+ accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
32
+ refreshToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
33
+ };
34
+ // nestforge:feature:swagger,auth:token:end
35
+
36
+ // nestforge:feature:swagger
37
+ @ApiTags('auth')
38
+ // nestforge:feature:swagger:end
39
+ @Controller('auth')
40
+ export class AuthController {
41
+ constructor(
42
+ private readonly authService: AuthService,
43
+ // nestforge:feature:auth:token
44
+ private readonly tokenService: TokenService,
45
+ // nestforge:feature:auth:token:end
46
+ // nestforge:feature:auth:session
47
+ private readonly sessionService: SessionService,
48
+ // nestforge:feature:auth:session:end
49
+ ) { }
50
+
51
+ // nestforge:feature:auth:session
52
+ @Public()
53
+ @Get('csrf-token')
54
+ // nestforge:feature:swagger
55
+ @ApiOperation({ summary: 'Emite um token CSRF vinculado à sessão' })
56
+ @ApiResponse({
57
+ status: 200,
58
+ description: 'Token CSRF emitido',
59
+ schema: {
60
+ example: {
61
+ csrfToken: 'a1b2c3d4e5f6...',
62
+ },
63
+ },
64
+ })
65
+ // nestforge:feature:swagger:end
66
+ getCsrfToken(@Req() request: Request) {
67
+ return this.sessionService.issueCsrfToken(request);
68
+ }
69
+ // nestforge:feature:auth:session:end
70
+
71
+ // nestforge:feature:auth:token,auth:password
72
+ @Public()
73
+ @Post('register')
74
+ // nestforge:feature:swagger
75
+ @ApiOperation({ summary: 'Cria uma nova conta' })
76
+ @ApiResponse({ status: 201, description: 'Conta criada com sucesso', schema: { example: TOKENS_EXAMPLE } })
77
+ @ApiResponse({ status: 409, description: 'E-mail já cadastrado', schema: { example: { statusCode: 409, message: 'E-mail já cadastrado' } } })
78
+ // nestforge:feature:swagger:end
79
+ async register(@Body() dto: RegisterDto) {
80
+ const user = await this.authService.register(dto);
81
+ return this.tokenService.issueTokens(user.id, user.email, user.role);
82
+ }
83
+
84
+ @Public()
85
+ @Post('login')
86
+ @HttpCode(HttpStatus.OK)
87
+ // nestforge:feature:swagger
88
+ @ApiOperation({ summary: 'Autentica e retorna access/refresh token' })
89
+ @ApiResponse({ status: 200, description: 'Login realizado com sucesso', schema: { example: TOKENS_EXAMPLE } })
90
+ @ApiResponse({ status: 401, description: 'Credenciais inválidas', schema: { example: { statusCode: 401, message: 'Credenciais inválidas' } } })
91
+ // nestforge:feature:swagger:end
92
+ async login(@Body() dto: LoginDto) {
93
+ const user = await this.authService.login(dto);
94
+ return this.tokenService.issueTokens(user.id, user.email, user.role);
95
+ }
96
+ // nestforge:feature:auth:token,auth:password:end
97
+
98
+ // nestforge:feature:auth:session
99
+ @Public()
100
+ @Post('register')
101
+ // nestforge:feature:swagger
102
+ @ApiOperation({ summary: 'Cria uma conta e inicia uma sessão' })
103
+ @ApiResponse({ status: 201, description: 'Conta criada e sessão iniciada' })
104
+ @ApiResponse({ status: 409, description: 'E-mail já cadastrado' })
105
+ // nestforge:feature:swagger:end
106
+ async registerWithSession(
107
+ @Body() dto: RegisterDto,
108
+ @Req() request: Request,
109
+ ) {
110
+ const user = await this.authService.register(dto);
111
+ return this.sessionService.establish(request, user);
112
+ }
113
+
114
+ @Public()
115
+ @Post('login')
116
+ @HttpCode(HttpStatus.OK)
117
+ // nestforge:feature:swagger
118
+ @ApiOperation({ summary: 'Autentica e inicia uma sessão por cookie' })
119
+ @ApiResponse({ status: 200, description: 'Sessão iniciada com sucesso' })
120
+ @ApiResponse({ status: 401, description: 'Credenciais inválidas' })
121
+ // nestforge:feature:swagger:end
122
+ async loginWithSession(
123
+ @Body() dto: LoginDto,
124
+ @Req() request: Request,
125
+ ) {
126
+ const user = await this.authService.login(dto);
127
+ return this.sessionService.establish(request, user);
128
+ }
129
+
130
+ @Post('logout')
131
+ @HttpCode(HttpStatus.OK)
132
+ // nestforge:feature:swagger
133
+ @ApiOperation({ summary: 'Encerra a sessão atual' })
134
+ @ApiResponse({ status: 200, description: 'Sessão encerrada com sucesso' })
135
+ // nestforge:feature:swagger:end
136
+ logoutSession(@Req() request: Request) {
137
+ return this.sessionService.destroy(request);
138
+ }
139
+ // nestforge:feature:auth:session:end
140
+
141
+ // nestforge:feature:auth:token
142
+ @Public()
143
+ @Post('refresh')
144
+ @HttpCode(HttpStatus.OK)
145
+ // nestforge:feature:swagger
146
+ @ApiOperation({ summary: 'Renova o access token usando o refresh token' })
147
+ @ApiResponse({ status: 200, description: 'Novo par de tokens emitido', schema: { example: TOKENS_EXAMPLE } })
148
+ @ApiResponse({ status: 401, description: 'Refresh token inválido, expirado ou já usado', schema: { example: { statusCode: 401, message: 'Refresh token inválido ou expirado' } } })
149
+ // nestforge:feature:swagger:end
150
+ refresh(@Body() dto: RefreshTokenDto) {
151
+ return this.tokenService.refresh(dto.refreshToken);
152
+ }
153
+
154
+ @Public()
155
+ @Post('logout')
156
+ @HttpCode(HttpStatus.OK)
157
+ // nestforge:feature:swagger
158
+ @ApiOperation({ summary: 'Revoga o refresh token informado' })
159
+ @ApiResponse({ status: 200, description: 'Logout realizado', schema: { example: { message: 'Logout realizado com sucesso' } } })
160
+ // nestforge:feature:swagger:end
161
+ logout(@Body() dto: RefreshTokenDto) {
162
+ return this.tokenService.logout(dto.refreshToken);
163
+ }
164
+ // nestforge:feature:auth:token:end
165
+
166
+ // nestforge:feature:redis,auth:password
167
+ @Public()
168
+ @Post('forgot-password')
169
+ @HttpCode(HttpStatus.OK)
170
+ // nestforge:feature:swagger
171
+ @ApiOperation({ summary: 'Envia um e-mail com instruções para redefinir a senha' })
172
+ @ApiResponse({
173
+ status: 200,
174
+ description: 'Resposta genérica — sempre a mesma, exista ou não o e-mail (evita enumeração de contas)',
175
+ schema: { example: { message: 'Se o e-mail existir, enviaremos instruções de redefinição de senha' } },
176
+ })
177
+ // nestforge:feature:swagger:end
178
+ forgotPassword(@Body() dto: ForgotPasswordDto) {
179
+ return this.authService.forgotPassword(dto.email);
180
+ }
181
+
182
+ @Public()
183
+ @Post('reset-password')
184
+ @HttpCode(HttpStatus.OK)
185
+ // nestforge:feature:swagger
186
+ @ApiOperation({ summary: 'Redefine a senha usando o token recebido por e-mail' })
187
+ @ApiResponse({ status: 200, description: 'Senha redefinida', schema: { example: { message: 'Senha redefinida com sucesso' } } })
188
+ @ApiResponse({ status: 401, description: 'Token inválido, expirado ou já usado', schema: { example: { statusCode: 401, message: 'Token de redefinição inválido ou expirado' } } })
189
+ // nestforge:feature:swagger:end
190
+ resetPassword(@Body() dto: ResetPasswordDto) {
191
+ return this.authService.resetPassword(dto.token, dto.password);
192
+ }
193
+
194
+ @Public()
195
+ @Get('verify-email')
196
+ // nestforge:feature:swagger
197
+ @ApiOperation({ summary: 'Confirma o e-mail usando o token recebido' })
198
+ @ApiResponse({ status: 200, description: 'E-mail verificado', schema: { example: { message: 'E-mail verificado com sucesso' } } })
199
+ @ApiResponse({ status: 401, description: 'Token inválido, expirado ou já usado', schema: { example: { statusCode: 401, message: 'Token de verificação inválido ou expirado' } } })
200
+ // nestforge:feature:swagger:end
201
+ verifyEmail(@Query('token') token: string) {
202
+ return this.authService.verifyEmail(token);
203
+ }
204
+ // nestforge:feature:redis,auth:password:end
205
+
206
+ @Public()
207
+ @Get('google')
208
+ @UseGuards(GoogleAuthGuard)
209
+ // nestforge:feature:swagger
210
+ @ApiOperation({ summary: 'Inicia o login via Google (redireciona)' })
211
+ // nestforge:feature:swagger:end
212
+ googleLogin() {
213
+ // o guard redireciona para o consentimento do Google; nada a fazer aqui
214
+ }
215
+
216
+ // nestforge:feature:auth:token
217
+ @Public()
218
+ @Get('google/callback')
219
+ @UseGuards(GoogleAuthGuard)
220
+ // nestforge:feature:swagger
221
+ @ApiExcludeEndpoint()
222
+ // nestforge:feature:swagger:end
223
+ async googleCallback(@Req() req: Request) {
224
+ const user = await this.authService.validateOAuthLogin(req.user as OAuthProfile);
225
+ return this.tokenService.issueTokens(user.id, user.email, user.role);
226
+ }
227
+ // nestforge:feature:auth:token:end
228
+
229
+ // nestforge:feature:auth:session
230
+ @Public()
231
+ @Get('google/callback')
232
+ @UseGuards(GoogleAuthGuard)
233
+ // nestforge:feature:swagger
234
+ @ApiExcludeEndpoint()
235
+ // nestforge:feature:swagger:end
236
+ async googleSessionCallback(@Req() request: Request) {
237
+ const user = await this.authService.validateOAuthLogin(
238
+ request.user as OAuthProfile,
239
+ );
240
+
241
+ return this.sessionService.establish(request, user);
242
+ }
243
+ // nestforge:feature:auth:session:end
244
+
245
+ @Public()
246
+ @Get('github')
247
+ @UseGuards(GithubAuthGuard)
248
+ // nestforge:feature:swagger
249
+ @ApiOperation({ summary: 'Inicia o login via GitHub (redireciona)' })
250
+ // nestforge:feature:swagger:end
251
+ githubLogin() {
252
+ // o guard redireciona para o consentimento do GitHub; nada a fazer aqui
253
+ }
254
+
255
+ // nestforge:feature:auth:token
256
+ @Public()
257
+ @Get('github/callback')
258
+ @UseGuards(GithubAuthGuard)
259
+ // nestforge:feature:swagger
260
+ @ApiExcludeEndpoint()
261
+ // nestforge:feature:swagger:end
262
+ async githubCallback(@Req() req: Request) {
263
+ const user = await this.authService.validateOAuthLogin(req.user as OAuthProfile);
264
+ return this.tokenService.issueTokens(user.id, user.email, user.role);
265
+ }
266
+ // nestforge:feature:auth:token:end
267
+
268
+ // nestforge:feature:auth:session
269
+ @Public()
270
+ @Get('github/callback')
271
+ @UseGuards(GithubAuthGuard)
272
+ // nestforge:feature:swagger
273
+ @ApiExcludeEndpoint()
274
+ // nestforge:feature:swagger:end
275
+ async githubSessionCallback(@Req() request: Request) {
276
+ const user = await this.authService.validateOAuthLogin(
277
+ request.user as OAuthProfile,
278
+ );
279
+
280
+ return this.sessionService.establish(request, user);
281
+ }
282
+ // nestforge:feature:auth:session:end
283
+ }
@@ -0,0 +1,86 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { TypeOrmModule } from '@nestjs/typeorm';
3
+ import { PassportModule } from '@nestjs/passport';
4
+ import { APP_GUARD } from '@nestjs/core';
5
+
6
+ // nestforge:feature:auth:token
7
+ import { JwtModule } from '@nestjs/jwt';
8
+ import { TokenService } from './token.service';
9
+ import { JwtStrategy } from './strategies/jwt.strategy';
10
+ import { JwtAuthGuard } from './guards/jwt-auth.guard';
11
+ import { RefreshTokenEntity } from './entities/refresh-token.entity';
12
+ // nestforge:feature:auth:token:end
13
+
14
+ // nestforge:feature:redis
15
+ import { MailModule } from '../mail/mail.module';
16
+ // nestforge:feature:redis:end
17
+
18
+ // nestforge:feature:redis,auth:password
19
+ import { PasswordResetTokenEntity } from './entities/password-reset-token.entity';
20
+ import { EmailVerificationTokenEntity } from './entities/email-verification-token.entity';
21
+ // nestforge:feature:redis,auth:password:end
22
+
23
+ import { UserEntity } from '../users/entities/user.entity';
24
+ import { OAuthAccountEntity } from './entities/oauth-account.entity';
25
+ import { AuthService } from './auth.service';
26
+ import { AuthController } from './auth.controller';
27
+ import { GoogleStrategy } from './strategies/google.strategy';
28
+ import { GithubStrategy } from './strategies/github.strategy';
29
+
30
+ // nestforge:feature:rbac
31
+ import { RolesGuard } from '../common/guards/roles.guard';
32
+ import { PermissionsGuard } from '../common/guards/permissions.guard';
33
+ // nestforge:feature:rbac:end
34
+
35
+ // nestforge:feature:auth:session
36
+ import { SessionEntity } from './entities/session.entity';
37
+ import { SessionAuthGuard } from './guards/session-auth.guard';
38
+ import { SessionService } from './session.service';
39
+ // nestforge:feature:auth:session:end
40
+
41
+ @Module({
42
+ imports: [
43
+ TypeOrmModule.forFeature([
44
+ UserEntity,
45
+ OAuthAccountEntity,
46
+ // nestforge:feature:auth:token
47
+ RefreshTokenEntity,
48
+ // nestforge:feature:auth:token:end
49
+ // nestforge:feature:redis,auth:password
50
+ PasswordResetTokenEntity,
51
+ EmailVerificationTokenEntity,
52
+ // nestforge:feature:redis,auth:password:end
53
+ // nestforge:feature:auth:session
54
+ SessionEntity,
55
+ // nestforge:feature:auth:session:end
56
+ ]),
57
+ PassportModule,
58
+ // nestforge:feature:auth:token
59
+ JwtModule.register({}),
60
+ // nestforge:feature:auth:token:end
61
+ // nestforge:feature:redis
62
+ MailModule,
63
+ // nestforge:feature:redis:end
64
+ ],
65
+ controllers: [AuthController],
66
+ providers: [
67
+ AuthService,
68
+ // nestforge:feature:auth:token
69
+ TokenService,
70
+ JwtStrategy,
71
+ { provide: APP_GUARD, useClass: JwtAuthGuard },
72
+ // nestforge:feature:auth:token:end
73
+ // nestforge:feature:auth:session
74
+ SessionService,
75
+ { provide: APP_GUARD, useClass: SessionAuthGuard },
76
+ // nestforge:feature:auth:session:end
77
+ GoogleStrategy,
78
+ GithubStrategy,
79
+ // nestforge:feature:rbac
80
+ { provide: APP_GUARD, useClass: RolesGuard },
81
+ { provide: APP_GUARD, useClass: PermissionsGuard },
82
+ // nestforge:feature:rbac:end
83
+ ],
84
+ exports: [AuthService],
85
+ })
86
+ export class AuthModule { }
@@ -0,0 +1,111 @@
1
+ // nestforge:feature-file:auth:password
2
+ import {
3
+ beforeEach,
4
+ describe,
5
+ expect,
6
+ it,
7
+ vi,
8
+ } from 'vitest';
9
+ import {
10
+ ConflictException,
11
+ UnauthorizedException,
12
+ } from '@nestjs/common';
13
+ import { DataSource, Repository } from 'typeorm';
14
+ import { AuthService } from './auth.service';
15
+ import { UserEntity } from '../users/entities/user.entity';
16
+ import { OAuthAccountEntity } from './entities/oauth-account.entity';
17
+
18
+ // nestforge:feature:redis
19
+ import { MailService } from '../mail/mail.service';
20
+ import { PasswordResetTokenEntity } from './entities/password-reset-token.entity';
21
+ import { EmailVerificationTokenEntity } from './entities/email-verification-token.entity';
22
+ // nestforge:feature:redis:end
23
+
24
+ describe('AuthService', () => {
25
+ let authService: AuthService;
26
+ let usersRepository: any;
27
+ let oauthAccountsRepository: any;
28
+ let dataSource: DataSource;
29
+
30
+ // nestforge:feature:redis
31
+ let passwordResetTokensRepository: any;
32
+ let emailVerificationTokensRepository: any;
33
+ let mailService: MailService;
34
+ // nestforge:feature:redis:end
35
+
36
+ beforeEach(() => {
37
+ usersRepository = {
38
+ findOne: vi.fn(),
39
+ create: vi.fn(),
40
+ save: vi.fn(),
41
+ };
42
+
43
+ oauthAccountsRepository = {
44
+ findOne: vi.fn(),
45
+ create: vi.fn(),
46
+ save: vi.fn(),
47
+ };
48
+
49
+ dataSource = {
50
+ transaction: vi.fn(),
51
+ } as unknown as DataSource;
52
+
53
+ // nestforge:feature:redis
54
+ passwordResetTokensRepository = {
55
+ findOne: vi.fn(),
56
+ create: vi.fn(),
57
+ save: vi.fn(),
58
+ };
59
+
60
+ emailVerificationTokensRepository = {
61
+ findOne: vi.fn(),
62
+ create: vi.fn(),
63
+ save: vi.fn(),
64
+ };
65
+
66
+ mailService = {
67
+ queueVerificationEmail: vi.fn(),
68
+ queuePasswordResetEmail: vi.fn(),
69
+ } as unknown as MailService;
70
+ // nestforge:feature:redis:end
71
+
72
+ authService = new AuthService(
73
+ usersRepository as unknown as Repository<UserEntity>,
74
+ oauthAccountsRepository as unknown as Repository<OAuthAccountEntity>,
75
+ dataSource,
76
+ // nestforge:feature:redis
77
+ passwordResetTokensRepository as unknown as Repository<PasswordResetTokenEntity>,
78
+ emailVerificationTokensRepository as unknown as Repository<EmailVerificationTokenEntity>,
79
+ mailService,
80
+ // nestforge:feature:redis:end
81
+ );
82
+ });
83
+
84
+ it('deve lançar ConflictException se o e-mail já existir', async () => {
85
+ usersRepository.findOne.mockResolvedValue({
86
+ id: 'user-1',
87
+ email: 'jeiel@example.com',
88
+ });
89
+
90
+ await expect(
91
+ authService.register({
92
+ name: 'Jeiel',
93
+ email: 'jeiel@example.com',
94
+ password: 'senhaForte123',
95
+ }),
96
+ ).rejects.toBeInstanceOf(ConflictException);
97
+ });
98
+
99
+ it('deve lançar UnauthorizedException com credenciais inválidas', async () => {
100
+ usersRepository.findOne.mockResolvedValue(null);
101
+
102
+ await expect(
103
+ authService.login({
104
+ email: 'naoexiste@example.com',
105
+ password: 'qualquer123',
106
+ }),
107
+ ).rejects.toBeInstanceOf(
108
+ UnauthorizedException,
109
+ );
110
+ });
111
+ });