@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 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,184 @@
|
|
|
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-cohort.ts
|
|
32
|
+
var create_cohort_exports = {};
|
|
33
|
+
__export(create_cohort_exports, {
|
|
34
|
+
createCohortWorkflow: () => createCohortWorkflow
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(create_cohort_exports);
|
|
37
|
+
var import_slugify = __toESM(require("@sindresorhus/slugify"), 1);
|
|
38
|
+
var import_drizzle_orm = require("drizzle-orm");
|
|
39
|
+
var import_content_resource_schema = require("@coursebuilder/core/schemas/content-resource-schema");
|
|
40
|
+
var import_logger = require("@coursebuilder/utils/logger");
|
|
41
|
+
|
|
42
|
+
// src/lib/mysql/workflows/content-resource-workflow-utils.ts
|
|
43
|
+
var import_nanoid = require("nanoid");
|
|
44
|
+
var guid = (0, import_nanoid.customAlphabet)("1234567890abcdefghijklmnopqrstuvwxyz", 5);
|
|
45
|
+
var normalizeExpirationDate = /* @__PURE__ */ __name((date) => {
|
|
46
|
+
if (!date)
|
|
47
|
+
return void 0;
|
|
48
|
+
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 23, 59, 59, 0));
|
|
49
|
+
}, "normalizeExpirationDate");
|
|
50
|
+
|
|
51
|
+
// src/lib/mysql/workflows/create-cohort.ts
|
|
52
|
+
var logger = import_logger.logger;
|
|
53
|
+
function createCohortWorkflow({ client, tables }, operations) {
|
|
54
|
+
const { contentResource, contentResourceResource, contentResourceProduct, contentResourceTag } = tables;
|
|
55
|
+
return {
|
|
56
|
+
async createCohort(input, userId) {
|
|
57
|
+
const hash = guid();
|
|
58
|
+
const cohortId = `cohort~${hash}`;
|
|
59
|
+
const cohort = await client.transaction(async (tx) => {
|
|
60
|
+
await tx.insert(contentResource).values({
|
|
61
|
+
id: cohortId,
|
|
62
|
+
type: "cohort",
|
|
63
|
+
createdById: userId,
|
|
64
|
+
fields: {
|
|
65
|
+
title: input.cohort.title,
|
|
66
|
+
description: input.cohort.description,
|
|
67
|
+
state: "draft",
|
|
68
|
+
visibility: "unlisted",
|
|
69
|
+
slug: (0, import_slugify.default)(`${input.cohort.title}~${hash}`),
|
|
70
|
+
startsAt: input.dates.start,
|
|
71
|
+
endsAt: input.dates.end
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
const cohort2 = await tx.query.contentResource.findFirst({
|
|
75
|
+
where: (0, import_drizzle_orm.eq)(contentResource.id, cohortId),
|
|
76
|
+
with: {
|
|
77
|
+
resources: {
|
|
78
|
+
with: {
|
|
79
|
+
resource: true
|
|
80
|
+
},
|
|
81
|
+
orderBy: (0, import_drizzle_orm.asc)(contentResourceResource.position)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
if (!cohort2) {
|
|
86
|
+
throw new Error("Failed to create cohort");
|
|
87
|
+
}
|
|
88
|
+
const parsedCohort = import_content_resource_schema.ContentResourceSchema.safeParse(cohort2);
|
|
89
|
+
if (!parsedCohort.success) {
|
|
90
|
+
throw new Error("Invalid cohort data");
|
|
91
|
+
}
|
|
92
|
+
if (input.cohort.tagIds) {
|
|
93
|
+
await tx.insert(contentResourceTag).values(input.cohort.tagIds.map((tag) => ({
|
|
94
|
+
contentResourceId: cohortId,
|
|
95
|
+
tagId: tag.id,
|
|
96
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
97
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
98
|
+
position: 0
|
|
99
|
+
})));
|
|
100
|
+
}
|
|
101
|
+
let position = 0;
|
|
102
|
+
for (const workshop of input.workshops) {
|
|
103
|
+
await tx.insert(contentResourceResource).values({
|
|
104
|
+
resourceOfId: cohortId,
|
|
105
|
+
resourceId: workshop.id,
|
|
106
|
+
position
|
|
107
|
+
});
|
|
108
|
+
position++;
|
|
109
|
+
}
|
|
110
|
+
return parsedCohort.data;
|
|
111
|
+
});
|
|
112
|
+
let product = null;
|
|
113
|
+
if (input.createProduct && input.pricing.price && input.pricing.price > 0) {
|
|
114
|
+
try {
|
|
115
|
+
product = await operations.createProduct({
|
|
116
|
+
name: input.cohort.title,
|
|
117
|
+
price: input.pricing.price,
|
|
118
|
+
quantityAvailable: -1,
|
|
119
|
+
type: "cohort",
|
|
120
|
+
state: "published",
|
|
121
|
+
visibility: "public",
|
|
122
|
+
openEnrollment: (/* @__PURE__ */ new Date()).toISOString(),
|
|
123
|
+
closeEnrollment: input.dates.start.toISOString()
|
|
124
|
+
});
|
|
125
|
+
if (product) {
|
|
126
|
+
await client.insert(contentResourceProduct).values({
|
|
127
|
+
resourceId: cohortId,
|
|
128
|
+
productId: product.id,
|
|
129
|
+
position: 0,
|
|
130
|
+
metadata: {
|
|
131
|
+
addedBy: userId
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
if (input.coupon?.enabled && input.coupon.percentageDiscount && input.coupon.expires) {
|
|
135
|
+
try {
|
|
136
|
+
const finalExpires = normalizeExpirationDate(input.coupon.expires);
|
|
137
|
+
await operations.createCoupon({
|
|
138
|
+
percentageDiscount: input.coupon.percentageDiscount,
|
|
139
|
+
expires: finalExpires || null,
|
|
140
|
+
restrictedToProductId: product.id,
|
|
141
|
+
default: true,
|
|
142
|
+
maxUses: -1,
|
|
143
|
+
quantity: "-1",
|
|
144
|
+
status: 1,
|
|
145
|
+
fields: {}
|
|
146
|
+
});
|
|
147
|
+
logger.debug("cohort.create.coupon.success", {
|
|
148
|
+
cohortId,
|
|
149
|
+
productId: product.id,
|
|
150
|
+
userId,
|
|
151
|
+
percentageDiscount: input.coupon.percentageDiscount
|
|
152
|
+
});
|
|
153
|
+
} catch (couponError) {
|
|
154
|
+
logger.error(new Error(`Failed to create coupon for cohort: ${couponError}`));
|
|
155
|
+
logger.debug("cohort.create.coupon.failed", {
|
|
156
|
+
cohortId,
|
|
157
|
+
productId: product.id,
|
|
158
|
+
userId
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} catch (productError) {
|
|
164
|
+
logger.error(new Error(`Failed to create product for cohort: ${productError}`));
|
|
165
|
+
logger.debug("cohort.create.product.failed", {
|
|
166
|
+
cohortId,
|
|
167
|
+
userId,
|
|
168
|
+
price: input.pricing.price
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
cohort,
|
|
174
|
+
product
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
__name(createCohortWorkflow, "createCohortWorkflow");
|
|
180
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
181
|
+
0 && (module.exports = {
|
|
182
|
+
createCohortWorkflow
|
|
183
|
+
});
|
|
184
|
+
//# sourceMappingURL=create-cohort.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/mysql/workflows/create-cohort.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 CreateCohortOperations = Pick<CatalogPort, 'createProduct'> &\n\tPick<CouponPort, 'createCoupon'>\n\n/**\n * Creates the private cohort 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 = createCohortWorkflow(context, operations)\n * ```\n */\nexport function createCohortWorkflow(\n\t{ client, tables }: MySqlContext,\n\toperations: CreateCohortOperations,\n): Pick<ContentResourcePort, 'createCohort'> {\n\tconst {\n\t\tcontentResource,\n\t\tcontentResourceResource,\n\t\tcontentResourceProduct,\n\t\tcontentResourceTag,\n\t} = tables\n\n\treturn {\n\t\tasync createCohort(\n\t\t\tinput: {\n\t\t\t\tcohort: {\n\t\t\t\t\ttitle: string\n\t\t\t\t\tdescription?: string\n\t\t\t\t\ttagIds?:\n\t\t\t\t\t\t| { id: string; fields: { label: string; name: string } }[]\n\t\t\t\t\t\t| null\n\t\t\t\t}\n\t\t\t\tdates: {\n\t\t\t\t\tstart: Date\n\t\t\t\t\tend: Date\n\t\t\t\t}\n\t\t\t\tcreateProduct?: boolean\n\t\t\t\tpricing: {\n\t\t\t\t\tprice?: number | null\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\tworkshops: { id: string }[]\n\t\t\t},\n\t\t\tuserId: string,\n\t\t) {\n\t\t\tconst hash = guid()\n\t\t\tconst cohortId = `cohort~${hash}`\n\n\t\t\t// Transaction only handles database operations\n\t\t\tconst cohort = await client.transaction(async (tx) => {\n\t\t\t\t// Create cohort content resource\n\t\t\t\tawait tx.insert(contentResource).values({\n\t\t\t\t\tid: cohortId,\n\t\t\t\t\ttype: 'cohort',\n\t\t\t\t\tcreatedById: userId,\n\t\t\t\t\tfields: {\n\t\t\t\t\t\ttitle: input.cohort.title,\n\t\t\t\t\t\tdescription: input.cohort.description,\n\t\t\t\t\t\tstate: 'draft',\n\t\t\t\t\t\tvisibility: 'unlisted',\n\t\t\t\t\t\tslug: slugify(`${input.cohort.title}~${hash}`),\n\t\t\t\t\t\tstartsAt: input.dates.start,\n\t\t\t\t\t\tendsAt: input.dates.end,\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\t// Fetch created cohort\n\t\t\t\tconst cohort = await tx.query.contentResource.findFirst({\n\t\t\t\t\twhere: eq(contentResource.id, cohortId),\n\t\t\t\t\twith: {\n\t\t\t\t\t\tresources: {\n\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\tresource: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\torderBy: asc(contentResourceResource.position),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\tif (!cohort) {\n\t\t\t\t\tthrow new Error('Failed to create cohort')\n\t\t\t\t}\n\n\t\t\t\tconst parsedCohort = ContentResourceSchema.safeParse(cohort)\n\t\t\t\tif (!parsedCohort.success) {\n\t\t\t\t\tthrow new Error('Invalid cohort data')\n\t\t\t\t}\n\n\t\t\t\t// Associate tags with cohort\n\t\t\t\tif (input.cohort.tagIds) {\n\t\t\t\t\tawait tx.insert(contentResourceTag).values(\n\t\t\t\t\t\tinput.cohort.tagIds.map((tag) => ({\n\t\t\t\t\t\t\tcontentResourceId: cohortId,\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}\n\n\t\t\t\t// Link workshops to cohort\n\t\t\t\tlet position = 0\n\t\t\t\tfor (const workshop of input.workshops) {\n\t\t\t\t\tawait tx.insert(contentResourceResource).values({\n\t\t\t\t\t\tresourceOfId: cohortId,\n\t\t\t\t\t\tresourceId: workshop.id,\n\t\t\t\t\t\tposition,\n\t\t\t\t\t})\n\t\t\t\t\tposition++\n\t\t\t\t}\n\n\t\t\t\treturn parsedCohort.data\n\t\t\t})\n\n\t\t\t// Handle product and coupon creation outside transaction\n\t\t\tlet product: any = null\n\t\t\tif (\n\t\t\t\tinput.createProduct &&\n\t\t\t\tinput.pricing.price &&\n\t\t\t\tinput.pricing.price > 0\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\tproduct = await operations.createProduct({\n\t\t\t\t\t\tname: input.cohort.title,\n\t\t\t\t\t\tprice: input.pricing.price,\n\t\t\t\t\t\tquantityAvailable: -1,\n\t\t\t\t\t\ttype: 'cohort',\n\t\t\t\t\t\tstate: 'published',\n\t\t\t\t\t\tvisibility: 'public',\n\t\t\t\t\t\topenEnrollment: new Date().toISOString(),\n\t\t\t\t\t\tcloseEnrollment: input.dates.start.toISOString(),\n\t\t\t\t\t})\n\n\t\t\t\t\tif (product) {\n\t\t\t\t\t\t// Link product to cohort resource\n\t\t\t\t\t\tawait client.insert(contentResourceProduct).values({\n\t\t\t\t\t\t\tresourceId: cohortId,\n\t\t\t\t\t\t\tproductId: product.id,\n\t\t\t\t\t\t\tposition: 0,\n\t\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t\taddedBy: userId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\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\tawait operations.createCoupon({\n\t\t\t\t\t\t\t\t\tpercentageDiscount: input.coupon.percentageDiscount,\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\tdefault: true,\n\t\t\t\t\t\t\t\t\tmaxUses: -1,\n\t\t\t\t\t\t\t\t\tquantity: '-1',\n\t\t\t\t\t\t\t\t\tstatus: 1,\n\t\t\t\t\t\t\t\t\tfields: {},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tlogger.debug('cohort.create.coupon.success', {\n\t\t\t\t\t\t\t\t\tcohortId,\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 cohort: ${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('cohort.create.coupon.failed', {\n\t\t\t\t\t\t\t\t\tcohortId,\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 - cohort 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}\n\t\t\t\t} catch (productError) {\n\t\t\t\t\tlogger.error(\n\t\t\t\t\t\tnew Error(`Failed to create product for cohort: ${productError}`),\n\t\t\t\t\t)\n\t\t\t\t\tlogger.debug('cohort.create.product.failed', {\n\t\t\t\t\t\tcohortId,\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t\tprice: input.pricing.price,\n\t\t\t\t\t})\n\t\t\t\t\t// Don't throw - cohort creation should succeed even if product fails\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcohort,\n\t\t\t\tproduct,\n\t\t\t}\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;qBAAoB;AACpB,yBAAwB;AAOxB,qCAGO;AACP,oBAAqC;;;ACZrC,oBAA+B;AAExB,IAAMA,WAAOC,8BAAe,wCAAwC,CAAA;AAEpE,IAAMC,0BAA0B,wBAACC,SAAAA;AACvC,MAAI,CAACA;AAAM,WAAOC;AAKlB,SAAO,IAAIC,KACVA,KAAKC,IACJH,KAAKI,eAAc,GACnBJ,KAAKK,YAAW,GAChBL,KAAKM,WAAU,GACf,IACA,IACA,IACA,CAAA,CAAA;AAGH,GAjBuC;;;ADgBvC,IAAMC,SAASC,cAAAA;AAoBR,SAASC,qBACf,EAAEC,QAAQC,OAAM,GAChBC,YAAkC;AAElC,QAAM,EACLC,iBACAC,yBACAC,wBACAC,mBAAkB,IACfL;AAEJ,SAAO;IACN,MAAMM,aACLC,OAuBAC,QAAc;AAEd,YAAMC,OAAOC,KAAAA;AACb,YAAMC,WAAW,UAAUF,IAAAA;AAG3B,YAAMG,SAAS,MAAMb,OAAOc,YAAY,OAAOC,OAAAA;AAE9C,cAAMA,GAAGC,OAAOb,eAAAA,EAAiBc,OAAO;UACvCC,IAAIN;UACJO,MAAM;UACNC,aAAaX;UACbY,QAAQ;YACPC,OAAOd,MAAMK,OAAOS;YACpBC,aAAaf,MAAMK,OAAOU;YAC1BC,OAAO;YACPC,YAAY;YACZC,UAAMC,eAAAA,SAAQ,GAAGnB,MAAMK,OAAOS,KAAK,IAAIZ,IAAAA,EAAM;YAC7CkB,UAAUpB,MAAMqB,MAAMC;YACtBC,QAAQvB,MAAMqB,MAAMG;UACrB;QACD,CAAA;AAGA,cAAMnB,UAAS,MAAME,GAAGkB,MAAM9B,gBAAgB+B,UAAU;UACvDC,WAAOC,uBAAGjC,gBAAgBe,IAAIN,QAAAA;UAC9ByB,MAAM;YACLC,WAAW;cACVD,MAAM;gBACLE,UAAU;cACX;cACAC,aAASC,wBAAIrC,wBAAwBsC,QAAQ;YAC9C;UACD;QACD,CAAA;AAEA,YAAI,CAAC7B,SAAQ;AACZ,gBAAM,IAAI8B,MAAM,yBAAA;QACjB;AAEA,cAAMC,eAAeC,qDAAsBC,UAAUjC,OAAAA;AACrD,YAAI,CAAC+B,aAAaG,SAAS;AAC1B,gBAAM,IAAIJ,MAAM,qBAAA;QACjB;AAGA,YAAInC,MAAMK,OAAOmC,QAAQ;AACxB,gBAAMjC,GAAGC,OAAOV,kBAAAA,EAAoBW,OACnCT,MAAMK,OAAOmC,OAAOC,IAAI,CAACC,SAAS;YACjCC,mBAAmBvC;YACnBwC,OAAOF,IAAIhC;YACXmC,WAAW,oBAAIC,KAAAA;YACfC,WAAW,oBAAID,KAAAA;YACfZ,UAAU;UACX,EAAA,CAAA;QAEF;AAGA,YAAIA,WAAW;AACf,mBAAWc,YAAYhD,MAAMiD,WAAW;AACvC,gBAAM1C,GAAGC,OAAOZ,uBAAAA,EAAyBa,OAAO;YAC/CyC,cAAc9C;YACd+C,YAAYH,SAAStC;YACrBwB;UACD,CAAA;AACAA;QACD;AAEA,eAAOE,aAAagB;MACrB,CAAA;AAGA,UAAIC,UAAe;AACnB,UACCrD,MAAMsD,iBACNtD,MAAMuD,QAAQC,SACdxD,MAAMuD,QAAQC,QAAQ,GACrB;AACD,YAAI;AACHH,oBAAU,MAAM3D,WAAW4D,cAAc;YACxCG,MAAMzD,MAAMK,OAAOS;YACnB0C,OAAOxD,MAAMuD,QAAQC;YACrBE,mBAAmB;YACnB/C,MAAM;YACNK,OAAO;YACPC,YAAY;YACZ0C,iBAAgB,oBAAIb,KAAAA,GAAOc,YAAW;YACtCC,iBAAiB7D,MAAMqB,MAAMC,MAAMsC,YAAW;UAC/C,CAAA;AAEA,cAAIP,SAAS;AAEZ,kBAAM7D,OAAOgB,OAAOX,sBAAAA,EAAwBY,OAAO;cAClD0C,YAAY/C;cACZ0D,WAAWT,QAAQ3C;cACnBwB,UAAU;cACV6B,UAAU;gBACTC,SAAS/D;cACV;YACD,CAAA;AAGA,gBACCD,MAAMiE,QAAQC,WACdlE,MAAMiE,OAAOE,sBACbnE,MAAMiE,OAAOG,SACZ;AACD,kBAAI;AACH,sBAAMC,eAAeC,wBACpBtE,MAAMiE,OAAOG,OAAO;AAErB,sBAAM1E,WAAW6E,aAAa;kBAC7BJ,oBAAoBnE,MAAMiE,OAAOE;kBACjCC,SAASC,gBAAgB;kBACzBG,uBAAuBnB,QAAQ3C;kBAC/B+D,SAAS;kBACTC,SAAS;kBACTC,UAAU;kBACVC,QAAQ;kBACR/D,QAAQ,CAAC;gBACV,CAAA;AACAxB,uBAAOwF,MAAM,gCAAgC;kBAC5CzE;kBACA0D,WAAWT,QAAQ3C;kBACnBT;kBACAkE,oBAAoBnE,MAAMiE,OAAOE;gBAClC,CAAA;cACD,SAASW,aAAa;AACrBzF,uBAAO0F,MACN,IAAI5C,MACH,uCAAuC2C,WAAAA,EAAa,CAAA;AAGtDzF,uBAAOwF,MAAM,+BAA+B;kBAC3CzE;kBACA0D,WAAWT,QAAQ3C;kBACnBT;gBACD,CAAA;cAED;YACD;UACD;QACD,SAAS+E,cAAc;AACtB3F,iBAAO0F,MACN,IAAI5C,MAAM,wCAAwC6C,YAAAA,EAAc,CAAA;AAEjE3F,iBAAOwF,MAAM,gCAAgC;YAC5CzE;YACAH;YACAuD,OAAOxD,MAAMuD,QAAQC;UACtB,CAAA;QAED;MACD;AAEA,aAAO;QACNnD;QACAgD;MACD;IACD;EACD;AACD;AAtMgB9D;","names":["guid","customAlphabet","normalizeExpirationDate","date","undefined","Date","UTC","getUTCFullYear","getUTCMonth","getUTCDate","logger","baseLogger","createCohortWorkflow","client","tables","operations","contentResource","contentResourceResource","contentResourceProduct","contentResourceTag","createCohort","input","userId","hash","guid","cohortId","cohort","transaction","tx","insert","values","id","type","createdById","fields","title","description","state","visibility","slug","slugify","startsAt","dates","start","endsAt","end","query","findFirst","where","eq","with","resources","resource","orderBy","asc","position","Error","parsedCohort","ContentResourceSchema","safeParse","success","tagIds","map","tag","contentResourceId","tagId","createdAt","Date","updatedAt","workshop","workshops","resourceOfId","resourceId","data","product","createProduct","pricing","price","name","quantityAvailable","openEnrollment","toISOString","closeEnrollment","productId","metadata","addedBy","coupon","enabled","percentageDiscount","expires","finalExpires","normalizeExpirationDate","createCoupon","restrictedToProductId","default","maxUses","quantity","status","debug","couponError","error","productError"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CatalogPort, CouponPort, ContentResourcePort } 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 CreateCohortOperations = Pick<CatalogPort, 'createProduct'> & Pick<CouponPort, 'createCoupon'>;
|
|
10
|
+
/**
|
|
11
|
+
* Creates the private cohort 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 = createCohortWorkflow(context, operations)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function createCohortWorkflow({ client, tables }: MySqlContext, operations: CreateCohortOperations): Pick<ContentResourcePort, 'createCohort'>;
|
|
23
|
+
|
|
24
|
+
export { createCohortWorkflow };
|
|
@@ -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 CreateCohortOperations = Pick<CatalogPort, 'createProduct'> & Pick<CouponPort, 'createCoupon'>;
|
|
10
|
+
/**
|
|
11
|
+
* Creates the private cohort 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 = createCohortWorkflow(context, operations)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function createCohortWorkflow({ client, tables }: MySqlContext, operations: CreateCohortOperations): Pick<ContentResourcePort, 'createCohort'>;
|
|
23
|
+
|
|
24
|
+
export { createCohortWorkflow };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,283 @@
|
|
|
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-series.ts
|
|
32
|
+
var create_event_series_exports = {};
|
|
33
|
+
__export(create_event_series_exports, {
|
|
34
|
+
createEventSeriesWorkflow: () => createEventSeriesWorkflow
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(create_event_series_exports);
|
|
37
|
+
var import_slugify = __toESM(require("@sindresorhus/slugify"), 1);
|
|
38
|
+
var import_drizzle_orm = require("drizzle-orm");
|
|
39
|
+
var import_content_resource_schema = require("@coursebuilder/core/schemas/content-resource-schema");
|
|
40
|
+
var import_logger = require("@coursebuilder/utils/logger");
|
|
41
|
+
|
|
42
|
+
// src/lib/mysql/workflows/content-resource-workflow-utils.ts
|
|
43
|
+
var import_nanoid = require("nanoid");
|
|
44
|
+
var guid = (0, import_nanoid.customAlphabet)("1234567890abcdefghijklmnopqrstuvwxyz", 5);
|
|
45
|
+
|
|
46
|
+
// src/lib/mysql/workflows/create-event-series.ts
|
|
47
|
+
var logger = import_logger.logger;
|
|
48
|
+
function createEventSeriesWorkflow({ client, tables }, operations) {
|
|
49
|
+
const { contentResource, contentResourceResource, contentResourceTag } = tables;
|
|
50
|
+
return {
|
|
51
|
+
async createEventSeries(input, userId) {
|
|
52
|
+
const { eventSeries: eventSeriesInput, childEvents: childEventsInput } = input;
|
|
53
|
+
if (childEventsInput.length === 0) {
|
|
54
|
+
throw new Error("At least one event is required");
|
|
55
|
+
}
|
|
56
|
+
const result = await client.transaction(async (tx) => {
|
|
57
|
+
const eventSeriesHash = guid();
|
|
58
|
+
const eventSeriesResourceId = (0, import_slugify.default)(`event-series~${eventSeriesHash}`);
|
|
59
|
+
const newEventSeries = {
|
|
60
|
+
id: eventSeriesResourceId,
|
|
61
|
+
type: "event-series",
|
|
62
|
+
fields: {
|
|
63
|
+
...eventSeriesInput.fields,
|
|
64
|
+
title: eventSeriesInput.fields.title,
|
|
65
|
+
state: "draft",
|
|
66
|
+
visibility: "public",
|
|
67
|
+
slug: (0, import_slugify.default)(`${eventSeriesInput.fields.title}~${eventSeriesHash}`)
|
|
68
|
+
},
|
|
69
|
+
createdById: userId
|
|
70
|
+
};
|
|
71
|
+
await tx.insert(contentResource).values(newEventSeries);
|
|
72
|
+
const eventSeriesResource = await tx.query.contentResource.findFirst({
|
|
73
|
+
where: (0, import_drizzle_orm.eq)(contentResource.id, eventSeriesResourceId),
|
|
74
|
+
with: {
|
|
75
|
+
resources: {
|
|
76
|
+
with: {
|
|
77
|
+
resource: {
|
|
78
|
+
with: {
|
|
79
|
+
resources: {
|
|
80
|
+
with: {
|
|
81
|
+
resource: true
|
|
82
|
+
},
|
|
83
|
+
orderBy: (0, import_drizzle_orm.asc)(contentResourceResource.position)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
orderBy: (0, import_drizzle_orm.asc)(contentResourceResource.position)
|
|
89
|
+
},
|
|
90
|
+
tags: {
|
|
91
|
+
with: {
|
|
92
|
+
tag: true
|
|
93
|
+
},
|
|
94
|
+
orderBy: (0, import_drizzle_orm.asc)(contentResourceTag.position)
|
|
95
|
+
},
|
|
96
|
+
resourceProducts: {
|
|
97
|
+
with: {
|
|
98
|
+
product: {
|
|
99
|
+
with: {
|
|
100
|
+
price: true
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
const parsedEventSeries = import_content_resource_schema.ContentResourceSchema.safeParse(eventSeriesResource);
|
|
108
|
+
if (!parsedEventSeries.success) {
|
|
109
|
+
throw new Error("Error parsing event series resource");
|
|
110
|
+
}
|
|
111
|
+
if (eventSeriesInput.fields.tagIds) {
|
|
112
|
+
await tx.insert(contentResourceTag).values(eventSeriesInput.fields.tagIds.map((tag) => ({
|
|
113
|
+
contentResourceId: eventSeriesResourceId,
|
|
114
|
+
tagId: tag.id,
|
|
115
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
116
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
117
|
+
position: 0
|
|
118
|
+
})));
|
|
119
|
+
}
|
|
120
|
+
const createdChildEvents = [];
|
|
121
|
+
for (let i = 0; i < childEventsInput.length; i++) {
|
|
122
|
+
const childEventInput = childEventsInput[i];
|
|
123
|
+
if (!childEventInput) {
|
|
124
|
+
throw new Error(`Child event input is required`);
|
|
125
|
+
}
|
|
126
|
+
const childEventHash = guid();
|
|
127
|
+
const childEventResourceId = (0, import_slugify.default)(`event~${childEventHash}`);
|
|
128
|
+
const newChildEvent = {
|
|
129
|
+
id: childEventResourceId,
|
|
130
|
+
type: "event",
|
|
131
|
+
fields: {
|
|
132
|
+
title: childEventInput.fields.title,
|
|
133
|
+
startsAt: childEventInput.fields.startsAt,
|
|
134
|
+
endsAt: childEventInput.fields.endsAt,
|
|
135
|
+
description: childEventInput.fields.description,
|
|
136
|
+
state: "draft",
|
|
137
|
+
visibility: "public",
|
|
138
|
+
slug: (0, import_slugify.default)(`${childEventInput.fields.title}~${childEventHash}`),
|
|
139
|
+
// No price/quantity - they're on the event series
|
|
140
|
+
price: null,
|
|
141
|
+
quantity: null
|
|
142
|
+
},
|
|
143
|
+
createdById: userId
|
|
144
|
+
};
|
|
145
|
+
await tx.insert(contentResource).values(newChildEvent);
|
|
146
|
+
const childEventResource = await tx.query.contentResource.findFirst({
|
|
147
|
+
where: (0, import_drizzle_orm.eq)(contentResource.id, childEventResourceId),
|
|
148
|
+
with: {
|
|
149
|
+
resources: {
|
|
150
|
+
with: {
|
|
151
|
+
resource: {
|
|
152
|
+
with: {
|
|
153
|
+
resources: {
|
|
154
|
+
with: {
|
|
155
|
+
resource: true
|
|
156
|
+
},
|
|
157
|
+
orderBy: (0, import_drizzle_orm.asc)(contentResourceResource.position)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
orderBy: (0, import_drizzle_orm.asc)(contentResourceResource.position)
|
|
163
|
+
},
|
|
164
|
+
tags: {
|
|
165
|
+
with: {
|
|
166
|
+
tag: true
|
|
167
|
+
},
|
|
168
|
+
orderBy: (0, import_drizzle_orm.asc)(contentResourceTag.position)
|
|
169
|
+
},
|
|
170
|
+
resourceProducts: {
|
|
171
|
+
with: {
|
|
172
|
+
product: {
|
|
173
|
+
with: {
|
|
174
|
+
price: true
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
const parsedChildEvent = import_content_resource_schema.ContentResourceSchema.safeParse(childEventResource);
|
|
182
|
+
if (!parsedChildEvent.success) {
|
|
183
|
+
throw new Error(`Error parsing child event resource ${i + 1}`);
|
|
184
|
+
}
|
|
185
|
+
if (childEventInput.fields.tagIds) {
|
|
186
|
+
await tx.insert(contentResourceTag).values(childEventInput.fields.tagIds.map((tag) => ({
|
|
187
|
+
contentResourceId: childEventResourceId,
|
|
188
|
+
tagId: tag.id,
|
|
189
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
190
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
191
|
+
position: 0
|
|
192
|
+
})));
|
|
193
|
+
}
|
|
194
|
+
await tx.insert(contentResourceResource).values({
|
|
195
|
+
resourceOfId: eventSeriesResourceId,
|
|
196
|
+
resourceId: childEventResourceId,
|
|
197
|
+
position: i
|
|
198
|
+
});
|
|
199
|
+
createdChildEvents.push(parsedChildEvent.data);
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
eventSeries: parsedEventSeries.data,
|
|
203
|
+
childEvents: createdChildEvents
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
const { eventSeries, childEvents } = result;
|
|
207
|
+
if (eventSeriesInput.sharedFields.price && eventSeriesInput.sharedFields.price > 0) {
|
|
208
|
+
try {
|
|
209
|
+
const product = await operations.createProduct({
|
|
210
|
+
name: eventSeriesInput.fields.title,
|
|
211
|
+
price: eventSeriesInput.sharedFields.price,
|
|
212
|
+
quantityAvailable: eventSeriesInput.sharedFields.quantity ?? -1,
|
|
213
|
+
type: "live",
|
|
214
|
+
state: "published",
|
|
215
|
+
visibility: "public"
|
|
216
|
+
});
|
|
217
|
+
if (product) {
|
|
218
|
+
await operations.addResourceToProduct({
|
|
219
|
+
resource: eventSeries,
|
|
220
|
+
productId: product.id,
|
|
221
|
+
userId
|
|
222
|
+
});
|
|
223
|
+
if (input.coupon?.enabled && input.coupon.percentageDiscount && input.coupon.expires) {
|
|
224
|
+
try {
|
|
225
|
+
let finalExpires = input.coupon.expires;
|
|
226
|
+
if (finalExpires instanceof Date) {
|
|
227
|
+
finalExpires = new Date(Date.UTC(finalExpires.getUTCFullYear(), finalExpires.getUTCMonth(), finalExpires.getUTCDate(), 23, 59, 59, 0));
|
|
228
|
+
}
|
|
229
|
+
const couponInput = {
|
|
230
|
+
quantity: "1",
|
|
231
|
+
maxUses: 1,
|
|
232
|
+
expires: finalExpires,
|
|
233
|
+
restrictedToProductId: product.id,
|
|
234
|
+
percentageDiscount: input.coupon.percentageDiscount,
|
|
235
|
+
status: 1,
|
|
236
|
+
default: true,
|
|
237
|
+
fields: {}
|
|
238
|
+
};
|
|
239
|
+
await operations.createCoupon(couponInput);
|
|
240
|
+
logger.debug("event.series.coupon.success", {
|
|
241
|
+
eventSeriesId: eventSeries.id,
|
|
242
|
+
productId: product.id,
|
|
243
|
+
userId,
|
|
244
|
+
percentageDiscount: input.coupon.percentageDiscount
|
|
245
|
+
});
|
|
246
|
+
} catch (couponError) {
|
|
247
|
+
logger.error(new Error(`Error creating coupon for event series: ${couponError}`));
|
|
248
|
+
logger.debug("event.series.coupon.failed", {
|
|
249
|
+
eventSeriesId: eventSeries.id,
|
|
250
|
+
productId: product.id,
|
|
251
|
+
userId
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
logger.error(new Error("Failed to create product"));
|
|
257
|
+
logger.debug("event.series.product.failed", {
|
|
258
|
+
eventSeriesId: eventSeries.id,
|
|
259
|
+
userId,
|
|
260
|
+
price: eventSeriesInput.sharedFields.price
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
} catch (error) {
|
|
264
|
+
logger.error(new Error(`Error creating and associating product: ${error}`));
|
|
265
|
+
logger.debug("event.series.product.creation.failed", {
|
|
266
|
+
eventSeriesId: eventSeries.id,
|
|
267
|
+
userId
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
eventSeries,
|
|
273
|
+
childEvents
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
__name(createEventSeriesWorkflow, "createEventSeriesWorkflow");
|
|
279
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
280
|
+
0 && (module.exports = {
|
|
281
|
+
createEventSeriesWorkflow
|
|
282
|
+
});
|
|
283
|
+
//# sourceMappingURL=create-event-series.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/mysql/workflows/create-event-series.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 CreateEventSeriesOperations = Pick<\n\tCatalogPort,\n\t'createProduct' | 'addResourceToProduct'\n> &\n\tPick<CouponPort, 'createCoupon'>\n\n/**\n * Creates the private event series 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 = createEventSeriesWorkflow(context, operations)\n * ```\n */\nexport function createEventSeriesWorkflow(\n\t{ client, tables }: MySqlContext,\n\toperations: CreateEventSeriesOperations,\n): Pick<ContentResourcePort, 'createEventSeries'> {\n\tconst { contentResource, contentResourceResource, contentResourceTag } =\n\t\ttables\n\n\treturn {\n\t\tasync createEventSeries(\n\t\t\tinput: {\n\t\t\t\teventSeries: {\n\t\t\t\t\ttype: 'event-series'\n\t\t\t\t\tfields: {\n\t\t\t\t\t\ttitle: string\n\t\t\t\t\t\tdescription?: string | undefined\n\t\t\t\t\t\ttagIds?:\n\t\t\t\t\t\t\t| { id: string; fields: { label: string; name: string } }[]\n\t\t\t\t\t\t\t| null\n\t\t\t\t\t\t\t| undefined\n\t\t\t\t\t}\n\t\t\t\t\tsharedFields: {\n\t\t\t\t\t\tprice: number | null | undefined\n\t\t\t\t\t\tquantity: number | null | undefined\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tchildEvents: Array<{\n\t\t\t\t\ttype: 'event'\n\t\t\t\t\tfields: {\n\t\t\t\t\t\ttitle: string\n\t\t\t\t\t\tstartsAt: Date | null | undefined\n\t\t\t\t\t\tendsAt: Date | null | undefined\n\t\t\t\t\t\tdescription?: string | undefined\n\t\t\t\t\t\ttagIds?:\n\t\t\t\t\t\t\t| { id: string; fields: { label: string; name: string } }[]\n\t\t\t\t\t\t\t| null\n\t\t\t\t\t\t\t| undefined\n\t\t\t\t\t}\n\t\t\t\t}>\n\t\t\t\tcoupon?:\n\t\t\t\t\t| {\n\t\t\t\t\t\t\tenabled: boolean\n\t\t\t\t\t\t\texpires?: Date | undefined\n\t\t\t\t\t\t\tpercentageDiscount?: string | undefined\n\t\t\t\t\t }\n\t\t\t\t\t| undefined\n\t\t\t},\n\t\t\tuserId: string,\n\t\t) {\n\t\t\tconst { eventSeries: eventSeriesInput, childEvents: childEventsInput } =\n\t\t\t\tinput\n\n\t\t\tif (childEventsInput.length === 0) {\n\t\t\t\tthrow new Error('At least one event is required')\n\t\t\t}\n\n\t\t\t// Execute all database operations within a transaction\n\t\t\tconst result = await client.transaction(async (tx) => {\n\t\t\t\t// Step 1: Create the event series resource\n\t\t\t\tconst eventSeriesHash = guid()\n\t\t\t\tconst eventSeriesResourceId = slugify(`event-series~${eventSeriesHash}`)\n\n\t\t\t\tconst newEventSeries = {\n\t\t\t\t\tid: eventSeriesResourceId,\n\t\t\t\t\ttype: 'event-series',\n\t\t\t\t\tfields: {\n\t\t\t\t\t\t...eventSeriesInput.fields,\n\t\t\t\t\t\ttitle: eventSeriesInput.fields.title,\n\t\t\t\t\t\tstate: 'draft',\n\t\t\t\t\t\tvisibility: 'public',\n\t\t\t\t\t\tslug: slugify(\n\t\t\t\t\t\t\t`${eventSeriesInput.fields.title}~${eventSeriesHash}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\tcreatedById: userId,\n\t\t\t\t}\n\n\t\t\t\tawait tx.insert(contentResource).values(newEventSeries)\n\n\t\t\t\t// Fetch the created event series with relations\n\t\t\t\tconst eventSeriesResource = await tx.query.contentResource.findFirst({\n\t\t\t\t\twhere: eq(contentResource.id, eventSeriesResourceId),\n\t\t\t\t\twith: {\n\t\t\t\t\t\tresources: {\n\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\tresource: {\n\t\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\t\tresources: {\n\t\t\t\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\t\t\t\tresource: true,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\torderBy: asc(contentResourceResource.position),\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\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\torderBy: asc(contentResourceResource.position),\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttags: {\n\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\ttag: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\torderBy: asc(contentResourceTag.position),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresourceProducts: {\n\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\tproduct: {\n\t\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\t\tprice: true,\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\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\tconst parsedEventSeries =\n\t\t\t\t\tContentResourceSchema.safeParse(eventSeriesResource)\n\t\t\t\tif (!parsedEventSeries.success) {\n\t\t\t\t\tthrow new Error('Error parsing event series resource')\n\t\t\t\t}\n\n\t\t\t\t// Step 2: Associate tags with event series\n\t\t\t\tif (eventSeriesInput.fields.tagIds) {\n\t\t\t\t\tawait tx.insert(contentResourceTag).values(\n\t\t\t\t\t\teventSeriesInput.fields.tagIds.map((tag) => ({\n\t\t\t\t\t\t\tcontentResourceId: eventSeriesResourceId,\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}\n\n\t\t\t\t// Step 3: Create child events and associate them\n\t\t\t\tconst createdChildEvents = []\n\n\t\t\t\tfor (let i = 0; i < childEventsInput.length; i++) {\n\t\t\t\t\tconst childEventInput = childEventsInput[i]\n\n\t\t\t\t\tif (!childEventInput) {\n\t\t\t\t\t\tthrow new Error(`Child event input is required`)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create child event\n\t\t\t\t\tconst childEventHash = guid()\n\t\t\t\t\tconst childEventResourceId = slugify(`event~${childEventHash}`)\n\n\t\t\t\t\tconst newChildEvent = {\n\t\t\t\t\t\tid: childEventResourceId,\n\t\t\t\t\t\ttype: 'event',\n\t\t\t\t\t\tfields: {\n\t\t\t\t\t\t\ttitle: childEventInput.fields.title,\n\t\t\t\t\t\t\tstartsAt: childEventInput.fields.startsAt,\n\t\t\t\t\t\t\tendsAt: childEventInput.fields.endsAt,\n\t\t\t\t\t\t\tdescription: childEventInput.fields.description,\n\t\t\t\t\t\t\tstate: 'draft',\n\t\t\t\t\t\t\tvisibility: 'public',\n\t\t\t\t\t\t\tslug: slugify(\n\t\t\t\t\t\t\t\t`${childEventInput.fields.title}~${childEventHash}`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t// No price/quantity - they're on the event series\n\t\t\t\t\t\t\tprice: null,\n\t\t\t\t\t\t\tquantity: null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcreatedById: userId,\n\t\t\t\t\t}\n\n\t\t\t\t\tawait tx.insert(contentResource).values(newChildEvent)\n\n\t\t\t\t\t// Fetch the created child event with relations\n\t\t\t\t\tconst childEventResource = await tx.query.contentResource.findFirst({\n\t\t\t\t\t\twhere: eq(contentResource.id, childEventResourceId),\n\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\tresources: {\n\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\tresource: {\n\t\t\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\t\t\tresources: {\n\t\t\t\t\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tresource: true,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\torderBy: asc(contentResourceResource.position),\n\t\t\t\t\t\t\t\t\t\t\t},\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\t},\n\t\t\t\t\t\t\t\torderBy: asc(contentResourceResource.position),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttags: {\n\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\ttag: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\torderBy: asc(contentResourceTag.position),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tresourceProducts: {\n\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\tproduct: {\n\t\t\t\t\t\t\t\t\t\twith: {\n\t\t\t\t\t\t\t\t\t\t\tprice: true,\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\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tconst parsedChildEvent =\n\t\t\t\t\t\tContentResourceSchema.safeParse(childEventResource)\n\t\t\t\t\tif (!parsedChildEvent.success) {\n\t\t\t\t\t\tthrow new Error(`Error parsing child event resource ${i + 1}`)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Associate tags with child event\n\t\t\t\t\tif (childEventInput.fields.tagIds) {\n\t\t\t\t\t\tawait tx.insert(contentResourceTag).values(\n\t\t\t\t\t\t\tchildEventInput.fields.tagIds.map((tag) => ({\n\t\t\t\t\t\t\t\tcontentResourceId: childEventResourceId,\n\t\t\t\t\t\t\t\ttagId: tag.id,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\tposition: 0,\n\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Associate child event with event series\n\t\t\t\t\tawait tx.insert(contentResourceResource).values({\n\t\t\t\t\t\tresourceOfId: eventSeriesResourceId,\n\t\t\t\t\t\tresourceId: childEventResourceId,\n\t\t\t\t\t\tposition: i,\n\t\t\t\t\t})\n\n\t\t\t\t\tcreatedChildEvents.push(parsedChildEvent.data)\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\teventSeries: parsedEventSeries.data,\n\t\t\t\t\tchildEvents: createdChildEvents,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst { eventSeries, childEvents } = result\n\n\t\t\t// Step 4: Handle product creation outside transaction\n\t\t\tif (\n\t\t\t\teventSeriesInput.sharedFields.price &&\n\t\t\t\teventSeriesInput.sharedFields.price > 0\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\tconst product = await operations.createProduct({\n\t\t\t\t\t\tname: eventSeriesInput.fields.title,\n\t\t\t\t\t\tprice: eventSeriesInput.sharedFields.price,\n\t\t\t\t\t\tquantityAvailable: eventSeriesInput.sharedFields.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\tawait operations.addResourceToProduct({\n\t\t\t\t\t\t\tresource: eventSeries,\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\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\tlet finalExpires = input.coupon.expires\n\t\t\t\t\t\t\t\tif (finalExpires instanceof Date) {\n\t\t\t\t\t\t\t\t\tfinalExpires = new Date(\n\t\t\t\t\t\t\t\t\t\tDate.UTC(\n\t\t\t\t\t\t\t\t\t\t\tfinalExpires.getUTCFullYear(),\n\t\t\t\t\t\t\t\t\t\t\tfinalExpires.getUTCMonth(),\n\t\t\t\t\t\t\t\t\t\t\tfinalExpires.getUTCDate(),\n\t\t\t\t\t\t\t\t\t\t\t23,\n\t\t\t\t\t\t\t\t\t\t\t59,\n\t\t\t\t\t\t\t\t\t\t\t59,\n\t\t\t\t\t\t\t\t\t\t\t0,\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\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,\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}\n\t\t\t\t\t\t\t\tawait operations.createCoupon(couponInput)\n\t\t\t\t\t\t\t\tlogger.debug('event.series.coupon.success', {\n\t\t\t\t\t\t\t\t\teventSeriesId: eventSeries.id,\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`Error creating coupon for event series: ${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.series.coupon.failed', {\n\t\t\t\t\t\t\t\t\teventSeriesId: eventSeries.id,\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 series 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.series.product.failed', {\n\t\t\t\t\t\t\teventSeriesId: eventSeries.id,\n\t\t\t\t\t\t\tuserId,\n\t\t\t\t\t\t\tprice: eventSeriesInput.sharedFields.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.series.product.creation.failed', {\n\t\t\t\t\t\teventSeriesId: eventSeries.id,\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t})\n\t\t\t\t\t// Note: We don't throw here since the core data is already committed\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { eventSeries, childEvents }\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","logger","baseLogger","createEventSeriesWorkflow","client","tables","operations","contentResource","contentResourceResource","contentResourceTag","createEventSeries","input","userId","eventSeries","eventSeriesInput","childEvents","childEventsInput","length","Error","result","transaction","tx","eventSeriesHash","guid","eventSeriesResourceId","slugify","newEventSeries","id","type","fields","title","state","visibility","slug","createdById","insert","values","eventSeriesResource","query","findFirst","where","eq","with","resources","resource","orderBy","asc","position","tags","tag","resourceProducts","product","price","parsedEventSeries","ContentResourceSchema","safeParse","success","tagIds","map","contentResourceId","tagId","createdAt","Date","updatedAt","createdChildEvents","i","childEventInput","childEventHash","childEventResourceId","newChildEvent","startsAt","endsAt","description","quantity","childEventResource","parsedChildEvent","resourceOfId","resourceId","push","data","sharedFields","createProduct","name","quantityAvailable","addResourceToProduct","productId","coupon","enabled","percentageDiscount","expires","finalExpires","UTC","getUTCFullYear","getUTCMonth","getUTCDate","couponInput","maxUses","restrictedToProductId","status","default","createCoupon","debug","eventSeriesId","couponError","error"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CatalogPort, CouponPort, ContentResourcePort } 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 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 };
|