@m5kdev/backend 0.1.1 → 0.1.3

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 (113) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +18 -0
  3. package/dist/src/lib/posthog.js +7 -0
  4. package/dist/src/lib/sentry.js +9 -0
  5. package/dist/src/modules/access/access.repository.js +32 -0
  6. package/dist/src/modules/access/access.service.js +51 -0
  7. package/dist/src/modules/access/access.test.js +182 -0
  8. package/dist/src/modules/access/access.utils.js +20 -0
  9. package/dist/src/modules/ai/ai.db.js +39 -0
  10. package/dist/src/modules/ai/ai.prompt.js +30 -0
  11. package/dist/src/modules/ai/ai.repository.js +26 -0
  12. package/dist/src/modules/ai/ai.router.js +132 -0
  13. package/dist/src/modules/ai/ai.service.js +207 -0
  14. package/dist/src/modules/ai/ai.trpc.d.ts +5 -5
  15. package/dist/src/modules/ai/ai.trpc.js +20 -0
  16. package/dist/src/modules/ai/ideogram/ideogram.constants.js +167 -0
  17. package/dist/src/modules/ai/ideogram/ideogram.dto.js +49 -0
  18. package/dist/src/modules/ai/ideogram/ideogram.prompt.js +860 -0
  19. package/dist/src/modules/ai/ideogram/ideogram.repository.js +46 -0
  20. package/dist/src/modules/ai/ideogram/ideogram.service.js +11 -0
  21. package/dist/src/modules/auth/auth.db.js +215 -0
  22. package/dist/src/modules/auth/auth.dto.js +38 -0
  23. package/dist/src/modules/auth/auth.lib.d.ts +4 -4
  24. package/dist/src/modules/auth/auth.lib.js +284 -0
  25. package/dist/src/modules/auth/auth.middleware.js +52 -0
  26. package/dist/src/modules/auth/auth.repository.js +541 -0
  27. package/dist/src/modules/auth/auth.service.js +201 -0
  28. package/dist/src/modules/auth/auth.trpc.d.ts +18 -18
  29. package/dist/src/modules/auth/auth.trpc.js +157 -0
  30. package/dist/src/modules/auth/auth.utils.js +97 -0
  31. package/dist/src/modules/base/base.abstract.js +53 -0
  32. package/dist/src/modules/base/base.dto.js +112 -0
  33. package/dist/src/modules/base/base.grants.js +123 -0
  34. package/dist/src/modules/base/base.grants.test.js +668 -0
  35. package/dist/src/modules/base/base.repository.js +307 -0
  36. package/dist/src/modules/base/base.service.js +109 -0
  37. package/dist/src/modules/base/base.types.js +2 -0
  38. package/dist/src/modules/billing/billing.db.js +29 -0
  39. package/dist/src/modules/billing/billing.repository.js +235 -0
  40. package/dist/src/modules/billing/billing.router.js +56 -0
  41. package/dist/src/modules/billing/billing.service.js +147 -0
  42. package/dist/src/modules/billing/billing.trpc.d.ts +5 -5
  43. package/dist/src/modules/billing/billing.trpc.js +17 -0
  44. package/dist/src/modules/clay/clay.repository.js +26 -0
  45. package/dist/src/modules/clay/clay.service.js +24 -0
  46. package/dist/src/modules/connect/connect.db.js +30 -0
  47. package/dist/src/modules/connect/connect.dto.js +36 -0
  48. package/dist/src/modules/connect/connect.linkedin.js +53 -0
  49. package/dist/src/modules/connect/connect.oauth.js +198 -0
  50. package/dist/src/modules/connect/connect.repository.d.ts +7 -7
  51. package/dist/src/modules/connect/connect.repository.js +54 -0
  52. package/dist/src/modules/connect/connect.router.js +54 -0
  53. package/dist/src/modules/connect/connect.service.d.ts +14 -14
  54. package/dist/src/modules/connect/connect.service.js +114 -0
  55. package/dist/src/modules/connect/connect.trpc.d.ts +10 -10
  56. package/dist/src/modules/connect/connect.trpc.js +21 -0
  57. package/dist/src/modules/connect/connect.types.js +2 -0
  58. package/dist/src/modules/crypto/crypto.db.js +17 -0
  59. package/dist/src/modules/crypto/crypto.repository.js +10 -0
  60. package/dist/src/modules/crypto/crypto.service.js +52 -0
  61. package/dist/src/modules/email/email.service.js +107 -0
  62. package/dist/src/modules/file/file.repository.js +79 -0
  63. package/dist/src/modules/file/file.router.js +99 -0
  64. package/dist/src/modules/file/file.service.js +150 -0
  65. package/dist/src/modules/recurrence/recurrence.db.js +66 -0
  66. package/dist/src/modules/recurrence/recurrence.repository.js +39 -0
  67. package/dist/src/modules/recurrence/recurrence.service.js +70 -0
  68. package/dist/src/modules/recurrence/recurrence.trpc.d.ts +15 -15
  69. package/dist/src/modules/recurrence/recurrence.trpc.js +65 -0
  70. package/dist/src/modules/social/social.dto.js +18 -0
  71. package/dist/src/modules/social/social.linkedin.js +427 -0
  72. package/dist/src/modules/social/social.linkedin.test.js +235 -0
  73. package/dist/src/modules/social/social.service.js +76 -0
  74. package/dist/src/modules/social/social.types.js +2 -0
  75. package/dist/src/modules/tag/tag.db.js +42 -0
  76. package/dist/src/modules/tag/tag.dto.js +9 -0
  77. package/dist/src/modules/tag/tag.repository.js +154 -0
  78. package/dist/src/modules/tag/tag.service.js +31 -0
  79. package/dist/src/modules/tag/tag.trpc.d.ts +5 -5
  80. package/dist/src/modules/tag/tag.trpc.js +47 -0
  81. package/dist/src/modules/utils/applyPagination.js +16 -0
  82. package/dist/src/modules/utils/applySorting.js +18 -0
  83. package/dist/src/modules/utils/getConditionsFromFilters.js +200 -0
  84. package/dist/src/modules/video/video.service.js +84 -0
  85. package/dist/src/modules/webhook/webhook.constants.js +10 -0
  86. package/dist/src/modules/webhook/webhook.db.js +17 -0
  87. package/dist/src/modules/webhook/webhook.dto.js +7 -0
  88. package/dist/src/modules/webhook/webhook.repository.js +56 -0
  89. package/dist/src/modules/webhook/webhook.router.js +30 -0
  90. package/dist/src/modules/webhook/webhook.service.js +68 -0
  91. package/dist/src/modules/workflow/workflow.db.js +30 -0
  92. package/dist/src/modules/workflow/workflow.repository.js +105 -0
  93. package/dist/src/modules/workflow/workflow.service.js +37 -0
  94. package/dist/src/modules/workflow/workflow.trpc.d.ts +5 -5
  95. package/dist/src/modules/workflow/workflow.trpc.js +21 -0
  96. package/dist/src/modules/workflow/workflow.types.js +2 -0
  97. package/dist/src/modules/workflow/workflow.utils.js +173 -0
  98. package/dist/src/test/stubs/utils.js +5 -0
  99. package/dist/src/trpc/context.d.ts +5 -5
  100. package/dist/src/trpc/context.js +17 -0
  101. package/dist/src/trpc/index.js +6 -0
  102. package/dist/src/trpc/procedures.d.ts +56 -56
  103. package/dist/src/trpc/procedures.js +32 -0
  104. package/dist/src/trpc/utils.js +20 -0
  105. package/dist/src/types.d.ts +33 -33
  106. package/dist/src/types.js +13 -0
  107. package/dist/src/utils/errors.js +104 -0
  108. package/dist/src/utils/logger.js +11 -0
  109. package/dist/src/utils/posthog.js +31 -0
  110. package/dist/src/utils/types.js +2 -0
  111. package/dist/tsconfig.tsbuildinfo +1 -1
  112. package/package.json +3 -3
  113. package/tsconfig.json +2 -0
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IdeogramRepository = void 0;
4
+ const neverthrow_1 = require("neverthrow");
5
+ const base_repository_1 = require("#modules/base/base.repository");
6
+ class IdeogramRepository extends base_repository_1.BaseExternaRepository {
7
+ async generate(input) {
8
+ if (!process.env.IDEOGRAM_API_KEY)
9
+ return this.error("INTERNAL_SERVER_ERROR", "IDEOGRAM_API_KEY is not set");
10
+ return this.throwableAsync(async () => {
11
+ const formData = new FormData();
12
+ formData.append("prompt", input.prompt);
13
+ if (input.seed)
14
+ formData.append("seed", input.seed.toString());
15
+ if (input.resolution)
16
+ formData.append("resolution", input.resolution);
17
+ if (input.rendering_speed)
18
+ formData.append("rendering_speed", input.rendering_speed);
19
+ if (input.magic_prompt)
20
+ formData.append("magic_prompt", input.magic_prompt);
21
+ if (input.negative_prompt)
22
+ formData.append("negative_prompt", input.negative_prompt);
23
+ if (input.num_images)
24
+ formData.append("num_images", input.num_images.toString());
25
+ if (input.color_palette)
26
+ formData.append("color_palette", JSON.stringify(input.color_palette));
27
+ if (input.style_codes)
28
+ formData.append("style_codes", JSON.stringify(input.style_codes));
29
+ if (input.aspect_ratio)
30
+ formData.append("aspect_ratio", input.aspect_ratio);
31
+ if (input.style_type)
32
+ formData.append("style_type", input.style_type);
33
+ if (input.style_preset)
34
+ formData.append("style_preset", input.style_preset);
35
+ //TODO: Add file support
36
+ const response = await fetch("https://api.ideogram.ai/v1/ideogram-v3/generate", {
37
+ method: "POST",
38
+ headers: { "Api-Key": process.env.IDEOGRAM_API_KEY },
39
+ body: formData,
40
+ });
41
+ const data = await response.json();
42
+ return (0, neverthrow_1.ok)(data);
43
+ });
44
+ }
45
+ }
46
+ exports.IdeogramRepository = IdeogramRepository;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IdeogramService = void 0;
4
+ const base_service_1 = require("#modules/base/base.service");
5
+ class IdeogramService extends base_service_1.BaseService {
6
+ async generate(input) {
7
+ const result = await this.repository.ideogram.generate(input);
8
+ return result;
9
+ }
10
+ }
11
+ exports.IdeogramService = IdeogramService;
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.accountClaimMagicLinks = exports.waitlist = exports.apikeys = exports.invitations = exports.teamMembers = exports.teams = exports.members = exports.organizations = exports.verifications = exports.accounts = exports.sessions = exports.users = void 0;
4
+ const sqlite_core_1 = require("drizzle-orm/sqlite-core");
5
+ const uuid_1 = require("uuid");
6
+ exports.users = (0, sqlite_core_1.sqliteTable)("users", {
7
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
8
+ name: (0, sqlite_core_1.text)("name").notNull(),
9
+ email: (0, sqlite_core_1.text)("email").notNull().unique(),
10
+ emailVerified: (0, sqlite_core_1.integer)("email_verified", { mode: "boolean" }).notNull(),
11
+ image: (0, sqlite_core_1.text)("image"),
12
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
13
+ .notNull()
14
+ .$default(() => new Date()),
15
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" })
16
+ .notNull()
17
+ .$default(() => new Date()),
18
+ role: (0, sqlite_core_1.text)("role"),
19
+ banned: (0, sqlite_core_1.integer)("banned", { mode: "boolean" }),
20
+ banReason: (0, sqlite_core_1.text)("ban_reason"),
21
+ banExpires: (0, sqlite_core_1.integer)("ban_expires", { mode: "timestamp" }),
22
+ stripeCustomerId: (0, sqlite_core_1.text)("stripe_customer_id").unique(),
23
+ paymentCustomerId: (0, sqlite_core_1.text)("payment_customer_id").unique(),
24
+ paymentPlanTier: (0, sqlite_core_1.text)("payment_plan_tier"),
25
+ paymentPlanExpiresAt: (0, sqlite_core_1.integer)("payment_plan_expires_at", {
26
+ mode: "timestamp",
27
+ }),
28
+ preferences: (0, sqlite_core_1.text)("preferences"),
29
+ metadata: (0, sqlite_core_1.text)("metadata", { mode: "json" })
30
+ .notNull()
31
+ .default({})
32
+ .$type(),
33
+ onboarding: (0, sqlite_core_1.integer)("onboarding"),
34
+ flags: (0, sqlite_core_1.text)("flags"),
35
+ });
36
+ exports.sessions = (0, sqlite_core_1.sqliteTable)("sessions", {
37
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
38
+ expiresAt: (0, sqlite_core_1.integer)("expires_at", { mode: "timestamp" }).notNull(),
39
+ token: (0, sqlite_core_1.text)("token").notNull().unique(),
40
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
41
+ .notNull()
42
+ .$default(() => new Date()),
43
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" })
44
+ .notNull()
45
+ .$default(() => new Date()),
46
+ ipAddress: (0, sqlite_core_1.text)("ip_address"),
47
+ userAgent: (0, sqlite_core_1.text)("user_agent"),
48
+ userId: (0, sqlite_core_1.text)("user_id")
49
+ .notNull()
50
+ .references(() => exports.users.id, { onDelete: "cascade" }),
51
+ impersonatedBy: (0, sqlite_core_1.text)("impersonated_by"),
52
+ activeOrganizationId: (0, sqlite_core_1.text)("active_organization_id"),
53
+ activeOrganizationRole: (0, sqlite_core_1.text)("active_organization_role"),
54
+ activeTeamId: (0, sqlite_core_1.text)("active_team_id"),
55
+ activeTeamRole: (0, sqlite_core_1.text)("active_team_role"),
56
+ });
57
+ exports.accounts = (0, sqlite_core_1.sqliteTable)("accounts", {
58
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
59
+ accountId: (0, sqlite_core_1.text)("account_id").notNull(),
60
+ providerId: (0, sqlite_core_1.text)("provider_id").notNull(),
61
+ userId: (0, sqlite_core_1.text)("user_id")
62
+ .notNull()
63
+ .references(() => exports.users.id, { onDelete: "cascade" }),
64
+ accessToken: (0, sqlite_core_1.text)("access_token"),
65
+ refreshToken: (0, sqlite_core_1.text)("refresh_token"),
66
+ idToken: (0, sqlite_core_1.text)("id_token"),
67
+ accessTokenExpiresAt: (0, sqlite_core_1.integer)("access_token_expires_at", {
68
+ mode: "timestamp",
69
+ }),
70
+ refreshTokenExpiresAt: (0, sqlite_core_1.integer)("refresh_token_expires_at", {
71
+ mode: "timestamp",
72
+ }),
73
+ scope: (0, sqlite_core_1.text)("scope"),
74
+ password: (0, sqlite_core_1.text)("password"),
75
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
76
+ .notNull()
77
+ .$default(() => new Date()),
78
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" })
79
+ .notNull()
80
+ .$default(() => new Date()),
81
+ });
82
+ exports.verifications = (0, sqlite_core_1.sqliteTable)("verifications", {
83
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
84
+ identifier: (0, sqlite_core_1.text)("identifier").notNull(),
85
+ value: (0, sqlite_core_1.text)("value").notNull(),
86
+ expiresAt: (0, sqlite_core_1.integer)("expires_at", { mode: "timestamp" }).notNull(),
87
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" }).$default(() => new Date()),
88
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" }).$default(() => new Date()),
89
+ });
90
+ exports.organizations = (0, sqlite_core_1.sqliteTable)("organizations", {
91
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
92
+ name: (0, sqlite_core_1.text)("name").notNull(),
93
+ slug: (0, sqlite_core_1.text)("slug").unique(),
94
+ logo: (0, sqlite_core_1.text)("logo"),
95
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
96
+ .notNull()
97
+ .$default(() => new Date()),
98
+ metadata: (0, sqlite_core_1.text)("metadata"),
99
+ });
100
+ exports.members = (0, sqlite_core_1.sqliteTable)("members", {
101
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
102
+ organizationId: (0, sqlite_core_1.text)("organization_id")
103
+ .notNull()
104
+ .references(() => exports.organizations.id),
105
+ userId: (0, sqlite_core_1.text)("user_id")
106
+ .notNull()
107
+ .references(() => exports.users.id),
108
+ role: (0, sqlite_core_1.text)("role").notNull(),
109
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
110
+ .notNull()
111
+ .$default(() => new Date()),
112
+ });
113
+ exports.teams = (0, sqlite_core_1.sqliteTable)("teams", {
114
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
115
+ name: (0, sqlite_core_1.text)("name").notNull(),
116
+ organizationId: (0, sqlite_core_1.text)("organization_id")
117
+ .notNull()
118
+ .references(() => exports.organizations.id),
119
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
120
+ .notNull()
121
+ .$default(() => new Date()),
122
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" }),
123
+ });
124
+ exports.teamMembers = (0, sqlite_core_1.sqliteTable)("teammembers", {
125
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
126
+ teamId: (0, sqlite_core_1.text)("team_id")
127
+ .notNull()
128
+ .references(() => exports.teams.id),
129
+ userId: (0, sqlite_core_1.text)("user_id")
130
+ .notNull()
131
+ .references(() => exports.users.id),
132
+ role: (0, sqlite_core_1.text)("role").notNull(),
133
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
134
+ .notNull()
135
+ .$default(() => new Date()),
136
+ });
137
+ exports.invitations = (0, sqlite_core_1.sqliteTable)("invitations", {
138
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
139
+ organizationId: (0, sqlite_core_1.text)("organization_id")
140
+ .notNull()
141
+ .references(() => exports.organizations.id),
142
+ teamId: (0, sqlite_core_1.text)("team_id").references(() => exports.teams.id),
143
+ email: (0, sqlite_core_1.text)("email").notNull(),
144
+ role: (0, sqlite_core_1.text)("role"),
145
+ status: (0, sqlite_core_1.text)("status").notNull(),
146
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
147
+ .notNull()
148
+ .$default(() => new Date()),
149
+ expiresAt: (0, sqlite_core_1.integer)("expires_at", { mode: "timestamp" }).notNull(),
150
+ inviterId: (0, sqlite_core_1.text)("inviter_id")
151
+ .notNull()
152
+ .references(() => exports.users.id),
153
+ });
154
+ exports.apikeys = (0, sqlite_core_1.sqliteTable)("apikeys", {
155
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
156
+ name: (0, sqlite_core_1.text)("name"),
157
+ start: (0, sqlite_core_1.text)("start"),
158
+ prefix: (0, sqlite_core_1.text)("prefix"),
159
+ key: (0, sqlite_core_1.text)("key").notNull(),
160
+ userId: (0, sqlite_core_1.text)("user_id")
161
+ .notNull()
162
+ .references(() => exports.users.id),
163
+ refillInterval: (0, sqlite_core_1.integer)("refill_interval", { mode: "number" }),
164
+ refillAmount: (0, sqlite_core_1.integer)("refill_amount", { mode: "number" }),
165
+ lastRefillAt: (0, sqlite_core_1.integer)("last_refill_at", { mode: "timestamp" }),
166
+ enabled: (0, sqlite_core_1.integer)("enabled", { mode: "boolean" }).notNull(),
167
+ rateLimitEnabled: (0, sqlite_core_1.integer)("rate_limit_enabled", { mode: "boolean" }).notNull(),
168
+ rateLimitTimeWindow: (0, sqlite_core_1.integer)("rate_limit_time_window", { mode: "number" }),
169
+ rateLimitMax: (0, sqlite_core_1.integer)("rate_limit_max", { mode: "number" }),
170
+ requestCount: (0, sqlite_core_1.integer)("request_count", { mode: "number" }).notNull(),
171
+ remaining: (0, sqlite_core_1.integer)("remaining", { mode: "number" }),
172
+ lastRequest: (0, sqlite_core_1.integer)("last_request", { mode: "timestamp" }),
173
+ expiresAt: (0, sqlite_core_1.integer)("expires_at", { mode: "timestamp" }),
174
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
175
+ .notNull()
176
+ .$default(() => new Date()),
177
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" })
178
+ .notNull()
179
+ .$default(() => new Date()),
180
+ permissions: (0, sqlite_core_1.text)("permissions"),
181
+ metadata: (0, sqlite_core_1.text)("metadata"),
182
+ });
183
+ exports.waitlist = (0, sqlite_core_1.sqliteTable)("waitlist", {
184
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
185
+ name: (0, sqlite_core_1.text)("name"),
186
+ email: (0, sqlite_core_1.text)("email"),
187
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
188
+ .notNull()
189
+ .$default(() => new Date()),
190
+ updatedAt: (0, sqlite_core_1.integer)("updated_at", { mode: "timestamp" }),
191
+ status: (0, sqlite_core_1.text)("status").notNull().default("WAITLIST"),
192
+ type: (0, sqlite_core_1.text)("type").notNull().default("WAITLIST"),
193
+ code: (0, sqlite_core_1.text)("code"),
194
+ expiresAt: (0, sqlite_core_1.integer)("expires_at", { mode: "timestamp" }),
195
+ userId: (0, sqlite_core_1.text)("user_id").references(() => exports.users.id),
196
+ claimUserId: (0, sqlite_core_1.text)("claim_user_id").references(() => exports.users.id),
197
+ claimedAt: (0, sqlite_core_1.integer)("claimed_at", { mode: "timestamp" }),
198
+ claimedEmail: (0, sqlite_core_1.text)("claimed_email"),
199
+ });
200
+ exports.accountClaimMagicLinks = (0, sqlite_core_1.sqliteTable)("account_claim_magic_links", {
201
+ id: (0, sqlite_core_1.text)("id").primaryKey().$default(uuid_1.v4),
202
+ claimId: (0, sqlite_core_1.text)("claim_id")
203
+ .notNull()
204
+ .references(() => exports.waitlist.id, { onDelete: "cascade" }),
205
+ userId: (0, sqlite_core_1.text)("user_id")
206
+ .notNull()
207
+ .references(() => exports.users.id, { onDelete: "cascade" }),
208
+ email: (0, sqlite_core_1.text)("email").notNull(),
209
+ token: (0, sqlite_core_1.text)("token").notNull(),
210
+ url: (0, sqlite_core_1.text)("url").notNull(),
211
+ expiresAt: (0, sqlite_core_1.integer)("expires_at", { mode: "timestamp" }),
212
+ createdAt: (0, sqlite_core_1.integer)("created_at", { mode: "timestamp" })
213
+ .notNull()
214
+ .$default(() => new Date()),
215
+ });
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.accountClaimMagicLinkOutputSchema = exports.accountClaimMagicLinkSchema = exports.accountClaimOutputSchema = exports.accountClaimSchema = exports.waitlistOutputSchema = exports.waitlistSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.waitlistSchema = zod_1.z.object({
6
+ id: zod_1.z.string(),
7
+ name: zod_1.z.string().nullable(),
8
+ email: zod_1.z.string().nullable(),
9
+ createdAt: zod_1.z.date(),
10
+ updatedAt: zod_1.z.date().nullable(),
11
+ status: zod_1.z.string(),
12
+ code: zod_1.z.string().nullable(),
13
+ expiresAt: zod_1.z.date().nullable(),
14
+ });
15
+ exports.waitlistOutputSchema = exports.waitlistSchema.omit({ code: true, expiresAt: true });
16
+ exports.accountClaimSchema = zod_1.z.object({
17
+ id: zod_1.z.string(),
18
+ claimUserId: zod_1.z.string().nullable(),
19
+ code: zod_1.z.string().nullable(),
20
+ status: zod_1.z.string(),
21
+ expiresAt: zod_1.z.date().nullable(),
22
+ claimedAt: zod_1.z.date().nullable(),
23
+ claimedEmail: zod_1.z.string().nullable(),
24
+ createdAt: zod_1.z.date(),
25
+ updatedAt: zod_1.z.date().nullable(),
26
+ });
27
+ exports.accountClaimOutputSchema = exports.accountClaimSchema.omit({ code: true });
28
+ exports.accountClaimMagicLinkSchema = zod_1.z.object({
29
+ id: zod_1.z.string(),
30
+ claimId: zod_1.z.string(),
31
+ userId: zod_1.z.string(),
32
+ email: zod_1.z.string(),
33
+ token: zod_1.z.string(),
34
+ url: zod_1.z.string(),
35
+ expiresAt: zod_1.z.date().nullable(),
36
+ createdAt: zod_1.z.date(),
37
+ });
38
+ exports.accountClaimMagicLinkOutputSchema = exports.accountClaimMagicLinkSchema.omit({ token: true });
@@ -3260,13 +3260,13 @@ export declare function createBetterAuth<O extends Orm, S extends Schema, E exte
3260
3260
  $Infer: {
3261
3261
  body: ({
3262
3262
  permission: {
3263
- readonly user?: ("get" | "set-role" | "create" | "update" | "delete" | "list" | "ban" | "impersonate" | "set-password")[] | undefined;
3263
+ readonly user?: ("get" | "delete" | "list" | "create" | "update" | "set-role" | "ban" | "impersonate" | "set-password")[] | undefined;
3264
3264
  readonly session?: ("delete" | "list" | "revoke")[] | undefined;
3265
3265
  };
3266
3266
  permissions?: never | undefined;
3267
3267
  } | {
3268
3268
  permissions: {
3269
- readonly user?: ("get" | "set-role" | "create" | "update" | "delete" | "list" | "ban" | "impersonate" | "set-password")[] | undefined;
3269
+ readonly user?: ("get" | "delete" | "list" | "create" | "update" | "set-role" | "ban" | "impersonate" | "set-password")[] | undefined;
3270
3270
  readonly session?: ("delete" | "list" | "revoke")[] | undefined;
3271
3271
  };
3272
3272
  permission?: never | undefined;
@@ -4791,7 +4791,7 @@ export declare function createBetterAuth<O extends Orm, S extends Schema, E exte
4791
4791
  socialProviders?: import("better-auth", { with: { "resolution-mode": "import" } }).SocialProviders | undefined;
4792
4792
  account?: {
4793
4793
  modelName?: string;
4794
- fields?: Partial<Record<"userId" | "accessToken" | "refreshToken" | "scope" | "createdAt" | "updatedAt" | "idToken" | "password" | "providerId" | "accountId" | "accessTokenExpiresAt" | "refreshTokenExpiresAt", string>>;
4794
+ fields?: Partial<Record<"userId" | "updatedAt" | "createdAt" | "accountId" | "providerId" | "accessToken" | "refreshToken" | "idToken" | "accessTokenExpiresAt" | "refreshTokenExpiresAt" | "scope" | "password", string>>;
4795
4795
  additionalFields?: {
4796
4796
  [key: string]: import("better-auth", { with: { "resolution-mode": "import" } }).DBFieldAttribute;
4797
4797
  };
@@ -4811,7 +4811,7 @@ export declare function createBetterAuth<O extends Orm, S extends Schema, E exte
4811
4811
  } | undefined;
4812
4812
  verification?: {
4813
4813
  modelName?: string;
4814
- fields?: Partial<Record<"value" | "expiresAt" | "createdAt" | "updatedAt" | "identifier", string>>;
4814
+ fields?: Partial<Record<"value" | "updatedAt" | "createdAt" | "expiresAt" | "identifier", string>>;
4815
4815
  additionalFields?: {
4816
4816
  [key: string]: import("better-auth", { with: { "resolution-mode": "import" } }).DBFieldAttribute;
4817
4817
  };
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createBetterAuth = createBetterAuth;
4
+ const tslib_1 = require("tslib");
5
+ const better_auth_1 = require("better-auth");
6
+ const drizzle_1 = require("better-auth/adapters/drizzle");
7
+ const api_1 = require("better-auth/api");
8
+ const plugins_1 = require("better-auth/plugins");
9
+ const drizzle_orm_1 = require("drizzle-orm");
10
+ const auth = tslib_1.__importStar(require("#modules/auth/auth.db"));
11
+ const auth_utils_1 = require("#modules/auth/auth.utils");
12
+ const logger_1 = require("#utils/logger");
13
+ const posthog_1 = require("#utils/posthog");
14
+ const schema = { ...auth };
15
+ function createBetterAuth({ orm, schema, services, hooks, options, config }) {
16
+ const { email: emailService, billing: billingService } = services;
17
+ const { waitlist = false, provisionedAccountEmailDomain } = config ?? {};
18
+ const normalizedProvisionedAccountEmailDomain = provisionedAccountEmailDomain
19
+ ? provisionedAccountEmailDomain.toLowerCase().replace(/^@/, "")
20
+ : null;
21
+ const logger = logger_1.logger.child({ layer: "betterAuth" });
22
+ const getWaitlistInvitationCode = async (ctx) => {
23
+ let code = ctx?.headers?.get("waitlist-invitation-code");
24
+ if (code)
25
+ return code;
26
+ const oauthState = await (0, api_1.getOAuthState)();
27
+ if (oauthState) {
28
+ code = oauthState.waitlistInvitationCode;
29
+ }
30
+ return code;
31
+ };
32
+ const isProvisionedAccountEmail = (email) => {
33
+ if (!normalizedProvisionedAccountEmailDomain)
34
+ return false;
35
+ return email.toLowerCase().endsWith(`@${normalizedProvisionedAccountEmailDomain}`);
36
+ };
37
+ return (0, better_auth_1.betterAuth)({
38
+ ...options,
39
+ baseURL: process.env.VITE_SERVER_URL,
40
+ session: {
41
+ expiresIn: 60 * 60 * 24 * 7,
42
+ updateAge: 60 * 60 * 24,
43
+ cookieCache: {
44
+ enabled: true,
45
+ maxAge: 60 * 5,
46
+ },
47
+ additionalFields: {
48
+ activeOrganizationRole: {
49
+ type: "string",
50
+ required: false,
51
+ defaultValue: null,
52
+ },
53
+ activeTeamRole: {
54
+ type: "string",
55
+ required: false,
56
+ defaultValue: null,
57
+ },
58
+ },
59
+ },
60
+ user: {
61
+ deleteUser: {
62
+ enabled: true,
63
+ sendDeleteAccountVerification: async ({ user, url }) => {
64
+ const result = await emailService?.sendDeleteAccountVerification(user.email, url);
65
+ if (result?.isErr()) {
66
+ logger.error(result.error);
67
+ hooks?.onError?.(result.error);
68
+ throw result.error;
69
+ }
70
+ },
71
+ },
72
+ additionalFields: {
73
+ onboarding: {
74
+ type: "number",
75
+ required: false,
76
+ defaultValue: null,
77
+ },
78
+ preferences: {
79
+ type: "string",
80
+ required: false,
81
+ defaultValue: null,
82
+ },
83
+ flags: {
84
+ type: "string",
85
+ required: false,
86
+ defaultValue: null,
87
+ },
88
+ stripeCustomerId: {
89
+ type: "string",
90
+ required: false,
91
+ defaultValue: null,
92
+ input: false,
93
+ },
94
+ paymentCustomerId: {
95
+ type: "string",
96
+ required: false,
97
+ defaultValue: null,
98
+ input: false,
99
+ },
100
+ paymentPlanTier: {
101
+ type: "string",
102
+ required: false,
103
+ defaultValue: null,
104
+ input: false,
105
+ },
106
+ paymentPlanExpiresAt: {
107
+ type: "number",
108
+ required: false,
109
+ defaultValue: null,
110
+ input: false,
111
+ },
112
+ },
113
+ },
114
+ database: (0, drizzle_1.drizzleAdapter)(orm, {
115
+ provider: "sqlite",
116
+ schema,
117
+ usePlural: true,
118
+ }),
119
+ emailAndPassword: {
120
+ enabled: true,
121
+ requireEmailVerification: !waitlist,
122
+ sendResetPassword: async ({ user, url }) => {
123
+ const result = await emailService?.sendResetPassword(user.email, url);
124
+ if (result?.isErr()) {
125
+ logger.error(result.error);
126
+ hooks?.onError?.(result.error);
127
+ throw result.error;
128
+ }
129
+ },
130
+ },
131
+ emailVerification: {
132
+ sendVerificationEmail: async ({ user, url }) => {
133
+ const result = await emailService?.sendVerification(user.email, url);
134
+ if (result?.isErr()) {
135
+ logger.error(result.error);
136
+ hooks?.onError?.(result.error);
137
+ throw result.error;
138
+ }
139
+ },
140
+ },
141
+ plugins: [
142
+ ...(options?.plugins ?? []),
143
+ (0, plugins_1.magicLink)({
144
+ disableSignUp: true,
145
+ sendMagicLink: async ({ email, url, token }) => {
146
+ const [user] = await orm
147
+ .select({ id: schema.users.id })
148
+ .from(schema.users)
149
+ .where((0, drizzle_orm_1.eq)(schema.users.email, email.toLowerCase()))
150
+ .limit(1);
151
+ if (!user)
152
+ return;
153
+ const [claim] = await orm
154
+ .select({ id: schema.waitlist.id })
155
+ .from(schema.waitlist)
156
+ .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema.waitlist.type, "ACCOUNT_CLAIM"), (0, drizzle_orm_1.eq)(schema.waitlist.claimUserId, user.id), (0, drizzle_orm_1.eq)(schema.waitlist.status, "INVITED"), (0, drizzle_orm_1.gte)(schema.waitlist.expiresAt, new Date())))
157
+ .orderBy((0, drizzle_orm_1.desc)(schema.waitlist.createdAt))
158
+ .limit(1);
159
+ if (claim) {
160
+ await orm.insert(schema.accountClaimMagicLinks).values({
161
+ claimId: claim.id,
162
+ userId: user.id,
163
+ email: email.toLowerCase(),
164
+ token,
165
+ url,
166
+ expiresAt: new Date(Date.now() + 1000 * 60 * 5),
167
+ });
168
+ }
169
+ },
170
+ }),
171
+ (0, plugins_1.admin)(),
172
+ (0, plugins_1.lastLoginMethod)(),
173
+ (0, plugins_1.organization)({
174
+ allowUserToCreateOrganization: false,
175
+ teams: {
176
+ enabled: true,
177
+ allowRemovingAllTeams: false,
178
+ },
179
+ sendInvitationEmail: async (data) => {
180
+ const invitationUrl = `${process.env.VITE_APP_URL}/organization/accept-invitation?id=${data.id}`;
181
+ const inviterName = data.inviter.user.name || data.inviter.user.email;
182
+ const result = await emailService?.sendOrganizationInvite(data.email, data.organization.name, inviterName, data.role, invitationUrl);
183
+ if (result?.isErr()) {
184
+ logger.error(result.error);
185
+ hooks?.onError?.(result.error);
186
+ throw result.error;
187
+ }
188
+ },
189
+ schema: {
190
+ team: {
191
+ modelName: "team",
192
+ },
193
+ teamMember: {
194
+ modelName: "teamMember",
195
+ additionalFields: {
196
+ role: {
197
+ type: "string",
198
+ required: true,
199
+ },
200
+ },
201
+ },
202
+ member: {
203
+ modelName: "member",
204
+ },
205
+ invitation: {
206
+ modelName: "invitation",
207
+ },
208
+ organization: {
209
+ modelName: "organization",
210
+ },
211
+ },
212
+ }),
213
+ (0, plugins_1.apiKey)(),
214
+ ],
215
+ trustedOrigins: [process.env.VITE_APP_URL, process.env.VITE_SERVER_URL],
216
+ databaseHooks: {
217
+ user: {
218
+ create: {
219
+ before: async (_user, ctx) => {
220
+ if (waitlist) {
221
+ const waitlistCode = await getWaitlistInvitationCode(ctx);
222
+ if (waitlistCode) {
223
+ const [waitlistInvitation] = await orm
224
+ .select()
225
+ .from(schema.waitlist)
226
+ .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema.waitlist.code, waitlistCode), (0, drizzle_orm_1.eq)(schema.waitlist.type, "WAITLIST"), (0, drizzle_orm_1.eq)(schema.waitlist.status, "INVITED"), (0, drizzle_orm_1.gte)(schema.waitlist.expiresAt, new Date())))
227
+ .limit(1);
228
+ if (!waitlistInvitation) {
229
+ return false;
230
+ }
231
+ await orm
232
+ .update(schema.waitlist)
233
+ .set({
234
+ status: "ACCEPTED",
235
+ updatedAt: new Date(),
236
+ })
237
+ .where((0, drizzle_orm_1.eq)(schema.waitlist.id, waitlistInvitation.id));
238
+ return;
239
+ }
240
+ }
241
+ if (waitlist) {
242
+ return false;
243
+ }
244
+ return;
245
+ },
246
+ after: async (user) => {
247
+ await (0, auth_utils_1.createOrganizationAndTeam)(orm, schema, user);
248
+ if (!isProvisionedAccountEmail(user.email)) {
249
+ await billingService?.createUserHook({ user });
250
+ }
251
+ (0, posthog_1.posthogCapture)({
252
+ distinctId: user.id,
253
+ event: "user_created",
254
+ properties: {
255
+ email: user.email,
256
+ name: user.name,
257
+ role: user.role,
258
+ image: user.image,
259
+ },
260
+ });
261
+ if (hooks?.afterCreateUser)
262
+ await hooks.afterCreateUser(user);
263
+ },
264
+ },
265
+ },
266
+ session: {
267
+ create: {
268
+ before: async (session) => {
269
+ const { organizationId, teamId, organizationRole, teamRole } = await (0, auth_utils_1.getActiveOrganizationAndTeam)(orm, schema, session.userId);
270
+ return {
271
+ data: {
272
+ ...session,
273
+ activeOrganizationId: organizationId,
274
+ activeTeamId: teamId,
275
+ activeOrganizationRole: organizationRole,
276
+ activeTeamRole: teamRole,
277
+ },
278
+ };
279
+ },
280
+ },
281
+ },
282
+ },
283
+ });
284
+ }