@coursebuilder/adapter-drizzle 0.1.4 → 0.3.0
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-3RJVKNXB.js → chunk-4PJWD6YK.js} +421 -392
- package/dist/{chunk-WQ7UXKZC.js → chunk-J63FMGT7.js} +538 -200
- package/dist/{chunk-2CI3IGR2.js → chunk-MCARHGE5.js} +2 -2
- package/dist/{chunk-Q5WENQT6.js → chunk-PIQXK2CY.js} +2 -2
- package/dist/{chunk-5HT43CVZ.js → chunk-QMDE6HUA.js} +43 -3
- package/dist/{chunk-53266VWH.js → chunk-QY4TPO7D.js} +2 -2
- package/dist/chunk-ZD3R6UPJ.js +96 -0
- package/dist/index.js +11 -11
- package/dist/lib/mysql/index.cjs +1110 -671
- package/dist/lib/mysql/index.cjs.map +1 -1
- package/dist/lib/mysql/index.d.cts +26 -0
- package/dist/lib/mysql/index.d.ts +26 -0
- package/dist/lib/mysql/index.js +11 -11
- package/dist/lib/mysql/schemas/auth/accounts.cjs +83 -72
- package/dist/lib/mysql/schemas/auth/accounts.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/accounts.js +6 -3
- package/dist/lib/mysql/schemas/auth/role-permissions.cjs +73 -62
- package/dist/lib/mysql/schemas/auth/role-permissions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/role-permissions.js +7 -4
- package/dist/lib/mysql/schemas/auth/roles.cjs +73 -62
- package/dist/lib/mysql/schemas/auth/roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/roles.js +6 -3
- package/dist/lib/mysql/schemas/auth/sessions.cjs +73 -62
- package/dist/lib/mysql/schemas/auth/sessions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/sessions.js +7 -4
- package/dist/lib/mysql/schemas/auth/user-permissions.cjs +74 -63
- package/dist/lib/mysql/schemas/auth/user-permissions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-permissions.js +6 -3
- package/dist/lib/mysql/schemas/auth/user-roles.cjs +74 -63
- package/dist/lib/mysql/schemas/auth/user-roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-roles.js +6 -3
- package/dist/lib/mysql/schemas/auth/users.cjs +158 -147
- package/dist/lib/mysql/schemas/auth/users.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/users.js +6 -3
- package/dist/lib/mysql/schemas/commerce/coupon.cjs +209 -103
- package/dist/lib/mysql/schemas/commerce/coupon.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/coupon.d.cts +3 -0
- package/dist/lib/mysql/schemas/commerce/coupon.d.ts +3 -0
- package/dist/lib/mysql/schemas/commerce/coupon.js +6 -3
- package/dist/lib/mysql/schemas/commerce/merchant-charge.cjs +154 -10
- package/dist/lib/mysql/schemas/commerce/merchant-charge.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/merchant-charge.d.cts +7 -1
- package/dist/lib/mysql/schemas/commerce/merchant-charge.d.ts +7 -1
- package/dist/lib/mysql/schemas/commerce/merchant-charge.js +6 -1
- package/dist/lib/mysql/schemas/commerce/price.cjs +68 -57
- package/dist/lib/mysql/schemas/commerce/price.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/price.js +6 -3
- package/dist/lib/mysql/schemas/commerce/product.cjs +115 -104
- package/dist/lib/mysql/schemas/commerce/product.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/product.js +6 -3
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.cjs +251 -13
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.d.cts +7 -1
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.d.ts +7 -1
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.js +15 -1
- package/dist/lib/mysql/schemas/commerce/purchase.cjs +71 -56
- package/dist/lib/mysql/schemas/commerce/purchase.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/purchase.js +6 -3
- package/dist/lib/mysql/schemas/commerce/upgradable-products.cjs +75 -64
- package/dist/lib/mysql/schemas/commerce/upgradable-products.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/upgradable-products.js +7 -4
- package/dist/lib/mysql/schemas/communication/communication-preferences.cjs +96 -85
- package/dist/lib/mysql/schemas/communication/communication-preferences.cjs.map +1 -1
- package/dist/lib/mysql/schemas/communication/communication-preferences.js +6 -3
- package/dist/lib/mysql/schemas/content/content-contributions.cjs +100 -89
- package/dist/lib/mysql/schemas/content/content-contributions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-contributions.js +6 -3
- package/dist/lib/mysql/schemas/content/content-resource-product.cjs +66 -55
- package/dist/lib/mysql/schemas/content/content-resource-product.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-product.js +6 -3
- package/dist/lib/mysql/schemas/content/content-resource-resource.cjs +79 -68
- package/dist/lib/mysql/schemas/content/content-resource-resource.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-resource.js +6 -3
- package/dist/lib/mysql/schemas/content/content-resource.cjs +103 -92
- package/dist/lib/mysql/schemas/content/content-resource.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource.js +6 -3
- package/package.json +2 -2
- package/src/lib/mysql/index.ts +456 -95
- package/src/lib/mysql/schemas/commerce/coupon.ts +18 -1
- package/src/lib/mysql/schemas/commerce/merchant-charge.ts +29 -1
- package/src/lib/mysql/schemas/commerce/purchase-user-transfer.ts +29 -1
- package/dist/chunk-PJHGIRZM.js +0 -50
package/src/lib/mysql/index.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { addSeconds, isAfter } from 'date-fns'
|
|
|
3
3
|
import {
|
|
4
4
|
and,
|
|
5
5
|
asc,
|
|
6
|
+
desc,
|
|
6
7
|
eq,
|
|
8
|
+
gte,
|
|
7
9
|
inArray,
|
|
8
10
|
isNotNull,
|
|
9
11
|
isNull,
|
|
@@ -38,6 +40,7 @@ import {
|
|
|
38
40
|
Purchase,
|
|
39
41
|
purchaseSchema,
|
|
40
42
|
PurchaseUserTransfer,
|
|
43
|
+
purchaseUserTransferSchema,
|
|
41
44
|
PurchaseUserTransferState,
|
|
42
45
|
ResourceProgress,
|
|
43
46
|
resourceProgressSchema,
|
|
@@ -52,7 +55,9 @@ import {
|
|
|
52
55
|
} from '@coursebuilder/core/schemas/content-resource-schema'
|
|
53
56
|
import { merchantAccountSchema } from '@coursebuilder/core/schemas/merchant-account-schema'
|
|
54
57
|
import { merchantCustomerSchema } from '@coursebuilder/core/schemas/merchant-customer-schema'
|
|
58
|
+
import { type ModuleProgress } from '@coursebuilder/core/schemas/resource-progress-schema'
|
|
55
59
|
import { VideoResourceSchema } from '@coursebuilder/core/schemas/video-resource'
|
|
60
|
+
import { logger } from '@coursebuilder/core/utils/logger'
|
|
56
61
|
import { validateCoupon } from '@coursebuilder/core/utils/validate-coupon'
|
|
57
62
|
|
|
58
63
|
import {
|
|
@@ -93,7 +98,10 @@ import {
|
|
|
93
98
|
getCouponSchema,
|
|
94
99
|
} from './schemas/commerce/coupon.js'
|
|
95
100
|
import { getMerchantAccountSchema } from './schemas/commerce/merchant-account.js'
|
|
96
|
-
import {
|
|
101
|
+
import {
|
|
102
|
+
getMerchantChargeRelationsSchema,
|
|
103
|
+
getMerchantChargeSchema,
|
|
104
|
+
} from './schemas/commerce/merchant-charge.js'
|
|
97
105
|
import { getMerchantCouponSchema } from './schemas/commerce/merchant-coupon.js'
|
|
98
106
|
import { getMerchantCustomerSchema } from './schemas/commerce/merchant-customer.js'
|
|
99
107
|
import { getMerchantPriceSchema } from './schemas/commerce/merchant-price.js'
|
|
@@ -104,7 +112,10 @@ import {
|
|
|
104
112
|
getProductRelationsSchema,
|
|
105
113
|
getProductSchema,
|
|
106
114
|
} from './schemas/commerce/product.js'
|
|
107
|
-
import {
|
|
115
|
+
import {
|
|
116
|
+
getPurchaseUserTransferRelationsSchema,
|
|
117
|
+
getPurchaseUserTransferSchema,
|
|
118
|
+
} from './schemas/commerce/purchase-user-transfer.js'
|
|
108
119
|
import {
|
|
109
120
|
getPurchaseRelationsSchema,
|
|
110
121
|
getPurchaseSchema,
|
|
@@ -164,6 +175,7 @@ export function getCourseBuilderSchema(mysqlTable: MySqlTableFn) {
|
|
|
164
175
|
couponRelations: getCouponRelationsSchema(mysqlTable),
|
|
165
176
|
merchantAccount: getMerchantAccountSchema(mysqlTable),
|
|
166
177
|
merchantCharge: getMerchantChargeSchema(mysqlTable),
|
|
178
|
+
merchantChargeRelations: getMerchantChargeRelationsSchema(mysqlTable),
|
|
167
179
|
merchantCoupon: getMerchantCouponSchema(mysqlTable),
|
|
168
180
|
merchantCustomer: getMerchantCustomerSchema(mysqlTable),
|
|
169
181
|
merchantPrice: getMerchantPriceSchema(mysqlTable),
|
|
@@ -174,6 +186,8 @@ export function getCourseBuilderSchema(mysqlTable: MySqlTableFn) {
|
|
|
174
186
|
purchases: getPurchaseSchema(mysqlTable),
|
|
175
187
|
purchaseRelations: getPurchaseRelationsSchema(mysqlTable),
|
|
176
188
|
purchaseUserTransfer: getPurchaseUserTransferSchema(mysqlTable),
|
|
189
|
+
purchaseUserTransferRelations:
|
|
190
|
+
getPurchaseUserTransferRelationsSchema(mysqlTable),
|
|
177
191
|
communicationChannel: getCommunicationChannelSchema(mysqlTable),
|
|
178
192
|
communicationPreferenceTypes:
|
|
179
193
|
getCommunicationPreferenceTypesSchema(mysqlTable),
|
|
@@ -234,7 +248,7 @@ export function mySqlDrizzleAdapter(
|
|
|
234
248
|
resourceProgress,
|
|
235
249
|
} = createTables(tableFn)
|
|
236
250
|
|
|
237
|
-
|
|
251
|
+
const adapter: CourseBuilderAdapter = {
|
|
238
252
|
client,
|
|
239
253
|
async redeemFullPriceCoupon(options) {
|
|
240
254
|
const {
|
|
@@ -246,7 +260,7 @@ export function mySqlDrizzleAdapter(
|
|
|
246
260
|
} = options
|
|
247
261
|
const email = String(baseEmail).replace(' ', '+')
|
|
248
262
|
|
|
249
|
-
const coupon = await
|
|
263
|
+
const coupon = await adapter.getCouponWithBulkPurchases(couponId)
|
|
250
264
|
|
|
251
265
|
const productId =
|
|
252
266
|
(coupon && (coupon.restrictedToProductId as string)) ||
|
|
@@ -259,16 +273,14 @@ export function mySqlDrizzleAdapter(
|
|
|
259
273
|
if (coupon && couponValidation.isRedeemable) {
|
|
260
274
|
// if the Coupon is the Bulk Coupon of a Bulk Purchase,
|
|
261
275
|
// then a bulk coupon is being redeemed
|
|
262
|
-
const bulkCouponRedemption = Boolean(
|
|
263
|
-
coupon.bulkCouponPurchases[0]?.bulkCouponId,
|
|
264
|
-
)
|
|
276
|
+
const bulkCouponRedemption = Boolean(coupon.bulkPurchase?.bulkCouponId)
|
|
265
277
|
|
|
266
|
-
const { user } = await
|
|
278
|
+
const { user } = await adapter.findOrCreateUser(email)
|
|
267
279
|
|
|
268
280
|
if (!user) throw new Error(`unable-to-create-user-${email}`)
|
|
269
281
|
|
|
270
282
|
const currentUser = currentUserId
|
|
271
|
-
? await
|
|
283
|
+
? await adapter.getUserById(currentUserId)
|
|
272
284
|
: null
|
|
273
285
|
|
|
274
286
|
const redeemingForCurrentUser = currentUser?.id === user.id
|
|
@@ -277,7 +289,7 @@ export function mySqlDrizzleAdapter(
|
|
|
277
289
|
// Purchase record for this product that is valid and wasn't a bulk
|
|
278
290
|
// coupon purchase.
|
|
279
291
|
const existingPurchases =
|
|
280
|
-
await
|
|
292
|
+
await adapter.getExistingNonBulkValidPurchasesOfProduct({
|
|
281
293
|
userId: user.id,
|
|
282
294
|
productId,
|
|
283
295
|
})
|
|
@@ -287,7 +299,7 @@ export function mySqlDrizzleAdapter(
|
|
|
287
299
|
|
|
288
300
|
const purchaseId = `purchase-${v4()}`
|
|
289
301
|
|
|
290
|
-
await
|
|
302
|
+
await adapter.createPurchase({
|
|
291
303
|
id: purchaseId,
|
|
292
304
|
userId: user.id,
|
|
293
305
|
couponId: bulkCouponRedemption ? null : coupon.id,
|
|
@@ -299,11 +311,11 @@ export function mySqlDrizzleAdapter(
|
|
|
299
311
|
},
|
|
300
312
|
})
|
|
301
313
|
|
|
302
|
-
const newPurchase = await
|
|
314
|
+
const newPurchase = await adapter.getPurchase(purchaseId)
|
|
303
315
|
|
|
304
|
-
await
|
|
316
|
+
await adapter.incrementCouponUsedCount(coupon.id)
|
|
305
317
|
|
|
306
|
-
await
|
|
318
|
+
await adapter.createPurchaseTransfer({
|
|
307
319
|
sourceUserId: user.id,
|
|
308
320
|
purchaseId: purchaseId,
|
|
309
321
|
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
|
|
@@ -411,7 +423,7 @@ export function mySqlDrizzleAdapter(
|
|
|
411
423
|
}),
|
|
412
424
|
)
|
|
413
425
|
},
|
|
414
|
-
availableUpgradesForProduct(
|
|
426
|
+
async availableUpgradesForProduct(
|
|
415
427
|
purchases: any,
|
|
416
428
|
productId: string,
|
|
417
429
|
): Promise<any[]> {
|
|
@@ -419,21 +431,24 @@ export function mySqlDrizzleAdapter(
|
|
|
419
431
|
({ productId }: Purchase) => productId,
|
|
420
432
|
)
|
|
421
433
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
434
|
+
if (previousPurchaseProductIds.length > 0) {
|
|
435
|
+
return await client.query.upgradableProducts.findMany({
|
|
436
|
+
where: and(
|
|
437
|
+
eq(upgradableProducts.upgradableToId, productId),
|
|
438
|
+
inArray(
|
|
439
|
+
upgradableProducts.upgradableFromId,
|
|
440
|
+
previousPurchaseProductIds,
|
|
441
|
+
),
|
|
428
442
|
),
|
|
429
|
-
)
|
|
430
|
-
}
|
|
443
|
+
})
|
|
444
|
+
}
|
|
445
|
+
return []
|
|
431
446
|
},
|
|
432
447
|
clearLessonProgressForUser(options: {
|
|
433
448
|
userId: string
|
|
434
449
|
lessons: { id: string; slug: string }[]
|
|
435
450
|
}): Promise<void> {
|
|
436
|
-
throw new Error('Method not implemented.')
|
|
451
|
+
throw new Error('clearLessonProgressForUser Method not implemented.')
|
|
437
452
|
},
|
|
438
453
|
async completeLessonProgressForUser(options: {
|
|
439
454
|
userId: string
|
|
@@ -486,11 +501,40 @@ export function mySqlDrizzleAdapter(
|
|
|
486
501
|
|
|
487
502
|
return parsedLessonProgress.data
|
|
488
503
|
},
|
|
489
|
-
couponForIdOrCode(options: {
|
|
504
|
+
async couponForIdOrCode(options: {
|
|
490
505
|
code?: string
|
|
491
506
|
couponId?: string
|
|
492
507
|
}): Promise<(Coupon & { merchantCoupon: MerchantCoupon }) | null> {
|
|
493
|
-
|
|
508
|
+
if (!options.couponId && !options.code) return null
|
|
509
|
+
const couponForIdOrCode = await client.query.coupon.findFirst({
|
|
510
|
+
where: or(
|
|
511
|
+
and(
|
|
512
|
+
or(
|
|
513
|
+
options.code ? eq(coupon.code, options.code) : undefined,
|
|
514
|
+
options.couponId ? eq(coupon.id, options.couponId) : undefined,
|
|
515
|
+
),
|
|
516
|
+
gte(coupon.expires, new Date()),
|
|
517
|
+
),
|
|
518
|
+
and(
|
|
519
|
+
or(
|
|
520
|
+
options.code ? eq(coupon.code, options.code) : undefined,
|
|
521
|
+
options.couponId ? eq(coupon.id, options.couponId) : undefined,
|
|
522
|
+
),
|
|
523
|
+
isNull(coupon.expires),
|
|
524
|
+
),
|
|
525
|
+
),
|
|
526
|
+
with: {
|
|
527
|
+
merchantCoupon: true,
|
|
528
|
+
},
|
|
529
|
+
})
|
|
530
|
+
|
|
531
|
+
if (!couponForIdOrCode) return null
|
|
532
|
+
|
|
533
|
+
return couponSchema
|
|
534
|
+
.extend({
|
|
535
|
+
merchantCoupon: merchantCouponSchema,
|
|
536
|
+
})
|
|
537
|
+
.parse(couponForIdOrCode)
|
|
494
538
|
},
|
|
495
539
|
async createMerchantChargeAndPurchase(options): Promise<Purchase> {
|
|
496
540
|
const purchaseId = await client.transaction(async (trx) => {
|
|
@@ -576,13 +620,10 @@ export function mySqlDrizzleAdapter(
|
|
|
576
620
|
),
|
|
577
621
|
)
|
|
578
622
|
.then((res) => {
|
|
579
|
-
console.log({ res })
|
|
580
623
|
return res[0]?.coupons ?? null
|
|
581
624
|
}),
|
|
582
625
|
)
|
|
583
626
|
|
|
584
|
-
console.log({ existingBulkCoupon })
|
|
585
|
-
|
|
586
627
|
const isBulkPurchase =
|
|
587
628
|
quantity > 1 ||
|
|
588
629
|
Boolean(existingBulkCoupon) ||
|
|
@@ -637,16 +678,12 @@ export function mySqlDrizzleAdapter(
|
|
|
637
678
|
merchantAccountId,
|
|
638
679
|
})
|
|
639
680
|
|
|
640
|
-
console.log({ newMerchantSession })
|
|
641
|
-
|
|
642
681
|
const merchantCouponUsed = stripeCouponId
|
|
643
682
|
? await client.query.merchantCoupon.findFirst({
|
|
644
683
|
where: eq(merchantCoupon.identifier, stripeCouponId),
|
|
645
684
|
})
|
|
646
685
|
: null
|
|
647
686
|
|
|
648
|
-
console.log({ merchantCouponUsed })
|
|
649
|
-
|
|
650
687
|
const pppMerchantCoupon = appliedPPPStripeCouponId
|
|
651
688
|
? await client.query.merchantCoupon.findFirst({
|
|
652
689
|
where: and(
|
|
@@ -656,8 +693,6 @@ export function mySqlDrizzleAdapter(
|
|
|
656
693
|
})
|
|
657
694
|
: null
|
|
658
695
|
|
|
659
|
-
console.log({ pppMerchantCoupon })
|
|
660
|
-
|
|
661
696
|
const newPurchaseStatus =
|
|
662
697
|
merchantCouponUsed?.type === 'ppp' || pppMerchantCoupon
|
|
663
698
|
? 'Restricted'
|
|
@@ -677,8 +712,6 @@ export function mySqlDrizzleAdapter(
|
|
|
677
712
|
couponId: usedCouponId || null,
|
|
678
713
|
})
|
|
679
714
|
|
|
680
|
-
console.log({ newPurchase })
|
|
681
|
-
|
|
682
715
|
const oneWeekInMilliseconds = 1000 * 60 * 60 * 24 * 7
|
|
683
716
|
|
|
684
717
|
const newPurchaseUserTransfer = await client
|
|
@@ -692,8 +725,6 @@ export function mySqlDrizzleAdapter(
|
|
|
692
725
|
sourceUserId: userId,
|
|
693
726
|
})
|
|
694
727
|
|
|
695
|
-
console.log({ newPurchaseUserTransfer })
|
|
696
|
-
|
|
697
728
|
// const result = await Promise.all([
|
|
698
729
|
// newMerchantCharge,
|
|
699
730
|
// newPurchase,
|
|
@@ -704,8 +735,6 @@ export function mySqlDrizzleAdapter(
|
|
|
704
735
|
//
|
|
705
736
|
// console.log('result', { result })
|
|
706
737
|
|
|
707
|
-
console.log('inside', { purchaseId })
|
|
708
|
-
|
|
709
738
|
return purchaseId
|
|
710
739
|
} catch (error) {
|
|
711
740
|
console.error(error)
|
|
@@ -714,8 +743,6 @@ export function mySqlDrizzleAdapter(
|
|
|
714
743
|
}
|
|
715
744
|
})
|
|
716
745
|
|
|
717
|
-
console.log('putside', { purchaseId })
|
|
718
|
-
|
|
719
746
|
const parsedPurchase = purchaseSchema.safeParse(
|
|
720
747
|
await client.query.purchases.findFirst({
|
|
721
748
|
where: eq(purchaseTable.id, purchaseId as string),
|
|
@@ -752,7 +779,7 @@ export function mySqlDrizzleAdapter(
|
|
|
752
779
|
return merchantCustomer
|
|
753
780
|
}
|
|
754
781
|
|
|
755
|
-
return await
|
|
782
|
+
return await adapter.createMerchantCustomer({
|
|
756
783
|
identifier: options.identifier,
|
|
757
784
|
merchantAccountId: options.merchantAccountId,
|
|
758
785
|
userId: options.user.id,
|
|
@@ -765,10 +792,10 @@ export function mySqlDrizzleAdapter(
|
|
|
765
792
|
user: User
|
|
766
793
|
isNewUser: boolean
|
|
767
794
|
}> {
|
|
768
|
-
const user = await
|
|
795
|
+
const user = await adapter.getUserByEmail?.(email)
|
|
769
796
|
|
|
770
797
|
if (!user) {
|
|
771
|
-
const newUser = await
|
|
798
|
+
const newUser = await adapter.createUser?.({
|
|
772
799
|
id: `u_${v4()}`,
|
|
773
800
|
email,
|
|
774
801
|
name,
|
|
@@ -799,19 +826,94 @@ export function mySqlDrizzleAdapter(
|
|
|
799
826
|
.then((res) => res[0] ?? null),
|
|
800
827
|
)
|
|
801
828
|
},
|
|
802
|
-
getCouponWithBulkPurchases(couponId: string): Promise<
|
|
829
|
+
async getCouponWithBulkPurchases(couponId: string): Promise<
|
|
803
830
|
| (Coupon & {
|
|
804
|
-
|
|
831
|
+
bulkPurchase?: Purchase | null
|
|
832
|
+
bulkCouponPurchases: { bulkCouponId?: string | null }[]
|
|
805
833
|
})
|
|
806
834
|
| null
|
|
807
835
|
> {
|
|
808
|
-
|
|
836
|
+
logger.debug('getCouponWithBulkPurchases', { couponId })
|
|
837
|
+
let couponData
|
|
838
|
+
try {
|
|
839
|
+
couponData =
|
|
840
|
+
(await client.query.coupon.findFirst({
|
|
841
|
+
where: eq(coupon.id, couponId),
|
|
842
|
+
with: {
|
|
843
|
+
bulkPurchase: true,
|
|
844
|
+
bulkCouponPurchases: true,
|
|
845
|
+
},
|
|
846
|
+
})) || null
|
|
847
|
+
} catch (e) {
|
|
848
|
+
console.log('getCouponWithBulkPurchases')
|
|
849
|
+
logger.error(e as Error)
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
if (!couponData) {
|
|
853
|
+
logger.debug('getCouponWithBulkPurchases', {
|
|
854
|
+
couponId,
|
|
855
|
+
error: 'no coupon found',
|
|
856
|
+
})
|
|
857
|
+
return null
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
const parsedCoupon = couponSchema
|
|
861
|
+
.merge(
|
|
862
|
+
z.object({
|
|
863
|
+
bulkCouponPurchases: z.array(purchaseSchema),
|
|
864
|
+
bulkPurchase: purchaseSchema.nullable().optional(),
|
|
865
|
+
}),
|
|
866
|
+
)
|
|
867
|
+
.nullable()
|
|
868
|
+
.safeParse(couponData)
|
|
869
|
+
|
|
870
|
+
if (!parsedCoupon.success) {
|
|
871
|
+
console.error('Error parsing coupon', couponData)
|
|
872
|
+
return null
|
|
873
|
+
}
|
|
874
|
+
return parsedCoupon.data
|
|
809
875
|
},
|
|
810
|
-
getDefaultCoupon(productIds?: string[]): Promise<{
|
|
876
|
+
async getDefaultCoupon(productIds?: string[]): Promise<{
|
|
811
877
|
defaultMerchantCoupon: MerchantCoupon
|
|
812
878
|
defaultCoupon: Coupon
|
|
813
879
|
} | null> {
|
|
814
|
-
|
|
880
|
+
const activeSaleCoupon = await client.query.coupon.findFirst({
|
|
881
|
+
where: and(
|
|
882
|
+
eq(coupon.status, 1),
|
|
883
|
+
eq(coupon.default, true),
|
|
884
|
+
gte(coupon.expires, new Date()),
|
|
885
|
+
or(
|
|
886
|
+
productIds
|
|
887
|
+
? inArray(coupon.restrictedToProductId, productIds)
|
|
888
|
+
: undefined,
|
|
889
|
+
isNull(coupon.restrictedToProductId),
|
|
890
|
+
),
|
|
891
|
+
),
|
|
892
|
+
orderBy: desc(coupon.percentageDiscount),
|
|
893
|
+
with: {
|
|
894
|
+
merchantCoupon: true,
|
|
895
|
+
product: true,
|
|
896
|
+
},
|
|
897
|
+
})
|
|
898
|
+
if (activeSaleCoupon) {
|
|
899
|
+
const { restrictedToProductId } = activeSaleCoupon
|
|
900
|
+
const validForProdcutId = restrictedToProductId
|
|
901
|
+
? productIds?.includes(restrictedToProductId as string)
|
|
902
|
+
: true
|
|
903
|
+
|
|
904
|
+
const { merchantCoupon: defaultMerchantCoupon, ...defaultCoupon } =
|
|
905
|
+
activeSaleCoupon
|
|
906
|
+
|
|
907
|
+
if (validForProdcutId) {
|
|
908
|
+
return {
|
|
909
|
+
defaultMerchantCoupon: merchantCouponSchema.parse(
|
|
910
|
+
defaultMerchantCoupon,
|
|
911
|
+
),
|
|
912
|
+
defaultCoupon: couponSchema.parse(defaultCoupon),
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
return null
|
|
815
917
|
},
|
|
816
918
|
getLessonProgressCountsByDate(): Promise<
|
|
817
919
|
{
|
|
@@ -819,13 +921,141 @@ export function mySqlDrizzleAdapter(
|
|
|
819
921
|
completedAt: string
|
|
820
922
|
}[]
|
|
821
923
|
> {
|
|
822
|
-
throw new Error('Method not implemented.')
|
|
924
|
+
throw new Error('getLessonProgressCountsByDate Method not implemented.')
|
|
823
925
|
},
|
|
824
|
-
getLessonProgressForUser(
|
|
825
|
-
|
|
926
|
+
async getLessonProgressForUser(
|
|
927
|
+
userId: string,
|
|
928
|
+
): Promise<ResourceProgress[]> {
|
|
929
|
+
const userProgress = await client.query.resourceProgress.findMany({
|
|
930
|
+
where: eq(resourceProgress.userId, userId),
|
|
931
|
+
})
|
|
932
|
+
const parsed = z.array(resourceProgressSchema).safeParse(userProgress)
|
|
933
|
+
if (!parsed.success) {
|
|
934
|
+
console.error('Error parsing user progress', userProgress)
|
|
935
|
+
return []
|
|
936
|
+
}
|
|
937
|
+
return parsed.data
|
|
938
|
+
},
|
|
939
|
+
async getModuleProgressForUser(
|
|
940
|
+
userIdOrEmail: string,
|
|
941
|
+
moduleIdOrSlug: string,
|
|
942
|
+
): Promise<ModuleProgress> {
|
|
943
|
+
const module = await client.query.contentResource.findFirst({
|
|
944
|
+
where: or(
|
|
945
|
+
eq(contentResource.id, moduleIdOrSlug),
|
|
946
|
+
eq(
|
|
947
|
+
sql`JSON_EXTRACT (${contentResource.fields}, "$.slug")`,
|
|
948
|
+
moduleIdOrSlug,
|
|
949
|
+
),
|
|
950
|
+
),
|
|
951
|
+
with: {
|
|
952
|
+
resources: {
|
|
953
|
+
orderBy: asc(contentResourceResource.position),
|
|
954
|
+
},
|
|
955
|
+
},
|
|
956
|
+
})
|
|
957
|
+
|
|
958
|
+
const parsedModule = ContentResourceSchema.parse(module)
|
|
959
|
+
|
|
960
|
+
const moduleResources =
|
|
961
|
+
await client.query.contentResourceResource.findMany({
|
|
962
|
+
where: inArray(
|
|
963
|
+
contentResourceResource.resourceOfId,
|
|
964
|
+
parsedModule.resources?.map((r) => r.resourceId) ?? [],
|
|
965
|
+
),
|
|
966
|
+
orderBy: asc(contentResourceResource.position),
|
|
967
|
+
})
|
|
968
|
+
|
|
969
|
+
const parsedModuleResources = z
|
|
970
|
+
.array(ContentResourceResourceSchema)
|
|
971
|
+
.safeParse(moduleResources)
|
|
972
|
+
|
|
973
|
+
if (!parsedModuleResources.success) {
|
|
974
|
+
console.error(
|
|
975
|
+
'Error parsing module resources',
|
|
976
|
+
parsedModuleResources.error,
|
|
977
|
+
)
|
|
978
|
+
return {
|
|
979
|
+
completedLessons: [],
|
|
980
|
+
nextResource: null,
|
|
981
|
+
percentCompleted: 0,
|
|
982
|
+
completedLessonsCount: 0,
|
|
983
|
+
totalLessonsCount: 0,
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
const user = await client.query.users.findFirst({
|
|
988
|
+
where: or(eq(users.id, userIdOrEmail), eq(users.email, userIdOrEmail)),
|
|
989
|
+
with: {
|
|
990
|
+
roles: true,
|
|
991
|
+
},
|
|
992
|
+
})
|
|
993
|
+
|
|
994
|
+
if (!user) {
|
|
995
|
+
console.error('User not found', userIdOrEmail)
|
|
996
|
+
return {
|
|
997
|
+
completedLessons: [],
|
|
998
|
+
nextResource: null,
|
|
999
|
+
percentCompleted: 0,
|
|
1000
|
+
completedLessonsCount: 0,
|
|
1001
|
+
totalLessonsCount: parsedModuleResources.data.length,
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
const parsedUser = userSchema.parse(user)
|
|
1006
|
+
|
|
1007
|
+
const userProgress = await client.query.resourceProgress.findMany({
|
|
1008
|
+
where: and(
|
|
1009
|
+
eq(resourceProgress.userId, parsedUser.id),
|
|
1010
|
+
isNotNull(resourceProgress.completedAt),
|
|
1011
|
+
inArray(
|
|
1012
|
+
resourceProgress.contentResourceId,
|
|
1013
|
+
parsedModuleResources.data.map((r) => r.resourceId),
|
|
1014
|
+
),
|
|
1015
|
+
),
|
|
1016
|
+
orderBy: asc(resourceProgress.completedAt),
|
|
1017
|
+
})
|
|
1018
|
+
|
|
1019
|
+
const nextResourceId = moduleResources.find(
|
|
1020
|
+
(r) => !userProgress.find((p) => p.contentResourceId === r.resourceId),
|
|
1021
|
+
)?.resourceId
|
|
1022
|
+
|
|
1023
|
+
const nextResource = await client.query.contentResource.findFirst({
|
|
1024
|
+
where: eq(contentResource.id, nextResourceId as string),
|
|
1025
|
+
})
|
|
1026
|
+
|
|
1027
|
+
const parsedNextResource = ContentResourceSchema.nullable()
|
|
1028
|
+
.optional()
|
|
1029
|
+
.default(null)
|
|
1030
|
+
.parse(nextResource)
|
|
1031
|
+
|
|
1032
|
+
const parsedProgress = z
|
|
1033
|
+
.array(resourceProgressSchema)
|
|
1034
|
+
.safeParse(userProgress)
|
|
1035
|
+
if (!parsedProgress.success) {
|
|
1036
|
+
console.error('Error parsing user progress', parsedProgress.error)
|
|
1037
|
+
return {
|
|
1038
|
+
completedLessons: [],
|
|
1039
|
+
nextResource: null,
|
|
1040
|
+
percentCompleted: 0,
|
|
1041
|
+
completedLessonsCount: 0,
|
|
1042
|
+
totalLessonsCount: parsedModuleResources.data.length,
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
const percentCompleted = Math.round(
|
|
1046
|
+
(parsedProgress.data.length / parsedModuleResources.data.length) * 100,
|
|
1047
|
+
)
|
|
1048
|
+
|
|
1049
|
+
return {
|
|
1050
|
+
completedLessons: parsedProgress.data,
|
|
1051
|
+
nextResource: parsedNextResource,
|
|
1052
|
+
percentCompleted,
|
|
1053
|
+
completedLessonsCount: parsedProgress.data.length,
|
|
1054
|
+
totalLessonsCount: parsedModuleResources.data.length,
|
|
1055
|
+
}
|
|
826
1056
|
},
|
|
827
1057
|
getLessonProgresses(): Promise<ResourceProgress[]> {
|
|
828
|
-
throw new Error('Method not implemented.')
|
|
1058
|
+
throw new Error('getLessonProgresses Method not implemented.')
|
|
829
1059
|
},
|
|
830
1060
|
async getMerchantCharge(
|
|
831
1061
|
merchantChargeId: string,
|
|
@@ -833,7 +1063,6 @@ export function mySqlDrizzleAdapter(
|
|
|
833
1063
|
const mCharge = await client.query.merchantCharge.findFirst({
|
|
834
1064
|
where: eq(merchantCharge.id, merchantChargeId),
|
|
835
1065
|
})
|
|
836
|
-
console.log('mCharge', mCharge)
|
|
837
1066
|
const parsed = merchantChargeSchema.safeParse(mCharge)
|
|
838
1067
|
if (!parsed.success) {
|
|
839
1068
|
console.error('Error parsing merchantCharge', mCharge)
|
|
@@ -906,7 +1135,7 @@ export function mySqlDrizzleAdapter(
|
|
|
906
1135
|
)
|
|
907
1136
|
},
|
|
908
1137
|
getPrice(productId: string): Promise<Price | null> {
|
|
909
|
-
throw new Error('
|
|
1138
|
+
throw new Error('getPrice not implemented.')
|
|
910
1139
|
},
|
|
911
1140
|
async getPriceForProduct(productId: string): Promise<Price | null> {
|
|
912
1141
|
return priceSchema.nullable().parse(
|
|
@@ -936,7 +1165,7 @@ export function mySqlDrizzleAdapter(
|
|
|
936
1165
|
id: newPurchaseId,
|
|
937
1166
|
})
|
|
938
1167
|
|
|
939
|
-
const newPurchase = await
|
|
1168
|
+
const newPurchase = await adapter.getPurchase(newPurchaseId)
|
|
940
1169
|
|
|
941
1170
|
return purchaseSchema.parse(newPurchase)
|
|
942
1171
|
},
|
|
@@ -944,20 +1173,28 @@ export function mySqlDrizzleAdapter(
|
|
|
944
1173
|
async getPurchaseForStripeCharge(
|
|
945
1174
|
stripeChargeId: string,
|
|
946
1175
|
): Promise<Purchase | null> {
|
|
1176
|
+
logger.debug('getPurchaseForStripeCharge', { stripeChargeId })
|
|
1177
|
+
|
|
1178
|
+
const chargeForPurchase = merchantChargeSchema.nullable().parse(
|
|
1179
|
+
(await client.query.merchantCharge.findFirst({
|
|
1180
|
+
where: eq(merchantCharge.identifier, stripeChargeId),
|
|
1181
|
+
})) || null,
|
|
1182
|
+
)
|
|
1183
|
+
|
|
1184
|
+
if (!chargeForPurchase) {
|
|
1185
|
+
logger.error(new Error('No charge found for purchase'))
|
|
1186
|
+
return null
|
|
1187
|
+
}
|
|
1188
|
+
|
|
947
1189
|
const purchase = purchaseSchema.safeParse(
|
|
948
|
-
await client
|
|
949
|
-
.
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
),
|
|
957
|
-
)
|
|
958
|
-
.then((res) => {
|
|
959
|
-
return res[0]?.purchases ?? null
|
|
960
|
-
}),
|
|
1190
|
+
await client.query.purchases.findFirst({
|
|
1191
|
+
where: eq(purchaseTable.merchantChargeId, chargeForPurchase.id),
|
|
1192
|
+
with: {
|
|
1193
|
+
user: true,
|
|
1194
|
+
product: true,
|
|
1195
|
+
bulkCoupon: true,
|
|
1196
|
+
},
|
|
1197
|
+
}),
|
|
961
1198
|
)
|
|
962
1199
|
|
|
963
1200
|
if (!purchase.success) {
|
|
@@ -966,7 +1203,7 @@ export function mySqlDrizzleAdapter(
|
|
|
966
1203
|
|
|
967
1204
|
return purchase.data
|
|
968
1205
|
},
|
|
969
|
-
getPurchaseUserTransferById(options: { id: string }): Promise<
|
|
1206
|
+
async getPurchaseUserTransferById(options: { id: string }): Promise<
|
|
970
1207
|
| (PurchaseUserTransfer & {
|
|
971
1208
|
sourceUser: User
|
|
972
1209
|
targetUser: User | null
|
|
@@ -974,15 +1211,51 @@ export function mySqlDrizzleAdapter(
|
|
|
974
1211
|
})
|
|
975
1212
|
| null
|
|
976
1213
|
> {
|
|
977
|
-
|
|
1214
|
+
const purchaseTransferData =
|
|
1215
|
+
await client.query.purchaseUserTransfer.findFirst({
|
|
1216
|
+
where: eq(purchaseUserTransfer.id, options.id),
|
|
1217
|
+
with: {
|
|
1218
|
+
sourceUser: true,
|
|
1219
|
+
targetUser: true,
|
|
1220
|
+
purchase: true,
|
|
1221
|
+
},
|
|
1222
|
+
})
|
|
1223
|
+
|
|
1224
|
+
return purchaseUserTransferSchema
|
|
1225
|
+
.merge(
|
|
1226
|
+
z.object({
|
|
1227
|
+
sourceUser: userSchema,
|
|
1228
|
+
targetUser: userSchema.nullable(),
|
|
1229
|
+
purchase: purchaseSchema,
|
|
1230
|
+
}),
|
|
1231
|
+
)
|
|
1232
|
+
.nullable()
|
|
1233
|
+
.parse(purchaseTransferData)
|
|
978
1234
|
},
|
|
979
|
-
getPurchaseWithUser(purchaseId: string): Promise<
|
|
1235
|
+
async getPurchaseWithUser(purchaseId: string): Promise<
|
|
980
1236
|
| (Purchase & {
|
|
981
1237
|
user: User
|
|
982
1238
|
})
|
|
983
1239
|
| null
|
|
984
1240
|
> {
|
|
985
|
-
|
|
1241
|
+
const purchaseData =
|
|
1242
|
+
(await client.query.purchases.findFirst({
|
|
1243
|
+
where: eq(purchaseTable.id, purchaseId),
|
|
1244
|
+
with: {
|
|
1245
|
+
user: true,
|
|
1246
|
+
},
|
|
1247
|
+
})) || null
|
|
1248
|
+
|
|
1249
|
+
const parsedPurchase = purchaseSchema
|
|
1250
|
+
.merge(z.object({ user: userSchema }))
|
|
1251
|
+
.nullable()
|
|
1252
|
+
.safeParse(purchaseData)
|
|
1253
|
+
|
|
1254
|
+
if (!parsedPurchase.success) {
|
|
1255
|
+
console.error('Error parsing purchase', parsedPurchase.error)
|
|
1256
|
+
return null
|
|
1257
|
+
}
|
|
1258
|
+
return parsedPurchase.data
|
|
986
1259
|
},
|
|
987
1260
|
async getPurchasesForUser(userId?: string): Promise<Purchase[]> {
|
|
988
1261
|
if (!userId) {
|
|
@@ -1021,7 +1294,7 @@ export function mySqlDrizzleAdapter(
|
|
|
1021
1294
|
userId: string,
|
|
1022
1295
|
): Promise<{
|
|
1023
1296
|
purchase?: Purchase
|
|
1024
|
-
existingPurchase?: Purchase
|
|
1297
|
+
existingPurchase?: Purchase | null
|
|
1025
1298
|
availableUpgrades: UpgradableProduct[]
|
|
1026
1299
|
}> {
|
|
1027
1300
|
const visiblePurchaseStates = ['Valid', 'Refunded', 'Restricted']
|
|
@@ -1043,8 +1316,6 @@ export function mySqlDrizzleAdapter(
|
|
|
1043
1316
|
|
|
1044
1317
|
const allPurchases = parsedPurchases.success ? parsedPurchases.data : []
|
|
1045
1318
|
|
|
1046
|
-
console.log('🦦', { allPurchases })
|
|
1047
|
-
|
|
1048
1319
|
const thePurchase = await client.query.purchases.findFirst({
|
|
1049
1320
|
where: and(
|
|
1050
1321
|
eq(purchaseTable.id, purchaseId),
|
|
@@ -1066,8 +1337,6 @@ export function mySqlDrizzleAdapter(
|
|
|
1066
1337
|
}
|
|
1067
1338
|
}
|
|
1068
1339
|
|
|
1069
|
-
console.log('🦦', { parsedPurchase: parsedPurchase.data })
|
|
1070
|
-
|
|
1071
1340
|
const purchaseCanUpgrade = ['Valid', 'Restricted'].includes(
|
|
1072
1341
|
parsedPurchase.data.state || '',
|
|
1073
1342
|
)
|
|
@@ -1095,24 +1364,56 @@ export function mySqlDrizzleAdapter(
|
|
|
1095
1364
|
})
|
|
1096
1365
|
}
|
|
1097
1366
|
|
|
1098
|
-
const existingPurchase =
|
|
1099
|
-
(
|
|
1100
|
-
|
|
1367
|
+
const existingPurchase = purchaseSchema
|
|
1368
|
+
.optional()
|
|
1369
|
+
.nullable()
|
|
1370
|
+
.parse(
|
|
1371
|
+
(await client.query.purchases.findFirst({
|
|
1372
|
+
where: and(
|
|
1373
|
+
eq(purchaseTable.userId, userId),
|
|
1374
|
+
eq(purchaseTable.productId, parsedPurchase.data.productId),
|
|
1375
|
+
inArray(purchaseTable.status, ['Valid', 'Restricted']),
|
|
1376
|
+
isNull(purchaseTable.bulkCouponId),
|
|
1377
|
+
not(eq(purchaseTable.id, parsedPurchase.data.id)),
|
|
1378
|
+
),
|
|
1379
|
+
with: {
|
|
1380
|
+
user: true,
|
|
1381
|
+
product: true,
|
|
1382
|
+
bulkCoupon: true,
|
|
1383
|
+
},
|
|
1384
|
+
})) || null,
|
|
1385
|
+
)
|
|
1101
1386
|
|
|
1102
|
-
return
|
|
1387
|
+
return {
|
|
1103
1388
|
availableUpgrades: z
|
|
1104
1389
|
.array(upgradableProductSchema)
|
|
1105
1390
|
.parse(availableUpgrades),
|
|
1106
1391
|
existingPurchase,
|
|
1107
1392
|
purchase: parsedPurchase.data,
|
|
1108
|
-
}
|
|
1393
|
+
}
|
|
1109
1394
|
},
|
|
1110
1395
|
async getUserById(userId: string): Promise<User | null> {
|
|
1111
|
-
|
|
1112
|
-
|
|
1396
|
+
const user = await client.query.users
|
|
1397
|
+
.findFirst({
|
|
1113
1398
|
where: eq(users.id, userId),
|
|
1114
|
-
|
|
1115
|
-
|
|
1399
|
+
with: {
|
|
1400
|
+
roles: {
|
|
1401
|
+
with: {
|
|
1402
|
+
role: true,
|
|
1403
|
+
},
|
|
1404
|
+
},
|
|
1405
|
+
},
|
|
1406
|
+
})
|
|
1407
|
+
.then(async (res) => {
|
|
1408
|
+
if (res) {
|
|
1409
|
+
return {
|
|
1410
|
+
...res,
|
|
1411
|
+
roles: res.roles.map((r) => r.role),
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
})
|
|
1415
|
+
|
|
1416
|
+
return userSchema.nullable().parse(user ?? null)
|
|
1116
1417
|
},
|
|
1117
1418
|
async pricesOfPurchasesTowardOneBundle({
|
|
1118
1419
|
userId,
|
|
@@ -1156,12 +1457,56 @@ export function mySqlDrizzleAdapter(
|
|
|
1156
1457
|
|
|
1157
1458
|
return z.array(priceSchema).parse(foundPrices)
|
|
1158
1459
|
},
|
|
1159
|
-
toggleLessonProgressForUser(options: {
|
|
1460
|
+
async toggleLessonProgressForUser(options: {
|
|
1160
1461
|
userId: string
|
|
1161
1462
|
lessonId?: string
|
|
1162
|
-
lessonSlug?: string
|
|
1163
1463
|
}): Promise<ResourceProgress | null> {
|
|
1164
|
-
|
|
1464
|
+
if (!options.lessonId) {
|
|
1465
|
+
throw new Error('No lessonId provided')
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
let lessonProgress = await client.query.resourceProgress.findFirst({
|
|
1469
|
+
where: and(
|
|
1470
|
+
eq(resourceProgress.userId, options.userId),
|
|
1471
|
+
eq(resourceProgress.contentResourceId, options.lessonId),
|
|
1472
|
+
),
|
|
1473
|
+
})
|
|
1474
|
+
|
|
1475
|
+
const now = new Date()
|
|
1476
|
+
|
|
1477
|
+
if (lessonProgress) {
|
|
1478
|
+
await client
|
|
1479
|
+
.update(resourceProgress)
|
|
1480
|
+
.set({
|
|
1481
|
+
completedAt: lessonProgress.completedAt ? null : now,
|
|
1482
|
+
updatedAt: now,
|
|
1483
|
+
})
|
|
1484
|
+
.where(eq(resourceProgress.contentResourceId, options.lessonId))
|
|
1485
|
+
} else {
|
|
1486
|
+
await client.insert(resourceProgress).values({
|
|
1487
|
+
userId: options.userId,
|
|
1488
|
+
contentResourceId: options.lessonId,
|
|
1489
|
+
completedAt: now,
|
|
1490
|
+
updatedAt: now,
|
|
1491
|
+
})
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
lessonProgress = await client.query.resourceProgress.findFirst({
|
|
1495
|
+
where: and(
|
|
1496
|
+
eq(resourceProgress.userId, options.userId),
|
|
1497
|
+
eq(resourceProgress.contentResourceId, options.lessonId),
|
|
1498
|
+
),
|
|
1499
|
+
})
|
|
1500
|
+
|
|
1501
|
+
const parsedLessonProgress =
|
|
1502
|
+
resourceProgressSchema.safeParse(lessonProgress)
|
|
1503
|
+
|
|
1504
|
+
if (!parsedLessonProgress.success) {
|
|
1505
|
+
console.error('Error parsing lesson progress', lessonProgress)
|
|
1506
|
+
return null
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
return parsedLessonProgress.data
|
|
1165
1510
|
},
|
|
1166
1511
|
transferPurchasesToNewUser(options: {
|
|
1167
1512
|
merchantCustomerId: string
|
|
@@ -1173,13 +1518,27 @@ export function mySqlDrizzleAdapter(
|
|
|
1173
1518
|
chargeId: string,
|
|
1174
1519
|
status: 'Valid' | 'Refunded' | 'Disputed' | 'Banned' | 'Restricted',
|
|
1175
1520
|
): Promise<Purchase | undefined> {
|
|
1176
|
-
throw new Error('Method not implemented.')
|
|
1521
|
+
throw new Error('updatePurchaseStatusForCharge Method not implemented.')
|
|
1177
1522
|
},
|
|
1178
|
-
updatePurchaseUserTransferTransferState(options: {
|
|
1523
|
+
async updatePurchaseUserTransferTransferState(options: {
|
|
1179
1524
|
id: string
|
|
1180
1525
|
transferState: PurchaseUserTransferState
|
|
1181
1526
|
}): Promise<PurchaseUserTransfer | null> {
|
|
1182
|
-
|
|
1527
|
+
await client
|
|
1528
|
+
.update(purchaseUserTransfer)
|
|
1529
|
+
.set({
|
|
1530
|
+
transferState: options.transferState,
|
|
1531
|
+
})
|
|
1532
|
+
.where(eq(purchaseUserTransfer.id, options.id))
|
|
1533
|
+
|
|
1534
|
+
const purchaseUserTransferData =
|
|
1535
|
+
(await client.query.purchaseUserTransfer.findFirst({
|
|
1536
|
+
where: eq(purchaseUserTransfer.id, options.id),
|
|
1537
|
+
})) || null
|
|
1538
|
+
|
|
1539
|
+
return purchaseUserTransferSchema
|
|
1540
|
+
.nullable()
|
|
1541
|
+
.parse(purchaseUserTransferData)
|
|
1183
1542
|
},
|
|
1184
1543
|
addResourceToResource: async function (options) {
|
|
1185
1544
|
const { parentResourceId, childResourceId } = options
|
|
@@ -1571,4 +1930,6 @@ export function mySqlDrizzleAdapter(
|
|
|
1571
1930
|
return undefined
|
|
1572
1931
|
},
|
|
1573
1932
|
}
|
|
1933
|
+
|
|
1934
|
+
return adapter
|
|
1574
1935
|
}
|