@coursebuilder/adapter-drizzle 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-253RMSB3.js +99 -0
- package/dist/{chunk-3WYG5OE7.js → chunk-3GONHHMY.js} +2 -2
- package/dist/{chunk-L5ZAWSTN.js → chunk-5QEGBX2O.js} +411 -120
- package/dist/{chunk-WFC55BSF.js → chunk-FPAQINSA.js} +2 -2
- package/dist/{chunk-RCL6HPBL.js → chunk-HWIQUI7O.js} +2 -2
- package/dist/{chunk-QGZ2F5SW.js → chunk-LPJ2P2KJ.js} +1162 -1027
- package/dist/{chunk-GAKWXOAY.js → chunk-OBUGOZKM.js} +2 -2
- package/dist/chunk-ORRM7KVW.js +25 -0
- package/dist/{chunk-A6XPL665.js → chunk-PBTEHA7F.js} +2 -2
- package/dist/{chunk-5XTOCFDB.js → chunk-YQNIXCD3.js} +2 -2
- package/dist/index.js +11 -10
- package/dist/lib/mysql/index.cjs +1513 -1060
- package/dist/lib/mysql/index.cjs.map +1 -1
- package/dist/lib/mysql/index.d.cts +2994 -2258
- package/dist/lib/mysql/index.d.ts +2994 -2258
- package/dist/lib/mysql/index.js +11 -10
- package/dist/lib/mysql/schemas/auth/accounts.cjs +106 -98
- package/dist/lib/mysql/schemas/auth/accounts.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/accounts.js +2 -2
- package/dist/lib/mysql/schemas/auth/device-access-token.cjs +99 -91
- package/dist/lib/mysql/schemas/auth/device-access-token.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/device-access-token.js +3 -3
- package/dist/lib/mysql/schemas/auth/device-verification.cjs +100 -92
- package/dist/lib/mysql/schemas/auth/device-verification.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/device-verification.js +3 -3
- package/dist/lib/mysql/schemas/auth/profiles.cjs +254 -0
- package/dist/lib/mysql/schemas/auth/profiles.cjs.map +1 -0
- package/dist/lib/mysql/schemas/auth/profiles.d.cts +112 -0
- package/dist/lib/mysql/schemas/auth/profiles.d.ts +112 -0
- package/dist/lib/mysql/schemas/auth/profiles.js +20 -0
- package/dist/lib/mysql/schemas/auth/profiles.js.map +1 -0
- package/dist/lib/mysql/schemas/auth/role-permissions.cjs +55 -46
- package/dist/lib/mysql/schemas/auth/role-permissions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/role-permissions.js +3 -3
- package/dist/lib/mysql/schemas/auth/roles.cjs +57 -48
- package/dist/lib/mysql/schemas/auth/roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/roles.js +2 -2
- package/dist/lib/mysql/schemas/auth/sessions.cjs +96 -88
- package/dist/lib/mysql/schemas/auth/sessions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/sessions.js +3 -3
- package/dist/lib/mysql/schemas/auth/user-permissions.cjs +99 -91
- package/dist/lib/mysql/schemas/auth/user-permissions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-permissions.js +2 -2
- package/dist/lib/mysql/schemas/auth/user-prefs.cjs +104 -96
- package/dist/lib/mysql/schemas/auth/user-prefs.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-prefs.js +2 -2
- package/dist/lib/mysql/schemas/auth/user-roles.cjs +58 -49
- package/dist/lib/mysql/schemas/auth/user-roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-roles.js +2 -2
- package/dist/lib/mysql/schemas/auth/users.cjs +295 -259
- package/dist/lib/mysql/schemas/auth/users.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/users.d.cts +1 -0
- package/dist/lib/mysql/schemas/auth/users.d.ts +1 -0
- package/dist/lib/mysql/schemas/auth/users.js +2 -2
- package/dist/lib/mysql/schemas/commerce/coupon.cjs +131 -123
- package/dist/lib/mysql/schemas/commerce/coupon.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/coupon.js +2 -2
- package/dist/lib/mysql/schemas/commerce/merchant-charge.cjs +96 -88
- package/dist/lib/mysql/schemas/commerce/merchant-charge.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/merchant-charge.js +2 -2
- package/dist/lib/mysql/schemas/commerce/merchant-subscription.cjs +90 -82
- package/dist/lib/mysql/schemas/commerce/merchant-subscription.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/merchant-subscription.js +2 -2
- package/dist/lib/mysql/schemas/commerce/price.cjs +98 -90
- package/dist/lib/mysql/schemas/commerce/price.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/price.js +2 -2
- package/dist/lib/mysql/schemas/commerce/product.cjs +125 -117
- package/dist/lib/mysql/schemas/commerce/product.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/product.js +2 -2
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.cjs +131 -123
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.js +3 -3
- package/dist/lib/mysql/schemas/commerce/purchase.cjs +184 -176
- package/dist/lib/mysql/schemas/commerce/purchase.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/purchase.js +2 -2
- package/dist/lib/mysql/schemas/commerce/subscription.cjs +117 -109
- package/dist/lib/mysql/schemas/commerce/subscription.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/subscription.js +2 -2
- package/dist/lib/mysql/schemas/commerce/upgradable-products.cjs +105 -97
- package/dist/lib/mysql/schemas/commerce/upgradable-products.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/upgradable-products.js +3 -3
- package/dist/lib/mysql/schemas/communication/comment.cjs +114 -106
- package/dist/lib/mysql/schemas/communication/comment.cjs.map +1 -1
- package/dist/lib/mysql/schemas/communication/comment.js +2 -2
- package/dist/lib/mysql/schemas/communication/communication-preferences.cjs +136 -128
- package/dist/lib/mysql/schemas/communication/communication-preferences.cjs.map +1 -1
- package/dist/lib/mysql/schemas/communication/communication-preferences.js +2 -2
- package/dist/lib/mysql/schemas/content/content-contributions.cjs +144 -136
- package/dist/lib/mysql/schemas/content/content-contributions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-contributions.js +2 -2
- package/dist/lib/mysql/schemas/content/content-resource-product.cjs +99 -91
- package/dist/lib/mysql/schemas/content/content-resource-product.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-product.js +2 -2
- package/dist/lib/mysql/schemas/content/content-resource-resource.cjs +108 -100
- package/dist/lib/mysql/schemas/content/content-resource-resource.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-resource.js +2 -2
- package/dist/lib/mysql/schemas/content/content-resource-tag.cjs +118 -110
- package/dist/lib/mysql/schemas/content/content-resource-tag.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-tag.js +2 -2
- package/dist/lib/mysql/schemas/content/content-resource-version.cjs +121 -113
- package/dist/lib/mysql/schemas/content/content-resource-version.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-version.js +2 -2
- package/dist/lib/mysql/schemas/content/content-resource.cjs +198 -190
- package/dist/lib/mysql/schemas/content/content-resource.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource.js +2 -2
- package/dist/lib/mysql/schemas/content/tag-tag.cjs +103 -95
- package/dist/lib/mysql/schemas/content/tag-tag.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/tag-tag.js +2 -2
- package/dist/lib/mysql/schemas/content/tag.cjs +116 -108
- package/dist/lib/mysql/schemas/content/tag.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/tag.js +2 -2
- package/dist/lib/mysql/schemas/entitlements/entitlement-type.cjs +46 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement-type.cjs.map +1 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement-type.d.cts +60 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement-type.d.ts +60 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement-type.js +8 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement-type.js.map +1 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement.cjs +351 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement.cjs.map +1 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement.d.cts +210 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement.d.ts +210 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement.js +21 -0
- package/dist/lib/mysql/schemas/entitlements/entitlement.js.map +1 -0
- package/dist/lib/mysql/schemas/org/organization-membership-roles.cjs +73 -35
- package/dist/lib/mysql/schemas/org/organization-membership-roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/org/organization-membership-roles.d.cts +1 -0
- package/dist/lib/mysql/schemas/org/organization-membership-roles.d.ts +1 -0
- package/dist/lib/mysql/schemas/org/organization-membership-roles.js +2 -3
- package/dist/lib/mysql/schemas/org/organization-memberships.cjs +88 -38
- package/dist/lib/mysql/schemas/org/organization-memberships.cjs.map +1 -1
- package/dist/lib/mysql/schemas/org/organization-memberships.d.cts +1 -0
- package/dist/lib/mysql/schemas/org/organization-memberships.d.ts +1 -0
- package/dist/lib/mysql/schemas/org/organization-memberships.js +2 -2
- package/dist/lib/mysql/schemas/org/organizations.cjs +131 -121
- package/dist/lib/mysql/schemas/org/organizations.cjs.map +1 -1
- package/dist/lib/mysql/schemas/org/organizations.js +2 -2
- package/package.json +4 -3
- package/src/lib/mysql/index.ts +349 -26
- package/src/lib/mysql/schemas/auth/profiles.ts +50 -0
- package/src/lib/mysql/schemas/auth/roles.ts +6 -1
- package/src/lib/mysql/schemas/auth/users.ts +6 -1
- package/src/lib/mysql/schemas/commerce/subscription.ts +3 -5
- package/src/lib/mysql/schemas/entitlements/entitlement-type.ts +21 -0
- package/src/lib/mysql/schemas/entitlements/entitlement.ts +66 -0
- package/src/lib/mysql/schemas/org/organization-membership-roles.ts +7 -0
- package/src/lib/mysql/schemas/org/organization-memberships.ts +6 -0
- package/dist/chunk-RP66NZN3.js +0 -81
package/src/lib/mysql/index.ts
CHANGED
|
@@ -61,7 +61,15 @@ import {
|
|
|
61
61
|
} from '@coursebuilder/core/schemas/content-resource-schema'
|
|
62
62
|
import { merchantAccountSchema } from '@coursebuilder/core/schemas/merchant-account-schema'
|
|
63
63
|
import { merchantCustomerSchema } from '@coursebuilder/core/schemas/merchant-customer-schema'
|
|
64
|
+
import {
|
|
65
|
+
MerchantSession,
|
|
66
|
+
MerchantSessionSchema,
|
|
67
|
+
} from '@coursebuilder/core/schemas/merchant-session'
|
|
68
|
+
import { MerchantSubscriptionSchema } from '@coursebuilder/core/schemas/merchant-subscription'
|
|
69
|
+
import { OrganizationMemberSchema } from '@coursebuilder/core/schemas/organization-member'
|
|
70
|
+
import { OrganizationSchema } from '@coursebuilder/core/schemas/organization-schema'
|
|
64
71
|
import { type ModuleProgress } from '@coursebuilder/core/schemas/resource-progress-schema'
|
|
72
|
+
import { SubscriptionSchema } from '@coursebuilder/core/schemas/subscription'
|
|
65
73
|
import { VideoResourceSchema } from '@coursebuilder/core/schemas/video-resource'
|
|
66
74
|
import { PaymentsProviderConfig } from '@coursebuilder/core/types'
|
|
67
75
|
import { logger } from '@coursebuilder/core/utils/logger'
|
|
@@ -83,6 +91,10 @@ import {
|
|
|
83
91
|
getPermissionsRelationsSchema,
|
|
84
92
|
getPermissionsSchema,
|
|
85
93
|
} from './schemas/auth/permissions.js'
|
|
94
|
+
import {
|
|
95
|
+
getProfilesRelationsSchema,
|
|
96
|
+
getProfilesSchema,
|
|
97
|
+
} from './schemas/auth/profiles.js'
|
|
86
98
|
import {
|
|
87
99
|
getRolePermissionsRelationsSchema,
|
|
88
100
|
getRolePermissionsSchema,
|
|
@@ -196,6 +208,11 @@ import {
|
|
|
196
208
|
getTagTagSchema,
|
|
197
209
|
} from './schemas/content/tag-tag.js'
|
|
198
210
|
import { getTagRelationsSchema, getTagSchema } from './schemas/content/tag.js'
|
|
211
|
+
import { getEntitlementTypesSchema } from './schemas/entitlements/entitlement-type.js'
|
|
212
|
+
import {
|
|
213
|
+
getEntitlementRelationsSchema,
|
|
214
|
+
getEntitlementsSchema,
|
|
215
|
+
} from './schemas/entitlements/entitlement.js'
|
|
199
216
|
import {
|
|
200
217
|
getOrganizationMembershipRolesRelationsSchema,
|
|
201
218
|
getOrganizationMembershipRolesSchema,
|
|
@@ -305,6 +322,11 @@ export function getCourseBuilderSchema(mysqlTable: MySqlTableFn) {
|
|
|
305
322
|
getMerchantSubscriptionRelationsSchema(mysqlTable),
|
|
306
323
|
subscription: getSubscriptionSchema(mysqlTable),
|
|
307
324
|
subscriptionRelations: getSubscriptionRelationsSchema(mysqlTable),
|
|
325
|
+
profiles: getProfilesSchema(mysqlTable),
|
|
326
|
+
profilesRelations: getProfilesRelationsSchema(mysqlTable),
|
|
327
|
+
entitlementTypes: getEntitlementTypesSchema(mysqlTable),
|
|
328
|
+
entitlements: getEntitlementsSchema(mysqlTable),
|
|
329
|
+
entitlementsRelations: getEntitlementRelationsSchema(mysqlTable),
|
|
308
330
|
} as const
|
|
309
331
|
}
|
|
310
332
|
|
|
@@ -342,6 +364,12 @@ export function mySqlDrizzleAdapter(
|
|
|
342
364
|
upgradableProducts,
|
|
343
365
|
resourceProgress,
|
|
344
366
|
comments,
|
|
367
|
+
organization: organizationTable,
|
|
368
|
+
organizationMemberships: organizationMembershipTable,
|
|
369
|
+
organizationMembershipRoles: organizationMembershipRoleTable,
|
|
370
|
+
roles: roleTable,
|
|
371
|
+
merchantSubscription: merchantSubscriptionTable,
|
|
372
|
+
subscription: subscriptionTable,
|
|
345
373
|
} = createTables(tableFn)
|
|
346
374
|
|
|
347
375
|
const adapter: CourseBuilderAdapter = {
|
|
@@ -655,6 +683,23 @@ export function mySqlDrizzleAdapter(
|
|
|
655
683
|
|
|
656
684
|
return parsedCoupon.data
|
|
657
685
|
},
|
|
686
|
+
async createMerchantSession(options): Promise<MerchantSession> {
|
|
687
|
+
const id = `ms_${v4()}`
|
|
688
|
+
await client.insert(merchantSession).values({
|
|
689
|
+
id,
|
|
690
|
+
identifier: options.identifier,
|
|
691
|
+
merchantAccountId: options.merchantAccountId,
|
|
692
|
+
...(options.organizationId
|
|
693
|
+
? { organizationId: options.organizationId }
|
|
694
|
+
: {}),
|
|
695
|
+
})
|
|
696
|
+
|
|
697
|
+
return MerchantSessionSchema.parse(
|
|
698
|
+
await client.query.merchantSession.findFirst({
|
|
699
|
+
where: eq(merchantSession.id, id),
|
|
700
|
+
}),
|
|
701
|
+
)
|
|
702
|
+
},
|
|
658
703
|
async createMerchantChargeAndPurchase(options): Promise<Purchase> {
|
|
659
704
|
const purchaseId = await client.transaction(async (trx) => {
|
|
660
705
|
try {
|
|
@@ -673,6 +718,7 @@ export function mySqlDrizzleAdapter(
|
|
|
673
718
|
upgradedFromPurchaseId,
|
|
674
719
|
country,
|
|
675
720
|
usedCouponId,
|
|
721
|
+
organizationId,
|
|
676
722
|
} = options
|
|
677
723
|
|
|
678
724
|
const existingMerchantCharge = merchantChargeSchema.nullable().parse(
|
|
@@ -761,6 +807,7 @@ export function mySqlDrizzleAdapter(
|
|
|
761
807
|
.update(coupon)
|
|
762
808
|
.set({
|
|
763
809
|
maxUses: (existingBulkCoupon?.maxUses || 0) + quantity,
|
|
810
|
+
...(organizationId ? { organizationId } : {}),
|
|
764
811
|
})
|
|
765
812
|
.where(eq(coupon.id, bulkCouponId))
|
|
766
813
|
} else {
|
|
@@ -778,6 +825,7 @@ export function mySqlDrizzleAdapter(
|
|
|
778
825
|
restrictedToProductId: productId,
|
|
779
826
|
maxUses: quantity,
|
|
780
827
|
status: 1,
|
|
828
|
+
...(organizationId ? { organizationId } : {}),
|
|
781
829
|
...(merchantCouponToUse
|
|
782
830
|
? {
|
|
783
831
|
merchantCouponId: merchantCouponToUse.id,
|
|
@@ -787,15 +835,14 @@ export function mySqlDrizzleAdapter(
|
|
|
787
835
|
}
|
|
788
836
|
}
|
|
789
837
|
|
|
838
|
+
// create a new merchant session
|
|
790
839
|
const merchantSessionId = `ms_${v4()}`
|
|
791
840
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
merchantAccountId,
|
|
798
|
-
})
|
|
841
|
+
await client.insert(merchantSession).values({
|
|
842
|
+
id: merchantSessionId,
|
|
843
|
+
identifier: checkoutSessionId,
|
|
844
|
+
merchantAccountId,
|
|
845
|
+
})
|
|
799
846
|
|
|
800
847
|
const merchantCouponUsed = stripeCouponId
|
|
801
848
|
? await client.query.merchantCoupon.findFirst({
|
|
@@ -817,7 +864,7 @@ export function mySqlDrizzleAdapter(
|
|
|
817
864
|
? 'Restricted'
|
|
818
865
|
: 'Valid'
|
|
819
866
|
|
|
820
|
-
|
|
867
|
+
await client.insert(purchaseTable).values({
|
|
821
868
|
id: purchaseId,
|
|
822
869
|
status: newPurchaseStatus,
|
|
823
870
|
userId,
|
|
@@ -829,20 +876,20 @@ export function mySqlDrizzleAdapter(
|
|
|
829
876
|
country,
|
|
830
877
|
upgradedFromId: upgradedFromPurchaseId || null,
|
|
831
878
|
couponId: usedCouponId || null,
|
|
879
|
+
...(organizationId ? { organizationId } : {}),
|
|
832
880
|
})
|
|
833
881
|
|
|
834
882
|
const oneWeekInMilliseconds = 1000 * 60 * 60 * 24 * 7
|
|
835
883
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
})
|
|
884
|
+
await client.insert(purchaseUserTransfer).values({
|
|
885
|
+
id: `put_${v4()}`,
|
|
886
|
+
purchaseId: purchaseId as string,
|
|
887
|
+
expiresAt: existingPurchase
|
|
888
|
+
? new Date()
|
|
889
|
+
: new Date(Date.now() + oneWeekInMilliseconds),
|
|
890
|
+
sourceUserId: userId,
|
|
891
|
+
...(organizationId ? { organizationId } : {}),
|
|
892
|
+
})
|
|
846
893
|
|
|
847
894
|
// const result = await Promise.all([
|
|
848
895
|
// newMerchantCharge,
|
|
@@ -1098,7 +1145,7 @@ export function mySqlDrizzleAdapter(
|
|
|
1098
1145
|
|
|
1099
1146
|
const ResultRowSchema = z.object({
|
|
1100
1147
|
resource_id: z.string(),
|
|
1101
|
-
resource_type: z.enum(['lesson', 'exercise']),
|
|
1148
|
+
resource_type: z.enum(['lesson', 'exercise', 'post']),
|
|
1102
1149
|
resource_slug: z.string().nullable(),
|
|
1103
1150
|
completed_at: z
|
|
1104
1151
|
.string()
|
|
@@ -1138,10 +1185,9 @@ export function mySqlDrizzleAdapter(
|
|
|
1138
1185
|
LEFT JOIN ${resourceProgress} rp ON rp.resourceId = cr.id
|
|
1139
1186
|
AND rp.userId = ${user.id}
|
|
1140
1187
|
WHERE
|
|
1141
|
-
cr.type IN ('lesson', 'exercise')
|
|
1188
|
+
cr.type IN ('lesson', 'exercise', 'post')
|
|
1142
1189
|
|
|
1143
1190
|
`)
|
|
1144
|
-
|
|
1145
1191
|
// Process the results
|
|
1146
1192
|
const completedLessons: ResourceProgress[] = []
|
|
1147
1193
|
let nextResource: Partial<ContentResource> | null = null
|
|
@@ -1471,6 +1517,7 @@ export function mySqlDrizzleAdapter(
|
|
|
1471
1517
|
...fieldsNoImage,
|
|
1472
1518
|
...(image?.url && { image }),
|
|
1473
1519
|
},
|
|
1520
|
+
type: input.type,
|
|
1474
1521
|
})
|
|
1475
1522
|
.where(eq(products.id, currentProduct.id))
|
|
1476
1523
|
|
|
@@ -2441,11 +2488,39 @@ export function mySqlDrizzleAdapter(
|
|
|
2441
2488
|
|
|
2442
2489
|
await client.insert(users).values({ ...data, id })
|
|
2443
2490
|
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2491
|
+
// creating a personal organization for the user
|
|
2492
|
+
// every user gets an organization of their very own
|
|
2493
|
+
const personalOrganization = await adapter.createOrganization({
|
|
2494
|
+
name: `Personal (${data.email})`,
|
|
2495
|
+
})
|
|
2496
|
+
|
|
2497
|
+
if (!personalOrganization) {
|
|
2498
|
+
throw new Error('Failed to create personal organization')
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
const membership = await adapter.addMemberToOrganization({
|
|
2502
|
+
organizationId: personalOrganization.id,
|
|
2503
|
+
userId: id,
|
|
2504
|
+
invitedById: id,
|
|
2505
|
+
})
|
|
2506
|
+
|
|
2507
|
+
if (!membership) {
|
|
2508
|
+
throw new Error('Failed to add user to personal organization')
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
await adapter.addRoleForMember({
|
|
2512
|
+
organizationId: personalOrganization.id,
|
|
2513
|
+
memberId: membership.id,
|
|
2514
|
+
role: 'owner',
|
|
2515
|
+
})
|
|
2516
|
+
|
|
2517
|
+
const user = await adapter.getUser?.(id)
|
|
2518
|
+
|
|
2519
|
+
if (!user) {
|
|
2520
|
+
throw new Error('Failed to get user')
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
return user
|
|
2449
2524
|
} catch (error) {
|
|
2450
2525
|
console.error(error)
|
|
2451
2526
|
throw error
|
|
@@ -2631,6 +2706,254 @@ export function mySqlDrizzleAdapter(
|
|
|
2631
2706
|
|
|
2632
2707
|
return undefined
|
|
2633
2708
|
},
|
|
2709
|
+
createOrganization: async (options: { name: string }) => {
|
|
2710
|
+
const organizationId = crypto.randomUUID()
|
|
2711
|
+
await client.insert(organizationTable).values({
|
|
2712
|
+
...options,
|
|
2713
|
+
id: organizationId,
|
|
2714
|
+
})
|
|
2715
|
+
|
|
2716
|
+
return adapter.getOrganization(organizationId)
|
|
2717
|
+
},
|
|
2718
|
+
getOrganization: async (organizationId: string) => {
|
|
2719
|
+
return OrganizationSchema.parse(
|
|
2720
|
+
await client.query.organization.findFirst({
|
|
2721
|
+
where: eq(organizationTable.id, organizationId),
|
|
2722
|
+
}),
|
|
2723
|
+
)
|
|
2724
|
+
},
|
|
2725
|
+
addMemberToOrganization: async (options: {
|
|
2726
|
+
organizationId: string
|
|
2727
|
+
userId: string
|
|
2728
|
+
invitedById: string
|
|
2729
|
+
}) => {
|
|
2730
|
+
const currentMembership =
|
|
2731
|
+
await client.query.organizationMemberships.findFirst({
|
|
2732
|
+
where: and(
|
|
2733
|
+
eq(
|
|
2734
|
+
organizationMembershipTable.organizationId,
|
|
2735
|
+
options.organizationId,
|
|
2736
|
+
),
|
|
2737
|
+
eq(organizationMembershipTable.userId, options.userId),
|
|
2738
|
+
),
|
|
2739
|
+
})
|
|
2740
|
+
|
|
2741
|
+
if (currentMembership) {
|
|
2742
|
+
return OrganizationMemberSchema.parse(currentMembership)
|
|
2743
|
+
} else {
|
|
2744
|
+
const id = crypto.randomUUID()
|
|
2745
|
+
await client.insert(organizationMembershipTable).values({
|
|
2746
|
+
...options,
|
|
2747
|
+
id,
|
|
2748
|
+
})
|
|
2749
|
+
|
|
2750
|
+
return OrganizationMemberSchema.parse(
|
|
2751
|
+
await client.query.organizationMemberships.findFirst({
|
|
2752
|
+
where: eq(organizationMembershipTable.id, id),
|
|
2753
|
+
with: {
|
|
2754
|
+
organization: true,
|
|
2755
|
+
user: true,
|
|
2756
|
+
},
|
|
2757
|
+
}),
|
|
2758
|
+
)
|
|
2759
|
+
}
|
|
2760
|
+
},
|
|
2761
|
+
removeMemberFromOrganization: async (options: {
|
|
2762
|
+
organizationId: string
|
|
2763
|
+
userId: string
|
|
2764
|
+
}) => {
|
|
2765
|
+
await client
|
|
2766
|
+
.delete(organizationMembershipTable)
|
|
2767
|
+
.where(
|
|
2768
|
+
and(
|
|
2769
|
+
eq(
|
|
2770
|
+
organizationMembershipTable.organizationId,
|
|
2771
|
+
options.organizationId,
|
|
2772
|
+
),
|
|
2773
|
+
eq(organizationMembershipTable.userId, options.userId),
|
|
2774
|
+
),
|
|
2775
|
+
)
|
|
2776
|
+
},
|
|
2777
|
+
addRoleForMember: async (options: {
|
|
2778
|
+
organizationId: string
|
|
2779
|
+
memberId: string
|
|
2780
|
+
role: string
|
|
2781
|
+
}) => {
|
|
2782
|
+
const existingRole = z
|
|
2783
|
+
.object({
|
|
2784
|
+
id: z.string(),
|
|
2785
|
+
})
|
|
2786
|
+
.nullish()
|
|
2787
|
+
.parse(
|
|
2788
|
+
await client.query.roles.findFirst({
|
|
2789
|
+
where: and(
|
|
2790
|
+
eq(roleTable.organizationId, options.organizationId),
|
|
2791
|
+
eq(roleTable.name, options.role),
|
|
2792
|
+
),
|
|
2793
|
+
}),
|
|
2794
|
+
)
|
|
2795
|
+
|
|
2796
|
+
const roleId = existingRole?.id || crypto.randomUUID()
|
|
2797
|
+
|
|
2798
|
+
if (!existingRole) {
|
|
2799
|
+
await client.insert(roleTable).values({
|
|
2800
|
+
name: options.role,
|
|
2801
|
+
organizationId: options.organizationId,
|
|
2802
|
+
id: roleId,
|
|
2803
|
+
})
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
const currentOrgMembershipRole =
|
|
2807
|
+
await client.query.organizationMembershipRoles.findFirst({
|
|
2808
|
+
where: and(
|
|
2809
|
+
eq(
|
|
2810
|
+
organizationMembershipRoleTable.organizationMembershipId,
|
|
2811
|
+
options.memberId,
|
|
2812
|
+
),
|
|
2813
|
+
eq(organizationMembershipRoleTable.roleId, roleId),
|
|
2814
|
+
),
|
|
2815
|
+
})
|
|
2816
|
+
|
|
2817
|
+
if (!currentOrgMembershipRole) {
|
|
2818
|
+
await client.insert(organizationMembershipRoleTable).values({
|
|
2819
|
+
organizationId: options.organizationId,
|
|
2820
|
+
organizationMembershipId: options.memberId,
|
|
2821
|
+
roleId,
|
|
2822
|
+
})
|
|
2823
|
+
}
|
|
2824
|
+
},
|
|
2825
|
+
removeRoleForMember: async (options: {
|
|
2826
|
+
organizationId: string
|
|
2827
|
+
memberId: string
|
|
2828
|
+
role: string
|
|
2829
|
+
}) => {
|
|
2830
|
+
const existingRole = z
|
|
2831
|
+
.object({
|
|
2832
|
+
id: z.string(),
|
|
2833
|
+
})
|
|
2834
|
+
.nullable()
|
|
2835
|
+
.parse(
|
|
2836
|
+
await client.query.roles.findFirst({
|
|
2837
|
+
where: and(
|
|
2838
|
+
eq(roleTable.organizationId, options.organizationId),
|
|
2839
|
+
eq(roleTable.name, options.role),
|
|
2840
|
+
),
|
|
2841
|
+
}),
|
|
2842
|
+
)
|
|
2843
|
+
|
|
2844
|
+
const roleId = existingRole?.id
|
|
2845
|
+
|
|
2846
|
+
if (roleId) {
|
|
2847
|
+
await client
|
|
2848
|
+
.delete(organizationMembershipRoleTable)
|
|
2849
|
+
.where(eq(organizationMembershipRoleTable.roleId, roleId))
|
|
2850
|
+
}
|
|
2851
|
+
},
|
|
2852
|
+
getMembershipsForUser: async (userId: string) => {
|
|
2853
|
+
return OrganizationMemberSchema.array().parse(
|
|
2854
|
+
(await client.query.organizationMemberships.findMany({
|
|
2855
|
+
where: eq(organizationMembershipTable.userId, userId),
|
|
2856
|
+
with: {
|
|
2857
|
+
organization: true,
|
|
2858
|
+
user: true,
|
|
2859
|
+
},
|
|
2860
|
+
})) || [],
|
|
2861
|
+
)
|
|
2862
|
+
},
|
|
2863
|
+
getOrganizationMembers: async (organizationId: string) => {
|
|
2864
|
+
return OrganizationMemberSchema.array().parse(
|
|
2865
|
+
(await client.query.organizationMemberships.findMany({
|
|
2866
|
+
where: eq(organizationMembershipTable.organizationId, organizationId),
|
|
2867
|
+
})) || [],
|
|
2868
|
+
)
|
|
2869
|
+
},
|
|
2870
|
+
createSubscription: async (options: {
|
|
2871
|
+
organizationId: string
|
|
2872
|
+
merchantSubscriptionId: string
|
|
2873
|
+
productId: string
|
|
2874
|
+
}) => {
|
|
2875
|
+
const id = `sub_${crypto.randomUUID()}`
|
|
2876
|
+
await client.insert(subscriptionTable).values({
|
|
2877
|
+
...options,
|
|
2878
|
+
id,
|
|
2879
|
+
})
|
|
2880
|
+
|
|
2881
|
+
return SubscriptionSchema.parse(
|
|
2882
|
+
await client.query.subscription.findFirst({
|
|
2883
|
+
where: eq(subscriptionTable.id, id),
|
|
2884
|
+
with: {
|
|
2885
|
+
product: true,
|
|
2886
|
+
},
|
|
2887
|
+
}),
|
|
2888
|
+
)
|
|
2889
|
+
},
|
|
2890
|
+
getMerchantSubscription: async (merchantSubscriptionId: string) => {
|
|
2891
|
+
return MerchantSubscriptionSchema.parse(
|
|
2892
|
+
await client.query.merchantSubscription.findFirst({
|
|
2893
|
+
where: eq(merchantSubscriptionTable.id, merchantSubscriptionId),
|
|
2894
|
+
}),
|
|
2895
|
+
)
|
|
2896
|
+
},
|
|
2897
|
+
createMerchantSubscription: async (options: {
|
|
2898
|
+
merchantAccountId: string
|
|
2899
|
+
merchantCustomerId: string
|
|
2900
|
+
merchantProductId: string
|
|
2901
|
+
identifier: string
|
|
2902
|
+
}) => {
|
|
2903
|
+
const id = crypto.randomUUID()
|
|
2904
|
+
await client.insert(merchantSubscriptionTable).values({
|
|
2905
|
+
...options,
|
|
2906
|
+
id,
|
|
2907
|
+
})
|
|
2908
|
+
|
|
2909
|
+
return MerchantSubscriptionSchema.parse(
|
|
2910
|
+
await client.query.merchantSubscription.findFirst({
|
|
2911
|
+
where: eq(merchantSubscriptionTable.id, id),
|
|
2912
|
+
}),
|
|
2913
|
+
)
|
|
2914
|
+
},
|
|
2915
|
+
updateMerchantSubscription: async (options: {
|
|
2916
|
+
merchantSubscriptionId: string
|
|
2917
|
+
status: string
|
|
2918
|
+
}) => {
|
|
2919
|
+
throw new Error('Not implemented')
|
|
2920
|
+
},
|
|
2921
|
+
deleteMerchantSubscription: async (merchantSubscriptionId: string) => {
|
|
2922
|
+
throw new Error('Not implemented')
|
|
2923
|
+
},
|
|
2924
|
+
getSubscriptionForStripeId: async (stripeSubscriptionId: string) => {
|
|
2925
|
+
const merchantSubscriptionParsed = MerchantSubscriptionSchema.safeParse(
|
|
2926
|
+
await client.query.merchantSubscription.findFirst({
|
|
2927
|
+
where: eq(merchantSubscriptionTable.identifier, stripeSubscriptionId),
|
|
2928
|
+
}),
|
|
2929
|
+
)
|
|
2930
|
+
|
|
2931
|
+
if (!merchantSubscriptionParsed.success) {
|
|
2932
|
+
throw new Error(
|
|
2933
|
+
`No merchant subscription found for stripe id ${stripeSubscriptionId} ${merchantSubscriptionParsed.error}`,
|
|
2934
|
+
)
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
const subscriptionParsed = SubscriptionSchema.safeParse(
|
|
2938
|
+
await client.query.subscription.findFirst({
|
|
2939
|
+
where: eq(
|
|
2940
|
+
subscriptionTable.merchantSubscriptionId,
|
|
2941
|
+
merchantSubscriptionParsed.data.id,
|
|
2942
|
+
),
|
|
2943
|
+
with: {
|
|
2944
|
+
product: true,
|
|
2945
|
+
},
|
|
2946
|
+
}),
|
|
2947
|
+
)
|
|
2948
|
+
|
|
2949
|
+
if (!subscriptionParsed.success) {
|
|
2950
|
+
throw new Error(
|
|
2951
|
+
`No subscription found for merchant subscription ${merchantSubscriptionParsed.data.id} ${subscriptionParsed.error}`,
|
|
2952
|
+
)
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2955
|
+
return subscriptionParsed.data
|
|
2956
|
+
},
|
|
2634
2957
|
}
|
|
2635
2958
|
|
|
2636
2959
|
return adapter
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { relations, sql } from 'drizzle-orm'
|
|
2
|
+
import {
|
|
3
|
+
index,
|
|
4
|
+
json,
|
|
5
|
+
MySqlTableFn,
|
|
6
|
+
timestamp,
|
|
7
|
+
uniqueIndex,
|
|
8
|
+
varchar,
|
|
9
|
+
} from 'drizzle-orm/mysql-core'
|
|
10
|
+
|
|
11
|
+
import { getUsersSchema } from './users.js'
|
|
12
|
+
|
|
13
|
+
export function getProfilesSchema(mysqlTable: MySqlTableFn) {
|
|
14
|
+
return mysqlTable(
|
|
15
|
+
'Profile',
|
|
16
|
+
{
|
|
17
|
+
id: varchar('id', { length: 255 }).notNull().primaryKey(),
|
|
18
|
+
userId: varchar('userId', { length: 255 }).notNull(),
|
|
19
|
+
type: varchar('type', { length: 255 }).notNull(),
|
|
20
|
+
fields: json('fields').$type<Record<string, any>>().default({}),
|
|
21
|
+
createdAt: timestamp('createdAt', {
|
|
22
|
+
mode: 'date',
|
|
23
|
+
fsp: 3,
|
|
24
|
+
}).default(sql`CURRENT_TIMESTAMP(3)`),
|
|
25
|
+
updatedAt: timestamp('updatedAt', {
|
|
26
|
+
mode: 'date',
|
|
27
|
+
fsp: 3,
|
|
28
|
+
}).default(sql`CURRENT_TIMESTAMP(3)`),
|
|
29
|
+
},
|
|
30
|
+
(profile) => ({
|
|
31
|
+
userIdIdx: index('userId_idx').on(profile.userId),
|
|
32
|
+
uniqueUserType: uniqueIndex('unique_user_type_idx').on(
|
|
33
|
+
profile.userId,
|
|
34
|
+
profile.type,
|
|
35
|
+
),
|
|
36
|
+
}),
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function getProfilesRelationsSchema(mysqlTable: MySqlTableFn) {
|
|
41
|
+
const profiles = getProfilesSchema(mysqlTable)
|
|
42
|
+
const users = getUsersSchema(mysqlTable)
|
|
43
|
+
return relations(profiles, ({ one }) => ({
|
|
44
|
+
user: one(users, {
|
|
45
|
+
fields: [profiles.userId],
|
|
46
|
+
references: [users.id],
|
|
47
|
+
relationName: 'profiles',
|
|
48
|
+
}),
|
|
49
|
+
}))
|
|
50
|
+
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
MySqlTableFn,
|
|
6
6
|
text,
|
|
7
7
|
timestamp,
|
|
8
|
+
uniqueIndex,
|
|
8
9
|
varchar,
|
|
9
10
|
} from 'drizzle-orm/mysql-core'
|
|
10
11
|
|
|
@@ -16,7 +17,7 @@ export function getRolesSchema(mysqlTable: MySqlTableFn) {
|
|
|
16
17
|
{
|
|
17
18
|
id: varchar('id', { length: 255 }).notNull().primaryKey(),
|
|
18
19
|
organizationId: varchar('organizationId', { length: 191 }),
|
|
19
|
-
name: varchar('name', { length: 255 }).notNull()
|
|
20
|
+
name: varchar('name', { length: 255 }).notNull(),
|
|
20
21
|
description: text('description'),
|
|
21
22
|
active: boolean('active').notNull().default(true),
|
|
22
23
|
createdAt: timestamp('createdAt', {
|
|
@@ -35,6 +36,10 @@ export function getRolesSchema(mysqlTable: MySqlTableFn) {
|
|
|
35
36
|
(role) => ({
|
|
36
37
|
nameIdx: index('name_idx').on(role.name),
|
|
37
38
|
organizationIdIdx: index('organizationId_idx').on(role.organizationId),
|
|
39
|
+
uniqueNamePerOrg: uniqueIndex('unique_name_per_org').on(
|
|
40
|
+
role.organizationId,
|
|
41
|
+
role.name,
|
|
42
|
+
),
|
|
38
43
|
}),
|
|
39
44
|
)
|
|
40
45
|
}
|
|
@@ -15,6 +15,7 @@ import { getContentContributionsSchema } from '../content/content-contributions.
|
|
|
15
15
|
import { getContentResourceSchema } from '../content/content-resource.js'
|
|
16
16
|
import { getOrganizationMembershipsSchema } from '../org/organization-memberships.js'
|
|
17
17
|
import { getAccountsSchema } from './accounts.js'
|
|
18
|
+
import { getProfilesSchema } from './profiles.js'
|
|
18
19
|
import { getUserPermissionsSchema } from './user-permissions.js'
|
|
19
20
|
import { getUserPrefsSchema } from './user-prefs.js'
|
|
20
21
|
import { getUserRolesSchema } from './user-roles.js'
|
|
@@ -48,6 +49,7 @@ export function getUsersSchema(mysqlTable: MySqlTableFn) {
|
|
|
48
49
|
|
|
49
50
|
export function getUsersRelationsSchema(mysqlTable: MySqlTableFn) {
|
|
50
51
|
const users = getUsersSchema(mysqlTable)
|
|
52
|
+
const profiles = getProfilesSchema(mysqlTable)
|
|
51
53
|
const accounts = getAccountsSchema(mysqlTable)
|
|
52
54
|
const communicationPreferences = getCommunicationPreferencesSchema(mysqlTable)
|
|
53
55
|
const userRoles = getUserRolesSchema(mysqlTable)
|
|
@@ -58,7 +60,10 @@ export function getUsersRelationsSchema(mysqlTable: MySqlTableFn) {
|
|
|
58
60
|
const comments = getCommentsSchema(mysqlTable)
|
|
59
61
|
const userPrefs = getUserPrefsSchema(mysqlTable)
|
|
60
62
|
const organizationMemberships = getOrganizationMembershipsSchema(mysqlTable)
|
|
61
|
-
return relations(users, ({ many }) => ({
|
|
63
|
+
return relations(users, ({ many, one }) => ({
|
|
64
|
+
profiles: many(profiles, {
|
|
65
|
+
relationName: 'profiles',
|
|
66
|
+
}),
|
|
62
67
|
accounts: many(accounts, {
|
|
63
68
|
relationName: 'user',
|
|
64
69
|
}),
|
|
@@ -8,14 +8,12 @@ import {
|
|
|
8
8
|
varchar,
|
|
9
9
|
} from 'drizzle-orm/mysql-core'
|
|
10
10
|
|
|
11
|
-
import { getUsersSchema } from '../auth/users.js'
|
|
12
11
|
import { getOrganizationsSchema } from '../org/organizations.js'
|
|
13
|
-
import { getCouponSchema } from './coupon.js'
|
|
14
|
-
import { getMerchantChargeSchema } from './merchant-charge.js'
|
|
15
|
-
import { getMerchantSessionSchema } from './merchant-session.js'
|
|
16
12
|
import { getMerchantSubscriptionSchema } from './merchant-subscription.js'
|
|
17
13
|
import { getProductSchema } from './product.js'
|
|
18
14
|
|
|
15
|
+
// TODO: do we add a renewal date here? probably just add that stuff to fields
|
|
16
|
+
// even status feels out of place at the top level maybe
|
|
19
17
|
export function getSubscriptionSchema(mysqlTable: MySqlTableFn) {
|
|
20
18
|
return mysqlTable(
|
|
21
19
|
'Subscription',
|
|
@@ -29,7 +27,7 @@ export function getSubscriptionSchema(mysqlTable: MySqlTableFn) {
|
|
|
29
27
|
merchantSubscriptionId: varchar('merchantSubscriptionId', {
|
|
30
28
|
length: 191,
|
|
31
29
|
}).notNull(),
|
|
32
|
-
status: varchar('status', { length: 191 }).default('
|
|
30
|
+
status: varchar('status', { length: 191 }).default('active').notNull(),
|
|
33
31
|
fields: json('fields').$type<Record<string, any>>().default({}),
|
|
34
32
|
},
|
|
35
33
|
(table) => {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MySqlTableFn,
|
|
3
|
+
text,
|
|
4
|
+
uniqueIndex,
|
|
5
|
+
varchar,
|
|
6
|
+
} from 'drizzle-orm/mysql-core'
|
|
7
|
+
|
|
8
|
+
export function getEntitlementTypesSchema(mysqlTable: MySqlTableFn) {
|
|
9
|
+
return mysqlTable(
|
|
10
|
+
'EntitlementType',
|
|
11
|
+
{
|
|
12
|
+
id: varchar('id', { length: 191 }).notNull().primaryKey(),
|
|
13
|
+
name: varchar('name', { length: 255 }).notNull(),
|
|
14
|
+
description: text('description'),
|
|
15
|
+
// Add any type-specific config fields here
|
|
16
|
+
},
|
|
17
|
+
(table) => ({
|
|
18
|
+
uniqueName: uniqueIndex('unique_name_idx').on(table.name),
|
|
19
|
+
}),
|
|
20
|
+
)
|
|
21
|
+
}
|