@m5kdev/backend 0.1.0 → 0.1.2

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 (294) hide show
  1. package/.cursor/rules/backend.mdc +70 -0
  2. package/.turbo/turbo-build.log +5 -0
  3. package/.turbo/turbo-check-types.log +5 -0
  4. package/.turbo/turbo-lint$colon$fix.log +255 -0
  5. package/CHANGELOG.md +19 -0
  6. package/dist/src/lib/posthog.d.ts +3 -0
  7. package/dist/src/lib/posthog.d.ts.map +1 -0
  8. package/dist/src/lib/posthog.js +7 -0
  9. package/dist/src/lib/sentry.d.ts +2 -0
  10. package/dist/src/lib/sentry.d.ts.map +1 -0
  11. package/dist/src/lib/sentry.js +9 -0
  12. package/dist/src/modules/access/access.repository.d.ts +2348 -0
  13. package/dist/src/modules/access/access.repository.d.ts.map +1 -0
  14. package/dist/src/modules/access/access.repository.js +32 -0
  15. package/dist/src/modules/access/access.service.d.ts +22 -0
  16. package/dist/src/modules/access/access.service.d.ts.map +1 -0
  17. package/dist/src/modules/access/access.service.js +51 -0
  18. package/dist/src/modules/access/access.test.d.ts +2 -0
  19. package/dist/src/modules/access/access.test.d.ts.map +1 -0
  20. package/dist/src/modules/access/access.test.js +182 -0
  21. package/dist/src/modules/access/access.utils.d.ts +17 -0
  22. package/dist/src/modules/access/access.utils.d.ts.map +1 -0
  23. package/dist/src/modules/access/access.utils.js +20 -0
  24. package/dist/src/modules/ai/ai.db.d.ts +396 -0
  25. package/dist/src/modules/ai/ai.db.d.ts.map +1 -0
  26. package/dist/src/modules/ai/ai.db.js +39 -0
  27. package/dist/src/modules/ai/ai.prompt.d.ts +28 -0
  28. package/dist/src/modules/ai/ai.prompt.d.ts.map +1 -0
  29. package/dist/src/modules/ai/ai.prompt.js +30 -0
  30. package/dist/src/modules/ai/ai.repository.d.ts +424 -0
  31. package/dist/src/modules/ai/ai.repository.d.ts.map +1 -0
  32. package/dist/src/modules/ai/ai.repository.js +26 -0
  33. package/dist/src/modules/ai/ai.router.d.ts +2 -0
  34. package/dist/src/modules/ai/ai.router.d.ts.map +1 -0
  35. package/dist/src/modules/ai/ai.router.js +132 -0
  36. package/dist/src/modules/ai/ai.service.d.ts +115 -0
  37. package/dist/src/modules/ai/ai.service.d.ts.map +1 -0
  38. package/dist/src/modules/ai/ai.service.js +207 -0
  39. package/dist/src/modules/ai/ai.trpc.d.ts +59 -0
  40. package/dist/src/modules/ai/ai.trpc.d.ts.map +1 -0
  41. package/dist/src/modules/ai/ai.trpc.js +20 -0
  42. package/dist/src/modules/ai/ideogram/ideogram.constants.d.ts +8 -0
  43. package/dist/src/modules/ai/ideogram/ideogram.constants.d.ts.map +1 -0
  44. package/dist/src/modules/ai/ideogram/ideogram.constants.js +167 -0
  45. package/dist/src/modules/ai/ideogram/ideogram.dto.d.ts +230 -0
  46. package/dist/src/modules/ai/ideogram/ideogram.dto.d.ts.map +1 -0
  47. package/dist/src/modules/ai/ideogram/ideogram.dto.js +49 -0
  48. package/dist/src/modules/ai/ideogram/ideogram.prompt.d.ts +3 -0
  49. package/dist/src/modules/ai/ideogram/ideogram.prompt.d.ts.map +1 -0
  50. package/dist/src/modules/ai/ideogram/ideogram.prompt.js +860 -0
  51. package/dist/src/modules/ai/ideogram/ideogram.repository.d.ts +7 -0
  52. package/dist/src/modules/ai/ideogram/ideogram.repository.d.ts.map +1 -0
  53. package/dist/src/modules/ai/ideogram/ideogram.repository.js +46 -0
  54. package/dist/src/modules/ai/ideogram/ideogram.service.d.ts +10 -0
  55. package/dist/src/modules/ai/ideogram/ideogram.service.d.ts.map +1 -0
  56. package/dist/src/modules/ai/ideogram/ideogram.service.js +11 -0
  57. package/dist/src/modules/auth/auth.db.d.ts +2336 -0
  58. package/dist/src/modules/auth/auth.db.d.ts.map +1 -0
  59. package/dist/src/modules/auth/auth.db.js +215 -0
  60. package/dist/src/modules/auth/auth.dto.d.ts +66 -0
  61. package/dist/src/modules/auth/auth.dto.d.ts.map +1 -0
  62. package/dist/src/modules/auth/auth.dto.js +38 -0
  63. package/dist/src/modules/auth/auth.lib.d.ts +4874 -0
  64. package/dist/src/modules/auth/auth.lib.d.ts.map +1 -0
  65. package/dist/src/modules/auth/auth.lib.js +284 -0
  66. package/dist/src/modules/auth/auth.middleware.d.ts +615 -0
  67. package/dist/src/modules/auth/auth.middleware.d.ts.map +1 -0
  68. package/dist/src/modules/auth/auth.middleware.js +52 -0
  69. package/dist/src/modules/auth/auth.repository.d.ts +2417 -0
  70. package/dist/src/modules/auth/auth.repository.d.ts.map +1 -0
  71. package/dist/src/modules/auth/auth.repository.js +541 -0
  72. package/dist/src/modules/auth/auth.service.d.ts +104 -0
  73. package/dist/src/modules/auth/auth.service.d.ts.map +1 -0
  74. package/dist/src/modules/auth/auth.service.js +201 -0
  75. package/dist/src/modules/auth/auth.trpc.d.ts +309 -0
  76. package/dist/src/modules/auth/auth.trpc.d.ts.map +1 -0
  77. package/dist/src/modules/auth/auth.trpc.js +157 -0
  78. package/dist/src/modules/auth/auth.utils.d.ts +2352 -0
  79. package/dist/src/modules/auth/auth.utils.d.ts.map +1 -0
  80. package/dist/src/modules/auth/auth.utils.js +97 -0
  81. package/dist/src/modules/base/base.abstract.d.ts +19 -0
  82. package/dist/src/modules/base/base.abstract.d.ts.map +1 -0
  83. package/dist/src/modules/base/base.abstract.js +53 -0
  84. package/dist/src/modules/base/base.dto.d.ts +70 -0
  85. package/dist/src/modules/base/base.dto.d.ts.map +1 -0
  86. package/dist/src/modules/base/base.dto.js +112 -0
  87. package/dist/src/modules/base/base.grants.d.ts +29 -0
  88. package/dist/src/modules/base/base.grants.d.ts.map +1 -0
  89. package/dist/src/modules/base/base.grants.js +123 -0
  90. package/dist/src/modules/base/base.grants.test.d.ts +2 -0
  91. package/dist/src/modules/base/base.grants.test.d.ts.map +1 -0
  92. package/dist/src/modules/base/base.grants.test.js +668 -0
  93. package/dist/src/modules/base/base.repository.d.ts +97 -0
  94. package/dist/src/modules/base/base.repository.d.ts.map +1 -0
  95. package/dist/src/modules/base/base.repository.js +307 -0
  96. package/dist/src/modules/base/base.service.d.ts +42 -0
  97. package/dist/src/modules/base/base.service.d.ts.map +1 -0
  98. package/dist/src/modules/base/base.service.js +109 -0
  99. package/dist/src/modules/base/base.types.d.ts +2 -0
  100. package/dist/src/modules/base/base.types.d.ts.map +1 -0
  101. package/dist/src/modules/base/base.types.js +2 -0
  102. package/dist/src/modules/billing/billing.db.d.ts +366 -0
  103. package/dist/src/modules/billing/billing.db.d.ts.map +1 -0
  104. package/dist/src/modules/billing/billing.db.js +29 -0
  105. package/dist/src/modules/billing/billing.repository.d.ts +2764 -0
  106. package/dist/src/modules/billing/billing.repository.d.ts.map +1 -0
  107. package/dist/src/modules/billing/billing.repository.js +235 -0
  108. package/dist/src/modules/billing/billing.router.d.ts +5 -0
  109. package/dist/src/modules/billing/billing.router.d.ts.map +1 -0
  110. package/dist/src/modules/billing/billing.router.js +56 -0
  111. package/dist/src/modules/billing/billing.service.d.ts +60 -0
  112. package/dist/src/modules/billing/billing.service.d.ts.map +1 -0
  113. package/dist/src/modules/billing/billing.service.js +147 -0
  114. package/dist/src/modules/billing/billing.trpc.d.ts +75 -0
  115. package/dist/src/modules/billing/billing.trpc.d.ts.map +1 -0
  116. package/dist/src/modules/billing/billing.trpc.js +17 -0
  117. package/dist/src/modules/clay/clay.repository.d.ts +6 -0
  118. package/dist/src/modules/clay/clay.repository.d.ts.map +1 -0
  119. package/dist/src/modules/clay/clay.repository.js +26 -0
  120. package/dist/src/modules/clay/clay.service.d.ts +29 -0
  121. package/dist/src/modules/clay/clay.service.d.ts.map +1 -0
  122. package/dist/src/modules/clay/clay.service.js +24 -0
  123. package/dist/src/modules/connect/connect.db.d.ts +357 -0
  124. package/dist/src/modules/connect/connect.db.d.ts.map +1 -0
  125. package/dist/src/modules/connect/connect.db.js +30 -0
  126. package/dist/src/modules/connect/connect.dto.d.ts +75 -0
  127. package/dist/src/modules/connect/connect.dto.d.ts.map +1 -0
  128. package/dist/src/modules/connect/connect.dto.js +36 -0
  129. package/dist/src/modules/connect/connect.linkedin.d.ts +3 -0
  130. package/dist/src/modules/connect/connect.linkedin.d.ts.map +1 -0
  131. package/dist/src/modules/connect/connect.linkedin.js +53 -0
  132. package/dist/src/modules/connect/connect.oauth.d.ts +28 -0
  133. package/dist/src/modules/connect/connect.oauth.d.ts.map +1 -0
  134. package/dist/src/modules/connect/connect.oauth.js +198 -0
  135. package/dist/src/modules/connect/connect.repository.d.ts +414 -0
  136. package/dist/src/modules/connect/connect.repository.d.ts.map +1 -0
  137. package/dist/src/modules/connect/connect.repository.js +54 -0
  138. package/dist/src/modules/connect/connect.router.d.ts +5 -0
  139. package/dist/src/modules/connect/connect.router.d.ts.map +1 -0
  140. package/dist/src/modules/connect/connect.router.js +54 -0
  141. package/dist/src/modules/connect/connect.service.d.ts +89 -0
  142. package/dist/src/modules/connect/connect.service.d.ts.map +1 -0
  143. package/dist/src/modules/connect/connect.service.js +114 -0
  144. package/dist/src/modules/connect/connect.trpc.d.ts +81 -0
  145. package/dist/src/modules/connect/connect.trpc.d.ts.map +1 -0
  146. package/dist/src/modules/connect/connect.trpc.js +21 -0
  147. package/dist/src/modules/connect/connect.types.d.ts +26 -0
  148. package/dist/src/modules/connect/connect.types.d.ts.map +1 -0
  149. package/dist/src/modules/connect/connect.types.js +2 -0
  150. package/dist/src/modules/crypto/crypto.db.d.ts +152 -0
  151. package/dist/src/modules/crypto/crypto.db.d.ts.map +1 -0
  152. package/dist/src/modules/crypto/crypto.db.js +17 -0
  153. package/dist/src/modules/crypto/crypto.repository.d.ts +160 -0
  154. package/dist/src/modules/crypto/crypto.repository.d.ts.map +1 -0
  155. package/dist/src/modules/crypto/crypto.repository.js +10 -0
  156. package/dist/src/modules/crypto/crypto.service.d.ts +11 -0
  157. package/dist/src/modules/crypto/crypto.service.d.ts.map +1 -0
  158. package/dist/src/modules/crypto/crypto.service.js +52 -0
  159. package/dist/src/modules/email/email.service.d.ts +57 -0
  160. package/dist/src/modules/email/email.service.d.ts.map +1 -0
  161. package/dist/src/modules/email/email.service.js +107 -0
  162. package/dist/src/modules/file/file.repository.d.ts +13 -0
  163. package/dist/src/modules/file/file.repository.d.ts.map +1 -0
  164. package/dist/src/modules/file/file.repository.js +79 -0
  165. package/dist/src/modules/file/file.router.d.ts +4 -0
  166. package/dist/src/modules/file/file.router.d.ts.map +1 -0
  167. package/dist/src/modules/file/file.router.js +99 -0
  168. package/dist/src/modules/file/file.service.d.ts +25 -0
  169. package/dist/src/modules/file/file.service.d.ts.map +1 -0
  170. package/dist/src/modules/file/file.service.js +150 -0
  171. package/dist/src/modules/recurrence/recurrence.db.d.ts +563 -0
  172. package/dist/src/modules/recurrence/recurrence.db.d.ts.map +1 -0
  173. package/dist/src/modules/recurrence/recurrence.db.js +66 -0
  174. package/dist/src/modules/recurrence/recurrence.repository.d.ts +585 -0
  175. package/dist/src/modules/recurrence/recurrence.repository.d.ts.map +1 -0
  176. package/dist/src/modules/recurrence/recurrence.repository.js +39 -0
  177. package/dist/src/modules/recurrence/recurrence.service.d.ts +30 -0
  178. package/dist/src/modules/recurrence/recurrence.service.d.ts.map +1 -0
  179. package/dist/src/modules/recurrence/recurrence.service.js +70 -0
  180. package/dist/src/modules/recurrence/recurrence.trpc.d.ts +243 -0
  181. package/dist/src/modules/recurrence/recurrence.trpc.d.ts.map +1 -0
  182. package/dist/src/modules/recurrence/recurrence.trpc.js +65 -0
  183. package/dist/src/modules/social/social.dto.d.ts +35 -0
  184. package/dist/src/modules/social/social.dto.d.ts.map +1 -0
  185. package/dist/src/modules/social/social.dto.js +18 -0
  186. package/dist/src/modules/social/social.linkedin.d.ts +11 -0
  187. package/dist/src/modules/social/social.linkedin.d.ts.map +1 -0
  188. package/dist/src/modules/social/social.linkedin.js +427 -0
  189. package/dist/src/modules/social/social.linkedin.test.d.ts +2 -0
  190. package/dist/src/modules/social/social.linkedin.test.d.ts.map +1 -0
  191. package/dist/src/modules/social/social.linkedin.test.js +235 -0
  192. package/dist/src/modules/social/social.service.d.ts +29 -0
  193. package/dist/src/modules/social/social.service.d.ts.map +1 -0
  194. package/dist/src/modules/social/social.service.js +76 -0
  195. package/dist/src/modules/social/social.types.d.ts +36 -0
  196. package/dist/src/modules/social/social.types.d.ts.map +1 -0
  197. package/dist/src/modules/social/social.types.js +2 -0
  198. package/dist/src/modules/tag/tag.db.d.ts +347 -0
  199. package/dist/src/modules/tag/tag.db.d.ts.map +1 -0
  200. package/dist/src/modules/tag/tag.db.js +42 -0
  201. package/dist/src/modules/tag/tag.dto.d.ts +1019 -0
  202. package/dist/src/modules/tag/tag.dto.d.ts.map +1 -0
  203. package/dist/src/modules/tag/tag.dto.js +9 -0
  204. package/dist/src/modules/tag/tag.repository.d.ts +384 -0
  205. package/dist/src/modules/tag/tag.repository.d.ts.map +1 -0
  206. package/dist/src/modules/tag/tag.repository.js +154 -0
  207. package/dist/src/modules/tag/tag.service.d.ts +36 -0
  208. package/dist/src/modules/tag/tag.service.d.ts.map +1 -0
  209. package/dist/src/modules/tag/tag.service.js +31 -0
  210. package/dist/src/modules/tag/tag.trpc.d.ts +191 -0
  211. package/dist/src/modules/tag/tag.trpc.d.ts.map +1 -0
  212. package/dist/src/modules/tag/tag.trpc.js +47 -0
  213. package/dist/src/modules/utils/applyPagination.d.ts +7 -0
  214. package/dist/src/modules/utils/applyPagination.d.ts.map +1 -0
  215. package/dist/src/modules/utils/applyPagination.js +16 -0
  216. package/dist/src/modules/utils/applySorting.d.ts +9 -0
  217. package/dist/src/modules/utils/applySorting.d.ts.map +1 -0
  218. package/dist/src/modules/utils/applySorting.js +18 -0
  219. package/dist/src/modules/utils/getConditionsFromFilters.d.ts +5 -0
  220. package/dist/src/modules/utils/getConditionsFromFilters.d.ts.map +1 -0
  221. package/dist/src/modules/utils/getConditionsFromFilters.js +200 -0
  222. package/dist/src/modules/video/video.service.d.ts +8 -0
  223. package/dist/src/modules/video/video.service.d.ts.map +1 -0
  224. package/dist/src/modules/video/video.service.js +84 -0
  225. package/dist/src/modules/webhook/webhook.constants.d.ts +9 -0
  226. package/dist/src/modules/webhook/webhook.constants.d.ts.map +1 -0
  227. package/dist/src/modules/webhook/webhook.constants.js +10 -0
  228. package/dist/src/modules/webhook/webhook.db.d.ts +137 -0
  229. package/dist/src/modules/webhook/webhook.db.d.ts.map +1 -0
  230. package/dist/src/modules/webhook/webhook.db.js +17 -0
  231. package/dist/src/modules/webhook/webhook.dto.d.ts +395 -0
  232. package/dist/src/modules/webhook/webhook.dto.d.ts.map +1 -0
  233. package/dist/src/modules/webhook/webhook.dto.js +7 -0
  234. package/dist/src/modules/webhook/webhook.repository.d.ts +149 -0
  235. package/dist/src/modules/webhook/webhook.repository.d.ts.map +1 -0
  236. package/dist/src/modules/webhook/webhook.repository.js +56 -0
  237. package/dist/src/modules/webhook/webhook.router.d.ts +4 -0
  238. package/dist/src/modules/webhook/webhook.router.d.ts.map +1 -0
  239. package/dist/src/modules/webhook/webhook.router.js +30 -0
  240. package/dist/src/modules/webhook/webhook.service.d.ts +10 -0
  241. package/dist/src/modules/webhook/webhook.service.d.ts.map +1 -0
  242. package/dist/src/modules/webhook/webhook.service.js +68 -0
  243. package/dist/src/modules/workflow/workflow.db.d.ts +297 -0
  244. package/dist/src/modules/workflow/workflow.db.d.ts.map +1 -0
  245. package/dist/src/modules/workflow/workflow.db.js +30 -0
  246. package/dist/src/modules/workflow/workflow.repository.d.ts +344 -0
  247. package/dist/src/modules/workflow/workflow.repository.d.ts.map +1 -0
  248. package/dist/src/modules/workflow/workflow.repository.js +105 -0
  249. package/dist/src/modules/workflow/workflow.service.d.ts +22 -0
  250. package/dist/src/modules/workflow/workflow.service.d.ts.map +1 -0
  251. package/dist/src/modules/workflow/workflow.service.js +37 -0
  252. package/dist/src/modules/workflow/workflow.trpc.d.ts +93 -0
  253. package/dist/src/modules/workflow/workflow.trpc.d.ts.map +1 -0
  254. package/dist/src/modules/workflow/workflow.trpc.js +21 -0
  255. package/dist/src/modules/workflow/workflow.types.d.ts +21 -0
  256. package/dist/src/modules/workflow/workflow.types.d.ts.map +1 -0
  257. package/dist/src/modules/workflow/workflow.types.js +2 -0
  258. package/dist/src/modules/workflow/workflow.utils.d.ts +22 -0
  259. package/dist/src/modules/workflow/workflow.utils.d.ts.map +1 -0
  260. package/dist/src/modules/workflow/workflow.utils.js +173 -0
  261. package/dist/src/test/stubs/utils.d.ts +3 -0
  262. package/dist/src/test/stubs/utils.d.ts.map +1 -0
  263. package/dist/src/test/stubs/utils.js +5 -0
  264. package/dist/src/trpc/context.d.ts +42 -0
  265. package/dist/src/trpc/context.d.ts.map +1 -0
  266. package/dist/src/trpc/context.js +17 -0
  267. package/dist/src/trpc/index.d.ts +4 -0
  268. package/dist/src/trpc/index.d.ts.map +1 -0
  269. package/dist/src/trpc/index.js +6 -0
  270. package/dist/src/trpc/procedures.d.ts +234 -0
  271. package/dist/src/trpc/procedures.d.ts.map +1 -0
  272. package/dist/src/trpc/procedures.js +32 -0
  273. package/dist/src/trpc/utils.d.ts +5 -0
  274. package/dist/src/trpc/utils.d.ts.map +1 -0
  275. package/dist/src/trpc/utils.js +20 -0
  276. package/dist/src/types.d.ts +486 -0
  277. package/dist/src/types.d.ts.map +1 -0
  278. package/dist/src/types.js +13 -0
  279. package/dist/src/utils/errors.d.ts +50 -0
  280. package/dist/src/utils/errors.d.ts.map +1 -0
  281. package/dist/src/utils/errors.js +104 -0
  282. package/dist/src/utils/logger.d.ts +2 -0
  283. package/dist/src/utils/logger.d.ts.map +1 -0
  284. package/dist/src/utils/logger.js +11 -0
  285. package/dist/src/utils/posthog.d.ts +14 -0
  286. package/dist/src/utils/posthog.d.ts.map +1 -0
  287. package/dist/src/utils/posthog.js +31 -0
  288. package/dist/src/utils/types.d.ts +5 -0
  289. package/dist/src/utils/types.d.ts.map +1 -0
  290. package/dist/src/utils/types.js +2 -0
  291. package/dist/tsconfig.tsbuildinfo +1 -0
  292. package/jest.config.ts +19 -0
  293. package/package.json +3 -6
  294. package/tsconfig.json +21 -0
