@umituz/web-polar-payment 1.0.17 → 1.0.19

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 CHANGED
@@ -111,4 +111,105 @@ declare const SUBSCRIPTION_STATUS: Readonly<{
111
111
  NONE: "none";
112
112
  }>;
113
113
 
114
- export { type BillingCycle, type CancelResult, type CancellationReason, type CheckoutParams, type CheckoutResult, type FirebaseAdapterConfig, type OrderItem, type PolarAdapter, type PolarContextValue, PolarProvider, SUBSCRIPTION_STATUS, type SubscriptionStatus, type SubscriptionStatusValue, type SyncResult, createFirebaseAdapter, usePolarBilling };
114
+ /**
115
+ * Product Entity
116
+ *
117
+ * Represents a Polar.sh product with pricing information
118
+ */
119
+ type RecurringInterval = 'day' | 'week' | 'month' | 'year';
120
+ type PriceType = 'fixed' | 'custom' | 'free' | 'seat_based' | 'metered_unit';
121
+ interface PolarPrice {
122
+ id: string;
123
+ type: PriceType;
124
+ amount_type: string;
125
+ amount?: number;
126
+ currency: string;
127
+ recurring_interval?: RecurringInterval;
128
+ is_archived: boolean;
129
+ product_id: string;
130
+ legacy?: boolean;
131
+ }
132
+ interface PolarProduct {
133
+ id: string;
134
+ name: string;
135
+ description: string | null;
136
+ is_recurring: boolean;
137
+ recurring_interval: RecurringInterval | null;
138
+ is_archived: boolean;
139
+ organization_id: string;
140
+ prices: PolarPrice[];
141
+ benefits: Array<{
142
+ id: string;
143
+ type: string;
144
+ description: string | null;
145
+ properties: Record<string, unknown>;
146
+ }>;
147
+ metadata: Record<string, unknown>;
148
+ created_at: string;
149
+ modified_at: string | null;
150
+ }
151
+ interface ProductListResponse {
152
+ items: PolarProduct[];
153
+ pagination: {
154
+ total_count: number;
155
+ max_page: number;
156
+ };
157
+ }
158
+ interface ProductListParams {
159
+ organizationId?: string;
160
+ isRecurring?: boolean;
161
+ page?: number;
162
+ limit?: number;
163
+ }
164
+
165
+ /**
166
+ * Polar API Service
167
+ *
168
+ * Direct client-side calls to Polar.sh API using OAT authentication
169
+ * Note: OAT tokens should only be used server-side in production
170
+ * This service is intended for server-side or edge function usage
171
+ */
172
+
173
+ interface PolarApiConfig {
174
+ apiToken: string;
175
+ baseUrl?: string;
176
+ }
177
+ /**
178
+ * Fetch products from Polar.sh API
179
+ *
180
+ * @param config - Polar API configuration with OAT token
181
+ * @param params - Query parameters for filtering products
182
+ * @returns Paginated list of products
183
+ *
184
+ * @example
185
+ * ```ts
186
+ * const products = await getProducts({
187
+ * apiToken: 'polar_oat_xxx',
188
+ * baseUrl: 'https://api.polar.sh/v1'
189
+ * }, {
190
+ * organizationId: 'org-123',
191
+ * isRecurring: true,
192
+ * page: 1,
193
+ * limit: 100
194
+ * });
195
+ * ```
196
+ */
197
+ declare function getProducts(config: PolarApiConfig, params?: ProductListParams): Promise<ProductListResponse>;
198
+ /**
199
+ * Fetch a single product by ID
200
+ *
201
+ * @param config - Polar API configuration
202
+ * @param productId - Product ID to fetch
203
+ * @returns Product details or null if not found
204
+ */
205
+ declare function getProductById(config: PolarApiConfig, productId: string): Promise<PolarProduct | null>;
206
+ /**
207
+ * Fetch all products with automatic pagination
208
+ *
209
+ * @param config - Polar API configuration
210
+ * @param params - Query parameters for filtering
211
+ * @returns All products matching the criteria
212
+ */
213
+ declare function getAllProducts(config: PolarApiConfig, params?: Omit<ProductListParams, 'page' | 'limit'>): Promise<PolarProduct[]>;
214
+
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 };
package/dist/index.d.ts CHANGED
@@ -111,4 +111,105 @@ declare const SUBSCRIPTION_STATUS: Readonly<{
111
111
  NONE: "none";
112
112
  }>;
