@umituz/web-polar-payment 1.0.19 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +68 -36
- package/dist/index.d.ts +68 -36
- package/dist/index.js +121 -75
- package/dist/index.mjs +119 -74
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/presentation/hooks/usePolarProducts.ts +83 -0
package/dist/index.d.mts
CHANGED
|
@@ -76,41 +76,6 @@ interface PolarContextValue {
|
|
|
76
76
|
}
|
|
77
77
|
declare function usePolarBilling(): PolarContextValue;
|
|
78
78
|
|
|
79
|
-
interface FirebaseAdapterConfig {
|
|
80
|
-
functions: unknown;
|
|
81
|
-
firestore: unknown;
|
|
82
|
-
callables?: {
|
|
83
|
-
createCheckout?: string;
|
|
84
|
-
syncSubscription?: string;
|
|
85
|
-
getBillingHistory?: string;
|
|
86
|
-
cancelSubscription?: string;
|
|
87
|
-
getPortalUrl?: string;
|
|
88
|
-
};
|
|
89
|
-
db?: {
|
|
90
|
-
usersCollection?: string;
|
|
91
|
-
planField?: string;
|
|
92
|
-
billingCycleField?: string;
|
|
93
|
-
subscriptionIdField?: string;
|
|
94
|
-
subscriptionStatusField?: string;
|
|
95
|
-
polarCustomerIdField?: string;
|
|
96
|
-
cancelAtPeriodEndField?: string;
|
|
97
|
-
currentPeriodEndField?: string;
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
declare function createFirebaseAdapter(config: FirebaseAdapterConfig): PolarAdapter;
|
|
101
|
-
|
|
102
|
-
declare const SUBSCRIPTION_STATUS: Readonly<{
|
|
103
|
-
ACTIVE: "active";
|
|
104
|
-
CANCELED: "canceled";
|
|
105
|
-
REVOKED: "revoked";
|
|
106
|
-
TRIALING: "trialing";
|
|
107
|
-
PAST_DUE: "past_due";
|
|
108
|
-
INCOMPLETE: "incomplete";
|
|
109
|
-
INCOMPLETE_EXPIRED: "incomplete_expired";
|
|
110
|
-
UNPAID: "unpaid";
|
|
111
|
-
NONE: "none";
|
|
112
|
-
}>;
|
|
113
|
-
|
|
114
79
|
/**
|
|
115
80
|
* Product Entity
|
|
116
81
|
*
|
|
@@ -162,6 +127,73 @@ interface ProductListParams {
|
|
|
162
127
|
limit?: number;
|
|
163
128
|
}
|
|
164
129
|
|
|
130
|
+
/**
|
|
131
|
+
* usePolarProducts Hook
|
|
132
|
+
*
|
|
133
|
+
* Fetch and manage products from Polar.sh API
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
interface UsePolarProductsOptions {
|
|
137
|
+
apiToken: string;
|
|
138
|
+
organizationId?: string;
|
|
139
|
+
isRecurring?: boolean;
|
|
140
|
+
enabled?: boolean;
|
|
141
|
+
}
|
|
142
|
+
interface UsePolarProductsResult {
|
|
143
|
+
products: PolarProduct[];
|
|
144
|
+
loading: boolean;
|
|
145
|
+
error: string | null;
|
|
146
|
+
refetch: () => Promise<void>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Fetch products from Polar.sh API
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const { products, loading, error } = usePolarProducts({
|
|
154
|
+
* apiToken: polarApiToken,
|
|
155
|
+
* organizationId: polarOrgId,
|
|
156
|
+
* isRecurring: true,
|
|
157
|
+
* });
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
declare function usePolarProducts(options: UsePolarProductsOptions): UsePolarProductsResult;
|
|
161
|
+
|
|
162
|
+
interface FirebaseAdapterConfig {
|
|
163
|
+
functions: unknown;
|
|
164
|
+
firestore: unknown;
|
|
165
|
+
callables?: {
|
|
166
|
+
createCheckout?: string;
|
|
167
|
+
syncSubscription?: string;
|
|
168
|
+
getBillingHistory?: string;
|
|
169
|
+
cancelSubscription?: string;
|
|
170
|
+
getPortalUrl?: string;
|
|
171
|
+
};
|
|
172
|
+
db?: {
|
|
173
|
+
usersCollection?: string;
|
|
174
|
+
planField?: string;
|
|
175
|
+
billingCycleField?: string;
|
|
176
|
+
subscriptionIdField?: string;
|
|
177
|
+
subscriptionStatusField?: string;
|
|
178
|
+
polarCustomerIdField?: string;
|
|
179
|
+
cancelAtPeriodEndField?: string;
|
|
180
|
+
currentPeriodEndField?: string;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
declare function createFirebaseAdapter(config: FirebaseAdapterConfig): PolarAdapter;
|
|
184
|
+
|
|
185
|
+
declare const SUBSCRIPTION_STATUS: Readonly<{
|
|
186
|
+
ACTIVE: "active";
|
|
187
|
+
CANCELED: "canceled";
|
|
188
|
+
REVOKED: "revoked";
|
|
189
|
+
TRIALING: "trialing";
|
|
190
|
+
PAST_DUE: "past_due";
|
|
191
|
+
INCOMPLETE: "incomplete";
|
|
192
|
+
INCOMPLETE_EXPIRED: "incomplete_expired";
|
|
193
|
+
UNPAID: "unpaid";
|
|
194
|
+
NONE: "none";
|
|
195
|
+
}>;
|
|
196
|
+
|
|
165
197
|
/**
|
|
166
198
|
* Polar API Service
|
|
167
199
|
*
|
|
@@ -212,4 +244,4 @@ declare function getProductById(config: PolarApiConfig, productId: string): Prom
|
|
|
212
244
|
*/
|
|
213
245
|
declare function getAllProducts(config: PolarApiConfig, params?: Omit<ProductListParams, 'page' | 'limit'>): Promise<PolarProduct[]>;
|
|
214
246
|
|
|
215
|
-
export { type BillingCycle, type CancelResult, type CancellationReason, type CheckoutParams, type CheckoutResult, type FirebaseAdapterConfig, type OrderItem, type PolarAdapter, type PolarApiConfig, type PolarContextValue, type PolarPrice, type PolarProduct, PolarProvider, type PriceType, type ProductListParams, type ProductListResponse, type RecurringInterval, SUBSCRIPTION_STATUS, type SubscriptionStatus, type SubscriptionStatusValue, type SyncResult, createFirebaseAdapter, getAllProducts, getProductById, getProducts, usePolarBilling };
|
|
247
|
+
export { type BillingCycle, type CancelResult, type CancellationReason, type CheckoutParams, type CheckoutResult, type FirebaseAdapterConfig, type OrderItem, type PolarAdapter, type PolarApiConfig, type PolarContextValue, type PolarPrice, type PolarProduct, PolarProvider, type PriceType, type ProductListParams, type ProductListResponse, type RecurringInterval, SUBSCRIPTION_STATUS, type SubscriptionStatus, type SubscriptionStatusValue, type SyncResult, type UsePolarProductsOptions, type UsePolarProductsResult, createFirebaseAdapter, getAllProducts, getProductById, getProducts, usePolarBilling, usePolarProducts };
|
package/dist/index.d.ts
CHANGED
|
@@ -76,41 +76,6 @@ interface PolarContextValue {
|
|
|
76
76
|
}
|
|
77
77
|
declare function usePolarBilling(): PolarContextValue;
|
|
78
78
|
|
|
79
|
-
interface FirebaseAdapterConfig {
|
|
80
|
-
functions: unknown;
|
|
81
|
-
firestore: unknown;
|
|
82
|
-
callables?: {
|
|
83
|
-
createCheckout?: string;
|
|
84
|
-
syncSubscription?: string;
|
|
85
|
-
getBillingHistory?: string;
|
|
86
|
-
cancelSubscription?: string;
|
|
87
|
-
getPortalUrl?: string;
|
|
88
|
-
};
|
|
89
|
-
db?: {
|
|
90
|
-
usersCollection?: string;
|
|
91
|
-
planField?: string;
|
|
92
|
-
billingCycleField?: string;
|
|
93
|
-
subscriptionIdField?: string;
|
|
94
|
-
subscriptionStatusField?: string;
|
|
95
|
-
polarCustomerIdField?: string;
|
|
96
|
-
cancelAtPeriodEndField?: string;
|
|
97
|
-
currentPeriodEndField?: string;
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
declare function createFirebaseAdapter(config: FirebaseAdapterConfig): PolarAdapter;
|
|
101
|
-
|
|
102
|
-
declare const SUBSCRIPTION_STATUS: Readonly<{
|
|
103
|
-
ACTIVE: "active";
|
|
104
|
-
CANCELED: "canceled";
|
|
105
|
-
REVOKED: "revoked";
|
|
106
|
-
TRIALING: "trialing";
|
|
107
|
-
PAST_DUE: "past_due";
|
|
108
|
-
INCOMPLETE: "incomplete";
|
|
109
|
-
INCOMPLETE_EXPIRED: "incomplete_expired";
|
|
110
|
-
UNPAID: "unpaid";
|
|
111
|
-
NONE: "none";
|
|
112
|
-
}>;
|
|
113
|
-
|
|
114
79
|
/**
|
|
115
80
|
* Product Entity
|
|
116
81
|
*
|
|
@@ -162,6 +127,73 @@ interface ProductListParams {
|
|
|
162
127
|
limit?: number;
|
|
163
128
|
}
|
|
164
129
|
|
|
130
|
+
/**
|
|
131
|
+
* usePolarProducts Hook
|
|
132
|
+
*
|
|
133
|
+
* Fetch and manage products from Polar.sh API
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
interface UsePolarProductsOptions {
|
|
137
|
+
apiToken: string;
|
|
138
|
+
organizationId?: string;
|
|
139
|
+
isRecurring?: boolean;
|
|
140
|
+
enabled?: boolean;
|
|
141
|
+
}
|
|
142
|
+
interface UsePolarProductsResult {
|
|
143
|
+
products: PolarProduct[];
|
|
144
|
+
loading: boolean;
|
|
145
|
+
error: string | null;
|
|
146
|
+
refetch: () => Promise<void>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Fetch products from Polar.sh API
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const { products, loading, error } = usePolarProducts({
|
|
154
|
+
* apiToken: polarApiToken,
|
|
155
|
+
* organizationId: polarOrgId,
|
|
156
|
+
* isRecurring: true,
|
|
157
|
+
* });
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
declare function usePolarProducts(options: UsePolarProductsOptions): UsePolarProductsResult;
|
|
161
|
+
|
|
162
|
+
interface FirebaseAdapterConfig {
|
|
163
|
+
functions: unknown;
|
|
164
|
+
firestore: unknown;
|
|
165
|
+
callables?: {
|
|
166
|
+
createCheckout?: string;
|
|
167
|
+
syncSubscription?: string;
|
|
168
|
+
getBillingHistory?: string;
|
|
169
|
+
cancelSubscription?: string;
|
|
170
|
+
getPortalUrl?: string;
|
|
171
|
+
};
|
|
172
|
+
db?: {
|
|
173
|
+
usersCollection?: string;
|
|
174
|
+
planField?: string;
|
|
175
|
+
billingCycleField?: string;
|
|
176
|
+
subscriptionIdField?: string;
|
|
177
|
+
subscriptionStatusField?: string;
|
|
178
|
+
polarCustomerIdField?: string;
|
|
179
|
+
cancelAtPeriodEndField?: string;
|
|
180
|
+
currentPeriodEndField?: string;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
declare function createFirebaseAdapter(config: FirebaseAdapterConfig): PolarAdapter;
|
|
184
|
+
|
|
185
|
+
declare const SUBSCRIPTION_STATUS: Readonly<{
|
|
186
|
+
ACTIVE: "active";
|
|
187
|
+
CANCELED: "canceled";
|
|
188
|
+
REVOKED: "revoked";
|
|
189
|
+
TRIALING: "trialing";
|
|
190
|
+
PAST_DUE: "past_due";
|
|
191
|
+
INCOMPLETE: "incomplete";
|
|
192
|
+
INCOMPLETE_EXPIRED: "incomplete_expired";
|
|
193
|
+
UNPAID: "unpaid";
|
|
194
|
+
NONE: "none";
|
|
195
|
+
}>;
|
|
196
|
+
|
|
165
197
|
/**
|
|
166
198
|
* Polar API Service
|
|
167
199
|
*
|
|
@@ -212,4 +244,4 @@ declare function getProductById(config: PolarApiConfig, productId: string): Prom
|
|
|
212
244
|
*/
|
|
213
245
|
declare function getAllProducts(config: PolarApiConfig, params?: Omit<ProductListParams, 'page' | 'limit'>): Promise<PolarProduct[]>;
|
|
214
246
|
|
|
215
|
-
export { type BillingCycle, type CancelResult, type CancellationReason, type CheckoutParams, type CheckoutResult, type FirebaseAdapterConfig, type OrderItem, type PolarAdapter, type PolarApiConfig, type PolarContextValue, type PolarPrice, type PolarProduct, PolarProvider, type PriceType, type ProductListParams, type ProductListResponse, type RecurringInterval, SUBSCRIPTION_STATUS, type SubscriptionStatus, type SubscriptionStatusValue, type SyncResult, createFirebaseAdapter, getAllProducts, getProductById, getProducts, usePolarBilling };
|
|
247
|
+
export { type BillingCycle, type CancelResult, type CancellationReason, type CheckoutParams, type CheckoutResult, type FirebaseAdapterConfig, type OrderItem, type PolarAdapter, type PolarApiConfig, type PolarContextValue, type PolarPrice, type PolarProduct, PolarProvider, type PriceType, type ProductListParams, type ProductListResponse, type RecurringInterval, SUBSCRIPTION_STATUS, type SubscriptionStatus, type SubscriptionStatusValue, type SyncResult, type UsePolarProductsOptions, type UsePolarProductsResult, createFirebaseAdapter, getAllProducts, getProductById, getProducts, usePolarBilling, usePolarProducts };
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,8 @@ __export(index_exports, {
|
|
|
36
36
|
getAllProducts: () => getAllProducts,
|
|
37
37
|
getProductById: () => getProductById,
|
|
38
38
|
getProducts: () => getProducts,
|
|
39
|
-
usePolarBilling: () => usePolarBilling
|
|
39
|
+
usePolarBilling: () => usePolarBilling,
|
|
40
|
+
usePolarProducts: () => usePolarProducts
|
|
40
41
|
});
|
|
41
42
|
module.exports = __toCommonJS(index_exports);
|
|
42
43
|
|
|
@@ -168,6 +169,123 @@ function PolarProvider({ adapter, userId, children }) {
|
|
|
168
169
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PolarContext.Provider, { value, children });
|
|
169
170
|
}
|
|
170
171
|
|
|
172
|
+
// src/presentation/hooks/usePolarProducts.ts
|
|
173
|
+
var import_react3 = require("react");
|
|
174
|
+
|
|
175
|
+
// src/infrastructure/services/polar-api.service.ts
|
|
176
|
+
async function getProducts(config, params) {
|
|
177
|
+
const baseUrl = config.baseUrl || "https://api.polar.sh/v1";
|
|
178
|
+
const url = new URL(`${baseUrl}/products`);
|
|
179
|
+
if (params?.organizationId) {
|
|
180
|
+
url.searchParams.set("organization_id", params.organizationId);
|
|
181
|
+
}
|
|
182
|
+
if (params?.isRecurring !== void 0) {
|
|
183
|
+
url.searchParams.set("is_recurring", String(params.isRecurring));
|
|
184
|
+
}
|
|
185
|
+
if (params?.page) {
|
|
186
|
+
url.searchParams.set("page", String(params.page));
|
|
187
|
+
}
|
|
188
|
+
if (params?.limit) {
|
|
189
|
+
url.searchParams.set("limit", String(Math.min(params.limit, 100)));
|
|
190
|
+
}
|
|
191
|
+
const response = await fetch(url.toString(), {
|
|
192
|
+
method: "GET",
|
|
193
|
+
headers: {
|
|
194
|
+
"Authorization": `Bearer ${config.apiToken}`,
|
|
195
|
+
"Accept": "application/json"
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
if (!response.ok) {
|
|
199
|
+
const error = await response.text();
|
|
200
|
+
throw new Error(
|
|
201
|
+
`Polar API error: ${response.status} ${response.statusText}
|
|
202
|
+
${error}`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
const data = await response.json();
|
|
206
|
+
return data;
|
|
207
|
+
}
|
|
208
|
+
async function getProductById(config, productId) {
|
|
209
|
+
const baseUrl = config.baseUrl || "https://api.polar.sh/v1";
|
|
210
|
+
const url = `${baseUrl}/products/${productId}`;
|
|
211
|
+
const response = await fetch(url, {
|
|
212
|
+
method: "GET",
|
|
213
|
+
headers: {
|
|
214
|
+
"Authorization": `Bearer ${config.apiToken}`,
|
|
215
|
+
"Accept": "application/json"
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
if (response.status === 404) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
if (!response.ok) {
|
|
222
|
+
const error = await response.text();
|
|
223
|
+
throw new Error(
|
|
224
|
+
`Polar API error: ${response.status} ${response.statusText}
|
|
225
|
+
${error}`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
const data = await response.json();
|
|
229
|
+
return data;
|
|
230
|
+
}
|
|
231
|
+
async function getAllProducts(config, params) {
|
|
232
|
+
const allProducts = [];
|
|
233
|
+
let page = 1;
|
|
234
|
+
let maxPage = 1;
|
|
235
|
+
do {
|
|
236
|
+
const response = await getProducts(config, {
|
|
237
|
+
...params,
|
|
238
|
+
page,
|
|
239
|
+
limit: 100
|
|
240
|
+
});
|
|
241
|
+
allProducts.push(...response.items);
|
|
242
|
+
maxPage = response.pagination.max_page;
|
|
243
|
+
page++;
|
|
244
|
+
} while (page <= maxPage);
|
|
245
|
+
return allProducts;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// src/presentation/hooks/usePolarProducts.ts
|
|
249
|
+
function usePolarProducts(options) {
|
|
250
|
+
const { apiToken, organizationId, isRecurring = true, enabled = true } = options;
|
|
251
|
+
const [products, setProducts] = (0, import_react3.useState)([]);
|
|
252
|
+
const [loading, setLoading] = (0, import_react3.useState)(true);
|
|
253
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
254
|
+
const fetchProducts = async () => {
|
|
255
|
+
if (!enabled) {
|
|
256
|
+
setLoading(false);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
setLoading(true);
|
|
261
|
+
setError(null);
|
|
262
|
+
const params = {
|
|
263
|
+
isRecurring
|
|
264
|
+
};
|
|
265
|
+
if (organizationId) {
|
|
266
|
+
params.organizationId = organizationId;
|
|
267
|
+
}
|
|
268
|
+
const data = await getAllProducts({ apiToken }, params);
|
|
269
|
+
setProducts(data);
|
|
270
|
+
} catch (err) {
|
|
271
|
+
const message = err instanceof Error ? err.message : "Failed to fetch products";
|
|
272
|
+
setError(message);
|
|
273
|
+
console.error("usePolarProducts error:", err);
|
|
274
|
+
} finally {
|
|
275
|
+
setLoading(false);
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
(0, import_react3.useEffect)(() => {
|
|
279
|
+
fetchProducts();
|
|
280
|
+
}, [apiToken, organizationId, isRecurring, enabled]);
|
|
281
|
+
return {
|
|
282
|
+
products,
|
|
283
|
+
loading,
|
|
284
|
+
error,
|
|
285
|
+
refetch: fetchProducts
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
171
289
|
// src/infrastructure/constants/billing.constants.ts
|
|
172
290
|
var SUBSCRIPTION_STATUS = Object.freeze({
|
|
173
291
|
ACTIVE: "active",
|
|
@@ -315,79 +433,6 @@ function createFirebaseAdapter(config) {
|
|
|
315
433
|
}
|
|
316
434
|
};
|
|
317
435
|
}
|
|
318
|
-
|
|
319
|
-
// src/infrastructure/services/polar-api.service.ts
|
|
320
|
-
async function getProducts(config, params) {
|
|
321
|
-
const baseUrl = config.baseUrl || "https://api.polar.sh/v1";
|
|
322
|
-
const url = new URL(`${baseUrl}/products`);
|
|
323
|
-
if (params?.organizationId) {
|
|
324
|
-
url.searchParams.set("organization_id", params.organizationId);
|
|
325
|
-
}
|
|
326
|
-
if (params?.isRecurring !== void 0) {
|
|
327
|
-
url.searchParams.set("is_recurring", String(params.isRecurring));
|
|
328
|
-
}
|
|
329
|
-
if (params?.page) {
|
|
330
|
-
url.searchParams.set("page", String(params.page));
|
|
331
|
-
}
|
|
332
|
-
if (params?.limit) {
|
|
333
|
-
url.searchParams.set("limit", String(Math.min(params.limit, 100)));
|
|
334
|
-
}
|
|
335
|
-
const response = await fetch(url.toString(), {
|
|
336
|
-
method: "GET",
|
|
337
|
-
headers: {
|
|
338
|
-
"Authorization": `Bearer ${config.apiToken}`,
|
|
339
|
-
"Accept": "application/json"
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
if (!response.ok) {
|
|
343
|
-
const error = await response.text();
|
|
344
|
-
throw new Error(
|
|
345
|
-
`Polar API error: ${response.status} ${response.statusText}
|
|
346
|
-
${error}`
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
const data = await response.json();
|
|
350
|
-
return data;
|
|
351
|
-
}
|
|
352
|
-
async function getProductById(config, productId) {
|
|
353
|
-
const baseUrl = config.baseUrl || "https://api.polar.sh/v1";
|
|
354
|
-
const url = `${baseUrl}/products/${productId}`;
|
|
355
|
-
const response = await fetch(url, {
|
|
356
|
-
method: "GET",
|
|
357
|
-
headers: {
|
|
358
|
-
"Authorization": `Bearer ${config.apiToken}`,
|
|
359
|
-
"Accept": "application/json"
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
if (response.status === 404) {
|
|
363
|
-
return null;
|
|
364
|
-
}
|
|
365
|
-
if (!response.ok) {
|
|
366
|
-
const error = await response.text();
|
|
367
|
-
throw new Error(
|
|
368
|
-
`Polar API error: ${response.status} ${response.statusText}
|
|
369
|
-
${error}`
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
const data = await response.json();
|
|
373
|
-
return data;
|
|
374
|
-
}
|
|
375
|
-
async function getAllProducts(config, params) {
|
|
376
|
-
const allProducts = [];
|
|
377
|
-
let page = 1;
|
|
378
|
-
let maxPage = 1;
|
|
379
|
-
do {
|
|
380
|
-
const response = await getProducts(config, {
|
|
381
|
-
...params,
|
|
382
|
-
page,
|
|
383
|
-
limit: 100
|
|
384
|
-
});
|
|
385
|
-
allProducts.push(...response.items);
|
|
386
|
-
maxPage = response.pagination.max_page;
|
|
387
|
-
page++;
|
|
388
|
-
} while (page <= maxPage);
|
|
389
|
-
return allProducts;
|
|
390
|
-
}
|
|
391
436
|
// Annotate the CommonJS export names for ESM import in node:
|
|
392
437
|
0 && (module.exports = {
|
|
393
438
|
PolarProvider,
|
|
@@ -396,5 +441,6 @@ async function getAllProducts(config, params) {
|
|
|
396
441
|
getAllProducts,
|
|
397
442
|
getProductById,
|
|
398
443
|
getProducts,
|
|
399
|
-
usePolarBilling
|
|
444
|
+
usePolarBilling,
|
|
445
|
+
usePolarProducts
|
|
400
446
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -132,6 +132,123 @@ function PolarProvider({ adapter, userId, children }) {
|
|
|
132
132
|
return /* @__PURE__ */ jsx(PolarContext.Provider, { value, children });
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
// src/presentation/hooks/usePolarProducts.ts
|
|
136
|
+
import { useState as useState2, useEffect as useEffect2 } from "react";
|
|
137
|
+
|
|
138
|
+
// src/infrastructure/services/polar-api.service.ts
|
|
139
|
+
async function getProducts(config, params) {
|
|
140
|
+
const baseUrl = config.baseUrl || "https://api.polar.sh/v1";
|
|
141
|
+
const url = new URL(`${baseUrl}/products`);
|
|
142
|
+
if (params?.organizationId) {
|
|
143
|
+
url.searchParams.set("organization_id", params.organizationId);
|
|
144
|
+
}
|
|
145
|
+
if (params?.isRecurring !== void 0) {
|
|
146
|
+
url.searchParams.set("is_recurring", String(params.isRecurring));
|
|
147
|
+
}
|
|
148
|
+
if (params?.page) {
|
|
149
|
+
url.searchParams.set("page", String(params.page));
|
|
150
|
+
}
|
|
151
|
+
if (params?.limit) {
|
|
152
|
+
url.searchParams.set("limit", String(Math.min(params.limit, 100)));
|
|
153
|
+
}
|
|
154
|
+
const response = await fetch(url.toString(), {
|
|
155
|
+
method: "GET",
|
|
156
|
+
headers: {
|
|
157
|
+
"Authorization": `Bearer ${config.apiToken}`,
|
|
158
|
+
"Accept": "application/json"
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
const error = await response.text();
|
|
163
|
+
throw new Error(
|
|
164
|
+
`Polar API error: ${response.status} ${response.statusText}
|
|
165
|
+
${error}`
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const data = await response.json();
|
|
169
|
+
return data;
|
|
170
|
+
}
|
|
171
|
+
async function getProductById(config, productId) {
|
|
172
|
+
const baseUrl = config.baseUrl || "https://api.polar.sh/v1";
|
|
173
|
+
const url = `${baseUrl}/products/${productId}`;
|
|
174
|
+
const response = await fetch(url, {
|
|
175
|
+
method: "GET",
|
|
176
|
+
headers: {
|
|
177
|
+
"Authorization": `Bearer ${config.apiToken}`,
|
|
178
|
+
"Accept": "application/json"
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
if (response.status === 404) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
const error = await response.text();
|
|
186
|
+
throw new Error(
|
|
187
|
+
`Polar API error: ${response.status} ${response.statusText}
|
|
188
|
+
${error}`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
const data = await response.json();
|
|
192
|
+
return data;
|
|
193
|
+
}
|
|
194
|
+
async function getAllProducts(config, params) {
|
|
195
|
+
const allProducts = [];
|
|
196
|
+
let page = 1;
|
|
197
|
+
let maxPage = 1;
|
|
198
|
+
do {
|
|
199
|
+
const response = await getProducts(config, {
|
|
200
|
+
...params,
|
|
201
|
+
page,
|
|
202
|
+
limit: 100
|
|
203
|
+
});
|
|
204
|
+
allProducts.push(...response.items);
|
|
205
|
+
maxPage = response.pagination.max_page;
|
|
206
|
+
page++;
|
|
207
|
+
} while (page <= maxPage);
|
|
208
|
+
return allProducts;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/presentation/hooks/usePolarProducts.ts
|
|
212
|
+
function usePolarProducts(options) {
|
|
213
|
+
const { apiToken, organizationId, isRecurring = true, enabled = true } = options;
|
|
214
|
+
const [products, setProducts] = useState2([]);
|
|
215
|
+
const [loading, setLoading] = useState2(true);
|
|
216
|
+
const [error, setError] = useState2(null);
|
|
217
|
+
const fetchProducts = async () => {
|
|
218
|
+
if (!enabled) {
|
|
219
|
+
setLoading(false);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
try {
|
|
223
|
+
setLoading(true);
|
|
224
|
+
setError(null);
|
|
225
|
+
const params = {
|
|
226
|
+
isRecurring
|
|
227
|
+
};
|
|
228
|
+
if (organizationId) {
|
|
229
|
+
params.organizationId = organizationId;
|
|
230
|
+
}
|
|
231
|
+
const data = await getAllProducts({ apiToken }, params);
|
|
232
|
+
setProducts(data);
|
|
233
|
+
} catch (err) {
|
|
234
|
+
const message = err instanceof Error ? err.message : "Failed to fetch products";
|
|
235
|
+
setError(message);
|
|
236
|
+
console.error("usePolarProducts error:", err);
|
|
237
|
+
} finally {
|
|
238
|
+
setLoading(false);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
useEffect2(() => {
|
|
242
|
+
fetchProducts();
|
|
243
|
+
}, [apiToken, organizationId, isRecurring, enabled]);
|
|
244
|
+
return {
|
|
245
|
+
products,
|
|
246
|
+
loading,
|
|
247
|
+
error,
|
|
248
|
+
refetch: fetchProducts
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
135
252
|
// src/infrastructure/constants/billing.constants.ts
|
|
136
253
|
var SUBSCRIPTION_STATUS = Object.freeze({
|
|
137
254
|
ACTIVE: "active",
|
|
@@ -279,79 +396,6 @@ function createFirebaseAdapter(config) {
|
|
|
279
396
|
}
|
|
280
397
|
};
|
|
281
398
|
}
|
|
282
|
-
|
|
283
|
-
// src/infrastructure/services/polar-api.service.ts
|
|
284
|
-
async function getProducts(config, params) {
|
|
285
|
-
const baseUrl = config.baseUrl || "https://api.polar.sh/v1";
|
|
286
|
-
const url = new URL(`${baseUrl}/products`);
|
|
287
|
-
if (params?.organizationId) {
|
|
288
|
-
url.searchParams.set("organization_id", params.organizationId);
|
|
289
|
-
}
|
|
290
|
-
if (params?.isRecurring !== void 0) {
|
|
291
|
-
url.searchParams.set("is_recurring", String(params.isRecurring));
|
|
292
|
-
}
|
|
293
|
-
if (params?.page) {
|
|
294
|
-
url.searchParams.set("page", String(params.page));
|
|
295
|
-
}
|
|
296
|
-
if (params?.limit) {
|
|
297
|
-
url.searchParams.set("limit", String(Math.min(params.limit, 100)));
|
|
298
|
-
}
|
|
299
|
-
const response = await fetch(url.toString(), {
|
|
300
|
-
method: "GET",
|
|
301
|
-
headers: {
|
|
302
|
-
"Authorization": `Bearer ${config.apiToken}`,
|
|
303
|
-
"Accept": "application/json"
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
if (!response.ok) {
|
|
307
|
-
const error = await response.text();
|
|
308
|
-
throw new Error(
|
|
309
|
-
`Polar API error: ${response.status} ${response.statusText}
|
|
310
|
-
${error}`
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
const data = await response.json();
|
|
314
|
-
return data;
|
|
315
|
-
}
|
|
316
|
-
async function getProductById(config, productId) {
|
|
317
|
-
const baseUrl = config.baseUrl || "https://api.polar.sh/v1";
|
|
318
|
-
const url = `${baseUrl}/products/${productId}`;
|
|
319
|
-
const response = await fetch(url, {
|
|
320
|
-
method: "GET",
|
|
321
|
-
headers: {
|
|
322
|
-
"Authorization": `Bearer ${config.apiToken}`,
|
|
323
|
-
"Accept": "application/json"
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
if (response.status === 404) {
|
|
327
|
-
return null;
|
|
328
|
-
}
|
|
329
|
-
if (!response.ok) {
|
|
330
|
-
const error = await response.text();
|
|
331
|
-
throw new Error(
|
|
332
|
-
`Polar API error: ${response.status} ${response.statusText}
|
|
333
|
-
${error}`
|
|
334
|
-
);
|
|
335
|
-
}
|
|
336
|
-
const data = await response.json();
|
|
337
|
-
return data;
|
|
338
|
-
}
|
|
339
|
-
async function getAllProducts(config, params) {
|
|
340
|
-
const allProducts = [];
|
|
341
|
-
let page = 1;
|
|
342
|
-
let maxPage = 1;
|
|
343
|
-
do {
|
|
344
|
-
const response = await getProducts(config, {
|
|
345
|
-
...params,
|
|
346
|
-
page,
|
|
347
|
-
limit: 100
|
|
348
|
-
});
|
|
349
|
-
allProducts.push(...response.items);
|
|
350
|
-
maxPage = response.pagination.max_page;
|
|
351
|
-
page++;
|
|
352
|
-
} while (page <= maxPage);
|
|
353
|
-
return allProducts;
|
|
354
|
-
}
|
|
355
399
|
export {
|
|
356
400
|
PolarProvider,
|
|
357
401
|
SUBSCRIPTION_STATUS,
|
|
@@ -359,5 +403,6 @@ export {
|
|
|
359
403
|
getAllProducts,
|
|
360
404
|
getProductById,
|
|
361
405
|
getProducts,
|
|
362
|
-
usePolarBilling
|
|
406
|
+
usePolarBilling,
|
|
407
|
+
usePolarProducts
|
|
363
408
|
};
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { PolarProvider } from './presentation/components/PolarProvider';
|
|
2
2
|
export { usePolarBilling } from './presentation/hooks/usePolarBilling';
|
|
3
|
+
export { usePolarProducts } from './presentation/hooks/usePolarProducts';
|
|
3
4
|
export type { PolarContextValue } from './presentation/hooks/usePolarBilling';
|
|
5
|
+
export type { UsePolarProductsOptions, UsePolarProductsResult } from './presentation/hooks/usePolarProducts';
|
|
4
6
|
export { createFirebaseAdapter } from './infrastructure/services/firebase-billing.service';
|
|
5
7
|
export type { FirebaseAdapterConfig } from './infrastructure/services/firebase-billing.service';
|
|
6
8
|
export { SUBSCRIPTION_STATUS } from './infrastructure/constants/billing.constants';
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePolarProducts Hook
|
|
3
|
+
*
|
|
4
|
+
* Fetch and manage products from Polar.sh API
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useEffect } from 'react';
|
|
8
|
+
import { getAllProducts } from '../../infrastructure/services/polar-api.service';
|
|
9
|
+
import type { PolarProduct, ProductListParams } from '../../domain/entities/product.entity';
|
|
10
|
+
|
|
11
|
+
export interface UsePolarProductsOptions {
|
|
12
|
+
apiToken: string;
|
|
13
|
+
organizationId?: string;
|
|
14
|
+
isRecurring?: boolean;
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface UsePolarProductsResult {
|
|
19
|
+
products: PolarProduct[];
|
|
20
|
+
loading: boolean;
|
|
21
|
+
error: string | null;
|
|
22
|
+
refetch: () => Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Fetch products from Polar.sh API
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* const { products, loading, error } = usePolarProducts({
|
|
31
|
+
* apiToken: polarApiToken,
|
|
32
|
+
* organizationId: polarOrgId,
|
|
33
|
+
* isRecurring: true,
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export function usePolarProducts(options: UsePolarProductsOptions): UsePolarProductsResult {
|
|
38
|
+
const { apiToken, organizationId, isRecurring = true, enabled = true } = options;
|
|
39
|
+
|
|
40
|
+
const [products, setProducts] = useState<PolarProduct[]>([]);
|
|
41
|
+
const [loading, setLoading] = useState(true);
|
|
42
|
+
const [error, setError] = useState<string | null>(null);
|
|
43
|
+
|
|
44
|
+
const fetchProducts = async () => {
|
|
45
|
+
if (!enabled) {
|
|
46
|
+
setLoading(false);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
setLoading(true);
|
|
52
|
+
setError(null);
|
|
53
|
+
|
|
54
|
+
const params: ProductListParams = {
|
|
55
|
+
isRecurring,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
if (organizationId) {
|
|
59
|
+
params.organizationId = organizationId;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const data = await getAllProducts({ apiToken }, params);
|
|
63
|
+
setProducts(data);
|
|
64
|
+
} catch (err) {
|
|
65
|
+
const message = err instanceof Error ? err.message : 'Failed to fetch products';
|
|
66
|
+
setError(message);
|
|
67
|
+
console.error('usePolarProducts error:', err);
|
|
68
|
+
} finally {
|
|
69
|
+
setLoading(false);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
fetchProducts();
|
|
75
|
+
}, [apiToken, organizationId, isRecurring, enabled]);
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
products,
|
|
79
|
+
loading,
|
|
80
|
+
error,
|
|
81
|
+
refetch: fetchProducts,
|
|
82
|
+
};
|
|
83
|
+
}
|