@@ -0,0 +1,160 @@
1
+ import type { LibSQLDatabase } from "drizzle-orm/libsql";
2
+ import { BaseTableRepository } from "#modules/base/base.repository";
3
+ declare const schema: {
4
+ cryptoPayments: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
5
+ name: "crypto_payments";
6
+ schema: undefined;
7
+ columns: {
8
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
9
+ name: "id";
10
+ tableName: "crypto_payments";
11
+ dataType: "string";
12
+ columnType: "SQLiteText";
13
+ data: string;
14
+ driverParam: string;
15
+ notNull: true;
16
+ hasDefault: true;
17
+ isPrimaryKey: true;
18
+ isAutoincrement: false;
19
+ hasRuntimeDefault: true;
20
+ enumValues: [string, ...string[]];
21
+ baseColumn: never;
22
+ identity: undefined;
23
+ generated: undefined;
24
+ }, {}, {
25
+ length: number | undefined;
26
+ }>;
27
+ createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
28
+ name: "created_at";
29
+ tableName: "crypto_payments";
30
+ dataType: "date";
31
+ columnType: "SQLiteTimestamp";
32
+ data: Date;
33
+ driverParam: number;
34
+ notNull: true;
35
+ hasDefault: true;
36
+ isPrimaryKey: false;
37
+ isAutoincrement: false;
38
+ hasRuntimeDefault: true;
39
+ enumValues: undefined;
40
+ baseColumn: never;
41
+ identity: undefined;
42
+ generated: undefined;
43
+ }, {}, {}>;
44
+ updatedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
45
+ name: "updated_at";
46
+ tableName: "crypto_payments";
47
+ dataType: "date";
48
+ columnType: "SQLiteTimestamp";
49
+ data: Date;
50
+ driverParam: number;
51
+ notNull: false;
52
+ hasDefault: false;
53
+ isPrimaryKey: false;
54
+ isAutoincrement: false;
55
+ hasRuntimeDefault: false;
56
+ enumValues: undefined;
57
+ baseColumn: never;
58
+ identity: undefined;
59
+ generated: undefined;
60
+ }, {}, {}>;
61
+ address: import("drizzle-orm/sqlite-core").SQLiteColumn<{
62
+ name: "address";
63
+ tableName: "crypto_payments";
64
+ dataType: "string";
65
+ columnType: "SQLiteText";
66
+ data: string;
67
+ driverParam: string;
68
+ notNull: true;
69
+ hasDefault: false;
70
+ isPrimaryKey: false;
71
+ isAutoincrement: false;
72
+ hasRuntimeDefault: false;
73
+ enumValues: [string, ...string[]];
74
+ baseColumn: never;
75
+ identity: undefined;
76
+ generated: undefined;
77
+ }, {}, {
78
+ length: number | undefined;
79
+ }>;
80
+ referenceId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
81
+ name: "reference_id";
82
+ tableName: "crypto_payments";
83
+ dataType: "string";
84
+ columnType: "SQLiteText";
85
+ data: string;
86
+ driverParam: string;
87
+ notNull: true;
88
+ hasDefault: false;
89
+ isPrimaryKey: false;
90
+ isAutoincrement: false;
91
+ hasRuntimeDefault: false;
92
+ enumValues: [string, ...string[]];
93
+ baseColumn: never;
94
+ identity: undefined;
95
+ generated: undefined;
96
+ }, {}, {
97
+ length: number | undefined;
98
+ }>;
99
+ status: import("drizzle-orm/sqlite-core").SQLiteColumn<{
100
+ name: "status";
101
+ tableName: "crypto_payments";
102
+ dataType: "string";
103
+ columnType: "SQLiteText";
104
+ data: string;
105
+ driverParam: string;
106
+ notNull: true;
107
+ hasDefault: true;
108
+ isPrimaryKey: false;
109
+ isAutoincrement: false;
110
+ hasRuntimeDefault: false;
111
+ enumValues: [string, ...string[]];
112
+ baseColumn: never;
113
+ identity: undefined;
114
+ generated: undefined;
115
+ }, {}, {
116
+ length: number | undefined;
117
+ }>;
118
+ derivationIndex: import("drizzle-orm/sqlite-core").SQLiteColumn<{
119
+ name: "derivation_index";
120
+ tableName: "crypto_payments";
121
+ dataType: "number";
122
+ columnType: "SQLiteInteger";
123
+ data: number;
124
+ driverParam: number;
125
+ notNull: true;
126
+ hasDefault: false;
127
+ isPrimaryKey: false;
128
+ isAutoincrement: false;
129
+ hasRuntimeDefault: false;
130
+ enumValues: undefined;
131
+ baseColumn: never;
132
+ identity: undefined;
133
+ generated: undefined;
134
+ }, {}, {}>;
135
+ amountExpected: import("drizzle-orm/sqlite-core").SQLiteColumn<{
136
+ name: "amount_expected";
137
+ tableName: "crypto_payments";
138
+ dataType: "number";
139
+ columnType: "SQLiteReal";
140
+ data: number;
141
+ driverParam: number;
142
+ notNull: true;
143
+ hasDefault: false;
144
+ isPrimaryKey: false;
145
+ isAutoincrement: false;
146
+ hasRuntimeDefault: false;
147
+ enumValues: undefined;
148
+ baseColumn: never;
149
+ identity: undefined;
150
+ generated: undefined;
151
+ }, {}, {}>;
152
+ };
153
+ dialect: "sqlite";
154
+ }>;
155
+ };
156
+ type Schema = typeof schema;
157
+ export declare class CryptoRepository extends BaseTableRepository<LibSQLDatabase<Schema>, Schema, Record<string, never>, Schema["cryptoPayments"]> {
158
+ }
159
+ export {};
160
+ //# sourceMappingURL=crypto.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.repository.d.ts","sourceRoot":"","sources":["../../../../src/modules/crypto/crypto.repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAGpE,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgB,CAAC;AAC7B,KAAK,MAAM,GAAG,OAAO,MAAM,CAAC;AAE5B,qBAAa,gBAAiB,SAAQ,mBAAmB,CACvD,cAAc,CAAC,MAAM,CAAC,EACtB,MAAM,EACN,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACrB,MAAM,CAAC,gBAAgB,CAAC,CACzB;CAAG"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CryptoRepository = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const base_repository_1 = require("#modules/base/base.repository");
6
+ const crypto = tslib_1.__importStar(require("#modules/crypto/crypto.db"));
7
+ const schema = { ...crypto };
8
+ class CryptoRepository extends base_repository_1.BaseTableRepository {
9
+ }
10
+ exports.CryptoRepository = CryptoRepository;
@@ -0,0 +1,11 @@
1
+ import { BaseService } from "#modules/base/base.service";
2
+ import type { ServerResult } from "#modules/base/base.dto";
3
+ import type { CryptoRepository } from "#modules/crypto/crypto.repository";
4
+ export declare class CryptoService extends BaseService<{
5
+ crypto: CryptoRepository;
6
+ }, Record<string, never>> {
7
+ private root;
8
+ private getRoot;
9
+ createBitcoinAddress(derivationIndex: number): ServerResult<string>;
10
+ }
11
+ //# sourceMappingURL=crypto.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.service.d.ts","sourceRoot":"","sources":["../../../../src/modules/crypto/crypto.service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAO1E,qBAAa,aAAc,SAAQ,WAAW,CAC5C;IAAE,MAAM,EAAE,gBAAgB,CAAA;CAAE,EAC5B,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CACtB;IACC,OAAO,CAAC,IAAI,CAA+B;IAE3C,OAAO,CAAC,OAAO;IAcf,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;CAsBpE"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CryptoService = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const bip32_1 = tslib_1.__importDefault(require("bip32"));
6
+ const bip39 = tslib_1.__importStar(require("bip39"));
7
+ const bitcoin = tslib_1.__importStar(require("bitcoinjs-lib"));
8
+ const ecc = tslib_1.__importStar(require("tiny-secp256k1"));
9
+ const neverthrow_1 = require("neverthrow");
10
+ const base_service_1 = require("#modules/base/base.service");
11
+ const BITCOIN_NATIVE_SEGWIT_PATH = "m/84'/0'/0'/0";
12
+ const bip32 = (0, bip32_1.default)(ecc);
13
+ class CryptoService extends base_service_1.BaseService {
14
+ root = null;
15
+ getRoot() {
16
+ if (this.root)
17
+ return this.root;
18
+ const seed = process.env.BITCOIN_SEED;
19
+ if (!seed?.trim()) {
20
+ throw new Error("BITCOIN_SEED environment variable is not set");
21
+ }
22
+ if (!bip39.validateMnemonic(seed.trim())) {
23
+ throw new Error("BITCOIN_SEED is not a valid BIP39 mnemonic");
24
+ }
25
+ const seedBuffer = bip39.mnemonicToSeedSync(seed.trim());
26
+ this.root = bip32.fromSeed(seedBuffer);
27
+ return this.root;
28
+ }
29
+ createBitcoinAddress(derivationIndex) {
30
+ return this.throwable(() => {
31
+ if (derivationIndex < 0 || !Number.isInteger(derivationIndex)) {
32
+ return this.error("BAD_REQUEST", "derivationIndex must be a non-negative integer");
33
+ }
34
+ const root = this.getRoot();
35
+ const path = `${BITCOIN_NATIVE_SEGWIT_PATH}/${derivationIndex}`;
36
+ const child = root.derivePath(path);
37
+ if (!child.publicKey) {
38
+ return this.error("INTERNAL_SERVER_ERROR", "Failed to derive public key");
39
+ }
40
+ const payment = bitcoin.payments.p2wpkh({
41
+ pubkey: child.publicKey,
42
+ network: bitcoin.networks.bitcoin,
43
+ });
44
+ const address = payment.address;
45
+ if (!address) {
46
+ return this.error("INTERNAL_SERVER_ERROR", "Failed to generate address");
47
+ }
48
+ return (0, neverthrow_1.ok)(address);
49
+ });
50
+ }
51
+ }
52
+ exports.CryptoService = CryptoService;
@@ -0,0 +1,57 @@
1
+ import { type FunctionComponent } from "react";
2
+ import { Resend } from "resend";
3
+ import { BaseService } from "#modules/base/base.service";
4
+ type Brand = {
5
+ name: string;
6
+ logo: string;
7
+ tagline: string;
8
+ };
9
+ type OverrideOptions = {
10
+ from?: string;
11
+ subject?: string;
12
+ previewText?: string;
13
+ };
14
+ type EmailTemplate = {
15
+ id: string;
16
+ subject?: string;
17
+ previewText?: string;
18
+ from?: string;
19
+ react: FunctionComponent<Record<string, unknown>>;
20
+ };
21
+ type EmailTemplates = {
22
+ accountDeletion: EmailTemplate;
23
+ verification: EmailTemplate;
24
+ waitlistConfirmation: EmailTemplate;
25
+ passwordReset: EmailTemplate;
26
+ systemWaitlistNotification: EmailTemplate;
27
+ waitlistInvite: EmailTemplate;
28
+ waitlistUserInvite: EmailTemplate;
29
+ organizationInvite: EmailTemplate;
30
+ [key: string]: EmailTemplate;
31
+ };
32
+ type EmailServiceProps = {
33
+ resendApiKey?: string;
34
+ brand: Brand;
35
+ noReplyFrom: string;
36
+ systemNotificationEmail: string;
37
+ templates: EmailTemplates;
38
+ };
39
+ export declare class EmailService extends BaseService<never, never> {
40
+ client: Resend;
41
+ brand: Brand;
42
+ noReplyFrom: string;
43
+ templates: EmailTemplates;
44
+ systemNotificationEmail: string;
45
+ constructor(props: EmailServiceProps);
46
+ sendTemplate(to: string | string[], templateKey: keyof EmailTemplates, templateProps: Record<string, unknown>, options?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
47
+ sendBrandTemplate(to: string | string[], templateKey: keyof EmailTemplates, templateProps: Record<string, unknown>, options?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
48
+ sendWaitlistConfirmation(email: string, overrideOptions?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
49
+ sendWaitlistInvite(email: string, code: string, overrideOptions?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
50
+ sendWaitlistUserInvite(email: string, code: string, inviter: string, name?: string, overrideOptions?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
51
+ sendOrganizationInvite(email: string, organizationName: string, inviterName: string, role: string, url: string, overrideOptions?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
52
+ sendVerification(email: string, url: string, overrideOptions?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
53
+ sendResetPassword(email: string, url: string, overrideOptions?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
54
+ sendDeleteAccountVerification(email: string, url: string, overrideOptions?: OverrideOptions): Promise<import("neverthrow").Err<never, import("../../utils/errors").ServerError> | import("neverthrow").Ok<void, never>>;
55
+ }
56
+ export {};
57
+ //# sourceMappingURL=email.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.service.d.ts","sourceRoot":"","sources":["../../../../src/modules/email/email.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmailService = void 0;
4
+ const neverthrow_1 = require("neverthrow");
5
+ const react_1 = require("react");
6
+ const resend_1 = require("resend");
7
+ const base_service_1 = require("#modules/base/base.service");
8
+ class EmailService extends base_service_1.BaseService {
9
+ client;
10
+ brand;
11
+ noReplyFrom;
12
+ templates;
13
+ systemNotificationEmail;
14
+ constructor(props) {
15
+ super(undefined, undefined);
16
+ this.client = new resend_1.Resend(props.resendApiKey || process.env.RESEND_API_KEY);
17
+ this.client = {};
18
+ this.brand = props.brand;
19
+ this.noReplyFrom = props.noReplyFrom;
20
+ this.templates = props.templates;
21
+ this.systemNotificationEmail = props.systemNotificationEmail;
22
+ }
23
+ async sendTemplate(to, templateKey, templateProps, options) {
24
+ const template = this.templates[templateKey];
25
+ if (!template) {
26
+ return this.error("NOT_FOUND", `Email template not found: ${String(templateKey)}`);
27
+ }
28
+ const from = options?.from || this.noReplyFrom;
29
+ const subject = options?.subject || template.subject || String(templateKey);
30
+ const previewText = options?.previewText || template.previewText || subject;
31
+ const { error } = await this.client.emails.send({
32
+ to,
33
+ subject,
34
+ from,
35
+ react: (0, react_1.createElement)(template.react, { ...templateProps, previewText }),
36
+ });
37
+ if (error)
38
+ return this.error("INTERNAL_SERVER_ERROR", `Failed to send email: ${templateKey}`, {
39
+ cause: error,
40
+ });
41
+ return (0, neverthrow_1.ok)();
42
+ }
43
+ async sendBrandTemplate(to, templateKey, templateProps, options) {
44
+ return this.sendTemplate(to, templateKey, {
45
+ brand: this.brand,
46
+ ...templateProps,
47
+ }, options);
48
+ }
49
+ async sendWaitlistConfirmation(email, overrideOptions) {
50
+ return this.sendTemplate(email, "waitlistConfirmation", {
51
+ email,
52
+ brand: this.brand,
53
+ }, overrideOptions);
54
+ }
55
+ async sendWaitlistInvite(email, code, overrideOptions) {
56
+ const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;
57
+ return this.sendTemplate(email, "waitlistInvite", {
58
+ url,
59
+ brand: this.brand,
60
+ }, overrideOptions);
61
+ }
62
+ async sendWaitlistUserInvite(email, code, inviter, name, overrideOptions) {
63
+ const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;
64
+ return this.sendTemplate(email, "waitlistUserInvite", {
65
+ url,
66
+ brand: this.brand,
67
+ inviter,
68
+ name,
69
+ }, {
70
+ previewText: `Create your ${this.brand.name} account today!`,
71
+ subject: `${inviter} has invited you to join ${this.brand.name}!`,
72
+ ...overrideOptions,
73
+ });
74
+ }
75
+ async sendOrganizationInvite(email, organizationName, inviterName, role, url, overrideOptions) {
76
+ return this.sendTemplate(email, "organizationInvite", {
77
+ url,
78
+ brand: this.brand,
79
+ organizationName,
80
+ inviterName,
81
+ role,
82
+ }, {
83
+ previewText: `${inviterName} invited you to ${organizationName}`,
84
+ subject: `${inviterName} invited you to join ${organizationName}`,
85
+ ...overrideOptions,
86
+ });
87
+ }
88
+ async sendVerification(email, url, overrideOptions) {
89
+ return this.sendTemplate(email, "verification", {
90
+ url,
91
+ brand: this.brand,
92
+ }, overrideOptions);
93
+ }
94
+ async sendResetPassword(email, url, overrideOptions) {
95
+ return this.sendTemplate(email, "passwordReset", {
96
+ url,
97
+ brand: this.brand,
98
+ }, overrideOptions);
99
+ }
100
+ async sendDeleteAccountVerification(email, url, overrideOptions) {
101
+ return this.sendTemplate(email, "accountDeletion", {
102
+ url,
103
+ brand: this.brand,
104
+ }, overrideOptions);
105
+ }
106
+ }
107
+ exports.EmailService = EmailService;
@@ -0,0 +1,13 @@
1
+ import { type GetObjectCommandOutput } from "@aws-sdk/client-s3";
2
+ import type { ServerResultAsync } from "#modules/base/base.dto";
3
+ import { BaseExternaRepository } from "#modules/base/base.repository";
4
+ export declare class FileRepository extends BaseExternaRepository {
5
+ private readonly s3;
6
+ constructor();
7
+ getS3UploadUrl(filename: string, filetype: string, expiresIn?: number): ServerResultAsync<string>;
8
+ getS3DownloadUrl(path: string, expiresIn?: number): ServerResultAsync<string>;
9
+ getS3Object(path: string): ServerResultAsync<GetObjectCommandOutput>;
10
+ getS3ObjectT(path: string): ServerResultAsync<GetObjectCommandOutput>;
11
+ deleteS3Object(path: string): ServerResultAsync<void>;
12
+ }
13
+ //# sourceMappingURL=file.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.repository.d.ts","sourceRoot":"","sources":["../../../../src/modules/file/file.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,sBAAsB,EAG5B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,qBAAa,cAAe,SAAQ,qBAAqB;IACvD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAW;;IAsBxB,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,SAAS,GACjB,iBAAiB,CAAC,MAAM,CAAC;IAYtB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAW7E,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAC,sBAAsB,CAAC;IAWpE,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAC,sBAAsB,CAAC;IAWrE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC;CAU5D"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileRepository = void 0;
4
+ const client_s3_1 = require("@aws-sdk/client-s3");
5
+ const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
6
+ const neverthrow_1 = require("neverthrow");
7
+ const base_repository_1 = require("#modules/base/base.repository");
8
+ class FileRepository extends base_repository_1.BaseExternaRepository {
9
+ s3;
10
+ constructor() {
11
+ super();
12
+ if (!process.env.AWS_REGION ||
13
+ !process.env.AWS_ACCESS_KEY_ID ||
14
+ !process.env.AWS_SECRET_ACCESS_KEY) {
15
+ throw new Error("Missing AWS environment variables");
16
+ }
17
+ this.s3 = new client_s3_1.S3Client({
18
+ region: process.env.AWS_REGION,
19
+ credentials: {
20
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
21
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
22
+ },
23
+ ...(process.env.AWS_S3_ENDPOINT ? { endpoint: process.env.AWS_S3_ENDPOINT } : {}),
24
+ forcePathStyle: !!process.env.AWS_S3_ENDPOINT, // Path style is often required for non-AWS S3 providers
25
+ });
26
+ }
27
+ async getS3UploadUrl(filename, filetype, expiresIn = 60 * 5) {
28
+ return this.throwableAsync(async () => {
29
+ const command = new client_s3_1.PutObjectCommand({
30
+ Bucket: process.env.AWS_S3_BUCKET,
31
+ Key: filename,
32
+ ContentType: filetype,
33
+ });
34
+ const url = await (0, s3_request_presigner_1.getSignedUrl)(this.s3, command, { expiresIn });
35
+ return (0, neverthrow_1.ok)(url);
36
+ });
37
+ }
38
+ async getS3DownloadUrl(path, expiresIn = 60 * 5) {
39
+ return this.throwableAsync(async () => {
40
+ const command = new client_s3_1.GetObjectCommand({
41
+ Bucket: process.env.AWS_S3_BUCKET,
42
+ Key: path,
43
+ });
44
+ const url = await (0, s3_request_presigner_1.getSignedUrl)(this.s3, command, { expiresIn });
45
+ return (0, neverthrow_1.ok)(url);
46
+ });
47
+ }
48
+ async getS3Object(path) {
49
+ return this.throwableAsync(async () => {
50
+ const command = new client_s3_1.GetObjectCommand({
51
+ Bucket: process.env.AWS_S3_BUCKET,
52
+ Key: path,
53
+ });
54
+ const data = await this.s3.send(command);
55
+ return (0, neverthrow_1.ok)(data);
56
+ });
57
+ }
58
+ async getS3ObjectT(path) {
59
+ return this.throwableAsync(async () => {
60
+ const command = new client_s3_1.GetObjectCommand({
61
+ Bucket: process.env.AWS_S3_BUCKET,
62
+ Key: path,
63
+ });
64
+ const data = await this.s3.send(command);
65
+ return (0, neverthrow_1.ok)(data);
66
+ });
67
+ }
68
+ async deleteS3Object(path) {
69
+ return this.throwableAsync(async () => {
70
+ const command = new client_s3_1.DeleteObjectCommand({
71
+ Bucket: process.env.AWS_S3_BUCKET,
72
+ Key: path,
73
+ });
74
+ await this.s3.send(command);
75
+ return (0, neverthrow_1.ok)(undefined);
76
+ });
77
+ }
78
+ }
79
+ exports.FileRepository = FileRepository;
@@ -0,0 +1,4 @@
1
+ import express from "express";
2
+ declare const uploadRouter: express.Router;
3
+ export { uploadRouter };
4
+ //# sourceMappingURL=file.router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.router.d.ts","sourceRoot":"","sources":["../../../../src/modules/file/file.router.ts"],"names":[],"mappings":"AAGA,OAAO,OAAwC,MAAM,SAAS,CAAC;AAwC/D,QAAA,MAAM,YAAY,EAAE,OAAO,CAAC,MAAyB,CAAC;AAgEtD,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uploadRouter = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
6
+ const file_constants_1 = require("@m5kdev/commons/modules/file/file.constants");
7
+ const body_parser_1 = tslib_1.__importDefault(require("body-parser"));
8
+ const express_1 = tslib_1.__importDefault(require("express"));
9
+ const multer_1 = tslib_1.__importDefault(require("multer"));
10
+ const uuid_1 = require("uuid");
11
+ const file_repository_1 = require("#modules/file/file.repository");
12
+ const file_service_1 = require("#modules/file/file.service");
13
+ const fileRepository = new file_repository_1.FileRepository();
14
+ const fileService = new file_service_1.FileService({ file: fileRepository });
15
+ function validateMimeType(type, file) {
16
+ return file_constants_1.fileTypes[type]?.mimetypes.includes(file.mimetype);
17
+ }
18
+ function getFileExtension(file) {
19
+ return file.originalname.split(".").pop();
20
+ }
21
+ const storage = multer_1.default.diskStorage({
22
+ destination: (_req, _file, cb) => {
23
+ cb(null, node_path_1.default.join(__dirname, "..", "uploads"));
24
+ },
25
+ filename: (_req, file, cb) => {
26
+ cb(null, `${(0, uuid_1.v4)()}.${getFileExtension(file)}`);
27
+ },
28
+ });
29
+ const fileFilter = (req, file, cb) => {
30
+ const { type } = req.params;
31
+ if (type && validateMimeType(type, file)) {
32
+ cb(null, true);
33
+ }
34
+ else {
35
+ cb(new Error("Invalid file type"));
36
+ }
37
+ };
38
+ const upload = (0, multer_1.default)({ storage, fileFilter });
39
+ const uploadRouter = express_1.default.Router();
40
+ exports.uploadRouter = uploadRouter;
41
+ uploadRouter.post("/file/:type", upload.single("file"), (req, res) => {
42
+ const { file } = req;
43
+ if (!file) {
44
+ return res.status(400).json({ error: "No file uploaded" });
45
+ }
46
+ return res.json({
47
+ url: `${process.env.VITE_SERVER_URL}/upload/file/${file.filename}`,
48
+ mimetype: file.mimetype,
49
+ size: file.size,
50
+ });
51
+ });
52
+ uploadRouter.get("/file/:filename", (req, res) => {
53
+ res.sendFile(node_path_1.default.join(__dirname, "..", "uploads", req.params.filename));
54
+ });
55
+ uploadRouter.get("/files/:path", async (req, res) => {
56
+ try {
57
+ const url = await fileService.getS3DownloadUrl(req.params.path);
58
+ if (url.isErr()) {
59
+ console.error(url.error);
60
+ return res.status(500).json({ error: url.error.message });
61
+ }
62
+ return res.json({ url: url.value });
63
+ }
64
+ catch (err) {
65
+ console.error(err);
66
+ return res.status(500).json({ error: err.message || "Failed to generate presigned URL" });
67
+ }
68
+ });
69
+ uploadRouter.post("/s3-presigned-url", body_parser_1.default.json(), async (req, res) => {
70
+ const { filename, filetype } = req.body;
71
+ if (!filename || !filetype) {
72
+ return res.status(400).json({ error: "Missing filename or filetype" });
73
+ }
74
+ try {
75
+ const url = await fileService.getS3UploadUrl(filename, filetype);
76
+ if (url.isErr()) {
77
+ return res.status(500).json({ error: url.error.message });
78
+ }
79
+ return res.json({ url: url.value });
80
+ }
81
+ catch (err) {
82
+ console.error(err);
83
+ return res.status(500).json({ error: err.message || "Failed to generate presigned URL" });
84
+ }
85
+ });
86
+ uploadRouter.delete("/files/:path(*)", async (req, res) => {
87
+ try {
88
+ const result = await fileService.deleteS3Object(req.params.path);
89
+ if (result.isErr()) {
90
+ console.error(result.error);
91
+ return res.status(500).json({ error: result.error.message });
92
+ }
93
+ return res.json({ success: true });
94
+ }
95
+ catch (err) {
96
+ console.error(err);
97
+ return res.status(500).json({ error: err.message || "Failed to delete S3 object" });
98
+ }
99
+ });
@@ -0,0 +1,25 @@
1
+ import { fileTypes } from "@m5kdev/commons/modules/file/file.constants";
2
+ import type { ServerResult, ServerResultAsync } from "#modules/base/base.dto";
3
+ import { BaseService } from "#modules/base/base.service";
4
+ import type { FileRepository } from "#modules/file/file.repository";
5
+ export declare class FileService extends BaseService<{
6
+ file: FileRepository;
7
+ }, never> {
8
+ isS3Path(path: string): boolean;
9
+ parseS3Path(S3Path: string): ServerResult<{
10
+ bucket: string;
11
+ path: string;
12
+ }>;
13
+ wrapS3Path(path: string, bucket: string): string;
14
+ getS3UploadUrl(filename: string, filetype: string, expiresIn?: number): ServerResultAsync<string>;
15
+ getS3DownloadUrl(path: string, expiresIn?: number): ServerResultAsync<string>;
16
+ getS3Object(path: string): ServerResultAsync<import("@aws-sdk/client-s3").GetObjectCommandOutput>;
17
+ deleteS3Object(path: string): ServerResultAsync<void>;
18
+ uploadFileToS3(localPath: string, returnDownloadUrl?: boolean): ServerResultAsync<string>;
19
+ downloadS3ToFile(s3Path: string): ServerResultAsync<string>;
20
+ getFileType(path: string): {
21
+ fileType: keyof typeof fileTypes;
22
+ extension: string;
23
+ } | undefined;
24
+ }
25
+ //# sourceMappingURL=file.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.service.d.ts","sourceRoot":"","sources":["../../../../src/modules/file/file.service.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,6CAA6C,CAAC;AAGxE,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,qBAAa,WAAY,SAAQ,WAAW,CAAC;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,EAAE,KAAK,CAAC;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAQ3E,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAIhD,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,SAAS,GACjB,iBAAiB,CAAC,MAAM,CAAC;IAI5B,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAI7E,WAAW,CAAC,IAAI,EAAE,MAAM;IAIxB,cAAc,CAAC,IAAI,EAAE,MAAM;IAIrB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,iBAAiB,UAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC;IA2CvF,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAgFjE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,OAAO,SAAS,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;CAY/F"}