@coursebuilder/server 0.1.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 (156) hide show
  1. package/LICENSE +21 -0
  2. package/dist/actions/checkout.d.ts +6 -0
  3. package/dist/actions/checkout.js +9 -0
  4. package/dist/actions/checkout.js.map +1 -0
  5. package/dist/actions/claimed.d.ts +6 -0
  6. package/dist/actions/claimed.js +8 -0
  7. package/dist/actions/claimed.js.map +1 -0
  8. package/dist/actions/create-magic-link.d.ts +6 -0
  9. package/dist/actions/create-magic-link.js +9 -0
  10. package/dist/actions/create-magic-link.js.map +1 -0
  11. package/dist/actions/index.d.ts +11 -0
  12. package/dist/actions/index.js +18 -0
  13. package/dist/actions/index.js.map +1 -0
  14. package/dist/actions/prices-coupon-for-code.d.ts +6 -0
  15. package/dist/actions/prices-coupon-for-code.js +63 -0
  16. package/dist/actions/prices-coupon-for-code.js.map +1 -0
  17. package/dist/actions/prices-formatted.d.ts +6 -0
  18. package/dist/actions/prices-formatted.js +8 -0
  19. package/dist/actions/prices-formatted.js.map +1 -0
  20. package/dist/actions/process-refund.d.ts +1 -0
  21. package/dist/actions/process-refund.js +8 -0
  22. package/dist/actions/process-refund.js.map +1 -0
  23. package/dist/actions/redeem.d.ts +1 -0
  24. package/dist/actions/redeem.js +8 -0
  25. package/dist/actions/redeem.js.map +1 -0
  26. package/dist/actions/transfer-purchase.d.ts +1 -0
  27. package/dist/actions/transfer-purchase.js +8 -0
  28. package/dist/actions/transfer-purchase.js.map +1 -0
  29. package/dist/actions/user-lookup.d.ts +6 -0
  30. package/dist/actions/user-lookup.js +9 -0
  31. package/dist/actions/user-lookup.js.map +1 -0
  32. package/dist/adapter-BtDS6LDw.d.ts +9 -0
  33. package/dist/chunk-22AMOZYZ.js +67 -0
  34. package/dist/chunk-22AMOZYZ.js.map +1 -0
  35. package/dist/chunk-4EQQSW57.js +32 -0
  36. package/dist/chunk-4EQQSW57.js.map +1 -0
  37. package/dist/chunk-4LZZLN6T.js +52 -0
  38. package/dist/chunk-4LZZLN6T.js.map +1 -0
  39. package/dist/chunk-4QQA3TC2.js +29 -0
  40. package/dist/chunk-4QQA3TC2.js.map +1 -0
  41. package/dist/chunk-4TSEPUSC.js +160 -0
  42. package/dist/chunk-4TSEPUSC.js.map +1 -0
  43. package/dist/chunk-5O4UO4IR.js +93 -0
  44. package/dist/chunk-5O4UO4IR.js.map +1 -0
  45. package/dist/chunk-7FCQOLKL.js +26 -0
  46. package/dist/chunk-7FCQOLKL.js.map +1 -0
  47. package/dist/chunk-AZLUMIIF.js +8 -0
  48. package/dist/chunk-AZLUMIIF.js.map +1 -0
  49. package/dist/chunk-E6HV6TNI.js +38 -0
  50. package/dist/chunk-E6HV6TNI.js.map +1 -0
  51. package/dist/chunk-ECNJPNPU.js +54 -0
  52. package/dist/chunk-ECNJPNPU.js.map +1 -0
  53. package/dist/chunk-F3KUYN5I.js +111 -0
  54. package/dist/chunk-F3KUYN5I.js.map +1 -0
  55. package/dist/chunk-G63YAJF2.js +107 -0
  56. package/dist/chunk-G63YAJF2.js.map +1 -0
  57. package/dist/chunk-JFR7XO72.js +7 -0
  58. package/dist/chunk-JFR7XO72.js.map +1 -0
  59. package/dist/chunk-KNC7QVGZ.js +26 -0
  60. package/dist/chunk-KNC7QVGZ.js.map +1 -0
  61. package/dist/chunk-ODSSRMD2.js +270 -0
  62. package/dist/chunk-ODSSRMD2.js.map +1 -0
  63. package/dist/chunk-VEKYIR7I.js +26 -0
  64. package/dist/chunk-VEKYIR7I.js.map +1 -0
  65. package/dist/chunk-W7YAT4NR.js +12 -0
  66. package/dist/chunk-W7YAT4NR.js.map +1 -0
  67. package/dist/chunk-WGAPYIUP.js +56 -0
  68. package/dist/chunk-WGAPYIUP.js.map +1 -0
  69. package/dist/chunk-WYNH2AWD.js +7 -0
  70. package/dist/chunk-WYNH2AWD.js.map +1 -0
  71. package/dist/chunk-Y5X5J55Z.js +384 -0
  72. package/dist/chunk-Y5X5J55Z.js.map +1 -0
  73. package/dist/chunk-YFLGJIMA.js +216 -0
  74. package/dist/chunk-YFLGJIMA.js.map +1 -0
  75. package/dist/chunk-ZFZNN4E5.js +7 -0
  76. package/dist/chunk-ZFZNN4E5.js.map +1 -0
  77. package/dist/create-inngest-middleware.d.ts +635 -0
  78. package/dist/create-inngest-middleware.js +12 -0
  79. package/dist/create-inngest-middleware.js.map +1 -0
  80. package/dist/http-router.d.ts +20 -0
  81. package/dist/http-router.js +24 -0
  82. package/dist/http-router.js.map +1 -0
  83. package/dist/http.d.ts +38 -0
  84. package/dist/http.js +32 -0
  85. package/dist/http.js.map +1 -0
  86. package/dist/index.d.ts +34 -0
  87. package/dist/index.js +365 -0
  88. package/dist/index.js.map +1 -0
  89. package/dist/magic-string.es-ENO43NON.js +1389 -0
  90. package/dist/magic-string.es-ENO43NON.js.map +1 -0
  91. package/dist/runtime/actions.d.ts +5 -0
  92. package/dist/runtime/actions.js +8 -0
  93. package/dist/runtime/actions.js.map +1 -0
  94. package/dist/runtime/assert.d.ts +15 -0
  95. package/dist/runtime/assert.js +8 -0
  96. package/dist/runtime/assert.js.map +1 -0
  97. package/dist/runtime/cookie.d.ts +8 -0
  98. package/dist/runtime/cookie.js +8 -0
  99. package/dist/runtime/cookie.js.map +1 -0
  100. package/dist/runtime/env.d.ts +9 -0
  101. package/dist/runtime/env.js +11 -0
  102. package/dist/runtime/env.js.map +1 -0
  103. package/dist/runtime/env.test.d.ts +2 -0
  104. package/dist/runtime/env.test.js +14956 -0
  105. package/dist/runtime/env.test.js.map +1 -0
  106. package/dist/runtime/init.d.ts +26 -0
  107. package/dist/runtime/init.js +14 -0
  108. package/dist/runtime/init.js.map +1 -0
  109. package/dist/runtime/logger.d.ts +4 -0
  110. package/dist/runtime/logger.js +10 -0
  111. package/dist/runtime/logger.js.map +1 -0
  112. package/dist/runtime/merge.d.ts +4 -0
  113. package/dist/runtime/merge.js +8 -0
  114. package/dist/runtime/merge.js.map +1 -0
  115. package/dist/runtime/providers.d.ts +21 -0
  116. package/dist/runtime/providers.js +9 -0
  117. package/dist/runtime/providers.js.map +1 -0
  118. package/dist/runtime/web.d.ts +29 -0
  119. package/dist/runtime/web.js +16 -0
  120. package/dist/runtime/web.js.map +1 -0
  121. package/package.json +65 -0
  122. package/src/actions/actions.test.ts +232 -0
  123. package/src/actions/checkout.ts +160 -0
  124. package/src/actions/claimed.ts +40 -0
  125. package/src/actions/create-magic-link.ts +78 -0
  126. package/src/actions/index.ts +401 -0
  127. package/src/actions/prices-coupon-for-code.ts +91 -0
  128. package/src/actions/prices-formatted.ts +313 -0
  129. package/src/actions/process-refund.ts +2 -0
  130. package/src/actions/redeem.ts +2 -0
  131. package/src/actions/transfer-purchase.ts +2 -0
  132. package/src/actions/user-lookup.ts +37 -0
  133. package/src/adapter.ts +28 -0
  134. package/src/create-inngest-middleware.ts +157 -0
  135. package/src/http-actions.ts +29 -0
  136. package/src/http-router.ts +79 -0
  137. package/src/http.test.ts +46 -0
  138. package/src/http.ts +83 -0
  139. package/src/index.test.ts +21 -0
  140. package/src/index.ts +44 -0
  141. package/src/mock-adapter.ts +398 -0
  142. package/src/mock-payment-provider.ts +56 -0
  143. package/src/resource-chat.ts +371 -0
  144. package/src/runtime/actions.ts +25 -0
  145. package/src/runtime/assert.ts +55 -0
  146. package/src/runtime/cookie.ts +12 -0
  147. package/src/runtime/env.test.ts +49 -0
  148. package/src/runtime/env.ts +63 -0
  149. package/src/runtime/init.ts +112 -0
  150. package/src/runtime/logger.ts +6 -0
  151. package/src/runtime/merge.ts +25 -0
  152. package/src/runtime/providers.ts +38 -0
  153. package/src/runtime/web.ts +199 -0
  154. package/src/streaming-chat-prompt-executor.ts +43 -0
  155. package/src/type-contracts.test.ts +167 -0
  156. package/src/web-body-parse.test.ts +55 -0
