@omnibase/core-js 0.1.6 → 0.2.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.
- package/dist/stripe/index.cjs +153 -0
- package/dist/stripe/index.d.cts +162 -0
- package/dist/stripe/index.d.ts +162 -0
- package/dist/stripe/index.js +124 -0
- package/dist/tenants/index.d.cts +4 -53
- package/dist/tenants/index.d.ts +4 -53
- package/dist/types-DgsX5kVK.d.cts +49 -0
- package/dist/types-DgsX5kVK.d.ts +49 -0
- package/package.json +7 -2
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/stripe/index.ts
|
|
21
|
+
var stripe_exports = {};
|
|
22
|
+
__export(stripe_exports, {
|
|
23
|
+
getAvailableProducts: () => getAvailableProducts,
|
|
24
|
+
getProduct: () => getProduct,
|
|
25
|
+
getStripeConfig: () => getStripeConfig
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(stripe_exports);
|
|
28
|
+
|
|
29
|
+
// src/stripe/config.ts
|
|
30
|
+
async function getStripeConfig() {
|
|
31
|
+
const baseUrl = process.env.OMNIBASE_API_URL;
|
|
32
|
+
if (!baseUrl) {
|
|
33
|
+
throw new Error("OMNIBASE_API_URL is not configured");
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const response = await fetch(`${baseUrl}/api/v1/stripe/config`, {
|
|
37
|
+
method: "GET",
|
|
38
|
+
headers: {
|
|
39
|
+
"Content-Type": "application/json"
|
|
40
|
+
},
|
|
41
|
+
credentials: "include"
|
|
42
|
+
});
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
const errorData = await response.text();
|
|
45
|
+
throw new Error(
|
|
46
|
+
`Failed to get Stripe config: ${response.status} - ${errorData}`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const data = await response.json();
|
|
50
|
+
return data;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error("Error getting Stripe config:", error);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function getAvailableProducts() {
|
|
57
|
+
const configResponse = await getStripeConfig();
|
|
58
|
+
if (!configResponse.data?.config) {
|
|
59
|
+
throw new Error("No Stripe configuration found");
|
|
60
|
+
}
|
|
61
|
+
const products = configResponse.data.config.products;
|
|
62
|
+
return products.map(transformProductToUIReady).sort(
|
|
63
|
+
(a, b) => a.pricing_display.sort_order - b.pricing_display.sort_order
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
async function getProduct(productId) {
|
|
67
|
+
const configResponse = await getStripeConfig();
|
|
68
|
+
if (!configResponse.data?.config) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const product = configResponse.data.config.products.find(
|
|
72
|
+
(p) => p.id === productId
|
|
73
|
+
);
|
|
74
|
+
return product || null;
|
|
75
|
+
}
|
|
76
|
+
function transformProductToUIReady(product) {
|
|
77
|
+
const ui = product.ui || {};
|
|
78
|
+
return {
|
|
79
|
+
...product,
|
|
80
|
+
pricing_display: {
|
|
81
|
+
name: ui.display_name || product.name,
|
|
82
|
+
tagline: ui.tagline,
|
|
83
|
+
features: ui.features || [],
|
|
84
|
+
badge: ui.badge,
|
|
85
|
+
cta_text: ui.cta_text || "Choose Plan",
|
|
86
|
+
highlighted: ui.highlighted || false,
|
|
87
|
+
sort_order: ui.sort_order || 0,
|
|
88
|
+
prices: product.prices.map((price) => {
|
|
89
|
+
const priceUI = price.ui || {};
|
|
90
|
+
return {
|
|
91
|
+
id: price.id,
|
|
92
|
+
display_name: priceUI.display_name || formatDefaultPriceName(price),
|
|
93
|
+
formatted_price: formatPrice(price, priceUI),
|
|
94
|
+
billing_period: priceUI.billing_period || formatDefaultBillingPeriod(price),
|
|
95
|
+
features: priceUI.features || [],
|
|
96
|
+
limits: priceUI.limits || []
|
|
97
|
+
};
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function formatPrice(price, priceUI) {
|
|
103
|
+
if (priceUI.price_display?.custom_text) {
|
|
104
|
+
return priceUI.price_display.custom_text;
|
|
105
|
+
}
|
|
106
|
+
if (!price.amount || price.amount === 0) {
|
|
107
|
+
return "Free";
|
|
108
|
+
}
|
|
109
|
+
const amount = price.amount / 100;
|
|
110
|
+
const currency = price.currency.toUpperCase();
|
|
111
|
+
let formattedPrice = "";
|
|
112
|
+
if (priceUI.price_display?.show_currency !== false) {
|
|
113
|
+
const currencySymbol = getCurrencySymbol(currency);
|
|
114
|
+
formattedPrice = `${currencySymbol}${amount.toFixed(2)}`;
|
|
115
|
+
} else {
|
|
116
|
+
formattedPrice = amount.toFixed(2);
|
|
117
|
+
}
|
|
118
|
+
if (priceUI.price_display?.suffix) {
|
|
119
|
+
formattedPrice += ` ${priceUI.price_display.suffix}`;
|
|
120
|
+
}
|
|
121
|
+
return formattedPrice;
|
|
122
|
+
}
|
|
123
|
+
function getCurrencySymbol(currency) {
|
|
124
|
+
const symbols = {
|
|
125
|
+
USD: "$",
|
|
126
|
+
EUR: "\u20AC",
|
|
127
|
+
GBP: "\xA3",
|
|
128
|
+
JPY: "\xA5",
|
|
129
|
+
CAD: "C$",
|
|
130
|
+
AUD: "A$"
|
|
131
|
+
};
|
|
132
|
+
return symbols[currency] || currency;
|
|
133
|
+
}
|
|
134
|
+
function formatDefaultPriceName(price) {
|
|
135
|
+
if (price.interval) {
|
|
136
|
+
return price.interval.charAt(0).toUpperCase() + price.interval.slice(1);
|
|
137
|
+
}
|
|
138
|
+
return "One-time";
|
|
139
|
+
}
|
|
140
|
+
function formatDefaultBillingPeriod(price) {
|
|
141
|
+
if (price.interval) {
|
|
142
|
+
const count = price.interval_count || 1;
|
|
143
|
+
const period = count === 1 ? price.interval : `${count} ${price.interval}s`;
|
|
144
|
+
return `per ${period}`;
|
|
145
|
+
}
|
|
146
|
+
return "one-time";
|
|
147
|
+
}
|
|
148
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
149
|
+
0 && (module.exports = {
|
|
150
|
+
getAvailableProducts,
|
|
151
|
+
getProduct,
|
|
152
|
+
getStripeConfig
|
|
153
|
+
});
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { A as ApiResponse } from '../types-DgsX5kVK.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stripe configuration types mirroring the Go structs and JSON schema
|
|
5
|
+
*/
|
|
6
|
+
type StripeConfigResponse = ApiResponse<{
|
|
7
|
+
config: StripeConfiguration;
|
|
8
|
+
message?: string;
|
|
9
|
+
}>;
|
|
10
|
+
interface StripeConfiguration {
|
|
11
|
+
version: string;
|
|
12
|
+
products: Product[];
|
|
13
|
+
}
|
|
14
|
+
interface Product {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
type?: "service" | "good" | "metered";
|
|
19
|
+
prices: Price[];
|
|
20
|
+
ui?: ProductUI;
|
|
21
|
+
}
|
|
22
|
+
interface Price {
|
|
23
|
+
id: string;
|
|
24
|
+
amount?: number;
|
|
25
|
+
currency: string;
|
|
26
|
+
interval?: "month" | "year" | "week" | "day";
|
|
27
|
+
interval_count?: number;
|
|
28
|
+
usage_type?: "licensed" | "metered";
|
|
29
|
+
billing_scheme?: "per_unit" | "tiered";
|
|
30
|
+
tiers_mode?: "graduated" | "volume";
|
|
31
|
+
tiers?: Tier[];
|
|
32
|
+
ui?: PriceUI;
|
|
33
|
+
}
|
|
34
|
+
interface Tier {
|
|
35
|
+
up_to: number | "inf";
|
|
36
|
+
flat_amount?: number;
|
|
37
|
+
unit_amount?: number;
|
|
38
|
+
}
|
|
39
|
+
interface ProductUI {
|
|
40
|
+
display_name?: string;
|
|
41
|
+
tagline?: string;
|
|
42
|
+
features?: string[];
|
|
43
|
+
badge?: string;
|
|
44
|
+
cta_text?: string;
|
|
45
|
+
highlighted?: boolean;
|
|
46
|
+
sort_order?: number;
|
|
47
|
+
}
|
|
48
|
+
interface PriceUI {
|
|
49
|
+
display_name?: string;
|
|
50
|
+
price_display?: PriceDisplay;
|
|
51
|
+
billing_period?: string;
|
|
52
|
+
features?: string[];
|
|
53
|
+
limits?: PriceLimit[];
|
|
54
|
+
}
|
|
55
|
+
interface PriceDisplay {
|
|
56
|
+
custom_text?: string;
|
|
57
|
+
show_currency?: boolean;
|
|
58
|
+
suffix?: string;
|
|
59
|
+
}
|
|
60
|
+
interface PriceLimit {
|
|
61
|
+
text: string;
|
|
62
|
+
value?: number;
|
|
63
|
+
unit?: string;
|
|
64
|
+
}
|
|
65
|
+
interface ProductWithPricingUI extends Product {
|
|
66
|
+
pricing_display: {
|
|
67
|
+
name: string;
|
|
68
|
+
tagline?: string;
|
|
69
|
+
features: string[];
|
|
70
|
+
badge?: string;
|
|
71
|
+
cta_text: string;
|
|
72
|
+
highlighted: boolean;
|
|
73
|
+
sort_order: number;
|
|
74
|
+
prices: Array<{
|
|
75
|
+
id: string;
|
|
76
|
+
display_name: string;
|
|
77
|
+
formatted_price: string;
|
|
78
|
+
billing_period: string;
|
|
79
|
+
features: string[];
|
|
80
|
+
limits: Array<{
|
|
81
|
+
text: string;
|
|
82
|
+
value?: number;
|
|
83
|
+
unit?: string;
|
|
84
|
+
}>;
|
|
85
|
+
}>;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get the current Stripe configuration from the database
|
|
91
|
+
*
|
|
92
|
+
* Retrieves the latest Stripe configuration including products, prices,
|
|
93
|
+
* and UI customization data. This configuration represents the current
|
|
94
|
+
* active pricing structure with all UI elements for pricing table rendering.
|
|
95
|
+
*
|
|
96
|
+
* @returns Promise resolving to the current Stripe configuration
|
|
97
|
+
*
|
|
98
|
+
* @throws {Error} When OMNIBASE_API_URL environment variable is not configured
|
|
99
|
+
* @throws {Error} When the API request fails due to network issues
|
|
100
|
+
* @throws {Error} When the server returns an error response (4xx, 5xx status codes)
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* Basic usage:
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const config = await getStripeConfig();
|
|
106
|
+
* console.log(`Found ${config.data.config.products.length} products`);
|
|
107
|
+
*
|
|
108
|
+
* // Access product UI configuration
|
|
109
|
+
* config.data.config.products.forEach(product => {
|
|
110
|
+
* console.log(`${product.name}: ${product.ui?.tagline || 'No tagline'}`);
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function getStripeConfig(): Promise<StripeConfigResponse>;
|
|
115
|
+
/**
|
|
116
|
+
* Get available products with UI-ready pricing data
|
|
117
|
+
*
|
|
118
|
+
* Transforms the raw Stripe configuration into UI-ready format for pricing
|
|
119
|
+
* table rendering. Includes formatted pricing, features, limits, and all
|
|
120
|
+
* display customizations needed for marketing pages.
|
|
121
|
+
*
|
|
122
|
+
* @returns Promise resolving to products ready for UI consumption
|
|
123
|
+
*
|
|
124
|
+
* @throws {Error} When OMNIBASE_API_URL environment variable is not configured
|
|
125
|
+
* @throws {Error} When the API request fails or configuration is invalid
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* Pricing table rendering:
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const products = await getAvailableProducts();
|
|
131
|
+
*
|
|
132
|
+
* products.forEach(product => {
|
|
133
|
+
* const display = product.pricing_display;
|
|
134
|
+
* console.log(`${display.name} - ${display.tagline}`);
|
|
135
|
+
*
|
|
136
|
+
* display.prices.forEach(price => {
|
|
137
|
+
* console.log(` ${price.display_name}: ${price.formatted_price}`);
|
|
138
|
+
* });
|
|
139
|
+
* });
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
declare function getAvailableProducts(): Promise<ProductWithPricingUI[]>;
|
|
143
|
+
/**
|
|
144
|
+
* Get a specific product by ID
|
|
145
|
+
*
|
|
146
|
+
* Retrieves a single product configuration by its ID from the current
|
|
147
|
+
* Stripe configuration. Useful for product-specific operations.
|
|
148
|
+
*
|
|
149
|
+
* @param productId - The configuration product ID to retrieve
|
|
150
|
+
* @returns Promise resolving to the product or null if not found
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* const product = await getProduct('starter_plan');
|
|
155
|
+
* if (product) {
|
|
156
|
+
* console.log(`Found product: ${product.name}`);
|
|
157
|
+
* }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
declare function getProduct(productId: string): Promise<Product | null>;
|
|
161
|
+
|
|
162
|
+
export { type Price, type PriceDisplay, type PriceLimit, type PriceUI, type Product, type ProductUI, type ProductWithPricingUI, type StripeConfigResponse, type StripeConfiguration, type Tier, getAvailableProducts, getProduct, getStripeConfig };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { A as ApiResponse } from '../types-DgsX5kVK.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stripe configuration types mirroring the Go structs and JSON schema
|
|
5
|
+
*/
|
|
6
|
+
type StripeConfigResponse = ApiResponse<{
|
|
7
|
+
config: StripeConfiguration;
|
|
8
|
+
message?: string;
|
|
9
|
+
}>;
|
|
10
|
+
interface StripeConfiguration {
|
|
11
|
+
version: string;
|
|
12
|
+
products: Product[];
|
|
13
|
+
}
|
|
14
|
+
interface Product {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
type?: "service" | "good" | "metered";
|
|
19
|
+
prices: Price[];
|
|
20
|
+
ui?: ProductUI;
|
|
21
|
+
}
|
|
22
|
+
interface Price {
|
|
23
|
+
id: string;
|
|
24
|
+
amount?: number;
|
|
25
|
+
currency: string;
|
|
26
|
+
interval?: "month" | "year" | "week" | "day";
|
|
27
|
+
interval_count?: number;
|
|
28
|
+
usage_type?: "licensed" | "metered";
|
|
29
|
+
billing_scheme?: "per_unit" | "tiered";
|
|
30
|
+
tiers_mode?: "graduated" | "volume";
|
|
31
|
+
tiers?: Tier[];
|
|
32
|
+
ui?: PriceUI;
|
|
33
|
+
}
|
|
34
|
+
interface Tier {
|
|
35
|
+
up_to: number | "inf";
|
|
36
|
+
flat_amount?: number;
|
|
37
|
+
unit_amount?: number;
|
|
38
|
+
}
|
|
39
|
+
interface ProductUI {
|
|
40
|
+
display_name?: string;
|
|
41
|
+
tagline?: string;
|
|
42
|
+
features?: string[];
|
|
43
|
+
badge?: string;
|
|
44
|
+
cta_text?: string;
|
|
45
|
+
highlighted?: boolean;
|
|
46
|
+
sort_order?: number;
|
|
47
|
+
}
|
|
48
|
+
interface PriceUI {
|
|
49
|
+
display_name?: string;
|
|
50
|
+
price_display?: PriceDisplay;
|
|
51
|
+
billing_period?: string;
|
|
52
|
+
features?: string[];
|
|
53
|
+
limits?: PriceLimit[];
|
|
54
|
+
}
|
|
55
|
+
interface PriceDisplay {
|
|
56
|
+
custom_text?: string;
|
|
57
|
+
show_currency?: boolean;
|
|
58
|
+
suffix?: string;
|
|
59
|
+
}
|
|
60
|
+
interface PriceLimit {
|
|
61
|
+
text: string;
|
|
62
|
+
value?: number;
|
|
63
|
+
unit?: string;
|
|
64
|
+
}
|
|
65
|
+
interface ProductWithPricingUI extends Product {
|
|
66
|
+
pricing_display: {
|
|
67
|
+
name: string;
|
|
68
|
+
tagline?: string;
|
|
69
|
+
features: string[];
|
|
70
|
+
badge?: string;
|
|
71
|
+
cta_text: string;
|
|
72
|
+
highlighted: boolean;
|
|
73
|
+
sort_order: number;
|
|
74
|
+
prices: Array<{
|
|
75
|
+
id: string;
|
|
76
|
+
display_name: string;
|
|
77
|
+
formatted_price: string;
|
|
78
|
+
billing_period: string;
|
|
79
|
+
features: string[];
|
|
80
|
+
limits: Array<{
|
|
81
|
+
text: string;
|
|
82
|
+
value?: number;
|
|
83
|
+
unit?: string;
|
|
84
|
+
}>;
|
|
85
|
+
}>;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get the current Stripe configuration from the database
|
|
91
|
+
*
|
|
92
|
+
* Retrieves the latest Stripe configuration including products, prices,
|
|
93
|
+
* and UI customization data. This configuration represents the current
|
|
94
|
+
* active pricing structure with all UI elements for pricing table rendering.
|
|
95
|
+
*
|
|
96
|
+
* @returns Promise resolving to the current Stripe configuration
|
|
97
|
+
*
|
|
98
|
+
* @throws {Error} When OMNIBASE_API_URL environment variable is not configured
|
|
99
|
+
* @throws {Error} When the API request fails due to network issues
|
|
100
|
+
* @throws {Error} When the server returns an error response (4xx, 5xx status codes)
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* Basic usage:
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const config = await getStripeConfig();
|
|
106
|
+
* console.log(`Found ${config.data.config.products.length} products`);
|
|
107
|
+
*
|
|
108
|
+
* // Access product UI configuration
|
|
109
|
+
* config.data.config.products.forEach(product => {
|
|
110
|
+
* console.log(`${product.name}: ${product.ui?.tagline || 'No tagline'}`);
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function getStripeConfig(): Promise<StripeConfigResponse>;
|
|
115
|
+
/**
|
|
116
|
+
* Get available products with UI-ready pricing data
|
|
117
|
+
*
|
|
118
|
+
* Transforms the raw Stripe configuration into UI-ready format for pricing
|
|
119
|
+
* table rendering. Includes formatted pricing, features, limits, and all
|
|
120
|
+
* display customizations needed for marketing pages.
|
|
121
|
+
*
|
|
122
|
+
* @returns Promise resolving to products ready for UI consumption
|
|
123
|
+
*
|
|
124
|
+
* @throws {Error} When OMNIBASE_API_URL environment variable is not configured
|
|
125
|
+
* @throws {Error} When the API request fails or configuration is invalid
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* Pricing table rendering:
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const products = await getAvailableProducts();
|
|
131
|
+
*
|
|
132
|
+
* products.forEach(product => {
|
|
133
|
+
* const display = product.pricing_display;
|
|
134
|
+
* console.log(`${display.name} - ${display.tagline}`);
|
|
135
|
+
*
|
|
136
|
+
* display.prices.forEach(price => {
|
|
137
|
+
* console.log(` ${price.display_name}: ${price.formatted_price}`);
|
|
138
|
+
* });
|
|
139
|
+
* });
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
declare function getAvailableProducts(): Promise<ProductWithPricingUI[]>;
|
|
143
|
+
/**
|
|
144
|
+
* Get a specific product by ID
|
|
145
|
+
*
|
|
146
|
+
* Retrieves a single product configuration by its ID from the current
|
|
147
|
+
* Stripe configuration. Useful for product-specific operations.
|
|
148
|
+
*
|
|
149
|
+
* @param productId - The configuration product ID to retrieve
|
|
150
|
+
* @returns Promise resolving to the product or null if not found
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* const product = await getProduct('starter_plan');
|
|
155
|
+
* if (product) {
|
|
156
|
+
* console.log(`Found product: ${product.name}`);
|
|
157
|
+
* }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
declare function getProduct(productId: string): Promise<Product | null>;
|
|
161
|
+
|
|
162
|
+
export { type Price, type PriceDisplay, type PriceLimit, type PriceUI, type Product, type ProductUI, type ProductWithPricingUI, type StripeConfigResponse, type StripeConfiguration, type Tier, getAvailableProducts, getProduct, getStripeConfig };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// src/stripe/config.ts
|
|
2
|
+
async function getStripeConfig() {
|
|
3
|
+
const baseUrl = process.env.OMNIBASE_API_URL;
|
|
4
|
+
if (!baseUrl) {
|
|
5
|
+
throw new Error("OMNIBASE_API_URL is not configured");
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
const response = await fetch(`${baseUrl}/api/v1/stripe/config`, {
|
|
9
|
+
method: "GET",
|
|
10
|
+
headers: {
|
|
11
|
+
"Content-Type": "application/json"
|
|
12
|
+
},
|
|
13
|
+
credentials: "include"
|
|
14
|
+
});
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
const errorData = await response.text();
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Failed to get Stripe config: ${response.status} - ${errorData}`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
const data = await response.json();
|
|
22
|
+
return data;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error("Error getting Stripe config:", error);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function getAvailableProducts() {
|
|
29
|
+
const configResponse = await getStripeConfig();
|
|
30
|
+
if (!configResponse.data?.config) {
|
|
31
|
+
throw new Error("No Stripe configuration found");
|
|
32
|
+
}
|
|
33
|
+
const products = configResponse.data.config.products;
|
|
34
|
+
return products.map(transformProductToUIReady).sort(
|
|
35
|
+
(a, b) => a.pricing_display.sort_order - b.pricing_display.sort_order
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
async function getProduct(productId) {
|
|
39
|
+
const configResponse = await getStripeConfig();
|
|
40
|
+
if (!configResponse.data?.config) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const product = configResponse.data.config.products.find(
|
|
44
|
+
(p) => p.id === productId
|
|
45
|
+
);
|
|
46
|
+
return product || null;
|
|
47
|
+
}
|
|
48
|
+
function transformProductToUIReady(product) {
|
|
49
|
+
const ui = product.ui || {};
|
|
50
|
+
return {
|
|
51
|
+
...product,
|
|
52
|
+
pricing_display: {
|
|
53
|
+
name: ui.display_name || product.name,
|
|
54
|
+
tagline: ui.tagline,
|
|
55
|
+
features: ui.features || [],
|
|
56
|
+
badge: ui.badge,
|
|
57
|
+
cta_text: ui.cta_text || "Choose Plan",
|
|
58
|
+
highlighted: ui.highlighted || false,
|
|
59
|
+
sort_order: ui.sort_order || 0,
|
|
60
|
+
prices: product.prices.map((price) => {
|
|
61
|
+
const priceUI = price.ui || {};
|
|
62
|
+
return {
|
|
63
|
+
id: price.id,
|
|
64
|
+
display_name: priceUI.display_name || formatDefaultPriceName(price),
|
|
65
|
+
formatted_price: formatPrice(price, priceUI),
|
|
66
|
+
billing_period: priceUI.billing_period || formatDefaultBillingPeriod(price),
|
|
67
|
+
features: priceUI.features || [],
|
|
68
|
+
limits: priceUI.limits || []
|
|
69
|
+
};
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function formatPrice(price, priceUI) {
|
|
75
|
+
if (priceUI.price_display?.custom_text) {
|
|
76
|
+
return priceUI.price_display.custom_text;
|
|
77
|
+
}
|
|
78
|
+
if (!price.amount || price.amount === 0) {
|
|
79
|
+
return "Free";
|
|
80
|
+
}
|
|
81
|
+
const amount = price.amount / 100;
|
|
82
|
+
const currency = price.currency.toUpperCase();
|
|
83
|
+
let formattedPrice = "";
|
|
84
|
+
if (priceUI.price_display?.show_currency !== false) {
|
|
85
|
+
const currencySymbol = getCurrencySymbol(currency);
|
|
86
|
+
formattedPrice = `${currencySymbol}${amount.toFixed(2)}`;
|
|
87
|
+
} else {
|
|
88
|
+
formattedPrice = amount.toFixed(2);
|
|
89
|
+
}
|
|
90
|
+
if (priceUI.price_display?.suffix) {
|
|
91
|
+
formattedPrice += ` ${priceUI.price_display.suffix}`;
|
|
92
|
+
}
|
|
93
|
+
return formattedPrice;
|
|
94
|
+
}
|
|
95
|
+
function getCurrencySymbol(currency) {
|
|
96
|
+
const symbols = {
|
|
97
|
+
USD: "$",
|
|
98
|
+
EUR: "\u20AC",
|
|
99
|
+
GBP: "\xA3",
|
|
100
|
+
JPY: "\xA5",
|
|
101
|
+
CAD: "C$",
|
|
102
|
+
AUD: "A$"
|
|
103
|
+
};
|
|
104
|
+
return symbols[currency] || currency;
|
|
105
|
+
}
|
|
106
|
+
function formatDefaultPriceName(price) {
|
|
107
|
+
if (price.interval) {
|
|
108
|
+
return price.interval.charAt(0).toUpperCase() + price.interval.slice(1);
|
|
109
|
+
}
|
|
110
|
+
return "One-time";
|
|
111
|
+
}
|
|
112
|
+
function formatDefaultBillingPeriod(price) {
|
|
113
|
+
if (price.interval) {
|
|
114
|
+
const count = price.interval_count || 1;
|
|
115
|
+
const period = count === 1 ? price.interval : `${count} ${price.interval}s`;
|
|
116
|
+
return `per ${period}`;
|
|
117
|
+
}
|
|
118
|
+
return "one-time";
|
|
119
|
+
}
|
|
120
|
+
export {
|
|
121
|
+
getAvailableProducts,
|
|
122
|
+
getProduct,
|
|
123
|
+
getStripeConfig
|
|
124
|
+
};
|
package/dist/tenants/index.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { A as ApiResponse } from '../types-DgsX5kVK.cjs';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Request data for accepting a tenant invitation
|
|
3
5
|
*
|
|
@@ -117,10 +119,7 @@ type AcceptTenantInviteResponse = ApiResponse<{
|
|
|
117
119
|
* @public
|
|
118
120
|
* @group User Management
|
|
119
121
|
*/
|
|
120
|
-
declare function acceptTenantInvite(token: string): Promise<
|
|
121
|
-
tenant_id: string;
|
|
122
|
-
message: string;
|
|
123
|
-
}>>;
|
|
122
|
+
declare function acceptTenantInvite(token: string): Promise<AcceptTenantInviteResponse>;
|
|
124
123
|
|
|
125
124
|
/**
|
|
126
125
|
* Response structure for tenant user invite creation
|
|
@@ -523,54 +522,6 @@ type DeleteTenantResponse = ApiResponse<{
|
|
|
523
522
|
*/
|
|
524
523
|
declare function deleteTenant(tenantId: string): Promise<DeleteTenantResponse>;
|
|
525
524
|
|
|
526
|
-
/**
|
|
527
|
-
* Base API Response structure for all tenant operations
|
|
528
|
-
*
|
|
529
|
-
* This generic type defines the standard response format returned by all
|
|
530
|
-
* tenant-related API endpoints. It provides a consistent structure for
|
|
531
|
-
* handling both successful responses and error conditions across the SDK.
|
|
532
|
-
*
|
|
533
|
-
* @template T - The type of the response data payload
|
|
534
|
-
*
|
|
535
|
-
* @example
|
|
536
|
-
* Successful response:
|
|
537
|
-
* ```typescript
|
|
538
|
-
* const response: ApiResponse<{ tenant: Tenant }> = {
|
|
539
|
-
* data: { tenant: { id: '123', name: 'My Company' } },
|
|
540
|
-
* status: 200
|
|
541
|
-
* };
|
|
542
|
-
* ```
|
|
543
|
-
*
|
|
544
|
-
* @example
|
|
545
|
-
* Error response:
|
|
546
|
-
* ```typescript
|
|
547
|
-
* const response: ApiResponse<never> = {
|
|
548
|
-
* status: 400,
|
|
549
|
-
* error: 'Invalid tenant name provided'
|
|
550
|
-
* };
|
|
551
|
-
* ```
|
|
552
|
-
*
|
|
553
|
-
* @since 1.0.0
|
|
554
|
-
* @public
|
|
555
|
-
*/
|
|
556
|
-
type ApiResponse<T> = {
|
|
557
|
-
/**
|
|
558
|
-
* Response data payload (present only on successful operations)
|
|
559
|
-
* Contains the actual data returned by the API endpoint
|
|
560
|
-
*/
|
|
561
|
-
data?: T;
|
|
562
|
-
/**
|
|
563
|
-
* HTTP status code indicating the result of the operation
|
|
564
|
-
* @example 200 for success, 400 for client errors, 500 for server errors
|
|
565
|
-
*/
|
|
566
|
-
status: number;
|
|
567
|
-
/**
|
|
568
|
-
* Error message (present only when operation fails)
|
|
569
|
-
* Provides human-readable description of what went wrong
|
|
570
|
-
*/
|
|
571
|
-
error?: string;
|
|
572
|
-
};
|
|
573
|
-
|
|
574
525
|
/**
|
|
575
526
|
* Response structure for switching the active tenant
|
|
576
527
|
*
|
|
@@ -681,4 +632,4 @@ type SwitchActiveTenantResponse = ApiResponse<{
|
|
|
681
632
|
*/
|
|
682
633
|
declare function switchActiveTenant(tenantId: string): Promise<SwitchActiveTenantResponse>;
|
|
683
634
|
|
|
684
|
-
export { type AcceptTenantInviteRequest, type AcceptTenantInviteResponse,
|
|
635
|
+
export { type AcceptTenantInviteRequest, type AcceptTenantInviteResponse, ApiResponse, type CreateTenantRequest, type CreateTenantResponse, type CreateTenantUserInviteRequest, type CreateTenantUserInviteResponse, type DeleteTenantResponse, type SwitchActiveTenantResponse, type Tenant, type TenantInvite, acceptTenantInvite, createTenant, createTenantUserInvite, deleteTenant, switchActiveTenant };
|
package/dist/tenants/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { A as ApiResponse } from '../types-DgsX5kVK.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Request data for accepting a tenant invitation
|
|
3
5
|
*
|
|
@@ -117,10 +119,7 @@ type AcceptTenantInviteResponse = ApiResponse<{
|
|
|
117
119
|
* @public
|
|
118
120
|
* @group User Management
|
|
119
121
|
*/
|
|
120
|
-
declare function acceptTenantInvite(token: string): Promise<
|
|
121
|
-
tenant_id: string;
|
|
122
|
-
message: string;
|
|
123
|
-
}>>;
|
|
122
|
+
declare function acceptTenantInvite(token: string): Promise<AcceptTenantInviteResponse>;
|
|
124
123
|
|
|
125
124
|
/**
|
|
126
125
|
* Response structure for tenant user invite creation
|
|
@@ -523,54 +522,6 @@ type DeleteTenantResponse = ApiResponse<{
|
|
|
523
522
|
*/
|
|
524
523
|
declare function deleteTenant(tenantId: string): Promise<DeleteTenantResponse>;
|
|
525
524
|
|
|
526
|
-
/**
|
|
527
|
-
* Base API Response structure for all tenant operations
|
|
528
|
-
*
|
|
529
|
-
* This generic type defines the standard response format returned by all
|
|
530
|
-
* tenant-related API endpoints. It provides a consistent structure for
|
|
531
|
-
* handling both successful responses and error conditions across the SDK.
|
|
532
|
-
*
|
|
533
|
-
* @template T - The type of the response data payload
|
|
534
|
-
*
|
|
535
|
-
* @example
|
|
536
|
-
* Successful response:
|
|
537
|
-
* ```typescript
|
|
538
|
-
* const response: ApiResponse<{ tenant: Tenant }> = {
|
|
539
|
-
* data: { tenant: { id: '123', name: 'My Company' } },
|
|
540
|
-
* status: 200
|
|
541
|
-
* };
|
|
542
|
-
* ```
|
|
543
|
-
*
|
|
544
|
-
* @example
|
|
545
|
-
* Error response:
|
|
546
|
-
* ```typescript
|
|
547
|
-
* const response: ApiResponse<never> = {
|
|
548
|
-
* status: 400,
|
|
549
|
-
* error: 'Invalid tenant name provided'
|
|
550
|
-
* };
|
|
551
|
-
* ```
|
|
552
|
-
*
|
|
553
|
-
* @since 1.0.0
|
|
554
|
-
* @public
|
|
555
|
-
*/
|
|
556
|
-
type ApiResponse<T> = {
|
|
557
|
-
/**
|
|
558
|
-
* Response data payload (present only on successful operations)
|
|
559
|
-
* Contains the actual data returned by the API endpoint
|
|
560
|
-
*/
|
|
561
|
-
data?: T;
|
|
562
|
-
/**
|
|
563
|
-
* HTTP status code indicating the result of the operation
|
|
564
|
-
* @example 200 for success, 400 for client errors, 500 for server errors
|
|
565
|
-
*/
|
|
566
|
-
status: number;
|
|
567
|
-
/**
|
|
568
|
-
* Error message (present only when operation fails)
|
|
569
|
-
* Provides human-readable description of what went wrong
|
|
570
|
-
*/
|
|
571
|
-
error?: string;
|
|
572
|
-
};
|
|
573
|
-
|
|
574
525
|
/**
|
|
575
526
|
* Response structure for switching the active tenant
|
|
576
527
|
*
|
|
@@ -681,4 +632,4 @@ type SwitchActiveTenantResponse = ApiResponse<{
|
|
|
681
632
|
*/
|
|
682
633
|
declare function switchActiveTenant(tenantId: string): Promise<SwitchActiveTenantResponse>;
|
|
683
634
|
|
|
684
|
-
export { type AcceptTenantInviteRequest, type AcceptTenantInviteResponse,
|
|
635
|
+
export { type AcceptTenantInviteRequest, type AcceptTenantInviteResponse, ApiResponse, type CreateTenantRequest, type CreateTenantResponse, type CreateTenantUserInviteRequest, type CreateTenantUserInviteResponse, type DeleteTenantResponse, type SwitchActiveTenantResponse, type Tenant, type TenantInvite, acceptTenantInvite, createTenant, createTenantUserInvite, deleteTenant, switchActiveTenant };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base API Response structure for all tenant operations
|
|
3
|
+
*
|
|
4
|
+
* This generic type defines the standard response format returned by all
|
|
5
|
+
* tenant-related API endpoints. It provides a consistent structure for
|
|
6
|
+
* handling both successful responses and error conditions across the SDK.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The type of the response data payload
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* Successful response:
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const response: ApiResponse<{ tenant: Tenant }> = {
|
|
14
|
+
* data: { tenant: { id: '123', name: 'My Company' } },
|
|
15
|
+
* status: 200
|
|
16
|
+
* };
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* Error response:
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const response: ApiResponse<never> = {
|
|
23
|
+
* status: 400,
|
|
24
|
+
* error: 'Invalid tenant name provided'
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @since 1.0.0
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
type ApiResponse<T> = {
|
|
32
|
+
/**
|
|
33
|
+
* Response data payload (present only on successful operations)
|
|
34
|
+
* Contains the actual data returned by the API endpoint
|
|
35
|
+
*/
|
|
36
|
+
data?: T;
|
|
37
|
+
/**
|
|
38
|
+
* HTTP status code indicating the result of the operation
|
|
39
|
+
* @example 200 for success, 400 for client errors, 500 for server errors
|
|
40
|
+
*/
|
|
41
|
+
status: number;
|
|
42
|
+
/**
|
|
43
|
+
* Error message (present only when operation fails)
|
|
44
|
+
* Provides human-readable description of what went wrong
|
|
45
|
+
*/
|
|
46
|
+
error?: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type { ApiResponse as A };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base API Response structure for all tenant operations
|
|
3
|
+
*
|
|
4
|
+
* This generic type defines the standard response format returned by all
|
|
5
|
+
* tenant-related API endpoints. It provides a consistent structure for
|
|
6
|
+
* handling both successful responses and error conditions across the SDK.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The type of the response data payload
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* Successful response:
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const response: ApiResponse<{ tenant: Tenant }> = {
|
|
14
|
+
* data: { tenant: { id: '123', name: 'My Company' } },
|
|
15
|
+
* status: 200
|
|
16
|
+
* };
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* Error response:
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const response: ApiResponse<never> = {
|
|
23
|
+
* status: 400,
|
|
24
|
+
* error: 'Invalid tenant name provided'
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @since 1.0.0
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
type ApiResponse<T> = {
|
|
32
|
+
/**
|
|
33
|
+
* Response data payload (present only on successful operations)
|
|
34
|
+
* Contains the actual data returned by the API endpoint
|
|
35
|
+
*/
|
|
36
|
+
data?: T;
|
|
37
|
+
/**
|
|
38
|
+
* HTTP status code indicating the result of the operation
|
|
39
|
+
* @example 200 for success, 400 for client errors, 500 for server errors
|
|
40
|
+
*/
|
|
41
|
+
status: number;
|
|
42
|
+
/**
|
|
43
|
+
* Error message (present only when operation fails)
|
|
44
|
+
* Provides human-readable description of what went wrong
|
|
45
|
+
*/
|
|
46
|
+
error?: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type { ApiResponse as A };
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omnibase/core-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "OmniBase core Javascript SDK - framework agnostic",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/**/*"
|
|
7
7
|
],
|
|
8
8
|
"type": "module",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "tsup src/database/index.ts src/tenants/index.ts src/auth/index.ts --format cjs,esm --dts",
|
|
10
|
+
"build": "tsup src/database/index.ts src/tenants/index.ts src/auth/index.ts src/stripe/index.ts --format cjs,esm --dts",
|
|
11
11
|
"prepublishOnly": "npm run build",
|
|
12
12
|
"build:docs": "bunx typedoc"
|
|
13
13
|
},
|
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
"import": "./dist/tenants/index.js",
|
|
25
25
|
"require": "./dist/tenants/index.cjs",
|
|
26
26
|
"types": "./dist/tenants/index.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./stripe": {
|
|
29
|
+
"import": "./dist/stripe/index.js",
|
|
30
|
+
"require": "./dist/stripe/index.cjs",
|
|
31
|
+
"types": "./dist/stripe/index.d.ts"
|
|
27
32
|
}
|
|
28
33
|
},
|
|
29
34
|
"keywords": [
|