113
113
 
114
- export { type BillingCycle, type CancelResult, type CancellationReason, type CheckoutParams, type CheckoutResult, type FirebaseAdapterConfig, type OrderItem, type PolarAdapter, type PolarContextValue, PolarProvider, SUBSCRIPTION_STATUS, type SubscriptionStatus, type SubscriptionStatusValue, type SyncResult, createFirebaseAdapter, usePolarBilling };
114
+ /**
115
+ * Product Entity
116
+ *
117
+ * Represents a Polar.sh product with pricing information
118
+ */
119
+ type RecurringInterval = 'day' | 'week' | 'month' | 'year';
120
+ type PriceType = 'fixed' | 'custom' | 'free' | 'seat_based' | 'metered_unit';
121
+ interface PolarPrice {
122
+ id: string;
123
+ type: PriceType;
124
+ amount_type: string;
125
+ amount?: number;
126
+ currency: string;
127
+ recurring_interval?: RecurringInterval;
128
+ is_archived: boolean;
129
+ product_id: string;
130
+ legacy?: boolean;
131
+ }
132
+ interface PolarProduct {
133
+ id: string;
134
+ name: string;
135
+ description: string | null;
136
+ is_recurring: boolean;
137
+ recurring_interval: RecurringInterval | null;
138
+ is_archived: boolean;
139
+ organization_id: string;
140
+ prices: PolarPrice[];
141
+ benefits: Array<{
142
+ id: string;
143
+ type: string;
144
+ description: string | null;
145
+ properties: Record<string, unknown>;
146
+ }>;
147
+ metadata: Record<string, unknown>;
148
+ created_at: string;
149
+ modified_at: string | null;
150
+ }
151
+ interface ProductListResponse {
152
+ items: PolarProduct[];
153
+ pagination: {
154
+ total_count: number;
155
+ max_page: number;
156
+ };
157
+ }
158
+ interface ProductListParams {
159
+ organizationId?: string;
160
+ isRecurring?: boolean;
161
+ page?: number;
162
+ limit?: number;
163
+ }
164
+
165
+ /**
166
+ * Polar API Service
167
+ *
168
+ * Direct client-side calls to Polar.sh API using OAT authentication
169
+ * Note: OAT tokens should only be used server-side in production
170
+ * This service is intended for server-side or edge function usage
171
+ */
172
+
173
+ interface PolarApiConfig {
174
+ apiToken: string;
175
+ baseUrl?: string;
176
+ }
177
+ /**
178
+ * Fetch products from Polar.sh API
179
+ *
180
+ * @param config - Polar API configuration with OAT token
181
+ * @param params - Query parameters for filtering products
182
+ * @returns Paginated list of products
183
+ *
184
+ * @example
185
+ * ```ts
186
+ * const products = await getProducts({
187
+ * apiToken: 'polar_oat_xxx',
188
+ * baseUrl: 'https://api.polar.sh/v1'
189
+ * }, {
190
+ * organizationId: 'org-123',
191
+ * isRecurring: true,
192
+ * page: 1,
193
+ * limit: 100
194
+ * });
195
+ * ```
196
+ */
197
+ declare function getProducts(config: PolarApiConfig, params?: ProductListParams): Promise<ProductListResponse>;
198
+ /**
199
+ * Fetch a single product by ID
200
+ *
201
+ * @param config - Polar API configuration
202
+ * @param productId - Product ID to fetch
203
+ * @returns Product details or null if not found
204
+ */
205
+ declare function getProductById(config: PolarApiConfig, productId: string): Promise<PolarProduct | null>;
206
+ /**
207
+ * Fetch all products with automatic pagination
208
+ *
209
+ * @param config - Polar API configuration
210
+ * @param params - Query parameters for filtering
211
+ * @returns All products matching the criteria
212
+ */
213
+ declare function getAllProducts(config: PolarApiConfig, params?: Omit<ProductListParams, 'page' | 'limit'>): Promise<PolarProduct[]>;
214
+
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 };
package/dist/index.js CHANGED
@@ -33,6 +33,9 @@ __export(index_exports, {
33
33
  PolarProvider: () => PolarProvider,
34
34
  SUBSCRIPTION_STATUS: () => SUBSCRIPTION_STATUS,
35
35
  createFirebaseAdapter: () => createFirebaseAdapter,
36
+ getAllProducts: () => getAllProducts,
37
+ getProductById: () => getProductById,
38
+ getProducts: () => getProducts,
36
39
  usePolarBilling: () => usePolarBilling
37
40
  });
