@dotted-labs/ngx-supabase-stripe 0.6.4 → 0.6.5

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.
@@ -705,6 +705,102 @@ var Currency;
705
705
  Currency["INR"] = "inr";
706
706
  })(Currency || (Currency = {}));
707
707
 
708
+ class ProductsService {
709
+ supabaseService = inject(SupabaseClientService);
710
+ /**
711
+ * Map a Stripe product row plus price rows to the public shape used by the UI.
712
+ */
713
+ toStripeProductPublic(product, prices = []) {
714
+ return this.parseProduct(product, prices);
715
+ }
716
+ /**
717
+ * Load all Stripe prices and products, returning parsed public products.
718
+ */
719
+ async fetchFullCatalog() {
720
+ const [pricesResult, productsResult] = await Promise.all([
721
+ this.supabaseService.selectStripePrices(),
722
+ this.supabaseService.selectStripeProducts(),
723
+ ]);
724
+ const pricesError = pricesResult.error;
725
+ const productsError = productsResult.error;
726
+ if (pricesError) {
727
+ return { data: null, error: pricesError };
728
+ }
729
+ if (productsError) {
730
+ return { data: null, error: productsError };
731
+ }
732
+ const prices = (pricesResult.data ?? []);
733
+ const stripeProducts = (productsResult.data ?? []);
734
+ const products = stripeProducts.map((product) => this.parseProduct(product, prices));
735
+ return { data: { prices, products }, error: null };
736
+ }
737
+ /**
738
+ * Load prices and a single product by id, returning parsed public product(s).
739
+ */
740
+ async fetchProductById(id) {
741
+ const [pricesResult, productResult] = await Promise.all([
742
+ this.supabaseService.selectStripePrices(),
743
+ this.supabaseService.selectStripeProduct(id),
744
+ ]);
745
+ const pricesError = pricesResult.error;
746
+ const productError = productResult.error;
747
+ if (pricesError) {
748
+ return { data: [], error: pricesError };
749
+ }
750
+ if (productError) {
751
+ return { data: [], error: productError };
752
+ }
753
+ const prices = (pricesResult.data ?? []);
754
+ const rows = productResult.data;
755
+ if (!rows?.length) {
756
+ return { data: [], error: null };
757
+ }
758
+ return { data: [this.parseProduct(rows[0], prices)], error: null };
759
+ }
760
+ /**
761
+ * Load prices and products for the given Stripe product ids.
762
+ */
763
+ async fetchProductsByIds(ids) {
764
+ const [pricesResult, productsResult] = await Promise.all([
765
+ this.supabaseService.selectStripePrices(),
766
+ this.supabaseService.selectStripeProductsByIds(ids),
767
+ ]);
768
+ const pricesError = pricesResult.error;
769
+ const productsError = productsResult.error;
770
+ if (pricesError) {
771
+ return { data: [], error: pricesError };
772
+ }
773
+ if (productsError) {
774
+ return { data: [], error: productsError };
775
+ }
776
+ const prices = (pricesResult.data ?? []);
777
+ const stripeProducts = (productsResult.data ?? []);
778
+ const products = stripeProducts.map((product) => this.parseProduct(product, prices));
779
+ return { data: products, error: null };
780
+ }
781
+ parseProduct(product, prices = []) {
782
+ const { attrs, ...mainProperties } = product;
783
+ return {
784
+ ...mainProperties,
785
+ images: attrs?.images ?? [],
786
+ prices: prices
787
+ .filter((price) => price.product === product.id)
788
+ .map((price) => ({
789
+ details: price,
790
+ recurringInterval: price?.attrs?.recurring?.interval ?? 'no-recurring',
791
+ })),
792
+ };
793
+ }
794
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ProductsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
795
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ProductsService, providedIn: 'root' });
796
+ }
797
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ProductsService, decorators: [{
798
+ type: Injectable,
799
+ args: [{
800
+ providedIn: 'root',
801
+ }]
802
+ }] });
803
+
708
804
  const initialProductsState = {
709
805
  products: null,
710
806
  prices: null,
@@ -716,17 +812,23 @@ const ProductsStore = signalStore({ providedIn: 'root' }, withState(initialProdu
716
812
  isStatusLoading: computed(() => state.status() === 'loading'),
717
813
  isStatusSuccess: computed(() => state.status() === 'success'),
718
814
  isStatusError: computed(() => state.status() === 'error'),
719
- oneTimeproductsByCurrency: computed(() => state.products()?.filter(product => product.prices.some(price => (price.details.type === 'one_time' && price.details.currency === state.currency()))) || []),
720
- recurringProductsByCurrency: computed(() => state.products()?.filter(product => product.prices.some(price => (price.details.type === 'recurring' && price.details.currency === state.currency()))) || []),
721
- productsByCurrency: computed(() => state.products()?.filter(product => product.prices.some(price => (price.details.currency === state.currency()))) || []),
815
+ oneTimeproductsByCurrency: computed(() => state
816
+ .products()
817
+ ?.filter((product) => product.prices.some((price) => price.details.type === 'one_time' && price.details.currency === state.currency())) || []),
818
+ recurringProductsByCurrency: computed(() => state
819
+ .products()
820
+ ?.filter((product) => product.prices.some((price) => price.details.type === 'recurring' && price.details.currency === state.currency())) || []),
821
+ productsByCurrency: computed(() => state
822
+ .products()
823
+ ?.filter((product) => product.prices.some((price) => price.details.currency === state.currency())) || []),
722
824
  hasProducts: computed(() => state.products() !== null && state.products().length > 0),
723
- isError: computed(() => state.error())
724
- })), withMethods((store, supabaseService = inject(SupabaseClientService)) => ({
825
+ isError: computed(() => state.error()),
826
+ })), withMethods((store, productsService = inject(ProductsService)) => ({
725
827
  /**
726
828
  * Get products by IDs from the current loaded products
727
829
  */
728
830
  getProductsByIds(ids) {
729
- return store.products()?.filter(product => product.id && ids.includes(product.id)) || [];
831
+ return store.products()?.filter((product) => product.id && ids.includes(product.id)) || [];
730
832
  },
731
833
  /**
732
834
  * Set the currency filter for products
@@ -740,15 +842,11 @@ const ProductsStore = signalStore({ providedIn: 'root' }, withState(initialProdu
740
842
  async loadProductById(id) {
741
843
  patchState(store, { status: 'loading', error: null });
742
844
  try {
743
- const { data: product, error: productError } = await supabaseService.selectStripeProduct(id);
845
+ const { data: products, error: productError } = await productsService.fetchProductById(id);
744
846
  if (productError) {
745
847
  console.error('🎮 [ProductsStore]: Error loading product', productError);
746
848
  patchState(store, { status: 'error', error: productError.message });
747
- }
748
- const products = [];
749
- if (product && product.length > 0) {
750
- const productParsed = parseProduct(product[0], store.prices());
751
- products.push(productParsed);
849
+ return;
752
850
  }
753
851
  patchState(store, { status: 'success', products });
754
852
  }
@@ -762,33 +860,25 @@ const ProductsStore = signalStore({ providedIn: 'root' }, withState(initialProdu
762
860
  async loadProducts() {
763
861
  patchState(store, { status: 'loading', error: null });
764
862
  try {
765
- const { data: prices, error: pricesError } = await supabaseService.selectStripePrices();
766
- if (pricesError) {
767
- console.error('🎮 [ProductsStore]: Error loading prices', pricesError);
768
- patchState(store, { status: 'error', error: pricesError.message });
769
- }
770
- patchState(store, { prices: prices || [] });
771
- const { data: stripeProducts, error: productsError } = await supabaseService.selectStripeProducts();
772
- if (productsError) {
773
- console.error('🎮 [ProductsStore]: Error loading products', productsError);
863
+ const { data, error } = await productsService.fetchFullCatalog();
864
+ if (error) {
865
+ console.error('🎮 [ProductsStore]: Error loading catalog', error);
774
866
  patchState(store, {
775
867
  status: 'error',
776
- error: productsError.message,
868
+ error: error.message,
777
869
  });
870
+ return;
778
871
  }
779
- if (stripeProducts) {
780
- {
781
- const products = [];
782
- stripeProducts.forEach(product => {
783
- products.push(parseProduct(product, store.prices()));
784
- });
785
- console.log('🎮 [ProductsStore] products: ', products);
786
- patchState(store, {
787
- status: 'success',
788
- products: products
789
- });
790
- }
872
+ if (!data) {
873
+ patchState(store, { status: 'success', prices: [], products: [] });
874
+ return;
791
875
  }
876
+ console.log('🎮 [ProductsStore] products: ', data.products);
877
+ patchState(store, {
878
+ status: 'success',
879
+ prices: data.prices,
880
+ products: data.products,
881
+ });
792
882
  }
793
883
  catch (error) {
794
884
  patchState(store, {
@@ -800,14 +890,17 @@ const ProductsStore = signalStore({ providedIn: 'root' }, withState(initialProdu
800
890
  async loadProductsByIds(ids) {
801
891
  patchState(store, { status: 'loading', error: null });
802
892
  try {
803
- const { data: products, error: productsError } = await supabaseService.selectStripeProductsByIds(ids);
893
+ const { data: products, error: productsError } = await productsService.fetchProductsByIds(ids);
804
894
  if (productsError) {
805
895
  console.error('🎮 [ProductsStore]: Error loading products', productsError);
806
896
  patchState(store, { status: 'error', error: productsError.message });
897
+ return;
807
898
  }
808
- if (products) {
809
- const products = [];
810
- }
899
+ console.log('🎮 [ProductsStore] products: ', products);
900
+ patchState(store, {
901
+ status: 'success',
902
+ products,
903
+ });
811
904
  }
812
905
  catch (error) {
813
906
  patchState(store, { status: 'error', error: error.message });
@@ -818,7 +911,7 @@ const ProductsStore = signalStore({ providedIn: 'root' }, withState(initialProdu
818
911
  */
819
912
  reset() {
820
913
  patchState(store, initialProductsState);
821
- }
914
+ },
822
915
  })), withHooks((store) => ({
823
916
  async onInit() {
824
917
  console.log('🎮 [ProductsStore] onInit');
@@ -828,19 +921,8 @@ const ProductsStore = signalStore({ providedIn: 'root' }, withState(initialProdu
828
921
  console.log('🎮 [ProductsStore] loading products...');
829
922
  await store.loadProducts();
830
923
  }
831
- }
924
+ },
832
925
  })));
