@foldspace-fe/casdoor-next-auth-kit 0.1.18 → 0.1.20

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.
@@ -9,12 +9,16 @@ import {
9
9
  normalizeBillingPurchaseStatus,
10
10
  normalizeBillingRuntimeConfig,
11
11
  normalizeCasdoorBuyProductResponse,
12
+ normalizeCasdoorOrderHistoryItem,
13
+ normalizeCasdoorPaymentHistoryItem,
12
14
  normalizeCasdoorProductId,
15
+ normalizeCasdoorSubscriptionDetail,
16
+ normalizeCasdoorSubscriptionHistoryItem,
13
17
  resolveBillingItem,
14
18
  resolveBillingProductSnapshot,
15
19
  resolveBillingPurchasable,
16
20
  resolveBillingSubscriptionProduct
17
- } from "../chunk-46V73LSW.js";
21
+ } from "../chunk-FL6LOXEG.js";
18
22
  import {
19
23
  buildAuthJumpHref
20
24
  } from "../chunk-T2M5MVPE.js";
@@ -129,6 +133,66 @@ function extractCasdoorResponseData(response) {
129
133
  }
130
134
  return response;
131
135
  }
136
+ function useBillingCasdoorQuery(loader, buildArgs, deps, missingLoaderMessage) {
137
+ const [data, setData] = useState();
138
+ const [loading, setLoading] = useState(false);
139
+ const [error, setError] = useState(null);
140
+ const refresh = useCallback(async () => {
141
+ if (!loader) {
142
+ setData(void 0);
143
+ setError(missingLoaderMessage);
144
+ setLoading(false);
145
+ return;
146
+ }
147
+ setLoading(true);
148
+ setError(null);
149
+ try {
150
+ const response = await loader(buildArgs());
151
+ const extracted = extractCasdoorResponseData(response);
152
+ setData(extracted);
153
+ setError(null);
154
+ } catch (err) {
155
+ const message = err instanceof Error ? err.message : String(err);
156
+ setData(void 0);
157
+ setError(message);
158
+ } finally {
159
+ setLoading(false);
160
+ }
161
+ }, [buildArgs, loader, missingLoaderMessage]);
162
+ useEffect(() => {
163
+ void refresh();
164
+ }, [refresh, ...deps]);
165
+ return useMemo(
166
+ () => ({
167
+ data,
168
+ loading,
169
+ error,
170
+ refresh
171
+ }),
172
+ [data, error, loading, refresh]
173
+ );
174
+ }
175
+ function pickCurrentCasdoorSubscription(records) {
176
+ if (!records.length) return void 0;
177
+ const active = records.find((record) => {
178
+ const status = (record.state ?? "").toLowerCase();
179
+ return status.includes("active") || status.includes("trial");
180
+ });
181
+ if (active) return active;
182
+ return [...records].sort((left, right) => {
183
+ const leftTime = Date.parse(left.endTime ?? left.createdTime ?? "") || 0;
184
+ const rightTime = Date.parse(right.endTime ?? right.createdTime ?? "") || 0;
185
+ return rightTime - leftTime;
186
+ })[0];
187
+ }
188
+ function pickLatestCasdoorOrder(records) {
189
+ if (!records.length) return void 0;
190
+ return [...records].sort((left, right) => {
191
+ const leftTime = Date.parse(left.updatedTime ?? left.createdTime ?? "") || 0;
192
+ const rightTime = Date.parse(right.updatedTime ?? right.createdTime ?? "") || 0;
193
+ return rightTime - leftTime;
194
+ })[0];
195
+ }
132
196
  async function runCasdoorProductPurchase(purchaseRequest, apiClient, loaders) {
133
197
  const buyProductLoader = loaders?.buyProductLoader ?? apiClient.buyProduct;
134
198
  if (!buyProductLoader) {
@@ -296,9 +360,12 @@ function BillingProvider({
296
360
  const resolvedLoaders = loaders ?? {};
297
361
  const subscriptionLoader = resolvedLoaders.subscriptionLoader ?? apiClient.fetchSubscription;
298
362
  const subscriptionHistoryLoader = resolvedLoaders.subscriptionHistoryLoader ?? apiClient.fetchSubscriptionHistory;
363
+ const subscriptionsLoader = resolvedLoaders.subscriptionsLoader ?? apiClient.fetchSubscriptions;
299
364
  const productsLoader = resolvedLoaders.productsLoader ?? apiClient.fetchProducts;
300
365
  const orderHistoryLoader = resolvedLoaders.orderHistoryLoader ?? apiClient.fetchOrderHistory;
366
+ const ordersLoader = resolvedLoaders.ordersLoader ?? apiClient.fetchOrders;
301
367
  const paymentHistoryLoader = resolvedLoaders.paymentHistoryLoader ?? apiClient.fetchPaymentHistory;
368
+ const paymentLoader = resolvedLoaders.paymentLoader ?? apiClient.fetchPayment;
302
369
  const purchaseStatusLoader = resolvedLoaders.purchaseStatusLoader ?? apiClient.fetchPurchaseStatus;
303
370
  const creditsLoader = resolvedLoaders.creditsLoader ?? apiClient.fetchCredits;
304
371
  const entitlementsLoader = resolvedLoaders.entitlementsLoader ?? apiClient.fetchEntitlements;
@@ -313,31 +380,74 @@ function BillingProvider({
313
380
  setRuntimeConfig(nextRuntimeConfig);
314
381
  }
315
382
  const nextCatalogKey = nextRuntimeConfig?.catalogKey ?? nextRuntimeCatalog?.catalogKey ?? catalogKey;
383
+ const nextSubscriptionsResponsePromise = subscriptionsLoader ? subscriptionsLoader({}).catch(() => void 0) : Promise.resolve(void 0);
384
+ const nextOrdersResponsePromise = ordersLoader ? ordersLoader({}).catch(() => void 0) : Promise.resolve(void 0);
316
385
  const [
317
386
  nextSubscription,
318
387
  nextSubscriptionHistory,
388
+ nextSubscriptionsResponse,
319
389
  nextProducts,
320
390
  nextOrderHistory,
391
+ nextOrdersResponse,
321
392
  nextPaymentHistory,
322
393
  nextCredits,
323
394
  nextEntitlements
324
395
  ] = await Promise.all([
325
396
  subscriptionLoader({ catalogKey: nextCatalogKey }),
326
397
  subscriptionHistoryLoader({ catalogKey: nextCatalogKey }),
398
+ nextSubscriptionsResponsePromise,
327
399
  productsLoader({ catalogKey: nextCatalogKey }),
328
400
  orderHistoryLoader({ catalogKey: nextCatalogKey }),
401
+ nextOrdersResponsePromise,
329
402
  paymentHistoryLoader({ catalogKey: nextCatalogKey }),
330
403
  creditsLoader({ catalogKey: nextCatalogKey }),
331
404
  entitlementsLoader({ catalogKey: nextCatalogKey })
332
405
  ]);
406
+ const casdoorSubscriptions = extractCasdoorResponseData(nextSubscriptionsResponse) ?? [];
407
+ const casdoorOrders = extractCasdoorResponseData(nextOrdersResponse) ?? [];
408
+ const derivedSubscriptionHistory = nextSubscriptionHistory ?? casdoorSubscriptions.map(normalizeCasdoorSubscriptionHistoryItem);
409
+ const derivedOrderHistory = nextOrderHistory ?? casdoorOrders.map(normalizeCasdoorOrderHistoryItem);
410
+ let resolvedPaymentHistory = nextPaymentHistory;
411
+ if ((!resolvedPaymentHistory || resolvedPaymentHistory.length === 0) && casdoorOrders.length && paymentLoader) {
412
+ const latestCasdoorOrder = pickLatestCasdoorOrder(casdoorOrders);
413
+ const paymentId = latestCasdoorOrder?.payment ?? latestCasdoorOrder?.transaction;
414
+ if (paymentId) {
415
+ const paymentResponse = await paymentLoader({ id: paymentId }).catch(() => void 0);
416
+ const paymentDetail = extractCasdoorResponseData(paymentResponse);
417
+ if (paymentDetail?.name) {
418
+ resolvedPaymentHistory = [
419
+ normalizeCasdoorPaymentHistoryItem({
420
+ name: paymentDetail.name,
421
+ order: paymentDetail.order,
422
+ outOrderId: paymentDetail.outOrderId,
423
+ product: paymentDetail.product ?? paymentDetail.productName,
424
+ productName: paymentDetail.productName,
425
+ productDisplayName: paymentDetail.productDisplayName,
426
+ price: paymentDetail.price,
427
+ currency: paymentDetail.currency,
428
+ state: paymentDetail.state,
429
+ transactionId: paymentDetail.transactionId,
430
+ createdTime: paymentDetail.createdTime,
431
+ updatedTime: paymentDetail.updatedTime
432
+ })
433
+ ];
434
+ }
435
+ }
436
+ }
333
437
  const subscriptionWithProduct = nextSubscription ? {
334
438
  ...nextSubscription,
335
439
  product: resolveBillingSubscriptionProduct(nextSubscription, nextRuntimeConfig ?? runtimeConfig)
336
- } : void 0;
440
+ } : (() => {
441
+ const derivedSubscription = normalizeCasdoorSubscriptionDetail(pickCurrentCasdoorSubscription(casdoorSubscriptions));
442
+ return derivedSubscription ? {
443
+ ...derivedSubscription,
444
+ product: resolveBillingSubscriptionProduct(derivedSubscription, nextRuntimeConfig ?? runtimeConfig)
445
+ } : void 0;
446
+ })();
337
447
  const normalizedCredits = deriveBillingCreditsState(nextCredits, nextProducts, nextRuntimeConfig?.conversionRules ?? runtimeConfig?.conversionRules);
338
448
  const normalizedEntitlements = nextEntitlements ?? deriveBillingEntitlements(subscriptionWithProduct, nextProducts, normalizedCredits, nextRuntimeConfig ?? runtimeConfig);
339
- const latestOrder = getLatestOrder(nextOrderHistory);
340
- const latestPayment = getLatestPayment(nextPaymentHistory);
449
+ const latestOrder = getLatestOrder(derivedOrderHistory);
450
+ const latestPayment = getLatestPayment(resolvedPaymentHistory);
341
451
  const fetchedPurchaseStatus = await purchaseStatusLoader({
342
452
  orderId: latestOrder?.orderId,
343
453
  paymentId: latestPayment?.paymentId,
@@ -349,10 +459,10 @@ function BillingProvider({
349
459
  latestPayment
350
460
  );
351
461
  setSubscription(subscriptionWithProduct);
352
- setSubscriptionHistory(nextSubscriptionHistory);
462
+ setSubscriptionHistory(derivedSubscriptionHistory);
353
463
  setProducts(nextProducts);
354
- setOrderHistory(nextOrderHistory);
355
- setPaymentHistory(nextPaymentHistory);
464
+ setOrderHistory(derivedOrderHistory);
465
+ setPaymentHistory(resolvedPaymentHistory);
356
466
  setCredits(normalizedCredits);
357
467
  setEntitlements(normalizedEntitlements);
358
468
  setPurchaseStatus(normalizedPurchaseStatus);
@@ -755,6 +865,166 @@ function useBillingProductPurchaseOptions(productId, preferredProviderName) {
755
865
  [detailState.error, detailState.loading, detailState.product, detailState.refresh, providerName]
756
866
  );
757
867
  }
868
+ function useBillingPricing(pricingId) {
869
+ const core = useRequiredCoreContext();
870
+ const loader = core.loaders?.pricingLoader ?? core.apiClient.fetchPricing;
871
+ return useBillingCasdoorQuery(
872
+ loader,
873
+ useCallback(() => ({ id: pricingId }), [pricingId]),
874
+ [pricingId, loader],
875
+ "Missing billing pricing loader."
876
+ );
877
+ }
878
+ function useBillingPlan(planId, includeOption = false) {
879
+ const core = useRequiredCoreContext();
880
+ const loader = core.loaders?.planLoader ?? core.apiClient.fetchPlan;
881
+ return useBillingCasdoorQuery(
882
+ loader,
883
+ useCallback(() => ({ id: planId, includeOption }), [includeOption, planId]),
884
+ [includeOption, loader, planId],
885
+ "Missing billing plan loader."
886
+ );
887
+ }
888
+ function useBillingOrder(orderId) {
889
+ const core = useRequiredCoreContext();
890
+ const loader = core.loaders?.orderLoader ?? core.apiClient.fetchOrder;
891
+ return useBillingCasdoorQuery(
892
+ loader,
893
+ useCallback(() => ({ id: orderId }), [orderId]),
894
+ [loader, orderId],
895
+ "Missing billing order loader."
896
+ );
897
+ }
898
+ function useBillingSubscriptionRecord(subscriptionId) {
899
+ const core = useRequiredCoreContext();
900
+ const loader = core.loaders?.subscriptionRecordLoader ?? core.apiClient.fetchSubscriptionRecord;
901
+ return useBillingCasdoorQuery(
902
+ loader,
903
+ useCallback(() => ({ id: subscriptionId }), [subscriptionId]),
904
+ [loader, subscriptionId],
905
+ "Missing billing subscription loader."
906
+ );
907
+ }
908
+ function useBillingOrders(options = {}) {
909
+ const core = useRequiredCoreContext();
910
+ const loader = core.loaders?.ordersLoader ?? core.apiClient.fetchOrders;
911
+ const owner = options.owner;
912
+ const user = options.user;
913
+ const product = options.product;
914
+ return useBillingCasdoorQuery(
915
+ loader,
916
+ useCallback(() => ({ owner, user, product }), [owner, product, user]),
917
+ [loader, owner, product, user],
918
+ "Missing billing orders loader."
919
+ );
920
+ }
921
+ function useBillingSubscriptions(options = {}) {
922
+ const core = useRequiredCoreContext();
923
+ const loader = core.loaders?.subscriptionsLoader ?? core.apiClient.fetchSubscriptions;
924
+ const owner = options.owner;
925
+ const user = options.user;
926
+ return useBillingCasdoorQuery(
927
+ loader,
928
+ useCallback(() => ({ owner, user }), [owner, user]),
929
+ [loader, owner, user],
930
+ "Missing billing subscriptions loader."
931
+ );
932
+ }
933
+ function useBillingPricingPlans(pricingId, includeOption = false, preferredPlanName) {
934
+ const pricingState = useBillingPricing(pricingId);
935
+ const core = useRequiredCoreContext();
936
+ const [selectedPlanName, setSelectedPlanName] = useState(preferredPlanName);
937
+ const planLoader = core.loaders?.planLoader ?? core.apiClient.fetchPlan;
938
+ const [plans, setPlans] = useState([]);
939
+ const [planLoading, setPlanLoading] = useState(false);
940
+ const [planError, setPlanError] = useState(null);
941
+ useEffect(() => {
942
+ if (preferredPlanName) {
943
+ setSelectedPlanName(preferredPlanName);
944
+ }
945
+ }, [preferredPlanName]);
946
+ useEffect(() => {
947
+ const nextPlanName = selectedPlanName ?? pricingState.data?.plans?.[0];
948
+ if (!nextPlanName || selectedPlanName && pricingState.data?.plans && !pricingState.data.plans.includes(selectedPlanName)) {
949
+ setSelectedPlanName(pricingState.data?.plans?.[0]);
950
+ return;
951
+ }
952
+ if (!selectedPlanName && nextPlanName) {
953
+ setSelectedPlanName(nextPlanName);
954
+ }
955
+ }, [pricingState.data?.plans, selectedPlanName]);
956
+ const refreshPlans = useCallback(async () => {
957
+ if (!planLoader) {
958
+ setPlans([]);
959
+ setPlanError("Missing billing plan loader.");
960
+ setPlanLoading(false);
961
+ return;
962
+ }
963
+ const planNames = pricingState.data?.plans ?? [];
964
+ if (!planNames.length) {
965
+ setPlans([]);
966
+ setPlanError(null);
967
+ setPlanLoading(false);
968
+ return;
969
+ }
970
+ setPlanLoading(true);
971
+ setPlanError(null);
972
+ try {
973
+ const results = await Promise.all(
974
+ planNames.map(async (planName) => {
975
+ const response = await planLoader({ id: planName, includeOption });
976
+ return extractCasdoorResponseData(response);
977
+ })
978
+ );
979
+ setPlans(results.filter((plan) => Boolean(plan)));
980
+ } catch (err) {
981
+ const message = err instanceof Error ? err.message : String(err);
982
+ setPlans([]);
983
+ setPlanError(message);
984
+ } finally {
985
+ setPlanLoading(false);
986
+ }
987
+ }, [includeOption, planLoader, pricingState.data?.plans]);
988
+ useEffect(() => {
989
+ void refreshPlans();
990
+ }, [refreshPlans]);
991
+ const selectedPlan = useMemo(
992
+ () => plans.find((plan) => plan.name === selectedPlanName) ?? (plans.length === 1 ? plans[0] : void 0),
993
+ [plans, selectedPlanName]
994
+ );
995
+ return useMemo(
996
+ () => ({
997
+ pricing: pricingState.data,
998
+ plans,
999
+ selectedPlanName,
1000
+ selectedPlan,
1001
+ setSelectedPlanName,
1002
+ loading: pricingState.loading || planLoading,
1003
+ error: pricingState.error ?? planError,
1004
+ refresh: async () => {
1005
+ await pricingState.refresh();
1006
+ await refreshPlans();
1007
+ }
1008
+ }),
1009
+ [planError, planLoading, plans, pricingState, refreshPlans, selectedPlan, selectedPlanName]
1010
+ );
1011
+ }
1012
+ function useBillingSubscriptionPurchaseOptions(pricingId, includeOption = false, preferredPlanName) {
1013
+ const pricingPlans = useBillingPricingPlans(pricingId, includeOption, preferredPlanName);
1014
+ return useMemo(
1015
+ () => ({
1016
+ pricing: pricingPlans.pricing,
1017
+ plans: pricingPlans.plans,
1018
+ selectedPlanName: pricingPlans.selectedPlanName,
1019
+ selectedPlan: pricingPlans.selectedPlan,
1020
+ setSelectedPlanName: pricingPlans.setSelectedPlanName,
1021
+ loading: pricingPlans.loading,
1022
+ error: pricingPlans.error,
1023
+ refresh: pricingPlans.refresh
1024
+ }),
1025
+ [pricingPlans]
1026
+ );
1027
+ }
758
1028
  function useBillingProducts() {
759
1029
  const core = useRequiredCoreContext();
760
1030
  const productContext = useOptionalContext(BillingProductContext);
@@ -1020,9 +1290,14 @@ export {
1020
1290
  useBillingCredits,
1021
1291
  useBillingEntitlements,
1022
1292
  useBillingItem,
1293
+ useBillingOrder,
1023
1294
  useBillingOrderHistory,
1295
+ useBillingOrders,
1024
1296
  useBillingPaymentHistory,
1025
1297
  useBillingPipeline,
1298
+ useBillingPlan,
1299
+ useBillingPricing,
1300
+ useBillingPricingPlans,
1026
1301
  useBillingProduct,
1027
1302
  useBillingProductDetail,
1028
1303
  useBillingProductPurchaseOptions,
@@ -1033,6 +1308,9 @@ export {
1033
1308
  useBillingSubscription,
1034
1309
  useBillingSubscriptionHistory,
1035
1310
  useBillingSubscriptionProduct,
1311
+ useBillingSubscriptionPurchaseOptions,
1312
+ useBillingSubscriptionRecord,
1313
+ useBillingSubscriptions,
1036
1314
  useCancelSubscription,
1037
1315
  useManageSubscription,
1038
1316
  usePurchaseProduct,