@coursebuilder/adapter-drizzle 0.1.2 → 0.1.4
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/dist/{chunk-QZOBGJSV.js → chunk-2CI3IGR2.js} +4 -4
- package/dist/{chunk-ISURSRBK.js → chunk-3RJVKNXB.js} +425 -142
- package/dist/{chunk-RVYJDDZD.js → chunk-53266VWH.js} +3 -3
- package/dist/{chunk-OIUOQ3TT.js → chunk-57CX5SOI.js} +2 -2
- package/dist/{chunk-75V6F7LZ.js → chunk-5HT43CVZ.js} +2 -2
- package/dist/{chunk-SFJM6FKE.js → chunk-BX5SO2JG.js} +2 -2
- package/dist/{chunk-LSOPFMDB.js → chunk-FNYW3XKR.js} +3 -3
- package/dist/{chunk-V6QEDDFG.js → chunk-GLPDG7UE.js} +2 -2
- package/dist/{chunk-VNI36MMC.js → chunk-H736K5TN.js} +1 -1
- package/dist/{chunk-6CBAFOL3.js → chunk-J4LBG2TH.js} +2 -2
- package/dist/{chunk-JD4KFACE.js → chunk-JKOYOL7A.js} +2 -2
- package/dist/{chunk-TMQIGK3N.js → chunk-MBB4GIJI.js} +2 -2
- package/dist/{chunk-27KREOQW.js → chunk-PJHGIRZM.js} +2 -2
- package/dist/{chunk-L2TQQYG4.js → chunk-PPBEA4EM.js} +2 -2
- package/dist/{chunk-MYRB6GLJ.js → chunk-Q5WENQT6.js} +3 -3
- package/dist/{chunk-H4MXNDWO.js → chunk-V23SCQL7.js} +2 -2
- package/dist/{chunk-NZDLUQWP.js → chunk-VDVCCU7D.js} +2 -2
- package/dist/{chunk-IN6G6MTW.js → chunk-VXZRMVNY.js} +2 -2
- package/dist/chunk-WQ7UXKZC.js +9293 -0
- package/dist/{chunk-JKRFXYAR.js → chunk-Y7QZGEPT.js} +2 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.js +20 -37
- package/dist/lib/mysql/index.cjs +1775 -1155
- package/dist/lib/mysql/index.cjs.map +1 -1
- package/dist/lib/mysql/index.d.cts +6143 -0
- package/dist/lib/mysql/index.d.ts +253 -19
- package/dist/lib/mysql/index.js +20 -24
- package/dist/lib/mysql/schemas/auth/accounts.cjs +73 -57
- package/dist/lib/mysql/schemas/auth/accounts.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/accounts.d.cts +184 -0
- package/dist/lib/mysql/schemas/auth/accounts.js +10 -10
- package/dist/lib/mysql/schemas/auth/permissions.d.cts +98 -0
- package/dist/lib/mysql/schemas/auth/permissions.js +2 -2
- package/dist/lib/mysql/schemas/auth/role-permissions.cjs +64 -48
- package/dist/lib/mysql/schemas/auth/role-permissions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/role-permissions.d.cts +89 -0
- package/dist/lib/mysql/schemas/auth/role-permissions.js +11 -11
- package/dist/lib/mysql/schemas/auth/roles.cjs +64 -48
- package/dist/lib/mysql/schemas/auth/roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/roles.d.cts +100 -0
- package/dist/lib/mysql/schemas/auth/roles.js +10 -10
- package/dist/lib/mysql/schemas/auth/sessions.cjs +64 -48
- package/dist/lib/mysql/schemas/auth/sessions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/sessions.d.cts +52 -0
- package/dist/lib/mysql/schemas/auth/sessions.js +11 -11
- package/dist/lib/mysql/schemas/auth/user-permissions.cjs +65 -49
- package/dist/lib/mysql/schemas/auth/user-permissions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-permissions.d.cts +89 -0
- package/dist/lib/mysql/schemas/auth/user-permissions.js +10 -10
- package/dist/lib/mysql/schemas/auth/user-roles.cjs +67 -51
- package/dist/lib/mysql/schemas/auth/user-roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-roles.d.cts +89 -0
- package/dist/lib/mysql/schemas/auth/user-roles.js +10 -10
- package/dist/lib/mysql/schemas/auth/users.cjs +170 -154
- package/dist/lib/mysql/schemas/auth/users.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/users.d.cts +106 -0
- package/dist/lib/mysql/schemas/auth/users.js +10 -10
- package/dist/lib/mysql/schemas/auth/verification-tokens.d.cts +60 -0
- package/dist/lib/mysql/schemas/auth/verification-tokens.js +2 -2
- package/dist/lib/mysql/schemas/commerce/coupon.cjs +180 -17
- package/dist/lib/mysql/schemas/commerce/coupon.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/coupon.d.cts +172 -0
- package/dist/lib/mysql/schemas/commerce/coupon.d.ts +10 -6
- package/dist/lib/mysql/schemas/commerce/coupon.js +12 -2
- package/dist/lib/mysql/schemas/commerce/merchant-account.d.cts +72 -0
- package/dist/lib/mysql/schemas/commerce/merchant-account.js +2 -2
- package/dist/lib/mysql/schemas/commerce/merchant-charge.d.cts +108 -0
- package/dist/lib/mysql/schemas/commerce/merchant-charge.js +2 -2
- package/dist/lib/mysql/schemas/commerce/merchant-coupon.d.cts +84 -0
- package/dist/lib/mysql/schemas/commerce/merchant-coupon.js +2 -2
- package/dist/lib/mysql/schemas/commerce/merchant-customer.d.cts +84 -0
- package/dist/lib/mysql/schemas/commerce/merchant-customer.js +2 -2
- package/dist/lib/mysql/schemas/commerce/merchant-price.d.cts +96 -0
- package/dist/lib/mysql/schemas/commerce/merchant-price.js +2 -2
- package/dist/lib/mysql/schemas/commerce/merchant-product.d.cts +84 -0
- package/dist/lib/mysql/schemas/commerce/merchant-product.js +2 -2
- package/dist/lib/mysql/schemas/commerce/merchant-session.d.cts +48 -0
- package/dist/lib/mysql/schemas/commerce/merchant-session.js +2 -2
- package/dist/lib/mysql/schemas/commerce/price.cjs +192 -11
- package/dist/lib/mysql/schemas/commerce/price.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/price.d.cts +101 -0
- package/dist/lib/mysql/schemas/commerce/price.d.ts +7 -2
- package/dist/lib/mysql/schemas/commerce/price.js +14 -4
- package/dist/lib/mysql/schemas/commerce/product.cjs +230 -9
- package/dist/lib/mysql/schemas/commerce/product.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/product.d.cts +114 -0
- package/dist/lib/mysql/schemas/commerce/product.d.ts +20 -2
- package/dist/lib/mysql/schemas/commerce/product.js +12 -2
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.d.cts +132 -0
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.js +2 -2
- package/dist/lib/mysql/schemas/commerce/purchase.cjs +152 -122
- package/dist/lib/mysql/schemas/commerce/purchase.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/purchase.d.cts +225 -0
- package/dist/lib/mysql/schemas/commerce/purchase.d.ts +2 -1
- package/dist/lib/mysql/schemas/commerce/purchase.js +10 -10
- package/dist/lib/mysql/schemas/commerce/upgradable-products.cjs +110 -24
- package/dist/lib/mysql/schemas/commerce/upgradable-products.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/upgradable-products.d.cts +101 -0
- package/dist/lib/mysql/schemas/commerce/upgradable-products.js +11 -3
- package/dist/lib/mysql/schemas/communication/communication-channel.d.cts +96 -0
- package/dist/lib/mysql/schemas/communication/communication-channel.js +2 -2
- package/dist/lib/mysql/schemas/communication/communication-preference-types.d.cts +96 -0
- package/dist/lib/mysql/schemas/communication/communication-preference-types.js +2 -2
- package/dist/lib/mysql/schemas/communication/communication-preferences.cjs +84 -68
- package/dist/lib/mysql/schemas/communication/communication-preferences.cjs.map +1 -1
- package/dist/lib/mysql/schemas/communication/communication-preferences.d.cts +150 -0
- package/dist/lib/mysql/schemas/communication/communication-preferences.js +10 -10
- package/dist/lib/mysql/schemas/content/content-contributions.cjs +92 -76
- package/dist/lib/mysql/schemas/content/content-contributions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-contributions.d.cts +114 -0
- package/dist/lib/mysql/schemas/content/content-contributions.js +10 -10
- package/dist/lib/mysql/schemas/content/content-resource-product.cjs +246 -0
- package/dist/lib/mysql/schemas/content/content-resource-product.cjs.map +1 -0
- package/dist/lib/mysql/schemas/content/content-resource-product.d.cts +101 -0
- package/dist/lib/mysql/schemas/content/content-resource-product.d.ts +101 -0
- package/dist/lib/mysql/schemas/content/content-resource-product.js +18 -0
- package/dist/lib/mysql/schemas/content/content-resource-resource.cjs +67 -51
- package/dist/lib/mysql/schemas/content/content-resource-resource.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-resource.d.cts +101 -0
- package/dist/lib/mysql/schemas/content/content-resource-resource.js +10 -10
- package/dist/lib/mysql/schemas/content/content-resource.cjs +116 -62
- package/dist/lib/mysql/schemas/content/content-resource.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource.d.cts +103 -0
- package/dist/lib/mysql/schemas/content/content-resource.d.ts +1 -0
- package/dist/lib/mysql/schemas/content/content-resource.js +10 -10
- package/dist/lib/mysql/schemas/content/contribution-types.d.cts +110 -0
- package/dist/lib/mysql/schemas/content/contribution-types.js +2 -2
- package/dist/lib/mysql/schemas/content/resource-progress.cjs +1 -1
- package/dist/lib/mysql/schemas/content/resource-progress.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/resource-progress.d.cts +84 -0
- package/dist/lib/mysql/schemas/content/resource-progress.d.ts +1 -1
- package/dist/lib/mysql/schemas/content/resource-progress.js +2 -2
- package/dist/lib/mysql/utils.cjs.map +1 -1
- package/dist/lib/mysql/utils.d.cts +12 -0
- package/dist/lib/mysql/utils.js +1 -1
- package/dist/lib/mysql/utils.js.map +1 -1
- package/dist/lib/utils.cjs.map +1 -1
- package/dist/lib/utils.d.cts +22 -0
- package/dist/lib/utils.d.ts +4 -8
- package/dist/lib/utils.js +12 -3
- package/dist/lib/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +0 -8
- package/src/lib/mysql/index.ts +611 -129
- package/src/lib/mysql/schemas/auth/user-roles.ts +2 -2
- package/src/lib/mysql/schemas/commerce/coupon.ts +20 -4
- package/src/lib/mysql/schemas/commerce/price.ts +23 -2
- package/src/lib/mysql/schemas/commerce/product.ts +27 -2
- package/src/lib/mysql/schemas/commerce/purchase.ts +6 -1
- package/src/lib/mysql/schemas/content/content-resource-product.ts +62 -0
- package/src/lib/mysql/schemas/content/content-resource.ts +5 -0
- package/src/lib/mysql/schemas/content/resource-progress.ts +1 -1
- package/src/lib/utils.ts +1 -9
- package/dist/chunk-44VDBYFU.js +0 -60
- package/dist/chunk-7LAAAEVE.js +0 -379
- package/dist/chunk-AFQGYW7Z.js +0 -45
- package/dist/chunk-CPE4P26C.js +0 -42
- package/dist/chunk-DHYYRN35.js +0 -4679
- package/dist/chunk-GFUUJRX7.js +0 -18
- package/dist/chunk-O2KKII62.js +0 -381
- package/dist/chunk-Y34AIPU7.js +0 -4137
- package/dist/lib/pg.cjs +0 -4527
- package/dist/lib/pg.cjs.map +0 -1
- package/dist/lib/pg.d.ts +0 -496
- package/dist/lib/pg.js +0 -11
- package/dist/lib/sqlite.cjs +0 -4536
- package/dist/lib/sqlite.cjs.map +0 -1
- package/dist/lib/sqlite.d.ts +0 -496
- package/dist/lib/sqlite.js +0 -12
- package/dist/lib/sqlite.js.map +0 -1
- package/src/lib/pg.ts +0 -579
- package/src/lib/sqlite.ts +0 -562
- /package/dist/lib/{pg.js.map → mysql/schemas/content/content-resource-product.js.map} +0 -0
package/src/lib/mysql/index.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import type { AdapterSession, AdapterUser } from '@auth/core/adapters'
|
|
2
2
|
import { addSeconds, isAfter } from 'date-fns'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
and,
|
|
5
|
+
asc,
|
|
6
|
+
eq,
|
|
7
|
+
inArray,
|
|
8
|
+
isNotNull,
|
|
9
|
+
isNull,
|
|
10
|
+
not,
|
|
11
|
+
or,
|
|
12
|
+
sql,
|
|
13
|
+
} from 'drizzle-orm'
|
|
4
14
|
import {
|
|
5
15
|
mysqlTable as defaultMySqlTableFn,
|
|
6
16
|
MySqlDatabase,
|
|
@@ -18,14 +28,19 @@ import {
|
|
|
18
28
|
MerchantCoupon,
|
|
19
29
|
merchantCouponSchema,
|
|
20
30
|
MerchantCustomer,
|
|
31
|
+
merchantPriceSchema,
|
|
21
32
|
MerchantProduct,
|
|
33
|
+
merchantProductSchema,
|
|
22
34
|
Price,
|
|
35
|
+
priceSchema,
|
|
23
36
|
Product,
|
|
37
|
+
productSchema,
|
|
24
38
|
Purchase,
|
|
25
39
|
purchaseSchema,
|
|
26
40
|
PurchaseUserTransfer,
|
|
27
41
|
PurchaseUserTransferState,
|
|
28
42
|
ResourceProgress,
|
|
43
|
+
resourceProgressSchema,
|
|
29
44
|
UpgradableProduct,
|
|
30
45
|
upgradableProductSchema,
|
|
31
46
|
User,
|
|
@@ -35,7 +50,10 @@ import {
|
|
|
35
50
|
ContentResourceResourceSchema,
|
|
36
51
|
ContentResourceSchema,
|
|
37
52
|
} from '@coursebuilder/core/schemas/content-resource-schema'
|
|
53
|
+
import { merchantAccountSchema } from '@coursebuilder/core/schemas/merchant-account-schema'
|
|
54
|
+
import { merchantCustomerSchema } from '@coursebuilder/core/schemas/merchant-customer-schema'
|
|
38
55
|
import { VideoResourceSchema } from '@coursebuilder/core/schemas/video-resource'
|
|
56
|
+
import { validateCoupon } from '@coursebuilder/core/utils/validate-coupon'
|
|
39
57
|
|
|
40
58
|
import {
|
|
41
59
|
getAccountsRelationsSchema,
|
|
@@ -70,7 +88,10 @@ import {
|
|
|
70
88
|
getUsersSchema,
|
|
71
89
|
} from './schemas/auth/users.js'
|
|
72
90
|
import { getVerificationTokensSchema } from './schemas/auth/verification-tokens.js'
|
|
73
|
-
import {
|
|
91
|
+
import {
|
|
92
|
+
getCouponRelationsSchema,
|
|
93
|
+
getCouponSchema,
|
|
94
|
+
} from './schemas/commerce/coupon.js'
|
|
74
95
|
import { getMerchantAccountSchema } from './schemas/commerce/merchant-account.js'
|
|
75
96
|
import { getMerchantChargeSchema } from './schemas/commerce/merchant-charge.js'
|
|
76
97
|
import { getMerchantCouponSchema } from './schemas/commerce/merchant-coupon.js'
|
|
@@ -79,7 +100,10 @@ import { getMerchantPriceSchema } from './schemas/commerce/merchant-price.js'
|
|
|
79
100
|
import { getMerchantProductSchema } from './schemas/commerce/merchant-product.js'
|
|
80
101
|
import { getMerchantSessionSchema } from './schemas/commerce/merchant-session.js'
|
|
81
102
|
import { getPriceSchema } from './schemas/commerce/price.js'
|
|
82
|
-
import {
|
|
103
|
+
import {
|
|
104
|
+
getProductRelationsSchema,
|
|
105
|
+
getProductSchema,
|
|
106
|
+
} from './schemas/commerce/product.js'
|
|
83
107
|
import { getPurchaseUserTransferSchema } from './schemas/commerce/purchase-user-transfer.js'
|
|
84
108
|
import {
|
|
85
109
|
getPurchaseRelationsSchema,
|
|
@@ -99,6 +123,10 @@ import {
|
|
|
99
123
|
getContentContributionRelationsSchema,
|
|
100
124
|
getContentContributionsSchema,
|
|
101
125
|
} from './schemas/content/content-contributions.js'
|
|
126
|
+
import {
|
|
127
|
+
getContentResourceProductRelationsSchema,
|
|
128
|
+
getContentResourceProductSchema,
|
|
129
|
+
} from './schemas/content/content-resource-product.js'
|
|
102
130
|
import {
|
|
103
131
|
getContentResourceResourceRelationsSchema,
|
|
104
132
|
getContentResourceResourceSchema,
|
|
@@ -133,6 +161,7 @@ export function getCourseBuilderSchema(mysqlTable: MySqlTableFn) {
|
|
|
133
161
|
usersRelations: getUsersRelationsSchema(mysqlTable),
|
|
134
162
|
verificationTokens: getVerificationTokensSchema(mysqlTable),
|
|
135
163
|
coupon: getCouponSchema(mysqlTable),
|
|
164
|
+
couponRelations: getCouponRelationsSchema(mysqlTable),
|
|
136
165
|
merchantAccount: getMerchantAccountSchema(mysqlTable),
|
|
137
166
|
merchantCharge: getMerchantChargeSchema(mysqlTable),
|
|
138
167
|
merchantCoupon: getMerchantCouponSchema(mysqlTable),
|
|
@@ -165,6 +194,10 @@ export function getCourseBuilderSchema(mysqlTable: MySqlTableFn) {
|
|
|
165
194
|
upgradableProducts: getUpgradableProductsSchema(mysqlTable),
|
|
166
195
|
upgradableProductsRelations:
|
|
167
196
|
getUpgradableProductsRelationsSchema(mysqlTable),
|
|
197
|
+
contentResourceProduct: getContentResourceProductSchema(mysqlTable),
|
|
198
|
+
contentResourceProductRelations:
|
|
199
|
+
getContentResourceProductRelationsSchema(mysqlTable),
|
|
200
|
+
productRelations: getProductRelationsSchema(mysqlTable),
|
|
168
201
|
} as const
|
|
169
202
|
}
|
|
170
203
|
|
|
@@ -198,20 +231,203 @@ export function mySqlDrizzleAdapter(
|
|
|
198
231
|
prices,
|
|
199
232
|
products,
|
|
200
233
|
upgradableProducts,
|
|
234
|
+
resourceProgress,
|
|
201
235
|
} = createTables(tableFn)
|
|
202
236
|
|
|
203
237
|
return {
|
|
204
238
|
client,
|
|
239
|
+
async redeemFullPriceCoupon(options) {
|
|
240
|
+
const {
|
|
241
|
+
email: baseEmail,
|
|
242
|
+
couponId,
|
|
243
|
+
productIds,
|
|
244
|
+
currentUserId,
|
|
245
|
+
redeemingProductId,
|
|
246
|
+
} = options
|
|
247
|
+
const email = String(baseEmail).replace(' ', '+')
|
|
248
|
+
|
|
249
|
+
const coupon = await this.getCouponWithBulkPurchases(couponId)
|
|
250
|
+
|
|
251
|
+
const productId =
|
|
252
|
+
(coupon && (coupon.restrictedToProductId as string)) ||
|
|
253
|
+
redeemingProductId
|
|
254
|
+
|
|
255
|
+
if (!productId) throw new Error(`unable-to-find-any-product-id`)
|
|
256
|
+
|
|
257
|
+
const couponValidation = validateCoupon(coupon, productIds)
|
|
258
|
+
|
|
259
|
+
if (coupon && couponValidation.isRedeemable) {
|
|
260
|
+
// if the Coupon is the Bulk Coupon of a Bulk Purchase,
|
|
261
|
+
// then a bulk coupon is being redeemed
|
|
262
|
+
const bulkCouponRedemption = Boolean(
|
|
263
|
+
coupon.bulkCouponPurchases[0]?.bulkCouponId,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
const { user } = await this.findOrCreateUser(email)
|
|
267
|
+
|
|
268
|
+
if (!user) throw new Error(`unable-to-create-user-${email}`)
|
|
269
|
+
|
|
270
|
+
const currentUser = currentUserId
|
|
271
|
+
? await this.getUserById(currentUserId)
|
|
272
|
+
: null
|
|
273
|
+
|
|
274
|
+
const redeemingForCurrentUser = currentUser?.id === user.id
|
|
275
|
+
|
|
276
|
+
// To prevent double-purchasing, check if this user already has a
|
|
277
|
+
// Purchase record for this product that is valid and wasn't a bulk
|
|
278
|
+
// coupon purchase.
|
|
279
|
+
const existingPurchases =
|
|
280
|
+
await this.getExistingNonBulkValidPurchasesOfProduct({
|
|
281
|
+
userId: user.id,
|
|
282
|
+
productId,
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
if (existingPurchases.length > 0)
|
|
286
|
+
throw new Error(`already-purchased-${email}`)
|
|
287
|
+
|
|
288
|
+
const purchaseId = `purchase-${v4()}`
|
|
289
|
+
|
|
290
|
+
await this.createPurchase({
|
|
291
|
+
id: purchaseId,
|
|
292
|
+
userId: user.id,
|
|
293
|
+
couponId: bulkCouponRedemption ? null : coupon.id,
|
|
294
|
+
redeemedBulkCouponId: bulkCouponRedemption ? coupon.id : null,
|
|
295
|
+
productId,
|
|
296
|
+
totalAmount: '0',
|
|
297
|
+
metadata: {
|
|
298
|
+
couponUsedId: bulkCouponRedemption ? null : coupon.id,
|
|
299
|
+
},
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
const newPurchase = await this.getPurchase(purchaseId)
|
|
303
|
+
|
|
304
|
+
await this.incrementCouponUsedCount(coupon.id)
|
|
305
|
+
|
|
306
|
+
await this.createPurchaseTransfer({
|
|
307
|
+
sourceUserId: user.id,
|
|
308
|
+
purchaseId: purchaseId,
|
|
309
|
+
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
return { purchase: newPurchase, redeemingForCurrentUser }
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return null
|
|
316
|
+
},
|
|
317
|
+
createPurchaseTransfer: async (options) => {
|
|
318
|
+
const id = `put_${v4()}`
|
|
319
|
+
await client.insert(purchaseUserTransfer).values({
|
|
320
|
+
id,
|
|
321
|
+
purchaseId: options.purchaseId,
|
|
322
|
+
sourceUserId: options.sourceUserId,
|
|
323
|
+
expiresAt: options.expiresAt,
|
|
324
|
+
})
|
|
325
|
+
},
|
|
326
|
+
incrementCouponUsedCount: async (couponId) => {
|
|
327
|
+
await client
|
|
328
|
+
.update(coupon)
|
|
329
|
+
.set({ usedCount: sql`${coupon.usedCount} + 1` })
|
|
330
|
+
.where(eq(coupon.id, couponId))
|
|
331
|
+
},
|
|
332
|
+
getExistingNonBulkValidPurchasesOfProduct: async ({
|
|
333
|
+
userId,
|
|
334
|
+
productId,
|
|
335
|
+
}) => {
|
|
336
|
+
const existingPurchases = await client.query.purchases.findMany({
|
|
337
|
+
where: and(
|
|
338
|
+
eq(purchaseTable.userId, userId),
|
|
339
|
+
productId ? eq(purchaseTable.productId, productId) : undefined,
|
|
340
|
+
eq(purchaseTable.status, 'Valid'),
|
|
341
|
+
isNull(purchaseTable.bulkCouponId),
|
|
342
|
+
),
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
return z.array(purchaseSchema).parse(existingPurchases)
|
|
346
|
+
},
|
|
347
|
+
createMerchantCustomer: async (options) => {
|
|
348
|
+
await client.insert(merchantCustomer).values({
|
|
349
|
+
id: `mc_${v4()}`,
|
|
350
|
+
identifier: options.identifier,
|
|
351
|
+
merchantAccountId: options.merchantAccountId,
|
|
352
|
+
userId: options.userId,
|
|
353
|
+
status: 1,
|
|
354
|
+
})
|
|
355
|
+
return merchantCustomerSchema.parse(
|
|
356
|
+
await client.query.merchantCustomer.findFirst({
|
|
357
|
+
where: eq(merchantCustomer.identifier, options.identifier),
|
|
358
|
+
}),
|
|
359
|
+
)
|
|
360
|
+
},
|
|
361
|
+
getMerchantAccount: async (options) => {
|
|
362
|
+
return merchantAccountSchema.parse(
|
|
363
|
+
await client.query.merchantAccount.findFirst({
|
|
364
|
+
where: eq(merchantAccount.label, options.provider),
|
|
365
|
+
}),
|
|
366
|
+
)
|
|
367
|
+
},
|
|
368
|
+
getMerchantPriceForProductId: async (productId) => {
|
|
369
|
+
const merchantPriceData = await client.query.merchantPrice.findFirst({
|
|
370
|
+
where: eq(merchantPrice.merchantProductId, productId),
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
const parsedMerchantPrice =
|
|
374
|
+
merchantPriceSchema.safeParse(merchantPriceData)
|
|
375
|
+
|
|
376
|
+
if (!parsedMerchantPrice.success) {
|
|
377
|
+
console.error(
|
|
378
|
+
'Error parsing merchant price',
|
|
379
|
+
JSON.stringify(parsedMerchantPrice.error),
|
|
380
|
+
)
|
|
381
|
+
return null
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return parsedMerchantPrice.data
|
|
385
|
+
},
|
|
386
|
+
getMerchantProductForProductId: async (productId) => {
|
|
387
|
+
const merchantProductData = await client.query.merchantProduct.findFirst({
|
|
388
|
+
where: eq(merchantProduct.productId, productId),
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
if (!merchantProductData) return null
|
|
392
|
+
return merchantProductSchema.parse(merchantProductData)
|
|
393
|
+
},
|
|
394
|
+
getMerchantCustomerForUserId: async (userId) => {
|
|
395
|
+
const merchantCustomerData =
|
|
396
|
+
await client.query.merchantCustomer.findFirst({
|
|
397
|
+
where: eq(merchantCustomer.userId, userId),
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
if (!merchantCustomerData) return null
|
|
401
|
+
return merchantCustomerSchema.parse(merchantCustomerData)
|
|
402
|
+
},
|
|
403
|
+
getUpgradableProducts: async (options) => {
|
|
404
|
+
const { upgradableFromId, upgradableToId } = options
|
|
405
|
+
return z.array(upgradableProductSchema).parse(
|
|
406
|
+
await client.query.upgradableProducts.findMany({
|
|
407
|
+
where: and(
|
|
408
|
+
eq(upgradableProducts.upgradableFromId, upgradableFromId),
|
|
409
|
+
eq(upgradableProducts.upgradableToId, upgradableToId),
|
|
410
|
+
),
|
|
411
|
+
}),
|
|
412
|
+
)
|
|
413
|
+
},
|
|
205
414
|
availableUpgradesForProduct(
|
|
206
415
|
purchases: any,
|
|
207
416
|
productId: string,
|
|
208
|
-
): Promise<
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
417
|
+
): Promise<any[]> {
|
|
418
|
+
const previousPurchaseProductIds = purchases.map(
|
|
419
|
+
({ productId }: Purchase) => productId,
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
return client.query.upgradableProducts.findMany({
|
|
423
|
+
where: and(
|
|
424
|
+
eq(upgradableProducts.upgradableToId, productId),
|
|
425
|
+
inArray(
|
|
426
|
+
upgradableProducts.upgradableFromId,
|
|
427
|
+
previousPurchaseProductIds,
|
|
428
|
+
),
|
|
429
|
+
),
|
|
430
|
+
})
|
|
215
431
|
},
|
|
216
432
|
clearLessonProgressForUser(options: {
|
|
217
433
|
userId: string
|
|
@@ -219,11 +435,56 @@ export function mySqlDrizzleAdapter(
|
|
|
219
435
|
}): Promise<void> {
|
|
220
436
|
throw new Error('Method not implemented.')
|
|
221
437
|
},
|
|
222
|
-
completeLessonProgressForUser(options: {
|
|
438
|
+
async completeLessonProgressForUser(options: {
|
|
223
439
|
userId: string
|
|
224
440
|
lessonId?: string
|
|
225
441
|
}): Promise<ResourceProgress | null> {
|
|
226
|
-
|
|
442
|
+
if (!options.lessonId) {
|
|
443
|
+
throw new Error('No lessonId provided')
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
let lessonProgress = await client.query.resourceProgress.findFirst({
|
|
447
|
+
where: and(
|
|
448
|
+
eq(resourceProgress.userId, options.userId),
|
|
449
|
+
eq(resourceProgress.contentResourceId, options.lessonId),
|
|
450
|
+
),
|
|
451
|
+
})
|
|
452
|
+
|
|
453
|
+
const now = new Date()
|
|
454
|
+
|
|
455
|
+
if (lessonProgress) {
|
|
456
|
+
if (!lessonProgress.completedAt) {
|
|
457
|
+
await client
|
|
458
|
+
.update(resourceProgress)
|
|
459
|
+
.set({
|
|
460
|
+
completedAt: now,
|
|
461
|
+
updatedAt: now,
|
|
462
|
+
})
|
|
463
|
+
.where(eq(resourceProgress.contentResourceId, options.lessonId))
|
|
464
|
+
}
|
|
465
|
+
} else {
|
|
466
|
+
await client.insert(resourceProgress).values({
|
|
467
|
+
userId: options.userId,
|
|
468
|
+
contentResourceId: options.lessonId,
|
|
469
|
+
completedAt: now,
|
|
470
|
+
updatedAt: now,
|
|
471
|
+
})
|
|
472
|
+
}
|
|
473
|
+
lessonProgress = await client.query.resourceProgress.findFirst({
|
|
474
|
+
where: and(
|
|
475
|
+
eq(resourceProgress.userId, options.userId),
|
|
476
|
+
eq(resourceProgress.contentResourceId, options.lessonId),
|
|
477
|
+
),
|
|
478
|
+
})
|
|
479
|
+
const parsedLessonProgress =
|
|
480
|
+
resourceProgressSchema.safeParse(lessonProgress)
|
|
481
|
+
|
|
482
|
+
if (!parsedLessonProgress.success) {
|
|
483
|
+
console.error('Error parsing lesson progress', lessonProgress)
|
|
484
|
+
return null
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return parsedLessonProgress.data
|
|
227
488
|
},
|
|
228
489
|
couponForIdOrCode(options: {
|
|
229
490
|
code?: string
|
|
@@ -258,7 +519,7 @@ export function mySqlDrizzleAdapter(
|
|
|
258
519
|
)
|
|
259
520
|
|
|
260
521
|
const existingPurchaseForCharge = existingMerchantCharge
|
|
261
|
-
? await client.query.
|
|
522
|
+
? await client.query.purchases.findFirst({
|
|
262
523
|
where: eq(
|
|
263
524
|
purchaseTable.merchantChargeId,
|
|
264
525
|
existingMerchantCharge.id,
|
|
@@ -272,13 +533,13 @@ export function mySqlDrizzleAdapter(
|
|
|
272
533
|
: null
|
|
273
534
|
|
|
274
535
|
if (existingPurchaseForCharge) {
|
|
275
|
-
return
|
|
536
|
+
return existingPurchaseForCharge.id
|
|
276
537
|
}
|
|
277
538
|
|
|
278
|
-
const merchantChargeId = v4()
|
|
279
|
-
const purchaseId = v4()
|
|
539
|
+
const merchantChargeId = `mc_${v4()}`
|
|
540
|
+
const purchaseId = `purch_${v4()}`
|
|
280
541
|
|
|
281
|
-
const newMerchantCharge =
|
|
542
|
+
const newMerchantCharge = await client.insert(merchantCharge).values({
|
|
282
543
|
id: merchantChargeId,
|
|
283
544
|
userId,
|
|
284
545
|
identifier: stripeChargeId,
|
|
@@ -308,9 +569,20 @@ export function mySqlDrizzleAdapter(
|
|
|
308
569
|
eq(purchaseTable.userId, userId),
|
|
309
570
|
),
|
|
310
571
|
)
|
|
311
|
-
.
|
|
572
|
+
.where(
|
|
573
|
+
and(
|
|
574
|
+
eq(coupon.restrictedToProductId, productId),
|
|
575
|
+
eq(purchaseTable.userId, userId),
|
|
576
|
+
),
|
|
577
|
+
)
|
|
578
|
+
.then((res) => {
|
|
579
|
+
console.log({ res })
|
|
580
|
+
return res[0]?.coupons ?? null
|
|
581
|
+
}),
|
|
312
582
|
)
|
|
313
583
|
|
|
584
|
+
console.log({ existingBulkCoupon })
|
|
585
|
+
|
|
314
586
|
const isBulkPurchase =
|
|
315
587
|
quantity > 1 ||
|
|
316
588
|
Boolean(existingBulkCoupon) ||
|
|
@@ -325,7 +597,7 @@ export function mySqlDrizzleAdapter(
|
|
|
325
597
|
existingBulkCoupon !== null ? existingBulkCoupon.id : v4()
|
|
326
598
|
|
|
327
599
|
if (existingBulkCoupon !== null) {
|
|
328
|
-
couponToUpdate =
|
|
600
|
+
couponToUpdate = await client
|
|
329
601
|
.update(coupon)
|
|
330
602
|
.set({
|
|
331
603
|
maxUses: (existingBulkCoupon?.maxUses || 0) + quantity,
|
|
@@ -340,7 +612,7 @@ export function mySqlDrizzleAdapter(
|
|
|
340
612
|
)
|
|
341
613
|
: null
|
|
342
614
|
|
|
343
|
-
couponToUpdate = await
|
|
615
|
+
couponToUpdate = await client.insert(coupon).values({
|
|
344
616
|
id: bulkCouponId as string,
|
|
345
617
|
percentageDiscount: '1.0',
|
|
346
618
|
restrictedToProductId: productId,
|
|
@@ -355,13 +627,17 @@ export function mySqlDrizzleAdapter(
|
|
|
355
627
|
}
|
|
356
628
|
}
|
|
357
629
|
|
|
358
|
-
const merchantSessionId = v4()
|
|
630
|
+
const merchantSessionId = `ms_${v4()}`
|
|
359
631
|
|
|
360
|
-
const newMerchantSession =
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
632
|
+
const newMerchantSession = await client
|
|
633
|
+
.insert(merchantSession)
|
|
634
|
+
.values({
|
|
635
|
+
id: merchantSessionId,
|
|
636
|
+
identifier: checkoutSessionId,
|
|
637
|
+
merchantAccountId,
|
|
638
|
+
})
|
|
639
|
+
|
|
640
|
+
console.log({ newMerchantSession })
|
|
365
641
|
|
|
366
642
|
const merchantCouponUsed = stripeCouponId
|
|
367
643
|
? await client.query.merchantCoupon.findFirst({
|
|
@@ -369,6 +645,8 @@ export function mySqlDrizzleAdapter(
|
|
|
369
645
|
})
|
|
370
646
|
: null
|
|
371
647
|
|
|
648
|
+
console.log({ merchantCouponUsed })
|
|
649
|
+
|
|
372
650
|
const pppMerchantCoupon = appliedPPPStripeCouponId
|
|
373
651
|
? await client.query.merchantCoupon.findFirst({
|
|
374
652
|
where: and(
|
|
@@ -378,12 +656,14 @@ export function mySqlDrizzleAdapter(
|
|
|
378
656
|
})
|
|
379
657
|
: null
|
|
380
658
|
|
|
659
|
+
console.log({ pppMerchantCoupon })
|
|
660
|
+
|
|
381
661
|
const newPurchaseStatus =
|
|
382
662
|
merchantCouponUsed?.type === 'ppp' || pppMerchantCoupon
|
|
383
663
|
? 'Restricted'
|
|
384
664
|
: 'Valid'
|
|
385
665
|
|
|
386
|
-
const newPurchase =
|
|
666
|
+
const newPurchase = await client.insert(purchaseTable).values({
|
|
387
667
|
id: purchaseId,
|
|
388
668
|
status: newPurchaseStatus,
|
|
389
669
|
userId,
|
|
@@ -397,12 +677,14 @@ export function mySqlDrizzleAdapter(
|
|
|
397
677
|
couponId: usedCouponId || null,
|
|
398
678
|
})
|
|
399
679
|
|
|
680
|
+
console.log({ newPurchase })
|
|
681
|
+
|
|
400
682
|
const oneWeekInMilliseconds = 1000 * 60 * 60 * 24 * 7
|
|
401
683
|
|
|
402
|
-
const newPurchaseUserTransfer =
|
|
684
|
+
const newPurchaseUserTransfer = await client
|
|
403
685
|
.insert(purchaseUserTransfer)
|
|
404
686
|
.values({
|
|
405
|
-
id: v4()
|
|
687
|
+
id: `put_${v4()}`,
|
|
406
688
|
purchaseId: purchaseId as string,
|
|
407
689
|
expiresAt: existingPurchase
|
|
408
690
|
? new Date()
|
|
@@ -410,13 +692,19 @@ export function mySqlDrizzleAdapter(
|
|
|
410
692
|
sourceUserId: userId,
|
|
411
693
|
})
|
|
412
694
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
695
|
+
console.log({ newPurchaseUserTransfer })
|
|
696
|
+
|
|
697
|
+
// const result = await Promise.all([
|
|
698
|
+
// newMerchantCharge,
|
|
699
|
+
// newPurchase,
|
|
700
|
+
// newPurchaseUserTransfer,
|
|
701
|
+
// newMerchantSession,
|
|
702
|
+
// ...(couponToUpdate ? [couponToUpdate] : []),
|
|
703
|
+
// ])
|
|
704
|
+
//
|
|
705
|
+
// console.log('result', { result })
|
|
706
|
+
|
|
707
|
+
console.log('inside', { purchaseId })
|
|
420
708
|
|
|
421
709
|
return purchaseId
|
|
422
710
|
} catch (error) {
|
|
@@ -426,30 +714,90 @@ export function mySqlDrizzleAdapter(
|
|
|
426
714
|
}
|
|
427
715
|
})
|
|
428
716
|
|
|
429
|
-
|
|
717
|
+
console.log('putside', { purchaseId })
|
|
718
|
+
|
|
719
|
+
const parsedPurchase = purchaseSchema.safeParse(
|
|
430
720
|
await client.query.purchases.findFirst({
|
|
431
721
|
where: eq(purchaseTable.id, purchaseId as string),
|
|
432
722
|
}),
|
|
433
723
|
)
|
|
724
|
+
|
|
725
|
+
if (!parsedPurchase.success) {
|
|
726
|
+
console.error(
|
|
727
|
+
'Error parsing purchase',
|
|
728
|
+
parsedPurchase,
|
|
729
|
+
JSON.stringify(parsedPurchase, null, 2),
|
|
730
|
+
)
|
|
731
|
+
throw new Error('Error parsing purchase')
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
return parsedPurchase.data
|
|
434
735
|
},
|
|
435
|
-
findOrCreateMerchantCustomer(options: {
|
|
736
|
+
async findOrCreateMerchantCustomer(options: {
|
|
436
737
|
user: User
|
|
437
738
|
identifier: string
|
|
438
739
|
merchantAccountId: string
|
|
439
740
|
}): Promise<MerchantCustomer | null> {
|
|
440
|
-
|
|
741
|
+
const merchantCustomer = merchantCustomerSchema
|
|
742
|
+
.nullable()
|
|
743
|
+
.optional()
|
|
744
|
+
.parse(
|
|
745
|
+
await client.query.merchantCustomer.findFirst({
|
|
746
|
+
where: (merchantCustomer, { eq }) =>
|
|
747
|
+
eq(merchantCustomer.identifier, options.identifier),
|
|
748
|
+
}),
|
|
749
|
+
)
|
|
750
|
+
|
|
751
|
+
if (merchantCustomer) {
|
|
752
|
+
return merchantCustomer
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
return await this.createMerchantCustomer({
|
|
756
|
+
identifier: options.identifier,
|
|
757
|
+
merchantAccountId: options.merchantAccountId,
|
|
758
|
+
userId: options.user.id,
|
|
759
|
+
})
|
|
441
760
|
},
|
|
442
|
-
findOrCreateUser(
|
|
761
|
+
async findOrCreateUser(
|
|
443
762
|
email: string,
|
|
444
763
|
name?: string | null,
|
|
445
764
|
): Promise<{
|
|
446
765
|
user: User
|
|
447
766
|
isNewUser: boolean
|
|
448
767
|
}> {
|
|
449
|
-
|
|
768
|
+
const user = await this.getUserByEmail?.(email)
|
|
769
|
+
|
|
770
|
+
if (!user) {
|
|
771
|
+
const newUser = await this.createUser?.({
|
|
772
|
+
id: `u_${v4()}`,
|
|
773
|
+
email,
|
|
774
|
+
name,
|
|
775
|
+
emailVerified: null,
|
|
776
|
+
})
|
|
777
|
+
if (!newUser) {
|
|
778
|
+
throw new Error('Could not create user')
|
|
779
|
+
}
|
|
780
|
+
return {
|
|
781
|
+
user: newUser as User,
|
|
782
|
+
isNewUser: true,
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
return {
|
|
787
|
+
user: user as User,
|
|
788
|
+
isNewUser: false,
|
|
789
|
+
}
|
|
450
790
|
},
|
|
451
|
-
getCoupon(couponIdOrCode: string): Promise<Coupon | null> {
|
|
452
|
-
|
|
791
|
+
async getCoupon(couponIdOrCode: string): Promise<Coupon | null> {
|
|
792
|
+
return couponSchema.nullable().parse(
|
|
793
|
+
await client
|
|
794
|
+
.select()
|
|
795
|
+
.from(coupon)
|
|
796
|
+
.where(
|
|
797
|
+
or(eq(coupon.id, couponIdOrCode), eq(coupon.code, couponIdOrCode)),
|
|
798
|
+
)
|
|
799
|
+
.then((res) => res[0] ?? null),
|
|
800
|
+
)
|
|
453
801
|
},
|
|
454
802
|
getCouponWithBulkPurchases(couponId: string): Promise<
|
|
455
803
|
| (Coupon & {
|
|
@@ -479,26 +827,100 @@ export function mySqlDrizzleAdapter(
|
|
|
479
827
|
getLessonProgresses(): Promise<ResourceProgress[]> {
|
|
480
828
|
throw new Error('Method not implemented.')
|
|
481
829
|
},
|
|
482
|
-
getMerchantCharge(
|
|
830
|
+
async getMerchantCharge(
|
|
483
831
|
merchantChargeId: string,
|
|
484
832
|
): Promise<MerchantCharge | null> {
|
|
485
|
-
|
|
833
|
+
const mCharge = await client.query.merchantCharge.findFirst({
|
|
834
|
+
where: eq(merchantCharge.id, merchantChargeId),
|
|
835
|
+
})
|
|
836
|
+
console.log('mCharge', mCharge)
|
|
837
|
+
const parsed = merchantChargeSchema.safeParse(mCharge)
|
|
838
|
+
if (!parsed.success) {
|
|
839
|
+
console.error('Error parsing merchantCharge', mCharge)
|
|
840
|
+
return null
|
|
841
|
+
}
|
|
842
|
+
return parsed.data
|
|
486
843
|
},
|
|
487
|
-
|
|
844
|
+
async getMerchantCouponsForTypeAndPercent(params: {
|
|
845
|
+
type: string
|
|
846
|
+
percentageDiscount: number
|
|
847
|
+
}): Promise<MerchantCoupon[]> {
|
|
848
|
+
return z.array(merchantCouponSchema).parse(
|
|
849
|
+
await client.query.merchantCoupon.findMany({
|
|
850
|
+
where: and(
|
|
851
|
+
eq(merchantCoupon.type, params.type),
|
|
852
|
+
eq(
|
|
853
|
+
merchantCoupon.percentageDiscount,
|
|
854
|
+
params.percentageDiscount.toString(),
|
|
855
|
+
),
|
|
856
|
+
),
|
|
857
|
+
}),
|
|
858
|
+
)
|
|
859
|
+
},
|
|
860
|
+
async getMerchantCouponForTypeAndPercent(params: {
|
|
861
|
+
type: string
|
|
862
|
+
percentageDiscount: number
|
|
863
|
+
}): Promise<MerchantCoupon | null> {
|
|
864
|
+
const foundMerchantCoupon = await client.query.merchantCoupon.findFirst({
|
|
865
|
+
where: and(
|
|
866
|
+
eq(merchantCoupon.type, params.type),
|
|
867
|
+
eq(
|
|
868
|
+
merchantCoupon.percentageDiscount,
|
|
869
|
+
params.percentageDiscount.toString(),
|
|
870
|
+
),
|
|
871
|
+
),
|
|
872
|
+
})
|
|
873
|
+
|
|
874
|
+
const parsed = merchantCouponSchema
|
|
875
|
+
.nullable()
|
|
876
|
+
.safeParse(foundMerchantCoupon)
|
|
877
|
+
if (parsed.success) {
|
|
878
|
+
return parsed.data
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
return null
|
|
882
|
+
},
|
|
883
|
+
async getMerchantCoupon(
|
|
488
884
|
merchantCouponId: string,
|
|
489
885
|
): Promise<MerchantCoupon | null> {
|
|
490
|
-
|
|
886
|
+
const foundMerchantCoupon = await client.query.merchantCoupon.findFirst({
|
|
887
|
+
where: eq(merchantCoupon.id, merchantCouponId),
|
|
888
|
+
})
|
|
889
|
+
|
|
890
|
+
const parsed = merchantCouponSchema
|
|
891
|
+
.nullable()
|
|
892
|
+
.safeParse(foundMerchantCoupon)
|
|
893
|
+
if (parsed.success) {
|
|
894
|
+
return parsed.data
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
return null
|
|
491
898
|
},
|
|
492
|
-
getMerchantProduct(
|
|
899
|
+
async getMerchantProduct(
|
|
493
900
|
stripeProductId: string,
|
|
494
901
|
): Promise<MerchantProduct | null> {
|
|
495
|
-
|
|
902
|
+
return merchantProductSchema.nullable().parse(
|
|
903
|
+
await client.query.merchantProduct.findFirst({
|
|
904
|
+
where: eq(merchantProduct.identifier, stripeProductId),
|
|
905
|
+
}),
|
|
906
|
+
)
|
|
496
907
|
},
|
|
497
908
|
getPrice(productId: string): Promise<Price | null> {
|
|
498
909
|
throw new Error('Method not implemented.')
|
|
499
910
|
},
|
|
500
|
-
|
|
501
|
-
|
|
911
|
+
async getPriceForProduct(productId: string): Promise<Price | null> {
|
|
912
|
+
return priceSchema.nullable().parse(
|
|
913
|
+
await client.query.prices.findFirst({
|
|
914
|
+
where: eq(prices.productId, productId),
|
|
915
|
+
}),
|
|
916
|
+
)
|
|
917
|
+
},
|
|
918
|
+
async getProduct(productId: string): Promise<Product | null> {
|
|
919
|
+
return productSchema.nullable().parse(
|
|
920
|
+
await client.query.products.findFirst({
|
|
921
|
+
where: eq(products.id, productId),
|
|
922
|
+
}),
|
|
923
|
+
)
|
|
502
924
|
},
|
|
503
925
|
async getPurchase(purchaseId: string): Promise<Purchase | null> {
|
|
504
926
|
const purchase = await client.query.purchases.findFirst({
|
|
@@ -510,7 +932,6 @@ export function mySqlDrizzleAdapter(
|
|
|
510
932
|
async createPurchase(options): Promise<Purchase> {
|
|
511
933
|
const newPurchaseId = options.id || `purchase-${v4()}`
|
|
512
934
|
await client.insert(purchaseTable).values({
|
|
513
|
-
state: 'Valid',
|
|
514
935
|
...options,
|
|
515
936
|
id: newPurchaseId,
|
|
516
937
|
})
|
|
@@ -519,77 +940,7 @@ export function mySqlDrizzleAdapter(
|
|
|
519
940
|
|
|
520
941
|
return purchaseSchema.parse(newPurchase)
|
|
521
942
|
},
|
|
522
|
-
async getPurchaseDetails(
|
|
523
|
-
purchaseId: string,
|
|
524
|
-
userId: string,
|
|
525
|
-
): Promise<{
|
|
526
|
-
purchase?: Purchase
|
|
527
|
-
existingPurchase?: Purchase
|
|
528
|
-
availableUpgrades: UpgradableProduct[]
|
|
529
|
-
}> {
|
|
530
|
-
const allPurchases = await this.getPurchasesForUser(userId)
|
|
531
|
-
const thePurchase = await client.query.purchases.findFirst({
|
|
532
|
-
where: and(
|
|
533
|
-
eq(purchaseTable.id, purchaseId),
|
|
534
|
-
eq(purchaseTable.userId, userId),
|
|
535
|
-
),
|
|
536
|
-
with: {
|
|
537
|
-
user: true,
|
|
538
|
-
product: true,
|
|
539
|
-
bulkCoupon: true,
|
|
540
|
-
},
|
|
541
|
-
})
|
|
542
|
-
|
|
543
|
-
const parsedPurchase = purchaseSchema.safeParse(thePurchase)
|
|
544
|
-
|
|
545
|
-
if (!parsedPurchase.success) {
|
|
546
|
-
console.error('Error parsing purchase', parsedPurchase)
|
|
547
|
-
return {
|
|
548
|
-
availableUpgrades: [],
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
const purchaseCanUpgrade = ['Valid', 'Restricted'].includes(
|
|
553
|
-
parsedPurchase.data.state || '',
|
|
554
|
-
)
|
|
555
|
-
|
|
556
|
-
if (!purchaseCanUpgrade) {
|
|
557
|
-
return {
|
|
558
|
-
availableUpgrades: [],
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
const availableUpgrades = await client.query.upgradableProducts.findMany({
|
|
563
|
-
where: and(
|
|
564
|
-
eq(
|
|
565
|
-
upgradableProducts.upgradableFromId,
|
|
566
|
-
parsedPurchase.data.product?.id as string,
|
|
567
|
-
),
|
|
568
|
-
not(
|
|
569
|
-
inArray(
|
|
570
|
-
upgradableProducts.upgradableToId,
|
|
571
|
-
allPurchases.map((p) => p.product?.id as string),
|
|
572
|
-
),
|
|
573
|
-
),
|
|
574
|
-
),
|
|
575
|
-
with: {
|
|
576
|
-
upgradableTo: true,
|
|
577
|
-
upgradableFrom: true,
|
|
578
|
-
},
|
|
579
|
-
})
|
|
580
|
-
|
|
581
|
-
const existingPurchase = allPurchases.find(
|
|
582
|
-
(p) => p.product?.id === parsedPurchase.data.product?.id,
|
|
583
|
-
)
|
|
584
943
|
|
|
585
|
-
return Promise.resolve({
|
|
586
|
-
availableUpgrades: z
|
|
587
|
-
.array(upgradableProductSchema)
|
|
588
|
-
.parse(availableUpgrades),
|
|
589
|
-
existingPurchase,
|
|
590
|
-
purchase: parsedPurchase.data,
|
|
591
|
-
})
|
|
592
|
-
},
|
|
593
944
|
async getPurchaseForStripeCharge(
|
|
594
945
|
stripeChargeId: string,
|
|
595
946
|
): Promise<Purchase | null> {
|
|
@@ -604,7 +955,9 @@ export function mySqlDrizzleAdapter(
|
|
|
604
955
|
eq(merchantCharge.id, purchaseTable.merchantChargeId),
|
|
605
956
|
),
|
|
606
957
|
)
|
|
607
|
-
.then((res) =>
|
|
958
|
+
.then((res) => {
|
|
959
|
+
return res[0]?.purchases ?? null
|
|
960
|
+
}),
|
|
608
961
|
)
|
|
609
962
|
|
|
610
963
|
if (!purchase.success) {
|
|
@@ -641,7 +994,7 @@ export function mySqlDrizzleAdapter(
|
|
|
641
994
|
const userPurchases = await client.query.purchases.findMany({
|
|
642
995
|
where: and(
|
|
643
996
|
eq(purchaseTable.userId, userId),
|
|
644
|
-
inArray(purchaseTable.
|
|
997
|
+
inArray(purchaseTable.status, visiblePurchaseStates),
|
|
645
998
|
),
|
|
646
999
|
with: {
|
|
647
1000
|
user: true,
|
|
@@ -654,12 +1007,106 @@ export function mySqlDrizzleAdapter(
|
|
|
654
1007
|
const parsedPurchases = z.array(purchaseSchema).safeParse(userPurchases)
|
|
655
1008
|
|
|
656
1009
|
if (!parsedPurchases.success) {
|
|
657
|
-
console.error(
|
|
1010
|
+
console.error(
|
|
1011
|
+
'Error parsing purchases',
|
|
1012
|
+
JSON.stringify(parsedPurchases.error),
|
|
1013
|
+
)
|
|
658
1014
|
return []
|
|
659
1015
|
}
|
|
660
1016
|
|
|
661
1017
|
return parsedPurchases.data
|
|
662
1018
|
},
|
|
1019
|
+
async getPurchaseDetails(
|
|
1020
|
+
purchaseId: string,
|
|
1021
|
+
userId: string,
|
|
1022
|
+
): Promise<{
|
|
1023
|
+
purchase?: Purchase
|
|
1024
|
+
existingPurchase?: Purchase & { product?: Product | null }
|
|
1025
|
+
availableUpgrades: UpgradableProduct[]
|
|
1026
|
+
}> {
|
|
1027
|
+
const visiblePurchaseStates = ['Valid', 'Refunded', 'Restricted']
|
|
1028
|
+
|
|
1029
|
+
const userPurchases = await client.query.purchases.findMany({
|
|
1030
|
+
where: and(
|
|
1031
|
+
eq(purchaseTable.userId, userId),
|
|
1032
|
+
inArray(purchaseTable.status, visiblePurchaseStates),
|
|
1033
|
+
),
|
|
1034
|
+
with: {
|
|
1035
|
+
user: true,
|
|
1036
|
+
product: true,
|
|
1037
|
+
bulkCoupon: true,
|
|
1038
|
+
},
|
|
1039
|
+
orderBy: asc(purchaseTable.createdAt),
|
|
1040
|
+
})
|
|
1041
|
+
|
|
1042
|
+
const parsedPurchases = z.array(purchaseSchema).safeParse(userPurchases)
|
|
1043
|
+
|
|
1044
|
+
const allPurchases = parsedPurchases.success ? parsedPurchases.data : []
|
|
1045
|
+
|
|
1046
|
+
console.log('🦦', { allPurchases })
|
|
1047
|
+
|
|
1048
|
+
const thePurchase = await client.query.purchases.findFirst({
|
|
1049
|
+
where: and(
|
|
1050
|
+
eq(purchaseTable.id, purchaseId),
|
|
1051
|
+
eq(purchaseTable.userId, userId),
|
|
1052
|
+
),
|
|
1053
|
+
with: {
|
|
1054
|
+
user: true,
|
|
1055
|
+
product: true,
|
|
1056
|
+
bulkCoupon: true,
|
|
1057
|
+
},
|
|
1058
|
+
})
|
|
1059
|
+
|
|
1060
|
+
const parsedPurchase = purchaseSchema.safeParse(thePurchase)
|
|
1061
|
+
|
|
1062
|
+
if (!parsedPurchase.success) {
|
|
1063
|
+
console.error('Error parsing purchase', parsedPurchase)
|
|
1064
|
+
return {
|
|
1065
|
+
availableUpgrades: [],
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
console.log('🦦', { parsedPurchase: parsedPurchase.data })
|
|
1070
|
+
|
|
1071
|
+
const purchaseCanUpgrade = ['Valid', 'Restricted'].includes(
|
|
1072
|
+
parsedPurchase.data.state || '',
|
|
1073
|
+
)
|
|
1074
|
+
|
|
1075
|
+
let availableUpgrades: any[] = []
|
|
1076
|
+
|
|
1077
|
+
if (purchaseCanUpgrade) {
|
|
1078
|
+
availableUpgrades = await client.query.upgradableProducts.findMany({
|
|
1079
|
+
where: and(
|
|
1080
|
+
eq(
|
|
1081
|
+
upgradableProducts.upgradableFromId,
|
|
1082
|
+
parsedPurchase.data.product?.id as string,
|
|
1083
|
+
),
|
|
1084
|
+
not(
|
|
1085
|
+
inArray(
|
|
1086
|
+
upgradableProducts.upgradableToId,
|
|
1087
|
+
allPurchases.map((p) => p.product?.id as string),
|
|
1088
|
+
),
|
|
1089
|
+
),
|
|
1090
|
+
),
|
|
1091
|
+
with: {
|
|
1092
|
+
upgradableTo: true,
|
|
1093
|
+
upgradableFrom: true,
|
|
1094
|
+
},
|
|
1095
|
+
})
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
const existingPurchase = allPurchases.find(
|
|
1099
|
+
(p) => p.product?.id === parsedPurchase.data.product?.id,
|
|
1100
|
+
)
|
|
1101
|
+
|
|
1102
|
+
return Promise.resolve({
|
|
1103
|
+
availableUpgrades: z
|
|
1104
|
+
.array(upgradableProductSchema)
|
|
1105
|
+
.parse(availableUpgrades),
|
|
1106
|
+
existingPurchase,
|
|
1107
|
+
purchase: parsedPurchase.data,
|
|
1108
|
+
})
|
|
1109
|
+
},
|
|
663
1110
|
async getUserById(userId: string): Promise<User | null> {
|
|
664
1111
|
return userSchema.nullable().parse(
|
|
665
1112
|
await client.query.users.findFirst({
|
|
@@ -667,11 +1114,47 @@ export function mySqlDrizzleAdapter(
|
|
|
667
1114
|
}),
|
|
668
1115
|
)
|
|
669
1116
|
},
|
|
670
|
-
pricesOfPurchasesTowardOneBundle(
|
|
1117
|
+
async pricesOfPurchasesTowardOneBundle({
|
|
1118
|
+
userId,
|
|
1119
|
+
bundleId,
|
|
1120
|
+
}: {
|
|
671
1121
|
userId: string | undefined
|
|
672
1122
|
bundleId: string
|
|
673
1123
|
}): Promise<Price[]> {
|
|
674
|
-
|
|
1124
|
+
if (userId === undefined) return []
|
|
1125
|
+
|
|
1126
|
+
const canUpgradeProducts = await client.query.upgradableProducts.findMany(
|
|
1127
|
+
{
|
|
1128
|
+
where: eq(upgradableProducts.upgradableToId, bundleId),
|
|
1129
|
+
},
|
|
1130
|
+
)
|
|
1131
|
+
|
|
1132
|
+
const upgradableFrom = z.array(z.string()).parse(
|
|
1133
|
+
canUpgradeProducts.map((product) => {
|
|
1134
|
+
return product.upgradableFromId
|
|
1135
|
+
}),
|
|
1136
|
+
)
|
|
1137
|
+
|
|
1138
|
+
const purchases = await client.query.purchases.findMany({
|
|
1139
|
+
where: and(
|
|
1140
|
+
eq(purchaseTable.userId, userId),
|
|
1141
|
+
inArray(purchaseTable.productId, upgradableFrom),
|
|
1142
|
+
),
|
|
1143
|
+
})
|
|
1144
|
+
|
|
1145
|
+
const productsPurchased = z.array(z.string()).parse(
|
|
1146
|
+
purchases.map((purchase) => {
|
|
1147
|
+
return purchase.productId
|
|
1148
|
+
}),
|
|
1149
|
+
)
|
|
1150
|
+
|
|
1151
|
+
if (productsPurchased.length === 0) return []
|
|
1152
|
+
|
|
1153
|
+
const foundPrices = await client.query.prices.findMany({
|
|
1154
|
+
where: inArray(prices.productId, productsPurchased),
|
|
1155
|
+
})
|
|
1156
|
+
|
|
1157
|
+
return z.array(priceSchema).parse(foundPrices)
|
|
675
1158
|
},
|
|
676
1159
|
toggleLessonProgressForUser(options: {
|
|
677
1160
|
userId: string
|
|
@@ -806,7 +1289,7 @@ export function mySqlDrizzleAdapter(
|
|
|
806
1289
|
WHERE
|
|
807
1290
|
type = 'videoResource'
|
|
808
1291
|
AND (id = ${id});
|
|
809
|
-
|
|
1292
|
+
|
|
810
1293
|
`
|
|
811
1294
|
return client
|
|
812
1295
|
.execute(query)
|
|
@@ -892,7 +1375,6 @@ export function mySqlDrizzleAdapter(
|
|
|
892
1375
|
return parsedResource.data
|
|
893
1376
|
},
|
|
894
1377
|
async createUser(data) {
|
|
895
|
-
console.log(data)
|
|
896
1378
|
try {
|
|
897
1379
|
const id = crypto.randomUUID()
|
|
898
1380
|
|