833
- function parseProduct(product, prices = []) {
834
- const { attrs, ...mainProperties } = product;
835
- return {
836
- ...mainProperties,
837
- images: attrs?.images || [],
838
- prices: prices.filter(price => price.product === product.id).map(price => ({
839
- details: price,
840
- recurringInterval: price?.attrs?.recurring?.interval || 'no-recurring'
841
- }))
842
- };
843
- }
844
926
 
845
927
  const initialSubscriptionState = {
846
928
  subscriptions: null,
@@ -855,7 +937,7 @@ const SubscriptionsStore = signalStore({ providedIn: 'root' }, withState(initial
855
937
  isStatusError: computed(() => state.status() === 'error'),
856
938
  hasSubscriptions: computed(() => state.subscriptions() !== null && state.subscriptions().length > 0),
857
939
  isError: computed(() => state.error()),
858
- })), withMethods((store, stripeService = inject(StripeClientService), supabaseService = inject(SupabaseClientService), productsStore = inject(ProductsStore), customerStore = inject(CustomerStore)) => ({
940
+ })), withMethods((store, stripeService = inject(StripeClientService), supabaseService = inject(SupabaseClientService), productsStore = inject(ProductsStore), productsService = inject(ProductsService), customerStore = inject(CustomerStore)) => ({
859
941
  /**
860
942
  * Create a subscription
861
943
  * @param priceId The price ID for the subscription
@@ -913,7 +995,7 @@ const SubscriptionsStore = signalStore({ providedIn: 'root' }, withState(initial
913
995
  const prices = (productsStore.prices() ?? []);
914
996
  const userProductsById = new Map((userStripeProducts ?? []).map((p) => [
915
997
  p.id,
916
- parseProduct(p, prices),
998
+ productsService.toStripeProductPublic(p, prices),
917
999
  ]));
918
1000
  console.log('🔍 [SubscriptionsStore] loaded subscriptions', subscriptions);
919
1001
  const parsedSubscriptions = subscriptions?.map((subscription) => {
@@ -2112,5 +2194,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2112
2194
  * Generated bundle index. Do not edit.
2113
2195
  */
2114
2196
 
2115
- export { CheckoutStore, Currency, CustomerDashboardComponent, CustomerStore, EmbeddedCheckoutComponent, EmbeddedSubscriptionComponent, PaymentIntentsListComponent, PaymentIntentsTableComponent, PortalAccountStore, ProductItemButtonComponent, ProductListComponent, ProductsStore, ReturnPageComponent, STRIPE_CONFIG, SUPABASE_BROWSER_CLIENT, SUPABASE_CONFIG, StripeClientService, SubscriptionCardComponent, SubscriptionReturnPageComponent, SubscriptionsListComponent, SubscriptionsStore, SupabaseClientService, parsePaymentIntent, parseProduct, parseSubscription, provideNgxSupabaseStripeConfig, provideStripeConfig, provideSupabaseConfig };
2197
+ export { CheckoutStore, Currency, CustomerDashboardComponent, CustomerStore, EmbeddedCheckoutComponent, EmbeddedSubscriptionComponent, PaymentIntentsListComponent, PaymentIntentsTableComponent, PortalAccountStore, ProductItemButtonComponent, ProductListComponent, ProductsService, ProductsStore, ReturnPageComponent, STRIPE_CONFIG, SUPABASE_BROWSER_CLIENT, SUPABASE_CONFIG, StripeClientService, SubscriptionCardComponent, SubscriptionReturnPageComponent, SubscriptionsListComponent, SubscriptionsStore, SupabaseClientService, parsePaymentIntent, parseSubscription, provideNgxSupabaseStripeConfig, provideStripeConfig, provideSupabaseConfig };
2116
2198
  //# sourceMappingURL=dotted-labs-ngx-supabase-stripe.mjs.map