@coursebuilder/adapter-drizzle 2.1.1 → 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.
Files changed (296) hide show
  1. package/dist/{chunk-KIQLUFJX.js → chunk-2GW3BJE2.js} +2 -2
  2. package/dist/{chunk-M3WM5Q7W.js → chunk-33ZN7FN7.js} +2 -2
  3. package/dist/chunk-4VZJQAPV.js +74 -0
  4. package/dist/chunk-5FLS4ZBX.js +109 -0
  5. package/dist/chunk-5YR5M22S.js +147 -0
  6. package/dist/chunk-6XQ6C3IX.js +18 -0
  7. package/dist/chunk-AIDM2CH6.js +146 -0
  8. package/dist/chunk-ALTODDUX.js +173 -0
  9. package/dist/chunk-AZY2VRAE.js +63 -0
  10. package/dist/chunk-BS7T27VL.js +239 -0
  11. package/dist/chunk-CN3FCRLR.js +55 -0
  12. package/dist/chunk-EAXC4CQD.js +245 -0
  13. package/dist/chunk-EDDG2YFS.js +249 -0
  14. package/dist/chunk-EDKWCMA7.js +210 -0
  15. package/dist/{chunk-7FBSP3VD.js → chunk-EDM6DKA5.js} +2 -2
  16. package/dist/{chunk-EZEQQJNH.js → chunk-EIQBTF5J.js} +2 -2
  17. package/dist/chunk-FYT7RTVW.js +248 -0
  18. package/dist/{chunk-F56AI52P.js → chunk-INZTF6QV.js} +2 -2
  19. package/dist/{chunk-AP5HBIV4.js → chunk-JVHX4JHA.js} +2 -2
  20. package/dist/chunk-LWEKWDLC.js +300 -0
  21. package/dist/chunk-OJPEBGGE.js +139 -0
  22. package/dist/chunk-QKOSV34V.js +16268 -0
  23. package/dist/chunk-QO3QE3LE.js +330 -0
  24. package/dist/chunk-QQKNNFFB.js +399 -0
  25. package/dist/chunk-RBHCV3UW.js +20 -0
  26. package/dist/chunk-TNH2C27F.js +252 -0
  27. package/dist/chunk-TNWNW666.js +133 -0
  28. package/dist/chunk-VBEXYQ6L.js +156 -0
  29. package/dist/chunk-W3ILNMLD.js +265 -0
  30. package/dist/chunk-WJ2ZUXL3.js +71 -0
  31. package/dist/{chunk-PJORQUQP.js → chunk-WUMDFFN3.js} +2 -2
  32. package/dist/{chunk-2AW5KYAK.js → chunk-X7DRYXB7.js} +2 -2
  33. package/dist/{chunk-PNPTKVJ4.js → chunk-XUBZKYH6.js} +24 -15
  34. package/dist/{chunk-WWBSNLRC.js → chunk-ZY4AFKUQ.js} +2 -2
  35. package/dist/index.d.ts +5 -11
  36. package/dist/index.js +41 -18
  37. package/dist/lib/mysql/cms-resource-actions.cjs +15912 -4127
  38. package/dist/lib/mysql/cms-resource-actions.cjs.map +1 -1
  39. package/dist/lib/mysql/cms-resource-actions.d.cts +8 -38
  40. package/dist/lib/mysql/cms-resource-actions.d.ts +8 -38
  41. package/dist/lib/mysql/cms-resource-actions.js +2 -1
  42. package/dist/lib/mysql/context.cjs +3380 -0
  43. package/dist/lib/mysql/context.cjs.map +1 -0
  44. package/dist/lib/mysql/context.d.cts +15 -0
  45. package/dist/lib/mysql/context.d.ts +15 -0
  46. package/dist/lib/mysql/context.js +34 -0
  47. package/dist/lib/mysql/context.js.map +1 -0
  48. package/dist/lib/mysql/index.cjs +21875 -15261
  49. package/dist/lib/mysql/index.cjs.map +1 -1
  50. package/dist/lib/mysql/index.d.cts +24 -14300
  51. package/dist/lib/mysql/index.d.ts +24 -14300
  52. package/dist/lib/mysql/index.js +46 -22
  53. package/dist/lib/mysql/ports/auth-storage.cjs +84 -0
  54. package/dist/lib/mysql/ports/auth-storage.cjs.map +1 -0
  55. package/dist/lib/mysql/ports/auth-storage.d.cts +22 -0
  56. package/dist/lib/mysql/ports/auth-storage.d.ts +22 -0
  57. package/dist/lib/mysql/ports/auth-storage.js +8 -0
  58. package/dist/lib/mysql/ports/auth-storage.js.map +1 -0
  59. package/dist/lib/mysql/ports/catalog.cjs +16688 -0
  60. package/dist/lib/mysql/ports/catalog.cjs.map +1 -0
  61. package/dist/lib/mysql/ports/catalog.d.cts +24 -0
  62. package/dist/lib/mysql/ports/catalog.d.ts +24 -0
  63. package/dist/lib/mysql/ports/catalog.js +9 -0
  64. package/dist/lib/mysql/ports/catalog.js.map +1 -0
  65. package/dist/lib/mysql/ports/content-resource.cjs +321 -0
  66. package/dist/lib/mysql/ports/content-resource.cjs.map +1 -0
  67. package/dist/lib/mysql/ports/content-resource.d.cts +23 -0
  68. package/dist/lib/mysql/ports/content-resource.d.ts +23 -0
  69. package/dist/lib/mysql/ports/content-resource.js +8 -0
  70. package/dist/lib/mysql/ports/content-resource.js.map +1 -0
  71. package/dist/lib/mysql/ports/coupon.cjs +16524 -0
  72. package/dist/lib/mysql/ports/coupon.cjs.map +1 -0
  73. package/dist/lib/mysql/ports/coupon.d.cts +22 -0
  74. package/dist/lib/mysql/ports/coupon.d.ts +22 -0
  75. package/dist/lib/mysql/ports/coupon.js +9 -0
  76. package/dist/lib/mysql/ports/coupon.js.map +1 -0
  77. package/dist/lib/mysql/ports/entitlement.cjs +16350 -0
  78. package/dist/lib/mysql/ports/entitlement.cjs.map +1 -0
  79. package/dist/lib/mysql/ports/entitlement.d.cts +22 -0
  80. package/dist/lib/mysql/ports/entitlement.d.ts +22 -0
  81. package/dist/lib/mysql/ports/entitlement.js +9 -0
  82. package/dist/lib/mysql/ports/entitlement.js.map +1 -0
  83. package/dist/lib/mysql/ports/identity.cjs +154 -0
  84. package/dist/lib/mysql/ports/identity.cjs.map +1 -0
  85. package/dist/lib/mysql/ports/identity.d.cts +22 -0
  86. package/dist/lib/mysql/ports/identity.d.ts +22 -0
  87. package/dist/lib/mysql/ports/identity.js +8 -0
  88. package/dist/lib/mysql/ports/identity.js.map +1 -0
  89. package/dist/lib/mysql/ports/merchant.cjs +194 -0
  90. package/dist/lib/mysql/ports/merchant.cjs.map +1 -0
  91. package/dist/lib/mysql/ports/merchant.d.cts +22 -0
  92. package/dist/lib/mysql/ports/merchant.d.ts +22 -0
  93. package/dist/lib/mysql/ports/merchant.js +8 -0
  94. package/dist/lib/mysql/ports/merchant.js.map +1 -0
  95. package/dist/lib/mysql/ports/organization.cjs +16426 -0
  96. package/dist/lib/mysql/ports/organization.cjs.map +1 -0
  97. package/dist/lib/mysql/ports/organization.d.cts +22 -0
  98. package/dist/lib/mysql/ports/organization.d.ts +22 -0
  99. package/dist/lib/mysql/ports/organization.js +9 -0
  100. package/dist/lib/mysql/ports/organization.js.map +1 -0
  101. package/dist/lib/mysql/ports/progress.cjs +16544 -0
  102. package/dist/lib/mysql/ports/progress.cjs.map +1 -0
  103. package/dist/lib/mysql/ports/progress.d.cts +22 -0
  104. package/dist/lib/mysql/ports/progress.d.ts +22 -0
  105. package/dist/lib/mysql/ports/progress.js +9 -0
  106. package/dist/lib/mysql/ports/progress.js.map +1 -0
  107. package/dist/lib/mysql/ports/purchase.cjs +16609 -0
  108. package/dist/lib/mysql/ports/purchase.cjs.map +1 -0
  109. package/dist/lib/mysql/ports/purchase.d.cts +23 -0
  110. package/dist/lib/mysql/ports/purchase.d.ts +23 -0
  111. package/dist/lib/mysql/ports/purchase.js +9 -0
  112. package/dist/lib/mysql/ports/purchase.js.map +1 -0
  113. package/dist/lib/mysql/ports/subscription.cjs +76 -0
  114. package/dist/lib/mysql/ports/subscription.cjs.map +1 -0
  115. package/dist/lib/mysql/ports/subscription.d.cts +22 -0
  116. package/dist/lib/mysql/ports/subscription.d.ts +22 -0
  117. package/dist/lib/mysql/ports/subscription.js +8 -0
  118. package/dist/lib/mysql/ports/subscription.js.map +1 -0
  119. package/dist/lib/mysql/schema.cjs +3373 -0
  120. package/dist/lib/mysql/schema.cjs.map +1 -0
  121. package/dist/lib/mysql/schema.d.cts +14385 -0
  122. package/dist/lib/mysql/schema.d.ts +14385 -0
  123. package/dist/lib/mysql/schema.js +35 -0
  124. package/dist/lib/mysql/schema.js.map +1 -0
  125. package/dist/lib/mysql/schemas/auth/accounts.cjs.map +1 -1
  126. package/dist/lib/mysql/schemas/auth/accounts.js +4 -4
  127. package/dist/lib/mysql/schemas/auth/device-access-token.cjs.map +1 -1
  128. package/dist/lib/mysql/schemas/auth/device-access-token.js +5 -5
  129. package/dist/lib/mysql/schemas/auth/device-verification.cjs.map +1 -1
  130. package/dist/lib/mysql/schemas/auth/device-verification.js +5 -5
  131. package/dist/lib/mysql/schemas/auth/personal-access-token.cjs.map +1 -1
  132. package/dist/lib/mysql/schemas/auth/personal-access-token.js +5 -5
  133. package/dist/lib/mysql/schemas/auth/profiles.cjs.map +1 -1
  134. package/dist/lib/mysql/schemas/auth/profiles.js +4 -4
  135. package/dist/lib/mysql/schemas/auth/role-permissions.cjs.map +1 -1
  136. package/dist/lib/mysql/schemas/auth/role-permissions.js +5 -5
  137. package/dist/lib/mysql/schemas/auth/roles.cjs.map +1 -1
  138. package/dist/lib/mysql/schemas/auth/roles.js +4 -4
  139. package/dist/lib/mysql/schemas/auth/sessions.cjs.map +1 -1
  140. package/dist/lib/mysql/schemas/auth/sessions.js +5 -5
  141. package/dist/lib/mysql/schemas/auth/user-permissions.cjs.map +1 -1
  142. package/dist/lib/mysql/schemas/auth/user-permissions.js +4 -4
  143. package/dist/lib/mysql/schemas/auth/user-prefs.cjs.map +1 -1
  144. package/dist/lib/mysql/schemas/auth/user-prefs.js +4 -4
  145. package/dist/lib/mysql/schemas/auth/user-roles.cjs.map +1 -1
  146. package/dist/lib/mysql/schemas/auth/user-roles.js +4 -4
  147. package/dist/lib/mysql/schemas/auth/users.cjs +5 -1
  148. package/dist/lib/mysql/schemas/auth/users.cjs.map +1 -1
  149. package/dist/lib/mysql/schemas/auth/users.js +4 -4
  150. package/dist/lib/mysql/schemas/commerce/coupon.cjs.map +1 -1
  151. package/dist/lib/mysql/schemas/commerce/coupon.js +4 -4
  152. package/dist/lib/mysql/schemas/commerce/merchant-charge.cjs.map +1 -1
  153. package/dist/lib/mysql/schemas/commerce/merchant-charge.js +4 -4
  154. package/dist/lib/mysql/schemas/commerce/merchant-subscription.cjs.map +1 -1
  155. package/dist/lib/mysql/schemas/commerce/merchant-subscription.js +4 -4
  156. package/dist/lib/mysql/schemas/commerce/price.cjs.map +1 -1
  157. package/dist/lib/mysql/schemas/commerce/price.js +4 -4
  158. package/dist/lib/mysql/schemas/commerce/product.cjs.map +1 -1
  159. package/dist/lib/mysql/schemas/commerce/product.js +4 -4
  160. package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.cjs.map +1 -1
  161. package/dist/lib/mysql/schemas/commerce/purchase-user-transfer.js +5 -5
  162. package/dist/lib/mysql/schemas/commerce/purchase.cjs +11 -2
  163. package/dist/lib/mysql/schemas/commerce/purchase.cjs.map +1 -1
  164. package/dist/lib/mysql/schemas/commerce/purchase.js +4 -4
  165. package/dist/lib/mysql/schemas/commerce/subscription.cjs +6 -1
  166. package/dist/lib/mysql/schemas/commerce/subscription.cjs.map +1 -1
  167. package/dist/lib/mysql/schemas/commerce/subscription.js +4 -4
  168. package/dist/lib/mysql/schemas/commerce/upgradable-products.cjs.map +1 -1
  169. package/dist/lib/mysql/schemas/commerce/upgradable-products.js +5 -5
  170. package/dist/lib/mysql/schemas/communication/comment.cjs +5 -1
  171. package/dist/lib/mysql/schemas/communication/comment.cjs.map +1 -1
  172. package/dist/lib/mysql/schemas/communication/comment.js +4 -4
  173. package/dist/lib/mysql/schemas/communication/communication-preferences.cjs +5 -1
  174. package/dist/lib/mysql/schemas/communication/communication-preferences.cjs.map +1 -1
  175. package/dist/lib/mysql/schemas/communication/communication-preferences.js +4 -4
  176. package/dist/lib/mysql/schemas/communication/question-response.cjs.map +1 -1
  177. package/dist/lib/mysql/schemas/communication/question-response.js +5 -5
  178. package/dist/lib/mysql/schemas/content/content-contributions.cjs +5 -1
  179. package/dist/lib/mysql/schemas/content/content-contributions.cjs.map +1 -1
  180. package/dist/lib/mysql/schemas/content/content-contributions.js +4 -4
  181. package/dist/lib/mysql/schemas/content/content-resource-product.cjs.map +1 -1
  182. package/dist/lib/mysql/schemas/content/content-resource-product.js +4 -4
  183. package/dist/lib/mysql/schemas/content/content-resource-resource.cjs.map +1 -1
  184. package/dist/lib/mysql/schemas/content/content-resource-resource.js +4 -4
  185. package/dist/lib/mysql/schemas/content/content-resource-tag.cjs.map +1 -1
  186. package/dist/lib/mysql/schemas/content/content-resource-tag.js +4 -4
  187. package/dist/lib/mysql/schemas/content/content-resource-version.cjs.map +1 -1
  188. package/dist/lib/mysql/schemas/content/content-resource-version.js +4 -4
  189. package/dist/lib/mysql/schemas/content/content-resource.cjs +5 -1
  190. package/dist/lib/mysql/schemas/content/content-resource.cjs.map +1 -1
  191. package/dist/lib/mysql/schemas/content/content-resource.js +4 -4
  192. package/dist/lib/mysql/schemas/content/tag-tag.cjs.map +1 -1
  193. package/dist/lib/mysql/schemas/content/tag-tag.js +4 -4
  194. package/dist/lib/mysql/schemas/content/tag.cjs.map +1 -1
  195. package/dist/lib/mysql/schemas/content/tag.js +4 -4
  196. package/dist/lib/mysql/schemas/entitlements/entitlement.cjs +11 -2
  197. package/dist/lib/mysql/schemas/entitlements/entitlement.cjs.map +1 -1
  198. package/dist/lib/mysql/schemas/entitlements/entitlement.js +5 -5
  199. package/dist/lib/mysql/schemas/org/organization-membership-roles.cjs +11 -2
  200. package/dist/lib/mysql/schemas/org/organization-membership-roles.cjs.map +1 -1
  201. package/dist/lib/mysql/schemas/org/organization-membership-roles.js +4 -4
  202. package/dist/lib/mysql/schemas/org/organization-memberships.cjs +11 -2
  203. package/dist/lib/mysql/schemas/org/organization-memberships.cjs.map +1 -1
  204. package/dist/lib/mysql/schemas/org/organization-memberships.d.cts +16 -0
  205. package/dist/lib/mysql/schemas/org/organization-memberships.d.ts +16 -0
  206. package/dist/lib/mysql/schemas/org/organization-memberships.js +4 -4
  207. package/dist/lib/mysql/schemas/org/organizations.cjs +11 -2
  208. package/dist/lib/mysql/schemas/org/organizations.cjs.map +1 -1
  209. package/dist/lib/mysql/schemas/org/organizations.d.cts +16 -0
  210. package/dist/lib/mysql/schemas/org/organizations.d.ts +16 -0
  211. package/dist/lib/mysql/schemas/org/organizations.js +4 -4
  212. package/dist/lib/mysql/workflows/content-resource-workflow-utils.cjs +40 -0
  213. package/dist/lib/mysql/workflows/content-resource-workflow-utils.cjs.map +1 -0
  214. package/dist/lib/mysql/workflows/content-resource-workflow-utils.d.cts +4 -0
  215. package/dist/lib/mysql/workflows/content-resource-workflow-utils.d.ts +4 -0
  216. package/dist/lib/mysql/workflows/content-resource-workflow-utils.js +10 -0
  217. package/dist/lib/mysql/workflows/content-resource-workflow-utils.js.map +1 -0
  218. package/dist/lib/mysql/workflows/create-cohort.cjs +184 -0
  219. package/dist/lib/mysql/workflows/create-cohort.cjs.map +1 -0
  220. package/dist/lib/mysql/workflows/create-cohort.d.cts +24 -0
  221. package/dist/lib/mysql/workflows/create-cohort.d.ts +24 -0
  222. package/dist/lib/mysql/workflows/create-cohort.js +9 -0
  223. package/dist/lib/mysql/workflows/create-cohort.js.map +1 -0
  224. package/dist/lib/mysql/workflows/create-event-series.cjs +283 -0
  225. package/dist/lib/mysql/workflows/create-event-series.cjs.map +1 -0
  226. package/dist/lib/mysql/workflows/create-event-series.d.cts +24 -0
  227. package/dist/lib/mysql/workflows/create-event-series.d.ts +24 -0
  228. package/dist/lib/mysql/workflows/create-event-series.js +9 -0
  229. package/dist/lib/mysql/workflows/create-event-series.js.map +1 -0
  230. package/dist/lib/mysql/workflows/create-event.cjs +194 -0
  231. package/dist/lib/mysql/workflows/create-event.cjs.map +1 -0
  232. package/dist/lib/mysql/workflows/create-event.d.cts +24 -0
  233. package/dist/lib/mysql/workflows/create-event.d.ts +24 -0
  234. package/dist/lib/mysql/workflows/create-event.js +9 -0
  235. package/dist/lib/mysql/workflows/create-event.js.map +1 -0
  236. package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.cjs +231 -0
  237. package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.cjs.map +1 -0
  238. package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.d.cts +22 -0
  239. package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.d.ts +22 -0
  240. package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.js +8 -0
  241. package/dist/lib/mysql/workflows/create-merchant-charge-and-purchase.js.map +1 -0
  242. package/dist/lib/mysql/workflows/create-workshop.cjs +286 -0
  243. package/dist/lib/mysql/workflows/create-workshop.cjs.map +1 -0
  244. package/dist/lib/mysql/workflows/create-workshop.d.cts +24 -0
  245. package/dist/lib/mysql/workflows/create-workshop.d.ts +24 -0
  246. package/dist/lib/mysql/workflows/create-workshop.js +9 -0
  247. package/dist/lib/mysql/workflows/create-workshop.js.map +1 -0
  248. package/dist/lib/mysql/workflows/redeem-full-price-coupon.cjs +130 -0
  249. package/dist/lib/mysql/workflows/redeem-full-price-coupon.cjs.map +1 -0
  250. package/dist/lib/mysql/workflows/redeem-full-price-coupon.d.cts +24 -0
  251. package/dist/lib/mysql/workflows/redeem-full-price-coupon.d.ts +24 -0
  252. package/dist/lib/mysql/workflows/redeem-full-price-coupon.js +8 -0
  253. package/dist/lib/mysql/workflows/redeem-full-price-coupon.js.map +1 -0
  254. package/dist/lib/mysql/workflows/transfer-purchase-to-user.cjs +95 -0
  255. package/dist/lib/mysql/workflows/transfer-purchase-to-user.cjs.map +1 -0
  256. package/dist/lib/mysql/workflows/transfer-purchase-to-user.d.cts +30 -0
  257. package/dist/lib/mysql/workflows/transfer-purchase-to-user.d.ts +30 -0
  258. package/dist/lib/mysql/workflows/transfer-purchase-to-user.js +8 -0
  259. package/dist/lib/mysql/workflows/transfer-purchase-to-user.js.map +1 -0
  260. package/dist/lib/utils.d.cts +1 -10
  261. package/dist/lib/utils.d.ts +1 -10
  262. package/dist/types.d.ts +14 -0
  263. package/dist/types.js +1 -0
  264. package/package.json +9 -5
  265. package/src/index.ts +3 -2
  266. package/src/lib/mysql/context.ts +20 -0
  267. package/src/lib/mysql/index.ts +118 -4873
  268. package/src/lib/mysql/ports/auth-storage.ts +139 -0
  269. package/src/lib/mysql/ports/catalog.ts +610 -0
  270. package/src/lib/mysql/ports/content-resource.ts +442 -0
  271. package/src/lib/mysql/ports/coupon.ts +387 -0
  272. package/src/lib/mysql/ports/entitlement.ts +96 -0
  273. package/src/lib/mysql/ports/identity.ts +160 -0
  274. package/src/lib/mysql/ports/merchant.ts +274 -0
  275. package/src/lib/mysql/ports/organization.ts +216 -0
  276. package/src/lib/mysql/ports/progress.ts +366 -0
  277. package/src/lib/mysql/ports/purchase.ts +517 -0
  278. package/src/lib/mysql/ports/subscription.ts +93 -0
  279. package/src/lib/mysql/schema.ts +374 -0
  280. package/src/lib/mysql/schemas/org/organization-memberships.ts +7 -0
  281. package/src/lib/mysql/schemas/org/organizations.ts +8 -0
  282. package/src/lib/mysql/workflows/content-resource-workflow-utils.ts +22 -0
  283. package/src/lib/mysql/workflows/create-cohort.ts +239 -0
  284. package/src/lib/mysql/workflows/create-event-series.ts +384 -0
  285. package/src/lib/mysql/workflows/create-event.ts +232 -0
  286. package/src/lib/mysql/workflows/create-merchant-charge-and-purchase.ts +365 -0
  287. package/src/lib/mysql/workflows/create-workshop.ts +372 -0
  288. package/src/lib/mysql/workflows/redeem-full-price-coupon.ts +179 -0
  289. package/src/lib/mysql/workflows/transfer-purchase-to-user.ts +142 -0
  290. package/src/types.ts +33 -0
  291. package/dist/authjs.d.ts +0 -27
  292. package/dist/authjs.js +0 -1
  293. package/dist/chunk-62VSIVME.js +0 -4714
  294. package/dist/chunk-RVXF3JZ7.js +0 -8732
  295. package/dist/chunk-WEJL5OFI.js +0 -8732
  296. package/src/authjs.ts +0 -34