package/src/http.ts ADDED
@@ -0,0 +1,83 @@
1
+ import type { Inngest } from 'inngest'
2
+
3
+ import type { ServerAdapter } from './adapter'
4
+ import type { CourseBuilderAuthConfig } from '@coursebuilder/core/auth'
5
+ import type { Provider } from '@coursebuilder/core/providers'
6
+ import type { User } from '@coursebuilder/core/schemas'
7
+ import type {
8
+ CallbacksOptions,
9
+ CookiesOptions,
10
+ } from '@coursebuilder/core/types'
11
+
12
+ import { CourseBuilderInternal } from './http-router'
13
+ import { assertConfig } from './runtime/assert'
14
+ import { createActionURL, setEnvDefaults } from './runtime/env.js'
15
+ import { logger, setLogger, type LoggerInstance } from './runtime/logger'
16
+ import { toInternalRequest, toResponse } from './runtime/web'
17
+
18
+ export { createActionURL, setEnvDefaults }
19
+
20
+ /**
21
+ * Handle a Course Builder HTTP request.
22
+ *
23
+ * @param request - Web-standard request to route.
24
+ * @param config - Course Builder server runtime configuration.
25
+ * @returns The web-standard response produced by the selected action.
26
+ */
27
+ export async function CourseBuilder(
28
+ request: Request,
29
+ config: CourseBuilderConfig,
30
+ ): Promise<Response> {
31
+ setLogger(config.logger, config.debug)
32
+
33
+ const internalRequest = await toInternalRequest(request, config)
34
+ if (!internalRequest) {
35
+ return Response.json('Bad request', { status: 400 })
36
+ }
37
+
38
+ const warningsOrError = assertConfig(internalRequest, config)
39
+
40
+ if (Array.isArray(warningsOrError)) {
41
+ warningsOrError.forEach((code) => logger.warn(code))
42
+ } else if (warningsOrError) {
43
+ logger.error(warningsOrError)
44
+ return Response.json('Internal Server Error', { status: 500 })
45
+ }
46
+ const isRedirect = request.headers?.has('X-Course-Builder-Return-Redirect')
47
+
48
+ try {
49
+ const internalResponse = await CourseBuilderInternal(
50
+ internalRequest,
51
+ config,
52
+ )
53
+
54
+ const response = toResponse(internalResponse)
55
+ const url = response.headers.get('Location')
56
+ if (!isRedirect || !url) return response
57
+
58
+ return Response.json({ url }, { headers: response.headers })
59
+ } catch (e) {
60
+ logger.error(e as Error)
61
+ if (request.method === 'POST' && internalRequest.action === 'session')
62
+ return Response.json(null, { status: 400 })
63
+ return Response.json(`something broke: ${(e as Error).message}`, {
64
+ status: 400,
65
+ })
66
+ }
67
+ }
68
+
69
+ /** Runtime configuration consumed by the server-owned HTTP entry point. */
70
+ export interface CourseBuilderConfig {
71
+ callbacks?: Partial<CallbacksOptions>
72
+ adapter?: ServerAdapter
73
+ providers: Provider[]
74
+ debug?: boolean
75
+ basePath?: string
76
+ logger?: LoggerInstance
77
+ cookies?: Partial<CookiesOptions>
78
+ useSecureCookies?: boolean
79
+ inngest?: Inngest
80
+ getCurrentUser?: () => Promise<User | null>
81
+ authConfig: CourseBuilderAuthConfig
82
+ baseUrl: string
83
+ }
@@ -0,0 +1,21 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import {
4
+ coreInngest,
5
+ courseBuilderCoreFunctions,
6
+ createInngestMiddleware,
7
+ } from './index'
8
+
9
+ describe('@coursebuilder/server Inngest composition', () => {
10
+ it('preserves the frozen core client and function aggregate', () => {
11
+ expect(coreInngest.id).toBe('core-inngest')
12
+ expect(courseBuilderCoreFunctions).toHaveLength(16)
13
+ expect(courseBuilderCoreFunctions[0]?.config.id).toBe(
14
+ 'transcript-ready-event',
15
+ )
16
+ })
17
+
18
+ it('exports middleware construction from the package root', () => {
19
+ expect(createInngestMiddleware).toBeTypeOf('function')
20
+ })
21
+ })
package/src/index.ts ADDED
@@ -0,0 +1,44 @@
1
+ import {
2
+ commerceFunctionsAfterResourceChat,
3
+ commerceFunctionsBeforeResourceChat,
4
+ } from '@coursebuilder/commerce/functions'
5
+ import {
6
+ PURCHASE_BENEFITS_ATTACHED_EVENT,
7
+ TEAM_SEAT_REDEMPTION_CREATED_EVENT,
8
+ } from '@coursebuilder/core/events/commerce'
9
+ import { resourceChat } from './resource-chat'
10
+ import { coreVideoProcessingFunctions } from '@coursebuilder/video-processing/functions'
11
+
12
+ import { defineCourseBuilderFunctions } from './create-inngest-middleware'
13
+
14
+ export { CourseBuilder, createActionURL, setEnvDefaults } from './http'
15
+ export type { CourseBuilderConfig } from './http'
16
+ export { CourseBuilderInternal } from './http-router'
17
+
18
+ /** @deprecated Import this provider-neutral event map from `@coursebuilder/core/events`. */
19
+ export type CourseBuilderCoreEvents =
20
+ import('@coursebuilder/core/events').CourseBuilderCoreEvents
21
+
22
+ export { PURCHASE_BENEFITS_ATTACHED_EVENT, TEAM_SEAT_REDEMPTION_CREATED_EVENT }
23
+
24
+ export const courseBuilderCoreFunctions = defineCourseBuilderFunctions([
25
+ ...coreVideoProcessingFunctions,
26
+ ...commerceFunctionsBeforeResourceChat,
27
+ resourceChat,
28
+ ...commerceFunctionsAfterResourceChat,
29
+ ])
30
+
31
+ export {
32
+ coreInngest,
33
+ createInngestMiddleware,
34
+ defineCourseBuilderFunctions,
35
+ } from './create-inngest-middleware'
36
+ export type {
37
+ CoreInngest,
38
+ CoreInngestContext,
39
+ CourseBuilderFunctionDefinition,
40
+ CourseBuilderHandlerInput,
41
+ CoreInngestFunctionInput,
42
+ CoreInngestHandler,
43
+ CoreInngestTrigger,
44
+ } from './create-inngest-middleware'
@@ -0,0 +1,398 @@
1
+ import {
2
+ ContentResourceResource,
3
+ Entitlement,
4
+ MerchantCharge,
5
+ UpgradableProduct,
6
+ } from '@coursebuilder/core/schemas'
7
+ import { AttributionSnapshotPayload } from '@coursebuilder/core/schemas/attribution-snapshot'
8
+ import { type ContentResource } from '@coursebuilder/core/schemas/content-resource-schema'
9
+ import { Coupon } from '@coursebuilder/core/schemas/coupon-schema'
10
+ import { MerchantCoupon } from '@coursebuilder/core/schemas/merchant-coupon-schema'
11
+ import { MerchantCustomer } from '@coursebuilder/core/schemas/merchant-customer-schema'
12
+ import { MerchantEvents } from '@coursebuilder/core/schemas/merchant-events-schema'
13
+ import { MerchantProduct } from '@coursebuilder/core/schemas/merchant-product-schema'
14
+ import { MerchantSession } from '@coursebuilder/core/schemas/merchant-session'
15
+ import { Price } from '@coursebuilder/core/schemas/price-schema'
16
+ import { Product } from '@coursebuilder/core/schemas/product-schema'
17
+ import { Purchase } from '@coursebuilder/core/schemas/purchase-schema'
18
+ import {
19
+ PurchaseUserTransfer,
20
+ PurchaseUserTransferState,
21
+ } from '@coursebuilder/core/schemas/purchase-user-transfer-schema'
22
+ import {
23
+ ModuleProgress,
24
+ ResourceProgress,
25
+ } from '@coursebuilder/core/schemas/resource-progress-schema'
26
+ import { User } from '@coursebuilder/core/schemas/user-schema'
27
+
28
+ import type { ServerAdapter } from './adapter'
29
+
30
+ export const mockServerAdapter: ServerAdapter = {
31
+ client: null,
32
+ getPersonalOrganization: async () => null,
33
+ createPersonalOrganization: async () => {
34
+ throw new Error('Method not implemented.')
35
+ },
36
+ transferPurchaseToUser: async () => {
37
+ return null
38
+ },
39
+ redeemFullPriceCoupon: async () => {
40
+ return {} as any
41
+ },
42
+ archiveProduct: async (productId) => {
43
+ return {} as any
44
+ },
45
+ updateProduct: async (product) => {
46
+ return {} as any
47
+ },
48
+ createProduct: async (product) => {
49
+ return {} as any
50
+ },
51
+ createPurchaseTransfer: async () => {
52
+ return Promise.resolve()
53
+ },
54
+ createCoupon: async (input) => {
55
+ return []
56
+ },
57
+ addResourceToProduct: async (options) => {
58
+ return null
59
+ },
60
+ incrementCouponUsedCount(_) {
61
+ return Promise.resolve()
62
+ },
63
+ getExistingNonBulkValidPurchasesOfProduct: async () => {
64
+ return []
65
+ },
66
+ getMerchantPriceForProductId: async (productId) => null,
67
+ getMerchantProductForProductId: async (productId) => null,
68
+ getMerchantAccount: async () => null,
69
+ createMerchantCustomer: async () => null,
70
+ createMerchantCoupon: async () => ({}) as MerchantCoupon,
71
+ getMerchantCustomerForUserId: async () => null,
72
+ getUpgradableProducts: async () => [],
73
+ createPurchase: async (options) => {
74
+ throw new Error('Method not implemented.')
75
+ },
76
+ availableUpgradesForProduct(
77
+ purchases: any,
78
+ productId: string,
79
+ ): Promise<
80
+ {
81
+ upgradableTo: { id: string; name: string }
82
+ upgradableFrom: { id: string; name: string }
83
+ }[]
84
+ > {
85
+ return Promise.resolve([])
86
+ },
87
+ clearLessonProgressForUser(options: {
88
+ userId: string
89
+ lessons: { id: string; slug: string }[]
90
+ }): Promise<void> {
91
+ return Promise.resolve(undefined)
92
+ },
93
+ completeLessonProgressForUser(options: {
94
+ userId: string
95
+ lessonId?: string
96
+ }): Promise<ResourceProgress | null> {
97
+ return Promise.resolve(null)
98
+ },
99
+ couponForIdOrCode(options: {
100
+ code?: string
101
+ couponId?: string
102
+ }): Promise<(Coupon & { merchantCoupon: MerchantCoupon }) | null> {
103
+ return Promise.resolve(null)
104
+ },
105
+ createMerchantChargeAndPurchase(options: {
106
+ userId: string
107
+ productId: string
108
+ stripeChargeId: string
109
+ stripeCouponId?: string
110
+ merchantAccountId: string
111
+ merchantProductId: string
112
+ merchantCustomerId: string
113
+ stripeChargeAmount: number
114
+ quantity?: number
115
+ bulk?: boolean
116
+ checkoutSessionId: string
117
+ appliedPPPStripeCouponId?: string
118
+ upgradedFromPurchaseId?: string
119
+ usedCouponId?: string
120
+ country?: string
121
+ organizationId?: string
122
+ purchaseBenefitsTransport?: string
123
+ attributionSnapshot?: AttributionSnapshotPayload
124
+ }): Promise<Purchase> {
125
+ throw new Error('Method not implemented.')
126
+ },
127
+ findOrCreateMerchantCustomer(options: {
128
+ user: User
129
+ identifier: string
130
+ merchantAccountId: string
131
+ }): Promise<MerchantCustomer | null> {
132
+ return Promise.resolve(null)
133
+ },
134
+ createMerchantEvent(options: {
135
+ merchantAccountId: string
136
+ identifier: string
137
+ payload: Record<string, any>
138
+ }): Promise<MerchantEvents> {
139
+ throw new Error('Method not implemented.')
140
+ },
141
+ getMerchantEventByIdentifier(
142
+ identifier: string,
143
+ ): Promise<MerchantEvents | null> {
144
+ return Promise.resolve(null)
145
+ },
146
+ getMerchantEventsByAccount(
147
+ merchantAccountId: string,
148
+ ): Promise<MerchantEvents[]> {
149
+ return Promise.resolve([])
150
+ },
151
+ findOrCreateUser(
152
+ email: string,
153
+ name?: string | null,
154
+ ): Promise<{
155
+ user: User
156
+ isNewUser: boolean
157
+ }> {
158
+ throw new Error('Method not implemented.')
159
+ },
160
+ getCoupon(couponIdOrCode: string): Promise<Coupon | null> {
161
+ return Promise.resolve(null)
162
+ },
163
+ getCouponWithBulkPurchases(couponId: string): Promise<
164
+ | (Coupon & {
165
+ redeemedBulkCouponPurchases: Purchase[]
166
+ bulkPurchase?: Purchase | null
167
+ })
168
+ | null
169
+ > {
170
+ return Promise.resolve(null)
171
+ },
172
+ getDefaultCoupon(productIds?: string[]): Promise<{
173
+ defaultMerchantCoupon: MerchantCoupon
174
+ defaultCoupon: Coupon
175
+ } | null> {
176
+ return Promise.resolve(null)
177
+ },
178
+ getLessonProgressCountsByDate(): Promise<
179
+ {
180
+ count: number
181
+ completedAt: string
182
+ }[]
183
+ > {
184
+ return Promise.resolve([])
185
+ },
186
+ getLessonProgressForUser(userId: string): Promise<ResourceProgress[]> {
187
+ return Promise.resolve([])
188
+ },
189
+ getModuleProgressForUser(
190
+ userId: string,
191
+ moduleId: string,
192
+ ): Promise<ModuleProgress> {
193
+ return Promise.resolve({
194
+ completedLessons: [],
195
+ nextResource: null,
196
+ percentCompleted: 0,
197
+ completedLessonsCount: 0,
198
+ totalLessonsCount: 0,
199
+ })
200
+ },
201
+ getLessonProgresses(): Promise<ResourceProgress[]> {
202
+ return Promise.resolve([])
203
+ },
204
+ getMerchantCharge(merchantChargeId: string): Promise<MerchantCharge | null> {
205
+ return Promise.resolve(null)
206
+ },
207
+ getMerchantCouponForTypeAndPercent(params: {
208
+ type: string
209
+ percentageDiscount: number
210
+ }): Promise<MerchantCoupon | null> {
211
+ return Promise.resolve(null)
212
+ },
213
+ getMerchantCouponsForTypeAndPercent(params: {
214
+ type: string
215
+ percentageDiscount: number
216
+ }): Promise<MerchantCoupon[]> {
217
+ return Promise.resolve([])
218
+ },
219
+ getMerchantCouponForTypeAndAmount(params: {
220
+ type: string
221
+ amountDiscount: number
222
+ }): Promise<MerchantCoupon | null> {
223
+ return Promise.resolve(null)
224
+ },
225
+ getMerchantCoupon(merchantCouponId: string): Promise<MerchantCoupon | null> {
226
+ return Promise.resolve(null)
227
+ },
228
+ getMerchantProduct(stripeProductId: string): Promise<MerchantProduct | null> {
229
+ return Promise.resolve(null)
230
+ },
231
+ getPrice(productId: string): Promise<Price | null> {
232
+ return Promise.resolve(null)
233
+ },
234
+ getPriceForProduct(productId: string): Promise<Price | null> {
235
+ return Promise.resolve(null)
236
+ },
237
+ getProduct(
238
+ productId?: string,
239
+ withResources: boolean = true,
240
+ ): Promise<Product | null> {
241
+ return Promise.resolve(null)
242
+ },
243
+ getProductResources(productId: string): Promise<ContentResource[] | null> {
244
+ return Promise.resolve(null)
245
+ },
246
+ getPurchaseCountForProduct(productId: string): Promise<number> {
247
+ return Promise.resolve(0)
248
+ },
249
+ getPurchase(purchaseId: string): Promise<Purchase | null> {
250
+ return Promise.resolve(null)
251
+ },
252
+ getPurchaseDetails(
253
+ purchaseId: string,
254
+ userId: string,
255
+ ): Promise<{
256
+ purchase?: Purchase
257
+ existingPurchase?: Purchase | null
258
+ availableUpgrades: UpgradableProduct[]
259
+ }> {
260
+ return Promise.resolve({ availableUpgrades: [] })
261
+ },
262
+ getPurchaseForStripeCharge(stripeChargeId: string): Promise<Purchase | null> {
263
+ return Promise.resolve(null)
264
+ },
265
+ getPurchaseByCheckoutSessionId(
266
+ checkoutSessionId: string,
267
+ ): Promise<Purchase | null> {
268
+ return Promise.resolve(null)
269
+ },
270
+ getPurchaseUserTransferById(options: { id: string }): Promise<
271
+ | (PurchaseUserTransfer & {
272
+ sourceUser: User
273
+ targetUser: User | null
274
+ purchase: Purchase
275
+ })
276
+ | null
277
+ > {
278
+ return Promise.resolve(null)
279
+ },
280
+ getPurchaseWithUser(purchaseId: string): Promise<
281
+ | (Purchase & {
282
+ user: User
283
+ })
284
+ | null
285
+ > {
286
+ return Promise.resolve(null)
287
+ },
288
+ getUserWithPurchasersByEmail(email: string): Promise<any | null> {
289
+ return Promise.resolve(null)
290
+ },
291
+ getPurchasesForUser(userId?: string): Promise<Purchase[]> {
292
+ return Promise.resolve([])
293
+ },
294
+ getEntitlementsForUser(params: {
295
+ userId: string
296
+ sourceType?: string
297
+ entitlementType?: string
298
+ }): Promise<Entitlement[]> {
299
+ return Promise.resolve([])
300
+ },
301
+ getEntitlementTypeByName(
302
+ name: string,
303
+ ): Promise<{ id: string; name: string } | null> {
304
+ return Promise.resolve(null)
305
+ },
306
+ getUserById(userId: string): Promise<User | null> {
307
+ return Promise.resolve(null)
308
+ },
309
+ pricesOfPurchasesTowardOneBundle(options: {
310
+ userId: string | undefined
311
+ bundleId: string
312
+ }): Promise<Price[]> {
313
+ return Promise.resolve([])
314
+ },
315
+ toggleLessonProgressForUser(options: {
316
+ userId: string
317
+ lessonId?: string
318
+ lessonSlug?: string
319
+ }): Promise<ResourceProgress | null> {
320
+ return Promise.resolve(null)
321
+ },
322
+ transferPurchasesToNewUser(options: {
323
+ merchantCustomerId: string
324
+ userId: string
325
+ }): Promise<unknown> {
326
+ return Promise.resolve(undefined)
327
+ },
328
+ updatePurchaseStatusForCharge(
329
+ chargeId: string,
330
+ status: 'Valid' | 'Refunded' | 'Disputed' | 'Banned' | 'Restricted',
331
+ ): Promise<Purchase | undefined> {
332
+ return Promise.resolve(undefined)
333
+ },
334
+ updatePurchaseUserTransferTransferState(options: {
335
+ id: string
336
+ transferState: PurchaseUserTransferState
337
+ }): Promise<PurchaseUserTransfer | null> {
338
+ return Promise.resolve(null)
339
+ },
340
+ addResourceToResource: async (options) => {
341
+ return {} as ContentResourceResource
342
+ },
343
+ removeResourceFromResource: async (options) => {
344
+ return null
345
+ },
346
+ createContentResource: async (resource) => {
347
+ return resource as ContentResource
348
+ },
349
+ getEvent: async (_) => {
350
+ return null
351
+ },
352
+ createEvent: async (_) => {
353
+ return null
354
+ },
355
+ createEventSeries: async (_) => {
356
+ return { eventSeries: null as any, childEvents: [] }
357
+ },
358
+ createCohort: async (_) => {
359
+ return { cohort: null as any, product: undefined }
360
+ },
361
+ createWorkshop: async (_) => {
362
+ return {
363
+ workshop: null as any,
364
+ sections: [],
365
+ lessons: [],
366
+ product: undefined,
367
+ }
368
+ },
369
+ getContentResource: async (_) => {
370
+ return null
371
+ },
372
+ getVideoResource: async (_) => {
373
+ return null
374
+ },
375
+ getParentResourceOfVideoResource: async (_) => {
376
+ return null
377
+ },
378
+ updateContentResourceFields(_) {
379
+ return null
380
+ },
381
+ createOrganization: async () => null,
382
+ getOrganization: async () => null,
383
+ addMemberToOrganization: async () => null,
384
+ removeMemberFromOrganization: async () => undefined,
385
+ addRoleForMember: async () => undefined,
386
+ removeRoleForMember: async () => undefined,
387
+ getMembershipsForUser: async () => [],
388
+ getOrganizationMembers: async () => [],
389
+ getMerchantSubscription: async () => null,
390
+ createMerchantSubscription: async () => null,
391
+ updateMerchantSubscription: async () => null,
392
+ deleteMerchantSubscription: async () => undefined,
393
+ createMerchantSession: async () => Promise.resolve({} as MerchantSession),
394
+ createSubscription: async () => null,
395
+ getSubscriptionForStripeId: async () => null,
396
+ updateSubscriptionStatus: async () => undefined,
397
+ getPurchasesForBulkCouponId: async () => [],
398
+ }
@@ -0,0 +1,56 @@
1
+ import type {
2
+ PaymentsAdapter,
3
+ PaymentsProviderConfig,
4
+ } from '@coursebuilder/core/types'
5
+
6
+ const mockPaymentsAdapter: PaymentsAdapter = {
7
+ getCouponPercentOff: async () => 0,
8
+ getCouponAmountOff: async () => 0,
9
+ createCoupon: async () => 'mock-coupon-id',
10
+ createPromotionCode: async () => 'mock-promotion-code-id',
11
+ createCheckoutSession: async () => 'mock-checkout-session-id',
12
+ createCustomer: async () => 'mock-customer-id',
13
+ verifyWebhookSignature: async () => true,
14
+ getCheckoutSession: async () => ({ id: 'mock-checkout-session-id' }) as any,
15
+ getCustomer: async () => ({ id: 'mock-customer-id' }) as any,
16
+ updateCustomer: async () => {},
17
+ refundCharge: async () => ({}) as any,
18
+ updateProduct: async () => {},
19
+ updatePrice: async () => {},
20
+ getProduct: async () => ({}) as any,
21
+ getPrice: async () => ({}) as any,
22
+ createPrice: async () => ({}) as any,
23
+ createProduct: async () => ({}) as any,
24
+ getSubscription: async () => ({}) as any,
25
+ getBillingPortalUrl: async () => 'mock-billing-portal-url',
26
+ updateSubscriptionItemQuantity: async () => ({}) as any,
27
+ }
28
+
29
+ export const mockPaymentProvider: PaymentsProviderConfig = {
30
+ id: 'mock-stripe',
31
+ name: 'Mock Stripe',
32
+ type: 'payment',
33
+ options: {
34
+ errorRedirectUrl: 'mock-error-redirect-url',
35
+ cancelUrl: 'mock-cancel-url',
36
+ baseSuccessUrl: 'mock-base-success-url',
37
+ paymentsAdapter: mockPaymentsAdapter,
38
+ },
39
+ getSubscriptionInfo: async () => ({}) as any,
40
+ getPurchaseInfo: async () => ({}) as any,
41
+ createCheckoutSession: async () => ({
42
+ redirect: 'mock-checkout-session-id',
43
+ status: 303,
44
+ }),
45
+ getCustomer: async () => ({ id: 'mock-customer-id' }) as any,
46
+ updateCustomer: async () => {},
47
+ refundCharge: async () => ({}) as any,
48
+ updateProduct: async () => {},
49
+ updatePrice: async () => {},
50
+ getProduct: async () => ({}) as any,
51
+ getPrice: async () => ({}) as any,
52
+ createPrice: async () => ({}) as any,
53
+ createProduct: async () => ({}) as any,
54
+ getSubscription: async () => ({}) as any,
55
+ getBillingPortalUrl: async () => 'mock-billing-portal-url',
56
+ }