@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
|
|
720
|
-
|
|
721
|
-
|
|
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,
|
|
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:
|
|
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
|
|
766
|
-
if (
|
|
767
|
-
console.error('🎮 [ProductsStore]: Error loading
|
|
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:
|
|
868
|
+
error: error.message,
|
|
777
869
|
});
|
|
870
|
+
return;
|
|
778
871
|
}
|
|
779
|
-
if (
|
|
780
|
-
{
|
|
781
|
-
|
|
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
|
|
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
|
-
|
|
809
|
-
|
|
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
|
-
|
|
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,
|
|
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
|