@@ -0,0 +1,8 @@
1
+ import {
2
+ createMerchantChargeAndPurchaseWorkflow
3
+ } from "../../../chunk-EDKWCMA7.js";
4
+ import "../../../chunk-2X5XVNDN.js";
5
+ export {
6
+ createMerchantChargeAndPurchaseWorkflow
7
+ };
8
+ //# sourceMappingURL=create-merchant-charge-and-purchase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,286 @@
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-workshop.ts
32
+ var create_workshop_exports = {};
33
+ __export(create_workshop_exports, {
34
+ createWorkshopWorkflow: () => createWorkshopWorkflow
35
+ });
36
+ module.exports = __toCommonJS(create_workshop_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-workshop.ts
52
+ var logger = import_logger.logger;
53
+ function createWorkshopWorkflow({ client, tables }, operations) {
54
+ const { contentResource, contentResourceResource, contentResourceProduct, contentResourceTag } = tables;
55
+ return {
56
+ async createWorkshop(input, userId) {
57
+ const hash = guid();
58
+ const workshopId = `workshop~${hash}`;
59
+ const result = await client.transaction(async (tx) => {
60
+ await tx.insert(contentResource).values({
61
+ id: workshopId,
62
+ type: "workshop",
63
+ createdById: userId,
64
+ fields: {
65
+ title: input.workshop.title,
66
+ description: input.workshop.description,
67
+ state: "draft",
68
+ visibility: "unlisted",
69
+ slug: (0, import_slugify.default)(`${input.workshop.title}~${hash}`)
70
+ }
71
+ });
72
+ const workshop = await tx.query.contentResource.findFirst({
73
+ where: (0, import_drizzle_orm.eq)(contentResource.id, workshopId),
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
+ }
91
+ });
92
+ if (!workshop) {
93
+ throw new Error("Failed to create workshop");
94
+ }
95
+ const parsedWorkshop = import_content_resource_schema.ContentResourceSchema.safeParse(workshop);
96
+ if (!parsedWorkshop.success) {
97
+ throw new Error("Invalid workshop data");
98
+ }
99
+ if (input.workshop.tagIds) {
100
+ await tx.insert(contentResourceTag).values(input.workshop.tagIds.map((tag) => ({
101
+ contentResourceId: workshopId,
102
+ tagId: tag.id,
103
+ createdAt: /* @__PURE__ */ new Date(),
104
+ updatedAt: /* @__PURE__ */ new Date(),
105
+ position: 0
106
+ })));
107
+ }
108
+ const createdSections = [];
109
+ const createdLessons = [];
110
+ let position = 0;
111
+ for (const item of input.structure) {
112
+ if (item.type === "section") {
113
+ const sectionHash = guid();
114
+ const sectionId = `section~${sectionHash}`;
115
+ await tx.insert(contentResource).values({
116
+ id: sectionId,
117
+ type: "section",
118
+ createdById: userId,
119
+ fields: {
120
+ title: item.title,
121
+ state: "draft",
122
+ visibility: "unlisted",
123
+ slug: (0, import_slugify.default)(`${item.title}~${sectionHash}`)
124
+ }
125
+ });
126
+ await tx.insert(contentResourceResource).values({
127
+ resourceOfId: workshopId,
128
+ resourceId: sectionId,
129
+ position
130
+ });
131
+ const section = await tx.query.contentResource.findFirst({
132
+ where: (0, import_drizzle_orm.eq)(contentResource.id, sectionId)
133
+ });
134
+ if (section) {
135
+ createdSections.push(section);
136
+ }
137
+ let lessonPosition = 0;
138
+ for (const lessonData of item.lessons) {
139
+ const lessonHash = guid();
140
+ const lessonId = `lesson_${lessonHash}`;
141
+ await tx.insert(contentResource).values({
142
+ id: lessonId,
143
+ type: "lesson",
144
+ createdById: userId,
145
+ fields: {
146
+ title: lessonData.title,
147
+ state: "draft",
148
+ visibility: "unlisted",
149
+ slug: (0, import_slugify.default)(`${lessonData.title}~${lessonHash}`),
150
+ lessonType: "lesson"
151
+ }
152
+ });
153
+ if (lessonData.videoResourceId) {
154
+ await tx.insert(contentResourceResource).values({
155
+ resourceOfId: lessonId,
156
+ resourceId: lessonData.videoResourceId,
157
+ position: 0
158
+ });
159
+ }
160
+ await tx.insert(contentResourceResource).values({
161
+ resourceOfId: sectionId,
162
+ resourceId: lessonId,
163
+ position: lessonPosition
164
+ });
165
+ const lesson = await tx.query.contentResource.findFirst({
166
+ where: (0, import_drizzle_orm.eq)(contentResource.id, lessonId)
167
+ });
168
+ if (lesson) {
169
+ createdLessons.push(lesson);
170
+ }
171
+ lessonPosition++;
172
+ }
173
+ position++;
174
+ } else {
175
+ const lessonHash = guid();
176
+ const lessonId = `lesson_${lessonHash}`;
177
+ await tx.insert(contentResource).values({
178
+ id: lessonId,
179
+ type: "lesson",
180
+ createdById: userId,
181
+ fields: {
182
+ title: item.title,
183
+ state: "draft",
184
+ visibility: "unlisted",
185
+ slug: (0, import_slugify.default)(`${item.title}~${lessonHash}`),
186
+ lessonType: "lesson"
187
+ }
188
+ });
189
+ if (item.videoResourceId) {
190
+ await tx.insert(contentResourceResource).values({
191
+ resourceOfId: lessonId,
192
+ resourceId: item.videoResourceId,
193
+ position: 0
194
+ });
195
+ }
196
+ await tx.insert(contentResourceResource).values({
197
+ resourceOfId: workshopId,
198
+ resourceId: lessonId,
199
+ position
200
+ });
201
+ const lesson = await tx.query.contentResource.findFirst({
202
+ where: (0, import_drizzle_orm.eq)(contentResource.id, lessonId)
203
+ });
204
+ if (lesson) {
205
+ createdLessons.push(lesson);
206
+ }
207
+ position++;
208
+ }
209
+ }
210
+ return {
211
+ workshop: parsedWorkshop.data,
212
+ sections: createdSections,
213
+ lessons: createdLessons
214
+ };
215
+ });
216
+ let product = null;
217
+ if (input.createProduct && input.pricing.price && input.pricing.price > 0) {
218
+ try {
219
+ product = await operations.createProduct({
220
+ name: input.workshop.title,
221
+ price: input.pricing.price,
222
+ quantityAvailable: input.pricing.quantity ?? -1,
223
+ type: "self-paced",
224
+ state: "published",
225
+ visibility: "public"
226
+ });
227
+ if (product) {
228
+ await client.insert(contentResourceProduct).values({
229
+ resourceId: workshopId,
230
+ productId: product.id,
231
+ position: 0,
232
+ metadata: {
233
+ addedBy: userId
234
+ }
235
+ });
236
+ if (input.coupon?.enabled && input.coupon.percentageDiscount && input.coupon.expires) {
237
+ try {
238
+ const finalExpires = normalizeExpirationDate(input.coupon.expires);
239
+ await operations.createCoupon({
240
+ percentageDiscount: input.coupon.percentageDiscount,
241
+ expires: finalExpires || null,
242
+ restrictedToProductId: product.id,
243
+ default: true,
244
+ maxUses: -1,
245
+ quantity: "-1",
246
+ status: 1,
247
+ fields: {}
248
+ });
249
+ logger.debug("workshop.create.coupon.success", {
250
+ workshopId,
251
+ productId: product.id,
252
+ userId,
253
+ percentageDiscount: input.coupon.percentageDiscount
254
+ });
255
+ } catch (couponError) {
256
+ logger.error(new Error(`Failed to create coupon for workshop: ${couponError}`));
257
+ logger.debug("workshop.create.coupon.failed", {
258
+ workshopId,
259
+ productId: product.id,
260
+ userId
261
+ });
262
+ }
263
+ }
264
+ }
265
+ } catch (productError) {
266
+ logger.error(new Error(`Failed to create product for workshop: ${productError}`));
267
+ logger.debug("workshop.create.product.failed", {
268
+ workshopId,
269
+ userId,
270
+ price: input.pricing.price
271
+ });
272
+ }
273
+ }
274
+ return {
275
+ ...result,
276
+ product
277
+ };
278
+ }
279
+ };
280
+ }
281
+ __name(createWorkshopWorkflow, "createWorkshopWorkflow");
282
+ // Annotate the CommonJS export names for ESM import in node:
283
+ 0 && (module.exports = {
284
+ createWorkshopWorkflow
285
+ });
286
+ //# sourceMappingURL=create-workshop.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/lib/mysql/workflows/create-workshop.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 CreateWorkshopOperations = Pick<CatalogPort, 'createProduct'> &\n\tPick<CouponPort, 'createCoupon'>\n\n/**\n * Creates the private workshop 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 = createWorkshopWorkflow(context, operations)\n * ```\n */\nexport function createWorkshopWorkflow(\n\t{ client, tables }: MySqlContext,\n\toperations: CreateWorkshopOperations,\n): Pick<ContentResourcePort, 'createWorkshop'> {\n\tconst {\n\t\tcontentResource,\n\t\tcontentResourceResource,\n\t\tcontentResourceProduct,\n\t\tcontentResourceTag,\n\t} = tables\n\n\treturn {\n\t\tasync createWorkshop(\n\t\t\tinput: {\n\t\t\t\tworkshop: {\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\tcreateProduct?: boolean\n\t\t\t\tpricing: {\n\t\t\t\t\tprice?: number | null\n\t\t\t\t\tquantity?: 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\tstructure: Array<\n\t\t\t\t\t| {\n\t\t\t\t\t\t\ttype: 'section'\n\t\t\t\t\t\t\ttitle: string\n\t\t\t\t\t\t\tlessons: { title: string; videoResourceId?: string }[]\n\t\t\t\t\t }\n\t\t\t\t\t| { type: 'lesson'; title: string; videoResourceId?: string }\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 workshopId = `workshop~${hash}`\n\n\t\t\t// Transaction only handles database operations\n\t\t\tconst result = await client.transaction(async (tx) => {\n\t\t\t\t// Create workshop content resource\n\t\t\t\tawait tx.insert(contentResource).values({\n\t\t\t\t\tid: workshopId,\n\t\t\t\t\ttype: 'workshop',\n\t\t\t\t\tcreatedById: userId,\n\t\t\t\t\tfields: {\n\t\t\t\t\t\ttitle: input.workshop.title,\n\t\t\t\t\t\tdescription: input.workshop.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.workshop.title}~${hash}`),\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\t// Fetch created workshop\n\t\t\t\tconst workshop = await tx.query.contentResource.findFirst({\n\t\t\t\t\twhere: eq(contentResource.id, workshopId),\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},\n\t\t\t\t})\n\n\t\t\t\tif (!workshop) {\n\t\t\t\t\tthrow new Error('Failed to create workshop')\n\t\t\t\t}\n\n\t\t\t\tconst parsedWorkshop = ContentResourceSchema.safeParse(workshop)\n\t\t\t\tif (!parsedWorkshop.success) {\n\t\t\t\t\tthrow new Error('Invalid workshop data')\n\t\t\t\t}\n\n\t\t\t\t// Associate tags with workshop\n\t\t\t\tif (input.workshop.tagIds) {\n\t\t\t\t\tawait tx.insert(contentResourceTag).values(\n\t\t\t\t\t\tinput.workshop.tagIds.map((tag) => ({\n\t\t\t\t\t\t\tcontentResourceId: workshopId,\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// Create sections and lessons\n\t\t\t\tconst createdSections: ContentResource[] = []\n\t\t\t\tconst createdLessons: ContentResource[] = []\n\t\t\t\tlet position = 0\n\n\t\t\t\tfor (const item of input.structure) {\n\t\t\t\t\tif (item.type === 'section') {\n\t\t\t\t\t\t// Create section\n\t\t\t\t\t\tconst sectionHash = guid()\n\t\t\t\t\t\tconst sectionId = `section~${sectionHash}`\n\n\t\t\t\t\t\tawait tx.insert(contentResource).values({\n\t\t\t\t\t\t\tid: sectionId,\n\t\t\t\t\t\t\ttype: 'section',\n\t\t\t\t\t\t\tcreatedById: userId,\n\t\t\t\t\t\t\tfields: {\n\t\t\t\t\t\t\t\ttitle: item.title,\n\t\t\t\t\t\t\t\tstate: 'draft',\n\t\t\t\t\t\t\t\tvisibility: 'unlisted',\n\t\t\t\t\t\t\t\tslug: slugify(`${item.title}~${sectionHash}`),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\t// Link section to workshop\n\t\t\t\t\t\tawait tx.insert(contentResourceResource).values({\n\t\t\t\t\t\t\tresourceOfId: workshopId,\n\t\t\t\t\t\t\tresourceId: sectionId,\n\t\t\t\t\t\t\tposition,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tconst section = await tx.query.contentResource.findFirst({\n\t\t\t\t\t\t\twhere: eq(contentResource.id, sectionId),\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (section) {\n\t\t\t\t\t\t\tcreatedSections.push(section as ContentResource)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Create lessons in section\n\t\t\t\t\t\tlet lessonPosition = 0\n\t\t\t\t\t\tfor (const lessonData of item.lessons) {\n\t\t\t\t\t\t\tconst lessonHash = guid()\n\t\t\t\t\t\t\tconst lessonId = `lesson_${lessonHash}`\n\n\t\t\t\t\t\t\tawait tx.insert(contentResource).values({\n\t\t\t\t\t\t\t\tid: lessonId,\n\t\t\t\t\t\t\t\ttype: 'lesson',\n\t\t\t\t\t\t\t\tcreatedById: userId,\n\t\t\t\t\t\t\t\tfields: {\n\t\t\t\t\t\t\t\t\ttitle: lessonData.title,\n\t\t\t\t\t\t\t\t\tstate: 'draft',\n\t\t\t\t\t\t\t\t\tvisibility: 'unlisted',\n\t\t\t\t\t\t\t\t\tslug: slugify(`${lessonData.title}~${lessonHash}`),\n\t\t\t\t\t\t\t\t\tlessonType: 'lesson',\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\t// Link video if provided\n\t\t\t\t\t\t\tif (lessonData.videoResourceId) {\n\t\t\t\t\t\t\t\tawait tx.insert(contentResourceResource).values({\n\t\t\t\t\t\t\t\t\tresourceOfId: lessonId,\n\t\t\t\t\t\t\t\t\tresourceId: lessonData.videoResourceId,\n\t\t\t\t\t\t\t\t\tposition: 0,\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\t// Link lesson to section\n\t\t\t\t\t\t\tawait tx.insert(contentResourceResource).values({\n\t\t\t\t\t\t\t\tresourceOfId: sectionId,\n\t\t\t\t\t\t\t\tresourceId: lessonId,\n\t\t\t\t\t\t\t\tposition: lessonPosition,\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tconst lesson = await tx.query.contentResource.findFirst({\n\t\t\t\t\t\t\t\twhere: eq(contentResource.id, lessonId),\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tif (lesson) {\n\t\t\t\t\t\t\t\tcreatedLessons.push(lesson as ContentResource)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlessonPosition++\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tposition++\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Create top-level lesson\n\t\t\t\t\t\tconst lessonHash = guid()\n\t\t\t\t\t\tconst lessonId = `lesson_${lessonHash}`\n\n\t\t\t\t\t\tawait tx.insert(contentResource).values({\n\t\t\t\t\t\t\tid: lessonId,\n\t\t\t\t\t\t\ttype: 'lesson',\n\t\t\t\t\t\t\tcreatedById: userId,\n\t\t\t\t\t\t\tfields: {\n\t\t\t\t\t\t\t\ttitle: item.title,\n\t\t\t\t\t\t\t\tstate: 'draft',\n\t\t\t\t\t\t\t\tvisibility: 'unlisted',\n\t\t\t\t\t\t\t\tslug: slugify(`${item.title}~${lessonHash}`),\n\t\t\t\t\t\t\t\tlessonType: 'lesson',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\t// Link video if provided\n\t\t\t\t\t\tif (item.videoResourceId) {\n\t\t\t\t\t\t\tawait tx.insert(contentResourceResource).values({\n\t\t\t\t\t\t\t\tresourceOfId: lessonId,\n\t\t\t\t\t\t\t\tresourceId: item.videoResourceId,\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\n\t\t\t\t\t\t// Link lesson to workshop\n\t\t\t\t\t\tawait tx.insert(contentResourceResource).values({\n\t\t\t\t\t\t\tresourceOfId: workshopId,\n\t\t\t\t\t\t\tresourceId: lessonId,\n\t\t\t\t\t\t\tposition,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tconst lesson = await tx.query.contentResource.findFirst({\n\t\t\t\t\t\t\twhere: eq(contentResource.id, lessonId),\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (lesson) {\n\t\t\t\t\t\t\tcreatedLessons.push(lesson as ContentResource)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tposition++\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tworkshop: parsedWorkshop.data,\n\t\t\t\t\tsections: createdSections,\n\t\t\t\t\tlessons: createdLessons,\n\t\t\t\t}\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.workshop.title,\n\t\t\t\t\t\tprice: input.pricing.price,\n\t\t\t\t\t\tquantityAvailable: input.pricing.quantity ?? -1,\n\t\t\t\t\t\ttype: 'self-paced',\n\t\t\t\t\t\tstate: 'published',\n\t\t\t\t\t\tvisibility: 'public',\n\t\t\t\t\t})\n\n\t\t\t\t\tif (product) {\n\t\t\t\t\t\t// Link product to workshop resource\n\t\t\t\t\t\tawait client.insert(contentResourceProduct).values({\n\t\t\t\t\t\t\tresourceId: workshopId,\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('workshop.create.coupon.success', {\n\t\t\t\t\t\t\t\t\tworkshopId,\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 workshop: ${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('workshop.create.coupon.failed', {\n\t\t\t\t\t\t\t\t\tworkshopId,\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 - workshop 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 workshop: ${productError}`),\n\t\t\t\t\t)\n\t\t\t\t\tlogger.debug('workshop.create.product.failed', {\n\t\t\t\t\t\tworkshopId,\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 - workshop 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\t...result,\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":"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","names":["guid","customAlphabet","normalizeExpirationDate","date","undefined","Date","UTC","getUTCFullYear","getUTCMonth","getUTCDate","logger","baseLogger","createWorkshopWorkflow","client","tables","operations","contentResource","contentResourceResource","contentResourceProduct","contentResourceTag","createWorkshop","input","userId","hash","guid","workshopId","result","transaction","tx","insert","values","id","type","createdById","fields","title","workshop","description","state","visibility","slug","slugify","query","findFirst","where","eq","with","resources","resource","orderBy","asc","position","Error","parsedWorkshop","ContentResourceSchema","safeParse","success","tagIds","map","tag","contentResourceId","tagId","createdAt","Date","updatedAt","createdSections","createdLessons","item","structure","sectionHash","sectionId","resourceOfId","resourceId","section","push","lessonPosition","lessonData","lessons","lessonHash","lessonId","lessonType","videoResourceId","lesson","data","sections","product","createProduct","pricing","price","name","quantityAvailable","quantity","productId","metadata","addedBy","coupon","enabled","percentageDiscount","expires","finalExpires","normalizeExpirationDate","createCoupon","restrictedToProductId","default","maxUses","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 CreateWorkshopOperations = Pick<CatalogPort, 'createProduct'> & Pick<CouponPort, 'createCoupon'>;
10
+ /**
11
+ * Creates the private workshop 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 = createWorkshopWorkflow(context, operations)
20
+ * ```
21
+ */
22
+ declare function createWorkshopWorkflow({ client, tables }: MySqlContext, operations: CreateWorkshopOperations): Pick<ContentResourcePort, 'createWorkshop'>;
23
+
24
+ export { createWorkshopWorkflow };
@@ -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 CreateWorkshopOperations = Pick<CatalogPort, 'createProduct'> & Pick<CouponPort, 'createCoupon'>;
10
+ /**
11
+ * Creates the private workshop 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 = createWorkshopWorkflow(context, operations)
20
+ * ```
21
+ */
22
+ declare function createWorkshopWorkflow({ client, tables }: MySqlContext, operations: CreateWorkshopOperations): Pick<ContentResourcePort, 'createWorkshop'>;
23
+
24
+ export { createWorkshopWorkflow };
@@ -0,0 +1,9 @@
1
+ import {
2
+ createWorkshopWorkflow
3
+ } from "../../../chunk-FYT7RTVW.js";
4
+ import "../../../chunk-6XQ6C3IX.js";
5
+ import "../../../chunk-2X5XVNDN.js";
6
+ export {
7
+ createWorkshopWorkflow
8
+ };
9
+ //# sourceMappingURL=create-workshop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,130 @@
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/redeem-full-price-coupon.ts
22
+ var redeem_full_price_coupon_exports = {};
23
+ __export(redeem_full_price_coupon_exports, {
24
+ createRedeemFullPriceCouponWorkflow: () => createRedeemFullPriceCouponWorkflow
25
+ });
26
+ module.exports = __toCommonJS(redeem_full_price_coupon_exports);
27
+ var import_drizzle_orm = require("drizzle-orm");
28
+ var import_uuid = require("uuid");
29
+ var import_logger = require("@coursebuilder/utils/logger");
30
+ var import_validate_coupon = require("@coursebuilder/commerce/validate-coupon");
31
+ var normalizeLearnerEmail = /* @__PURE__ */ __name((email) => email.trim().toLowerCase().replace(/\s+/g, "+"), "normalizeLearnerEmail");
32
+ function createRedeemFullPriceCouponWorkflow({ client, tables }, operations) {
33
+ const { purchases: purchaseTable } = tables;
34
+ return {
35
+ async redeemFullPriceCoupon(options) {
36
+ const { email: baseEmail, couponId, productIds, currentUserId, redeemingProductId } = options;
37
+ const email = normalizeLearnerEmail(String(baseEmail));
38
+ const coupon = await operations.getCouponWithBulkPurchases(couponId);
39
+ const productId = coupon && coupon.restrictedToProductId || redeemingProductId;
40
+ if (!productId)
41
+ throw new Error(`unable-to-find-any-product-id`);
42
+ const couponValidation = (0, import_validate_coupon.validateCoupon)(coupon, productIds);
43
+ if (coupon && couponValidation.isRedeemable) {
44
+ const bulkCouponRedemption = Boolean(coupon.maxUses > 1);
45
+ const { user } = await operations.findOrCreateUser(email);
46
+ if (!user)
47
+ throw new Error(`unable-to-create-user-${email}`);
48
+ const currentUser = currentUserId ? await operations.getUserById(currentUserId) : null;
49
+ const redeemingForCurrentUser = currentUser?.id === user.id;
50
+ if (bulkCouponRedemption) {
51
+ const existingValidRedemption = await client.query.purchases.findFirst({
52
+ where: (0, import_drizzle_orm.and)((0, import_drizzle_orm.eq)(purchaseTable.redeemedBulkCouponId, coupon.id), (0, import_drizzle_orm.eq)(purchaseTable.userId, user.id), (0, import_drizzle_orm.eq)(purchaseTable.status, "Valid"))
53
+ });
54
+ if (existingValidRedemption) {
55
+ import_logger.logger.info("adapter.coupon.redeem.duplicate_team_seat", {
56
+ couponId: coupon.id,
57
+ currentUserId,
58
+ email,
59
+ productId,
60
+ purchaseId: existingValidRedemption.id,
61
+ userId: user.id
62
+ });
63
+ return {
64
+ error: {
65
+ message: "team-seat-redemption-already-claimed"
66
+ },
67
+ redeemingForCurrentUser,
68
+ purchase: null
69
+ };
70
+ }
71
+ }
72
+ const existingPurchases = await operations.getExistingNonBulkValidPurchasesOfProduct({
73
+ userId: user.id,
74
+ productId
75
+ });
76
+ if (existingPurchases.length > 0) {
77
+ const errorMessage = `already-purchased-${email}`;
78
+ import_logger.logger.info("adapter.coupon.redeem.already_purchased", {
79
+ couponId: coupon.id,
80
+ currentUserId,
81
+ email,
82
+ productId,
83
+ userId: user.id
84
+ });
85
+ return {
86
+ error: {
87
+ message: errorMessage
88
+ },
89
+ redeemingForCurrentUser,
90
+ purchase: null
91
+ };
92
+ throw new Error(errorMessage);
93
+ }
94
+ const purchaseId = `purchase-${(0, import_uuid.v4)()}`;
95
+ const userMemberships = await operations.getMembershipsForUser(user.id);
96
+ const organizationId = coupon.organizationId || userMemberships.find((m) => m.organization.name?.includes(user.email))?.organizationId;
97
+ await operations.createPurchase({
98
+ id: purchaseId,
99
+ userId: user.id,
100
+ couponId: bulkCouponRedemption ? null : coupon.id,
101
+ redeemedBulkCouponId: bulkCouponRedemption ? coupon.id : null,
102
+ productId,
103
+ totalAmount: "0",
104
+ organizationId,
105
+ metadata: {
106
+ couponUsedId: bulkCouponRedemption ? null : coupon.id
107
+ }
108
+ });
109
+ const newPurchase = await operations.getPurchase(purchaseId);
110
+ await operations.incrementCouponUsedCount(coupon.id);
111
+ await operations.createPurchaseTransfer({
112
+ sourceUserId: user.id,
113
+ purchaseId,
114
+ expiresAt: new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7)
115
+ });
116
+ return {
117
+ purchase: newPurchase,
118
+ redeemingForCurrentUser
119
+ };
120
+ }
121
+ return null;
122
+ }
123
+ };
124
+ }
125
+ __name(createRedeemFullPriceCouponWorkflow, "createRedeemFullPriceCouponWorkflow");
126
+ // Annotate the CommonJS export names for ESM import in node:
127
+ 0 && (module.exports = {
128
+ createRedeemFullPriceCouponWorkflow
129
+ });
130
+ //# sourceMappingURL=redeem-full-price-coupon.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/lib/mysql/workflows/redeem-full-price-coupon.ts"],"sourcesContent":["import { and, eq } from 'drizzle-orm'\nimport { v4 } from 'uuid'\n\nimport type {\n\tCouponPort,\n\tIdentityPort,\n\tOrganizationPort,\n\tPurchasePort,\n} from '@coursebuilder/core/ports'\nimport { logger } from '@coursebuilder/utils/logger'\nimport { validateCoupon } from '@coursebuilder/commerce/validate-coupon'\n\nimport type { MySqlContext } from '../context.js'\n\ntype RedeemFullPriceCouponOperations = Pick<\n\tCouponPort,\n\t'getCouponWithBulkPurchases' | 'incrementCouponUsedCount'\n> &\n\tPick<IdentityPort, 'findOrCreateUser' | 'getUserById'> &\n\tPick<OrganizationPort, 'getMembershipsForUser'> &\n\tPick<\n\t\tPurchasePort,\n\t\t| 'createPurchase'\n\t\t| 'createPurchaseTransfer'\n\t\t| 'getExistingNonBulkValidPurchasesOfProduct'\n\t\t| 'getPurchase'\n\t>\n\nconst normalizeLearnerEmail = (email: string) =>\n\temail.trim().toLowerCase().replace(/\\s+/g, '+')\n\n/**\n * Creates the private full-price coupon redemption workflow.\n *\n * @param context - The shared MySQL client and table set.\n * @param operations - Narrow identity, organization, purchase, and coupon operations.\n * @returns The purchase-owned coupon redemption operation.\n *\n * @example\n * ```ts\n * const workflow = createRedeemFullPriceCouponWorkflow(context, operations)\n * ```\n */\nexport function createRedeemFullPriceCouponWorkflow(\n\t{ client, tables }: MySqlContext,\n\toperations: RedeemFullPriceCouponOperations,\n): Pick<PurchasePort, 'redeemFullPriceCoupon'> {\n\tconst { purchases: purchaseTable } = tables\n\n\treturn {\n\t\tasync redeemFullPriceCoupon(options) {\n\t\t\tconst {\n\t\t\t\temail: baseEmail,\n\t\t\t\tcouponId,\n\t\t\t\tproductIds,\n\t\t\t\tcurrentUserId,\n\t\t\t\tredeemingProductId,\n\t\t\t} = options\n\t\t\tconst email = normalizeLearnerEmail(String(baseEmail))\n\n\t\t\tconst coupon = await operations.getCouponWithBulkPurchases(couponId)\n\n\t\t\tconst productId =\n\t\t\t\t(coupon && (coupon.restrictedToProductId as string)) ||\n\t\t\t\tredeemingProductId\n\n\t\t\tif (!productId) throw new Error(`unable-to-find-any-product-id`)\n\n\t\t\tconst couponValidation = validateCoupon(coupon, productIds)\n\n\t\t\tif (coupon && couponValidation.isRedeemable) {\n\t\t\t\t// if the Coupon is the Bulk Coupon of a Bulk Purchase,\n\t\t\t\t// then a bulk coupon is being redeemed\n\t\t\t\tconst bulkCouponRedemption = Boolean(coupon.maxUses > 1)\n\n\t\t\t\tconst { user } = await operations.findOrCreateUser(email)\n\n\t\t\t\tif (!user) throw new Error(`unable-to-create-user-${email}`)\n\n\t\t\t\tconst currentUser = currentUserId\n\t\t\t\t\t? await operations.getUserById(currentUserId)\n\t\t\t\t\t: null\n\n\t\t\t\tconst redeemingForCurrentUser = currentUser?.id === user.id\n\n\t\t\t\tif (bulkCouponRedemption) {\n\t\t\t\t\tconst existingValidRedemption =\n\t\t\t\t\t\tawait client.query.purchases.findFirst({\n\t\t\t\t\t\t\twhere: and(\n\t\t\t\t\t\t\t\teq(purchaseTable.redeemedBulkCouponId, coupon.id),\n\t\t\t\t\t\t\t\teq(purchaseTable.userId, user.id),\n\t\t\t\t\t\t\t\teq(purchaseTable.status, 'Valid'),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t})\n\n\t\t\t\t\tif (existingValidRedemption) {\n\t\t\t\t\t\tlogger.info('adapter.coupon.redeem.duplicate_team_seat', {\n\t\t\t\t\t\t\tcouponId: coupon.id,\n\t\t\t\t\t\t\tcurrentUserId,\n\t\t\t\t\t\t\temail,\n\t\t\t\t\t\t\tproductId,\n\t\t\t\t\t\t\tpurchaseId: existingValidRedemption.id,\n\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\tmessage: 'team-seat-redemption-already-claimed',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tredeemingForCurrentUser,\n\t\t\t\t\t\t\tpurchase: null,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// To prevent double-purchasing, check if this user already has a\n\t\t\t\t// Purchase record for this product that is valid and wasn't a bulk\n\t\t\t\t// coupon purchase.\n\t\t\t\tconst existingPurchases =\n\t\t\t\t\tawait operations.getExistingNonBulkValidPurchasesOfProduct({\n\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\tproductId,\n\t\t\t\t\t})\n\n\t\t\t\tif (existingPurchases.length > 0) {\n\t\t\t\t\tconst errorMessage = `already-purchased-${email}`\n\t\t\t\t\tlogger.info('adapter.coupon.redeem.already_purchased', {\n\t\t\t\t\t\tcouponId: coupon.id,\n\t\t\t\t\t\tcurrentUserId,\n\t\t\t\t\t\temail,\n\t\t\t\t\t\tproductId,\n\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t})\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tmessage: errorMessage,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tredeemingForCurrentUser,\n\t\t\t\t\t\tpurchase: null,\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(errorMessage)\n\t\t\t\t}\n\n\t\t\t\tconst purchaseId = `purchase-${v4()}`\n\t\t\t\tconst userMemberships = await operations.getMembershipsForUser(user.id)\n\t\t\t\tconst organizationId =\n\t\t\t\t\tcoupon.organizationId ||\n\t\t\t\t\tuserMemberships.find((m) => m.organization.name?.includes(user.email))\n\t\t\t\t\t\t?.organizationId // safer way to make sure we are using personal organization\n\n\t\t\t\tawait operations.createPurchase({\n\t\t\t\t\tid: purchaseId,\n\t\t\t\t\tuserId: user.id,\n\t\t\t\t\tcouponId: bulkCouponRedemption ? null : coupon.id,\n\t\t\t\t\tredeemedBulkCouponId: bulkCouponRedemption ? coupon.id : null,\n\t\t\t\t\tproductId,\n\t\t\t\t\ttotalAmount: '0',\n\t\t\t\t\torganizationId,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tcouponUsedId: bulkCouponRedemption ? null : coupon.id,\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\tconst newPurchase = await operations.getPurchase(purchaseId)\n\n\t\t\t\tawait operations.incrementCouponUsedCount(coupon.id)\n\n\t\t\t\tawait operations.createPurchaseTransfer({\n\t\t\t\t\tsourceUserId: user.id,\n\t\t\t\t\tpurchaseId: purchaseId,\n\t\t\t\t\texpiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),\n\t\t\t\t})\n\n\t\t\t\treturn { purchase: newPurchase, redeemingForCurrentUser }\n\t\t\t}\n\n\t\t\treturn null\n\t\t},\n\t}\n}\n"],"mappings":"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","names":["normalizeLearnerEmail","email","trim","toLowerCase","replace","createRedeemFullPriceCouponWorkflow","client","tables","operations","purchases","purchaseTable","redeemFullPriceCoupon","options","baseEmail","couponId","productIds","currentUserId","redeemingProductId","String","coupon","getCouponWithBulkPurchases","productId","restrictedToProductId","Error","couponValidation","validateCoupon","isRedeemable","bulkCouponRedemption","Boolean","maxUses","user","findOrCreateUser","currentUser","getUserById","redeemingForCurrentUser","id","existingValidRedemption","query","findFirst","where","and","eq","redeemedBulkCouponId","userId","status","logger","info","purchaseId","error","message","purchase","existingPurchases","getExistingNonBulkValidPurchasesOfProduct","length","errorMessage","v4","userMemberships","getMembershipsForUser","organizationId","find","m","organization","name","includes","createPurchase","totalAmount","metadata","couponUsedId","newPurchase","getPurchase","incrementCouponUsedCount","createPurchaseTransfer","sourceUserId","expiresAt","Date","now"]}
@@ -0,0 +1,24 @@
1
+ import { CouponPort, IdentityPort, OrganizationPort, 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
+ type RedeemFullPriceCouponOperations = Pick<CouponPort, 'getCouponWithBulkPurchases' | 'incrementCouponUsedCount'> & Pick<IdentityPort, 'findOrCreateUser' | 'getUserById'> & Pick<OrganizationPort, 'getMembershipsForUser'> & Pick<PurchasePort, 'createPurchase' | 'createPurchaseTransfer' | 'getExistingNonBulkValidPurchasesOfProduct' | 'getPurchase'>;
10
+ /**
11
+ * Creates the private full-price coupon redemption workflow.
12
+ *
13
+ * @param context - The shared MySQL client and table set.
14
+ * @param operations - Narrow identity, organization, purchase, and coupon operations.
15
+ * @returns The purchase-owned coupon redemption operation.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const workflow = createRedeemFullPriceCouponWorkflow(context, operations)
20
+ * ```
21
+ */
22
+ declare function createRedeemFullPriceCouponWorkflow({ client, tables }: MySqlContext, operations: RedeemFullPriceCouponOperations): Pick<PurchasePort, 'redeemFullPriceCoupon'>;
23
+
24
+ export { createRedeemFullPriceCouponWorkflow };
@@ -0,0 +1,24 @@
1
+ import { CouponPort, IdentityPort, OrganizationPort, 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
+ type RedeemFullPriceCouponOperations = Pick<CouponPort, 'getCouponWithBulkPurchases' | 'incrementCouponUsedCount'> & Pick<IdentityPort, 'findOrCreateUser' | 'getUserById'> & Pick<OrganizationPort, 'getMembershipsForUser'> & Pick<PurchasePort, 'createPurchase' | 'createPurchaseTransfer' | 'getExistingNonBulkValidPurchasesOfProduct' | 'getPurchase'>;
10
+ /**
11
+ * Creates the private full-price coupon redemption workflow.
12
+ *
13
+ * @param context - The shared MySQL client and table set.
14
+ * @param operations - Narrow identity, organization, purchase, and coupon operations.
15
+ * @returns The purchase-owned coupon redemption operation.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const workflow = createRedeemFullPriceCouponWorkflow(context, operations)
20
+ * ```
21
+ */
22
+ declare function createRedeemFullPriceCouponWorkflow({ client, tables }: MySqlContext, operations: RedeemFullPriceCouponOperations): Pick<PurchasePort, 'redeemFullPriceCoupon'>;
23
+
24
+ export { createRedeemFullPriceCouponWorkflow };
@@ -0,0 +1,8 @@
1
+ import {
2
+ createRedeemFullPriceCouponWorkflow
3
+ } from "../../../chunk-5FLS4ZBX.js";
4
+ import "../../../chunk-2X5XVNDN.js";
5
+ export {
6
+ createRedeemFullPriceCouponWorkflow
7
+ };
8
+ //# sourceMappingURL=redeem-full-price-coupon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}