38
41
  module.exports = __toCommonJS(index_exports);
@@ -312,10 +315,86 @@ function createFirebaseAdapter(config) {
312
315
  }
313
316
  };
314
317
  }
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
+ }
315
391
  // Annotate the CommonJS export names for ESM import in node:
316
392
  0 && (module.exports = {
317
393
  PolarProvider,
318
394
  SUBSCRIPTION_STATUS,
319
395
  createFirebaseAdapter,
396
+ getAllProducts,
397
+ getProductById,
398
+ getProducts,
320
399
  usePolarBilling
321
400
  });
package/dist/index.mjs CHANGED
@@ -279,9 +279,85 @@ function createFirebaseAdapter(config) {
279
279
  }
280
280
  };
281
281
  }
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
+ }
282
355
  export {
283
356
  PolarProvider,
284
357
  SUBSCRIPTION_STATUS,
285
358
  createFirebaseAdapter,
359
+ getAllProducts,
360
+ getProductById,
361
+ getProducts,
286
362
  usePolarBilling
287
363
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/web-polar-payment",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "Universal Polar.sh subscription billing — Firebase adapter",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Product Entity
3
+ *
4
+ * Represents a Polar.sh product with pricing information
5
+ */
6
+
7
+ export type RecurringInterval = 'day' | 'week' | 'month' | 'year';
8
+
9
+ export type PriceType = 'fixed' | 'custom' | 'free' | 'seat_based' | 'metered_unit';
10
+
11
+ export interface PolarPrice {
12
+ id: string;
13
+ type: PriceType;
14
+ amount_type: string;
15
+ amount?: number;
16
+ currency: string;
17
+ recurring_interval?: RecurringInterval;
18
+ is_archived: boolean;
19
+ product_id: string;
20
+ legacy?: boolean;
21
+ }
22
+
23
+ export interface PolarProduct {
24
+ id: string;
25
+ name: string;
26
+ description: string | null;
27
+ is_recurring: boolean;
28
+ recurring_interval: RecurringInterval | null;
29
+ is_archived: boolean;
30
+ organization_id: string;
31
+ prices: PolarPrice[];
32
+ benefits: Array<{
33
+ id: string;
34
+ type: string;
35
+ description: string | null;
36
+ properties: Record<string, unknown>;
37
+ }>;
38
+ metadata: Record<string, unknown>;
39
+ created_at: string;
40
+ modified_at: string | null;
41
+ }
42
+
43
+ export interface ProductListResponse {
44
+ items: PolarProduct[];
45
+ pagination: {
46
+ total_count: number;
47
+ max_page: number;
48
+ };
49
+ }
50
+
51
+ export interface ProductListParams {
52
+ organizationId?: string;
53
+ isRecurring?: boolean;
54
+ page?: number;
55
+ limit?: number;
56
+ }
package/src/index.ts CHANGED
@@ -7,3 +7,8 @@ export { SUBSCRIPTION_STATUS } from './infrastructure/constants/billing.constant
7
7
  export type { SubscriptionStatusValue, BillingCycle } from './domain/entities/subscription.entity';
8
8
  export type { SubscriptionStatus, CheckoutParams, CheckoutResult, OrderItem, CancellationReason, CancelResult, SyncResult } from './domain/entities';
9
9
  export type { PolarAdapter } from './domain/interfaces';
10
+
11
+ // Product API
12
+ export { getProducts, getProductById, getAllProducts } from './infrastructure/services/polar-api.service';
13
+ export type { PolarApiConfig } from './infrastructure/services/polar-api.service';
14
+ export type { PolarProduct, PolarPrice, ProductListResponse, ProductListParams, RecurringInterval, PriceType } from './domain/entities/product.entity';
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Polar API Service
3
+ *
4
+ * Direct client-side calls to Polar.sh API using OAT authentication
5
+ * Note: OAT tokens should only be used server-side in production
6
+ * This service is intended for server-side or edge function usage
7
+ */
8
+
9
+ import type {
10
+ PolarProduct,
11
+ ProductListResponse,
12
+ ProductListParams
13
+ } from '../../domain/entities/product.entity';
14
+
15
+ export interface PolarApiConfig {
16
+ apiToken: string;
17
+ baseUrl?: string;
18
+ }
19
+
20
+ /**
21
+ * Fetch products from Polar.sh API
22
+ *
23
+ * @param config - Polar API configuration with OAT token
24
+ * @param params - Query parameters for filtering products
25
+ * @returns Paginated list of products
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const products = await getProducts({
30
+ * apiToken: 'polar_oat_xxx',
31
+ * baseUrl: 'https://api.polar.sh/v1'
32
+ * }, {
33
+ * organizationId: 'org-123',
34
+ * isRecurring: true,
35
+ * page: 1,
36
+ * limit: 100
37
+ * });
38
+ * ```
39
+ */
40
+ export async function getProducts(
41
+ config: PolarApiConfig,
42
+ params?: ProductListParams
43
+ ): Promise<ProductListResponse> {
44
+ const baseUrl = config.baseUrl || 'https://api.polar.sh/v1';
45
+ const url = new URL(`${baseUrl}/products`);
46
+
47
+ if (params?.organizationId) {
48
+ url.searchParams.set('organization_id', params.organizationId);
49
+ }
50
+
51
+ if (params?.isRecurring !== undefined) {
52
+ url.searchParams.set('is_recurring', String(params.isRecurring));
53
+ }
54
+
55
+ if (params?.page) {
56
+ url.searchParams.set('page', String(params.page));
57
+ }
58
+
59
+ if (params?.limit) {
60
+ url.searchParams.set('limit', String(Math.min(params.limit, 100)));
61
+ }
62
+
63
+ const response = await fetch(url.toString(), {
64
+ method: 'GET',
65
+ headers: {
66
+ 'Authorization': `Bearer ${config.apiToken}`,
67
+ 'Accept': 'application/json',
68
+ },
69
+ });
70
+
71
+ if (!response.ok) {
72
+ const error = await response.text();
73
+ throw new Error(
74
+ `Polar API error: ${response.status} ${response.statusText}\n${error}`
75
+ );
76
+ }
77
+
78
+ const data = await response.json();
79
+ return data as ProductListResponse;
80
+ }
81
+
82
+ /**
83
+ * Fetch a single product by ID
84
+ *
85
+ * @param config - Polar API configuration
86
+ * @param productId - Product ID to fetch
87
+ * @returns Product details or null if not found
88
+ */
89
+ export async function getProductById(
90
+ config: PolarApiConfig,
91
+ productId: string
92
+ ): Promise<PolarProduct | null> {
93
+ const baseUrl = config.baseUrl || 'https://api.polar.sh/v1';
94
+ const url = `${baseUrl}/products/${productId}`;
95
+
96
+ const response = await fetch(url, {
97
+ method: 'GET',
98
+ headers: {
99
+ 'Authorization': `Bearer ${config.apiToken}`,
100
+ 'Accept': 'application/json',
101
+ },
102
+ });
103
+
104
+ if (response.status === 404) {
105
+ return null;
106
+ }
107
+
108
+ if (!response.ok) {
109
+ const error = await response.text();
110
+ throw new Error(
111
+ `Polar API error: ${response.status} ${response.statusText}\n${error}`
112
+ );
113
+ }
114
+
115
+ const data = await response.json();
116
+ return data as PolarProduct;
117
+ }
118
+
119
+ /**
120
+ * Fetch all products with automatic pagination
121
+ *
122
+ * @param config - Polar API configuration
123
+ * @param params - Query parameters for filtering
124
+ * @returns All products matching the criteria
125
+ */
126
+ export async function getAllProducts(
127
+ config: PolarApiConfig,
128
+ params?: Omit<ProductListParams, 'page' | 'limit'>
129
+ ): Promise<PolarProduct[]> {
130
+ const allProducts: PolarProduct[] = [];
131
+ let page = 1;
132
+ let maxPage = 1;
133
+
134
+ do {
135
+ const response = await getProducts(config, {
136
+ ...params,
137
+ page,
138
+ limit: 100,
139
+ });
140
+
141
+ allProducts.push(...response.items);
142
+ maxPage = response.pagination.max_page;
143
+ page++;
144
+ } while (page <= maxPage);
145
+
146
+ return allProducts;
147
+ }