@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.
- package/.cursor/rules/backend.mdc +70 -0
- package/.turbo/turbo-build.log +5 -0
- package/.turbo/turbo-check-types.log +5 -0
- package/.turbo/turbo-lint$colon$fix.log +255 -0
- package/CHANGELOG.md +19 -0
- package/dist/src/lib/posthog.d.ts +3 -0
- package/dist/src/lib/posthog.d.ts.map +1 -0
- package/dist/src/lib/posthog.js +7 -0
- package/dist/src/lib/sentry.d.ts +2 -0
- package/dist/src/lib/sentry.d.ts.map +1 -0
- package/dist/src/lib/sentry.js +9 -0
- package/dist/src/modules/access/access.repository.d.ts +2348 -0
- package/dist/src/modules/access/access.repository.d.ts.map +1 -0
- package/dist/src/modules/access/access.repository.js +32 -0
- package/dist/src/modules/access/access.service.d.ts +22 -0
- package/dist/src/modules/access/access.service.d.ts.map +1 -0
- package/dist/src/modules/access/access.service.js +51 -0
- package/dist/src/modules/access/access.test.d.ts +2 -0
- package/dist/src/modules/access/access.test.d.ts.map +1 -0
- package/dist/src/modules/access/access.test.js +182 -0
- package/dist/src/modules/access/access.utils.d.ts +17 -0
- package/dist/src/modules/access/access.utils.d.ts.map +1 -0
- package/dist/src/modules/access/access.utils.js +20 -0
- package/dist/src/modules/ai/ai.db.d.ts +396 -0
- package/dist/src/modules/ai/ai.db.d.ts.map +1 -0
- package/dist/src/modules/ai/ai.db.js +39 -0
- package/dist/src/modules/ai/ai.prompt.d.ts +28 -0
- package/dist/src/modules/ai/ai.prompt.d.ts.map +1 -0
- package/dist/src/modules/ai/ai.prompt.js +30 -0
- package/dist/src/modules/ai/ai.repository.d.ts +424 -0
- package/dist/src/modules/ai/ai.repository.d.ts.map +1 -0
- package/dist/src/modules/ai/ai.repository.js +26 -0
- package/dist/src/modules/ai/ai.router.d.ts +2 -0
- package/dist/src/modules/ai/ai.router.d.ts.map +1 -0
- package/dist/src/modules/ai/ai.router.js +132 -0
- package/dist/src/modules/ai/ai.service.d.ts +115 -0
- package/dist/src/modules/ai/ai.service.d.ts.map +1 -0
- package/dist/src/modules/ai/ai.service.js +207 -0
- package/dist/src/modules/ai/ai.trpc.d.ts +59 -0
- package/dist/src/modules/ai/ai.trpc.d.ts.map +1 -0
- package/dist/src/modules/ai/ai.trpc.js +20 -0
- package/dist/src/modules/ai/ideogram/ideogram.constants.d.ts +8 -0
- package/dist/src/modules/ai/ideogram/ideogram.constants.d.ts.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.constants.js +167 -0
- package/dist/src/modules/ai/ideogram/ideogram.dto.d.ts +230 -0
- package/dist/src/modules/ai/ideogram/ideogram.dto.d.ts.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.dto.js +49 -0
- package/dist/src/modules/ai/ideogram/ideogram.prompt.d.ts +3 -0
- package/dist/src/modules/ai/ideogram/ideogram.prompt.d.ts.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.prompt.js +860 -0
- package/dist/src/modules/ai/ideogram/ideogram.repository.d.ts +7 -0
- package/dist/src/modules/ai/ideogram/ideogram.repository.d.ts.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.repository.js +46 -0
- package/dist/src/modules/ai/ideogram/ideogram.service.d.ts +10 -0
- package/dist/src/modules/ai/ideogram/ideogram.service.d.ts.map +1 -0
- package/dist/src/modules/ai/ideogram/ideogram.service.js +11 -0
- package/dist/src/modules/auth/auth.db.d.ts +2336 -0
- package/dist/src/modules/auth/auth.db.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.db.js +215 -0
- package/dist/src/modules/auth/auth.dto.d.ts +66 -0
- package/dist/src/modules/auth/auth.dto.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.dto.js +38 -0
- package/dist/src/modules/auth/auth.lib.d.ts +4874 -0
- package/dist/src/modules/auth/auth.lib.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.lib.js +284 -0
- package/dist/src/modules/auth/auth.middleware.d.ts +615 -0
- package/dist/src/modules/auth/auth.middleware.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.middleware.js +52 -0
- package/dist/src/modules/auth/auth.repository.d.ts +2417 -0
- package/dist/src/modules/auth/auth.repository.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.repository.js +541 -0
- package/dist/src/modules/auth/auth.service.d.ts +104 -0
- package/dist/src/modules/auth/auth.service.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.service.js +201 -0
- package/dist/src/modules/auth/auth.trpc.d.ts +309 -0
- package/dist/src/modules/auth/auth.trpc.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.trpc.js +157 -0
- package/dist/src/modules/auth/auth.utils.d.ts +2352 -0
- package/dist/src/modules/auth/auth.utils.d.ts.map +1 -0
- package/dist/src/modules/auth/auth.utils.js +97 -0
- package/dist/src/modules/base/base.abstract.d.ts +19 -0
- package/dist/src/modules/base/base.abstract.d.ts.map +1 -0
- package/dist/src/modules/base/base.abstract.js +53 -0
- package/dist/src/modules/base/base.dto.d.ts +70 -0
- package/dist/src/modules/base/base.dto.d.ts.map +1 -0
- package/dist/src/modules/base/base.dto.js +112 -0
- package/dist/src/modules/base/base.grants.d.ts +29 -0
- package/dist/src/modules/base/base.grants.d.ts.map +1 -0
- package/dist/src/modules/base/base.grants.js +123 -0
- package/dist/src/modules/base/base.grants.test.d.ts +2 -0
- package/dist/src/modules/base/base.grants.test.d.ts.map +1 -0
- package/dist/src/modules/base/base.grants.test.js +668 -0
- package/dist/src/modules/base/base.repository.d.ts +97 -0
- package/dist/src/modules/base/base.repository.d.ts.map +1 -0
- package/dist/src/modules/base/base.repository.js +307 -0
- package/dist/src/modules/base/base.service.d.ts +42 -0
- package/dist/src/modules/base/base.service.d.ts.map +1 -0
- package/dist/src/modules/base/base.service.js +109 -0
- package/dist/src/modules/base/base.types.d.ts +2 -0
- package/dist/src/modules/base/base.types.d.ts.map +1 -0
- package/dist/src/modules/base/base.types.js +2 -0
- package/dist/src/modules/billing/billing.db.d.ts +366 -0
- package/dist/src/modules/billing/billing.db.d.ts.map +1 -0
- package/dist/src/modules/billing/billing.db.js +29 -0
- package/dist/src/modules/billing/billing.repository.d.ts +2764 -0
- package/dist/src/modules/billing/billing.repository.d.ts.map +1 -0
- package/dist/src/modules/billing/billing.repository.js +235 -0
- package/dist/src/modules/billing/billing.router.d.ts +5 -0
- package/dist/src/modules/billing/billing.router.d.ts.map +1 -0
- package/dist/src/modules/billing/billing.router.js +56 -0
- package/dist/src/modules/billing/billing.service.d.ts +60 -0
- package/dist/src/modules/billing/billing.service.d.ts.map +1 -0
- package/dist/src/modules/billing/billing.service.js +147 -0
- package/dist/src/modules/billing/billing.trpc.d.ts +75 -0
- package/dist/src/modules/billing/billing.trpc.d.ts.map +1 -0
- package/dist/src/modules/billing/billing.trpc.js +17 -0
- package/dist/src/modules/clay/clay.repository.d.ts +6 -0
- package/dist/src/modules/clay/clay.repository.d.ts.map +1 -0
- package/dist/src/modules/clay/clay.repository.js +26 -0
- package/dist/src/modules/clay/clay.service.d.ts +29 -0
- package/dist/src/modules/clay/clay.service.d.ts.map +1 -0
- package/dist/src/modules/clay/clay.service.js +24 -0
- package/dist/src/modules/connect/connect.db.d.ts +357 -0
- package/dist/src/modules/connect/connect.db.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.db.js +30 -0
- package/dist/src/modules/connect/connect.dto.d.ts +75 -0
- package/dist/src/modules/connect/connect.dto.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.dto.js +36 -0
- package/dist/src/modules/connect/connect.linkedin.d.ts +3 -0
- package/dist/src/modules/connect/connect.linkedin.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.linkedin.js +53 -0
- package/dist/src/modules/connect/connect.oauth.d.ts +28 -0
- package/dist/src/modules/connect/connect.oauth.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.oauth.js +198 -0
- package/dist/src/modules/connect/connect.repository.d.ts +414 -0
- package/dist/src/modules/connect/connect.repository.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.repository.js +54 -0
- package/dist/src/modules/connect/connect.router.d.ts +5 -0
- package/dist/src/modules/connect/connect.router.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.router.js +54 -0
- package/dist/src/modules/connect/connect.service.d.ts +89 -0
- package/dist/src/modules/connect/connect.service.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.service.js +114 -0
- package/dist/src/modules/connect/connect.trpc.d.ts +81 -0
- package/dist/src/modules/connect/connect.trpc.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.trpc.js +21 -0
- package/dist/src/modules/connect/connect.types.d.ts +26 -0
- package/dist/src/modules/connect/connect.types.d.ts.map +1 -0
- package/dist/src/modules/connect/connect.types.js +2 -0
- package/dist/src/modules/crypto/crypto.db.d.ts +152 -0
- package/dist/src/modules/crypto/crypto.db.d.ts.map +1 -0
- package/dist/src/modules/crypto/crypto.db.js +17 -0
- package/dist/src/modules/crypto/crypto.repository.d.ts +160 -0
- package/dist/src/modules/crypto/crypto.repository.d.ts.map +1 -0
- package/dist/src/modules/crypto/crypto.repository.js +10 -0
- package/dist/src/modules/crypto/crypto.service.d.ts +11 -0
- package/dist/src/modules/crypto/crypto.service.d.ts.map +1 -0
- package/dist/src/modules/crypto/crypto.service.js +52 -0
- package/dist/src/modules/email/email.service.d.ts +57 -0
- package/dist/src/modules/email/email.service.d.ts.map +1 -0
- package/dist/src/modules/email/email.service.js +107 -0
- package/dist/src/modules/file/file.repository.d.ts +13 -0
- package/dist/src/modules/file/file.repository.d.ts.map +1 -0
- package/dist/src/modules/file/file.repository.js +79 -0
- package/dist/src/modules/file/file.router.d.ts +4 -0
- package/dist/src/modules/file/file.router.d.ts.map +1 -0
- package/dist/src/modules/file/file.router.js +99 -0
- package/dist/src/modules/file/file.service.d.ts +25 -0
- package/dist/src/modules/file/file.service.d.ts.map +1 -0
- package/dist/src/modules/file/file.service.js +150 -0
- package/dist/src/modules/recurrence/recurrence.db.d.ts +563 -0
- package/dist/src/modules/recurrence/recurrence.db.d.ts.map +1 -0
- package/dist/src/modules/recurrence/recurrence.db.js +66 -0
- package/dist/src/modules/recurrence/recurrence.repository.d.ts +585 -0
- package/dist/src/modules/recurrence/recurrence.repository.d.ts.map +1 -0
- package/dist/src/modules/recurrence/recurrence.repository.js +39 -0
- package/dist/src/modules/recurrence/recurrence.service.d.ts +30 -0
- package/dist/src/modules/recurrence/recurrence.service.d.ts.map +1 -0
- package/dist/src/modules/recurrence/recurrence.service.js +70 -0
- package/dist/src/modules/recurrence/recurrence.trpc.d.ts +243 -0
- package/dist/src/modules/recurrence/recurrence.trpc.d.ts.map +1 -0
- package/dist/src/modules/recurrence/recurrence.trpc.js +65 -0
- package/dist/src/modules/social/social.dto.d.ts +35 -0
- package/dist/src/modules/social/social.dto.d.ts.map +1 -0
- package/dist/src/modules/social/social.dto.js +18 -0
- package/dist/src/modules/social/social.linkedin.d.ts +11 -0
- package/dist/src/modules/social/social.linkedin.d.ts.map +1 -0
- package/dist/src/modules/social/social.linkedin.js +427 -0
- package/dist/src/modules/social/social.linkedin.test.d.ts +2 -0
- package/dist/src/modules/social/social.linkedin.test.d.ts.map +1 -0
- package/dist/src/modules/social/social.linkedin.test.js +235 -0
- package/dist/src/modules/social/social.service.d.ts +29 -0
- package/dist/src/modules/social/social.service.d.ts.map +1 -0
- package/dist/src/modules/social/social.service.js +76 -0
- package/dist/src/modules/social/social.types.d.ts +36 -0
- package/dist/src/modules/social/social.types.d.ts.map +1 -0
- package/dist/src/modules/social/social.types.js +2 -0
- package/dist/src/modules/tag/tag.db.d.ts +347 -0
- package/dist/src/modules/tag/tag.db.d.ts.map +1 -0
- package/dist/src/modules/tag/tag.db.js +42 -0
- package/dist/src/modules/tag/tag.dto.d.ts +1019 -0
- package/dist/src/modules/tag/tag.dto.d.ts.map +1 -0
- package/dist/src/modules/tag/tag.dto.js +9 -0
- package/dist/src/modules/tag/tag.repository.d.ts +384 -0
- package/dist/src/modules/tag/tag.repository.d.ts.map +1 -0
- package/dist/src/modules/tag/tag.repository.js +154 -0
- package/dist/src/modules/tag/tag.service.d.ts +36 -0
- package/dist/src/modules/tag/tag.service.d.ts.map +1 -0
- package/dist/src/modules/tag/tag.service.js +31 -0
- package/dist/src/modules/tag/tag.trpc.d.ts +191 -0
- package/dist/src/modules/tag/tag.trpc.d.ts.map +1 -0
- package/dist/src/modules/tag/tag.trpc.js +47 -0
- package/dist/src/modules/utils/applyPagination.d.ts +7 -0
- package/dist/src/modules/utils/applyPagination.d.ts.map +1 -0
- package/dist/src/modules/utils/applyPagination.js +16 -0
- package/dist/src/modules/utils/applySorting.d.ts +9 -0
- package/dist/src/modules/utils/applySorting.d.ts.map +1 -0
- package/dist/src/modules/utils/applySorting.js +18 -0
- package/dist/src/modules/utils/getConditionsFromFilters.d.ts +5 -0
- package/dist/src/modules/utils/getConditionsFromFilters.d.ts.map +1 -0
- package/dist/src/modules/utils/getConditionsFromFilters.js +200 -0
- package/dist/src/modules/video/video.service.d.ts +8 -0
- package/dist/src/modules/video/video.service.d.ts.map +1 -0
- package/dist/src/modules/video/video.service.js +84 -0
- package/dist/src/modules/webhook/webhook.constants.d.ts +9 -0
- package/dist/src/modules/webhook/webhook.constants.d.ts.map +1 -0
- package/dist/src/modules/webhook/webhook.constants.js +10 -0
- package/dist/src/modules/webhook/webhook.db.d.ts +137 -0
- package/dist/src/modules/webhook/webhook.db.d.ts.map +1 -0
- package/dist/src/modules/webhook/webhook.db.js +17 -0
- package/dist/src/modules/webhook/webhook.dto.d.ts +395 -0
- package/dist/src/modules/webhook/webhook.dto.d.ts.map +1 -0
- package/dist/src/modules/webhook/webhook.dto.js +7 -0
- package/dist/src/modules/webhook/webhook.repository.d.ts +149 -0
- package/dist/src/modules/webhook/webhook.repository.d.ts.map +1 -0
- package/dist/src/modules/webhook/webhook.repository.js +56 -0
- package/dist/src/modules/webhook/webhook.router.d.ts +4 -0
- package/dist/src/modules/webhook/webhook.router.d.ts.map +1 -0
- package/dist/src/modules/webhook/webhook.router.js +30 -0
- package/dist/src/modules/webhook/webhook.service.d.ts +10 -0
- package/dist/src/modules/webhook/webhook.service.d.ts.map +1 -0
- package/dist/src/modules/webhook/webhook.service.js +68 -0
- package/dist/src/modules/workflow/workflow.db.d.ts +297 -0
- package/dist/src/modules/workflow/workflow.db.d.ts.map +1 -0
- package/dist/src/modules/workflow/workflow.db.js +30 -0
- package/dist/src/modules/workflow/workflow.repository.d.ts +344 -0
- package/dist/src/modules/workflow/workflow.repository.d.ts.map +1 -0
- package/dist/src/modules/workflow/workflow.repository.js +105 -0
- package/dist/src/modules/workflow/workflow.service.d.ts +22 -0
- package/dist/src/modules/workflow/workflow.service.d.ts.map +1 -0
- package/dist/src/modules/workflow/workflow.service.js +37 -0
- package/dist/src/modules/workflow/workflow.trpc.d.ts +93 -0
- package/dist/src/modules/workflow/workflow.trpc.d.ts.map +1 -0
- package/dist/src/modules/workflow/workflow.trpc.js +21 -0
- package/dist/src/modules/workflow/workflow.types.d.ts +21 -0
- package/dist/src/modules/workflow/workflow.types.d.ts.map +1 -0
- package/dist/src/modules/workflow/workflow.types.js +2 -0
- package/dist/src/modules/workflow/workflow.utils.d.ts +22 -0
- package/dist/src/modules/workflow/workflow.utils.d.ts.map +1 -0
- package/dist/src/modules/workflow/workflow.utils.js +173 -0
- package/dist/src/test/stubs/utils.d.ts +3 -0
- package/dist/src/test/stubs/utils.d.ts.map +1 -0
- package/dist/src/test/stubs/utils.js +5 -0
- package/dist/src/trpc/context.d.ts +42 -0
- package/dist/src/trpc/context.d.ts.map +1 -0
- package/dist/src/trpc/context.js +17 -0
- package/dist/src/trpc/index.d.ts +4 -0
- package/dist/src/trpc/index.d.ts.map +1 -0
- package/dist/src/trpc/index.js +6 -0
- package/dist/src/trpc/procedures.d.ts +234 -0
- package/dist/src/trpc/procedures.d.ts.map +1 -0
- package/dist/src/trpc/procedures.js +32 -0
- package/dist/src/trpc/utils.d.ts +5 -0
- package/dist/src/trpc/utils.d.ts.map +1 -0
- package/dist/src/trpc/utils.js +20 -0
- package/dist/src/types.d.ts +486 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +13 -0
- package/dist/src/utils/errors.d.ts +50 -0
- package/dist/src/utils/errors.d.ts.map +1 -0
- package/dist/src/utils/errors.js +104 -0
- package/dist/src/utils/logger.d.ts +2 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +11 -0
- package/dist/src/utils/posthog.d.ts +14 -0
- package/dist/src/utils/posthog.d.ts.map +1 -0
- package/dist/src/utils/posthog.js +31 -0
- package/dist/src/utils/types.d.ts +5 -0
- package/dist/src/utils/types.d.ts.map +1 -0
- package/dist/src/utils/types.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/jest.config.ts +19 -0
- package/package.json +3 -6
- 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 @@
|
|
|
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"}
|