@coursebuilder/adapter-drizzle 2.1.0 → 3.0.0-canary.0.0c9beb2ae
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-KIQLUFJX.js → chunk-2GW3BJE2.js} +2 -2
- package/dist/{chunk-M3WM5Q7W.js → chunk-33ZN7FN7.js} +2 -2
- package/dist/chunk-4VZJQAPV.js +74 -0
- package/dist/chunk-5FLS4ZBX.js +109 -0
- package/dist/chunk-5YR5M22S.js +147 -0
- package/dist/chunk-6XQ6C3IX.js +18 -0
- package/dist/chunk-AIDM2CH6.js +146 -0
- package/dist/chunk-ALTODDUX.js +173 -0
- package/dist/chunk-AZY2VRAE.js +63 -0
- package/dist/chunk-BS7T27VL.js +239 -0
- package/dist/chunk-CN3FCRLR.js +55 -0
- package/dist/chunk-EAXC4CQD.js +245 -0
- package/dist/chunk-EDDG2YFS.js +249 -0
- package/dist/chunk-EDKWCMA7.js +210 -0
- package/dist/{chunk-CFSRMUNC.js → chunk-EDM6DKA5.js} +2 -2
- package/dist/{chunk-EZEQQJNH.js → chunk-EIQBTF5J.js} +2 -2
- package/dist/chunk-FYT7RTVW.js +248 -0
- package/dist/{chunk-DUFH5L2F.js → chunk-INZTF6QV.js} +2 -2
- package/dist/{chunk-3AF6MZQ7.js → chunk-JVHX4JHA.js} +2 -2
- package/dist/chunk-LWEKWDLC.js +300 -0
- package/dist/chunk-OJPEBGGE.js +139 -0
- package/dist/chunk-QKOSV34V.js +16268 -0
- package/dist/chunk-QO3QE3LE.js +330 -0
- package/dist/chunk-QQKNNFFB.js +399 -0
- package/dist/chunk-RBHCV3UW.js +20 -0
- package/dist/chunk-TNH2C27F.js +252 -0
- package/dist/chunk-TNWNW666.js +133 -0
- package/dist/chunk-VBEXYQ6L.js +156 -0
- package/dist/chunk-W3ILNMLD.js +265 -0
- package/dist/chunk-WJ2ZUXL3.js +71 -0
- package/dist/{chunk-4SWTV7Z3.js → chunk-WUMDFFN3.js} +2 -2
- package/dist/{chunk-FJGNLVE4.js → chunk-X7DRYXB7.js} +2 -2
- package/dist/{chunk-PNPTKVJ4.js → chunk-XUBZKYH6.js} +24 -15
- package/dist/{chunk-MYG6PCE3.js → chunk-ZY4AFKUQ.js} +2 -2
- package/dist/index.d.ts +5 -11
- package/dist/index.js +42 -19
- package/dist/lib/mysql/cms-resource-actions.cjs +15932 -4129
- package/dist/lib/mysql/cms-resource-actions.cjs.map +1 -1
- package/dist/lib/mysql/cms-resource-actions.d.cts +10 -25
- package/dist/lib/mysql/cms-resource-actions.d.ts +10 -25
- package/dist/lib/mysql/cms-resource-actions.js +2 -1
- package/dist/lib/mysql/context.cjs +3380 -0
- package/dist/lib/mysql/context.cjs.map +1 -0
- package/dist/lib/mysql/context.d.cts +15 -0
- package/dist/lib/mysql/context.d.ts +15 -0
- package/dist/lib/mysql/context.js +34 -0
- package/dist/lib/mysql/context.js.map +1 -0
- package/dist/lib/mysql/index.cjs +21648 -15013
- package/dist/lib/mysql/index.cjs.map +1 -1
- package/dist/lib/mysql/index.d.cts +24 -14300
- package/dist/lib/mysql/index.d.ts +24 -14300
- package/dist/lib/mysql/index.js +47 -23
- package/dist/lib/mysql/ports/auth-storage.cjs +84 -0
- package/dist/lib/mysql/ports/auth-storage.cjs.map +1 -0
- package/dist/lib/mysql/ports/auth-storage.d.cts +22 -0
- package/dist/lib/mysql/ports/auth-storage.d.ts +22 -0
- package/dist/lib/mysql/ports/auth-storage.js +8 -0
- package/dist/lib/mysql/ports/auth-storage.js.map +1 -0
- package/dist/lib/mysql/ports/catalog.cjs +16688 -0
- package/dist/lib/mysql/ports/catalog.cjs.map +1 -0
- package/dist/lib/mysql/ports/catalog.d.cts +24 -0
- package/dist/lib/mysql/ports/catalog.d.ts +24 -0
- package/dist/lib/mysql/ports/catalog.js +9 -0
- package/dist/lib/mysql/ports/catalog.js.map +1 -0
- package/dist/lib/mysql/ports/content-resource.cjs +321 -0
- package/dist/lib/mysql/ports/content-resource.cjs.map +1 -0
- package/dist/lib/mysql/ports/content-resource.d.cts +23 -0
- package/dist/lib/mysql/ports/content-resource.d.ts +23 -0
- package/dist/lib/mysql/ports/content-resource.js +8 -0
- package/dist/lib/mysql/ports/content-resource.js.map +1 -0
- package/dist/lib/mysql/ports/coupon.cjs +16524 -0
- package/dist/lib/mysql/ports/coupon.cjs.map +1 -0
- package/dist/lib/mysql/ports/coupon.d.cts +22 -0
- package/dist/lib/mysql/ports/coupon.d.ts +22 -0
- package/dist/lib/mysql/ports/coupon.js +9 -0
- package/dist/lib/mysql/ports/coupon.js.map +1 -0
- package/dist/lib/mysql/ports/entitlement.cjs +16350 -0
- package/dist/lib/mysql/ports/entitlement.cjs.map +1 -0
- package/dist/lib/mysql/ports/entitlement.d.cts +22 -0
- package/dist/lib/mysql/ports/entitlement.d.ts +22 -0
- package/dist/lib/mysql/ports/entitlement.js +9 -0
- package/dist/lib/mysql/ports/entitlement.js.map +1 -0
- package/dist/lib/mysql/ports/identity.cjs +154 -0
- package/dist/lib/mysql/ports/identity.cjs.map +1 -0
- package/dist/lib/mysql/ports/identity.d.cts +22 -0
- package/dist/lib/mysql/ports/identity.d.ts +22 -0
- package/dist/lib/mysql/ports/identity.js +8 -0
- package/dist/lib/mysql/ports/identity.js.map +1 -0
- package/dist/lib/mysql/ports/merchant.cjs +194 -0
- package/dist/lib/mysql/ports/merchant.cjs.map +1 -0
- package/dist/lib/mysql/ports/merchant.d.cts +22 -0
- package/dist/lib/mysql/ports/merchant.d.ts +22 -0
- package/dist/lib/mysql/ports/merchant.js +8 -0
- package/dist/lib/mysql/ports/merchant.js.map +1 -0
- package/dist/lib/mysql/ports/organization.cjs +16426 -0
- package/dist/lib/mysql/ports/organization.cjs.map +1 -0
- package/dist/lib/mysql/ports/organization.d.cts +22 -0
- package/dist/lib/mysql/ports/organization.d.ts +22 -0
- package/dist/lib/mysql/ports/organization.js +9 -0
- package/dist/lib/mysql/ports/organization.js.map +1 -0
- package/dist/lib/mysql/ports/progress.cjs +16544 -0
- package/dist/lib/mysql/ports/progress.cjs.map +1 -0
- package/dist/lib/mysql/ports/progress.d.cts +22 -0
- package/dist/lib/mysql/ports/progress.d.ts +22 -0
- package/dist/lib/mysql/ports/progress.js +9 -0
- package/dist/lib/mysql/ports/progress.js.map +1 -0
- package/dist/lib/mysql/ports/purchase.cjs +16609 -0
- package/dist/lib/mysql/ports/purchase.cjs.map +1 -0
- package/dist/lib/mysql/ports/purchase.d.cts +23 -0
- package/dist/lib/mysql/ports/purchase.d.ts +23 -0
- package/dist/lib/mysql/ports/purchase.js +9 -0
- package/dist/lib/mysql/ports/purchase.js.map +1 -0
- package/dist/lib/mysql/ports/subscription.cjs +76 -0
- package/dist/lib/mysql/ports/subscription.cjs.map +1 -0
- package/dist/lib/mysql/ports/subscription.d.cts +22 -0
- package/dist/lib/mysql/ports/subscription.d.ts +22 -0
- package/dist/lib/mysql/ports/subscription.js +8 -0
- package/dist/lib/mysql/ports/subscription.js.map +1 -0
- package/dist/lib/mysql/schema.cjs +3373 -0
- package/dist/lib/mysql/schema.cjs.map +1 -0
- package/dist/lib/mysql/schema.d.cts +14385 -0
- package/dist/lib/mysql/schema.d.ts +14385 -0
- package/dist/lib/mysql/schema.js +35 -0
- package/dist/lib/mysql/schema.js.map +1 -0
- package/dist/lib/mysql/schemas/auth/accounts.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/accounts.js +6 -6
- package/dist/lib/mysql/schemas/auth/device-access-token.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/device-access-token.js +7 -7
- package/dist/lib/mysql/schemas/auth/device-verification.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/device-verification.js +7 -7
- package/dist/lib/mysql/schemas/auth/personal-access-token.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/personal-access-token.js +7 -7
- package/dist/lib/mysql/schemas/auth/profiles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/profiles.js +6 -6
- package/dist/lib/mysql/schemas/auth/role-permissions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/role-permissions.js +7 -7
- package/dist/lib/mysql/schemas/auth/roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/roles.js +6 -6
- package/dist/lib/mysql/schemas/auth/sessions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/sessions.js +7 -7
- package/dist/lib/mysql/schemas/auth/user-permissions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-permissions.js +6 -6
- package/dist/lib/mysql/schemas/auth/user-prefs.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-prefs.js +6 -6
- package/dist/lib/mysql/schemas/auth/user-roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/user-roles.js +6 -6
- package/dist/lib/mysql/schemas/auth/users.cjs +5 -1
- package/dist/lib/mysql/schemas/auth/users.cjs.map +1 -1
- package/dist/lib/mysql/schemas/auth/users.js +6 -6
- package/dist/lib/mysql/schemas/commerce/coupon.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/coupon.js +6 -6
- package/dist/lib/mysql/schemas/commerce/merchant-charge.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/merchant-charge.js +6 -6
- package/dist/lib/mysql/schemas/commerce/merchant-subscription.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/merchant-subscription.js +6 -6
- package/dist/lib/mysql/schemas/commerce/price.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/price.js +6 -6
- package/dist/lib/mysql/schemas/commerce/product.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/product.js +6 -6
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.js +7 -7
- package/dist/lib/mysql/schemas/commerce/purchase.cjs +11 -2
- package/dist/lib/mysql/schemas/commerce/purchase.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/purchase.js +6 -6
- package/dist/lib/mysql/schemas/commerce/subscription.cjs +6 -1
- package/dist/lib/mysql/schemas/commerce/subscription.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/subscription.js +6 -6
- package/dist/lib/mysql/schemas/commerce/upgradable-products.cjs.map +1 -1
- package/dist/lib/mysql/schemas/commerce/upgradable-products.js +7 -7
- package/dist/lib/mysql/schemas/communication/comment.cjs +5 -1
- package/dist/lib/mysql/schemas/communication/comment.cjs.map +1 -1
- package/dist/lib/mysql/schemas/communication/comment.js +6 -6
- package/dist/lib/mysql/schemas/communication/communication-preferences.cjs +5 -1
- package/dist/lib/mysql/schemas/communication/communication-preferences.cjs.map +1 -1
- package/dist/lib/mysql/schemas/communication/communication-preferences.js +6 -6
- package/dist/lib/mysql/schemas/communication/question-response.cjs.map +1 -1
- package/dist/lib/mysql/schemas/communication/question-response.js +7 -7
- package/dist/lib/mysql/schemas/content/content-contributions.cjs +5 -1
- package/dist/lib/mysql/schemas/content/content-contributions.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-contributions.js +6 -6
- package/dist/lib/mysql/schemas/content/content-resource-product.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-product.js +6 -6
- package/dist/lib/mysql/schemas/content/content-resource-resource.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-resource.js +6 -6
- package/dist/lib/mysql/schemas/content/content-resource-tag.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-tag.js +6 -6
- package/dist/lib/mysql/schemas/content/content-resource-version.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource-version.js +6 -6
- package/dist/lib/mysql/schemas/content/content-resource.cjs +5 -1
- package/dist/lib/mysql/schemas/content/content-resource.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/content-resource.js +6 -6
- package/dist/lib/mysql/schemas/content/tag-tag.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/tag-tag.js +6 -6
- package/dist/lib/mysql/schemas/content/tag.cjs.map +1 -1
- package/dist/lib/mysql/schemas/content/tag.js +6 -6
- package/dist/lib/mysql/schemas/entitlements/entitlement.cjs +11 -2
- package/dist/lib/mysql/schemas/entitlements/entitlement.cjs.map +1 -1
- package/dist/lib/mysql/schemas/entitlements/entitlement.js +7 -7
- package/dist/lib/mysql/schemas/org/organization-membership-roles.cjs +11 -2
- package/dist/lib/mysql/schemas/org/organization-membership-roles.cjs.map +1 -1
- package/dist/lib/mysql/schemas/org/organization-membership-roles.js +6 -6
- package/dist/lib/mysql/schemas/org/organization-memberships.cjs +11 -2
- package/dist/lib/mysql/schemas/org/organization-memberships.cjs.map +1 -1
- package/dist/lib/mysql/schemas/org/organization-memberships.d.cts +16 -0
- package/dist/lib/mysql/schemas/org/organization-memberships.d.ts +16 -0
- package/dist/lib/mysql/schemas/org/organization-memberships.js +6 -6
- package/dist/lib/mysql/schemas/org/organizations.cjs +11 -2
- package/dist/lib/mysql/schemas/org/organizations.cjs.map +1 -1
- package/dist/lib/mysql/schemas/org/organizations.d.cts +16 -0
- package/dist/lib/mysql/schemas/org/organizations.d.ts +16 -0
- package/dist/lib/mysql/schemas/org/organizations.js +6 -6
- package/dist/lib/mysql/workflows/content-resource-workflow-utils.cjs +40 -0
- package/dist/lib/mysql/workflows/content-resource-workflow-utils.cjs.map +1 -0
- package/dist/lib/mysql/workflows/content-resource-workflow-utils.d.cts +4 -0
- package/dist/lib/mysql/workflows/content-resource-workflow-utils.d.ts +4 -0
- package/dist/lib/mysql/workflows/content-resource-workflow-utils.js +10 -0
- package/dist/lib/mysql/workflows/content-resource-workflow-utils.js.map +1 -0
- package/dist/lib/mysql/workflows/create-cohort.cjs +184 -0
- package/dist/lib/mysql/workflows/create-cohort.cjs.map +1 -0
- package/dist/lib/mysql/workflows/create-cohort.d.cts +24 -0
- package/dist/lib/mysql/workflows/create-cohort.d.ts +24 -0
- package/dist/lib/mysql/workflows/create-cohort.js +9 -0
- package/dist/lib/mysql/workflows/create-cohort.js.map +1 -0
- package/dist/lib/mysql/workflows/create-event-series.cjs +283 -0
- package/dist/lib/mysql/workflows/create-event-series.cjs.map +1 -0
- package/dist/lib/mysql/workflows/create-event-series.d.cts +24 -0
- package/dist/lib/mysql/workflows/create-event-series.d.ts +24 -0
- package/dist/lib/mysql/workflows/create-event-series.js +9 -0
- package/dist/lib/mysql/workflows/create-event-series.js.map +1 -0
- package/dist/lib/mysql/workflows/create-event.cjs +194 -0
- package/dist/lib/mysql/workflows/create-event.cjs.map +1 -0
- package/dist/lib/mysql/workflows/create-event.d.cts +24 -0
- package/dist/lib/mysql/workflows/create-event.d.ts +24 -0
- package/dist/lib/mysql/workflows/create-event.js +9 -0
- package/dist/lib/mysql/workflows/create-event.js.map +1 -0
- package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.cjs +231 -0
- package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.cjs.map +1 -0
- package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.d.cts +22 -0
- package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.d.ts +22 -0
- package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.js +8 -0
- package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.js.map +1 -0
- package/dist/lib/mysql/workflows/create-workshop.cjs +286 -0
- package/dist/lib/mysql/workflows/create-workshop.cjs.map +1 -0
- package/dist/lib/mysql/workflows/create-workshop.d.cts +24 -0
- package/dist/lib/mysql/workflows/create-workshop.d.ts +24 -0
- package/dist/lib/mysql/workflows/create-workshop.js +9 -0
- package/dist/lib/mysql/workflows/create-workshop.js.map +1 -0
- package/dist/lib/mysql/workflows/redeem-full-price-coupon.cjs +130 -0
- package/dist/lib/mysql/workflows/redeem-full-price-coupon.cjs.map +1 -0
- package/dist/lib/mysql/workflows/redeem-full-price-coupon.d.cts +24 -0
- package/dist/lib/mysql/workflows/redeem-full-price-coupon.d.ts +24 -0
- package/dist/lib/mysql/workflows/redeem-full-price-coupon.js +8 -0
- package/dist/lib/mysql/workflows/redeem-full-price-coupon.js.map +1 -0
- package/dist/lib/mysql/workflows/transfer-purchase-to-user.cjs +95 -0
- package/dist/lib/mysql/workflows/transfer-purchase-to-user.cjs.map +1 -0
- package/dist/lib/mysql/workflows/transfer-purchase-to-user.d.cts +30 -0
- package/dist/lib/mysql/workflows/transfer-purchase-to-user.d.ts +30 -0
- package/dist/lib/mysql/workflows/transfer-purchase-to-user.js +8 -0
- package/dist/lib/mysql/workflows/transfer-purchase-to-user.js.map +1 -0
- package/dist/lib/utils.d.cts +1 -10
- package/dist/lib/utils.d.ts +1 -10
- package/dist/types.d.ts +14 -0
- package/dist/types.js +1 -0
- package/package.json +9 -5
- package/src/index.ts +3 -2
- package/src/lib/mysql/cms-resource-actions.ts +37 -0
- package/src/lib/mysql/context.ts +20 -0
- package/src/lib/mysql/index.ts +118 -4872
- package/src/lib/mysql/ports/auth-storage.ts +139 -0
- package/src/lib/mysql/ports/catalog.ts +610 -0
- package/src/lib/mysql/ports/content-resource.ts +442 -0
- package/src/lib/mysql/ports/coupon.ts +387 -0
- package/src/lib/mysql/ports/entitlement.ts +96 -0
- package/src/lib/mysql/ports/identity.ts +160 -0
- package/src/lib/mysql/ports/merchant.ts +274 -0
- package/src/lib/mysql/ports/organization.ts +216 -0
- package/src/lib/mysql/ports/progress.ts +366 -0
- package/src/lib/mysql/ports/purchase.ts +517 -0
- package/src/lib/mysql/ports/subscription.ts +93 -0
- package/src/lib/mysql/schema.ts +374 -0
- package/src/lib/mysql/schemas/org/organization-memberships.ts +7 -0
- package/src/lib/mysql/schemas/org/organizations.ts +8 -0
- package/src/lib/mysql/workflows/content-resource-workflow-utils.ts +22 -0
- package/src/lib/mysql/workflows/create-cohort.ts +239 -0
- package/src/lib/mysql/workflows/create-event-series.ts +384 -0
- package/src/lib/mysql/workflows/create-event.ts +232 -0
- package/src/lib/mysql/workflows/create-merchant-charge-and-purchase.ts +365 -0
- package/src/lib/mysql/workflows/create-workshop.ts +372 -0
- package/src/lib/mysql/workflows/redeem-full-price-coupon.ts +179 -0
- package/src/lib/mysql/workflows/transfer-purchase-to-user.ts +142 -0
- package/src/types.ts +33 -0
- package/dist/authjs.d.ts +0 -27
- package/dist/authjs.js +0 -1
- package/dist/chunk-25RKHMRM.js +0 -8729
- package/dist/chunk-2AW5KYAK.js +0 -101
- package/dist/chunk-3EF5ZXLG.js +0 -101
- package/dist/chunk-7FBSP3VD.js +0 -78
- package/dist/chunk-AP5HBIV4.js +0 -112
- package/dist/chunk-F56AI52P.js +0 -49
- package/dist/chunk-HAQZSRJL.js +0 -4696
- package/dist/chunk-I2U5PTWN.js +0 -79
- package/dist/chunk-IBQGXFEX.js +0 -8729
- package/dist/chunk-PJORQUQP.js +0 -58
- package/dist/chunk-W6RPAAKG.js +0 -2144
- package/dist/chunk-WKJTU24D.js +0 -88
- package/dist/chunk-WWBSNLRC.js +0 -63
- package/src/authjs.ts +0 -34
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CatalogPort, CouponPort, ContentResourcePort } from '@coursebuilder/core/ports';
|
|
2
|
+
import { MySqlContext } from '../context.js';
|
|
3
|
+
import 'drizzle-orm/mysql-core';
|
|
4
|
+
import '../schema.js';
|
|
5
|
+
import 'drizzle-orm';
|
|
6
|
+
import '@coursebuilder/core/auth';
|
|
7
|
+
import '../schemas/auth/users.js';
|
|
8
|
+
|
|
9
|
+
type CreateEventSeriesOperations = Pick<CatalogPort, 'createProduct' | 'addResourceToProduct'> & Pick<CouponPort, 'createCoupon'>;
|
|
10
|
+
/**
|
|
11
|
+
* Creates the private event series creation workflow.
|
|
12
|
+
*
|
|
13
|
+
* @param context - The shared MySQL client and table set.
|
|
14
|
+
* @param operations - Narrow catalog, coupon, and content resource operations.
|
|
15
|
+
* @returns The content resource creation operation.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const workflow = createEventSeriesWorkflow(context, operations)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function createEventSeriesWorkflow({ client, tables }: MySqlContext, operations: CreateEventSeriesOperations): Pick<ContentResourcePort, 'createEventSeries'>;
|
|
23
|
+
|
|
24
|
+
export { createEventSeriesWorkflow };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/lib/mysql/workflows/create-event.ts
|
|
32
|
+
var create_event_exports = {};
|
|
33
|
+
__export(create_event_exports, {
|
|
34
|
+
createEventWorkflow: () => createEventWorkflow
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(create_event_exports);
|
|
37
|
+
var import_slugify = __toESM(require("@sindresorhus/slugify"), 1);
|
|
38
|
+
var import_content_resource_schema = require("@coursebuilder/core/schemas/content-resource-schema");
|
|
39
|
+
var import_logger = require("@coursebuilder/utils/logger");
|
|
40
|
+
|
|
41
|
+
// src/lib/mysql/workflows/content-resource-workflow-utils.ts
|
|
42
|
+
var import_nanoid = require("nanoid");
|
|
43
|
+
var guid = (0, import_nanoid.customAlphabet)("1234567890abcdefghijklmnopqrstuvwxyz", 5);
|
|
44
|
+
var normalizeExpirationDate = /* @__PURE__ */ __name((date) => {
|
|
45
|
+
if (!date)
|
|
46
|
+
return void 0;
|
|
47
|
+
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 23, 59, 59, 0));
|
|
48
|
+
}, "normalizeExpirationDate");
|
|
49
|
+
|
|
50
|
+
// src/lib/mysql/workflows/create-event.ts
|
|
51
|
+
var logger = import_logger.logger;
|
|
52
|
+
function createEventWorkflow({ client, tables }, operations) {
|
|
53
|
+
const { contentResource, contentResourceTag } = tables;
|
|
54
|
+
return {
|
|
55
|
+
async createEvent(input, userId) {
|
|
56
|
+
const hash = guid();
|
|
57
|
+
const newEventId = (0, import_slugify.default)(`${input.type}~${hash}`);
|
|
58
|
+
const newEvent = {
|
|
59
|
+
id: newEventId,
|
|
60
|
+
type: "event",
|
|
61
|
+
fields: {
|
|
62
|
+
title: input.fields.title,
|
|
63
|
+
state: "draft",
|
|
64
|
+
visibility: "public",
|
|
65
|
+
slug: (0, import_slugify.default)(`${input.fields.title}~${hash}`),
|
|
66
|
+
description: input.fields.description,
|
|
67
|
+
startsAt: input.fields.startsAt,
|
|
68
|
+
endsAt: input.fields.endsAt
|
|
69
|
+
},
|
|
70
|
+
createdById: userId
|
|
71
|
+
};
|
|
72
|
+
await client.insert(contentResource).values(newEvent);
|
|
73
|
+
const event = await operations.getEvent(newEventId, {
|
|
74
|
+
withResources: true,
|
|
75
|
+
withTags: true,
|
|
76
|
+
withProducts: true,
|
|
77
|
+
withPricing: true
|
|
78
|
+
});
|
|
79
|
+
const parsedEvent = import_content_resource_schema.ContentResourceSchema.safeParse(event);
|
|
80
|
+
if (!parsedEvent.success) {
|
|
81
|
+
logger.error(new Error("Error parsing event resource"));
|
|
82
|
+
throw new Error("Error parsing event resource");
|
|
83
|
+
}
|
|
84
|
+
if (input.fields.price && input.fields.price > 0) {
|
|
85
|
+
try {
|
|
86
|
+
const product = await operations.createProduct({
|
|
87
|
+
name: input.fields.title,
|
|
88
|
+
price: input.fields.price,
|
|
89
|
+
quantityAvailable: input.fields.quantity ?? -1,
|
|
90
|
+
type: "live",
|
|
91
|
+
state: "published",
|
|
92
|
+
visibility: "public"
|
|
93
|
+
});
|
|
94
|
+
if (product) {
|
|
95
|
+
const resourceProduct = await operations.addResourceToProduct({
|
|
96
|
+
resource: parsedEvent.data,
|
|
97
|
+
productId: product.id,
|
|
98
|
+
userId
|
|
99
|
+
});
|
|
100
|
+
if (!resourceProduct) {
|
|
101
|
+
logger.error(new Error("Failed to add resource to product"));
|
|
102
|
+
logger.debug("event.addResourceToProduct.failed", {
|
|
103
|
+
eventId: newEventId,
|
|
104
|
+
productId: product.id,
|
|
105
|
+
userId
|
|
106
|
+
});
|
|
107
|
+
} else {
|
|
108
|
+
logger.debug("event.addResourceToProduct.success", {
|
|
109
|
+
eventId: newEventId,
|
|
110
|
+
productId: product.id,
|
|
111
|
+
userId
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (input.coupon?.enabled && input.coupon.percentageDiscount && input.coupon.expires) {
|
|
115
|
+
try {
|
|
116
|
+
const finalExpires = normalizeExpirationDate(input.coupon.expires);
|
|
117
|
+
const couponInput = {
|
|
118
|
+
quantity: "1",
|
|
119
|
+
maxUses: -1,
|
|
120
|
+
expires: finalExpires || null,
|
|
121
|
+
restrictedToProductId: product.id,
|
|
122
|
+
percentageDiscount: input.coupon.percentageDiscount,
|
|
123
|
+
status: 1,
|
|
124
|
+
default: true,
|
|
125
|
+
fields: {
|
|
126
|
+
bypassSoldOut: false
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
await operations.createCoupon(couponInput);
|
|
130
|
+
logger.debug("event.create.coupon.success", {
|
|
131
|
+
eventId: newEventId,
|
|
132
|
+
productId: product.id,
|
|
133
|
+
userId,
|
|
134
|
+
percentageDiscount: input.coupon.percentageDiscount
|
|
135
|
+
});
|
|
136
|
+
} catch (couponError) {
|
|
137
|
+
logger.error(new Error(`Failed to create coupon for event: ${couponError}`));
|
|
138
|
+
logger.debug("event.create.coupon.failed", {
|
|
139
|
+
eventId: newEventId,
|
|
140
|
+
productId: product.id,
|
|
141
|
+
userId
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
logger.error(new Error("Failed to create product"));
|
|
147
|
+
logger.debug("event.create.product.failed", {
|
|
148
|
+
eventId: newEventId,
|
|
149
|
+
userId,
|
|
150
|
+
price: input.fields.price
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
logger.error(new Error(`Error creating and associating product: ${error}`));
|
|
155
|
+
logger.debug("event.create.product.failed", {
|
|
156
|
+
eventId: newEventId,
|
|
157
|
+
userId,
|
|
158
|
+
price: input.fields.price
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (input.fields.tagIds) {
|
|
163
|
+
try {
|
|
164
|
+
await client.insert(contentResourceTag).values(input.fields.tagIds.map((tag) => ({
|
|
165
|
+
contentResourceId: newEventId,
|
|
166
|
+
tagId: tag.id,
|
|
167
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
168
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
169
|
+
position: 0
|
|
170
|
+
})));
|
|
171
|
+
logger.debug("event.create.tags.success", {
|
|
172
|
+
eventId: newEventId,
|
|
173
|
+
userId,
|
|
174
|
+
tagIds: input.fields.tagIds
|
|
175
|
+
});
|
|
176
|
+
} catch (error) {
|
|
177
|
+
logger.error(new Error(`Error associating tags with event: ${error}`));
|
|
178
|
+
logger.debug("event.create.tags.failed", {
|
|
179
|
+
eventId: newEventId,
|
|
180
|
+
userId,
|
|
181
|
+
tagIds: input.fields.tagIds
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return parsedEvent.data;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
__name(createEventWorkflow, "createEventWorkflow");
|
|
190
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
191
|
+
0 && (module.exports = {
|
|
192
|
+
createEventWorkflow
|
|
193
|
+
});
|
|
194
|
+
//# sourceMappingURL=create-event.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/mysql/workflows/create-event.ts","../../../../src/lib/mysql/workflows/content-resource-workflow-utils.ts"],"sourcesContent":["import slugify from '@sindresorhus/slugify'\nimport { asc, eq } from 'drizzle-orm'\n\nimport type {\n\tCatalogPort,\n\tContentResourcePort,\n\tCouponPort,\n} from '@coursebuilder/core/ports'\nimport {\n\tContentResourceSchema,\n\ttype ContentResource,\n} from '@coursebuilder/core/schemas/content-resource-schema'\nimport { logger as baseLogger } from '@coursebuilder/utils/logger'\n\nimport type { MySqlContext } from '../context.js'\nimport {\n\tguid,\n\tnormalizeExpirationDate,\n} from './content-resource-workflow-utils.js'\n\nconst logger = baseLogger as unknown as {\n\tdebug: (message: string, attrs?: Record<string, unknown>) => void\n\terror: (error: Error, attrs?: Record<string, unknown>) => void\n}\n\ntype CreateEventOperations = Pick<ContentResourcePort, 'getEvent'> &\n\tPick<CatalogPort, 'createProduct' | 'addResourceToProduct'> &\n\tPick<CouponPort, 'createCoupon'>\n\n/**\n * Creates the private event creation workflow.\n *\n * @param context - The shared MySQL client and table set.\n * @param operations - Narrow catalog, coupon, and content resource operations.\n * @returns The content resource creation operation.\n *\n * @example\n * ```ts\n * const workflow = createEventWorkflow(context, operations)\n * ```\n */\nexport function createEventWorkflow(\n\t{ client, tables }: MySqlContext,\n\toperations: CreateEventOperations,\n): Pick<ContentResourcePort, 'createEvent'> {\n\tconst { contentResource, contentResourceTag } = tables\n\n\treturn {\n\t\tasync createEvent(\n\t\t\tinput: {\n\t\t\t\ttype: 'event'\n\t\t\t\tfields: {\n\t\t\t\t\ttitle: string\n\t\t\t\t\tstartsAt?: Date | null | undefined\n\t\t\t\t\tendsAt?: Date | null | undefined\n\t\t\t\t\tdescription?: string | null | undefined\n\t\t\t\t\tprice?: number | null | undefined\n\t\t\t\t\tquantity?: number | null | undefined\n\t\t\t\t\tstate?: string | null | undefined\n\t\t\t\t\tvisibility?: string | null | undefined\n\t\t\t\t\tslug?: string | null | undefined\n\t\t\t\t\ttagIds?:\n\t\t\t\t\t\t| { id: string; fields: Record<string, any> }[]\n\t\t\t\t\t\t| null\n\t\t\t\t\t\t| undefined\n\t\t\t\t}\n\t\t\t\tcoupon?: {\n\t\t\t\t\tenabled: boolean\n\t\t\t\t\tpercentageDiscount: string\n\t\t\t\t\texpires: Date\n\t\t\t\t}\n\t\t\t},\n\t\t\tuserId: string,\n\t\t) {\n\t\t\tconst hash = guid()\n\t\t\tconst newEventId = slugify(`${input.type}~${hash}`)\n\n\t\t\tconst newEvent = {\n\t\t\t\tid: newEventId,\n\t\t\t\ttype: 'event',\n\t\t\t\tfields: {\n\t\t\t\t\ttitle: input.fields.title,\n\t\t\t\t\tstate: 'draft',\n\t\t\t\t\tvisibility: 'public',\n\t\t\t\t\tslug: slugify(`${input.fields.title}~${hash}`),\n\t\t\t\t\tdescription: input.fields.description,\n\t\t\t\t\tstartsAt: input.fields.startsAt,\n\t\t\t\t\tendsAt: input.fields.endsAt,\n\t\t\t\t},\n\t\t\t\tcreatedById: userId,\n\t\t\t}\n\n\t\t\tawait client.insert(contentResource).values(newEvent)\n\t\t\tconst event = await operations.getEvent(newEventId, {\n\t\t\t\twithResources: true,\n\t\t\t\twithTags: true,\n\t\t\t\twithProducts: true,\n\t\t\t\twithPricing: true,\n\t\t\t})\n\n\t\t\tconst parsedEvent = ContentResourceSchema.safeParse(event)\n\n\t\t\tif (!parsedEvent.success) {\n\t\t\t\tlogger.error(new Error('Error parsing event resource'))\n\t\t\t\tthrow new Error('Error parsing event resource')\n\t\t\t}\n\n\t\t\t// if price is provided, create a product and associate it with the event\n\t\t\tif (input.fields.price && input.fields.price > 0) {\n\t\t\t\ttry {\n\t\t\t\t\tconst product = await operations.createProduct({\n\t\t\t\t\t\tname: input.fields.title,\n\t\t\t\t\t\tprice: input.fields.price,\n\t\t\t\t\t\tquantityAvailable: input.fields.quantity ?? -1,\n\t\t\t\t\t\ttype: 'live',\n\t\t\t\t\t\tstate: 'published',\n\t\t\t\t\t\tvisibility: 'public',\n\t\t\t\t\t})\n\t\t\t\t\tif (product) {\n\t\t\t\t\t\tconst resourceProduct = await operations.addResourceToProduct({\n\t\t\t\t\t\t\tresource: parsedEvent.data,\n\t\t\t\t\t\t\tproductId: product.id,\n\t\t\t\t\t\t\tuserId,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (!resourceProduct) {\n\t\t\t\t\t\t\tlogger.error(new Error('Failed to add resource to product'))\n\t\t\t\t\t\t\tlogger.debug('event.addResourceToProduct.failed', {\n\t\t\t\t\t\t\t\teventId: newEventId,\n\t\t\t\t\t\t\t\tproductId: product.id,\n\t\t\t\t\t\t\t\tuserId,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlogger.debug('event.addResourceToProduct.success', {\n\t\t\t\t\t\t\t\teventId: newEventId,\n\t\t\t\t\t\t\t\tproductId: product.id,\n\t\t\t\t\t\t\t\tuserId,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Create coupon if enabled\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinput.coupon?.enabled &&\n\t\t\t\t\t\t\tinput.coupon.percentageDiscount &&\n\t\t\t\t\t\t\tinput.coupon.expires\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst finalExpires = normalizeExpirationDate(\n\t\t\t\t\t\t\t\t\tinput.coupon.expires,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tconst couponInput = {\n\t\t\t\t\t\t\t\t\tquantity: '1',\n\t\t\t\t\t\t\t\t\tmaxUses: -1,\n\t\t\t\t\t\t\t\t\texpires: finalExpires || null,\n\t\t\t\t\t\t\t\t\trestrictedToProductId: product.id,\n\t\t\t\t\t\t\t\t\tpercentageDiscount: input.coupon.percentageDiscount,\n\t\t\t\t\t\t\t\t\tstatus: 1,\n\t\t\t\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\t\t\t\tfields: {\n\t\t\t\t\t\t\t\t\t\tbypassSoldOut: false,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tawait operations.createCoupon(couponInput)\n\t\t\t\t\t\t\t\tlogger.debug('event.create.coupon.success', {\n\t\t\t\t\t\t\t\t\teventId: newEventId,\n\t\t\t\t\t\t\t\t\tproductId: product.id,\n\t\t\t\t\t\t\t\t\tuserId,\n\t\t\t\t\t\t\t\t\tpercentageDiscount: input.coupon.percentageDiscount,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} catch (couponError) {\n\t\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t`Failed to create coupon for event: ${couponError}`,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tlogger.debug('event.create.coupon.failed', {\n\t\t\t\t\t\t\t\t\teventId: newEventId,\n\t\t\t\t\t\t\t\t\tproductId: product.id,\n\t\t\t\t\t\t\t\t\tuserId,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t// Don't throw here - event creation should succeed even if coupon fails\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger.error(new Error('Failed to create product'))\n\t\t\t\t\t\tlogger.debug('event.create.product.failed', {\n\t\t\t\t\t\t\teventId: newEventId,\n\t\t\t\t\t\t\tuserId,\n\t\t\t\t\t\t\tprice: input.fields.price,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error(\n\t\t\t\t\t\tnew Error(`Error creating and associating product: ${error}`),\n\t\t\t\t\t)\n\t\t\t\t\tlogger.debug('event.create.product.failed', {\n\t\t\t\t\t\teventId: newEventId,\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t\tprice: input.fields.price,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// if we provide tagIds, we need to associate them with the event\n\t\t\tif (input.fields.tagIds) {\n\t\t\t\ttry {\n\t\t\t\t\tawait client.insert(contentResourceTag).values(\n\t\t\t\t\t\tinput.fields.tagIds.map((tag) => ({\n\t\t\t\t\t\t\tcontentResourceId: newEventId,\n\t\t\t\t\t\t\ttagId: tag.id,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\tposition: 0,\n\t\t\t\t\t\t})),\n\t\t\t\t\t)\n\t\t\t\t\tlogger.debug('event.create.tags.success', {\n\t\t\t\t\t\teventId: newEventId,\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t\ttagIds: input.fields.tagIds,\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error(new Error(`Error associating tags with event: ${error}`))\n\t\t\t\t\tlogger.debug('event.create.tags.failed', {\n\t\t\t\t\t\teventId: newEventId,\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t\ttagIds: input.fields.tagIds,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn parsedEvent.data\n\t\t},\n\t}\n}\n","import { customAlphabet } from 'nanoid'\n\nexport const guid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 5)\n\nexport const normalizeExpirationDate = (date: Date | undefined) => {\n\tif (!date) return undefined\n\n\t// Create a new Date object for 23:59:59 UTC on the date part of the input date\n\t// The input date should be a JS Date representing 00:00:00 LA time for the chosen day.\n\t// Its UTC date parts (getUTCFullYear, etc.) will give us the correct calendar day.\n\treturn new Date(\n\t\tDate.UTC(\n\t\t\tdate.getUTCFullYear(),\n\t\t\tdate.getUTCMonth(), // 0-indexed\n\t\t\tdate.getUTCDate(),\n\t\t\t23, // hours\n\t\t\t59, // minutes\n\t\t\t59, // seconds\n\t\t\t0, // milliseconds\n\t\t),\n\t)\n}\n"],"mappings":"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","names":["guid","customAlphabet","normalizeExpirationDate","date","undefined","Date","UTC","getUTCFullYear","getUTCMonth","getUTCDate","logger","baseLogger","createEventWorkflow","client","tables","operations","contentResource","contentResourceTag","createEvent","input","userId","hash","guid","newEventId","slugify","type","newEvent","id","fields","title","state","visibility","slug","description","startsAt","endsAt","createdById","insert","values","event","getEvent","withResources","withTags","withProducts","withPricing","parsedEvent","ContentResourceSchema","safeParse","success","error","Error","price","product","createProduct","name","quantityAvailable","quantity","resourceProduct","addResourceToProduct","resource","data","productId","debug","eventId","coupon","enabled","percentageDiscount","expires","finalExpires","normalizeExpirationDate","couponInput","maxUses","restrictedToProductId","status","default","bypassSoldOut","createCoupon","couponError","tagIds","map","tag","contentResourceId","tagId","createdAt","Date","updatedAt","position"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ContentResourcePort, CatalogPort, CouponPort } from '@coursebuilder/core/ports';
|
|
2
|
+
import { MySqlContext } from '../context.cjs';
|
|
3
|
+
import 'drizzle-orm/mysql-core';
|
|
4
|
+
import '../schema.cjs';
|
|
5
|
+
import 'drizzle-orm';
|
|
6
|
+
import '@coursebuilder/core/auth';
|
|
7
|
+
import '../schemas/auth/users.cjs';
|
|
8
|
+
|
|
9
|
+
type CreateEventOperations = Pick<ContentResourcePort, 'getEvent'> & Pick<CatalogPort, 'createProduct' | 'addResourceToProduct'> & Pick<CouponPort, 'createCoupon'>;
|
|
10
|
+
/**
|
|
11
|
+
* Creates the private event creation workflow.
|
|
12
|
+
*
|
|
13
|
+
* @param context - The shared MySQL client and table set.
|
|
14
|
+
* @param operations - Narrow catalog, coupon, and content resource operations.
|
|
15
|
+
* @returns The content resource creation operation.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const workflow = createEventWorkflow(context, operations)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function createEventWorkflow({ client, tables }: MySqlContext, operations: CreateEventOperations): Pick<ContentResourcePort, 'createEvent'>;
|
|
23
|
+
|
|
24
|
+
export { createEventWorkflow };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ContentResourcePort, CatalogPort, CouponPort } from '@coursebuilder/core/ports';
|
|
2
|
+
import { MySqlContext } from '../context.js';
|
|
3
|
+
import 'drizzle-orm/mysql-core';
|
|
4
|
+
import '../schema.js';
|
|
5
|
+
import 'drizzle-orm';
|
|
6
|
+
import '@coursebuilder/core/auth';
|
|
7
|
+
import '../schemas/auth/users.js';
|
|
8
|
+
|
|
9
|
+
type CreateEventOperations = Pick<ContentResourcePort, 'getEvent'> & Pick<CatalogPort, 'createProduct' | 'addResourceToProduct'> & Pick<CouponPort, 'createCoupon'>;
|
|
10
|
+
/**
|
|
11
|
+
* Creates the private event creation workflow.
|
|
12
|
+
*
|
|
13
|
+
* @param context - The shared MySQL client and table set.
|
|
14
|
+
* @param operations - Narrow catalog, coupon, and content resource operations.
|
|
15
|
+
* @returns The content resource creation operation.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const workflow = createEventWorkflow(context, operations)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function createEventWorkflow({ client, tables }: MySqlContext, operations: CreateEventOperations): Pick<ContentResourcePort, 'createEvent'>;
|
|
23
|
+
|
|
24
|
+
export { createEventWorkflow };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/lib/mysql/workflows/create-merchant-charge-and-purchase.ts
|
|
22
|
+
var create_merchant_charge_and_purchase_exports = {};
|
|
23
|
+
__export(create_merchant_charge_and_purchase_exports, {
|
|
24
|
+
createMerchantChargeAndPurchaseWorkflow: () => createMerchantChargeAndPurchaseWorkflow
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(create_merchant_charge_and_purchase_exports);
|
|
27
|
+
var import_drizzle_orm = require("drizzle-orm");
|
|
28
|
+
var import_uuid = require("uuid");
|
|
29
|
+
var import_purchase_benefit_transport = require("@coursebuilder/commerce/purchase-benefit-transport");
|
|
30
|
+
var import_schemas = require("@coursebuilder/core/schemas");
|
|
31
|
+
var import_logger = require("@coursebuilder/utils/logger");
|
|
32
|
+
function toError(error) {
|
|
33
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
34
|
+
}
|
|
35
|
+
__name(toError, "toError");
|
|
36
|
+
var logger = import_logger.logger;
|
|
37
|
+
function mergePurchaseBenefitFields(fields, expansion) {
|
|
38
|
+
if (!expansion)
|
|
39
|
+
return fields;
|
|
40
|
+
return {
|
|
41
|
+
...fields,
|
|
42
|
+
...expansion.success ? {
|
|
43
|
+
purchaseBenefits: expansion.benefits
|
|
44
|
+
} : {
|
|
45
|
+
purchaseBenefitsReview: expansion.review
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
__name(mergePurchaseBenefitFields, "mergePurchaseBenefitFields");
|
|
50
|
+
function createMerchantChargeAndPurchaseWorkflow({ client, tables }) {
|
|
51
|
+
const { purchases: purchaseTable, purchaseUserTransfer, coupon, merchantCoupon, merchantCharge, merchantSession } = tables;
|
|
52
|
+
return {
|
|
53
|
+
async createMerchantChargeAndPurchase(options) {
|
|
54
|
+
const purchaseId = await client.transaction(async (trx) => {
|
|
55
|
+
try {
|
|
56
|
+
const { userId, stripeChargeId, stripeCouponId, merchantAccountId, merchantProductId, merchantCustomerId, productId, stripeChargeAmount, quantity = 1, checkoutSessionId, appliedPPPStripeCouponId, upgradedFromPurchaseId, country, usedCouponId, organizationId, attributionSnapshot } = options;
|
|
57
|
+
const existingMerchantCharge = import_schemas.merchantChargeSchema.nullable().parse(await trx.query.merchantCharge.findFirst({
|
|
58
|
+
where: (0, import_drizzle_orm.eq)(merchantCharge.identifier, stripeChargeId)
|
|
59
|
+
}) || null);
|
|
60
|
+
const existingPurchaseForCharge = existingMerchantCharge ? await trx.query.purchases.findFirst({
|
|
61
|
+
where: (0, import_drizzle_orm.eq)(purchaseTable.merchantChargeId, existingMerchantCharge.id),
|
|
62
|
+
with: {
|
|
63
|
+
user: true,
|
|
64
|
+
product: true,
|
|
65
|
+
bulkCoupon: true
|
|
66
|
+
}
|
|
67
|
+
}) : null;
|
|
68
|
+
if (existingPurchaseForCharge) {
|
|
69
|
+
return existingPurchaseForCharge.id;
|
|
70
|
+
}
|
|
71
|
+
const merchantChargeId = `mc_${(0, import_uuid.v4)()}`;
|
|
72
|
+
const purchaseId2 = `purch_${(0, import_uuid.v4)()}`;
|
|
73
|
+
const newMerchantCharge = await trx.insert(merchantCharge).values({
|
|
74
|
+
id: merchantChargeId,
|
|
75
|
+
userId,
|
|
76
|
+
identifier: stripeChargeId,
|
|
77
|
+
merchantAccountId,
|
|
78
|
+
merchantProductId,
|
|
79
|
+
merchantCustomerId
|
|
80
|
+
});
|
|
81
|
+
const existingPurchase = import_schemas.purchaseSchema.nullable().parse(await trx.query.purchases.findFirst({
|
|
82
|
+
where: (0, import_drizzle_orm.and)((0, import_drizzle_orm.eq)(purchaseTable.productId, productId), (0, import_drizzle_orm.eq)(purchaseTable.userId, userId), (0, import_drizzle_orm.inArray)(purchaseTable.status, [
|
|
83
|
+
"Valid",
|
|
84
|
+
"Restricted"
|
|
85
|
+
]))
|
|
86
|
+
}) || null);
|
|
87
|
+
const existingBulkCoupon = import_schemas.couponSchema.nullable().parse(await trx.select().from(coupon).leftJoin(purchaseTable, (0, import_drizzle_orm.and)((0, import_drizzle_orm.eq)(coupon.id, purchaseTable.bulkCouponId), (0, import_drizzle_orm.eq)(purchaseTable.userId, userId))).where((0, import_drizzle_orm.and)((0, import_drizzle_orm.eq)(coupon.restrictedToProductId, productId), (0, import_drizzle_orm.eq)(purchaseTable.userId, userId), (0, import_drizzle_orm.eq)(purchaseTable.status, "Valid"))).then((res) => {
|
|
88
|
+
return res[0]?.Coupon ?? null;
|
|
89
|
+
}));
|
|
90
|
+
const isBulkPurchase = quantity > 1 || Boolean(existingBulkCoupon) || Boolean(options.bulk);
|
|
91
|
+
let bulkCouponId = null;
|
|
92
|
+
let couponToUpdate = null;
|
|
93
|
+
const purchaseBenefitsTransport = options.purchaseBenefitsTransport?.trim() || void 0;
|
|
94
|
+
const purchaseBenefitExpansion = purchaseBenefitsTransport ? (0, import_purchase_benefit_transport.parseAndExpandPurchaseBenefitTransport)({
|
|
95
|
+
transport: purchaseBenefitsTransport,
|
|
96
|
+
appliesTo: isBulkPurchase ? "redeemed_team_seat" : "buyer"
|
|
97
|
+
}) : null;
|
|
98
|
+
if (purchaseBenefitExpansion && !purchaseBenefitExpansion.success) {
|
|
99
|
+
logger.info("purchase_benefits.transport.needs_review", {
|
|
100
|
+
checkoutSessionId,
|
|
101
|
+
event: "purchase_benefits.transport.needs_review",
|
|
102
|
+
metadataKey: import_purchase_benefit_transport.PURCHASE_BENEFIT_METADATA_KEY,
|
|
103
|
+
productId,
|
|
104
|
+
stripeChargeId,
|
|
105
|
+
userId,
|
|
106
|
+
errors: purchaseBenefitExpansion.review.errors
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (isBulkPurchase) {
|
|
110
|
+
bulkCouponId = existingBulkCoupon !== null ? existingBulkCoupon.id : (0, import_uuid.v4)();
|
|
111
|
+
if (existingBulkCoupon !== null) {
|
|
112
|
+
const existingCouponFields = existingBulkCoupon.fields ?? {};
|
|
113
|
+
couponToUpdate = await trx.update(coupon).set({
|
|
114
|
+
maxUses: (existingBulkCoupon?.maxUses || 0) + quantity,
|
|
115
|
+
fields: mergePurchaseBenefitFields(existingCouponFields, purchaseBenefitExpansion),
|
|
116
|
+
...organizationId ? {
|
|
117
|
+
organizationId
|
|
118
|
+
} : {}
|
|
119
|
+
}).where((0, import_drizzle_orm.eq)(coupon.id, bulkCouponId));
|
|
120
|
+
} else {
|
|
121
|
+
let merchantCouponToUse = stripeCouponId ? import_schemas.merchantCouponSchema.nullable().parse(await trx.query.merchantCoupon.findFirst({
|
|
122
|
+
where: (0, import_drizzle_orm.eq)(merchantCoupon.identifier, stripeCouponId)
|
|
123
|
+
}) || null) : null;
|
|
124
|
+
if (!merchantCouponToUse && usedCouponId) {
|
|
125
|
+
const usedCoupon = import_schemas.couponSchema.nullable().parse(await trx.query.coupon.findFirst({
|
|
126
|
+
where: (0, import_drizzle_orm.eq)(coupon.id, usedCouponId)
|
|
127
|
+
}) || null);
|
|
128
|
+
if (usedCoupon?.merchantCouponId) {
|
|
129
|
+
merchantCouponToUse = import_schemas.merchantCouponSchema.nullable().parse(await trx.query.merchantCoupon.findFirst({
|
|
130
|
+
where: (0, import_drizzle_orm.eq)(merchantCoupon.id, usedCoupon.merchantCouponId)
|
|
131
|
+
}) || null);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const bulkCouponValues = {
|
|
135
|
+
id: bulkCouponId,
|
|
136
|
+
percentageDiscount: "1.0",
|
|
137
|
+
restrictedToProductId: productId,
|
|
138
|
+
maxUses: quantity,
|
|
139
|
+
status: 1,
|
|
140
|
+
fields: mergePurchaseBenefitFields({}, purchaseBenefitExpansion),
|
|
141
|
+
...organizationId ? {
|
|
142
|
+
organizationId
|
|
143
|
+
} : {},
|
|
144
|
+
...merchantCouponToUse ? {
|
|
145
|
+
merchantCouponId: merchantCouponToUse.id
|
|
146
|
+
} : {}
|
|
147
|
+
};
|
|
148
|
+
couponToUpdate = await trx.insert(coupon).values(bulkCouponValues);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const merchantSessionId = `ms_${(0, import_uuid.v4)()}`;
|
|
152
|
+
await trx.insert(merchantSession).values({
|
|
153
|
+
id: merchantSessionId,
|
|
154
|
+
identifier: checkoutSessionId,
|
|
155
|
+
merchantAccountId
|
|
156
|
+
});
|
|
157
|
+
const merchantCouponUsed = stripeCouponId ? await trx.query.merchantCoupon.findFirst({
|
|
158
|
+
where: (0, import_drizzle_orm.eq)(merchantCoupon.identifier, stripeCouponId)
|
|
159
|
+
}) : null;
|
|
160
|
+
const pppMerchantCoupon = appliedPPPStripeCouponId ? await trx.query.merchantCoupon.findFirst({
|
|
161
|
+
where: (0, import_drizzle_orm.and)((0, import_drizzle_orm.eq)(merchantCoupon.identifier, appliedPPPStripeCouponId), (0, import_drizzle_orm.eq)(merchantCoupon.type, "ppp"))
|
|
162
|
+
}) : null;
|
|
163
|
+
const newPurchaseStatus = merchantCouponUsed?.type === "ppp" || pppMerchantCoupon ? "Restricted" : "Valid";
|
|
164
|
+
await trx.insert(purchaseTable).values({
|
|
165
|
+
id: purchaseId2,
|
|
166
|
+
status: newPurchaseStatus,
|
|
167
|
+
userId,
|
|
168
|
+
productId,
|
|
169
|
+
merchantChargeId,
|
|
170
|
+
totalAmount: (stripeChargeAmount / 100).toFixed(),
|
|
171
|
+
bulkCouponId,
|
|
172
|
+
merchantSessionId,
|
|
173
|
+
country,
|
|
174
|
+
fields: {
|
|
175
|
+
...!isBulkPurchase ? mergePurchaseBenefitFields({}, purchaseBenefitExpansion) : {},
|
|
176
|
+
...attributionSnapshot ? {
|
|
177
|
+
attribution: attributionSnapshot
|
|
178
|
+
} : {}
|
|
179
|
+
},
|
|
180
|
+
upgradedFromId: upgradedFromPurchaseId || null,
|
|
181
|
+
couponId: usedCouponId || null,
|
|
182
|
+
...organizationId ? {
|
|
183
|
+
organizationId
|
|
184
|
+
} : {}
|
|
185
|
+
});
|
|
186
|
+
const oneWeekInMilliseconds = 1e3 * 60 * 60 * 24 * 7;
|
|
187
|
+
await trx.insert(purchaseUserTransfer).values({
|
|
188
|
+
id: `put_${(0, import_uuid.v4)()}`,
|
|
189
|
+
purchaseId: purchaseId2,
|
|
190
|
+
expiresAt: existingPurchase ? /* @__PURE__ */ new Date() : new Date(Date.now() + oneWeekInMilliseconds),
|
|
191
|
+
sourceUserId: userId,
|
|
192
|
+
...organizationId ? {
|
|
193
|
+
organizationId
|
|
194
|
+
} : {}
|
|
195
|
+
});
|
|
196
|
+
return purchaseId2;
|
|
197
|
+
} catch (error) {
|
|
198
|
+
logger.error(toError(error), {
|
|
199
|
+
checkoutSessionId: options.checkoutSessionId,
|
|
200
|
+
event: "adapter.purchase.create.failed",
|
|
201
|
+
organizationId: options.organizationId,
|
|
202
|
+
productId: options.productId,
|
|
203
|
+
stripeChargeId: options.stripeChargeId,
|
|
204
|
+
userId: options.userId
|
|
205
|
+
});
|
|
206
|
+
trx.rollback();
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
const parsedPurchase = import_schemas.purchaseSchema.safeParse(await client.query.purchases.findFirst({
|
|
211
|
+
where: (0, import_drizzle_orm.eq)(purchaseTable.id, purchaseId)
|
|
212
|
+
}));
|
|
213
|
+
if (!parsedPurchase.success) {
|
|
214
|
+
logger.error(parsedPurchase.error, {
|
|
215
|
+
event: "adapter.purchase.parse_failed",
|
|
216
|
+
productId: options.productId,
|
|
217
|
+
purchaseId,
|
|
218
|
+
userId: options.userId
|
|
219
|
+
});
|
|
220
|
+
throw new Error("Error parsing purchase");
|
|
221
|
+
}
|
|
222
|
+
return parsedPurchase.data;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
__name(createMerchantChargeAndPurchaseWorkflow, "createMerchantChargeAndPurchaseWorkflow");
|
|
227
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
228
|
+
0 && (module.exports = {
|
|
229
|
+
createMerchantChargeAndPurchaseWorkflow
|
|
230
|
+
});
|
|
231
|
+
//# sourceMappingURL=create-merchant-charge-and-purchase.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/mysql/workflows/create-merchant-charge-and-purchase.ts"],"sourcesContent":["import { and, eq, inArray } from 'drizzle-orm'\nimport { v4 } from 'uuid'\n\nimport type { PurchasePort } from '@coursebuilder/core/ports'\nimport {\n\tparseAndExpandPurchaseBenefitTransport,\n\tPURCHASE_BENEFIT_METADATA_KEY,\n} from '@coursebuilder/commerce/purchase-benefit-transport'\nimport {\n\tcouponSchema,\n\tmerchantChargeSchema,\n\tmerchantCouponSchema,\n\tpurchaseSchema,\n\ttype Purchase,\n} from '@coursebuilder/core/schemas'\nimport { logger as baseLogger } from '@coursebuilder/utils/logger'\n\nimport type { MySqlContext } from '../context.js'\n\nfunction toError(error: unknown) {\n\treturn error instanceof Error ? error : new Error(String(error))\n}\n\nconst logger = baseLogger as unknown as {\n\terror: (error: Error, attrs?: Record<string, unknown>) => void\n\tinfo: (message: string, attrs?: Record<string, unknown>) => void\n}\n\ntype PurchaseBenefitExpansion = ReturnType<\n\ttypeof parseAndExpandPurchaseBenefitTransport\n> | null\n\nfunction mergePurchaseBenefitFields(\n\tfields: Record<string, any>,\n\texpansion: PurchaseBenefitExpansion,\n) {\n\tif (!expansion) return fields\n\n\treturn {\n\t\t...fields,\n\t\t...(expansion.success\n\t\t\t? { purchaseBenefits: expansion.benefits }\n\t\t\t: { purchaseBenefitsReview: expansion.review }),\n\t}\n}\n\n/**\n * Creates the private merchant charge and purchase workflow.\n *\n * @param context - The shared MySQL client and table set.\n * @returns The purchase-owned merchant charge creation operation.\n *\n * @example\n * ```ts\n * const workflow = createMerchantChargeAndPurchaseWorkflow(context)\n * ```\n */\nexport function createMerchantChargeAndPurchaseWorkflow({\n\tclient,\n\ttables,\n}: MySqlContext): Pick<PurchasePort, 'createMerchantChargeAndPurchase'> {\n\tconst {\n\t\tpurchases: purchaseTable,\n\t\tpurchaseUserTransfer,\n\t\tcoupon,\n\t\tmerchantCoupon,\n\t\tmerchantCharge,\n\t\tmerchantSession,\n\t} = tables\n\n\treturn {\n\t\tasync createMerchantChargeAndPurchase(options): Promise<Purchase> {\n\t\t\tconst purchaseId = await client.transaction(async (trx) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst {\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t\tstripeChargeId,\n\t\t\t\t\t\tstripeCouponId,\n\t\t\t\t\t\tmerchantAccountId,\n\t\t\t\t\t\tmerchantProductId,\n\t\t\t\t\t\tmerchantCustomerId,\n\t\t\t\t\t\tproductId,\n\t\t\t\t\t\tstripeChargeAmount,\n\t\t\t\t\t\tquantity = 1,\n\t\t\t\t\t\tcheckoutSessionId,\n\t\t\t\t\t\tappliedPPPStripeCouponId,\n\t\t\t\t\t\tupgradedFromPurchaseId,\n\t\t\t\t\t\tcountry,\n\t\t\t\t\t\tusedCouponId,\n\t\t\t\t\t\torganizationId,\n\t\t\t\t\t\tattributionSnapshot,\n\t\t\t\t\t} = options\n\n\t\t\t\t\tconst existingMerchantCharge = merchantChargeSchema.nullable().parse(\n\t\t\t\t\t\t(await trx.query.merchantCharge.findFirst({\n\t\t\t\t\t\t\twhere: eq(merchantCharge.identifier, stripeChargeId),\n\t\t\t\t\t\t})) || null,\n\t\t\t\t\t)\n\n\t\t\t\t\tconst existingPurchaseForCharge = existingMerchantCharge\n\t\t\t\t\t\t? await trx.query.purchases.findFirst({\n\t\t\t\t\t\t\t\twhere: eq(\n\t\t\t\t\t\t\t\t\tpurchaseTable.merchantChargeId,\n\t\t\t\t\t\t\t\t\texistingMerchantCharge.id,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\tuser: true,\n\t\t\t\t\t\t\t\t\tproduct: true,\n\t\t\t\t\t\t\t\t\tbulkCoupon: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: null\n\n\t\t\t\t\tif (existingPurchaseForCharge) {\n\t\t\t\t\t\treturn existingPurchaseForCharge.id\n\t\t\t\t\t}\n\n\t\t\t\t\tconst merchantChargeId = `mc_${v4()}`\n\t\t\t\t\tconst purchaseId = `purch_${v4()}`\n\n\t\t\t\t\tconst newMerchantCharge = await trx.insert(merchantCharge).values({\n\t\t\t\t\t\tid: merchantChargeId,\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t\tidentifier: stripeChargeId,\n\t\t\t\t\t\tmerchantAccountId,\n\t\t\t\t\t\tmerchantProductId,\n\t\t\t\t\t\tmerchantCustomerId,\n\t\t\t\t\t})\n\n\t\t\t\t\tconst existingPurchase = purchaseSchema.nullable().parse(\n\t\t\t\t\t\t(await trx.query.purchases.findFirst({\n\t\t\t\t\t\t\twhere: and(\n\t\t\t\t\t\t\t\teq(purchaseTable.productId, productId),\n\t\t\t\t\t\t\t\teq(purchaseTable.userId, userId),\n\t\t\t\t\t\t\t\tinArray(purchaseTable.status, ['Valid', 'Restricted']),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t})) || null,\n\t\t\t\t\t)\n\n\t\t\t\t\tconst existingBulkCoupon = couponSchema.nullable().parse(\n\t\t\t\t\t\tawait trx\n\t\t\t\t\t\t\t.select()\n\t\t\t\t\t\t\t.from(coupon)\n\t\t\t\t\t\t\t.leftJoin(\n\t\t\t\t\t\t\t\tpurchaseTable,\n\t\t\t\t\t\t\t\tand(\n\t\t\t\t\t\t\t\t\teq(coupon.id, purchaseTable.bulkCouponId),\n\t\t\t\t\t\t\t\t\teq(purchaseTable.userId, userId),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.where(\n\t\t\t\t\t\t\t\tand(\n\t\t\t\t\t\t\t\t\teq(coupon.restrictedToProductId, productId),\n\t\t\t\t\t\t\t\t\teq(purchaseTable.userId, userId),\n\t\t\t\t\t\t\t\t\teq(purchaseTable.status, 'Valid'),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\t\treturn res[0]?.Coupon ?? null\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\n\t\t\t\t\tconst isBulkPurchase =\n\t\t\t\t\t\tquantity > 1 || Boolean(existingBulkCoupon) || Boolean(options.bulk)\n\n\t\t\t\t\tlet bulkCouponId: string | null = null\n\t\t\t\t\tlet couponToUpdate = null\n\t\t\t\t\tconst purchaseBenefitsTransport =\n\t\t\t\t\t\toptions.purchaseBenefitsTransport?.trim() || undefined\n\t\t\t\t\tconst purchaseBenefitExpansion = purchaseBenefitsTransport\n\t\t\t\t\t\t? parseAndExpandPurchaseBenefitTransport({\n\t\t\t\t\t\t\t\ttransport: purchaseBenefitsTransport,\n\t\t\t\t\t\t\t\tappliesTo: isBulkPurchase ? 'redeemed_team_seat' : 'buyer',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: null\n\n\t\t\t\t\tif (purchaseBenefitExpansion && !purchaseBenefitExpansion.success) {\n\t\t\t\t\t\tlogger.info('purchase_benefits.transport.needs_review', {\n\t\t\t\t\t\t\tcheckoutSessionId,\n\t\t\t\t\t\t\tevent: 'purchase_benefits.transport.needs_review',\n\t\t\t\t\t\t\tmetadataKey: PURCHASE_BENEFIT_METADATA_KEY,\n\t\t\t\t\t\t\tproductId,\n\t\t\t\t\t\t\tstripeChargeId,\n\t\t\t\t\t\t\tuserId,\n\t\t\t\t\t\t\terrors: purchaseBenefitExpansion.review.errors,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isBulkPurchase) {\n\t\t\t\t\t\tbulkCouponId =\n\t\t\t\t\t\t\texistingBulkCoupon !== null ? existingBulkCoupon.id : v4()\n\n\t\t\t\t\t\tif (existingBulkCoupon !== null) {\n\t\t\t\t\t\t\tconst existingCouponFields = existingBulkCoupon.fields ?? {}\n\t\t\t\t\t\t\tcouponToUpdate = await trx\n\t\t\t\t\t\t\t\t.update(coupon)\n\t\t\t\t\t\t\t\t.set({\n\t\t\t\t\t\t\t\t\tmaxUses: (existingBulkCoupon?.maxUses || 0) + quantity,\n\t\t\t\t\t\t\t\t\tfields: mergePurchaseBenefitFields(\n\t\t\t\t\t\t\t\t\t\texistingCouponFields,\n\t\t\t\t\t\t\t\t\t\tpurchaseBenefitExpansion,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t...(organizationId ? { organizationId } : {}),\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.where(eq(coupon.id, bulkCouponId as string))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Try to find merchant coupon by stripeCouponId first\n\t\t\t\t\t\t\tlet merchantCouponToUse = stripeCouponId\n\t\t\t\t\t\t\t\t? merchantCouponSchema.nullable().parse(\n\t\t\t\t\t\t\t\t\t\t(await trx.query.merchantCoupon.findFirst({\n\t\t\t\t\t\t\t\t\t\t\twhere: eq(merchantCoupon.identifier, stripeCouponId),\n\t\t\t\t\t\t\t\t\t\t})) || null,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: null\n\n\t\t\t\t\t\t\t// Fallback: If not found, try to find via usedCouponId from checkout session metadata\n\t\t\t\t\t\t\tif (!merchantCouponToUse && usedCouponId) {\n\t\t\t\t\t\t\t\t// First get the coupon record to find its merchantCouponId\n\t\t\t\t\t\t\t\tconst usedCoupon = couponSchema.nullable().parse(\n\t\t\t\t\t\t\t\t\t(await trx.query.coupon.findFirst({\n\t\t\t\t\t\t\t\t\t\twhere: eq(coupon.id, usedCouponId),\n\t\t\t\t\t\t\t\t\t})) || null,\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\t// Then get the merchant coupon\n\t\t\t\t\t\t\t\tif (usedCoupon?.merchantCouponId) {\n\t\t\t\t\t\t\t\t\tmerchantCouponToUse = merchantCouponSchema.nullable().parse(\n\t\t\t\t\t\t\t\t\t\t(await trx.query.merchantCoupon.findFirst({\n\t\t\t\t\t\t\t\t\t\t\twhere: eq(merchantCoupon.id, usedCoupon.merchantCouponId),\n\t\t\t\t\t\t\t\t\t\t})) || null,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst bulkCouponValues = {\n\t\t\t\t\t\t\t\tid: bulkCouponId as string,\n\t\t\t\t\t\t\t\tpercentageDiscount: '1.0',\n\t\t\t\t\t\t\t\trestrictedToProductId: productId,\n\t\t\t\t\t\t\t\tmaxUses: quantity,\n\t\t\t\t\t\t\t\tstatus: 1,\n\t\t\t\t\t\t\t\tfields: mergePurchaseBenefitFields(\n\t\t\t\t\t\t\t\t\t{},\n\t\t\t\t\t\t\t\t\tpurchaseBenefitExpansion,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t...(organizationId ? { organizationId } : {}),\n\t\t\t\t\t\t\t\t...(merchantCouponToUse\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tmerchantCouponId: merchantCouponToUse.id,\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tcouponToUpdate = await trx.insert(coupon).values(bulkCouponValues)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a new merchant session\n\t\t\t\t\tconst merchantSessionId = `ms_${v4()}`\n\n\t\t\t\t\tawait trx.insert(merchantSession).values({\n\t\t\t\t\t\tid: merchantSessionId,\n\t\t\t\t\t\tidentifier: checkoutSessionId,\n\t\t\t\t\t\tmerchantAccountId,\n\t\t\t\t\t})\n\n\t\t\t\t\tconst merchantCouponUsed = stripeCouponId\n\t\t\t\t\t\t? await trx.query.merchantCoupon.findFirst({\n\t\t\t\t\t\t\t\twhere: eq(merchantCoupon.identifier, stripeCouponId),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: null\n\n\t\t\t\t\tconst pppMerchantCoupon = appliedPPPStripeCouponId\n\t\t\t\t\t\t? await trx.query.merchantCoupon.findFirst({\n\t\t\t\t\t\t\t\twhere: and(\n\t\t\t\t\t\t\t\t\teq(merchantCoupon.identifier, appliedPPPStripeCouponId),\n\t\t\t\t\t\t\t\t\teq(merchantCoupon.type, 'ppp'),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: null\n\n\t\t\t\t\tconst newPurchaseStatus =\n\t\t\t\t\t\tmerchantCouponUsed?.type === 'ppp' || pppMerchantCoupon\n\t\t\t\t\t\t\t? 'Restricted'\n\t\t\t\t\t\t\t: 'Valid'\n\n\t\t\t\t\tawait trx.insert(purchaseTable).values({\n\t\t\t\t\t\tid: purchaseId,\n\t\t\t\t\t\tstatus: newPurchaseStatus,\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t\tproductId,\n\t\t\t\t\t\tmerchantChargeId,\n\t\t\t\t\t\ttotalAmount: (stripeChargeAmount / 100).toFixed(),\n\t\t\t\t\t\tbulkCouponId,\n\t\t\t\t\t\tmerchantSessionId,\n\t\t\t\t\t\tcountry,\n\t\t\t\t\t\tfields: {\n\t\t\t\t\t\t\t...(!isBulkPurchase\n\t\t\t\t\t\t\t\t? mergePurchaseBenefitFields({}, purchaseBenefitExpansion)\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(attributionSnapshot\n\t\t\t\t\t\t\t\t? { attribution: attributionSnapshot }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tupgradedFromId: upgradedFromPurchaseId || null,\n\t\t\t\t\t\tcouponId: usedCouponId || null,\n\t\t\t\t\t\t...(organizationId ? { organizationId } : {}),\n\t\t\t\t\t})\n\n\t\t\t\t\tconst oneWeekInMilliseconds = 1000 * 60 * 60 * 24 * 7\n\n\t\t\t\t\tawait trx.insert(purchaseUserTransfer).values({\n\t\t\t\t\t\tid: `put_${v4()}`,\n\t\t\t\t\t\tpurchaseId: purchaseId as string,\n\t\t\t\t\t\texpiresAt: existingPurchase\n\t\t\t\t\t\t\t? new Date()\n\t\t\t\t\t\t\t: new Date(Date.now() + oneWeekInMilliseconds),\n\t\t\t\t\t\tsourceUserId: userId,\n\t\t\t\t\t\t...(organizationId ? { organizationId } : {}),\n\t\t\t\t\t})\n\n\t\t\t\t\t// const result = await Promise.all([\n\t\t\t\t\t// \tnewMerchantCharge,\n\t\t\t\t\t// \tnewPurchase,\n\t\t\t\t\t// \tnewPurchaseUserTransfer,\n\t\t\t\t\t// \tnewMerchantSession,\n\t\t\t\t\t// \t...(couponToUpdate ? [couponToUpdate] : []),\n\t\t\t\t\t// ])\n\t\t\t\t\t//\n\t\t\t\t\t// console.log('result', { result })\n\n\t\t\t\t\treturn purchaseId\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error(toError(error), {\n\t\t\t\t\t\tcheckoutSessionId: options.checkoutSessionId,\n\t\t\t\t\t\tevent: 'adapter.purchase.create.failed',\n\t\t\t\t\t\torganizationId: options.organizationId,\n\t\t\t\t\t\tproductId: options.productId,\n\t\t\t\t\t\tstripeChargeId: options.stripeChargeId,\n\t\t\t\t\t\tuserId: options.userId,\n\t\t\t\t\t})\n\t\t\t\t\ttrx.rollback()\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst parsedPurchase = purchaseSchema.safeParse(\n\t\t\t\tawait client.query.purchases.findFirst({\n\t\t\t\t\twhere: eq(purchaseTable.id, purchaseId as string),\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!parsedPurchase.success) {\n\t\t\t\tlogger.error(parsedPurchase.error, {\n\t\t\t\t\tevent: 'adapter.purchase.parse_failed',\n\t\t\t\t\tproductId: options.productId,\n\t\t\t\t\tpurchaseId: purchaseId as string,\n\t\t\t\t\tuserId: options.userId,\n\t\t\t\t})\n\t\t\t\tthrow new Error('Error parsing purchase')\n\t\t\t}\n\n\t\t\treturn parsedPurchase.data\n\t\t},\n\t}\n}\n"],"mappings":"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","names":["toError","error","Error","String","logger","baseLogger","mergePurchaseBenefitFields","fields","expansion","success","purchaseBenefits","benefits","purchaseBenefitsReview","review","createMerchantChargeAndPurchaseWorkflow","client","tables","purchases","purchaseTable","purchaseUserTransfer","coupon","merchantCoupon","merchantCharge","merchantSession","createMerchantChargeAndPurchase","options","purchaseId","transaction","trx","userId","stripeChargeId","stripeCouponId","merchantAccountId","merchantProductId","merchantCustomerId","productId","stripeChargeAmount","quantity","checkoutSessionId","appliedPPPStripeCouponId","upgradedFromPurchaseId","country","usedCouponId","organizationId","attributionSnapshot","existingMerchantCharge","merchantChargeSchema","nullable","parse","query","findFirst","where","eq","identifier","existingPurchaseForCharge","merchantChargeId","id","with","user","product","bulkCoupon","v4","newMerchantCharge","insert","values","existingPurchase","purchaseSchema","and","inArray","status","existingBulkCoupon","couponSchema","select","from","leftJoin","bulkCouponId","restrictedToProductId","then","res","Coupon","isBulkPurchase","Boolean","bulk","couponToUpdate","purchaseBenefitsTransport","trim","undefined","purchaseBenefitExpansion","parseAndExpandPurchaseBenefitTransport","transport","appliesTo","info","event","metadataKey","PURCHASE_BENEFIT_METADATA_KEY","errors","existingCouponFields","update","set","maxUses","merchantCouponToUse","merchantCouponSchema","usedCoupon","merchantCouponId","bulkCouponValues","percentageDiscount","merchantSessionId","merchantCouponUsed","pppMerchantCoupon","type","newPurchaseStatus","totalAmount","toFixed","attribution","upgradedFromId","couponId","oneWeekInMilliseconds","expiresAt","Date","now","sourceUserId","rollback","parsedPurchase","safeParse","data"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PurchasePort } from '@coursebuilder/core/ports';
|
|
2
|
+
import { MySqlContext } from '../context.cjs';
|
|
3
|
+
import 'drizzle-orm/mysql-core';
|
|
4
|
+
import '../schema.cjs';
|
|
5
|
+
import 'drizzle-orm';
|
|
6
|
+
import '@coursebuilder/core/auth';
|
|
7
|
+
import '../schemas/auth/users.cjs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates the private merchant charge and purchase workflow.
|
|
11
|
+
*
|
|
12
|
+
* @param context - The shared MySQL client and table set.
|
|
13
|
+
* @returns The purchase-owned merchant charge creation operation.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const workflow = createMerchantChargeAndPurchaseWorkflow(context)
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare function createMerchantChargeAndPurchaseWorkflow({ client, tables, }: MySqlContext): Pick<PurchasePort, 'createMerchantChargeAndPurchase'>;
|
|
21
|
+
|
|
22
|
+
export { createMerchantChargeAndPurchaseWorkflow };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PurchasePort } from '@coursebuilder/core/ports';
|
|
2
|
+
import { MySqlContext } from '../context.js';
|
|
3
|
+
import 'drizzle-orm/mysql-core';
|
|
4
|
+
import '../schema.js';
|
|
5
|
+
import 'drizzle-orm';
|
|
6
|
+
import '@coursebuilder/core/auth';
|
|
7
|
+
import '../schemas/auth/users.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates the private merchant charge and purchase workflow.
|
|
11
|
+
*
|
|
12
|
+
* @param context - The shared MySQL client and table set.
|
|
13
|
+
* @returns The purchase-owned merchant charge creation operation.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const workflow = createMerchantChargeAndPurchaseWorkflow(context)
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare function createMerchantChargeAndPurchaseWorkflow({ client, tables, }: MySqlContext): Pick<PurchasePort, 'createMerchantChargeAndPurchase'>;
|
|
21
|
+
|
|
22
|
+
export { createMerchantChargeAndPurchaseWorkflow };
|