@edx/frontend-app-subscription-manage 1.3.2 → 1.4.0

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 (226) hide show
  1. package/dist/app.js +2 -2
  2. package/dist/app.js.map +1 -1
  3. package/dist/components/ActiveSubscription/ActiveSubscription.d.ts +7 -0
  4. package/dist/components/ActiveSubscription/ActiveSubscription.js +24 -0
  5. package/dist/components/ActiveSubscription/ActiveSubscription.js.map +1 -0
  6. package/dist/components/BecomeSubscriber/BecomeSubscriber.d.ts +7 -0
  7. package/dist/components/BecomeSubscriber/BecomeSubscriber.js +19 -0
  8. package/dist/components/BecomeSubscriber/BecomeSubscriber.js.map +1 -0
  9. package/dist/components/CancelConfirmation/CancelConfirmation.d.ts +12 -0
  10. package/dist/components/CancelConfirmation/CancelConfirmation.js +21 -0
  11. package/dist/components/CancelConfirmation/CancelConfirmation.js.map +1 -0
  12. package/dist/components/CancelSuccess/CancelSuccess.d.ts +7 -0
  13. package/dist/components/CancelSuccess/CancelSuccess.js +17 -0
  14. package/dist/components/CancelSuccess/CancelSuccess.js.map +1 -0
  15. package/dist/components/CanceledSubscription/CanceledSubscription.d.ts +13 -0
  16. package/dist/components/CanceledSubscription/CanceledSubscription.js +27 -0
  17. package/dist/components/CanceledSubscription/CanceledSubscription.js.map +1 -0
  18. package/dist/components/EnrolledCoursesList/EnrolledCoursesList.d.ts +8 -0
  19. package/dist/components/EnrolledCoursesList/EnrolledCoursesList.js +20 -0
  20. package/dist/components/EnrolledCoursesList/EnrolledCoursesList.js.map +1 -0
  21. package/dist/components/HelpFooter/HelpFooter.d.ts +3 -0
  22. package/dist/components/HelpFooter/HelpFooter.js +12 -0
  23. package/dist/components/HelpFooter/HelpFooter.js.map +1 -0
  24. package/dist/components/OrderHistoryHeader/OrderHistoryHeader.d.ts +3 -0
  25. package/dist/components/OrderHistoryHeader/OrderHistoryHeader.js +9 -0
  26. package/dist/components/OrderHistoryHeader/OrderHistoryHeader.js.map +1 -0
  27. package/dist/components/PaymentHistory/PaymentHistory.d.ts +10 -0
  28. package/dist/components/PaymentHistory/PaymentHistory.js +23 -0
  29. package/dist/components/PaymentHistory/PaymentHistory.js.map +1 -0
  30. package/dist/components/RenewSubscriptionModal/RenewSubscriptionModal.d.ts +17 -0
  31. package/dist/components/RenewSubscriptionModal/RenewSubscriptionModal.js +63 -0
  32. package/dist/components/RenewSubscriptionModal/RenewSubscriptionModal.js.map +1 -0
  33. package/dist/components/ResubscribeCard/ResubscribeCard.d.ts +9 -0
  34. package/dist/components/ResubscribeCard/ResubscribeCard.js +25 -0
  35. package/dist/components/ResubscribeCard/ResubscribeCard.js.map +1 -0
  36. package/dist/components/SubscriptionTabs/SubscriptionTabs.d.ts +8 -0
  37. package/dist/components/SubscriptionTabs/SubscriptionTabs.js +9 -0
  38. package/dist/components/SubscriptionTabs/SubscriptionTabs.js.map +1 -0
  39. package/dist/components/UpdatePaymentMethodModal/UpdatePaymentMethodModal.d.ts +9 -0
  40. package/dist/components/UpdatePaymentMethodModal/UpdatePaymentMethodModal.js +135 -0
  41. package/dist/components/UpdatePaymentMethodModal/UpdatePaymentMethodModal.js.map +1 -0
  42. package/dist/components/messages.d.ts +473 -0
  43. package/dist/components/messages.js +482 -0
  44. package/dist/components/messages.js.map +1 -0
  45. package/dist/constants.d.ts +14 -56
  46. package/dist/constants.js +23 -272
  47. package/dist/constants.js.map +1 -1
  48. package/dist/data/hooks/keys.d.ts +8 -13
  49. package/dist/data/hooks/keys.js +8 -13
  50. package/dist/data/hooks/keys.js.map +1 -1
  51. package/dist/data/hooks/useManageQueries.d.ts +37 -0
  52. package/dist/data/hooks/useManageQueries.js +206 -0
  53. package/dist/data/hooks/useManageQueries.js.map +1 -0
  54. package/dist/data/services/subs/urls.d.ts +2 -2
  55. package/dist/data/services/subs/urls.js.map +1 -1
  56. package/dist/data/services/subscription/cancelSubscription.d.ts +6 -0
  57. package/dist/data/services/subscription/cancelSubscription.js +31 -0
  58. package/dist/data/services/subscription/cancelSubscription.js.map +1 -0
  59. package/dist/data/services/subscription/getBillingPlans.d.ts +3 -0
  60. package/dist/{utils/fetchBillingPlans.js → data/services/subscription/getBillingPlans.js} +10 -21
  61. package/dist/data/services/subscription/getBillingPlans.js.map +1 -0
  62. package/dist/data/services/subscription/getIsCurrentUserSubscriber.d.ts +3 -0
  63. package/dist/data/services/subscription/getIsCurrentUserSubscriber.js +35 -0
  64. package/dist/data/services/subscription/getIsCurrentUserSubscriber.js.map +1 -0
  65. package/dist/data/services/subscription/getPaymentHistory.d.ts +6 -0
  66. package/dist/data/services/subscription/getPaymentHistory.js +65 -0
  67. package/dist/data/services/subscription/getPaymentHistory.js.map +1 -0
  68. package/dist/data/services/subscription/getSubscriptionEnrollments.d.ts +7 -0
  69. package/dist/data/services/subscription/getSubscriptionEnrollments.js +98 -0
  70. package/dist/data/services/subscription/getSubscriptionEnrollments.js.map +1 -0
  71. package/dist/data/services/subscription/getSubscriptionPaymentMethod.d.ts +8 -0
  72. package/dist/data/services/subscription/getSubscriptionPaymentMethod.js +42 -0
  73. package/dist/data/services/subscription/getSubscriptionPaymentMethod.js.map +1 -0
  74. package/dist/data/services/subscription/reactivateSubscription.d.ts +6 -0
  75. package/dist/data/services/subscription/reactivateSubscription.js +30 -0
  76. package/dist/data/services/subscription/reactivateSubscription.js.map +1 -0
  77. package/dist/data/services/subscription/updateSubscriptionPaymentMethod.d.ts +10 -0
  78. package/dist/data/services/subscription/updateSubscriptionPaymentMethod.js +31 -0
  79. package/dist/data/services/subscription/updateSubscriptionPaymentMethod.js.map +1 -0
  80. package/dist/icons/ExternalLinkIcon.d.ts +6 -0
  81. package/dist/icons/ExternalLinkIcon.js +18 -0
  82. package/dist/icons/ExternalLinkIcon.js.map +1 -0
  83. package/dist/icons/index.d.ts +1 -0
  84. package/dist/icons/index.js +2 -0
  85. package/dist/icons/index.js.map +1 -0
  86. package/dist/manageSubscriptionPage/CancelSubscriptionPage.d.ts +3 -0
  87. package/dist/manageSubscriptionPage/CancelSubscriptionPage.js +53 -0
  88. package/dist/manageSubscriptionPage/CancelSubscriptionPage.js.map +1 -0
  89. package/dist/manageSubscriptionPage/CancelSuccessPage.d.ts +3 -0
  90. package/dist/manageSubscriptionPage/CancelSuccessPage.js +24 -0
  91. package/dist/manageSubscriptionPage/CancelSuccessPage.js.map +1 -0
  92. package/dist/manageSubscriptionPage/ManageSubscriptionPage.d.ts +3 -0
  93. package/dist/manageSubscriptionPage/ManageSubscriptionPage.js +87 -0
  94. package/dist/manageSubscriptionPage/ManageSubscriptionPage.js.map +1 -0
  95. package/dist/messages.js +2 -2
  96. package/dist/messages.js.map +1 -1
  97. package/dist/routes.d.ts +9 -2
  98. package/dist/routes.js +26 -6
  99. package/dist/routes.js.map +1 -1
  100. package/dist/style.scss +1 -14
  101. package/dist/styles/components/manageSubscription.scss +454 -0
  102. package/dist/types.d.ts +57 -201
  103. package/dist/types.js +3 -0
  104. package/dist/types.js.map +1 -1
  105. package/dist/utils/billingDetails.d.ts +3 -20
  106. package/dist/utils/billingDetails.js +4 -25
  107. package/dist/utils/billingDetails.js.map +1 -1
  108. package/dist/utils/edxSession.d.ts +18 -0
  109. package/dist/utils/edxSession.js +72 -0
  110. package/dist/utils/edxSession.js.map +1 -0
  111. package/dist/utils/formatDate.d.ts +16 -0
  112. package/dist/utils/formatDate.js +69 -0
  113. package/dist/utils/formatDate.js.map +1 -0
  114. package/dist/utils/graphqlClient.d.ts +9 -10
  115. package/dist/utils/graphqlClient.js +22 -11
  116. package/dist/utils/graphqlClient.js.map +1 -1
  117. package/dist/utils/invoiceAmount.d.ts +22 -0
  118. package/dist/utils/invoiceAmount.js +59 -0
  119. package/dist/utils/invoiceAmount.js.map +1 -0
  120. package/dist/utils/queries.d.ts +38 -33
  121. package/dist/utils/queries.js +83 -123
  122. package/dist/utils/queries.js.map +1 -1
  123. package/dist/utils/subscriptionView.d.ts +15 -0
  124. package/dist/utils/subscriptionView.js +50 -0
  125. package/dist/utils/subscriptionView.js.map +1 -0
  126. package/dist/utils/urls.d.ts +13 -0
  127. package/dist/utils/urls.js +52 -0
  128. package/dist/utils/urls.js.map +1 -0
  129. package/package.json +7 -2
  130. package/dist/checkoutPage/CheckoutPage.d.ts +0 -3
  131. package/dist/checkoutPage/CheckoutPage.js +0 -30
  132. package/dist/checkoutPage/CheckoutPage.js.map +0 -1
  133. package/dist/components/BrandMarks/BrandMarks.d.ts +0 -3
  134. package/dist/components/BrandMarks/BrandMarks.js +0 -9
  135. package/dist/components/BrandMarks/BrandMarks.js.map +0 -1
  136. package/dist/components/CartSummary/CartSummary.d.ts +0 -21
  137. package/dist/components/CartSummary/CartSummary.js +0 -30
  138. package/dist/components/CartSummary/CartSummary.js.map +0 -1
  139. package/dist/components/CartSummary/Messages.d.ts +0 -73
  140. package/dist/components/CartSummary/Messages.js +0 -76
  141. package/dist/components/CartSummary/Messages.js.map +0 -1
  142. package/dist/components/Checkout/Checkout.d.ts +0 -4
  143. package/dist/components/Checkout/Checkout.js +0 -40
  144. package/dist/components/Checkout/Checkout.js.map +0 -1
  145. package/dist/components/CheckoutGate/CheckoutGate.d.ts +0 -7
  146. package/dist/components/CheckoutGate/CheckoutGate.js +0 -35
  147. package/dist/components/CheckoutGate/CheckoutGate.js.map +0 -1
  148. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.d.ts +0 -9
  149. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.js +0 -31
  150. package/dist/components/CourseEnrollmentCard/CourseEnrollmentCard.js.map +0 -1
  151. package/dist/components/CourseEnrollmentCard/Messages.d.ts +0 -33
  152. package/dist/components/CourseEnrollmentCard/Messages.js +0 -35
  153. package/dist/components/CourseEnrollmentCard/Messages.js.map +0 -1
  154. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.d.ts +0 -13
  155. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.js +0 -11
  156. package/dist/components/EdxUnlimitedBanner/EdxUnlimitedBanner.js.map +0 -1
  157. package/dist/components/EnrollmentSummary/EnrollmentSummary.d.ts +0 -15
  158. package/dist/components/EnrollmentSummary/EnrollmentSummary.js +0 -21
  159. package/dist/components/EnrollmentSummary/EnrollmentSummary.js.map +0 -1
  160. package/dist/components/EnrollmentSummary/Messages.d.ts +0 -33
  161. package/dist/components/EnrollmentSummary/Messages.js +0 -35
  162. package/dist/components/EnrollmentSummary/Messages.js.map +0 -1
  163. package/dist/components/PaymentFields/PaymentFields.d.ts +0 -9
  164. package/dist/components/PaymentFields/PaymentFields.js +0 -7
  165. package/dist/components/PaymentFields/PaymentFields.js.map +0 -1
  166. package/dist/components/PaymentForm/Messages.d.ts +0 -88
  167. package/dist/components/PaymentForm/Messages.js +0 -95
  168. package/dist/components/PaymentForm/Messages.js.map +0 -1
  169. package/dist/components/PaymentForm/PaymentForm.d.ts +0 -21
  170. package/dist/components/PaymentForm/PaymentForm.js +0 -69
  171. package/dist/components/PaymentForm/PaymentForm.js.map +0 -1
  172. package/dist/components/StatusScreens/Messages.d.ts +0 -103
  173. package/dist/components/StatusScreens/Messages.js +0 -108
  174. package/dist/components/StatusScreens/Messages.js.map +0 -1
  175. package/dist/components/StatusScreens/StatusScreens.d.ts +0 -23
  176. package/dist/components/StatusScreens/StatusScreens.js +0 -25
  177. package/dist/components/StatusScreens/StatusScreens.js.map +0 -1
  178. package/dist/data/hooks/useCheckout.d.ts +0 -57
  179. package/dist/data/hooks/useCheckout.js +0 -249
  180. package/dist/data/hooks/useCheckout.js.map +0 -1
  181. package/dist/data/hooks/useCheckoutGate.d.ts +0 -15
  182. package/dist/data/hooks/useCheckoutGate.js +0 -39
  183. package/dist/data/hooks/useCheckoutGate.js.map +0 -1
  184. package/dist/data/hooks/useCheckoutMutations.d.ts +0 -16
  185. package/dist/data/hooks/useCheckoutMutations.js +0 -131
  186. package/dist/data/hooks/useCheckoutMutations.js.map +0 -1
  187. package/dist/data/hooks/useCheckoutQueries.d.ts +0 -30
  188. package/dist/data/hooks/useCheckoutQueries.js +0 -97
  189. package/dist/data/hooks/useCheckoutQueries.js.map +0 -1
  190. package/dist/styles/components/brandMarks.scss +0 -54
  191. package/dist/styles/components/cartSummary.scss +0 -18
  192. package/dist/styles/components/checkout.scss +0 -29
  193. package/dist/styles/components/checkoutStepper.scss +0 -9
  194. package/dist/styles/components/courseEnrollmentCard.scss +0 -38
  195. package/dist/styles/components/edxUnlimitedBanner.scss +0 -138
  196. package/dist/styles/components/enrollmentSummary.scss +0 -13
  197. package/dist/styles/components/paymentFields.scss +0 -15
  198. package/dist/styles/components/paymentForm.scss +0 -105
  199. package/dist/styles/components/statusScreens.scss +0 -29
  200. package/dist/styles/components/successScreen.scss +0 -0
  201. package/dist/utils/auth.d.ts +0 -7
  202. package/dist/utils/auth.js +0 -28
  203. package/dist/utils/auth.js.map +0 -1
  204. package/dist/utils/bootstrapApi.d.ts +0 -20
  205. package/dist/utils/bootstrapApi.js +0 -142
  206. package/dist/utils/bootstrapApi.js.map +0 -1
  207. package/dist/utils/cartApi.d.ts +0 -16
  208. package/dist/utils/cartApi.js +0 -118
  209. package/dist/utils/cartApi.js.map +0 -1
  210. package/dist/utils/checkout.d.ts +0 -6
  211. package/dist/utils/checkout.js +0 -28
  212. package/dist/utils/checkout.js.map +0 -1
  213. package/dist/utils/fetchActiveSubscriptions.d.ts +0 -4
  214. package/dist/utils/fetchActiveSubscriptions.js +0 -36
  215. package/dist/utils/fetchActiveSubscriptions.js.map +0 -1
  216. package/dist/utils/fetchBillingPlans.d.ts +0 -2
  217. package/dist/utils/fetchBillingPlans.js.map +0 -1
  218. package/dist/utils/index.d.ts +0 -3
  219. package/dist/utils/index.js +0 -17
  220. package/dist/utils/index.js.map +0 -1
  221. package/dist/utils/provision.d.ts +0 -25
  222. package/dist/utils/provision.js +0 -95
  223. package/dist/utils/provision.js.map +0 -1
  224. package/dist/utils/stripe.d.ts +0 -7
  225. package/dist/utils/stripe.js +0 -43
  226. package/dist/utils/stripe.js.map +0 -1
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Hooks for Viax session, subscriber status, enrollments, and cancel mutation.
3
+ */
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ import { useEffect, useMemo } from 'react';
14
+ import { useMutation, useQuery, useQueryClient, } from '@tanstack/react-query';
15
+ import { getAppConfig, getSiteConfig } from '@openedx/frontend-base';
16
+ import { appId } from '../../constants';
17
+ import { createGqlClient } from '../../utils/graphqlClient';
18
+ import { fetchEdxSession, getEdxSessionUrl } from '../../utils/edxSession';
19
+ import { cancelSubscription } from '../services/subscription/cancelSubscription';
20
+ import { getBillingPlans } from '../services/subscription/getBillingPlans';
21
+ import { getIsCurrentUserSubscriber } from '../services/subscription/getIsCurrentUserSubscriber';
22
+ import { getPaymentHistory } from '../services/subscription/getPaymentHistory';
23
+ import { getSubscriptionEnrollments } from '../services/subscription/getSubscriptionEnrollments';
24
+ import { getSubscriptionPaymentMethod, } from '../services/subscription/getSubscriptionPaymentMethod';
25
+ import { reactivateSubscription } from '../services/subscription/reactivateSubscription';
26
+ import { updateSubscriptionPaymentMethod, } from '../services/subscription/updateSubscriptionPaymentMethod';
27
+ import { manageKeys } from './keys';
28
+ /** Shared Viax GraphQL client for the manage MFE (singleton per API URL). */
29
+ let cachedClient = null;
30
+ let cachedApiUrl;
31
+ export function useViaxClient() {
32
+ const config = getAppConfig(appId);
33
+ const apiUrl = config.VIAX_API_URL;
34
+ return useMemo(() => {
35
+ if (!apiUrl) {
36
+ return null;
37
+ }
38
+ if (cachedClient && cachedApiUrl === apiUrl) {
39
+ return cachedClient;
40
+ }
41
+ cachedClient = createGqlClient({ apiUrl });
42
+ cachedApiUrl = apiUrl;
43
+ return cachedClient;
44
+ }, [apiUrl]);
45
+ }
46
+ /** Exchange edX session cookies for a Viax token. */
47
+ export function useViaxSessionQuery() {
48
+ const sessionUrl = getSiteConfig().lmsBaseUrl
49
+ ? getEdxSessionUrl()
50
+ : null;
51
+ return useQuery({
52
+ queryKey: manageKeys.viaxSession(),
53
+ enabled: !!sessionUrl,
54
+ queryFn: () => fetchEdxSession(sessionUrl),
55
+ staleTime: 5 * 60 * 1000,
56
+ retry: 1,
57
+ });
58
+ }
59
+ /**
60
+ * Applies the Viax token from the session query onto the GraphQL client.
61
+ */
62
+ export function useViaxSession(client) {
63
+ var _a, _b;
64
+ const sessionQuery = useViaxSessionQuery();
65
+ useEffect(() => {
66
+ var _a;
67
+ if (client && ((_a = sessionQuery.data) === null || _a === void 0 ? void 0 : _a.viaxToken)) {
68
+ client.setToken(sessionQuery.data.viaxToken);
69
+ }
70
+ }, [client, (_a = sessionQuery.data) === null || _a === void 0 ? void 0 : _a.viaxToken]);
71
+ return {
72
+ sessionReady: Boolean(client && sessionQuery.isSuccess && ((_b = sessionQuery.data) === null || _b === void 0 ? void 0 : _b.viaxToken)),
73
+ isSessionLoading: sessionQuery.isPending,
74
+ isSessionError: sessionQuery.isError,
75
+ sessionError: sessionQuery.error,
76
+ };
77
+ }
78
+ /** Current user's subscription context. */
79
+ export function useIsSubscriberQuery(client, sessionReady) {
80
+ return useQuery({
81
+ queryKey: manageKeys.isSubscriber(),
82
+ enabled: !!client && sessionReady,
83
+ queryFn: () => getIsCurrentUserSubscriber(client.gql),
84
+ staleTime: 2 * 60 * 1000,
85
+ retry: 1,
86
+ });
87
+ }
88
+ /** Available monthly / annual billing plans for price display. */
89
+ export function useBillingPlansQuery(client, sessionReady) {
90
+ return useQuery({
91
+ queryKey: manageKeys.billingPlans(),
92
+ enabled: !!client && sessionReady,
93
+ queryFn: () => getBillingPlans(client.gql),
94
+ staleTime: 10 * 60 * 1000,
95
+ retry: 1,
96
+ });
97
+ }
98
+ /** Enrollments for cancel confirmation. */
99
+ export function useSubscriptionEnrollmentsQuery(client, sessionReady, subscriptionBiIds) {
100
+ const ids = (Array.isArray(subscriptionBiIds)
101
+ ? subscriptionBiIds
102
+ : [subscriptionBiIds !== null && subscriptionBiIds !== void 0 ? subscriptionBiIds : ''])
103
+ .map((id) => (id !== null && id !== void 0 ? id : '').trim())
104
+ .filter(Boolean);
105
+ const key = ids.join(',') || 'none';
106
+ return useQuery({
107
+ queryKey: manageKeys.enrollments(key),
108
+ enabled: !!client && sessionReady && ids.length > 0,
109
+ queryFn: () => getSubscriptionEnrollments(client.gql, ids),
110
+ staleTime: 60 * 1000,
111
+ retry: 1,
112
+ });
113
+ }
114
+ /** Invoices for the Payment history tab. */
115
+ export function usePaymentHistoryQuery(client, sessionReady, subscriptionBiId) {
116
+ const sub = (subscriptionBiId === null || subscriptionBiId === void 0 ? void 0 : subscriptionBiId.trim()) || '';
117
+ return useQuery({
118
+ queryKey: manageKeys.paymentHistory(sub || 'none'),
119
+ enabled: !!client && sessionReady && !!sub,
120
+ queryFn: () => getPaymentHistory(client.gql, sub),
121
+ staleTime: 60 * 1000,
122
+ retry: 1,
123
+ });
124
+ }
125
+ /** Stripe payment method on file for renew / manage display. */
126
+ export function useSubscriptionPaymentMethodQuery(client, sessionReady, subscriptionBiId, enabled = true) {
127
+ const sub = (subscriptionBiId === null || subscriptionBiId === void 0 ? void 0 : subscriptionBiId.trim()) || '';
128
+ return useQuery({
129
+ queryKey: manageKeys.paymentMethod(sub || 'none'),
130
+ enabled: !!client && sessionReady && !!sub && enabled,
131
+ queryFn: () => getSubscriptionPaymentMethod(client.gql, sub),
132
+ staleTime: 60 * 1000,
133
+ retry: 1,
134
+ });
135
+ }
136
+ /** Cancel subscription mutation; invalidates subscriber query on success. */
137
+ export function useCancelSubscriptionMutation(client) {
138
+ const queryClient = useQueryClient();
139
+ return useMutation({
140
+ mutationFn: (subscriptionBiId) => {
141
+ if (!client) {
142
+ throw new Error('Viax client is not configured.');
143
+ }
144
+ return cancelSubscription(client.gql, subscriptionBiId);
145
+ },
146
+ onSuccess: () => {
147
+ queryClient.invalidateQueries({ queryKey: manageKeys.isSubscriber() });
148
+ },
149
+ });
150
+ }
151
+ /** Undo pending cancellation before period end; refreshes subscriber view on success. */
152
+ export function useReactivateSubscriptionMutation(client) {
153
+ const queryClient = useQueryClient();
154
+ const markActive = (prev) => {
155
+ if (!prev) {
156
+ return prev !== null && prev !== void 0 ? prev : null;
157
+ }
158
+ return Object.assign(Object.assign({}, prev), { isSubscriber: true, canEnroll: true, status: 'ACTIVE', canceledAt: null });
159
+ };
160
+ return useMutation({
161
+ mutationFn: (subscriptionBiId) => {
162
+ if (!client) {
163
+ throw new Error('Viax client is not configured.');
164
+ }
165
+ return reactivateSubscription(client.gql, subscriptionBiId);
166
+ },
167
+ onSuccess: () => __awaiter(this, void 0, void 0, function* () {
168
+ // Immediate UI flip to the active manage view.
169
+ queryClient.setQueryData(manageKeys.isSubscriber(), markActive);
170
+ yield queryClient.refetchQueries({ queryKey: manageKeys.isSubscriber() });
171
+ // If the read-after-write still shows a cancel status, keep the active view
172
+ // (reactivate already succeeded).
173
+ queryClient.setQueryData(manageKeys.isSubscriber(), (prev) => {
174
+ var _a;
175
+ if (!prev) {
176
+ return prev !== null && prev !== void 0 ? prev : null;
177
+ }
178
+ const status = ((_a = prev.status) !== null && _a !== void 0 ? _a : '').toUpperCase();
179
+ const stillCanceled = (status.includes('CANCEL'));
180
+ return stillCanceled ? markActive(prev) : Object.assign(Object.assign({}, prev), { canceledAt: null });
181
+ });
182
+ yield queryClient.invalidateQueries({
183
+ queryKey: [...manageKeys.all, 'paymentHistory'],
184
+ });
185
+ }),
186
+ });
187
+ }
188
+ /** Update default Stripe payment method on the subscription. */
189
+ export function useUpdatePaymentMethodMutation(client) {
190
+ const queryClient = useQueryClient();
191
+ return useMutation({
192
+ mutationFn: (args) => {
193
+ if (!client) {
194
+ throw new Error('Viax client is not configured.');
195
+ }
196
+ return updateSubscriptionPaymentMethod(client.gql, args);
197
+ },
198
+ onSuccess: () => {
199
+ queryClient.invalidateQueries({ queryKey: manageKeys.isSubscriber() });
200
+ queryClient.invalidateQueries({
201
+ queryKey: [...manageKeys.all, 'paymentMethod'],
202
+ });
203
+ },
204
+ });
205
+ }
206
+ //# sourceMappingURL=useManageQueries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useManageQueries.js","sourceRoot":"","sources":["../../../src/data/hooks/useManageQueries.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hooks for Viax session, subscriber status, enrollments, and cancel mutation.\n */\n\nimport { useEffect, useMemo } from 'react';\nimport {\n useMutation,\n useQuery,\n useQueryClient,\n type UseMutationResult,\n type UseQueryResult,\n} from '@tanstack/react-query';\nimport { getAppConfig, getSiteConfig } from '@openedx/frontend-base';\n\nimport { appId } from '../../constants';\nimport type {\n CurrentUserSubscriberResult,\n PaymentHistoryItem,\n SubscriptionEnrollment,\n BillingPlansResult,\n} from '../../types';\nimport { createGqlClient, type ViaxGqlClient } from '../../utils/graphqlClient';\nimport { fetchEdxSession, getEdxSessionUrl } from '../../utils/edxSession';\nimport { cancelSubscription } from '../services/subscription/cancelSubscription';\nimport { getBillingPlans } from '../services/subscription/getBillingPlans';\nimport { getIsCurrentUserSubscriber } from '../services/subscription/getIsCurrentUserSubscriber';\nimport { getPaymentHistory } from '../services/subscription/getPaymentHistory';\nimport { getSubscriptionEnrollments } from '../services/subscription/getSubscriptionEnrollments';\nimport {\n getSubscriptionPaymentMethod,\n type SubscriptionPaymentMethod,\n} from '../services/subscription/getSubscriptionPaymentMethod';\nimport { reactivateSubscription } from '../services/subscription/reactivateSubscription';\nimport {\n updateSubscriptionPaymentMethod,\n type UpdatePaymentMethodArgs,\n} from '../services/subscription/updateSubscriptionPaymentMethod';\nimport { manageKeys } from './keys';\n\n/** Shared Viax GraphQL client for the manage MFE (singleton per API URL). */\nlet cachedClient: ViaxGqlClient | null = null;\nlet cachedApiUrl: string | undefined;\n\nexport function useViaxClient(): ViaxGqlClient | null {\n const config = getAppConfig(appId);\n const apiUrl = config.VIAX_API_URL as string | undefined;\n\n return useMemo(() => {\n if (!apiUrl) {\n return null;\n }\n if (cachedClient && cachedApiUrl === apiUrl) {\n return cachedClient;\n }\n cachedClient = createGqlClient({ apiUrl });\n cachedApiUrl = apiUrl;\n return cachedClient;\n }, [apiUrl]);\n}\n\n/** Exchange edX session cookies for a Viax token. */\nexport function useViaxSessionQuery(): UseQueryResult<Awaited<ReturnType<typeof fetchEdxSession>>> {\n const sessionUrl = getSiteConfig().lmsBaseUrl\n ? getEdxSessionUrl()\n : null;\n\n return useQuery({\n queryKey: manageKeys.viaxSession(),\n enabled: !!sessionUrl,\n queryFn: () => fetchEdxSession(sessionUrl!),\n staleTime: 5 * 60 * 1000,\n retry: 1,\n });\n}\n\n/**\n * Applies the Viax token from the session query onto the GraphQL client.\n */\nexport function useViaxSession(client: ViaxGqlClient | null) {\n const sessionQuery = useViaxSessionQuery();\n\n useEffect(() => {\n if (client && sessionQuery.data?.viaxToken) {\n client.setToken(sessionQuery.data.viaxToken);\n }\n }, [client, sessionQuery.data?.viaxToken]);\n\n return {\n sessionReady: Boolean(client && sessionQuery.isSuccess && sessionQuery.data?.viaxToken),\n isSessionLoading: sessionQuery.isPending,\n isSessionError: sessionQuery.isError,\n sessionError: sessionQuery.error,\n };\n}\n\n/** Current user's subscription context. */\nexport function useIsSubscriberQuery(\n client: ViaxGqlClient | null,\n sessionReady: boolean,\n): UseQueryResult<CurrentUserSubscriberResult | null> {\n return useQuery({\n queryKey: manageKeys.isSubscriber(),\n enabled: !!client && sessionReady,\n queryFn: () => getIsCurrentUserSubscriber(client!.gql),\n staleTime: 2 * 60 * 1000,\n retry: 1,\n });\n}\n\n/** Available monthly / annual billing plans for price display. */\nexport function useBillingPlansQuery(\n client: ViaxGqlClient | null,\n sessionReady: boolean,\n): UseQueryResult<BillingPlansResult> {\n return useQuery({\n queryKey: manageKeys.billingPlans(),\n enabled: !!client && sessionReady,\n queryFn: () => getBillingPlans(client!.gql),\n staleTime: 10 * 60 * 1000,\n retry: 1,\n });\n}\n\n/** Enrollments for cancel confirmation. */\nexport function useSubscriptionEnrollmentsQuery(\n client: ViaxGqlClient | null,\n sessionReady: boolean,\n subscriptionBiIds: string | string[] | null | undefined,\n): UseQueryResult<SubscriptionEnrollment[]> {\n const ids = (Array.isArray(subscriptionBiIds)\n ? subscriptionBiIds\n : [subscriptionBiIds ?? ''])\n .map((id) => (id ?? '').trim())\n .filter(Boolean);\n const key = ids.join(',') || 'none';\n\n return useQuery({\n queryKey: manageKeys.enrollments(key),\n enabled: !!client && sessionReady && ids.length > 0,\n queryFn: () => getSubscriptionEnrollments(client!.gql, ids),\n staleTime: 60 * 1000,\n retry: 1,\n });\n}\n\n/** Invoices for the Payment history tab. */\nexport function usePaymentHistoryQuery(\n client: ViaxGqlClient | null,\n sessionReady: boolean,\n subscriptionBiId: string | null | undefined,\n): UseQueryResult<PaymentHistoryItem[]> {\n const sub = subscriptionBiId?.trim() || '';\n\n return useQuery({\n queryKey: manageKeys.paymentHistory(sub || 'none'),\n enabled: !!client && sessionReady && !!sub,\n queryFn: () => getPaymentHistory(client!.gql, sub),\n staleTime: 60 * 1000,\n retry: 1,\n });\n}\n\n/** Stripe payment method on file for renew / manage display. */\nexport function useSubscriptionPaymentMethodQuery(\n client: ViaxGqlClient | null,\n sessionReady: boolean,\n subscriptionBiId: string | null | undefined,\n enabled = true,\n): UseQueryResult<SubscriptionPaymentMethod | null> {\n const sub = subscriptionBiId?.trim() || '';\n\n return useQuery({\n queryKey: manageKeys.paymentMethod(sub || 'none'),\n enabled: !!client && sessionReady && !!sub && enabled,\n queryFn: () => getSubscriptionPaymentMethod(client!.gql, sub),\n staleTime: 60 * 1000,\n retry: 1,\n });\n}\n\n/** Cancel subscription mutation; invalidates subscriber query on success. */\nexport function useCancelSubscriptionMutation(\n client: ViaxGqlClient | null,\n): UseMutationResult<Record<string, unknown> | null, Error, string> {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (subscriptionBiId: string) => {\n if (!client) {\n throw new Error('Viax client is not configured.');\n }\n return cancelSubscription(client.gql, subscriptionBiId);\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: manageKeys.isSubscriber() });\n },\n });\n}\n\n/** Undo pending cancellation before period end; refreshes subscriber view on success. */\nexport function useReactivateSubscriptionMutation(\n client: ViaxGqlClient | null,\n): UseMutationResult<Record<string, unknown> | null, Error, string> {\n const queryClient = useQueryClient();\n\n const markActive = (\n prev: CurrentUserSubscriberResult | null | undefined,\n ): CurrentUserSubscriberResult | null => {\n if (!prev) {\n return prev ?? null;\n }\n return {\n ...prev,\n isSubscriber: true,\n canEnroll: true,\n status: 'ACTIVE',\n canceledAt: null,\n };\n };\n\n return useMutation({\n mutationFn: (subscriptionBiId: string) => {\n if (!client) {\n throw new Error('Viax client is not configured.');\n }\n return reactivateSubscription(client.gql, subscriptionBiId);\n },\n onSuccess: async () => {\n // Immediate UI flip to the active manage view.\n queryClient.setQueryData(manageKeys.isSubscriber(), markActive);\n\n await queryClient.refetchQueries({ queryKey: manageKeys.isSubscriber() });\n\n // If the read-after-write still shows a cancel status, keep the active view\n // (reactivate already succeeded).\n queryClient.setQueryData(\n manageKeys.isSubscriber(),\n (prev: CurrentUserSubscriberResult | null | undefined) => {\n if (!prev) {\n return prev ?? null;\n }\n const status = (prev.status ?? '').toUpperCase();\n const stillCanceled = (\n status.includes('CANCEL')\n );\n return stillCanceled ? markActive(prev) : {\n ...prev,\n canceledAt: null,\n };\n },\n );\n\n await queryClient.invalidateQueries({\n queryKey: [...manageKeys.all, 'paymentHistory'],\n });\n },\n });\n}\n\n/** Update default Stripe payment method on the subscription. */\nexport function useUpdatePaymentMethodMutation(\n client: ViaxGqlClient | null,\n): UseMutationResult<Record<string, unknown> | null, Error, UpdatePaymentMethodArgs> {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (args: UpdatePaymentMethodArgs) => {\n if (!client) {\n throw new Error('Viax client is not configured.');\n }\n return updateSubscriptionPaymentMethod(client.gql, args);\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: manageKeys.isSubscriber() });\n queryClient.invalidateQueries({\n queryKey: [...manageKeys.all, 'paymentMethod'],\n });\n },\n });\n}\n"]}
@@ -1,2 +1,2 @@
1
- export function getApiUrl(): string;
2
- export function getSubsInitApiUrl(): string;
1
+ export declare const getApiUrl: () => string;
2
+ export declare const getSubsInitApiUrl: () => string;
@@ -1 +1 @@
1
- {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../../src/data/services/subs/urls.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,aAAa,EAAE,CAAC,UAAU,MAAM,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,SAAS,EAAE,qBAAqB,CAAC,CAAC","sourcesContent":["import { getSiteConfig } from '@openedx/frontend-base';\n\nexport const getApiUrl = () => (`${getSiteConfig().lmsBaseUrl}/api`);\n\nexport const getSubsInitApiUrl = () => (`${getApiUrl()}/subscription/init/`);\n"]}
1
+ {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../../src/data/services/subs/urls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,aAAa,EAAE,CAAC,UAAU,MAAM,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,SAAS,EAAE,qBAAqB,CAAC,CAAC","sourcesContent":["import { getSiteConfig } from '@openedx/frontend-base';\n\nexport const getApiUrl = () => (`${getSiteConfig().lmsBaseUrl}/api`);\n\nexport const getSubsInitApiUrl = () => (`${getApiUrl()}/subscription/init/`);\n"]}
@@ -0,0 +1,6 @@
1
+ import type { GqlRunner } from '../../../types';
2
+ /**
3
+ * Cancel the learner's subscription (at period end by default).
4
+ * Returns the raw JSON scalar from Viax when available.
5
+ */
6
+ export declare function cancelSubscription(gql: GqlRunner, subscriptionBiId: string, immediate?: boolean): Promise<Record<string, unknown> | null>;
@@ -0,0 +1,31 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { CANCEL_SUBSCRIPTION } from '../../../utils/queries';
11
+ /**
12
+ * Cancel the learner's subscription (at period end by default).
13
+ * Returns the raw JSON scalar from Viax when available.
14
+ */
15
+ export function cancelSubscription(gql_1, subscriptionBiId_1) {
16
+ return __awaiter(this, arguments, void 0, function* (gql, subscriptionBiId, immediate = false) {
17
+ const data = yield gql(CANCEL_SUBSCRIPTION, {
18
+ biId: subscriptionBiId,
19
+ immediate,
20
+ });
21
+ const result = data === null || data === void 0 ? void 0 : data.tCancelSubscription;
22
+ if (!result) {
23
+ return null;
24
+ }
25
+ if (typeof result === 'object') {
26
+ return result;
27
+ }
28
+ return { result };
29
+ });
30
+ }
31
+ //# sourceMappingURL=cancelSubscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancelSubscription.js","sourceRoot":"","sources":["../../../../src/data/services/subscription/cancelSubscription.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;;GAGG;AACH,MAAM,UAAgB,kBAAkB;yDACtC,GAAc,EACd,gBAAwB,EACxB,SAAS,GAAG,KAAK;QAEjB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,mBAAmB,EAAE;YAC1C,IAAI,EAAE,gBAAgB;YACtB,SAAS;SACV,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,mBAAmB,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,MAAiC,CAAC;QAC3C,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,CAAC;IACpB,CAAC;CAAA","sourcesContent":["import type { GqlRunner } from '../../../types';\nimport { CANCEL_SUBSCRIPTION } from '../../../utils/queries';\n\n/**\n * Cancel the learner's subscription (at period end by default).\n * Returns the raw JSON scalar from Viax when available.\n */\nexport async function cancelSubscription(\n gql: GqlRunner,\n subscriptionBiId: string,\n immediate = false,\n): Promise<Record<string, unknown> | null> {\n const data = await gql(CANCEL_SUBSCRIPTION, {\n biId: subscriptionBiId,\n immediate,\n });\n const result = data?.tCancelSubscription;\n if (!result) {\n return null;\n }\n if (typeof result === 'object') {\n return result as Record<string, unknown>;\n }\n return { result };\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { BillingPlansResult, GqlRunner } from '../../../types';
2
+ /** Fetch available customer billing plans (monthly / annual). */
3
+ export declare function getBillingPlans(gql: GqlRunner): Promise<BillingPlansResult>;
@@ -7,25 +7,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- /**
11
- * api/billingPlans.ts — fetch billing plans without authentication.
12
- * Called on component mount to show prices before the user clicks Place order.
13
- */
14
- import { GET_BILLING_PLANS } from './queries';
15
- export function fetchBillingPlans(apiUrl) {
10
+ import { GET_BILLING_PLANS } from '../../../utils/queries';
11
+ /** Fetch available customer billing plans (monthly / annual). */
12
+ export function getBillingPlans(gql) {
16
13
  return __awaiter(this, void 0, void 0, function* () {
17
- var _a, _b, _c, _d, _e;
18
- const res = yield fetch(apiUrl, {
19
- method: 'POST',
20
- headers: { 'Content-Type': 'application/json' },
21
- body: JSON.stringify({ query: GET_BILLING_PLANS }),
22
- });
23
- if (!res.ok)
24
- throw new Error(`Failed to fetch billing plans (${res.status})`);
25
- const json = yield res.json();
26
- if ((_a = json.errors) === null || _a === void 0 ? void 0 : _a.length)
27
- throw new Error(((_b = json.errors[0]) === null || _b === void 0 ? void 0 : _b.message) || 'GraphQL error');
28
- const edges = (_e = (_d = (_c = json.data) === null || _c === void 0 ? void 0 : _c.filterCustomerBillingPlan) === null || _d === void 0 ? void 0 : _d.edges) !== null && _e !== void 0 ? _e : [];
14
+ var _a, _b;
15
+ const data = yield gql(GET_BILLING_PLANS);
16
+ const edges = (_b = (_a = data === null || data === void 0 ? void 0 : data.filterCustomerBillingPlan) === null || _a === void 0 ? void 0 : _a.edges) !== null && _b !== void 0 ? _b : [];
17
+ if (!edges.length) {
18
+ throw new Error('No billing plans found.');
19
+ }
29
20
  const plans = edges.map(({ node }) => {
30
21
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
31
22
  return ({
@@ -40,9 +31,7 @@ export function fetchBillingPlans(apiUrl) {
40
31
  },
41
32
  });
42
33
  });
43
- if (!plans.length)
44
- throw new Error('No billing plans found.');
45
34
  return { plans };
46
35
  });
47
36
  }
48
- //# sourceMappingURL=fetchBillingPlans.js.map
37
+ //# sourceMappingURL=getBillingPlans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getBillingPlans.js","sourceRoot":"","sources":["../../../../src/data/services/subscription/getBillingPlans.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,iEAAiE;AACjE,MAAM,UAAgB,eAAe,CAAC,GAAc;;;QAClD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC1C,MAAM,KAAK,GAQL,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,yBAAyB,0CAAE,KAAK,mCAAI,EAAE,CAAC;QAEnD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,KAAK,GAAkB,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;;YAAC,OAAA,CAAC;gBACpD,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,aAAa,EAAE,IAAI,CAAC,cAAc;gBAClC,MAAM,EAAE,MAAA,MAAA,IAAI,CAAC,aAAa,0CAAE,MAAM,mCAAI,GAAG;gBACzC,QAAQ,EAAE,MAAA,MAAA,MAAA,IAAI,CAAC,aAAa,0CAAE,KAAK,0CAAE,IAAI,mCAAI,KAAK;gBAClD,UAAU,EAAE,IAAI,CAAC,aAAa;gBAC9B,cAAc,EAAE;oBACd,GAAG,EAAE,MAAA,MAAA,IAAI,CAAC,iBAAiB,0CAAE,GAAG,mCAAI,EAAE;oBACtC,MAAM,EAAE,MAAA,MAAA,IAAI,CAAC,iBAAiB,0CAAE,MAAM,mCAAI,EAAE;iBAC7C;aACF,CAAC,CAAA;SAAA,CAAC,CAAC;QAEJ,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;CAAA","sourcesContent":["import type { BillingPlan, BillingPlansResult, GqlRunner } from '../../../types';\nimport { GET_BILLING_PLANS } from '../../../utils/queries';\n\n/** Fetch available customer billing plans (monthly / annual). */\nexport async function getBillingPlans(gql: GqlRunner): Promise<BillingPlansResult> {\n const data = await gql(GET_BILLING_PLANS);\n const edges: {\n node: {\n uid: string,\n tStripePriceId: string,\n tStripeAmount?: { amount: string, units?: { code: string } },\n bipIsTemplate: boolean,\n bipOwnershipModel?: { uid: string, omName: string },\n },\n }[] = data?.filterCustomerBillingPlan?.edges ?? [];\n\n if (!edges.length) {\n throw new Error('No billing plans found.');\n }\n\n const plans: BillingPlan[] = edges.map(({ node }) => ({\n uid: node.uid,\n stripePriceId: node.tStripePriceId,\n amount: node.tStripeAmount?.amount ?? '0',\n currency: node.tStripeAmount?.units?.code ?? 'USD',\n isTemplate: node.bipIsTemplate,\n ownershipModel: {\n uid: node.bipOwnershipModel?.uid ?? '',\n omName: node.bipOwnershipModel?.omName ?? '',\n },\n }));\n\n return { plans };\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { GqlRunner, CurrentUserSubscriberResult } from '../../../types';
2
+ /** Check whether the authenticated user has an active / recent subscription. */
3
+ export declare function getIsCurrentUserSubscriber(gql: GqlRunner): Promise<CurrentUserSubscriberResult | null>;
@@ -0,0 +1,35 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { GET_IS_CURRENT_USER_SUBSCRIBER } from '../../../utils/queries';
11
+ /** Check whether the authenticated user has an active / recent subscription. */
12
+ export function getIsCurrentUserSubscriber(gql) {
13
+ return __awaiter(this, void 0, void 0, function* () {
14
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
15
+ const data = yield gql(GET_IS_CURRENT_USER_SUBSCRIBER);
16
+ const result = data === null || data === void 0 ? void 0 : data.tIsCurrentUserSubscriber;
17
+ if (!result || typeof result !== 'object') {
18
+ return null;
19
+ }
20
+ return {
21
+ isSubscriber: result.isSubscriber === true,
22
+ canEnroll: result.canEnroll === true,
23
+ subscriptionBiId: (_a = result.subscriptionBiId) !== null && _a !== void 0 ? _a : null,
24
+ status: (_b = result.status) !== null && _b !== void 0 ? _b : null,
25
+ currentPeriodEnd: (_c = result.currentPeriodEnd) !== null && _c !== void 0 ? _c : null,
26
+ subscriptionStartDate: (_d = result.subscriptionStartDate) !== null && _d !== void 0 ? _d : null,
27
+ subscriptionEndDate: (_e = result.subscriptionEndDate) !== null && _e !== void 0 ? _e : null,
28
+ renewalType: (_g = (_f = result.renewalType) !== null && _f !== void 0 ? _f : result.planName) !== null && _g !== void 0 ? _g : null,
29
+ canceledAt: (_j = (_h = result.canceledAt) !== null && _h !== void 0 ? _h : result.cancelledAt) !== null && _j !== void 0 ? _j : null,
30
+ amount: (_l = (_k = result.amount) !== null && _k !== void 0 ? _k : result.price) !== null && _l !== void 0 ? _l : null,
31
+ currency: (_m = result.currency) !== null && _m !== void 0 ? _m : null,
32
+ };
33
+ });
34
+ }
35
+ //# sourceMappingURL=getIsCurrentUserSubscriber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getIsCurrentUserSubscriber.js","sourceRoot":"","sources":["../../../../src/data/services/subscription/getIsCurrentUserSubscriber.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAExE,gFAAgF;AAChF,MAAM,UAAgB,0BAA0B,CAC9C,GAAc;;;QAEd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,8BAA8B,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,wBAAwB,CAAC;QAC9C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO;YACL,YAAY,EAAE,MAAM,CAAC,YAAY,KAAK,IAAI;YAC1C,SAAS,EAAE,MAAM,CAAC,SAAS,KAAK,IAAI;YACpC,gBAAgB,EAAE,MAAA,MAAM,CAAC,gBAAgB,mCAAI,IAAI;YACjD,MAAM,EAAE,MAAA,MAAM,CAAC,MAAM,mCAAI,IAAI;YAC7B,gBAAgB,EAAE,MAAA,MAAM,CAAC,gBAAgB,mCAAI,IAAI;YACjD,qBAAqB,EAAE,MAAA,MAAM,CAAC,qBAAqB,mCAAI,IAAI;YAC3D,mBAAmB,EAAE,MAAA,MAAM,CAAC,mBAAmB,mCAAI,IAAI;YACvD,WAAW,EAAE,MAAA,MAAA,MAAM,CAAC,WAAW,mCAAI,MAAM,CAAC,QAAQ,mCAAI,IAAI;YAC1D,UAAU,EAAE,MAAA,MAAA,MAAM,CAAC,UAAU,mCAAI,MAAM,CAAC,WAAW,mCAAI,IAAI;YAC3D,MAAM,EAAE,MAAA,MAAA,MAAM,CAAC,MAAM,mCAAI,MAAM,CAAC,KAAK,mCAAI,IAAI;YAC7C,QAAQ,EAAE,MAAA,MAAM,CAAC,QAAQ,mCAAI,IAAI;SAClC,CAAC;IACJ,CAAC;CAAA","sourcesContent":["import type { GqlRunner, CurrentUserSubscriberResult } from '../../../types';\nimport { GET_IS_CURRENT_USER_SUBSCRIBER } from '../../../utils/queries';\n\n/** Check whether the authenticated user has an active / recent subscription. */\nexport async function getIsCurrentUserSubscriber(\n gql: GqlRunner,\n): Promise<CurrentUserSubscriberResult | null> {\n const data = await gql(GET_IS_CURRENT_USER_SUBSCRIBER);\n const result = data?.tIsCurrentUserSubscriber;\n if (!result || typeof result !== 'object') {\n return null;\n }\n\n return {\n isSubscriber: result.isSubscriber === true,\n canEnroll: result.canEnroll === true,\n subscriptionBiId: result.subscriptionBiId ?? null,\n status: result.status ?? null,\n currentPeriodEnd: result.currentPeriodEnd ?? null,\n subscriptionStartDate: result.subscriptionStartDate ?? null,\n subscriptionEndDate: result.subscriptionEndDate ?? null,\n renewalType: result.renewalType ?? result.planName ?? null,\n canceledAt: result.canceledAt ?? result.cancelledAt ?? null,\n amount: result.amount ?? result.price ?? null,\n currency: result.currency ?? null,\n };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { GqlRunner, PaymentHistoryItem } from '../../../types';
2
+ /**
3
+ * Payment history invoices for a subscription.
4
+ * Sorted newest billDate first.
5
+ */
6
+ export declare function getPaymentHistory(gql: GqlRunner, subscriptionBiId: string, first?: number): Promise<PaymentHistoryItem[]>;
@@ -0,0 +1,65 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { GET_PAYMENT_HISTORY } from '../../../utils/queries';
11
+ import { sumFinancialCharges } from '../../../utils/invoiceAmount';
12
+ function escapeFilterValue(value) {
13
+ return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
14
+ }
15
+ function codeOrName(value) {
16
+ var _a, _b;
17
+ if (!value)
18
+ return null;
19
+ if (typeof value === 'string')
20
+ return value;
21
+ return (_b = (_a = value.code) !== null && _a !== void 0 ? _a : value.name) !== null && _b !== void 0 ? _b : null;
22
+ }
23
+ function normalizeInvoice(node) {
24
+ var _a, _b, _c, _d, _e, _f, _g;
25
+ const { amount, currency } = sumFinancialCharges(node.billFinancialCharges);
26
+ const biId = String((_a = node.biId) !== null && _a !== void 0 ? _a : '');
27
+ return {
28
+ biId,
29
+ orderNumber: biId ? `EDX-${biId}` : '',
30
+ stripeInvoiceId: (_b = node.tStripeInvoiceId) !== null && _b !== void 0 ? _b : null,
31
+ status: codeOrName(node.bpStatus),
32
+ billDate: (_c = node.billDate) !== null && _c !== void 0 ? _c : null,
33
+ periodStart: (_e = (_d = node.billBillingPeriod) === null || _d === void 0 ? void 0 : _d.start) !== null && _e !== void 0 ? _e : null,
34
+ periodEnd: (_g = (_f = node.billBillingPeriod) === null || _f === void 0 ? void 0 : _f.end) !== null && _g !== void 0 ? _g : null,
35
+ amount,
36
+ currency,
37
+ isTrial: amount === 0,
38
+ };
39
+ }
40
+ /**
41
+ * Payment history invoices for a subscription.
42
+ * Sorted newest billDate first.
43
+ */
44
+ export function getPaymentHistory(gql_1, subscriptionBiId_1) {
45
+ return __awaiter(this, arguments, void 0, function* (gql, subscriptionBiId, first = 50) {
46
+ var _a, _b;
47
+ const sub = subscriptionBiId.trim();
48
+ if (!sub) {
49
+ return [];
50
+ }
51
+ const filter = `biRelatesTo.biId = '${escapeFilterValue(sub)}'`;
52
+ const data = yield gql(GET_PAYMENT_HISTORY, { filter, first });
53
+ const edges = (_b = (_a = data === null || data === void 0 ? void 0 : data.filterTwouInvoice) === null || _a === void 0 ? void 0 : _a.edges) !== null && _b !== void 0 ? _b : [];
54
+ return edges
55
+ .map((edge) => edge === null || edge === void 0 ? void 0 : edge.node)
56
+ .filter(Boolean)
57
+ .map((node) => normalizeInvoice(node))
58
+ .sort((a, b) => {
59
+ const aTime = a.billDate ? new Date(a.billDate).getTime() : 0;
60
+ const bTime = b.billDate ? new Date(b.billDate).getTime() : 0;
61
+ return bTime - aTime;
62
+ });
63
+ });
64
+ }
65
+ //# sourceMappingURL=getPaymentHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getPaymentHistory.js","sourceRoot":"","sources":["../../../../src/data/services/subscription/getPaymentHistory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { GqlRunner, PaymentHistoryItem } from '../../../types';\nimport { GET_PAYMENT_HISTORY } from '../../../utils/queries';\nimport { sumFinancialCharges } from '../../../utils/invoiceAmount';\n\nfunction escapeFilterValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nfunction codeOrName(\n value: { code?: string, name?: string } | string | null | undefined,\n): string | null {\n if (!value) return null;\n if (typeof value === 'string') return value;\n return value.code ?? value.name ?? null;\n}\n\nfunction normalizeInvoice(node: Record<string, any>): PaymentHistoryItem {\n const { amount, currency } = sumFinancialCharges(node.billFinancialCharges);\n const biId = String(node.biId ?? '');\n\n return {\n biId,\n orderNumber: biId ? `EDX-${biId}` : '',\n stripeInvoiceId: node.tStripeInvoiceId ?? null,\n status: codeOrName(node.bpStatus),\n billDate: node.billDate ?? null,\n periodStart: node.billBillingPeriod?.start ?? null,\n periodEnd: node.billBillingPeriod?.end ?? null,\n amount,\n currency,\n isTrial: amount === 0,\n };\n}\n\n/**\n * Payment history invoices for a subscription.\n * Sorted newest billDate first.\n */\nexport async function getPaymentHistory(\n gql: GqlRunner,\n subscriptionBiId: string,\n first = 50,\n): Promise<PaymentHistoryItem[]> {\n const sub = subscriptionBiId.trim();\n if (!sub) {\n return [];\n }\n\n const filter = `biRelatesTo.biId = '${escapeFilterValue(sub)}'`;\n const data = await gql(GET_PAYMENT_HISTORY, { filter, first });\n const edges = data?.filterTwouInvoice?.edges ?? [];\n\n return edges\n .map((edge: { node?: Record<string, any> }) => edge?.node)\n .filter(Boolean)\n .map((node: Record<string, any>) => normalizeInvoice(node))\n .sort((a: PaymentHistoryItem, b: PaymentHistoryItem) => {\n const aTime = a.billDate ? new Date(a.billDate).getTime() : 0;\n const bTime = b.billDate ? new Date(b.billDate).getTime() : 0;\n return bTime - aTime;\n });\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { GqlRunner, SubscriptionEnrollment } from '../../../types';
2
+ /** Build `tSubscriptionBiId IN ('…', '…')` for one or more subscription BI ids. */
3
+ export declare function buildEnrollmentsFilter(subscriptionBiIds: string | string[]): string | null;
4
+ /**
5
+ * List enrollments for the learner's subscription(s) (cancel confirmation course list).
6
+ */
7
+ export declare function getSubscriptionEnrollments(gql: GqlRunner, subscriptionBiIds: string | string[]): Promise<SubscriptionEnrollment[]>;
@@ -0,0 +1,98 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { getSiteConfig } from '@openedx/frontend-base';
11
+ import { GET_SUBSCRIPTION_ENROLLMENTS } from '../../../utils/queries';
12
+ /** Known TwouEnrollment bpStatus.code values. */
13
+ const ENROLLMENT_STATUSES = new Set([
14
+ 'ACTIVE',
15
+ 'COMPLETED',
16
+ 'SUSPENDED',
17
+ 'PENDING',
18
+ 'FAILED',
19
+ ]);
20
+ function escapeFilterValue(value) {
21
+ return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
22
+ }
23
+ function resolveInstitutionName(course) {
24
+ var _a, _b, _c;
25
+ const schools = Array.isArray(course === null || course === void 0 ? void 0 : course.tSchools)
26
+ ? [...course.tSchools].sort((a, b) => { var _a, _b; return ((_a = a === null || a === void 0 ? void 0 : a.tSortValue) !== null && _a !== void 0 ? _a : 0) - ((_b = b === null || b === void 0 ? void 0 : b.tSortValue) !== null && _b !== void 0 ? _b : 0); })
27
+ : [];
28
+ const fromSchool = (_b = (_a = schools.find((s) => { var _a; return (_a = s === null || s === void 0 ? void 0 : s.tName) === null || _a === void 0 ? void 0 : _a.trim(); })) === null || _a === void 0 ? void 0 : _a.tName) === null || _b === void 0 ? void 0 : _b.trim();
29
+ if (fromSchool) {
30
+ return fromSchool;
31
+ }
32
+ const brand = (_c = course === null || course === void 0 ? void 0 : course.tBrandText) === null || _c === void 0 ? void 0 : _c.trim();
33
+ return brand || null;
34
+ }
35
+ /** LMS certificate page for a completed course run, when available. */
36
+ function resolveCertificateUrl(courseRunKey) {
37
+ var _a, _b;
38
+ const key = courseRunKey === null || courseRunKey === void 0 ? void 0 : courseRunKey.trim();
39
+ if (!key) {
40
+ return null;
41
+ }
42
+ const lms = (_b = (_a = getSiteConfig().lmsBaseUrl) === null || _a === void 0 ? void 0 : _a.replace(/\/+$/, '')) !== null && _b !== void 0 ? _b : '';
43
+ const path = `/certificates/${encodeURIComponent(key)}`;
44
+ return lms ? `${lms}${path}` : path;
45
+ }
46
+ /** Build `tSubscriptionBiId IN ('…', '…')` for one or more subscription BI ids. */
47
+ export function buildEnrollmentsFilter(subscriptionBiIds) {
48
+ const ids = (Array.isArray(subscriptionBiIds) ? subscriptionBiIds : [subscriptionBiIds])
49
+ .map((id) => id.trim())
50
+ .filter(Boolean);
51
+ if (!ids.length) {
52
+ return null;
53
+ }
54
+ const quoted = ids.map((id) => `'${escapeFilterValue(id)}'`).join(', ');
55
+ return `tSubscriptionBiId IN (${quoted})`;
56
+ }
57
+ /**
58
+ * List enrollments for the learner's subscription(s) (cancel confirmation course list).
59
+ */
60
+ export function getSubscriptionEnrollments(gql, subscriptionBiIds) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ var _a, _b;
63
+ const filter = buildEnrollmentsFilter(subscriptionBiIds);
64
+ if (!filter) {
65
+ return [];
66
+ }
67
+ const data = yield gql(GET_SUBSCRIPTION_ENROLLMENTS, { filter });
68
+ const edges = (_b = (_a = data === null || data === void 0 ? void 0 : data.filterTwouEnrollment) === null || _a === void 0 ? void 0 : _a.edges) !== null && _b !== void 0 ? _b : [];
69
+ return edges
70
+ .map((edge) => edge === null || edge === void 0 ? void 0 : edge.node)
71
+ .filter(Boolean)
72
+ .filter((node) => {
73
+ var _a, _b;
74
+ const code = ((_b = (_a = node === null || node === void 0 ? void 0 : node.bpStatus) === null || _a === void 0 ? void 0 : _a.code) !== null && _b !== void 0 ? _b : '').toUpperCase();
75
+ return ENROLLMENT_STATUSES.has(code);
76
+ })
77
+ .map((node) => {
78
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
79
+ const status = ((_b = (_a = node === null || node === void 0 ? void 0 : node.bpStatus) === null || _a === void 0 ? void 0 : _a.code) !== null && _b !== void 0 ? _b : '').toUpperCase();
80
+ const courseRunKey = (_c = node.tCourseRunKey) !== null && _c !== void 0 ? _c : null;
81
+ const isCompleted = status === 'COMPLETED';
82
+ return {
83
+ biId: node.biId,
84
+ courseMaId: (_e = (_d = node.tCourse) === null || _d === void 0 ? void 0 : _d.maId) !== null && _e !== void 0 ? _e : null,
85
+ courseName: (_g = (_f = node.tCourse) === null || _f === void 0 ? void 0 : _f.maName) !== null && _g !== void 0 ? _g : null,
86
+ courseSlug: null,
87
+ imageUrl: (_j = (_h = node.tCourse) === null || _h === void 0 ? void 0 : _h.imageUrl) !== null && _j !== void 0 ? _j : null,
88
+ orgName: resolveInstitutionName(node.tCourse),
89
+ orgLogoUrl: null,
90
+ courseRunKey,
91
+ status,
92
+ hasCertificate: isCompleted,
93
+ certificateUrl: isCompleted ? resolveCertificateUrl(courseRunKey) : null,
94
+ };
95
+ });
96
+ });
97
+ }
98
+ //# sourceMappingURL=getSubscriptionEnrollments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getSubscriptionEnrollments.js","sourceRoot":"","sources":["../../../../src/data/services/subscription/getSubscriptionEnrollments.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAEtE,iDAAiD;AACjD,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,QAAQ;IACR,WAAW;IACX,WAAW;IACX,SAAS;IACT,QAAQ;CACT,CAAC,CAAC;AAEH,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAW;;IACzC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,CAAC;QAC7C,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CACvB,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE,eAAC,OAAA,CAAC,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,UAAU,mCAAI,CAAC,CAAC,GAAG,CAAC,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,UAAU,mCAAI,CAAC,CAAC,CAAA,EAAA,CAChE;QACH,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,UAAU,GAAG,MAAA,MAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,KAAK,0CAAE,IAAI,EAAE,CAAA,EAAA,CAAC,0CAAE,KAAK,0CAAE,IAAI,EAAE,CAAC;IAC7E,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,MAAM,KAAK,GAAG,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,0CAAE,IAAI,EAAE,CAAC;IACzC,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC;AAED,uEAAuE;AACvE,SAAS,qBAAqB,CAAC,YAA2B;;IACxD,MAAM,GAAG,GAAG,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,MAAA,MAAA,aAAa,EAAE,CAAC,UAAU,0CAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,mCAAI,EAAE,CAAC;IAClE,MAAM,IAAI,GAAG,iBAAiB,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;IACxD,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACtC,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,sBAAsB,CACpC,iBAAoC;IAEpC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;SACrF,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;SACtB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxE,OAAO,yBAAyB,MAAM,GAAG,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAgB,0BAA0B,CAC9C,GAAc,EACd,iBAAoC;;;QAEpC,MAAM,MAAM,GAAG,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,4BAA4B,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,oBAAoB,0CAAE,KAAK,mCAAI,EAAE,CAAC;QAEtD,OAAO,KAAK;aACT,GAAG,CAAC,CAAC,IAAoB,EAAE,EAAE,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,CAAC;aACzC,MAAM,CAAC,OAAO,CAAC;aACf,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE;;YACpB,MAAM,IAAI,GAAG,CAAC,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,IAAI,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACxD,OAAO,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,IAAS,EAA0B,EAAE;;YACzC,MAAM,MAAM,GAAG,CAAC,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,IAAI,mCAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1D,MAAM,YAAY,GAAG,MAAA,IAAI,CAAC,aAAa,mCAAI,IAAI,CAAC;YAChD,MAAM,WAAW,GAAG,MAAM,KAAK,WAAW,CAAC;YAE3C,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,UAAU,EAAE,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,mCAAI,IAAI;gBACtC,UAAU,EAAE,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,MAAM,mCAAI,IAAI;gBACxC,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,QAAQ,mCAAI,IAAI;gBACxC,OAAO,EAAE,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC;gBAC7C,UAAU,EAAE,IAAI;gBAChB,YAAY;gBACZ,MAAM;gBACN,cAAc,EAAE,WAAW;gBAC3B,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI;aACzE,CAAC;QACJ,CAAC,CAAC,CAAC;IACP,CAAC;CAAA","sourcesContent":["import { getSiteConfig } from '@openedx/frontend-base';\n\nimport type { GqlRunner, SubscriptionEnrollment } from '../../../types';\nimport { GET_SUBSCRIPTION_ENROLLMENTS } from '../../../utils/queries';\n\n/** Known TwouEnrollment bpStatus.code values. */\nconst ENROLLMENT_STATUSES = new Set([\n 'ACTIVE',\n 'COMPLETED',\n 'SUSPENDED',\n 'PENDING',\n 'FAILED',\n]);\n\nfunction escapeFilterValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nfunction resolveInstitutionName(course: any): string | null {\n const schools = Array.isArray(course?.tSchools)\n ? [...course.tSchools].sort(\n (a: any, b: any) => (a?.tSortValue ?? 0) - (b?.tSortValue ?? 0),\n )\n : [];\n const fromSchool = schools.find((s: any) => s?.tName?.trim())?.tName?.trim();\n if (fromSchool) {\n return fromSchool;\n }\n const brand = course?.tBrandText?.trim();\n return brand || null;\n}\n\n/** LMS certificate page for a completed course run, when available. */\nfunction resolveCertificateUrl(courseRunKey: string | null): string | null {\n const key = courseRunKey?.trim();\n if (!key) {\n return null;\n }\n const lms = getSiteConfig().lmsBaseUrl?.replace(/\\/+$/, '') ?? '';\n const path = `/certificates/${encodeURIComponent(key)}`;\n return lms ? `${lms}${path}` : path;\n}\n\n/** Build `tSubscriptionBiId IN ('…', '…')` for one or more subscription BI ids. */\nexport function buildEnrollmentsFilter(\n subscriptionBiIds: string | string[],\n): string | null {\n const ids = (Array.isArray(subscriptionBiIds) ? subscriptionBiIds : [subscriptionBiIds])\n .map((id) => id.trim())\n .filter(Boolean);\n\n if (!ids.length) {\n return null;\n }\n\n const quoted = ids.map((id) => `'${escapeFilterValue(id)}'`).join(', ');\n return `tSubscriptionBiId IN (${quoted})`;\n}\n\n/**\n * List enrollments for the learner's subscription(s) (cancel confirmation course list).\n */\nexport async function getSubscriptionEnrollments(\n gql: GqlRunner,\n subscriptionBiIds: string | string[],\n): Promise<SubscriptionEnrollment[]> {\n const filter = buildEnrollmentsFilter(subscriptionBiIds);\n if (!filter) {\n return [];\n }\n\n const data = await gql(GET_SUBSCRIPTION_ENROLLMENTS, { filter });\n const edges = data?.filterTwouEnrollment?.edges ?? [];\n\n return edges\n .map((edge: { node?: any }) => edge?.node)\n .filter(Boolean)\n .filter((node: any) => {\n const code = (node?.bpStatus?.code ?? '').toUpperCase();\n return ENROLLMENT_STATUSES.has(code);\n })\n .map((node: any): SubscriptionEnrollment => {\n const status = (node?.bpStatus?.code ?? '').toUpperCase();\n const courseRunKey = node.tCourseRunKey ?? null;\n const isCompleted = status === 'COMPLETED';\n\n return {\n biId: node.biId,\n courseMaId: node.tCourse?.maId ?? null,\n courseName: node.tCourse?.maName ?? null,\n courseSlug: null,\n imageUrl: node.tCourse?.imageUrl ?? null,\n orgName: resolveInstitutionName(node.tCourse),\n orgLogoUrl: null,\n courseRunKey,\n status,\n hasCertificate: isCompleted,\n certificateUrl: isCompleted ? resolveCertificateUrl(courseRunKey) : null,\n };\n });\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { GqlRunner } from '../../../types';
2
+ export interface SubscriptionPaymentMethod {
3
+ stripePaymentMethodId: string | null;
4
+ last4: string | null;
5
+ brand: string | null;
6
+ }
7
+ /** Load the Stripe payment method on file for a subscription BI. */
8
+ export declare function getSubscriptionPaymentMethod(gql: GqlRunner, subscriptionBiId: string): Promise<SubscriptionPaymentMethod | null>;