@magnet-cms/plugin-polar 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.
@@ -0,0 +1,435 @@
1
+ import { PolarPluginConfig, SubscriptionAccessResponse, CreateCheckoutDto, SessionResponse, PolarMetricsResponse, CreatePortalDto } from '../index.js';
2
+ export { PolarPlugin } from '../index.js';
3
+ import { Model, BaseSchema } from '@magnet-cms/common';
4
+ import { OnModuleInit } from '@nestjs/common';
5
+ import { Polar } from '@polar-sh/sdk';
6
+
7
+ /**
8
+ * Polar Plugin Module
9
+ *
10
+ * Registers all Polar schemas, services, and controllers.
11
+ * Auto-imported by the @Plugin decorator's `module` field.
12
+ */
13
+ declare class PolarModule {
14
+ }
15
+
16
+ /**
17
+ * Core Polar SDK service.
18
+ *
19
+ * Initializes the Polar client from plugin options and provides
20
+ * typed access for other services to use.
21
+ */
22
+ declare class PolarService implements OnModuleInit {
23
+ private readonly config;
24
+ private readonly logger;
25
+ private polar;
26
+ constructor(config: PolarPluginConfig);
27
+ onModuleInit(): void;
28
+ /** Get the initialized Polar client */
29
+ get client(): Polar;
30
+ /** Get the plugin configuration */
31
+ get pluginConfig(): PolarPluginConfig;
32
+ /**
33
+ * Verify that raw body is available on the request.
34
+ * Must be called before webhook signature verification.
35
+ * Consumers must enable `rawBody: true` in NestFactory.create().
36
+ */
37
+ verifyRawBodyAvailable(req: {
38
+ rawBody?: Buffer;
39
+ }): asserts req is {
40
+ rawBody: Buffer;
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Polar Product — synced from Polar via webhooks.
46
+ * Represents a product available for purchase.
47
+ */
48
+ declare class PolarProduct {
49
+ /** Polar Product ID */
50
+ polarProductId: string;
51
+ /** Product name */
52
+ name: string;
53
+ /** Product description */
54
+ description?: string;
55
+ /** Whether the product is a recurring subscription */
56
+ isRecurring: boolean;
57
+ /** Whether the product is archived in Polar */
58
+ isArchived: boolean;
59
+ /** Polar Organization ID */
60
+ organizationId?: string;
61
+ /** Arbitrary metadata from Polar */
62
+ metadata?: Record<string, string | number | boolean>;
63
+ /** When the product was last synced */
64
+ updatedAt: Date;
65
+ }
66
+
67
+ /**
68
+ * Polar Customer — maps a Polar customer to a Magnet user.
69
+ * Synced from Polar via webhooks.
70
+ */
71
+ declare class PolarCustomer {
72
+ /** Polar Customer ID */
73
+ polarCustomerId: string;
74
+ /** Customer email address */
75
+ email: string;
76
+ /** Customer display name */
77
+ name?: string;
78
+ /** Reference to the Magnet user ID (via Polar externalId) */
79
+ userId?: string;
80
+ /** Arbitrary metadata from Polar */
81
+ metadata?: Record<string, string | number | boolean>;
82
+ /** When the customer was created in Polar */
83
+ createdAt: Date;
84
+ }
85
+
86
+ declare class PolarCustomerService {
87
+ private readonly customerModel;
88
+ constructor(customerModel: Model<PolarCustomer>);
89
+ /**
90
+ * Upsert a Polar customer record from a webhook customer payload.
91
+ */
92
+ upsertFromWebhook(data: {
93
+ id: string;
94
+ email: string;
95
+ name?: string | null;
96
+ externalId?: string | null;
97
+ metadata?: Record<string, string | number | boolean>;
98
+ }): Promise<BaseSchema<PolarCustomer>>;
99
+ /**
100
+ * Delete a customer record by Polar Customer ID.
101
+ */
102
+ deleteByPolarId(polarCustomerId: string): Promise<void>;
103
+ /**
104
+ * Find a customer by Magnet user ID.
105
+ */
106
+ findByUserId(userId: string): Promise<BaseSchema<PolarCustomer> | null>;
107
+ /**
108
+ * Find a customer by Polar Customer ID.
109
+ */
110
+ findByPolarId(polarCustomerId: string): Promise<BaseSchema<PolarCustomer> | null>;
111
+ /**
112
+ * List all customers.
113
+ */
114
+ findAll(): Promise<BaseSchema<PolarCustomer>[]>;
115
+ /**
116
+ * Link a Polar customer to a Magnet user.
117
+ */
118
+ linkToUser(polarCustomerId: string, userId: string): Promise<BaseSchema<PolarCustomer>>;
119
+ }
120
+
121
+ /**
122
+ * Polar Subscription — synced from Polar via webhooks.
123
+ * Tracks active, canceled, and past subscriptions.
124
+ */
125
+ declare class PolarSubscription {
126
+ /** Polar Subscription ID */
127
+ polarSubscriptionId: string;
128
+ /** Reference to PolarCustomer.polarCustomerId */
129
+ customerId: string;
130
+ /** Reference to PolarProduct.polarProductId */
131
+ productId: string;
132
+ /** Subscription status from Polar */
133
+ status: string;
134
+ /** Subscription amount in smallest currency unit (cents) */
135
+ amount?: number;
136
+ /** Three-letter ISO currency code */
137
+ currency?: string;
138
+ /** Recurring interval (month, year, week, day) */
139
+ recurringInterval?: string;
140
+ /** Start of the current billing period */
141
+ currentPeriodStart: Date;
142
+ /** End of the current billing period */
143
+ currentPeriodEnd: Date;
144
+ /** Whether the subscription will be canceled at the end of the period */
145
+ cancelAtPeriodEnd: boolean;
146
+ /** When the subscription started */
147
+ startedAt?: Date;
148
+ /** When the subscription ended (null if still active) */
149
+ endedAt?: Date;
150
+ /** When the subscription was last synced */
151
+ updatedAt: Date;
152
+ }
153
+
154
+ declare class PolarSubscriptionService {
155
+ private readonly subscriptionModel;
156
+ private readonly polarService;
157
+ constructor(subscriptionModel: Model<PolarSubscription>, polarService: PolarService);
158
+ /**
159
+ * Upsert a subscription from a webhook subscription payload.
160
+ */
161
+ syncSubscription(data: {
162
+ id: string;
163
+ customerId: string;
164
+ productId: string;
165
+ status: string;
166
+ amount?: number;
167
+ currency?: string;
168
+ recurringInterval?: string;
169
+ currentPeriodStart: Date;
170
+ currentPeriodEnd: Date;
171
+ cancelAtPeriodEnd: boolean;
172
+ startedAt?: Date | null;
173
+ endedAt?: Date | null;
174
+ }): Promise<BaseSchema<PolarSubscription>>;
175
+ /**
176
+ * Delete a subscription record by Polar Subscription ID.
177
+ */
178
+ deleteByPolarId(polarSubscriptionId: string): Promise<void>;
179
+ /**
180
+ * Find active subscription for a customer.
181
+ */
182
+ findActiveByCustomerId(customerId: string): Promise<BaseSchema<PolarSubscription> | null>;
183
+ /**
184
+ * List all subscriptions.
185
+ */
186
+ findAll(): Promise<BaseSchema<PolarSubscription>[]>;
187
+ /**
188
+ * Revoke (cancel immediately) a subscription via Polar SDK.
189
+ */
190
+ revoke(polarSubscriptionId: string): Promise<void>;
191
+ }
192
+
193
+ declare class PolarAccessService {
194
+ private readonly polarService;
195
+ private readonly customerService;
196
+ private readonly subscriptionService;
197
+ private readonly productModel;
198
+ constructor(polarService: PolarService, customerService: PolarCustomerService, subscriptionService: PolarSubscriptionService, productModel: Model<PolarProduct>);
199
+ /**
200
+ * Get subscription access info for a user.
201
+ * Returns subscription status, plan name, and feature flags.
202
+ */
203
+ getAccess(userId: string): Promise<SubscriptionAccessResponse>;
204
+ /**
205
+ * Resolve feature flags for a plan name from plugin config.
206
+ */
207
+ private resolveFeaturesForPlan;
208
+ }
209
+
210
+ /**
211
+ * Polar Benefit Grant — synced from Polar via webhooks.
212
+ * Represents an instance of a benefit granted to a specific customer.
213
+ */
214
+ declare class PolarBenefitGrant {
215
+ /** Polar Benefit Grant ID */
216
+ polarBenefitGrantId: string;
217
+ /** Reference to PolarBenefit.polarBenefitId */
218
+ benefitId: string;
219
+ /** Reference to PolarCustomer.polarCustomerId */
220
+ customerId: string;
221
+ /** Reference to PolarSubscription.polarSubscriptionId (optional) */
222
+ subscriptionId?: string;
223
+ /** Whether the benefit is currently granted */
224
+ isGranted: boolean;
225
+ /** Whether the benefit has been revoked */
226
+ isRevoked: boolean;
227
+ /** When the benefit was granted */
228
+ grantedAt?: Date;
229
+ /** When the benefit was revoked (null if still active) */
230
+ revokedAt?: Date;
231
+ }
232
+
233
+ /**
234
+ * Polar Benefit — synced from Polar via webhooks.
235
+ * Represents an entitlement attached to a product (license keys, downloads, Discord, etc.).
236
+ */
237
+ declare class PolarBenefit {
238
+ /** Polar Benefit ID */
239
+ polarBenefitId: string;
240
+ /** Benefit type (license_keys, downloadables, discord, custom, github_repository, meter_credit, etc.) */
241
+ type: string;
242
+ /** Benefit description */
243
+ description?: string;
244
+ /** Polar Organization ID */
245
+ organizationId?: string;
246
+ /** Whether the benefit is selectable by the customer */
247
+ selectable: boolean;
248
+ /** Whether the benefit can be deleted */
249
+ deletable: boolean;
250
+ /** When the benefit was created */
251
+ createdAt: Date;
252
+ }
253
+
254
+ declare class PolarBenefitService {
255
+ private readonly benefitModel;
256
+ private readonly benefitGrantModel;
257
+ constructor(benefitModel: Model<PolarBenefit>, benefitGrantModel: Model<PolarBenefitGrant>);
258
+ /**
259
+ * Upsert a benefit from a webhook benefit payload.
260
+ */
261
+ syncBenefit(data: {
262
+ id: string;
263
+ type: string;
264
+ description: string;
265
+ organizationId: string;
266
+ selectable: boolean;
267
+ deletable: boolean;
268
+ }): Promise<BaseSchema<PolarBenefit>>;
269
+ /**
270
+ * Upsert a benefit grant from a webhook payload.
271
+ * Handles created, updated, and revoked states.
272
+ */
273
+ syncBenefitGrant(data: {
274
+ id: string;
275
+ benefitId: string;
276
+ customerId: string;
277
+ subscriptionId?: string;
278
+ isGranted: boolean;
279
+ isRevoked: boolean;
280
+ grantedAt?: Date;
281
+ revokedAt?: Date;
282
+ }): Promise<BaseSchema<PolarBenefitGrant>>;
283
+ /**
284
+ * Find active benefit grants for a customer.
285
+ */
286
+ findGrantsByCustomerId(customerId: string): Promise<BaseSchema<PolarBenefitGrant>[]>;
287
+ /**
288
+ * List all benefits.
289
+ */
290
+ findAll(): Promise<BaseSchema<PolarBenefit>[]>;
291
+ /**
292
+ * List all benefit grants.
293
+ */
294
+ findGrantsAll(): Promise<BaseSchema<PolarBenefitGrant>[]>;
295
+ }
296
+
297
+ declare class PolarCheckoutService {
298
+ private readonly polarService;
299
+ constructor(polarService: PolarService);
300
+ /**
301
+ * Create a Polar Checkout session.
302
+ */
303
+ createCheckoutSession(dto: CreateCheckoutDto): Promise<SessionResponse>;
304
+ }
305
+
306
+ /**
307
+ * Polar Order — synced from Polar via webhooks.
308
+ * Represents a completed payment / transaction.
309
+ */
310
+ declare class PolarOrder {
311
+ /** Polar Order ID */
312
+ polarOrderId: string;
313
+ /** Reference to PolarCustomer.polarCustomerId */
314
+ customerId: string;
315
+ /** Reference to PolarProduct.polarProductId */
316
+ productId: string;
317
+ /** Reference to PolarSubscription.polarSubscriptionId (nullable for one-time purchases) */
318
+ subscriptionId?: string;
319
+ /** Order status */
320
+ status: string;
321
+ /** Total order amount in smallest currency unit (cents) */
322
+ totalAmount: number;
323
+ /** Three-letter ISO currency code */
324
+ currency: string;
325
+ /** Reason for billing (purchase, subscription_create, subscription_cycle, etc.) */
326
+ billingReason?: string;
327
+ /** When the order was created */
328
+ createdAt: Date;
329
+ }
330
+
331
+ declare class PolarMetricsService {
332
+ private readonly orderModel;
333
+ private readonly subscriptionModel;
334
+ private readonly polarService;
335
+ private readonly logger;
336
+ constructor(orderModel: Model<PolarOrder>, subscriptionModel: Model<PolarSubscription>, polarService: PolarService);
337
+ /**
338
+ * Get dashboard metrics — hybrid of live Polar API and local DB data.
339
+ */
340
+ getMetrics(): Promise<PolarMetricsResponse>;
341
+ /**
342
+ * Fetch metrics from Polar's analytics API.
343
+ */
344
+ private getMetricsFromApi;
345
+ /**
346
+ * Fall back to local DB computation if API call fails.
347
+ */
348
+ private getMetricsFromDb;
349
+ private countActiveSubscriptions;
350
+ private calculateRevenueThisMonth;
351
+ private calculateChurnRate;
352
+ private getRevenueByMonth;
353
+ private getRecentOrders;
354
+ }
355
+
356
+ declare class PolarOrderService {
357
+ private readonly orderModel;
358
+ constructor(orderModel: Model<PolarOrder>);
359
+ /**
360
+ * Upsert an order from a webhook order payload.
361
+ */
362
+ syncOrder(data: {
363
+ id: string;
364
+ customerId: string;
365
+ productId: string;
366
+ subscriptionId?: string | null;
367
+ status: string;
368
+ totalAmount: number;
369
+ currency: string;
370
+ billingReason?: string;
371
+ createdAt?: Date;
372
+ }): Promise<BaseSchema<PolarOrder>>;
373
+ /**
374
+ * List all orders.
375
+ */
376
+ findAll(): Promise<BaseSchema<PolarOrder>[]>;
377
+ /**
378
+ * Find orders for a customer.
379
+ */
380
+ findByCustomerId(customerId: string): Promise<BaseSchema<PolarOrder>[]>;
381
+ }
382
+
383
+ declare class PolarPortalService {
384
+ private readonly polarService;
385
+ private readonly customerService;
386
+ constructor(polarService: PolarService, customerService: PolarCustomerService);
387
+ /**
388
+ * Create a Polar Customer Portal session.
389
+ */
390
+ createPortalSession(dto: CreatePortalDto): Promise<SessionResponse>;
391
+ }
392
+
393
+ declare class PolarProductService {
394
+ private readonly productModel;
395
+ constructor(productModel: Model<PolarProduct>);
396
+ /**
397
+ * Upsert a product from a webhook product payload.
398
+ */
399
+ syncProduct(data: {
400
+ id: string;
401
+ name: string;
402
+ description?: string | null;
403
+ isRecurring: boolean;
404
+ isArchived: boolean;
405
+ organizationId?: string;
406
+ metadata?: Record<string, string | number | boolean>;
407
+ }): Promise<BaseSchema<PolarProduct>>;
408
+ /**
409
+ * Delete a product by Polar Product ID.
410
+ */
411
+ deleteProduct(polarProductId: string): Promise<void>;
412
+ /**
413
+ * List all non-archived products.
414
+ */
415
+ findActiveProducts(): Promise<BaseSchema<PolarProduct>[]>;
416
+ /**
417
+ * List all products.
418
+ */
419
+ findAllProducts(): Promise<BaseSchema<PolarProduct>[]>;
420
+ }
421
+
422
+ /**
423
+ * Polar Processed Event — idempotency tracking for webhook events.
424
+ * Stores event IDs to prevent duplicate processing.
425
+ */
426
+ declare class PolarProcessedEvent {
427
+ /** Polar Event ID — unique to prevent reprocessing */
428
+ polarEventId: string;
429
+ /** Event type (e.g., 'order.paid', 'subscription.updated') */
430
+ eventType: string;
431
+ /** When this event was processed */
432
+ processedAt: Date;
433
+ }
434
+
435
+ export { CreateCheckoutDto, CreatePortalDto, PolarAccessService, PolarBenefit, PolarBenefitGrant, PolarBenefitService, PolarCheckoutService, PolarCustomer, PolarCustomerService, PolarMetricsResponse, PolarMetricsService, PolarModule, PolarOrder, PolarOrderService, PolarPluginConfig, PolarPortalService, PolarProcessedEvent, PolarProduct, PolarProductService, PolarService, PolarSubscription, PolarSubscriptionService, SessionResponse, SubscriptionAccessResponse };
@@ -0,0 +1,22 @@
1
+ import { init_polar_module, init_access_service, init_benefit_service, init_checkout_service, init_customer_service, init_metrics_service, init_order_service, init_portal_service, init_product_service, init_subscription_service, init_polar_service, init_benefit_schema, init_benefit_grant_schema, init_customer_schema, init_order_schema, init_processed_event_schema, init_product_schema, init_subscription_schema } from '../chunk-7KT7JQIH.js';
2
+ export { PolarAccessService, PolarBenefit, PolarBenefitGrant, PolarBenefitService, PolarCheckoutService, PolarCustomer, PolarCustomerService, PolarMetricsService, PolarModule, PolarOrder, PolarOrderService, PolarPlugin, PolarPortalService, PolarProcessedEvent, PolarProduct, PolarProductService, PolarService, PolarSubscription, PolarSubscriptionService } from '../chunk-7KT7JQIH.js';
3
+
4
+ // src/backend/index.ts
5
+ init_polar_module();
6
+ init_access_service();
7
+ init_benefit_service();
8
+ init_checkout_service();
9
+ init_customer_service();
10
+ init_metrics_service();
11
+ init_order_service();
12
+ init_portal_service();
13
+ init_product_service();
14
+ init_subscription_service();
15
+ init_polar_service();
16
+ init_benefit_schema();
17
+ init_benefit_grant_schema();
18
+ init_customer_schema();
19
+ init_order_schema();
20
+ init_processed_event_schema();
21
+ init_product_schema();
22
+ init_subscription_schema();