@m5kdev/backend 0.8.7 → 0.8.9

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 (385) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +33 -0
  2. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/api/index.d.cts +1 -0
  3. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/factory.d.cts +1 -0
  4. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/get-field-attributes.d.cts +1 -0
  5. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/get-id-field.d.cts +1 -0
  6. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/index.d.cts +1 -0
  7. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/adapter/types.d.cts +1 -0
  8. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/get-tables.d.cts +1 -0
  9. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/index.d.cts +1 -0
  10. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/account.d.cts +1 -0
  11. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/rate-limit.d.cts +1 -0
  12. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/session.d.cts +1 -0
  13. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/shared.d.cts +1 -0
  14. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/user.d.cts +1 -0
  15. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/db/schema/verification.d.cts +1 -0
  16. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/index.d.cts +1 -0
  17. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/social-providers/index.d.cts +1 -0
  18. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/context.d.cts +1 -0
  19. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/helper.d.cts +7 -0
  20. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/init-options.d.cts +1 -0
  21. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/plugin-client.d.cts +1 -0
  22. package/dist/node_modules/.pnpm/@better-auth_core@1.4.18_@better-auth_utils@0.3.0_@better-fetch_fetch@1.1.21_better-cal_347838d331444e5371f256b914727290/node_modules/@better-auth/core/dist/types/plugin.d.cts +1 -0
  23. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/dialect-adapter-base.d.cts +1 -0
  24. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/dialect-adapter.d.cts +1 -0
  25. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/dialect.d.cts +1 -0
  26. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mssql/mssql-adapter.d.cts +1 -0
  27. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mssql/mssql-dialect.d.cts +1 -0
  28. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mssql/mssql-introspector.d.cts +1 -0
  29. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mysql/mysql-adapter.d.cts +1 -0
  30. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mysql/mysql-dialect.d.cts +1 -0
  31. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/mysql/mysql-introspector.d.cts +1 -0
  32. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/postgres/postgres-adapter.d.cts +1 -0
  33. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect.d.cts +1 -0
  34. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/postgres/postgres-introspector.d.cts +1 -0
  35. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-adapter.d.cts +1 -0
  36. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-dialect.d.cts +1 -0
  37. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-introspector.d.cts +1 -0
  38. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/expression/expression-builder.d.cts +1 -0
  39. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/index.d.cts +1 -0
  40. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/kysely.d.cts +38 -0
  41. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/migration/file-migration-provider.d.cts +1 -0
  42. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/migration/migrator.d.cts +1 -0
  43. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/binary-operation-parser.d.cts +1 -0
  44. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/delete-from-parser.d.cts +1 -0
  45. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/expression-parser.d.cts +1 -0
  46. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/group-by-parser.d.cts +1 -0
  47. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/insert-values-parser.d.cts +1 -0
  48. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/join-parser.d.cts +1 -0
  49. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/merge-into-parser.d.cts +1 -0
  50. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/reference-parser.d.cts +1 -0
  51. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/returning-parser.d.cts +1 -0
  52. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/select-from-parser.d.cts +1 -0
  53. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/select-parser.d.cts +1 -0
  54. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/set-operation-parser.d.cts +1 -0
  55. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/tuple-parser.d.cts +1 -0
  56. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/unary-operation-parser.d.cts +1 -0
  57. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/update-parser.d.cts +1 -0
  58. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/update-set-parser.d.cts +1 -0
  59. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/value-parser.d.cts +1 -0
  60. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/parser/with-parser.d.cts +1 -0
  61. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/case-builder.d.cts +1 -0
  62. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/delete-query-builder.d.cts +1 -0
  63. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/having-interface.d.cts +1 -0
  64. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/insert-query-builder.d.cts +1 -0
  65. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/join-builder.d.cts +1 -0
  66. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/merge-query-builder.d.cts +1 -0
  67. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/on-conflict-builder.d.cts +1 -0
  68. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/output-interface.d.cts +1 -0
  69. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/returning-interface.d.cts +1 -0
  70. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/select-query-builder.d.cts +1 -0
  71. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/update-query-builder.d.cts +1 -0
  72. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-builder/where-interface.d.cts +1 -0
  73. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-creator.d.cts +1 -0
  74. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/default-query-executor.d.cts +1 -0
  75. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/noop-query-executor.d.cts +1 -0
  76. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/query-executor-base.d.cts +1 -0
  77. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/query-executor-provider.d.cts +1 -0
  78. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/query-executor/query-executor.d.cts +1 -0
  79. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/raw-builder/raw-builder.d.cts +1 -0
  80. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/raw-builder/sql.d.cts +1 -0
  81. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-add-foreign-key-constraint-builder.d.cts +1 -0
  82. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-add-index-builder.d.cts +1 -0
  83. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-builder.d.cts +1 -0
  84. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-drop-constraint-builder.d.cts +1 -0
  85. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/alter-table-executor.d.cts +1 -0
  86. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-index-builder.d.cts +1 -0
  87. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-schema-builder.d.cts +1 -0
  88. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-table-builder.d.cts +1 -0
  89. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-type-builder.d.cts +1 -0
  90. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/create-view-builder.d.cts +1 -0
  91. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-index-builder.d.cts +1 -0
  92. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-schema-builder.d.cts +1 -0
  93. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-table-builder.d.cts +1 -0
  94. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-type-builder.d.cts +1 -0
  95. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/drop-view-builder.d.cts +1 -0
  96. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/refresh-materialized-view-builder.d.cts +1 -0
  97. package/dist/node_modules/.pnpm/kysely@0.28.5/node_modules/kysely/dist/esm/schema/schema.d.cts +1 -0
  98. package/dist/src/lib/posthog.cjs +8 -0
  99. package/dist/src/lib/posthog.cjs.map +1 -0
  100. package/dist/src/lib/posthog.d.cts +7 -0
  101. package/dist/src/lib/sentry.cjs +11 -0
  102. package/dist/src/lib/sentry.cjs.map +1 -0
  103. package/dist/src/lib/sentry.d.cts +1 -0
  104. package/dist/src/modules/access/access.repository.cjs +26 -0
  105. package/dist/src/modules/access/access.repository.cjs.map +1 -0
  106. package/dist/src/modules/access/access.repository.d.cts +2352 -0
  107. package/dist/src/modules/access/access.service.cjs +42 -0
  108. package/dist/src/modules/access/access.service.cjs.map +1 -0
  109. package/dist/src/modules/access/access.service.d.cts +25 -0
  110. package/dist/src/modules/access/access.utils.cjs +23 -0
  111. package/dist/src/modules/access/access.utils.cjs.map +1 -0
  112. package/dist/src/modules/access/access.utils.d.cts +19 -0
  113. package/dist/src/modules/ai/ai.db.cjs +46 -0
  114. package/dist/src/modules/ai/ai.db.cjs.map +1 -0
  115. package/dist/src/modules/ai/ai.db.d.cts +401 -0
  116. package/dist/src/modules/ai/ai.prompt.cjs +33 -0
  117. package/dist/src/modules/ai/ai.prompt.cjs.map +1 -0
  118. package/dist/src/modules/ai/ai.prompt.d.cts +30 -0
  119. package/dist/src/modules/ai/ai.prompts.cjs +18 -0
  120. package/dist/src/modules/ai/ai.prompts.cjs.map +1 -0
  121. package/dist/src/modules/ai/ai.prompts.d.cts +10 -0
  122. package/dist/src/modules/ai/ai.repository.cjs +25 -0
  123. package/dist/src/modules/ai/ai.repository.cjs.map +1 -0
  124. package/dist/src/modules/ai/ai.repository.d.cts +428 -0
  125. package/dist/src/modules/ai/ai.router.cjs +0 -0
  126. package/dist/src/modules/ai/ai.router.d.cts +1 -0
  127. package/dist/src/modules/ai/ai.service.cjs +312 -0
  128. package/dist/src/modules/ai/ai.service.cjs.map +1 -0
  129. package/dist/src/modules/ai/ai.service.d.cts +141 -0
  130. package/dist/src/modules/ai/ai.trpc.cjs +19 -0
  131. package/dist/src/modules/ai/ai.trpc.cjs.map +1 -0
  132. package/dist/src/modules/ai/ai.trpc.d.cts +31 -0
  133. package/dist/src/modules/ai/ideogram/ideogram.constants.cjs +191 -0
  134. package/dist/src/modules/ai/ideogram/ideogram.constants.cjs.map +1 -0
  135. package/dist/src/modules/ai/ideogram/ideogram.constants.d.cts +11 -0
  136. package/dist/src/modules/ai/ideogram/ideogram.dto.cjs +49 -0
  137. package/dist/src/modules/ai/ideogram/ideogram.dto.cjs.map +1 -0
  138. package/dist/src/modules/ai/ideogram/ideogram.dto.d.cts +234 -0
  139. package/dist/src/modules/ai/ideogram/ideogram.prompt.cjs +862 -0
  140. package/dist/src/modules/ai/ideogram/ideogram.prompt.cjs.map +1 -0
  141. package/dist/src/modules/ai/ideogram/ideogram.prompt.d.cts +7 -0
  142. package/dist/src/modules/ai/ideogram/ideogram.repository.cjs +34 -0
  143. package/dist/src/modules/ai/ideogram/ideogram.repository.cjs.map +1 -0
  144. package/dist/src/modules/ai/ideogram/ideogram.repository.d.cts +11 -0
  145. package/dist/src/modules/ai/ideogram/ideogram.service.cjs +12 -0
  146. package/dist/src/modules/ai/ideogram/ideogram.service.cjs.map +1 -0
  147. package/dist/src/modules/ai/ideogram/ideogram.service.d.cts +14 -0
  148. package/dist/src/modules/auth/auth.db.cjs +187 -0
  149. package/dist/src/modules/auth/auth.db.cjs.map +1 -0
  150. package/dist/src/modules/auth/auth.db.d.cts +2341 -0
  151. package/dist/src/modules/auth/auth.dto.cjs +50 -0
  152. package/dist/src/modules/auth/auth.dto.cjs.map +1 -0
  153. package/dist/src/modules/auth/auth.dto.d.cts +70 -0
  154. package/dist/src/modules/auth/auth.lib.cjs +234 -0
  155. package/dist/src/modules/auth/auth.lib.cjs.map +1 -0
  156. package/dist/src/modules/auth/auth.lib.d.cts +4894 -0
  157. package/dist/src/modules/auth/auth.middleware.cjs +41 -0
  158. package/dist/src/modules/auth/auth.middleware.cjs.map +1 -0
  159. package/dist/src/modules/auth/auth.middleware.d.cts +619 -0
  160. package/dist/src/modules/auth/auth.repository.cjs +403 -0
  161. package/dist/src/modules/auth/auth.repository.cjs.map +1 -0
  162. package/dist/src/modules/auth/auth.repository.d.cts +2453 -0
  163. package/dist/src/modules/auth/auth.service.cjs +229 -0
  164. package/dist/src/modules/auth/auth.service.cjs.map +1 -0
  165. package/dist/src/modules/auth/auth.service.d.cts +105 -0
  166. package/dist/src/modules/auth/auth.trpc.cjs +110 -0
  167. package/dist/src/modules/auth/auth.trpc.cjs.map +1 -0
  168. package/dist/src/modules/auth/auth.trpc.d.cts +303 -0
  169. package/dist/src/modules/auth/auth.utils.cjs +80 -0
  170. package/dist/src/modules/auth/auth.utils.cjs.map +1 -0
  171. package/dist/src/modules/auth/auth.utils.d.cts +2356 -0
  172. package/dist/src/modules/base/base.abstract.cjs +62 -0
  173. package/dist/src/modules/base/base.abstract.cjs.map +1 -0
  174. package/dist/src/modules/base/base.abstract.d.cts +29 -0
  175. package/dist/src/modules/base/base.actor.cjs +83 -0
  176. package/dist/src/modules/base/base.actor.cjs.map +1 -0
  177. package/dist/src/modules/base/base.actor.d.cts +73 -0
  178. package/dist/src/modules/base/base.dto.cjs +98 -0
  179. package/dist/src/modules/base/base.dto.cjs.map +1 -0
  180. package/dist/src/modules/base/base.dto.d.cts +67 -0
  181. package/dist/src/modules/base/base.grants.cjs +107 -0
  182. package/dist/src/modules/base/base.grants.cjs.map +1 -0
  183. package/dist/src/modules/base/base.grants.d.cts +28 -0
  184. package/dist/src/modules/base/base.procedure.cjs +255 -0
  185. package/dist/src/modules/base/base.procedure.cjs.map +1 -0
  186. package/dist/src/modules/base/base.procedure.d.cts +111 -0
  187. package/dist/src/modules/base/base.repository.cjs +269 -0
  188. package/dist/src/modules/base/base.repository.cjs.map +1 -0
  189. package/dist/src/modules/base/base.repository.d.cts +125 -0
  190. package/dist/src/modules/base/base.repository.d.mts +2 -0
  191. package/dist/src/modules/base/base.repository.mjs +12 -0
  192. package/dist/src/modules/base/base.repository.mjs.map +1 -1
  193. package/dist/src/modules/base/base.service.cjs +119 -0
  194. package/dist/src/modules/base/base.service.cjs.map +1 -0
  195. package/dist/src/modules/base/base.service.d.cts +44 -0
  196. package/dist/src/modules/base/base.types.cjs +0 -0
  197. package/dist/src/modules/base/base.types.d.cts +5 -0
  198. package/dist/src/modules/billing/billing.db.cjs +38 -0
  199. package/dist/src/modules/billing/billing.db.cjs.map +1 -0
  200. package/dist/src/modules/billing/billing.db.d.cts +371 -0
  201. package/dist/src/modules/billing/billing.repository.cjs +190 -0
  202. package/dist/src/modules/billing/billing.repository.cjs.map +1 -0
  203. package/dist/src/modules/billing/billing.repository.d.cts +2787 -0
  204. package/dist/src/modules/billing/billing.router.cjs +43 -0
  205. package/dist/src/modules/billing/billing.router.cjs.map +1 -0
  206. package/dist/src/modules/billing/billing.router.d.cts +9 -0
  207. package/dist/src/modules/billing/billing.service.cjs +127 -0
  208. package/dist/src/modules/billing/billing.service.cjs.map +1 -0
  209. package/dist/src/modules/billing/billing.service.d.cts +53 -0
  210. package/dist/src/modules/billing/billing.trpc.cjs +19 -0
  211. package/dist/src/modules/billing/billing.trpc.cjs.map +1 -0
  212. package/dist/src/modules/billing/billing.trpc.d.cts +48 -0
  213. package/dist/src/modules/clay/clay.repository.cjs +29 -0
  214. package/dist/src/modules/clay/clay.repository.cjs.map +1 -0
  215. package/dist/src/modules/clay/clay.repository.d.cts +10 -0
  216. package/dist/src/modules/clay/clay.service.cjs +24 -0
  217. package/dist/src/modules/clay/clay.service.cjs.map +1 -0
  218. package/dist/src/modules/clay/clay.service.d.cts +32 -0
  219. package/dist/src/modules/connect/connect.db.cjs +37 -0
  220. package/dist/src/modules/connect/connect.db.cjs.map +1 -0
  221. package/dist/src/modules/connect/connect.db.d.cts +362 -0
  222. package/dist/src/modules/connect/connect.dto.cjs +45 -0
  223. package/dist/src/modules/connect/connect.dto.cjs.map +1 -0
  224. package/dist/src/modules/connect/connect.dto.d.cts +79 -0
  225. package/dist/src/modules/connect/connect.dto.d.mts +2 -2
  226. package/dist/src/modules/connect/connect.linkedin.cjs +48 -0
  227. package/dist/src/modules/connect/connect.linkedin.cjs.map +1 -0
  228. package/dist/src/modules/connect/connect.linkedin.d.cts +7 -0
  229. package/dist/src/modules/connect/connect.oauth.cjs +153 -0
  230. package/dist/src/modules/connect/connect.oauth.cjs.map +1 -0
  231. package/dist/src/modules/connect/connect.oauth.d.cts +32 -0
  232. package/dist/src/modules/connect/connect.repository.cjs +42 -0
  233. package/dist/src/modules/connect/connect.repository.cjs.map +1 -0
  234. package/dist/src/modules/connect/connect.repository.d.cts +419 -0
  235. package/dist/src/modules/connect/connect.repository.d.mts +1 -1
  236. package/dist/src/modules/connect/connect.router.cjs +48 -0
  237. package/dist/src/modules/connect/connect.router.cjs.map +1 -0
  238. package/dist/src/modules/connect/connect.router.d.cts +9 -0
  239. package/dist/src/modules/connect/connect.service.cjs +90 -0
  240. package/dist/src/modules/connect/connect.service.cjs.map +1 -0
  241. package/dist/src/modules/connect/connect.service.d.cts +103 -0
  242. package/dist/src/modules/connect/connect.service.d.mts +2 -2
  243. package/dist/src/modules/connect/connect.trpc.cjs +18 -0
  244. package/dist/src/modules/connect/connect.trpc.cjs.map +1 -0
  245. package/dist/src/modules/connect/connect.trpc.d.cts +53 -0
  246. package/dist/src/modules/connect/connect.trpc.d.mts +1 -1
  247. package/dist/src/modules/connect/connect.types.cjs +0 -0
  248. package/dist/src/modules/connect/connect.types.d.cts +29 -0
  249. package/dist/src/modules/crypto/crypto.db.cjs +26 -0
  250. package/dist/src/modules/crypto/crypto.db.cjs.map +1 -0
  251. package/dist/src/modules/crypto/crypto.db.d.cts +157 -0
  252. package/dist/src/modules/crypto/crypto.repository.cjs +9 -0
  253. package/dist/src/modules/crypto/crypto.repository.cjs.map +1 -0
  254. package/dist/src/modules/crypto/crypto.repository.d.cts +163 -0
  255. package/dist/src/modules/crypto/crypto.service.cjs +46 -0
  256. package/dist/src/modules/crypto/crypto.service.cjs.map +1 -0
  257. package/dist/src/modules/crypto/crypto.service.d.cts +15 -0
  258. package/dist/src/modules/email/email.service.cjs +107 -0
  259. package/dist/src/modules/email/email.service.cjs.map +1 -0
  260. package/dist/src/modules/email/email.service.d.cts +62 -0
  261. package/dist/src/modules/file/file.repository.cjs +74 -0
  262. package/dist/src/modules/file/file.repository.cjs.map +1 -0
  263. package/dist/src/modules/file/file.repository.d.cts +17 -0
  264. package/dist/src/modules/file/file.router.cjs +94 -0
  265. package/dist/src/modules/file/file.router.cjs.map +1 -0
  266. package/dist/src/modules/file/file.router.d.cts +7 -0
  267. package/dist/src/modules/file/file.service.cjs +120 -0
  268. package/dist/src/modules/file/file.service.cjs.map +1 -0
  269. package/dist/src/modules/file/file.service.d.cts +30 -0
  270. package/dist/src/modules/recurrence/recurrence.db.cjs +55 -0
  271. package/dist/src/modules/recurrence/recurrence.db.cjs.map +1 -0
  272. package/dist/src/modules/recurrence/recurrence.db.d.cts +568 -0
  273. package/dist/src/modules/recurrence/recurrence.repository.cjs +31 -0
  274. package/dist/src/modules/recurrence/recurrence.repository.cjs.map +1 -0
  275. package/dist/src/modules/recurrence/recurrence.repository.d.cts +588 -0
  276. package/dist/src/modules/recurrence/recurrence.service.cjs +66 -0
  277. package/dist/src/modules/recurrence/recurrence.service.cjs.map +1 -0
  278. package/dist/src/modules/recurrence/recurrence.service.d.cts +88 -0
  279. package/dist/src/modules/recurrence/recurrence.service.d.mts +2 -1
  280. package/dist/src/modules/recurrence/recurrence.service.mjs +1 -1
  281. package/dist/src/modules/recurrence/recurrence.service.mjs.map +1 -1
  282. package/dist/src/modules/recurrence/recurrence.trpc.cjs +46 -0
  283. package/dist/src/modules/recurrence/recurrence.trpc.cjs.map +1 -0
  284. package/dist/src/modules/recurrence/recurrence.trpc.d.cts +216 -0
  285. package/dist/src/modules/recurrence/recurrence.trpc.d.mts +2 -1
  286. package/dist/src/modules/social/social.dto.cjs +26 -0
  287. package/dist/src/modules/social/social.dto.cjs.map +1 -0
  288. package/dist/src/modules/social/social.dto.d.cts +39 -0
  289. package/dist/src/modules/social/social.linkedin.cjs +349 -0
  290. package/dist/src/modules/social/social.linkedin.cjs.map +1 -0
  291. package/dist/src/modules/social/social.linkedin.d.cts +15 -0
  292. package/dist/src/modules/social/social.service.cjs +57 -0
  293. package/dist/src/modules/social/social.service.cjs.map +1 -0
  294. package/dist/src/modules/social/social.service.d.cts +34 -0
  295. package/dist/src/modules/social/social.types.cjs +0 -0
  296. package/dist/src/modules/social/social.types.d.cts +40 -0
  297. package/dist/src/modules/tag/tag.db.cjs +43 -0
  298. package/dist/src/modules/tag/tag.db.cjs.map +1 -0
  299. package/dist/src/modules/tag/tag.db.d.cts +352 -0
  300. package/dist/src/modules/tag/tag.dto.cjs +15 -0
  301. package/dist/src/modules/tag/tag.dto.cjs.map +1 -0
  302. package/dist/src/modules/tag/tag.dto.d.cts +1025 -0
  303. package/dist/src/modules/tag/tag.repository.cjs +116 -0
  304. package/dist/src/modules/tag/tag.repository.cjs.map +1 -0
  305. package/dist/src/modules/tag/tag.repository.d.cts +394 -0
  306. package/dist/src/modules/tag/tag.service.cjs +48 -0
  307. package/dist/src/modules/tag/tag.service.cjs.map +1 -0
  308. package/dist/src/modules/tag/tag.service.d.cts +120 -0
  309. package/dist/src/modules/tag/tag.trpc.cjs +32 -0
  310. package/dist/src/modules/tag/tag.trpc.cjs.map +1 -0
  311. package/dist/src/modules/tag/tag.trpc.d.cts +174 -0
  312. package/dist/src/modules/tag/tag.trpc.d.mts +3 -2
  313. package/dist/src/modules/utils/applyPagination.cjs +16 -0
  314. package/dist/src/modules/utils/applyPagination.cjs.map +1 -0
  315. package/dist/src/modules/utils/applyPagination.d.cts +10 -0
  316. package/dist/src/modules/utils/applySorting.cjs +20 -0
  317. package/dist/src/modules/utils/applySorting.cjs.map +1 -0
  318. package/dist/src/modules/utils/applySorting.d.cts +13 -0
  319. package/dist/src/modules/utils/getConditionsFromFilters.cjs +152 -0
  320. package/dist/src/modules/utils/getConditionsFromFilters.cjs.map +1 -0
  321. package/dist/src/modules/utils/getConditionsFromFilters.d.cts +9 -0
  322. package/dist/src/modules/utils/getGlobalSearchCondition.cjs +30 -0
  323. package/dist/src/modules/utils/getGlobalSearchCondition.cjs.map +1 -0
  324. package/dist/src/modules/utils/getGlobalSearchCondition.d.cts +18 -0
  325. package/dist/src/modules/utils/getGlobalSearchCondition.d.mts +18 -0
  326. package/dist/src/modules/utils/getGlobalSearchCondition.mjs +26 -0
  327. package/dist/src/modules/utils/getGlobalSearchCondition.mjs.map +1 -0
  328. package/dist/src/modules/video/video.service.cjs +114 -0
  329. package/dist/src/modules/video/video.service.cjs.map +1 -0
  330. package/dist/src/modules/video/video.service.d.cts +12 -0
  331. package/dist/src/modules/video/video.service.mjs.map +1 -1
  332. package/dist/src/modules/webhook/webhook.constants.cjs +13 -0
  333. package/dist/src/modules/webhook/webhook.constants.cjs.map +1 -0
  334. package/dist/src/modules/webhook/webhook.constants.d.cts +12 -0
  335. package/dist/src/modules/webhook/webhook.db.cjs +19 -0
  336. package/dist/src/modules/webhook/webhook.db.cjs.map +1 -0
  337. package/dist/src/modules/webhook/webhook.db.d.cts +142 -0
  338. package/dist/src/modules/webhook/webhook.dto.cjs +11 -0
  339. package/dist/src/modules/webhook/webhook.dto.cjs.map +1 -0
  340. package/dist/src/modules/webhook/webhook.dto.d.cts +402 -0
  341. package/dist/src/modules/webhook/webhook.repository.cjs +52 -0
  342. package/dist/src/modules/webhook/webhook.repository.cjs.map +1 -0
  343. package/dist/src/modules/webhook/webhook.repository.d.cts +154 -0
  344. package/dist/src/modules/webhook/webhook.router.cjs +26 -0
  345. package/dist/src/modules/webhook/webhook.router.cjs.map +1 -0
  346. package/dist/src/modules/webhook/webhook.router.d.cts +8 -0
  347. package/dist/src/modules/webhook/webhook.service.cjs +61 -0
  348. package/dist/src/modules/webhook/webhook.service.cjs.map +1 -0
  349. package/dist/src/modules/webhook/webhook.service.d.cts +14 -0
  350. package/dist/src/modules/workflow/workflow.db.cjs +35 -0
  351. package/dist/src/modules/workflow/workflow.db.cjs.map +1 -0
  352. package/dist/src/modules/workflow/workflow.db.d.cts +302 -0
  353. package/dist/src/modules/workflow/workflow.repository.cjs +95 -0
  354. package/dist/src/modules/workflow/workflow.repository.cjs.map +1 -0
  355. package/dist/src/modules/workflow/workflow.repository.d.cts +371 -0
  356. package/dist/src/modules/workflow/workflow.service.cjs +41 -0
  357. package/dist/src/modules/workflow/workflow.service.cjs.map +1 -0
  358. package/dist/src/modules/workflow/workflow.service.d.cts +68 -0
  359. package/dist/src/modules/workflow/workflow.trpc.cjs +19 -0
  360. package/dist/src/modules/workflow/workflow.trpc.cjs.map +1 -0
  361. package/dist/src/modules/workflow/workflow.trpc.d.cts +65 -0
  362. package/dist/src/modules/workflow/workflow.types.cjs +0 -0
  363. package/dist/src/modules/workflow/workflow.types.d.cts +25 -0
  364. package/dist/src/modules/workflow/workflow.utils.cjs +185 -0
  365. package/dist/src/modules/workflow/workflow.utils.cjs.map +1 -0
  366. package/dist/src/modules/workflow/workflow.utils.d.cts +36 -0
  367. package/dist/src/types.cjs +12 -0
  368. package/dist/src/types.cjs.map +1 -0
  369. package/dist/src/types.d.cts +344 -0
  370. package/dist/src/types.d.mts +6 -6
  371. package/dist/src/utils/errors.cjs +101 -0
  372. package/dist/src/utils/errors.cjs.map +1 -0
  373. package/dist/src/utils/errors.d.cts +62 -0
  374. package/dist/src/utils/logger.cjs +13 -0
  375. package/dist/src/utils/logger.cjs.map +1 -0
  376. package/dist/src/utils/logger.d.cts +7 -0
  377. package/dist/src/utils/posthog.cjs +31 -0
  378. package/dist/src/utils/posthog.cjs.map +1 -0
  379. package/dist/src/utils/posthog.d.cts +17 -0
  380. package/dist/src/utils/trpc.cjs +156 -0
  381. package/dist/src/utils/trpc.cjs.map +1 -0
  382. package/dist/src/utils/trpc.d.cts +54 -0
  383. package/dist/src/utils/types.cjs +0 -0
  384. package/dist/src/utils/types.d.cts +9 -0
  385. package/package.json +171 -45
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.service.cjs","names":["bip32","ecc","BaseService","bitcoin"],"sources":["../../../../src/modules/crypto/crypto.service.ts"],"sourcesContent":["import BIP32Factory from \"bip32\";\r\nimport * as bip39 from \"bip39\";\r\nimport * as bitcoin from \"bitcoinjs-lib\";\r\nimport * as ecc from \"tiny-secp256k1\";\r\nimport { ok } from \"neverthrow\";\r\nimport { BaseService } from \"../base/base.service\";\r\nimport type { ServerResult } from \"../base/base.dto\";\r\nimport type { CryptoRepository } from \"./crypto.repository\";\r\nimport type { BIP32Interface } from \"bip32\";\r\n\r\nconst BITCOIN_NATIVE_SEGWIT_PATH = \"m/84'/0'/0'/0\";\r\n\r\nconst bip32 = BIP32Factory(ecc);\r\n\r\nexport class CryptoService extends BaseService<\r\n { crypto: CryptoRepository },\r\n Record<string, never>\r\n> {\r\n private root: BIP32Interface | null = null;\r\n\r\n private getRoot(): BIP32Interface {\r\n if (this.root) return this.root;\r\n const seed = process.env.BITCOIN_SEED;\r\n if (!seed?.trim()) {\r\n throw new Error(\"BITCOIN_SEED environment variable is not set\");\r\n }\r\n if (!bip39.validateMnemonic(seed.trim())) {\r\n throw new Error(\"BITCOIN_SEED is not a valid BIP39 mnemonic\");\r\n }\r\n const seedBuffer = bip39.mnemonicToSeedSync(seed.trim());\r\n this.root = bip32.fromSeed(seedBuffer);\r\n return this.root;\r\n }\r\n\r\n createBitcoinAddress(derivationIndex: number): ServerResult<string> {\r\n return this.throwable(() => {\r\n if (derivationIndex < 0 || !Number.isInteger(derivationIndex)) {\r\n return this.error(\"BAD_REQUEST\", \"derivationIndex must be a non-negative integer\");\r\n }\r\n const root = this.getRoot();\r\n const path = `${BITCOIN_NATIVE_SEGWIT_PATH}/${derivationIndex}`;\r\n const child = root.derivePath(path);\r\n if (!child.publicKey) {\r\n return this.error(\"INTERNAL_SERVER_ERROR\", \"Failed to derive public key\");\r\n }\r\n const payment = bitcoin.payments.p2wpkh({\r\n pubkey: child.publicKey,\r\n network: bitcoin.networks.bitcoin,\r\n });\r\n const address = payment.address;\r\n if (!address) {\r\n return this.error(\"INTERNAL_SERVER_ERROR\", \"Failed to generate address\");\r\n }\r\n return ok(address);\r\n });\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;AAUA,MAAM,6BAA6B;AAEnC,MAAMA,WAAAA,GAAAA,MAAAA,SAAqBC,eAAI;AAE/B,IAAa,gBAAb,cAAmCC,sCAAAA,YAGjC;CACA,OAAsC;CAEtC,UAAkC;AAChC,MAAI,KAAK,KAAM,QAAO,KAAK;EAC3B,MAAM,OAAO,QAAQ,IAAI;AACzB,MAAI,CAAC,MAAM,MAAM,CACf,OAAM,IAAI,MAAM,+CAA+C;AAEjE,MAAI,CAAC,MAAM,iBAAiB,KAAK,MAAM,CAAC,CACtC,OAAM,IAAI,MAAM,6CAA6C;EAE/D,MAAM,aAAa,MAAM,mBAAmB,KAAK,MAAM,CAAC;AACxD,OAAK,OAAOF,QAAM,SAAS,WAAW;AACtC,SAAO,KAAK;;CAGd,qBAAqB,iBAA+C;AAClE,SAAO,KAAK,gBAAgB;AAC1B,OAAI,kBAAkB,KAAK,CAAC,OAAO,UAAU,gBAAgB,CAC3D,QAAO,KAAK,MAAM,eAAe,iDAAiD;GAEpF,MAAM,OAAO,KAAK,SAAS;GAC3B,MAAM,OAAO,GAAG,2BAA2B,GAAG;GAC9C,MAAM,QAAQ,KAAK,WAAW,KAAK;AACnC,OAAI,CAAC,MAAM,UACT,QAAO,KAAK,MAAM,yBAAyB,8BAA8B;GAM3E,MAAM,UAJUG,cAAQ,SAAS,OAAO;IACtC,QAAQ,MAAM;IACd,SAASA,cAAQ,SAAS;IAC3B,CAAC,CACsB;AACxB,OAAI,CAAC,QACH,QAAO,KAAK,MAAM,yBAAyB,6BAA6B;AAE1E,WAAA,GAAA,WAAA,IAAU,QAAQ;IAClB"}
@@ -0,0 +1,15 @@
1
+ import { ServerResult } from "../base/base.dto.cjs";
2
+ import { BaseService } from "../base/base.service.cjs";
3
+ import { CryptoRepository } from "./crypto.repository.cjs";
4
+
5
+ //#region src/modules/crypto/crypto.service.d.ts
6
+ declare class CryptoService extends BaseService<{
7
+ crypto: CryptoRepository;
8
+ }, Record<string, never>> {
9
+ private root;
10
+ private getRoot;
11
+ createBitcoinAddress(derivationIndex: number): ServerResult<string>;
12
+ }
13
+ //#endregion
14
+ export { CryptoService };
15
+ //# sourceMappingURL=crypto.service.d.cts.map
@@ -0,0 +1,107 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../../_virtual/_rolldown/runtime.cjs");
3
+ const require_src_modules_base_base_service = require("../base/base.service.cjs");
4
+ let neverthrow = require("neverthrow");
5
+ let react = require("react");
6
+ let resend = require("resend");
7
+ //#region src/modules/email/email.service.ts
8
+ var EmailService = class extends require_src_modules_base_base_service.BaseService {
9
+ client;
10
+ brand;
11
+ noReplyFrom;
12
+ templates;
13
+ systemNotificationEmail;
14
+ constructor(props) {
15
+ super(void 0, void 0);
16
+ this.client = new resend.Resend(props.resendApiKey || process.env.RESEND_API_KEY);
17
+ this.brand = props.brand;
18
+ this.noReplyFrom = props.noReplyFrom;
19
+ this.templates = props.templates;
20
+ this.systemNotificationEmail = props.systemNotificationEmail;
21
+ }
22
+ async sendTemplate(to, templateKey, templateProps, options) {
23
+ const template = this.templates[templateKey];
24
+ if (!template) return this.error("NOT_FOUND", `Email template not found: ${String(templateKey)}`);
25
+ const from = options?.from || this.noReplyFrom;
26
+ const subject = options?.subject || template.subject || String(templateKey);
27
+ const previewText = options?.previewText || template.previewText || subject;
28
+ const { error } = await this.client.emails.send({
29
+ to,
30
+ subject,
31
+ from,
32
+ react: (0, react.createElement)(template.react, {
33
+ ...templateProps,
34
+ previewText
35
+ })
36
+ });
37
+ if (error) return this.error("INTERNAL_SERVER_ERROR", `Failed to send email: ${templateKey}`, { cause: error });
38
+ return (0, neverthrow.ok)();
39
+ }
40
+ async sendBrandTemplate(to, templateKey, templateProps, options) {
41
+ return this.sendTemplate(to, templateKey, {
42
+ brand: this.brand,
43
+ ...templateProps
44
+ }, options);
45
+ }
46
+ async sendWaitlistConfirmation(email, overrideOptions) {
47
+ return this.sendTemplate(email, "waitlistConfirmation", {
48
+ email,
49
+ brand: this.brand
50
+ }, overrideOptions);
51
+ }
52
+ async sendWaitlistInvite(email, code, overrideOptions) {
53
+ const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;
54
+ return this.sendTemplate(email, "waitlistInvite", {
55
+ url,
56
+ brand: this.brand
57
+ }, overrideOptions);
58
+ }
59
+ async sendWaitlistUserInvite(email, code, inviter, name, overrideOptions) {
60
+ const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;
61
+ return this.sendTemplate(email, "waitlistUserInvite", {
62
+ url,
63
+ brand: this.brand,
64
+ inviter,
65
+ name
66
+ }, {
67
+ previewText: `Create your ${this.brand.name} account today!`,
68
+ subject: `${inviter} has invited you to join ${this.brand.name}!`,
69
+ ...overrideOptions
70
+ });
71
+ }
72
+ async sendOrganizationInvite(email, organizationName, inviterName, role, url, overrideOptions) {
73
+ return this.sendTemplate(email, "organizationInvite", {
74
+ url,
75
+ brand: this.brand,
76
+ organizationName,
77
+ inviterName,
78
+ role
79
+ }, {
80
+ previewText: `${inviterName} invited you to ${organizationName}`,
81
+ subject: `${inviterName} invited you to join ${organizationName}`,
82
+ ...overrideOptions
83
+ });
84
+ }
85
+ async sendVerification(email, url, overrideOptions) {
86
+ return this.sendTemplate(email, "verification", {
87
+ url,
88
+ brand: this.brand
89
+ }, overrideOptions);
90
+ }
91
+ async sendResetPassword(email, url, overrideOptions) {
92
+ return this.sendTemplate(email, "passwordReset", {
93
+ url,
94
+ brand: this.brand
95
+ }, overrideOptions);
96
+ }
97
+ async sendDeleteAccountVerification(email, url, overrideOptions) {
98
+ return this.sendTemplate(email, "accountDeletion", {
99
+ url,
100
+ brand: this.brand
101
+ }, overrideOptions);
102
+ }
103
+ };
104
+ //#endregion
105
+ exports.EmailService = EmailService;
106
+
107
+ //# sourceMappingURL=email.service.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.service.cjs","names":["BaseService","Resend"],"sources":["../../../../src/modules/email/email.service.ts"],"sourcesContent":["import { ok } from \"neverthrow\";\r\nimport { createElement, type FunctionComponent } from \"react\";\r\nimport { Resend } from \"resend\";\r\nimport { BaseService } from \"../base/base.service\";\r\n\r\ntype Brand = {\r\n name: string;\r\n logo: string;\r\n tagline: string;\r\n};\r\n\r\ntype OverrideOptions = {\r\n from?: string;\r\n subject?: string;\r\n previewText?: string;\r\n};\r\n\r\ntype EmailTemplate = {\r\n id: string;\r\n subject?: string;\r\n previewText?: string;\r\n from?: string;\r\n react: FunctionComponent<Record<string, unknown>>;\r\n};\r\n\r\ntype EmailTemplates = {\r\n accountDeletion: EmailTemplate;\r\n verification: EmailTemplate;\r\n waitlistConfirmation: EmailTemplate;\r\n passwordReset: EmailTemplate;\r\n systemWaitlistNotification: EmailTemplate;\r\n waitlistInvite: EmailTemplate;\r\n waitlistUserInvite: EmailTemplate;\r\n organizationInvite: EmailTemplate;\r\n [key: string]: EmailTemplate;\r\n};\r\n\r\ntype EmailServiceProps = {\r\n resendApiKey?: string;\r\n brand: Brand;\r\n noReplyFrom: string;\r\n systemNotificationEmail: string;\r\n templates: EmailTemplates;\r\n};\r\n\r\nexport class EmailService extends BaseService<never, never> {\r\n public client: Resend;\r\n public brand: Brand;\r\n public noReplyFrom: string;\r\n public templates: EmailTemplates;\r\n public systemNotificationEmail: string;\r\n\r\n constructor(props: EmailServiceProps) {\r\n super(undefined, undefined);\r\n this.client = new Resend(props.resendApiKey || process.env.RESEND_API_KEY);\r\n this.brand = props.brand;\r\n this.noReplyFrom = props.noReplyFrom;\r\n this.templates = props.templates;\r\n this.systemNotificationEmail = props.systemNotificationEmail;\r\n }\r\n\r\n async sendTemplate(\r\n to: string | string[],\r\n templateKey: keyof EmailTemplates,\r\n templateProps: Record<string, unknown>,\r\n options?: OverrideOptions\r\n ) {\r\n const template = this.templates[templateKey];\r\n if (!template) {\r\n return this.error(\"NOT_FOUND\", `Email template not found: ${String(templateKey)}`);\r\n }\r\n const from = options?.from || this.noReplyFrom;\r\n const subject = options?.subject || template.subject || String(templateKey);\r\n const previewText = options?.previewText || template.previewText || subject;\r\n\r\n const { error } = await this.client.emails.send({\r\n to,\r\n subject,\r\n from,\r\n react: createElement(template.react, { ...templateProps, previewText }),\r\n });\r\n if (error)\r\n return this.error(\"INTERNAL_SERVER_ERROR\", `Failed to send email: ${templateKey}`, {\r\n cause: error,\r\n });\r\n return ok();\r\n }\r\n\r\n async sendBrandTemplate(\r\n to: string | string[],\r\n templateKey: keyof EmailTemplates,\r\n templateProps: Record<string, unknown>,\r\n options?: OverrideOptions\r\n ) {\r\n return this.sendTemplate(\r\n to,\r\n templateKey,\r\n {\r\n brand: this.brand,\r\n ...templateProps,\r\n },\r\n options\r\n );\r\n }\r\n\r\n async sendWaitlistConfirmation(email: string, overrideOptions?: OverrideOptions) {\r\n return this.sendTemplate(\r\n email,\r\n \"waitlistConfirmation\",\r\n {\r\n email,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n\r\n async sendWaitlistInvite(email: string, code: string, overrideOptions?: OverrideOptions) {\r\n const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;\r\n return this.sendTemplate(\r\n email,\r\n \"waitlistInvite\",\r\n {\r\n url,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n\r\n async sendWaitlistUserInvite(\r\n email: string,\r\n code: string,\r\n inviter: string,\r\n name?: string,\r\n overrideOptions?: OverrideOptions\r\n ) {\r\n const url = `${process.env.VITE_APP_URL}/signup?code=${code}&email=${email}`;\r\n return this.sendTemplate(\r\n email,\r\n \"waitlistUserInvite\",\r\n {\r\n url,\r\n brand: this.brand,\r\n inviter,\r\n name,\r\n },\r\n {\r\n previewText: `Create your ${this.brand.name} account today!`,\r\n subject: `${inviter} has invited you to join ${this.brand.name}!`,\r\n ...overrideOptions,\r\n }\r\n );\r\n }\r\n\r\n async sendOrganizationInvite(\r\n email: string,\r\n organizationName: string,\r\n inviterName: string,\r\n role: string,\r\n url: string,\r\n overrideOptions?: OverrideOptions\r\n ) {\r\n return this.sendTemplate(\r\n email,\r\n \"organizationInvite\",\r\n {\r\n url,\r\n brand: this.brand,\r\n organizationName,\r\n inviterName,\r\n role,\r\n },\r\n {\r\n previewText: `${inviterName} invited you to ${organizationName}`,\r\n subject: `${inviterName} invited you to join ${organizationName}`,\r\n ...overrideOptions,\r\n }\r\n );\r\n }\r\n\r\n async sendVerification(email: string, url: string, overrideOptions?: OverrideOptions) {\r\n return this.sendTemplate(\r\n email,\r\n \"verification\",\r\n {\r\n url,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n\r\n async sendResetPassword(email: string, url: string, overrideOptions?: OverrideOptions) {\r\n return this.sendTemplate(\r\n email,\r\n \"passwordReset\",\r\n {\r\n url,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n\r\n async sendDeleteAccountVerification(\r\n email: string,\r\n url: string,\r\n overrideOptions?: OverrideOptions\r\n ) {\r\n return this.sendTemplate(\r\n email,\r\n \"accountDeletion\",\r\n {\r\n url,\r\n brand: this.brand,\r\n },\r\n overrideOptions\r\n );\r\n }\r\n}\r\n"],"mappings":";;;;;;;AA6CA,IAAa,eAAb,cAAkCA,sCAAAA,YAA0B;CAC1D;CACA;CACA;CACA;CACA;CAEA,YAAY,OAA0B;AACpC,QAAM,KAAA,GAAW,KAAA,EAAU;AAC3B,OAAK,SAAS,IAAIC,OAAAA,OAAO,MAAM,gBAAgB,QAAQ,IAAI,eAAe;AAC1E,OAAK,QAAQ,MAAM;AACnB,OAAK,cAAc,MAAM;AACzB,OAAK,YAAY,MAAM;AACvB,OAAK,0BAA0B,MAAM;;CAGvC,MAAM,aACJ,IACA,aACA,eACA,SACA;EACA,MAAM,WAAW,KAAK,UAAU;AAChC,MAAI,CAAC,SACH,QAAO,KAAK,MAAM,aAAa,6BAA6B,OAAO,YAAY,GAAG;EAEpF,MAAM,OAAO,SAAS,QAAQ,KAAK;EACnC,MAAM,UAAU,SAAS,WAAW,SAAS,WAAW,OAAO,YAAY;EAC3E,MAAM,cAAc,SAAS,eAAe,SAAS,eAAe;EAEpE,MAAM,EAAE,UAAU,MAAM,KAAK,OAAO,OAAO,KAAK;GAC9C;GACA;GACA;GACA,QAAA,GAAA,MAAA,eAAqB,SAAS,OAAO;IAAE,GAAG;IAAe;IAAa,CAAC;GACxE,CAAC;AACF,MAAI,MACF,QAAO,KAAK,MAAM,yBAAyB,yBAAyB,eAAe,EACjF,OAAO,OACR,CAAC;AACJ,UAAA,GAAA,WAAA,KAAW;;CAGb,MAAM,kBACJ,IACA,aACA,eACA,SACA;AACA,SAAO,KAAK,aACV,IACA,aACA;GACE,OAAO,KAAK;GACZ,GAAG;GACJ,EACD,QACD;;CAGH,MAAM,yBAAyB,OAAe,iBAAmC;AAC/E,SAAO,KAAK,aACV,OACA,wBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD;;CAGH,MAAM,mBAAmB,OAAe,MAAc,iBAAmC;EACvF,MAAM,MAAM,GAAG,QAAQ,IAAI,aAAa,eAAe,KAAK,SAAS;AACrE,SAAO,KAAK,aACV,OACA,kBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD;;CAGH,MAAM,uBACJ,OACA,MACA,SACA,MACA,iBACA;EACA,MAAM,MAAM,GAAG,QAAQ,IAAI,aAAa,eAAe,KAAK,SAAS;AACrE,SAAO,KAAK,aACV,OACA,sBACA;GACE;GACA,OAAO,KAAK;GACZ;GACA;GACD,EACD;GACE,aAAa,eAAe,KAAK,MAAM,KAAK;GAC5C,SAAS,GAAG,QAAQ,2BAA2B,KAAK,MAAM,KAAK;GAC/D,GAAG;GACJ,CACF;;CAGH,MAAM,uBACJ,OACA,kBACA,aACA,MACA,KACA,iBACA;AACA,SAAO,KAAK,aACV,OACA,sBACA;GACE;GACA,OAAO,KAAK;GACZ;GACA;GACA;GACD,EACD;GACE,aAAa,GAAG,YAAY,kBAAkB;GAC9C,SAAS,GAAG,YAAY,uBAAuB;GAC/C,GAAG;GACJ,CACF;;CAGH,MAAM,iBAAiB,OAAe,KAAa,iBAAmC;AACpF,SAAO,KAAK,aACV,OACA,gBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD;;CAGH,MAAM,kBAAkB,OAAe,KAAa,iBAAmC;AACrF,SAAO,KAAK,aACV,OACA,iBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD;;CAGH,MAAM,8BACJ,OACA,KACA,iBACA;AACA,SAAO,KAAK,aACV,OACA,mBACA;GACE;GACA,OAAO,KAAK;GACb,EACD,gBACD"}
@@ -0,0 +1,62 @@
1
+ import { ServerError } from "../../utils/errors.cjs";
2
+ import { BaseService } from "../base/base.service.cjs";
3
+ import * as _$neverthrow from "neverthrow";
4
+ import { FunctionComponent } from "react";
5
+ import { Resend } from "resend";
6
+
7
+ //#region src/modules/email/email.service.d.ts
8
+ type Brand = {
9
+ name: string;
10
+ logo: string;
11
+ tagline: string;
12
+ };
13
+ type OverrideOptions = {
14
+ from?: string;
15
+ subject?: string;
16
+ previewText?: string;
17
+ };
18
+ type EmailTemplate = {
19
+ id: string;
20
+ subject?: string;
21
+ previewText?: string;
22
+ from?: string;
23
+ react: FunctionComponent<Record<string, unknown>>;
24
+ };
25
+ type EmailTemplates = {
26
+ accountDeletion: EmailTemplate;
27
+ verification: EmailTemplate;
28
+ waitlistConfirmation: EmailTemplate;
29
+ passwordReset: EmailTemplate;
30
+ systemWaitlistNotification: EmailTemplate;
31
+ waitlistInvite: EmailTemplate;
32
+ waitlistUserInvite: EmailTemplate;
33
+ organizationInvite: EmailTemplate;
34
+ [key: string]: EmailTemplate;
35
+ };
36
+ type EmailServiceProps = {
37
+ resendApiKey?: string;
38
+ brand: Brand;
39
+ noReplyFrom: string;
40
+ systemNotificationEmail: string;
41
+ templates: EmailTemplates;
42
+ };
43
+ declare class EmailService extends BaseService<never, never> {
44
+ client: Resend;
45
+ brand: Brand;
46
+ noReplyFrom: string;
47
+ templates: EmailTemplates;
48
+ systemNotificationEmail: string;
49
+ constructor(props: EmailServiceProps);
50
+ sendTemplate(to: string | string[], templateKey: keyof EmailTemplates, templateProps: Record<string, unknown>, options?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
51
+ sendBrandTemplate(to: string | string[], templateKey: keyof EmailTemplates, templateProps: Record<string, unknown>, options?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
52
+ sendWaitlistConfirmation(email: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
53
+ sendWaitlistInvite(email: string, code: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
54
+ sendWaitlistUserInvite(email: string, code: string, inviter: string, name?: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
55
+ sendOrganizationInvite(email: string, organizationName: string, inviterName: string, role: string, url: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
56
+ sendVerification(email: string, url: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
57
+ sendResetPassword(email: string, url: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
58
+ sendDeleteAccountVerification(email: string, url: string, overrideOptions?: OverrideOptions): Promise<_$neverthrow.Err<never, ServerError> | _$neverthrow.Ok<void, never>>;
59
+ }
60
+ //#endregion
61
+ export { EmailService };
62
+ //# sourceMappingURL=email.service.d.cts.map
@@ -0,0 +1,74 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../../_virtual/_rolldown/runtime.cjs");
3
+ const require_src_modules_base_base_repository = require("../base/base.repository.cjs");
4
+ let neverthrow = require("neverthrow");
5
+ let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
6
+ let _aws_sdk_s3_request_presigner = require("@aws-sdk/s3-request-presigner");
7
+ //#region src/modules/file/file.repository.ts
8
+ var FileRepository = class extends require_src_modules_base_base_repository.BaseExternaRepository {
9
+ s3;
10
+ constructor() {
11
+ super();
12
+ if (!process.env.AWS_REGION || !process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) throw new Error("Missing AWS environment variables");
13
+ this.s3 = new _aws_sdk_client_s3.S3Client({
14
+ region: process.env.AWS_REGION,
15
+ credentials: {
16
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
17
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
18
+ },
19
+ ...process.env.AWS_S3_ENDPOINT ? { endpoint: process.env.AWS_S3_ENDPOINT } : {},
20
+ forcePathStyle: !!process.env.AWS_S3_ENDPOINT
21
+ });
22
+ }
23
+ async getS3UploadUrl(filename, filetype, expiresIn = 300) {
24
+ return this.throwableAsync(async () => {
25
+ const command = new _aws_sdk_client_s3.PutObjectCommand({
26
+ Bucket: process.env.AWS_S3_BUCKET,
27
+ Key: filename,
28
+ ContentType: filetype
29
+ });
30
+ return (0, neverthrow.ok)(await (0, _aws_sdk_s3_request_presigner.getSignedUrl)(this.s3, command, { expiresIn }));
31
+ });
32
+ }
33
+ async getS3DownloadUrl(path, expiresIn = 300) {
34
+ return this.throwableAsync(async () => {
35
+ const command = new _aws_sdk_client_s3.GetObjectCommand({
36
+ Bucket: process.env.AWS_S3_BUCKET,
37
+ Key: path
38
+ });
39
+ return (0, neverthrow.ok)(await (0, _aws_sdk_s3_request_presigner.getSignedUrl)(this.s3, command, { expiresIn }));
40
+ });
41
+ }
42
+ async getS3Object(path) {
43
+ return this.throwableAsync(async () => {
44
+ const command = new _aws_sdk_client_s3.GetObjectCommand({
45
+ Bucket: process.env.AWS_S3_BUCKET,
46
+ Key: path
47
+ });
48
+ return (0, neverthrow.ok)(await this.s3.send(command));
49
+ });
50
+ }
51
+ async getS3ObjectT(path) {
52
+ return this.throwableAsync(async () => {
53
+ const command = new _aws_sdk_client_s3.GetObjectCommand({
54
+ Bucket: process.env.AWS_S3_BUCKET,
55
+ Key: path
56
+ });
57
+ return (0, neverthrow.ok)(await this.s3.send(command));
58
+ });
59
+ }
60
+ async deleteS3Object(path) {
61
+ return this.throwableAsync(async () => {
62
+ const command = new _aws_sdk_client_s3.DeleteObjectCommand({
63
+ Bucket: process.env.AWS_S3_BUCKET,
64
+ Key: path
65
+ });
66
+ await this.s3.send(command);
67
+ return (0, neverthrow.ok)(void 0);
68
+ });
69
+ }
70
+ };
71
+ //#endregion
72
+ exports.FileRepository = FileRepository;
73
+
74
+ //# sourceMappingURL=file.repository.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.repository.cjs","names":["BaseExternaRepository","S3Client","PutObjectCommand","GetObjectCommand","DeleteObjectCommand"],"sources":["../../../../src/modules/file/file.repository.ts"],"sourcesContent":["import {\r\n DeleteObjectCommand,\r\n GetObjectCommand,\r\n type GetObjectCommandOutput,\r\n PutObjectCommand,\r\n S3Client,\r\n} from \"@aws-sdk/client-s3\";\r\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\r\nimport { ok } from \"neverthrow\";\r\nimport type { ServerResultAsync } from \"../base/base.dto\";\r\nimport { BaseExternaRepository } from \"../base/base.repository\";\r\n\r\nexport class FileRepository extends BaseExternaRepository {\r\n private readonly s3: S3Client;\r\n constructor() {\r\n super();\r\n\r\n if (\r\n !process.env.AWS_REGION ||\r\n !process.env.AWS_ACCESS_KEY_ID ||\r\n !process.env.AWS_SECRET_ACCESS_KEY\r\n ) {\r\n throw new Error(\"Missing AWS environment variables\");\r\n }\r\n\r\n this.s3 = new S3Client({\r\n region: process.env.AWS_REGION,\r\n credentials: {\r\n accessKeyId: process.env.AWS_ACCESS_KEY_ID,\r\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\r\n },\r\n ...(process.env.AWS_S3_ENDPOINT ? { endpoint: process.env.AWS_S3_ENDPOINT } : {}),\r\n forcePathStyle: !!process.env.AWS_S3_ENDPOINT, // Path style is often required for non-AWS S3 providers\r\n });\r\n }\r\n async getS3UploadUrl(\r\n filename: string,\r\n filetype: string,\r\n expiresIn = 60 * 5\r\n ): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const command = new PutObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: filename,\r\n ContentType: filetype,\r\n });\r\n const url = await getSignedUrl(this.s3, command, { expiresIn });\r\n return ok(url);\r\n });\r\n }\r\n\r\n async getS3DownloadUrl(path: string, expiresIn = 60 * 5): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const command = new GetObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: path,\r\n });\r\n const url = await getSignedUrl(this.s3, command, { expiresIn });\r\n return ok(url);\r\n });\r\n }\r\n\r\n async getS3Object(path: string): ServerResultAsync<GetObjectCommandOutput> {\r\n return this.throwableAsync(async () => {\r\n const command = new GetObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: path,\r\n });\r\n const data = await this.s3.send(command);\r\n return ok(data);\r\n });\r\n }\r\n\r\n async getS3ObjectT(path: string): ServerResultAsync<GetObjectCommandOutput> {\r\n return this.throwableAsync(async () => {\r\n const command = new GetObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: path,\r\n });\r\n const data = await this.s3.send(command);\r\n return ok(data);\r\n });\r\n }\r\n\r\n async deleteS3Object(path: string): ServerResultAsync<void> {\r\n return this.throwableAsync(async () => {\r\n const command = new DeleteObjectCommand({\r\n Bucket: process.env.AWS_S3_BUCKET,\r\n Key: path,\r\n });\r\n await this.s3.send(command);\r\n return ok(undefined);\r\n });\r\n }\r\n}\r\n"],"mappings":";;;;;;;AAYA,IAAa,iBAAb,cAAoCA,yCAAAA,sBAAsB;CACxD;CACA,cAAc;AACZ,SAAO;AAEP,MACE,CAAC,QAAQ,IAAI,cACb,CAAC,QAAQ,IAAI,qBACb,CAAC,QAAQ,IAAI,sBAEb,OAAM,IAAI,MAAM,oCAAoC;AAGtD,OAAK,KAAK,IAAIC,mBAAAA,SAAS;GACrB,QAAQ,QAAQ,IAAI;GACpB,aAAa;IACX,aAAa,QAAQ,IAAI;IACzB,iBAAiB,QAAQ,IAAI;IAC9B;GACD,GAAI,QAAQ,IAAI,kBAAkB,EAAE,UAAU,QAAQ,IAAI,iBAAiB,GAAG,EAAE;GAChF,gBAAgB,CAAC,CAAC,QAAQ,IAAI;GAC/B,CAAC;;CAEJ,MAAM,eACJ,UACA,UACA,YAAY,KACe;AAC3B,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIC,mBAAAA,iBAAiB;IACnC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACL,aAAa;IACd,CAAC;AAEF,WAAA,GAAA,WAAA,IADY,OAAA,GAAA,8BAAA,cAAmB,KAAK,IAAI,SAAS,EAAE,WAAW,CAAC,CACjD;IACd;;CAGJ,MAAM,iBAAiB,MAAc,YAAY,KAAmC;AAClF,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIC,mBAAAA,iBAAiB;IACnC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACN,CAAC;AAEF,WAAA,GAAA,WAAA,IADY,OAAA,GAAA,8BAAA,cAAmB,KAAK,IAAI,SAAS,EAAE,WAAW,CAAC,CACjD;IACd;;CAGJ,MAAM,YAAY,MAAyD;AACzE,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIA,mBAAAA,iBAAiB;IACnC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACN,CAAC;AAEF,WAAA,GAAA,WAAA,IADa,MAAM,KAAK,GAAG,KAAK,QAAQ,CACzB;IACf;;CAGJ,MAAM,aAAa,MAAyD;AAC1E,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIA,mBAAAA,iBAAiB;IACnC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACN,CAAC;AAEF,WAAA,GAAA,WAAA,IADa,MAAM,KAAK,GAAG,KAAK,QAAQ,CACzB;IACf;;CAGJ,MAAM,eAAe,MAAuC;AAC1D,SAAO,KAAK,eAAe,YAAY;GACrC,MAAM,UAAU,IAAIC,mBAAAA,oBAAoB;IACtC,QAAQ,QAAQ,IAAI;IACpB,KAAK;IACN,CAAC;AACF,SAAM,KAAK,GAAG,KAAK,QAAQ;AAC3B,WAAA,GAAA,WAAA,IAAU,KAAA,EAAU;IACpB"}
@@ -0,0 +1,17 @@
1
+ import { ServerResultAsync } from "../base/base.dto.cjs";
2
+ import { BaseExternaRepository } from "../base/base.repository.cjs";
3
+ import { GetObjectCommandOutput } from "@aws-sdk/client-s3";
4
+
5
+ //#region src/modules/file/file.repository.d.ts
6
+ declare class FileRepository extends BaseExternaRepository {
7
+ private readonly s3;
8
+ constructor();
9
+ getS3UploadUrl(filename: string, filetype: string, expiresIn?: number): ServerResultAsync<string>;
10
+ getS3DownloadUrl(path: string, expiresIn?: number): ServerResultAsync<string>;
11
+ getS3Object(path: string): ServerResultAsync<GetObjectCommandOutput>;
12
+ getS3ObjectT(path: string): ServerResultAsync<GetObjectCommandOutput>;
13
+ deleteS3Object(path: string): ServerResultAsync<void>;
14
+ }
15
+ //#endregion
16
+ export { FileRepository };
17
+ //# sourceMappingURL=file.repository.d.cts.map
@@ -0,0 +1,94 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
3
+ const require_src_modules_file_file_repository = require("./file.repository.cjs");
4
+ const require_src_modules_file_file_service = require("./file.service.cjs");
5
+ let uuid = require("uuid");
6
+ let body_parser = require("body-parser");
7
+ body_parser = require_runtime.__toESM(body_parser);
8
+ let express = require("express");
9
+ express = require_runtime.__toESM(express);
10
+ let node_path = require("node:path");
11
+ node_path = require_runtime.__toESM(node_path);
12
+ let _m5kdev_commons_modules_file_file_constants = require("@m5kdev/commons/modules/file/file.constants");
13
+ let multer = require("multer");
14
+ multer = require_runtime.__toESM(multer);
15
+ //#region src/modules/file/file.router.ts
16
+ const fileService = new require_src_modules_file_file_service.FileService({ file: new require_src_modules_file_file_repository.FileRepository() });
17
+ function validateMimeType(type, file) {
18
+ return _m5kdev_commons_modules_file_file_constants.fileTypes[type]?.mimetypes.includes(file.mimetype);
19
+ }
20
+ function getFileExtension(file) {
21
+ return file.originalname.split(".").pop();
22
+ }
23
+ const storage = multer.default.diskStorage({
24
+ destination: (_req, _file, cb) => {
25
+ cb(null, node_path.default.join(__dirname, "..", "uploads"));
26
+ },
27
+ filename: (_req, file, cb) => {
28
+ cb(null, `${(0, uuid.v4)()}.${getFileExtension(file)}`);
29
+ }
30
+ });
31
+ const fileFilter = (req, file, cb) => {
32
+ const { type } = req.params;
33
+ if (type && validateMimeType(type, file)) cb(null, true);
34
+ else cb(/* @__PURE__ */ new Error("Invalid file type"));
35
+ };
36
+ const upload = (0, multer.default)({
37
+ storage,
38
+ fileFilter
39
+ });
40
+ const uploadRouter = express.default.Router();
41
+ uploadRouter.post("/file/:type", upload.single("file"), (req, res) => {
42
+ const { file } = req;
43
+ if (!file) return res.status(400).json({ error: "No file uploaded" });
44
+ return res.json({
45
+ url: `${process.env.VITE_SERVER_URL}/upload/file/${file.filename}`,
46
+ mimetype: file.mimetype,
47
+ size: file.size
48
+ });
49
+ });
50
+ uploadRouter.get("/file/:filename", (req, res) => {
51
+ res.sendFile(node_path.default.join(__dirname, "..", "uploads", req.params.filename));
52
+ });
53
+ uploadRouter.get("/files/:path", async (req, res) => {
54
+ try {
55
+ const url = await fileService.getS3DownloadUrl(req.params.path);
56
+ if (url.isErr()) {
57
+ console.error(url.error);
58
+ return res.status(500).json({ error: url.error.message });
59
+ }
60
+ return res.json({ url: url.value });
61
+ } catch (err) {
62
+ console.error(err);
63
+ return res.status(500).json({ error: err.message || "Failed to generate presigned URL" });
64
+ }
65
+ });
66
+ uploadRouter.post("/s3-presigned-url", body_parser.default.json(), async (req, res) => {
67
+ const { filename, filetype } = req.body;
68
+ if (!filename || !filetype) return res.status(400).json({ error: "Missing filename or filetype" });
69
+ try {
70
+ const url = await fileService.getS3UploadUrl(filename, filetype);
71
+ if (url.isErr()) return res.status(500).json({ error: url.error.message });
72
+ return res.json({ url: url.value });
73
+ } catch (err) {
74
+ console.error(err);
75
+ return res.status(500).json({ error: err.message || "Failed to generate presigned URL" });
76
+ }
77
+ });
78
+ uploadRouter.delete("/files/:path(*)", async (req, res) => {
79
+ try {
80
+ const result = await fileService.deleteS3Object(req.params.path);
81
+ if (result.isErr()) {
82
+ console.error(result.error);
83
+ return res.status(500).json({ error: result.error.message });
84
+ }
85
+ return res.json({ success: true });
86
+ } catch (err) {
87
+ console.error(err);
88
+ return res.status(500).json({ error: err.message || "Failed to delete S3 object" });
89
+ }
90
+ });
91
+ //#endregion
92
+ exports.uploadRouter = uploadRouter;
93
+
94
+ //# sourceMappingURL=file.router.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.router.cjs","names":["FileService","FileRepository","fileTypes","path","bodyParser"],"sources":["../../../../src/modules/file/file.router.ts"],"sourcesContent":["import path from \"node:path\";\r\nimport { fileTypes } from \"@m5kdev/commons/modules/file/file.constants\";\r\nimport bodyParser from \"body-parser\";\r\nimport express, { type Request, type Response } from \"express\";\r\nimport multer from \"multer\";\r\nimport { v4 as uuidv4 } from \"uuid\";\r\nimport { FileRepository } from \"./file.repository\";\r\nimport { FileService } from \"./file.service\";\r\n\r\nconst fileRepository = new FileRepository();\r\nconst fileService = new FileService({ file: fileRepository });\r\n\r\nfunction validateMimeType(type: string, file: Express.Multer.File): boolean {\r\n return fileTypes[type]?.mimetypes.includes(file.mimetype);\r\n}\r\n\r\nfunction getFileExtension(file: Express.Multer.File): string | undefined {\r\n return file.originalname.split(\".\").pop();\r\n}\r\n\r\nconst storage = multer.diskStorage({\r\n destination: (_req, _file, cb) => {\r\n cb(null, path.join(__dirname, \"..\", \"uploads\"));\r\n },\r\n filename: (_req, file, cb) => {\r\n cb(null, `${uuidv4()}.${getFileExtension(file)}`);\r\n },\r\n});\r\n\r\nconst fileFilter = (\r\n req: Request,\r\n file: Express.Multer.File,\r\n cb: multer.FileFilterCallback\r\n): void => {\r\n const { type } = req.params;\r\n if (type && validateMimeType(type, file)) {\r\n cb(null, true);\r\n } else {\r\n cb(new Error(\"Invalid file type\"));\r\n }\r\n};\r\n\r\nconst upload = multer({ storage, fileFilter });\r\nconst uploadRouter: express.Router = express.Router();\r\n\r\nuploadRouter.post(\"/file/:type\", upload.single(\"file\"), (req: Request, res: Response) => {\r\n const { file } = req;\r\n if (!file) {\r\n return res.status(400).json({ error: \"No file uploaded\" });\r\n }\r\n return res.json({\r\n url: `${process.env.VITE_SERVER_URL}/upload/file/${file.filename}`,\r\n mimetype: file.mimetype,\r\n size: file.size,\r\n });\r\n});\r\n\r\nuploadRouter.get(\"/file/:filename\", (req: Request, res: Response) => {\r\n res.sendFile(path.join(__dirname, \"..\", \"uploads\", req.params.filename!));\r\n});\r\n\r\nuploadRouter.get(\"/files/:path\", async (req: Request, res: Response) => {\r\n try {\r\n const url = await fileService.getS3DownloadUrl(req.params.path!);\r\n if (url.isErr()) {\r\n console.error(url.error);\r\n return res.status(500).json({ error: url.error.message });\r\n }\r\n return res.json({ url: url.value });\r\n } catch (err: any) {\r\n console.error(err);\r\n return res.status(500).json({ error: err.message || \"Failed to generate presigned URL\" });\r\n }\r\n});\r\n\r\nuploadRouter.post(\"/s3-presigned-url\", bodyParser.json(), async (req: Request, res: Response) => {\r\n const { filename, filetype } = req.body;\r\n\r\n if (!filename || !filetype) {\r\n return res.status(400).json({ error: \"Missing filename or filetype\" });\r\n }\r\n try {\r\n const url = await fileService.getS3UploadUrl(filename, filetype);\r\n if (url.isErr()) {\r\n return res.status(500).json({ error: url.error.message });\r\n }\r\n return res.json({ url: url.value });\r\n } catch (err: any) {\r\n console.error(err);\r\n return res.status(500).json({ error: err.message || \"Failed to generate presigned URL\" });\r\n }\r\n});\r\n\r\nuploadRouter.delete(\"/files/:path(*)\", async (req: Request, res: Response) => {\r\n try {\r\n const result = await fileService.deleteS3Object(req.params.path!);\r\n if (result.isErr()) {\r\n console.error(result.error);\r\n return res.status(500).json({ error: result.error.message });\r\n }\r\n return res.json({ success: true });\r\n } catch (err: any) {\r\n console.error(err);\r\n return res.status(500).json({ error: err.message || \"Failed to delete S3 object\" });\r\n }\r\n});\r\n\r\nexport { uploadRouter };\r\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import express from "express";
2
+
3
+ //#region src/modules/file/file.router.d.ts
4
+ declare const uploadRouter: express.Router;
5
+ //#endregion
6
+ export { uploadRouter };
7
+ //# sourceMappingURL=file.router.d.cts.map
@@ -0,0 +1,120 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
3
+ const require_src_modules_base_base_service = require("../base/base.service.cjs");
4
+ let neverthrow = require("neverthrow");
5
+ let uuid = require("uuid");
6
+ let node_path = require("node:path");
7
+ node_path = require_runtime.__toESM(node_path);
8
+ let _m5kdev_commons_modules_file_file_constants = require("@m5kdev/commons/modules/file/file.constants");
9
+ let node_fs = require("node:fs");
10
+ let node_fs_promises = require("node:fs/promises");
11
+ let node_os = require("node:os");
12
+ let node_stream = require("node:stream");
13
+ let node_stream_promises = require("node:stream/promises");
14
+ //#region src/modules/file/file.service.ts
15
+ var FileService = class extends require_src_modules_base_base_service.BaseService {
16
+ isS3Path(path) {
17
+ return path.startsWith("s3::");
18
+ }
19
+ parseS3Path(S3Path) {
20
+ if (!this.isS3Path(S3Path)) return this.error("BAD_REQUEST", "Invalid S3 path");
21
+ const [bucket, path] = S3Path.split("s3::")[1].split("//");
22
+ return (0, neverthrow.ok)({
23
+ bucket,
24
+ path
25
+ });
26
+ }
27
+ wrapS3Path(path, bucket) {
28
+ return `s3::${bucket}//${path}`;
29
+ }
30
+ getS3UploadUrl(filename, filetype, expiresIn = 300) {
31
+ return this.repository.file.getS3UploadUrl(filename, filetype, expiresIn);
32
+ }
33
+ getS3DownloadUrl(path, expiresIn = 300) {
34
+ return this.repository.file.getS3DownloadUrl(path, expiresIn);
35
+ }
36
+ getS3Object(path) {
37
+ return this.repository.file.getS3Object(path);
38
+ }
39
+ deleteS3Object(path) {
40
+ return this.repository.file.deleteS3Object(path);
41
+ }
42
+ async uploadFileToS3(localPath, returnDownloadUrl = false) {
43
+ return this.throwableAsync(async () => {
44
+ const extension = localPath.split(".").pop()?.toLowerCase();
45
+ const filename = `${(0, uuid.v4)()}${extension ? `.${extension}` : ""}`;
46
+ const filetype = extension && {
47
+ jpg: "image/jpeg",
48
+ jpeg: "image/jpeg",
49
+ png: "image/png",
50
+ webp: "image/webp",
51
+ mp4: "video/mp4",
52
+ mov: "video/mov",
53
+ avi: "video/avi",
54
+ mkv: "video/mkv",
55
+ webm: "video/webm",
56
+ mp3: "audio/mp3",
57
+ wav: "audio/wav",
58
+ m4a: "audio/m4a"
59
+ }[extension] || "application/octet-stream";
60
+ const presigned = await this.getS3UploadUrl(filename, filetype);
61
+ if (presigned.isErr()) return (0, neverthrow.err)(presigned.error);
62
+ const file = await (0, node_fs_promises.readFile)(localPath);
63
+ const res = await fetch(presigned.value, {
64
+ method: "PUT",
65
+ body: file,
66
+ headers: { "Content-Type": filetype }
67
+ });
68
+ if (!res.ok) return this.error("INTERNAL_SERVER_ERROR", `Failed to upload to S3: ${res.status}`);
69
+ if (returnDownloadUrl) {
70
+ const downloadUrl = await this.getS3DownloadUrl(filename);
71
+ if (downloadUrl.isErr()) return (0, neverthrow.err)(downloadUrl.error);
72
+ return (0, neverthrow.ok)(downloadUrl.value);
73
+ }
74
+ return (0, neverthrow.ok)(filename);
75
+ });
76
+ }
77
+ async downloadS3ToFile(s3Path) {
78
+ return this.throwableAsync(async () => {
79
+ const extension = s3Path.split(".").pop();
80
+ const destinationPath = node_path.default.join((0, node_os.tmpdir)(), "s3-downloads", `${(0, uuid.v4)()}${extension ? `.${extension}` : ""}`);
81
+ const result = await this.repository.file.getS3Object(s3Path);
82
+ if (result.isErr()) return (0, neverthrow.err)(result.error);
83
+ const body = result.value.Body;
84
+ if (!body) return this.error("NOT_FOUND", "S3 object body is empty");
85
+ await (0, node_fs_promises.mkdir)((0, node_path.dirname)(destinationPath), { recursive: true });
86
+ if (typeof body === "object" && "transformToByteArray" in body && typeof body.transformToByteArray === "function") {
87
+ await (0, node_fs_promises.writeFile)(destinationPath, await body.transformToByteArray());
88
+ return (0, neverthrow.ok)(destinationPath);
89
+ }
90
+ const writeStream = (0, node_fs.createWriteStream)(destinationPath);
91
+ let input = null;
92
+ const unknownBody = body;
93
+ if (typeof unknownBody === "object" && unknownBody !== null && "pipe" in unknownBody && typeof unknownBody.pipe === "function") input = unknownBody;
94
+ else if (typeof unknownBody === "object" && unknownBody !== null && "getReader" in unknownBody && typeof unknownBody.getReader === "function") input = node_stream.Readable.fromWeb(unknownBody);
95
+ else if (typeof unknownBody === "object" && unknownBody !== null && "stream" in unknownBody && typeof unknownBody.stream === "function") input = node_stream.Readable.fromWeb(unknownBody.stream());
96
+ if (input) {
97
+ await (0, node_stream_promises.pipeline)(input, writeStream);
98
+ return (0, neverthrow.ok)(destinationPath);
99
+ }
100
+ if (typeof unknownBody === "object" && unknownBody !== null && "arrayBuffer" in unknownBody && typeof unknownBody.arrayBuffer === "function") {
101
+ const buffer = Buffer.from(await unknownBody.arrayBuffer());
102
+ await (0, node_stream_promises.pipeline)(node_stream.Readable.from(buffer), writeStream);
103
+ return (0, neverthrow.ok)(destinationPath);
104
+ }
105
+ return this.error("INTERNAL_SERVER_ERROR", "Unsupported S3 body type");
106
+ });
107
+ }
108
+ getFileType(path) {
109
+ const extension = path.split(".").pop();
110
+ if (!extension) return void 0;
111
+ for (const [key, value] of Object.entries(_m5kdev_commons_modules_file_file_constants.fileTypes)) if (value.extensions.includes(extension)) return {
112
+ fileType: key,
113
+ extension
114
+ };
115
+ }
116
+ };
117
+ //#endregion
118
+ exports.FileService = FileService;
119
+
120
+ //# sourceMappingURL=file.service.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.service.cjs","names":["BaseService","path","Readable","fileTypes"],"sources":["../../../../src/modules/file/file.service.ts"],"sourcesContent":["import { createWriteStream } from \"node:fs\";\r\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\r\nimport { tmpdir } from \"node:os\";\r\nimport path, { dirname } from \"node:path\";\r\nimport { Readable } from \"node:stream\";\r\nimport { pipeline } from \"node:stream/promises\";\r\nimport { fileTypes } from \"@m5kdev/commons/modules/file/file.constants\";\r\nimport { err, ok } from \"neverthrow\";\r\nimport { v4 as uuidv4 } from \"uuid\";\r\nimport type { ServerResult, ServerResultAsync } from \"../base/base.dto\";\r\nimport { BaseService } from \"../base/base.service\";\r\nimport type { FileRepository } from \"./file.repository\";\r\n\r\nexport class FileService extends BaseService<{ file: FileRepository }, never> {\r\n isS3Path(path: string): boolean {\r\n return path.startsWith(\"s3::\");\r\n }\r\n\r\n parseS3Path(S3Path: string): ServerResult<{ bucket: string; path: string }> {\r\n if (!this.isS3Path(S3Path)) {\r\n return this.error(\"BAD_REQUEST\", \"Invalid S3 path\");\r\n }\r\n const [bucket, path] = S3Path.split(\"s3::\")[1].split(\"//\");\r\n return ok({ bucket, path });\r\n }\r\n\r\n wrapS3Path(path: string, bucket: string): string {\r\n return `s3::${bucket}//${path}`;\r\n }\r\n\r\n getS3UploadUrl(\r\n filename: string,\r\n filetype: string,\r\n expiresIn = 60 * 5\r\n ): ServerResultAsync<string> {\r\n return this.repository.file.getS3UploadUrl(filename, filetype, expiresIn);\r\n }\r\n\r\n getS3DownloadUrl(path: string, expiresIn = 60 * 5): ServerResultAsync<string> {\r\n return this.repository.file.getS3DownloadUrl(path, expiresIn);\r\n }\r\n\r\n getS3Object(path: string) {\r\n return this.repository.file.getS3Object(path);\r\n }\r\n\r\n deleteS3Object(path: string) {\r\n return this.repository.file.deleteS3Object(path);\r\n }\r\n\r\n async uploadFileToS3(localPath: string, returnDownloadUrl = false): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const extension = localPath.split(\".\").pop()?.toLowerCase();\r\n const filename = `${uuidv4()}${extension ? `.${extension}` : \"\"}`;\r\n\r\n const mimeByExt: Record<string, string> = {\r\n jpg: \"image/jpeg\",\r\n jpeg: \"image/jpeg\",\r\n png: \"image/png\",\r\n webp: \"image/webp\",\r\n mp4: \"video/mp4\",\r\n mov: \"video/mov\",\r\n avi: \"video/avi\",\r\n mkv: \"video/mkv\",\r\n webm: \"video/webm\",\r\n mp3: \"audio/mp3\",\r\n wav: \"audio/wav\",\r\n m4a: \"audio/m4a\",\r\n };\r\n const filetype = (extension && mimeByExt[extension]) || \"application/octet-stream\";\r\n\r\n const presigned = await this.getS3UploadUrl(filename, filetype);\r\n if (presigned.isErr()) return err(presigned.error);\r\n\r\n const file = await readFile(localPath);\r\n const res = await fetch(presigned.value, {\r\n method: \"PUT\",\r\n body: file,\r\n headers: { \"Content-Type\": filetype },\r\n });\r\n if (!res.ok) {\r\n return this.error(\"INTERNAL_SERVER_ERROR\", `Failed to upload to S3: ${res.status}`);\r\n }\r\n if (returnDownloadUrl) {\r\n const downloadUrl = await this.getS3DownloadUrl(filename);\r\n if (downloadUrl.isErr()) return err(downloadUrl.error);\r\n return ok(downloadUrl.value);\r\n }\r\n\r\n return ok(filename);\r\n });\r\n }\r\n\r\n async downloadS3ToFile(s3Path: string): ServerResultAsync<string> {\r\n return this.throwableAsync(async () => {\r\n const extension = s3Path.split(\".\").pop();\r\n const destinationPath = path.join(\r\n tmpdir(),\r\n \"s3-downloads\",\r\n `${uuidv4()}${extension ? `.${extension}` : \"\"}`\r\n );\r\n\r\n const result = await this.repository.file.getS3Object(s3Path);\r\n if (result.isErr()) return err(result.error);\r\n\r\n const body = result.value.Body;\r\n if (!body) return this.error(\"NOT_FOUND\", \"S3 object body is empty\");\r\n\r\n await mkdir(dirname(destinationPath), { recursive: true });\r\n\r\n // AWS SDK v3 SdkStream has transformToByteArray method - use it for reliable handling\r\n if (\r\n typeof body === \"object\" &&\r\n \"transformToByteArray\" in body &&\r\n typeof body.transformToByteArray === \"function\"\r\n ) {\r\n const bytes = await body.transformToByteArray();\r\n await writeFile(destinationPath, bytes);\r\n return ok(destinationPath);\r\n }\r\n\r\n // Fallback: try streaming approaches\r\n const writeStream = createWriteStream(destinationPath);\r\n let input: NodeJS.ReadableStream | null = null;\r\n const unknownBody: unknown = body;\r\n\r\n if (\r\n typeof unknownBody === \"object\" &&\r\n unknownBody !== null &&\r\n \"pipe\" in unknownBody &&\r\n typeof (unknownBody as { pipe?: unknown }).pipe === \"function\"\r\n ) {\r\n input = unknownBody as NodeJS.ReadableStream;\r\n } else if (\r\n typeof unknownBody === \"object\" &&\r\n unknownBody !== null &&\r\n \"getReader\" in unknownBody &&\r\n typeof (unknownBody as { getReader?: unknown }).getReader === \"function\"\r\n ) {\r\n input = Readable.fromWeb(unknownBody as unknown as globalThis.ReadableStream);\r\n } else if (\r\n typeof unknownBody === \"object\" &&\r\n unknownBody !== null &&\r\n \"stream\" in unknownBody &&\r\n typeof (unknownBody as { stream?: unknown }).stream === \"function\"\r\n ) {\r\n input = Readable.fromWeb(\r\n (unknownBody as { stream: () => globalThis.ReadableStream }).stream()\r\n );\r\n }\r\n\r\n if (input) {\r\n await pipeline(input, writeStream);\r\n return ok(destinationPath);\r\n }\r\n\r\n if (\r\n typeof unknownBody === \"object\" &&\r\n unknownBody !== null &&\r\n \"arrayBuffer\" in unknownBody &&\r\n typeof (unknownBody as { arrayBuffer?: unknown }).arrayBuffer === \"function\"\r\n ) {\r\n const buffer = Buffer.from(\r\n await (unknownBody as { arrayBuffer: () => Promise<ArrayBuffer> }).arrayBuffer()\r\n );\r\n await pipeline(Readable.from(buffer), writeStream);\r\n return ok(destinationPath);\r\n }\r\n\r\n return this.error(\"INTERNAL_SERVER_ERROR\", \"Unsupported S3 body type\");\r\n });\r\n }\r\n\r\n getFileType(path: string): { fileType: keyof typeof fileTypes; extension: string } | undefined {\r\n // determine the type of the file\r\n const extension = path.split(\".\").pop();\r\n if (!extension) return undefined;\r\n\r\n for (const [key, value] of Object.entries(fileTypes)) {\r\n if (value.extensions.includes(extension)) {\r\n return { fileType: key, extension };\r\n }\r\n }\r\n return undefined;\r\n }\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { ServerResult, ServerResultAsync } from "../base/base.dto.cjs";
2
+ import { BaseService } from "../base/base.service.cjs";
3
+ import { FileRepository } from "./file.repository.cjs";
4
+ import * as _$_aws_sdk_client_s30 from "@aws-sdk/client-s3";
5
+ import { fileTypes } from "@m5kdev/commons/modules/file/file.constants";
6
+
7
+ //#region src/modules/file/file.service.d.ts
8
+ declare class FileService extends BaseService<{
9
+ file: FileRepository;
10
+ }, never> {
11
+ isS3Path(path: string): boolean;
12
+ parseS3Path(S3Path: string): ServerResult<{
13
+ bucket: string;
14
+ path: string;
15
+ }>;
16
+ wrapS3Path(path: string, bucket: string): string;
17
+ getS3UploadUrl(filename: string, filetype: string, expiresIn?: number): ServerResultAsync<string>;
18
+ getS3DownloadUrl(path: string, expiresIn?: number): ServerResultAsync<string>;
19
+ getS3Object(path: string): ServerResultAsync<_$_aws_sdk_client_s30.GetObjectCommandOutput>;
20
+ deleteS3Object(path: string): ServerResultAsync<void>;
21
+ uploadFileToS3(localPath: string, returnDownloadUrl?: boolean): ServerResultAsync<string>;
22
+ downloadS3ToFile(s3Path: string): ServerResultAsync<string>;
23
+ getFileType(path: string): {
24
+ fileType: keyof typeof fileTypes;
25
+ extension: string;
26
+ } | undefined;
27
+ }
28
+ //#endregion
29
+ export { FileService };
30
+ //# sourceMappingURL=file.service.d.cts.map