@revealui/services 0.0.2 → 0.1.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 (112) hide show
  1. package/LICENSE +22 -202
  2. package/LICENSE.commercial +112 -0
  3. package/README.md +177 -0
  4. package/dist/api/create-checkout-session/index.d.ts +2 -0
  5. package/dist/api/create-checkout-session/index.d.ts.map +1 -0
  6. package/dist/api/create-checkout-session/index.js +61 -0
  7. package/dist/api/create-checkout-session/index.js.map +1 -0
  8. package/dist/api/create-portal-link/index.d.ts +2 -0
  9. package/dist/api/create-portal-link/index.d.ts.map +1 -0
  10. package/dist/api/create-portal-link/index.js +37 -0
  11. package/dist/api/create-portal-link/index.js.map +1 -0
  12. package/dist/api/handlers/customer-handlers.d.ts +27 -0
  13. package/dist/api/handlers/customer-handlers.d.ts.map +1 -0
  14. package/dist/api/handlers/customer-handlers.js +86 -0
  15. package/dist/api/handlers/customer-handlers.js.map +1 -0
  16. package/dist/api/handlers/index.d.ts +18 -0
  17. package/dist/api/handlers/index.d.ts.map +1 -0
  18. package/dist/api/handlers/index.js +18 -0
  19. package/dist/api/handlers/index.js.map +1 -0
  20. package/dist/api/handlers/invoice-handlers.d.ts +9 -0
  21. package/dist/api/handlers/invoice-handlers.d.ts.map +1 -0
  22. package/dist/api/handlers/invoice-handlers.js +52 -0
  23. package/dist/api/handlers/invoice-handlers.js.map +1 -0
  24. package/dist/api/handlers/payment-handlers.d.ts +13 -0
  25. package/dist/api/handlers/payment-handlers.d.ts.map +1 -0
  26. package/dist/api/handlers/payment-handlers.js +133 -0
  27. package/dist/api/handlers/payment-handlers.js.map +1 -0
  28. package/dist/api/handlers/payment-intent.d.ts +21 -0
  29. package/dist/api/handlers/payment-intent.d.ts.map +1 -0
  30. package/dist/api/handlers/payment-intent.js +87 -0
  31. package/dist/api/handlers/payment-intent.js.map +1 -0
  32. package/dist/api/handlers/product-handlers.d.ts +11 -0
  33. package/dist/api/handlers/product-handlers.d.ts.map +1 -0
  34. package/dist/api/handlers/product-handlers.js +43 -0
  35. package/dist/api/handlers/product-handlers.js.map +1 -0
  36. package/dist/api/handlers/subscription-handlers.d.ts +13 -0
  37. package/dist/api/handlers/subscription-handlers.d.ts.map +1 -0
  38. package/dist/api/handlers/subscription-handlers.js +115 -0
  39. package/dist/api/handlers/subscription-handlers.js.map +1 -0
  40. package/dist/api/index.d.ts +8 -0
  41. package/dist/api/index.d.ts.map +1 -0
  42. package/dist/api/index.js +8 -0
  43. package/dist/api/index.js.map +1 -0
  44. package/dist/api/types/stripe.d.ts +42 -0
  45. package/dist/api/types/stripe.d.ts.map +1 -0
  46. package/dist/api/types/stripe.js +72 -0
  47. package/dist/api/types/stripe.js.map +1 -0
  48. package/dist/api/update-price/index.d.ts +42 -0
  49. package/dist/api/update-price/index.d.ts.map +1 -0
  50. package/dist/api/update-price/index.js +78 -0
  51. package/dist/api/update-price/index.js.map +1 -0
  52. package/dist/api/update-product/index.d.ts +44 -0
  53. package/dist/api/update-product/index.d.ts.map +1 -0
  54. package/dist/api/update-product/index.js +85 -0
  55. package/dist/api/update-product/index.js.map +1 -0
  56. package/dist/api/utils.d.ts +34 -0
  57. package/dist/api/utils.d.ts.map +1 -0
  58. package/dist/api/utils.js +66 -0
  59. package/dist/api/utils.js.map +1 -0
  60. package/dist/api/webhooks/index.d.ts +2 -0
  61. package/dist/api/webhooks/index.d.ts.map +1 -0
  62. package/dist/api/webhooks/index.js +270 -0
  63. package/dist/api/webhooks/index.js.map +1 -0
  64. package/dist/client/index.d.ts +11 -0
  65. package/dist/client/index.d.ts.map +1 -0
  66. package/dist/client/index.js +12 -0
  67. package/dist/client/index.js.map +1 -0
  68. package/dist/index.d.ts +35 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +46 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/stripe/db-circuit-breaker.d.ts +47 -0
  73. package/dist/stripe/db-circuit-breaker.d.ts.map +1 -0
  74. package/dist/stripe/db-circuit-breaker.js +223 -0
  75. package/dist/stripe/db-circuit-breaker.js.map +1 -0
  76. package/dist/stripe/index.d.ts +2 -0
  77. package/dist/stripe/index.d.ts.map +1 -0
  78. package/dist/stripe/index.js +2 -0
  79. package/dist/stripe/index.js.map +1 -0
  80. package/dist/stripe/stripeClient.d.ts +126 -0
  81. package/dist/stripe/stripeClient.d.ts.map +1 -0
  82. package/dist/stripe/stripeClient.js +226 -0
  83. package/dist/stripe/stripeClient.js.map +1 -0
  84. package/dist/supabase/index.d.ts +6 -0
  85. package/dist/supabase/index.d.ts.map +1 -0
  86. package/dist/supabase/index.js +5 -0
  87. package/dist/supabase/index.js.map +1 -0
  88. package/dist/supabase/resilience.d.ts +50 -0
  89. package/dist/supabase/resilience.d.ts.map +1 -0
  90. package/dist/supabase/resilience.js +166 -0
  91. package/dist/supabase/resilience.js.map +1 -0
  92. package/dist/supabase/types.d.ts +206 -0
  93. package/dist/supabase/types.d.ts.map +1 -0
  94. package/dist/supabase/types.js +19 -0
  95. package/dist/supabase/types.js.map +1 -0
  96. package/dist/supabase/utils/client.d.ts +4 -0
  97. package/dist/supabase/utils/client.d.ts.map +1 -0
  98. package/dist/supabase/utils/client.js +12 -0
  99. package/dist/supabase/utils/client.js.map +1 -0
  100. package/dist/supabase/utils/server.d.ts +10 -0
  101. package/dist/supabase/utils/server.d.ts.map +1 -0
  102. package/dist/supabase/utils/server.js +49 -0
  103. package/dist/supabase/utils/server.js.map +1 -0
  104. package/dist/supabase/utils/web.d.ts +4 -0
  105. package/dist/supabase/utils/web.d.ts.map +1 -0
  106. package/dist/supabase/utils/web.js +37 -0
  107. package/dist/supabase/utils/web.js.map +1 -0
  108. package/package.json +70 -54
  109. package/dist/.vite/ssr-manifest.json +0 -209
  110. package/dist/assets/index-Bai9hEWd.js +0 -16
  111. package/dist/assets/index-Bai9hEWd.js.map +0 -1
  112. package/dist/index.html +0 -23
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Subscription event handlers for Stripe webhooks
3
+ */
4
+ import { logger } from '@revealui/core/utils/logger';
5
+ import { protectedStripe } from '../../stripe/stripeClient.js';
6
+ import { extractCustomerId } from '../types/stripe.js';
7
+ export const manageSubscriptionStatusChange = async (subscriptionId, customerId, createAction = false, supabase) => {
8
+ const { data: customerData, error: noCustomerError } = await supabase
9
+ .from('users')
10
+ .select('id')
11
+ .eq('stripe_customer_id', String(customerId))
12
+ .single();
13
+ if (noCustomerError)
14
+ throw noCustomerError;
15
+ const { id: uuid } = customerData;
16
+ const subscription = await protectedStripe.subscriptions.retrieve(subscriptionId);
17
+ const typedSubscription = subscription;
18
+ const subscriptionData = {
19
+ id: typedSubscription.id,
20
+ user_id: uuid,
21
+ metadata: typedSubscription.metadata,
22
+ status: typedSubscription.status,
23
+ price_id: typedSubscription.items.data[0]?.price?.id || null,
24
+ stripe_subscription_id: typedSubscription.id,
25
+ };
26
+ const { error } = await supabase.from('subscriptions').upsert([subscriptionData]);
27
+ if (error)
28
+ throw error;
29
+ logger.info('Inserted/updated subscription', {
30
+ subscriptionId: typedSubscription.id,
31
+ userId: uuid,
32
+ });
33
+ if (createAction && typedSubscription.default_payment_method && uuid) {
34
+ // Payment method update logic would go here
35
+ }
36
+ };
37
+ export const handleCheckoutSessionCompleted = async (event, supabase) => {
38
+ const checkoutSession = event.data.object;
39
+ const subscriptionId = typeof checkoutSession.subscription === 'string'
40
+ ? checkoutSession.subscription
41
+ : checkoutSession.subscription?.id;
42
+ const customerId = extractCustomerId(checkoutSession.customer);
43
+ if (!(subscriptionId && customerId)) {
44
+ throw new Error('Checkout session missing subscription or customer');
45
+ }
46
+ try {
47
+ await manageSubscriptionStatusChange(subscriptionId, customerId, true, supabase);
48
+ }
49
+ catch (error) {
50
+ if (error instanceof Error) {
51
+ handleSupabaseError(error);
52
+ }
53
+ else {
54
+ handleSupabaseError(new Error(String(error)));
55
+ }
56
+ }
57
+ };
58
+ export const handleCustomerSubscriptionDeleted = async (event, supabase) => {
59
+ const subscription = event.data.object;
60
+ const customerId = extractCustomerId(subscription.customer);
61
+ if (!customerId) {
62
+ throw new Error('Subscription missing customer');
63
+ }
64
+ try {
65
+ await manageSubscriptionStatusChange(subscription.id, customerId, false, supabase);
66
+ }
67
+ catch (error) {
68
+ if (error instanceof Error) {
69
+ handleSupabaseError(error);
70
+ }
71
+ else {
72
+ handleSupabaseError(new Error(String(error)));
73
+ }
74
+ }
75
+ };
76
+ export const handleCustomerSubscriptionCreated = async (event, supabase) => {
77
+ const subscription = event.data.object;
78
+ const customerId = extractCustomerId(subscription.customer);
79
+ if (!customerId) {
80
+ throw new Error('Subscription missing customer');
81
+ }
82
+ try {
83
+ await manageSubscriptionStatusChange(subscription.id, customerId, true, supabase);
84
+ }
85
+ catch (error) {
86
+ if (error instanceof Error) {
87
+ handleSupabaseError(error);
88
+ }
89
+ else {
90
+ handleSupabaseError(new Error(String(error)));
91
+ }
92
+ }
93
+ };
94
+ export const handleCustomerSubscriptionUpdated = async (event, supabase) => {
95
+ const subscription = event.data.object;
96
+ const customerId = extractCustomerId(subscription.customer);
97
+ if (!customerId) {
98
+ throw new Error('Subscription missing customer');
99
+ }
100
+ try {
101
+ await manageSubscriptionStatusChange(subscription.id, customerId, false, supabase);
102
+ }
103
+ catch (error) {
104
+ if (error instanceof Error) {
105
+ handleSupabaseError(error);
106
+ }
107
+ else {
108
+ handleSupabaseError(new Error(String(error)));
109
+ }
110
+ }
111
+ };
112
+ export const handleSupabaseError = (error) => {
113
+ logger.error('Supabase error', { error });
114
+ };
115
+ //# sourceMappingURL=subscription-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-handlers.js","sourceRoot":"","sources":["../../../src/api/handlers/subscription-handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { POST as createCheckoutSession } from './create-checkout-session/index.js';
2
+ import { POST as createPortalLink } from './create-portal-link/index.js';
3
+ import { POST as updatePrice } from './update-price/index.js';
4
+ import { POST as updateProduct } from './update-product/index.js';
5
+ import { createPaymentIntent } from './utils.js';
6
+ import { POST as webhooks } from './webhooks/index.js';
7
+ export { createCheckoutSession, createPortalLink, updatePrice, updateProduct, webhooks, createPaymentIntent, };
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAA;AAClF,OAAO,EAAE,IAAI,IAAI,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEtD,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,mBAAmB,GACpB,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { POST as createCheckoutSession } from './create-checkout-session/index.js';
2
+ import { POST as createPortalLink } from './create-portal-link/index.js';
3
+ import { POST as updatePrice } from './update-price/index.js';
4
+ import { POST as updateProduct } from './update-product/index.js';
5
+ import { createPaymentIntent } from './utils.js';
6
+ import { POST as webhooks } from './webhooks/index.js';
7
+ export { createCheckoutSession, createPortalLink, updatePrice, updateProduct, webhooks, createPaymentIntent, };
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAA;AAClF,OAAO,EAAE,IAAI,IAAI,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEtD,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,mBAAmB,GACpB,CAAA"}
@@ -0,0 +1,42 @@
1
+ import type { Stripe } from 'stripe';
2
+ /**
3
+ * Typed Stripe webhook event helper
4
+ * Ensures type safety when accessing event.data.object
5
+ */
6
+ export type StripeWebhookEvent<T extends Stripe.Event.Type> = Stripe.Event & {
7
+ type: T;
8
+ data: {
9
+ object: T extends keyof Stripe.Event.Data.Object ? Stripe.Event.Data.Object[T] : unknown;
10
+ };
11
+ };
12
+ /**
13
+ * Extended webhook event type for events not in standard Stripe.Event.Type
14
+ * Used for payment_method and setup_intent events
15
+ */
16
+ export type ExtendedStripeWebhookEvent<T extends string> = Omit<Stripe.Event, 'type' | 'data'> & {
17
+ type: T;
18
+ data: {
19
+ object: unknown;
20
+ };
21
+ };
22
+ /**
23
+ * Type guard to check if an object is a Stripe Customer
24
+ */
25
+ export declare function isStripeCustomer(obj: unknown): obj is Stripe.Customer;
26
+ /**
27
+ * Type guard to check if an object is a Stripe PaymentMethod
28
+ */
29
+ export declare function isStripePaymentMethod(obj: unknown): obj is Stripe.PaymentMethod;
30
+ /**
31
+ * Type guard to check if an object is a Stripe Subscription
32
+ */
33
+ export declare function isStripeSubscription(obj: unknown): obj is Stripe.Subscription;
34
+ /**
35
+ * Type guard to check if an object is a Stripe CheckoutSession
36
+ */
37
+ export declare function isStripeCheckoutSession(obj: unknown): obj is Stripe.Checkout.Session;
38
+ /**
39
+ * Helper to safely extract customer ID from various Stripe objects
40
+ */
41
+ export declare function extractCustomerId(obj: Stripe.Customer | Stripe.DeletedCustomer | Stripe.PaymentMethod | Stripe.Subscription | Stripe.Checkout.Session | string | null | undefined): string | null;
42
+ //# sourceMappingURL=stripe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../../src/api/types/stripe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEpC;;;GAGG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,GAAG;IAC3E,IAAI,EAAE,CAAC,CAAA;IACP,IAAI,EAAE;QACJ,MAAM,EAAE,CAAC,SAAS,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAA;KACzF,CAAA;CACF,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG;IAC/F,IAAI,EAAE,CAAC,CAAA;IACP,IAAI,EAAE;QACJ,MAAM,EAAE,OAAO,CAAA;KAChB,CAAA;CACF,CAAA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,CAQrE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,aAAa,CAQ/E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,YAAY,CAQ7E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAQpF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EACC,MAAM,CAAC,QAAQ,GACf,MAAM,CAAC,eAAe,GACtB,MAAM,CAAC,aAAa,GACpB,MAAM,CAAC,YAAY,GACnB,MAAM,CAAC,QAAQ,CAAC,OAAO,GACvB,MAAM,GACN,IAAI,GACJ,SAAS,GACZ,MAAM,GAAG,IAAI,CA2Bf"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Type guard to check if an object is a Stripe Customer
3
+ */
4
+ export function isStripeCustomer(obj) {
5
+ return (typeof obj === 'object' &&
6
+ obj !== null &&
7
+ 'id' in obj &&
8
+ 'object' in obj &&
9
+ obj.object === 'customer');
10
+ }
11
+ /**
12
+ * Type guard to check if an object is a Stripe PaymentMethod
13
+ */
14
+ export function isStripePaymentMethod(obj) {
15
+ return (typeof obj === 'object' &&
16
+ obj !== null &&
17
+ 'id' in obj &&
18
+ 'object' in obj &&
19
+ obj.object === 'payment_method');
20
+ }
21
+ /**
22
+ * Type guard to check if an object is a Stripe Subscription
23
+ */
24
+ export function isStripeSubscription(obj) {
25
+ return (typeof obj === 'object' &&
26
+ obj !== null &&
27
+ 'id' in obj &&
28
+ 'object' in obj &&
29
+ obj.object === 'subscription');
30
+ }
31
+ /**
32
+ * Type guard to check if an object is a Stripe CheckoutSession
33
+ */
34
+ export function isStripeCheckoutSession(obj) {
35
+ return (typeof obj === 'object' &&
36
+ obj !== null &&
37
+ 'id' in obj &&
38
+ 'object' in obj &&
39
+ obj.object === 'checkout.session');
40
+ }
41
+ /**
42
+ * Helper to safely extract customer ID from various Stripe objects
43
+ */
44
+ export function extractCustomerId(obj) {
45
+ if (typeof obj === 'string') {
46
+ return obj;
47
+ }
48
+ if (obj === null || obj === undefined) {
49
+ return null;
50
+ }
51
+ if (typeof obj === 'object' && 'customer' in obj) {
52
+ const customer = obj.customer;
53
+ if (typeof customer === 'string') {
54
+ return customer;
55
+ }
56
+ if (typeof customer === 'object' && customer !== null) {
57
+ // Handle both Customer and DeletedCustomer
58
+ if ('id' in customer && typeof customer.id === 'string') {
59
+ return customer.id;
60
+ }
61
+ // DeletedCustomer has 'deleted' property
62
+ if ('deleted' in customer && customer.deleted === true && 'id' in customer) {
63
+ return typeof customer.id === 'string' ? customer.id : null;
64
+ }
65
+ }
66
+ }
67
+ if (typeof obj === 'object' && 'id' in obj && typeof obj.id === 'string') {
68
+ return obj.id;
69
+ }
70
+ return null;
71
+ }
72
+ //# sourceMappingURL=stripe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe.js","sourceRoot":"","sources":["../../../src/api/types/stripe.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,IAAI,IAAI,GAAG;QACX,QAAQ,IAAI,GAAG;QACd,GAA0B,CAAC,MAAM,KAAK,UAAU,CAClD,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAY;IAChD,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,IAAI,IAAI,GAAG;QACX,QAAQ,IAAI,GAAG;QACd,GAA0B,CAAC,MAAM,KAAK,gBAAgB,CACxD,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,IAAI,IAAI,GAAG;QACX,QAAQ,IAAI,GAAG;QACd,GAA0B,CAAC,MAAM,KAAK,cAAc,CACtD,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAY;IAClD,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,IAAI,IAAI,GAAG;QACX,QAAQ,IAAI,GAAG;QACd,GAA0B,CAAC,MAAM,KAAK,kBAAkB,CAC1D,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAQa;IAEb,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAA;QAC7B,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,QAAQ,CAAA;QACjB,CAAC;QACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtD,2CAA2C;YAC3C,IAAI,IAAI,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACxD,OAAO,QAAQ,CAAC,EAAE,CAAA;YACpB,CAAC;YACD,yCAAyC;YACzC,IAAI,SAAS,IAAI,QAAQ,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC3E,OAAO,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,IAAI,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QACzE,OAAO,GAAG,CAAC,EAAE,CAAA;IACf,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { VercelRequest, VercelResponse } from '@vercel/node';
2
+ import type Stripe from 'stripe';
3
+ interface RevealUIQueryResult {
4
+ docs?: Array<{
5
+ id: string | number;
6
+ }>;
7
+ }
8
+ interface RevealUIInstance {
9
+ find(arg0: {
10
+ collection: string;
11
+ where: {
12
+ stripeProductID: {
13
+ equals: string;
14
+ };
15
+ };
16
+ }): Promise<RevealUIQueryResult>;
17
+ update(arg0: {
18
+ collection: string;
19
+ id: string | number;
20
+ data: {
21
+ priceJSON: string;
22
+ skipSync: boolean;
23
+ };
24
+ }): Promise<unknown>;
25
+ logger: {
26
+ info: (message: string) => void;
27
+ error: (message: string) => void;
28
+ };
29
+ }
30
+ export type StripeWebhookHandler<T> = (args: {
31
+ event: Stripe.Event & T;
32
+ revealui: RevealUIInstance;
33
+ stripe: Stripe;
34
+ }) => Promise<void>;
35
+ export declare const updatePrice: StripeWebhookHandler<{
36
+ data: {
37
+ object: Stripe.Price;
38
+ };
39
+ }>;
40
+ export declare function POST(req: VercelRequest, res: VercelResponse): Promise<void>;
41
+ export {};
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/update-price/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACjE,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAEhC,UAAU,mBAAmB;IAC3B,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAA;CACtC;AAED,UAAU,gBAAgB;IACxB,IAAI,CAAC,IAAI,EAAE;QACT,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE;YAAE,eAAe,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAC/C,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAChC,MAAM,CAAC,IAAI,EAAE;QACX,UAAU,EAAE,MAAM,CAAA;QAClB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;QACnB,IAAI,EAAE;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,OAAO,CAAA;SAAE,CAAA;KAC/C,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;QAC/B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;KACjC,CAAA;CACF;AAED,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAA;IACvB,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;CACf,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAInB,eAAO,MAAM,WAAW,EAAE,oBAAoB,CAAC;IAC7C,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC,KAAK,CAAA;KACrB,CAAA;CACF,CAuEA,CAAA;AAQD,wBAAsB,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBjF"}
@@ -0,0 +1,78 @@
1
+ import { logger } from '@revealui/core/utils/logger';
2
+ const logs = false;
3
+ export const updatePrice = async (args) => {
4
+ const { event, revealui, stripe } = args;
5
+ const priceObject = event.data.object;
6
+ if (typeof priceObject !== 'object' ||
7
+ priceObject === null ||
8
+ !('product' in priceObject) ||
9
+ !('id' in priceObject)) {
10
+ revealui.logger.error('Invalid price object in Stripe event');
11
+ return;
12
+ }
13
+ const stripeProduct = priceObject.product;
14
+ const stripeProductID = typeof stripeProduct === 'string' ? stripeProduct : stripeProduct.id;
15
+ if (logs)
16
+ revealui.logger.info(`🪝 A price was created or updated in Stripe on product ID: ${stripeProductID}, syncing to RevealUI...`);
17
+ let revealuiProductID;
18
+ // First lookup the product in RevealUI
19
+ try {
20
+ if (logs)
21
+ revealui.logger.info(`- Looking up existing RevealUI product...`);
22
+ const productQuery = await revealui.find({
23
+ collection: 'products',
24
+ where: {
25
+ stripeProductID: {
26
+ equals: stripeProductID,
27
+ },
28
+ },
29
+ });
30
+ revealuiProductID = productQuery.docs?.[0]?.id;
31
+ if (revealuiProductID) {
32
+ if (logs)
33
+ revealui.logger.info(`- Found existing product with Stripe ID: ${stripeProductID}, saving price...`);
34
+ }
35
+ }
36
+ catch (err) {
37
+ const msg = err instanceof Error ? err.message : 'Unknown error';
38
+ revealui.logger.error(`Error finding product ${msg}`);
39
+ }
40
+ try {
41
+ // Find all stripe prices that are assigned to "revealuiProductID"
42
+ const stripePrices = await stripe.prices.list({
43
+ product: stripeProductID,
44
+ limit: 100,
45
+ });
46
+ await revealui.update({
47
+ collection: 'products',
48
+ id: revealuiProductID || '',
49
+ data: {
50
+ priceJSON: JSON.stringify(stripePrices),
51
+ skipSync: true,
52
+ },
53
+ });
54
+ if (logs)
55
+ revealui.logger.info(`✅ Successfully updated product price.`);
56
+ }
57
+ catch (error) {
58
+ const errorMessage = error instanceof Error ? error.message : String(error);
59
+ revealui.logger.error(`- Error updating product price: ${errorMessage}`);
60
+ }
61
+ };
62
+ export async function POST(req, res) {
63
+ if (req.method !== 'POST') {
64
+ res.status(405).send('Method Not Allowed');
65
+ return;
66
+ }
67
+ const { event, revealui, stripe } = req.body;
68
+ try {
69
+ await updatePrice({ event, revealui, stripe });
70
+ res.status(200).send('Product updated successfully');
71
+ }
72
+ catch (error) {
73
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
74
+ logger.error('Error updating product', { error: errorMessage });
75
+ res.status(500).send('Internal Server Error');
76
+ }
77
+ }
78
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/update-price/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { VercelRequest, VercelResponse } from '@vercel/node';
2
+ import type Stripe from 'stripe';
3
+ interface RevealUIQueryResult {
4
+ docs?: Array<{
5
+ id: string | number;
6
+ }>;
7
+ }
8
+ interface RevealUIInstance {
9
+ find(arg0: {
10
+ collection: string;
11
+ where: {
12
+ stripeProductID: {
13
+ equals: string;
14
+ };
15
+ };
16
+ }): Promise<RevealUIQueryResult>;
17
+ update(arg0: {
18
+ collection: string;
19
+ id: string | number;
20
+ data: {
21
+ priceJSON: string;
22
+ skipSync: boolean;
23
+ name: string;
24
+ description: string | null;
25
+ };
26
+ }): Promise<unknown>;
27
+ logger: {
28
+ info: (message: string) => void;
29
+ error: (message: string) => void;
30
+ };
31
+ }
32
+ export type StripeWebhookHandler<T> = (args: {
33
+ event: Stripe.Event & T;
34
+ revealui: RevealUIInstance;
35
+ stripe: Stripe;
36
+ }) => Promise<void>;
37
+ export declare const updateProduct: StripeWebhookHandler<{
38
+ data: {
39
+ object: Stripe.Product;
40
+ };
41
+ }>;
42
+ export declare function POST(req: VercelRequest, res: VercelResponse): Promise<void>;
43
+ export {};
44
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/update-product/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACjE,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAIhC,UAAU,mBAAmB;IAC3B,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAA;CACtC;AAED,UAAU,gBAAgB;IACxB,IAAI,CAAC,IAAI,EAAE;QACT,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE;YAAE,eAAe,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAC/C,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAChC,MAAM,CAAC,IAAI,EAAE;QACX,UAAU,EAAE,MAAM,CAAA;QAClB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;QACnB,IAAI,EAAE;YACJ,SAAS,EAAE,MAAM,CAAA;YACjB,QAAQ,EAAE,OAAO,CAAA;YACjB,IAAI,EAAE,MAAM,CAAA;YACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;SAC3B,CAAA;KACF,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;QAC/B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;KACjC,CAAA;CACF;AAED,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAA;IACvB,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;CACf,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEnB,eAAO,MAAM,aAAa,EAAE,oBAAoB,CAAC;IAC/C,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC,OAAO,CAAA;KACvB,CAAA;CACF,CA8EA,CAAA;AAQD,wBAAsB,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBjF"}
@@ -0,0 +1,85 @@
1
+ // api/update-product.ts
2
+ import { logger } from '@revealui/core/utils/logger';
3
+ const logs = false;
4
+ export const updateProduct = async (args) => {
5
+ const { event, revealui, stripe } = args;
6
+ const { id: stripeProductID, name: stripeProductName, description: stripeDescription, } = event.data.object;
7
+ if (logs)
8
+ revealui.logger.info(`Syncing Stripe product with ID: ${stripeProductID} to RevealUI...
9
+ Product name: ${stripeProductName}
10
+ Product description: ${stripeDescription}`);
11
+ let revealuiProductID;
12
+ // First lookup the product in RevealUI
13
+ try {
14
+ if (logs)
15
+ revealui.logger.info(`- Looking up existing RevealUI product...`);
16
+ const productQuery = await revealui.find({
17
+ collection: 'products',
18
+ where: {
19
+ stripeProductID: {
20
+ equals: stripeProductID,
21
+ },
22
+ },
23
+ });
24
+ revealuiProductID = productQuery.docs?.[0]?.id;
25
+ if (revealuiProductID) {
26
+ if (logs)
27
+ revealui.logger.info(`- Found existing product with Stripe ID: ${stripeProductID}, syncing now...`);
28
+ }
29
+ }
30
+ catch (error) {
31
+ const message = error instanceof Error ? error.message : 'Unknown error';
32
+ revealui.logger.error(`Error finding product ${message}`);
33
+ }
34
+ let prices;
35
+ try {
36
+ if (logs)
37
+ revealui.logger.info(`- Looking up all prices associated with this product...`);
38
+ // Find all stripe prices that are assigned to "revealuiProductID"
39
+ prices = await stripe.prices.list({
40
+ product: stripeProductID,
41
+ limit: 100,
42
+ });
43
+ }
44
+ catch (error) {
45
+ const errorMessage = error instanceof Error ? error.message : String(error);
46
+ revealui.logger.error(`- Error looking up prices: ${errorMessage}`);
47
+ }
48
+ try {
49
+ if (logs)
50
+ revealui.logger.info(`- Updating document...`);
51
+ await revealui.update({
52
+ collection: 'products',
53
+ id: revealuiProductID || '',
54
+ data: {
55
+ name: stripeProductName,
56
+ description: stripeDescription,
57
+ priceJSON: JSON.stringify(prices || { data: [], has_more: false }),
58
+ skipSync: true,
59
+ },
60
+ });
61
+ if (logs)
62
+ revealui.logger.info(`✅ Successfully updated product.`);
63
+ }
64
+ catch (error) {
65
+ const errorMessage = error instanceof Error ? error.message : String(error);
66
+ revealui.logger.error(`- Error updating product: ${errorMessage}`);
67
+ }
68
+ };
69
+ export async function POST(req, res) {
70
+ if (req.method !== 'POST') {
71
+ res.status(405).send('Method Not Allowed');
72
+ return;
73
+ }
74
+ const { event, revealui, stripe } = req.body;
75
+ try {
76
+ await updateProduct({ event, revealui, stripe });
77
+ res.status(200).send('Product updated successfully');
78
+ }
79
+ catch (error) {
80
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
81
+ logger.error('Error updating product', { error: errorMessage });
82
+ res.status(500).send('Internal Server Error');
83
+ }
84
+ }
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/update-product/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * API Utilities - Re-exports from focused handler modules
3
+ *
4
+ * This file preserves backward compatibility. New code should import
5
+ * directly from the focused modules in ./handlers/ instead.
6
+ *
7
+ * @see ./handlers/subscription-handlers.ts
8
+ * @see ./handlers/invoice-handlers.ts
9
+ * @see ./handlers/product-handlers.ts
10
+ * @see ./handlers/customer-handlers.ts
11
+ * @see ./handlers/payment-handlers.ts
12
+ * @see ./handlers/payment-intent.ts
13
+ */
14
+ import type { IncomingMessage, ServerResponse } from 'node:http';
15
+ import { createServerClient } from '../supabase/index.js';
16
+ interface Context {
17
+ req: IncomingMessage;
18
+ res: ServerResponse;
19
+ }
20
+ export declare function createClient(context: Context): ReturnType<typeof createServerClient>;
21
+ export declare const getURL: () => string;
22
+ export { copyBillingDetailsToCustomer, createOrRetrieveCustomer, createPaymentIntent, handleCheckoutSessionCompleted, handleCustomerCreated, handleCustomerSubscriptionCreated, handleCustomerSubscriptionDeleted, handleCustomerSubscriptionUpdated, handleCustomerUpdated, handleInvoicePaymentFailed, handleInvoicePaymentSucceeded, handlePaymentMethodAttached, handlePaymentMethodCreated, handlePaymentMethodDetached, handlePaymentMethodUpdated, handleSetupIntentFailed, handleSetupIntentSucceeded, handleSupabaseError, manageSubscriptionStatusChange, toDateTime, upsertPriceRecord, upsertProductRecord, upsertRecord, } from './handlers/index.js';
23
+ import type { RevealRequest } from '@revealui/core';
24
+ interface CreateStripeCustomerParams {
25
+ req: RevealRequest;
26
+ data: {
27
+ email?: string;
28
+ stripeCustomerID?: string;
29
+ [key: string]: unknown;
30
+ };
31
+ operation: string;
32
+ }
33
+ export declare const createStripeCustomer: ({ req, data, operation, }: CreateStripeCustomerParams) => Promise<typeof data>;
34
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/api/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAGhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEzD,UAAU,OAAO;IACf,GAAG,EAAE,eAAe,CAAA;IACpB,GAAG,EAAE,cAAc,CAAA;CACpB;AACD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAEpF;AAED,eAAO,MAAM,MAAM,QAAO,MAOzB,CAAA;AAGD,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,EACnB,8BAA8B,EAC9B,qBAAqB,EACrB,iCAAiC,EACjC,iCAAiC,EACjC,iCAAiC,EACjC,qBAAqB,EACrB,0BAA0B,EAC1B,6BAA6B,EAC7B,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,EACnB,8BAA8B,EAC9B,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACb,MAAM,qBAAqB,CAAA;AAG5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAInD,UAAU,0BAA0B;IAClC,GAAG,EAAE,aAAa,CAAA;IAClB,IAAI,EAAE;QACJ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KACvB,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,oBAAoB,GAAU,2BAIxC,0BAA0B,KAAG,OAAO,CAAC,OAAO,IAAI,CAmClD,CAAA"}