@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,2474 @@
1
+ import { Plugin, InjectPluginOptions, DatabaseModule, RestrictedRoute, EmailService } from '@magnet-cms/core';
2
+ import { Logger, HttpException, HttpStatus, Injectable, Module, Post, Body, Get, Param, Controller, HttpCode, Req, Headers, Optional } from '@nestjs/common';
3
+ import { Polar } from '@polar-sh/sdk';
4
+ import { Field, Schema, Prop, InjectModel } from '@magnet-cms/common';
5
+ import { RFCDate } from '@polar-sh/sdk/types/rfcdate';
6
+ import { validateEvent, WebhookVerificationError } from '@polar-sh/sdk/webhooks';
7
+
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
13
+ var __esm = (fn, res) => function __init() {
14
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
+ };
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ function _ts_decorate(decorators, target, key, desc) {
30
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
31
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
32
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
33
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
34
+ }
35
+ function _ts_metadata(k, v) {
36
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
37
+ }
38
+ function _ts_param(paramIndex, decorator) {
39
+ return function(target, key) {
40
+ decorator(target, key, paramIndex);
41
+ };
42
+ }
43
+ var PolarService;
44
+ var init_polar_service = __esm({
45
+ "src/polar.service.ts"() {
46
+ __name(_ts_decorate, "_ts_decorate");
47
+ __name(_ts_metadata, "_ts_metadata");
48
+ __name(_ts_param, "_ts_param");
49
+ PolarService = class _PolarService {
50
+ static {
51
+ __name(this, "PolarService");
52
+ }
53
+ config;
54
+ logger;
55
+ polar;
56
+ constructor(config) {
57
+ this.config = config;
58
+ this.logger = new Logger(_PolarService.name);
59
+ this.polar = null;
60
+ }
61
+ onModuleInit() {
62
+ if (!this.config.accessToken) {
63
+ throw new Error("[PolarPlugin] Missing accessToken in plugin options. Configure it via: { plugin: PolarPlugin, options: { accessToken: process.env.POLAR_ACCESS_TOKEN } }");
64
+ }
65
+ this.polar = new Polar({
66
+ accessToken: this.config.accessToken
67
+ });
68
+ if (this.config.webhookSecret) {
69
+ this.logger.debug("Webhook secret configured. Ensure rawBody is enabled in NestFactory.create() for signature verification.");
70
+ }
71
+ }
72
+ /** Get the initialized Polar client */
73
+ get client() {
74
+ if (!this.polar) {
75
+ throw new Error("[PolarPlugin] Polar client not initialized. Ensure the module has been initialized.");
76
+ }
77
+ return this.polar;
78
+ }
79
+ /** Get the plugin configuration */
80
+ get pluginConfig() {
81
+ return this.config;
82
+ }
83
+ /**
84
+ * Verify that raw body is available on the request.
85
+ * Must be called before webhook signature verification.
86
+ * Consumers must enable `rawBody: true` in NestFactory.create().
87
+ */
88
+ verifyRawBodyAvailable(req) {
89
+ if (!req.rawBody) {
90
+ throw new HttpException("[PolarPlugin] Raw request body not available. Enable rawBody in your NestJS bootstrap: NestFactory.create(AppModule, { rawBody: true }). This is required for Polar webhook signature verification.", HttpStatus.INTERNAL_SERVER_ERROR);
91
+ }
92
+ }
93
+ };
94
+ PolarService = _ts_decorate([
95
+ Injectable(),
96
+ _ts_param(0, InjectPluginOptions("polar")),
97
+ _ts_metadata("design:type", Function),
98
+ _ts_metadata("design:paramtypes", [
99
+ typeof PolarPluginConfig === "undefined" ? Object : PolarPluginConfig
100
+ ])
101
+ ], PolarService);
102
+ }
103
+ });
104
+ function _ts_decorate2(decorators, target, key, desc) {
105
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
106
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
107
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
108
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
109
+ }
110
+ function _ts_metadata2(k, v) {
111
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
112
+ }
113
+ var PolarOrder;
114
+ var init_order_schema = __esm({
115
+ "src/schemas/order.schema.ts"() {
116
+ __name(_ts_decorate2, "_ts_decorate");
117
+ __name(_ts_metadata2, "_ts_metadata");
118
+ PolarOrder = class {
119
+ static {
120
+ __name(this, "PolarOrder");
121
+ }
122
+ /** Polar Order ID */
123
+ polarOrderId;
124
+ /** Reference to PolarCustomer.polarCustomerId */
125
+ customerId;
126
+ /** Reference to PolarProduct.polarProductId */
127
+ productId;
128
+ /** Reference to PolarSubscription.polarSubscriptionId (nullable for one-time purchases) */
129
+ subscriptionId;
130
+ /** Order status */
131
+ status;
132
+ /** Total order amount in smallest currency unit (cents) */
133
+ totalAmount;
134
+ /** Three-letter ISO currency code */
135
+ currency;
136
+ /** Reason for billing (purchase, subscription_create, subscription_cycle, etc.) */
137
+ billingReason;
138
+ /** When the order was created */
139
+ createdAt;
140
+ };
141
+ _ts_decorate2([
142
+ Field.Text({
143
+ required: true,
144
+ unique: true
145
+ }),
146
+ _ts_metadata2("design:type", String)
147
+ ], PolarOrder.prototype, "polarOrderId", void 0);
148
+ _ts_decorate2([
149
+ Field.Text({
150
+ required: true
151
+ }),
152
+ _ts_metadata2("design:type", String)
153
+ ], PolarOrder.prototype, "customerId", void 0);
154
+ _ts_decorate2([
155
+ Field.Text({
156
+ required: true
157
+ }),
158
+ _ts_metadata2("design:type", String)
159
+ ], PolarOrder.prototype, "productId", void 0);
160
+ _ts_decorate2([
161
+ Field.Text(),
162
+ _ts_metadata2("design:type", String)
163
+ ], PolarOrder.prototype, "subscriptionId", void 0);
164
+ _ts_decorate2([
165
+ Field.Select({
166
+ required: true,
167
+ options: [
168
+ {
169
+ label: "Paid",
170
+ value: "paid"
171
+ },
172
+ {
173
+ label: "Refunded",
174
+ value: "refunded"
175
+ },
176
+ {
177
+ label: "Pending",
178
+ value: "pending"
179
+ }
180
+ ]
181
+ }),
182
+ _ts_metadata2("design:type", String)
183
+ ], PolarOrder.prototype, "status", void 0);
184
+ _ts_decorate2([
185
+ Field.Number({
186
+ required: true
187
+ }),
188
+ _ts_metadata2("design:type", Number)
189
+ ], PolarOrder.prototype, "totalAmount", void 0);
190
+ _ts_decorate2([
191
+ Field.Text({
192
+ required: true
193
+ }),
194
+ _ts_metadata2("design:type", String)
195
+ ], PolarOrder.prototype, "currency", void 0);
196
+ _ts_decorate2([
197
+ Field.Text(),
198
+ _ts_metadata2("design:type", String)
199
+ ], PolarOrder.prototype, "billingReason", void 0);
200
+ _ts_decorate2([
201
+ Field.Date({
202
+ required: true,
203
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
204
+ }),
205
+ _ts_metadata2("design:type", typeof Date === "undefined" ? Object : Date)
206
+ ], PolarOrder.prototype, "createdAt", void 0);
207
+ PolarOrder = _ts_decorate2([
208
+ Schema({
209
+ versioning: false,
210
+ i18n: false,
211
+ visible: false
212
+ })
213
+ ], PolarOrder);
214
+ }
215
+ });
216
+ function _ts_decorate3(decorators, target, key, desc) {
217
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
218
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
219
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
220
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
221
+ }
222
+ function _ts_metadata3(k, v) {
223
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
224
+ }
225
+ var PolarProduct;
226
+ var init_product_schema = __esm({
227
+ "src/schemas/product.schema.ts"() {
228
+ __name(_ts_decorate3, "_ts_decorate");
229
+ __name(_ts_metadata3, "_ts_metadata");
230
+ PolarProduct = class {
231
+ static {
232
+ __name(this, "PolarProduct");
233
+ }
234
+ /** Polar Product ID */
235
+ polarProductId;
236
+ /** Product name */
237
+ name;
238
+ /** Product description */
239
+ description;
240
+ /** Whether the product is a recurring subscription */
241
+ isRecurring = false;
242
+ /** Whether the product is archived in Polar */
243
+ isArchived = false;
244
+ /** Polar Organization ID */
245
+ organizationId;
246
+ /** Arbitrary metadata from Polar */
247
+ metadata;
248
+ /** When the product was last synced */
249
+ updatedAt;
250
+ };
251
+ _ts_decorate3([
252
+ Field.Text({
253
+ required: true,
254
+ unique: true
255
+ }),
256
+ _ts_metadata3("design:type", String)
257
+ ], PolarProduct.prototype, "polarProductId", void 0);
258
+ _ts_decorate3([
259
+ Field.Text({
260
+ required: true
261
+ }),
262
+ _ts_metadata3("design:type", String)
263
+ ], PolarProduct.prototype, "name", void 0);
264
+ _ts_decorate3([
265
+ Field.Text(),
266
+ _ts_metadata3("design:type", String)
267
+ ], PolarProduct.prototype, "description", void 0);
268
+ _ts_decorate3([
269
+ Field.Boolean({
270
+ default: false
271
+ })
272
+ ], PolarProduct.prototype, "isRecurring", void 0);
273
+ _ts_decorate3([
274
+ Field.Boolean({
275
+ default: false
276
+ })
277
+ ], PolarProduct.prototype, "isArchived", void 0);
278
+ _ts_decorate3([
279
+ Field.Text(),
280
+ _ts_metadata3("design:type", String)
281
+ ], PolarProduct.prototype, "organizationId", void 0);
282
+ _ts_decorate3([
283
+ Prop({
284
+ type: Object
285
+ }),
286
+ _ts_metadata3("design:type", typeof Record === "undefined" ? Object : Record)
287
+ ], PolarProduct.prototype, "metadata", void 0);
288
+ _ts_decorate3([
289
+ Field.Date({
290
+ required: true,
291
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
292
+ }),
293
+ _ts_metadata3("design:type", typeof Date === "undefined" ? Object : Date)
294
+ ], PolarProduct.prototype, "updatedAt", void 0);
295
+ PolarProduct = _ts_decorate3([
296
+ Schema({
297
+ versioning: false,
298
+ i18n: false,
299
+ visible: false
300
+ })
301
+ ], PolarProduct);
302
+ }
303
+ });
304
+ function _ts_decorate4(decorators, target, key, desc) {
305
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
306
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
307
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
308
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
309
+ }
310
+ function _ts_metadata4(k, v) {
311
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
312
+ }
313
+ var PolarCustomer;
314
+ var init_customer_schema = __esm({
315
+ "src/schemas/customer.schema.ts"() {
316
+ __name(_ts_decorate4, "_ts_decorate");
317
+ __name(_ts_metadata4, "_ts_metadata");
318
+ PolarCustomer = class {
319
+ static {
320
+ __name(this, "PolarCustomer");
321
+ }
322
+ /** Polar Customer ID */
323
+ polarCustomerId;
324
+ /** Customer email address */
325
+ email;
326
+ /** Customer display name */
327
+ name;
328
+ /** Reference to the Magnet user ID (via Polar externalId) */
329
+ userId;
330
+ /** Arbitrary metadata from Polar */
331
+ metadata;
332
+ /** When the customer was created in Polar */
333
+ createdAt;
334
+ };
335
+ _ts_decorate4([
336
+ Field.Text({
337
+ required: true,
338
+ unique: true
339
+ }),
340
+ _ts_metadata4("design:type", String)
341
+ ], PolarCustomer.prototype, "polarCustomerId", void 0);
342
+ _ts_decorate4([
343
+ Field.Email({
344
+ required: true
345
+ }),
346
+ _ts_metadata4("design:type", String)
347
+ ], PolarCustomer.prototype, "email", void 0);
348
+ _ts_decorate4([
349
+ Field.Text(),
350
+ _ts_metadata4("design:type", String)
351
+ ], PolarCustomer.prototype, "name", void 0);
352
+ _ts_decorate4([
353
+ Field.Text(),
354
+ _ts_metadata4("design:type", String)
355
+ ], PolarCustomer.prototype, "userId", void 0);
356
+ _ts_decorate4([
357
+ Prop({
358
+ type: Object
359
+ }),
360
+ _ts_metadata4("design:type", typeof Record === "undefined" ? Object : Record)
361
+ ], PolarCustomer.prototype, "metadata", void 0);
362
+ _ts_decorate4([
363
+ Field.Date({
364
+ required: true,
365
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
366
+ }),
367
+ _ts_metadata4("design:type", typeof Date === "undefined" ? Object : Date)
368
+ ], PolarCustomer.prototype, "createdAt", void 0);
369
+ PolarCustomer = _ts_decorate4([
370
+ Schema({
371
+ versioning: false,
372
+ i18n: false,
373
+ visible: false
374
+ })
375
+ ], PolarCustomer);
376
+ }
377
+ });
378
+ function _ts_decorate5(decorators, target, key, desc) {
379
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
380
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
381
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
382
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
383
+ }
384
+ function _ts_metadata5(k, v) {
385
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
386
+ }
387
+ function _ts_param2(paramIndex, decorator) {
388
+ return function(target, key) {
389
+ decorator(target, key, paramIndex);
390
+ };
391
+ }
392
+ var PolarCustomerService;
393
+ var init_customer_service = __esm({
394
+ "src/services/customer.service.ts"() {
395
+ init_customer_schema();
396
+ __name(_ts_decorate5, "_ts_decorate");
397
+ __name(_ts_metadata5, "_ts_metadata");
398
+ __name(_ts_param2, "_ts_param");
399
+ PolarCustomerService = class {
400
+ static {
401
+ __name(this, "PolarCustomerService");
402
+ }
403
+ customerModel;
404
+ constructor(customerModel) {
405
+ this.customerModel = customerModel;
406
+ }
407
+ /**
408
+ * Upsert a Polar customer record from a webhook customer payload.
409
+ */
410
+ async upsertFromWebhook(data) {
411
+ const customerData = {
412
+ polarCustomerId: data.id,
413
+ email: data.email,
414
+ name: data.name ?? void 0,
415
+ userId: data.externalId ?? void 0,
416
+ metadata: data.metadata
417
+ };
418
+ const existing = await this.customerModel.findOne({
419
+ polarCustomerId: data.id
420
+ });
421
+ if (existing) {
422
+ return this.customerModel.update({
423
+ polarCustomerId: data.id
424
+ }, customerData);
425
+ }
426
+ return this.customerModel.create(customerData);
427
+ }
428
+ /**
429
+ * Delete a customer record by Polar Customer ID.
430
+ */
431
+ async deleteByPolarId(polarCustomerId) {
432
+ await this.customerModel.delete({
433
+ polarCustomerId
434
+ });
435
+ }
436
+ /**
437
+ * Find a customer by Magnet user ID.
438
+ */
439
+ async findByUserId(userId) {
440
+ return this.customerModel.findOne({
441
+ userId
442
+ });
443
+ }
444
+ /**
445
+ * Find a customer by Polar Customer ID.
446
+ */
447
+ async findByPolarId(polarCustomerId) {
448
+ return this.customerModel.findOne({
449
+ polarCustomerId
450
+ });
451
+ }
452
+ /**
453
+ * List all customers.
454
+ */
455
+ async findAll() {
456
+ return this.customerModel.find();
457
+ }
458
+ /**
459
+ * Link a Polar customer to a Magnet user.
460
+ */
461
+ async linkToUser(polarCustomerId, userId) {
462
+ return this.customerModel.update({
463
+ polarCustomerId
464
+ }, {
465
+ userId
466
+ });
467
+ }
468
+ };
469
+ PolarCustomerService = _ts_decorate5([
470
+ Injectable(),
471
+ _ts_param2(0, InjectModel(PolarCustomer)),
472
+ _ts_metadata5("design:type", Function),
473
+ _ts_metadata5("design:paramtypes", [
474
+ typeof Model === "undefined" ? Object : Model
475
+ ])
476
+ ], PolarCustomerService);
477
+ }
478
+ });
479
+ function _ts_decorate6(decorators, target, key, desc) {
480
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
481
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
482
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
483
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
484
+ }
485
+ function _ts_metadata6(k, v) {
486
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
487
+ }
488
+ var PolarSubscription;
489
+ var init_subscription_schema = __esm({
490
+ "src/schemas/subscription.schema.ts"() {
491
+ __name(_ts_decorate6, "_ts_decorate");
492
+ __name(_ts_metadata6, "_ts_metadata");
493
+ PolarSubscription = class {
494
+ static {
495
+ __name(this, "PolarSubscription");
496
+ }
497
+ /** Polar Subscription ID */
498
+ polarSubscriptionId;
499
+ /** Reference to PolarCustomer.polarCustomerId */
500
+ customerId;
501
+ /** Reference to PolarProduct.polarProductId */
502
+ productId;
503
+ /** Subscription status from Polar */
504
+ status;
505
+ /** Subscription amount in smallest currency unit (cents) */
506
+ amount;
507
+ /** Three-letter ISO currency code */
508
+ currency;
509
+ /** Recurring interval (month, year, week, day) */
510
+ recurringInterval;
511
+ /** Start of the current billing period */
512
+ currentPeriodStart;
513
+ /** End of the current billing period */
514
+ currentPeriodEnd;
515
+ /** Whether the subscription will be canceled at the end of the period */
516
+ cancelAtPeriodEnd = false;
517
+ /** When the subscription started */
518
+ startedAt;
519
+ /** When the subscription ended (null if still active) */
520
+ endedAt;
521
+ /** When the subscription was last synced */
522
+ updatedAt;
523
+ };
524
+ _ts_decorate6([
525
+ Field.Text({
526
+ required: true,
527
+ unique: true
528
+ }),
529
+ _ts_metadata6("design:type", String)
530
+ ], PolarSubscription.prototype, "polarSubscriptionId", void 0);
531
+ _ts_decorate6([
532
+ Field.Text({
533
+ required: true
534
+ }),
535
+ _ts_metadata6("design:type", String)
536
+ ], PolarSubscription.prototype, "customerId", void 0);
537
+ _ts_decorate6([
538
+ Field.Text({
539
+ required: true
540
+ }),
541
+ _ts_metadata6("design:type", String)
542
+ ], PolarSubscription.prototype, "productId", void 0);
543
+ _ts_decorate6([
544
+ Field.Select({
545
+ required: true,
546
+ options: [
547
+ {
548
+ label: "Active",
549
+ value: "active"
550
+ },
551
+ {
552
+ label: "Canceled",
553
+ value: "canceled"
554
+ },
555
+ {
556
+ label: "Past Due",
557
+ value: "past_due"
558
+ },
559
+ {
560
+ label: "Trialing",
561
+ value: "trialing"
562
+ },
563
+ {
564
+ label: "Incomplete",
565
+ value: "incomplete"
566
+ },
567
+ {
568
+ label: "Unpaid",
569
+ value: "unpaid"
570
+ },
571
+ {
572
+ label: "Revoked",
573
+ value: "revoked"
574
+ }
575
+ ]
576
+ }),
577
+ _ts_metadata6("design:type", String)
578
+ ], PolarSubscription.prototype, "status", void 0);
579
+ _ts_decorate6([
580
+ Field.Number(),
581
+ _ts_metadata6("design:type", Number)
582
+ ], PolarSubscription.prototype, "amount", void 0);
583
+ _ts_decorate6([
584
+ Field.Text(),
585
+ _ts_metadata6("design:type", String)
586
+ ], PolarSubscription.prototype, "currency", void 0);
587
+ _ts_decorate6([
588
+ Field.Text(),
589
+ _ts_metadata6("design:type", String)
590
+ ], PolarSubscription.prototype, "recurringInterval", void 0);
591
+ _ts_decorate6([
592
+ Field.Date({
593
+ required: true
594
+ }),
595
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
596
+ ], PolarSubscription.prototype, "currentPeriodStart", void 0);
597
+ _ts_decorate6([
598
+ Field.Date({
599
+ required: true
600
+ }),
601
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
602
+ ], PolarSubscription.prototype, "currentPeriodEnd", void 0);
603
+ _ts_decorate6([
604
+ Field.Boolean({
605
+ default: false
606
+ })
607
+ ], PolarSubscription.prototype, "cancelAtPeriodEnd", void 0);
608
+ _ts_decorate6([
609
+ Field.Date(),
610
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
611
+ ], PolarSubscription.prototype, "startedAt", void 0);
612
+ _ts_decorate6([
613
+ Field.Date(),
614
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
615
+ ], PolarSubscription.prototype, "endedAt", void 0);
616
+ _ts_decorate6([
617
+ Field.Date({
618
+ required: true,
619
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
620
+ }),
621
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
622
+ ], PolarSubscription.prototype, "updatedAt", void 0);
623
+ PolarSubscription = _ts_decorate6([
624
+ Schema({
625
+ versioning: false,
626
+ i18n: false,
627
+ visible: false
628
+ })
629
+ ], PolarSubscription);
630
+ }
631
+ });
632
+ function _ts_decorate7(decorators, target, key, desc) {
633
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
634
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
635
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
636
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
637
+ }
638
+ function _ts_metadata7(k, v) {
639
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
640
+ }
641
+ function _ts_param3(paramIndex, decorator) {
642
+ return function(target, key) {
643
+ decorator(target, key, paramIndex);
644
+ };
645
+ }
646
+ var PolarSubscriptionService;
647
+ var init_subscription_service = __esm({
648
+ "src/services/subscription.service.ts"() {
649
+ init_polar_service();
650
+ init_subscription_schema();
651
+ __name(_ts_decorate7, "_ts_decorate");
652
+ __name(_ts_metadata7, "_ts_metadata");
653
+ __name(_ts_param3, "_ts_param");
654
+ PolarSubscriptionService = class {
655
+ static {
656
+ __name(this, "PolarSubscriptionService");
657
+ }
658
+ subscriptionModel;
659
+ polarService;
660
+ constructor(subscriptionModel, polarService) {
661
+ this.subscriptionModel = subscriptionModel;
662
+ this.polarService = polarService;
663
+ }
664
+ /**
665
+ * Upsert a subscription from a webhook subscription payload.
666
+ */
667
+ async syncSubscription(data) {
668
+ const subData = {
669
+ polarSubscriptionId: data.id,
670
+ customerId: data.customerId,
671
+ productId: data.productId,
672
+ status: data.status,
673
+ amount: data.amount,
674
+ currency: data.currency,
675
+ recurringInterval: data.recurringInterval,
676
+ currentPeriodStart: data.currentPeriodStart,
677
+ currentPeriodEnd: data.currentPeriodEnd,
678
+ cancelAtPeriodEnd: data.cancelAtPeriodEnd,
679
+ startedAt: data.startedAt ?? void 0,
680
+ endedAt: data.endedAt ?? void 0,
681
+ updatedAt: /* @__PURE__ */ new Date()
682
+ };
683
+ const existing = await this.subscriptionModel.findOne({
684
+ polarSubscriptionId: data.id
685
+ });
686
+ if (existing) {
687
+ return this.subscriptionModel.update({
688
+ polarSubscriptionId: data.id
689
+ }, subData);
690
+ }
691
+ return this.subscriptionModel.create(subData);
692
+ }
693
+ /**
694
+ * Delete a subscription record by Polar Subscription ID.
695
+ */
696
+ async deleteByPolarId(polarSubscriptionId) {
697
+ await this.subscriptionModel.delete({
698
+ polarSubscriptionId
699
+ });
700
+ }
701
+ /**
702
+ * Find active subscription for a customer.
703
+ */
704
+ async findActiveByCustomerId(customerId) {
705
+ return this.subscriptionModel.findOne({
706
+ customerId,
707
+ status: "active"
708
+ });
709
+ }
710
+ /**
711
+ * List all subscriptions.
712
+ */
713
+ async findAll() {
714
+ return this.subscriptionModel.find();
715
+ }
716
+ /**
717
+ * Revoke (cancel immediately) a subscription via Polar SDK.
718
+ */
719
+ async revoke(polarSubscriptionId) {
720
+ await this.polarService.client.subscriptions.revoke({
721
+ id: polarSubscriptionId
722
+ });
723
+ }
724
+ };
725
+ PolarSubscriptionService = _ts_decorate7([
726
+ Injectable(),
727
+ _ts_param3(0, InjectModel(PolarSubscription)),
728
+ _ts_metadata7("design:type", Function),
729
+ _ts_metadata7("design:paramtypes", [
730
+ typeof Model === "undefined" ? Object : Model,
731
+ typeof PolarService === "undefined" ? Object : PolarService
732
+ ])
733
+ ], PolarSubscriptionService);
734
+ }
735
+ });
736
+ function _ts_decorate8(decorators, target, key, desc) {
737
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
738
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
739
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
740
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
741
+ }
742
+ function _ts_metadata8(k, v) {
743
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
744
+ }
745
+ function _ts_param4(paramIndex, decorator) {
746
+ return function(target, key) {
747
+ decorator(target, key, paramIndex);
748
+ };
749
+ }
750
+ var PolarAccessService;
751
+ var init_access_service = __esm({
752
+ "src/services/access.service.ts"() {
753
+ init_polar_service();
754
+ init_product_schema();
755
+ init_customer_service();
756
+ init_subscription_service();
757
+ __name(_ts_decorate8, "_ts_decorate");
758
+ __name(_ts_metadata8, "_ts_metadata");
759
+ __name(_ts_param4, "_ts_param");
760
+ PolarAccessService = class {
761
+ static {
762
+ __name(this, "PolarAccessService");
763
+ }
764
+ polarService;
765
+ customerService;
766
+ subscriptionService;
767
+ productModel;
768
+ constructor(polarService, customerService, subscriptionService, productModel) {
769
+ this.polarService = polarService;
770
+ this.customerService = customerService;
771
+ this.subscriptionService = subscriptionService;
772
+ this.productModel = productModel;
773
+ }
774
+ /**
775
+ * Get subscription access info for a user.
776
+ * Returns subscription status, plan name, and feature flags.
777
+ */
778
+ async getAccess(userId) {
779
+ const noAccess = {
780
+ hasActiveSubscription: false,
781
+ plan: null,
782
+ expiresAt: null,
783
+ features: []
784
+ };
785
+ const customer = await this.customerService.findByUserId(userId);
786
+ if (!customer) {
787
+ return noAccess;
788
+ }
789
+ const subscription = await this.subscriptionService.findActiveByCustomerId(customer.polarCustomerId);
790
+ if (!subscription) {
791
+ return noAccess;
792
+ }
793
+ let planName = null;
794
+ const product = await this.productModel.findOne({
795
+ polarProductId: subscription.productId
796
+ });
797
+ planName = product?.name ?? null;
798
+ const features = this.resolveFeaturesForPlan(planName);
799
+ return {
800
+ hasActiveSubscription: true,
801
+ plan: planName,
802
+ expiresAt: subscription.currentPeriodEnd,
803
+ features
804
+ };
805
+ }
806
+ /**
807
+ * Resolve feature flags for a plan name from plugin config.
808
+ */
809
+ resolveFeaturesForPlan(planName) {
810
+ if (!planName) return [];
811
+ const featuresConfig = this.polarService.pluginConfig.features;
812
+ if (!featuresConfig) return [];
813
+ const normalizedPlan = planName.toLowerCase();
814
+ for (const [key, features] of Object.entries(featuresConfig)) {
815
+ if (key.toLowerCase() === normalizedPlan) {
816
+ return features;
817
+ }
818
+ }
819
+ return [];
820
+ }
821
+ };
822
+ PolarAccessService = _ts_decorate8([
823
+ Injectable(),
824
+ _ts_param4(3, InjectModel(PolarProduct)),
825
+ _ts_metadata8("design:type", Function),
826
+ _ts_metadata8("design:paramtypes", [
827
+ typeof PolarService === "undefined" ? Object : PolarService,
828
+ typeof PolarCustomerService === "undefined" ? Object : PolarCustomerService,
829
+ typeof PolarSubscriptionService === "undefined" ? Object : PolarSubscriptionService,
830
+ typeof Model === "undefined" ? Object : Model
831
+ ])
832
+ ], PolarAccessService);
833
+ }
834
+ });
835
+ function _ts_decorate9(decorators, target, key, desc) {
836
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
837
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
838
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
839
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
840
+ }
841
+ function _ts_metadata9(k, v) {
842
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
843
+ }
844
+ var PolarBenefitGrant;
845
+ var init_benefit_grant_schema = __esm({
846
+ "src/schemas/benefit-grant.schema.ts"() {
847
+ __name(_ts_decorate9, "_ts_decorate");
848
+ __name(_ts_metadata9, "_ts_metadata");
849
+ PolarBenefitGrant = class {
850
+ static {
851
+ __name(this, "PolarBenefitGrant");
852
+ }
853
+ /** Polar Benefit Grant ID */
854
+ polarBenefitGrantId;
855
+ /** Reference to PolarBenefit.polarBenefitId */
856
+ benefitId;
857
+ /** Reference to PolarCustomer.polarCustomerId */
858
+ customerId;
859
+ /** Reference to PolarSubscription.polarSubscriptionId (optional) */
860
+ subscriptionId;
861
+ /** Whether the benefit is currently granted */
862
+ isGranted = true;
863
+ /** Whether the benefit has been revoked */
864
+ isRevoked = false;
865
+ /** When the benefit was granted */
866
+ grantedAt;
867
+ /** When the benefit was revoked (null if still active) */
868
+ revokedAt;
869
+ };
870
+ _ts_decorate9([
871
+ Field.Text({
872
+ required: true,
873
+ unique: true
874
+ }),
875
+ _ts_metadata9("design:type", String)
876
+ ], PolarBenefitGrant.prototype, "polarBenefitGrantId", void 0);
877
+ _ts_decorate9([
878
+ Field.Text({
879
+ required: true
880
+ }),
881
+ _ts_metadata9("design:type", String)
882
+ ], PolarBenefitGrant.prototype, "benefitId", void 0);
883
+ _ts_decorate9([
884
+ Field.Text({
885
+ required: true
886
+ }),
887
+ _ts_metadata9("design:type", String)
888
+ ], PolarBenefitGrant.prototype, "customerId", void 0);
889
+ _ts_decorate9([
890
+ Field.Text(),
891
+ _ts_metadata9("design:type", String)
892
+ ], PolarBenefitGrant.prototype, "subscriptionId", void 0);
893
+ _ts_decorate9([
894
+ Field.Boolean({
895
+ default: true
896
+ })
897
+ ], PolarBenefitGrant.prototype, "isGranted", void 0);
898
+ _ts_decorate9([
899
+ Field.Boolean({
900
+ default: false
901
+ })
902
+ ], PolarBenefitGrant.prototype, "isRevoked", void 0);
903
+ _ts_decorate9([
904
+ Field.Date(),
905
+ _ts_metadata9("design:type", typeof Date === "undefined" ? Object : Date)
906
+ ], PolarBenefitGrant.prototype, "grantedAt", void 0);
907
+ _ts_decorate9([
908
+ Field.Date(),
909
+ _ts_metadata9("design:type", typeof Date === "undefined" ? Object : Date)
910
+ ], PolarBenefitGrant.prototype, "revokedAt", void 0);
911
+ PolarBenefitGrant = _ts_decorate9([
912
+ Schema({
913
+ versioning: false,
914
+ i18n: false,
915
+ visible: false
916
+ })
917
+ ], PolarBenefitGrant);
918
+ }
919
+ });
920
+ function _ts_decorate10(decorators, target, key, desc) {
921
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
922
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
923
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
924
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
925
+ }
926
+ function _ts_metadata10(k, v) {
927
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
928
+ }
929
+ var PolarBenefit;
930
+ var init_benefit_schema = __esm({
931
+ "src/schemas/benefit.schema.ts"() {
932
+ __name(_ts_decorate10, "_ts_decorate");
933
+ __name(_ts_metadata10, "_ts_metadata");
934
+ PolarBenefit = class {
935
+ static {
936
+ __name(this, "PolarBenefit");
937
+ }
938
+ /** Polar Benefit ID */
939
+ polarBenefitId;
940
+ /** Benefit type (license_keys, downloadables, discord, custom, github_repository, meter_credit, etc.) */
941
+ type;
942
+ /** Benefit description */
943
+ description;
944
+ /** Polar Organization ID */
945
+ organizationId;
946
+ /** Whether the benefit is selectable by the customer */
947
+ selectable = false;
948
+ /** Whether the benefit can be deleted */
949
+ deletable = true;
950
+ /** When the benefit was created */
951
+ createdAt;
952
+ };
953
+ _ts_decorate10([
954
+ Field.Text({
955
+ required: true,
956
+ unique: true
957
+ }),
958
+ _ts_metadata10("design:type", String)
959
+ ], PolarBenefit.prototype, "polarBenefitId", void 0);
960
+ _ts_decorate10([
961
+ Field.Text({
962
+ required: true
963
+ }),
964
+ _ts_metadata10("design:type", String)
965
+ ], PolarBenefit.prototype, "type", void 0);
966
+ _ts_decorate10([
967
+ Field.Text(),
968
+ _ts_metadata10("design:type", String)
969
+ ], PolarBenefit.prototype, "description", void 0);
970
+ _ts_decorate10([
971
+ Field.Text(),
972
+ _ts_metadata10("design:type", String)
973
+ ], PolarBenefit.prototype, "organizationId", void 0);
974
+ _ts_decorate10([
975
+ Field.Boolean({
976
+ default: false
977
+ })
978
+ ], PolarBenefit.prototype, "selectable", void 0);
979
+ _ts_decorate10([
980
+ Field.Boolean({
981
+ default: true
982
+ })
983
+ ], PolarBenefit.prototype, "deletable", void 0);
984
+ _ts_decorate10([
985
+ Field.Date({
986
+ required: true,
987
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
988
+ }),
989
+ _ts_metadata10("design:type", typeof Date === "undefined" ? Object : Date)
990
+ ], PolarBenefit.prototype, "createdAt", void 0);
991
+ PolarBenefit = _ts_decorate10([
992
+ Schema({
993
+ versioning: false,
994
+ i18n: false,
995
+ visible: false
996
+ })
997
+ ], PolarBenefit);
998
+ }
999
+ });
1000
+ function _ts_decorate11(decorators, target, key, desc) {
1001
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1002
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1003
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1004
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1005
+ }
1006
+ function _ts_metadata11(k, v) {
1007
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1008
+ }
1009
+ function _ts_param5(paramIndex, decorator) {
1010
+ return function(target, key) {
1011
+ decorator(target, key, paramIndex);
1012
+ };
1013
+ }
1014
+ var PolarBenefitService;
1015
+ var init_benefit_service = __esm({
1016
+ "src/services/benefit.service.ts"() {
1017
+ init_benefit_grant_schema();
1018
+ init_benefit_schema();
1019
+ __name(_ts_decorate11, "_ts_decorate");
1020
+ __name(_ts_metadata11, "_ts_metadata");
1021
+ __name(_ts_param5, "_ts_param");
1022
+ PolarBenefitService = class {
1023
+ static {
1024
+ __name(this, "PolarBenefitService");
1025
+ }
1026
+ benefitModel;
1027
+ benefitGrantModel;
1028
+ constructor(benefitModel, benefitGrantModel) {
1029
+ this.benefitModel = benefitModel;
1030
+ this.benefitGrantModel = benefitGrantModel;
1031
+ }
1032
+ /**
1033
+ * Upsert a benefit from a webhook benefit payload.
1034
+ */
1035
+ async syncBenefit(data) {
1036
+ const benefitData = {
1037
+ polarBenefitId: data.id,
1038
+ type: data.type,
1039
+ description: data.description,
1040
+ organizationId: data.organizationId,
1041
+ selectable: data.selectable,
1042
+ deletable: data.deletable
1043
+ };
1044
+ const existing = await this.benefitModel.findOne({
1045
+ polarBenefitId: data.id
1046
+ });
1047
+ if (existing) {
1048
+ return this.benefitModel.update({
1049
+ polarBenefitId: data.id
1050
+ }, benefitData);
1051
+ }
1052
+ return this.benefitModel.create(benefitData);
1053
+ }
1054
+ /**
1055
+ * Upsert a benefit grant from a webhook payload.
1056
+ * Handles created, updated, and revoked states.
1057
+ */
1058
+ async syncBenefitGrant(data) {
1059
+ const grantData = {
1060
+ polarBenefitGrantId: data.id,
1061
+ benefitId: data.benefitId,
1062
+ customerId: data.customerId,
1063
+ subscriptionId: data.subscriptionId,
1064
+ isGranted: data.isGranted,
1065
+ isRevoked: data.isRevoked,
1066
+ grantedAt: data.grantedAt,
1067
+ revokedAt: data.revokedAt
1068
+ };
1069
+ const existing = await this.benefitGrantModel.findOne({
1070
+ polarBenefitGrantId: data.id
1071
+ });
1072
+ if (existing) {
1073
+ return this.benefitGrantModel.update({
1074
+ polarBenefitGrantId: data.id
1075
+ }, grantData);
1076
+ }
1077
+ return this.benefitGrantModel.create(grantData);
1078
+ }
1079
+ /**
1080
+ * Find active benefit grants for a customer.
1081
+ */
1082
+ async findGrantsByCustomerId(customerId) {
1083
+ return this.benefitGrantModel.findMany({
1084
+ customerId,
1085
+ isGranted: true,
1086
+ isRevoked: false
1087
+ });
1088
+ }
1089
+ /**
1090
+ * List all benefits.
1091
+ */
1092
+ async findAll() {
1093
+ return this.benefitModel.find();
1094
+ }
1095
+ /**
1096
+ * List all benefit grants.
1097
+ */
1098
+ async findGrantsAll() {
1099
+ return this.benefitGrantModel.find();
1100
+ }
1101
+ };
1102
+ PolarBenefitService = _ts_decorate11([
1103
+ Injectable(),
1104
+ _ts_param5(0, InjectModel(PolarBenefit)),
1105
+ _ts_param5(1, InjectModel(PolarBenefitGrant)),
1106
+ _ts_metadata11("design:type", Function),
1107
+ _ts_metadata11("design:paramtypes", [
1108
+ typeof Model === "undefined" ? Object : Model,
1109
+ typeof Model === "undefined" ? Object : Model
1110
+ ])
1111
+ ], PolarBenefitService);
1112
+ }
1113
+ });
1114
+ function _ts_decorate12(decorators, target, key, desc) {
1115
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1116
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1117
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1118
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1119
+ }
1120
+ function _ts_metadata12(k, v) {
1121
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1122
+ }
1123
+ var PolarCheckoutService;
1124
+ var init_checkout_service = __esm({
1125
+ "src/services/checkout.service.ts"() {
1126
+ init_polar_service();
1127
+ __name(_ts_decorate12, "_ts_decorate");
1128
+ __name(_ts_metadata12, "_ts_metadata");
1129
+ PolarCheckoutService = class {
1130
+ static {
1131
+ __name(this, "PolarCheckoutService");
1132
+ }
1133
+ polarService;
1134
+ constructor(polarService) {
1135
+ this.polarService = polarService;
1136
+ }
1137
+ /**
1138
+ * Create a Polar Checkout session.
1139
+ */
1140
+ async createCheckoutSession(dto) {
1141
+ const checkout = await this.polarService.client.checkouts.create({
1142
+ products: dto.products,
1143
+ successUrl: dto.successUrl,
1144
+ returnUrl: dto.returnUrl,
1145
+ customerEmail: dto.customerEmail,
1146
+ externalCustomerId: dto.userId,
1147
+ metadata: dto.metadata
1148
+ });
1149
+ return {
1150
+ sessionId: checkout.id,
1151
+ url: checkout.url
1152
+ };
1153
+ }
1154
+ };
1155
+ PolarCheckoutService = _ts_decorate12([
1156
+ Injectable(),
1157
+ _ts_metadata12("design:type", Function),
1158
+ _ts_metadata12("design:paramtypes", [
1159
+ typeof PolarService === "undefined" ? Object : PolarService
1160
+ ])
1161
+ ], PolarCheckoutService);
1162
+ }
1163
+ });
1164
+ function _ts_decorate13(decorators, target, key, desc) {
1165
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1166
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1167
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1168
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1169
+ }
1170
+ function _ts_metadata13(k, v) {
1171
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1172
+ }
1173
+ function _ts_param6(paramIndex, decorator) {
1174
+ return function(target, key) {
1175
+ decorator(target, key, paramIndex);
1176
+ };
1177
+ }
1178
+ var PolarMetricsService;
1179
+ var init_metrics_service = __esm({
1180
+ "src/services/metrics.service.ts"() {
1181
+ init_polar_service();
1182
+ init_order_schema();
1183
+ init_subscription_schema();
1184
+ __name(_ts_decorate13, "_ts_decorate");
1185
+ __name(_ts_metadata13, "_ts_metadata");
1186
+ __name(_ts_param6, "_ts_param");
1187
+ PolarMetricsService = class _PolarMetricsService {
1188
+ static {
1189
+ __name(this, "PolarMetricsService");
1190
+ }
1191
+ orderModel;
1192
+ subscriptionModel;
1193
+ polarService;
1194
+ logger;
1195
+ constructor(orderModel, subscriptionModel, polarService) {
1196
+ this.orderModel = orderModel;
1197
+ this.subscriptionModel = subscriptionModel;
1198
+ this.polarService = polarService;
1199
+ this.logger = new Logger(_PolarMetricsService.name);
1200
+ }
1201
+ /**
1202
+ * Get dashboard metrics — hybrid of live Polar API and local DB data.
1203
+ */
1204
+ async getMetrics() {
1205
+ try {
1206
+ return await this.getMetricsFromApi();
1207
+ } catch (error) {
1208
+ this.logger.warn(`Failed to fetch metrics from Polar API, falling back to local DB: ${error instanceof Error ? error.message : String(error)}`);
1209
+ return this.getMetricsFromDb();
1210
+ }
1211
+ }
1212
+ /**
1213
+ * Fetch metrics from Polar's analytics API.
1214
+ */
1215
+ async getMetricsFromApi() {
1216
+ const now = /* @__PURE__ */ new Date();
1217
+ const startDate = new Date(now.getFullYear(), now.getMonth() - 11, 1);
1218
+ const response = await this.polarService.client.metrics.get({
1219
+ startDate: new RFCDate(startDate),
1220
+ endDate: new RFCDate(now),
1221
+ interval: "month"
1222
+ });
1223
+ const periods = response.periods;
1224
+ const latestPeriod = periods[periods.length - 1];
1225
+ const mrr = Number(latestPeriod?.monthlyRecurringRevenue ?? 0);
1226
+ const revenueThisMonth = Number(latestPeriod?.revenue ?? 0);
1227
+ const activeSubscriptions = Number(latestPeriod?.activeSubscriptions ?? 0);
1228
+ const churned = Number(latestPeriod?.churnedSubscriptions ?? 0);
1229
+ const churnRate = activeSubscriptions + churned > 0 ? Math.round(churned / (activeSubscriptions + churned) * 100) : 0;
1230
+ const revenueByMonth = periods.map((period) => {
1231
+ const d = period.timestamp;
1232
+ const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
1233
+ return {
1234
+ month: key,
1235
+ revenue: Number(period.revenue ?? 0)
1236
+ };
1237
+ });
1238
+ const recentOrders = await this.getRecentOrders();
1239
+ return {
1240
+ mrr,
1241
+ revenueThisMonth,
1242
+ activeSubscriptions,
1243
+ churnRate,
1244
+ revenueByMonth,
1245
+ recentOrders
1246
+ };
1247
+ }
1248
+ /**
1249
+ * Fall back to local DB computation if API call fails.
1250
+ */
1251
+ async getMetricsFromDb() {
1252
+ const [activeSubscriptions, revenueThisMonth, recentOrders] = await Promise.all([
1253
+ this.countActiveSubscriptions(),
1254
+ this.calculateRevenueThisMonth(),
1255
+ this.getRecentOrders()
1256
+ ]);
1257
+ const churnRate = await this.calculateChurnRate();
1258
+ const revenueByMonth = await this.getRevenueByMonth();
1259
+ return {
1260
+ mrr: 0,
1261
+ revenueThisMonth,
1262
+ activeSubscriptions,
1263
+ churnRate,
1264
+ revenueByMonth,
1265
+ recentOrders
1266
+ };
1267
+ }
1268
+ async countActiveSubscriptions() {
1269
+ const subs = await this.subscriptionModel.findMany({
1270
+ status: "active"
1271
+ });
1272
+ return subs.length;
1273
+ }
1274
+ async calculateRevenueThisMonth() {
1275
+ const orders = await this.orderModel.findMany({
1276
+ status: "paid"
1277
+ });
1278
+ const now = /* @__PURE__ */ new Date();
1279
+ const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
1280
+ return orders.filter((o) => new Date(o.createdAt) >= startOfMonth).reduce((sum, o) => sum + o.totalAmount, 0);
1281
+ }
1282
+ async calculateChurnRate() {
1283
+ const allSubs = await this.subscriptionModel.find();
1284
+ if (allSubs.length === 0) return 0;
1285
+ const canceled = allSubs.filter((s) => s.status === "canceled");
1286
+ return Math.round(canceled.length / allSubs.length * 100);
1287
+ }
1288
+ async getRevenueByMonth() {
1289
+ const orders = await this.orderModel.findMany({
1290
+ status: "paid"
1291
+ });
1292
+ const monthMap = /* @__PURE__ */ new Map();
1293
+ const now = /* @__PURE__ */ new Date();
1294
+ for (let i = 11; i >= 0; i--) {
1295
+ const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
1296
+ const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
1297
+ monthMap.set(key, 0);
1298
+ }
1299
+ for (const order of orders) {
1300
+ const d = new Date(order.createdAt);
1301
+ const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
1302
+ if (monthMap.has(key)) {
1303
+ monthMap.set(key, (monthMap.get(key) ?? 0) + order.totalAmount);
1304
+ }
1305
+ }
1306
+ return Array.from(monthMap.entries()).map(([month, revenue]) => ({
1307
+ month,
1308
+ revenue
1309
+ }));
1310
+ }
1311
+ async getRecentOrders() {
1312
+ const orders = await this.orderModel.find();
1313
+ return orders.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()).slice(0, 10).map((o) => ({
1314
+ id: o.id,
1315
+ totalAmount: o.totalAmount,
1316
+ currency: o.currency,
1317
+ status: o.status,
1318
+ customerEmail: o.customerId,
1319
+ createdAt: o.createdAt.toISOString()
1320
+ }));
1321
+ }
1322
+ };
1323
+ PolarMetricsService = _ts_decorate13([
1324
+ Injectable(),
1325
+ _ts_param6(0, InjectModel(PolarOrder)),
1326
+ _ts_param6(1, InjectModel(PolarSubscription)),
1327
+ _ts_metadata13("design:type", Function),
1328
+ _ts_metadata13("design:paramtypes", [
1329
+ typeof Model === "undefined" ? Object : Model,
1330
+ typeof Model === "undefined" ? Object : Model,
1331
+ typeof PolarService === "undefined" ? Object : PolarService
1332
+ ])
1333
+ ], PolarMetricsService);
1334
+ }
1335
+ });
1336
+ function _ts_decorate14(decorators, target, key, desc) {
1337
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1338
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1339
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1340
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1341
+ }
1342
+ function _ts_metadata14(k, v) {
1343
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1344
+ }
1345
+ var PolarPortalService;
1346
+ var init_portal_service = __esm({
1347
+ "src/services/portal.service.ts"() {
1348
+ init_polar_service();
1349
+ init_customer_service();
1350
+ __name(_ts_decorate14, "_ts_decorate");
1351
+ __name(_ts_metadata14, "_ts_metadata");
1352
+ PolarPortalService = class {
1353
+ static {
1354
+ __name(this, "PolarPortalService");
1355
+ }
1356
+ polarService;
1357
+ customerService;
1358
+ constructor(polarService, customerService) {
1359
+ this.polarService = polarService;
1360
+ this.customerService = customerService;
1361
+ }
1362
+ /**
1363
+ * Create a Polar Customer Portal session.
1364
+ */
1365
+ async createPortalSession(dto) {
1366
+ let customerId = dto.customerId;
1367
+ if (!customerId && dto.userId) {
1368
+ const customer = await this.customerService.findByUserId(dto.userId);
1369
+ if (!customer) {
1370
+ throw new HttpException("No Polar customer found for this user", HttpStatus.NOT_FOUND);
1371
+ }
1372
+ customerId = customer.polarCustomerId;
1373
+ }
1374
+ if (!customerId) {
1375
+ throw new HttpException("Either customerId or userId must be provided", HttpStatus.BAD_REQUEST);
1376
+ }
1377
+ const session = await this.polarService.client.customerSessions.create({
1378
+ customerId,
1379
+ returnUrl: dto.returnUrl
1380
+ });
1381
+ return {
1382
+ sessionId: session.id,
1383
+ url: session.customerPortalUrl
1384
+ };
1385
+ }
1386
+ };
1387
+ PolarPortalService = _ts_decorate14([
1388
+ Injectable(),
1389
+ _ts_metadata14("design:type", Function),
1390
+ _ts_metadata14("design:paramtypes", [
1391
+ typeof PolarService === "undefined" ? Object : PolarService,
1392
+ typeof PolarCustomerService === "undefined" ? Object : PolarCustomerService
1393
+ ])
1394
+ ], PolarPortalService);
1395
+ }
1396
+ });
1397
+ function _ts_decorate15(decorators, target, key, desc) {
1398
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1399
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1400
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1401
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1402
+ }
1403
+ function _ts_metadata15(k, v) {
1404
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1405
+ }
1406
+ function _ts_param7(paramIndex, decorator) {
1407
+ return function(target, key) {
1408
+ decorator(target, key, paramIndex);
1409
+ };
1410
+ }
1411
+ var PolarProductService;
1412
+ var init_product_service = __esm({
1413
+ "src/services/product.service.ts"() {
1414
+ init_product_schema();
1415
+ __name(_ts_decorate15, "_ts_decorate");
1416
+ __name(_ts_metadata15, "_ts_metadata");
1417
+ __name(_ts_param7, "_ts_param");
1418
+ PolarProductService = class {
1419
+ static {
1420
+ __name(this, "PolarProductService");
1421
+ }
1422
+ productModel;
1423
+ constructor(productModel) {
1424
+ this.productModel = productModel;
1425
+ }
1426
+ /**
1427
+ * Upsert a product from a webhook product payload.
1428
+ */
1429
+ async syncProduct(data) {
1430
+ const productData = {
1431
+ polarProductId: data.id,
1432
+ name: data.name,
1433
+ description: data.description ?? void 0,
1434
+ isRecurring: data.isRecurring,
1435
+ isArchived: data.isArchived,
1436
+ organizationId: data.organizationId,
1437
+ metadata: data.metadata,
1438
+ updatedAt: /* @__PURE__ */ new Date()
1439
+ };
1440
+ const existing = await this.productModel.findOne({
1441
+ polarProductId: data.id
1442
+ });
1443
+ if (existing) {
1444
+ return this.productModel.update({
1445
+ polarProductId: data.id
1446
+ }, productData);
1447
+ }
1448
+ return this.productModel.create(productData);
1449
+ }
1450
+ /**
1451
+ * Delete a product by Polar Product ID.
1452
+ */
1453
+ async deleteProduct(polarProductId) {
1454
+ await this.productModel.delete({
1455
+ polarProductId
1456
+ });
1457
+ }
1458
+ /**
1459
+ * List all non-archived products.
1460
+ */
1461
+ async findActiveProducts() {
1462
+ return this.productModel.findMany({
1463
+ isArchived: false
1464
+ });
1465
+ }
1466
+ /**
1467
+ * List all products.
1468
+ */
1469
+ async findAllProducts() {
1470
+ return this.productModel.find();
1471
+ }
1472
+ };
1473
+ PolarProductService = _ts_decorate15([
1474
+ Injectable(),
1475
+ _ts_param7(0, InjectModel(PolarProduct)),
1476
+ _ts_metadata15("design:type", Function),
1477
+ _ts_metadata15("design:paramtypes", [
1478
+ typeof Model === "undefined" ? Object : Model
1479
+ ])
1480
+ ], PolarProductService);
1481
+ }
1482
+ });
1483
+ function _ts_decorate16(decorators, target, key, desc) {
1484
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1485
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1486
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1487
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1488
+ }
1489
+ function _ts_metadata16(k, v) {
1490
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1491
+ }
1492
+ var PolarProcessedEvent;
1493
+ var init_processed_event_schema = __esm({
1494
+ "src/schemas/processed-event.schema.ts"() {
1495
+ __name(_ts_decorate16, "_ts_decorate");
1496
+ __name(_ts_metadata16, "_ts_metadata");
1497
+ PolarProcessedEvent = class {
1498
+ static {
1499
+ __name(this, "PolarProcessedEvent");
1500
+ }
1501
+ /** Polar Event ID — unique to prevent reprocessing */
1502
+ polarEventId;
1503
+ /** Event type (e.g., 'order.paid', 'subscription.updated') */
1504
+ eventType;
1505
+ /** When this event was processed */
1506
+ processedAt;
1507
+ };
1508
+ _ts_decorate16([
1509
+ Field.Text({
1510
+ required: true,
1511
+ unique: true
1512
+ }),
1513
+ _ts_metadata16("design:type", String)
1514
+ ], PolarProcessedEvent.prototype, "polarEventId", void 0);
1515
+ _ts_decorate16([
1516
+ Field.Text({
1517
+ required: true
1518
+ }),
1519
+ _ts_metadata16("design:type", String)
1520
+ ], PolarProcessedEvent.prototype, "eventType", void 0);
1521
+ _ts_decorate16([
1522
+ Field.Date({
1523
+ required: true,
1524
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
1525
+ }),
1526
+ _ts_metadata16("design:type", typeof Date === "undefined" ? Object : Date)
1527
+ ], PolarProcessedEvent.prototype, "processedAt", void 0);
1528
+ PolarProcessedEvent = _ts_decorate16([
1529
+ Schema({
1530
+ versioning: false,
1531
+ i18n: false,
1532
+ visible: false
1533
+ })
1534
+ ], PolarProcessedEvent);
1535
+ }
1536
+ });
1537
+ function _ts_decorate17(decorators, target, key, desc) {
1538
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1539
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1540
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1541
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1542
+ }
1543
+ function _ts_metadata17(k, v) {
1544
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1545
+ }
1546
+ function _ts_param8(paramIndex, decorator) {
1547
+ return function(target, key) {
1548
+ decorator(target, key, paramIndex);
1549
+ };
1550
+ }
1551
+ var PolarOrderService;
1552
+ var init_order_service = __esm({
1553
+ "src/services/order.service.ts"() {
1554
+ init_order_schema();
1555
+ __name(_ts_decorate17, "_ts_decorate");
1556
+ __name(_ts_metadata17, "_ts_metadata");
1557
+ __name(_ts_param8, "_ts_param");
1558
+ PolarOrderService = class {
1559
+ static {
1560
+ __name(this, "PolarOrderService");
1561
+ }
1562
+ orderModel;
1563
+ constructor(orderModel) {
1564
+ this.orderModel = orderModel;
1565
+ }
1566
+ /**
1567
+ * Upsert an order from a webhook order payload.
1568
+ */
1569
+ async syncOrder(data) {
1570
+ const orderData = {
1571
+ polarOrderId: data.id,
1572
+ customerId: data.customerId,
1573
+ productId: data.productId,
1574
+ subscriptionId: data.subscriptionId ?? void 0,
1575
+ status: data.status === "paid" ? "paid" : data.status === "refunded" ? "refunded" : "pending",
1576
+ totalAmount: data.totalAmount,
1577
+ currency: data.currency,
1578
+ billingReason: data.billingReason,
1579
+ createdAt: data.createdAt ?? /* @__PURE__ */ new Date()
1580
+ };
1581
+ const existing = await this.orderModel.findOne({
1582
+ polarOrderId: data.id
1583
+ });
1584
+ if (existing) {
1585
+ return this.orderModel.update({
1586
+ polarOrderId: data.id
1587
+ }, orderData);
1588
+ }
1589
+ return this.orderModel.create(orderData);
1590
+ }
1591
+ /**
1592
+ * List all orders.
1593
+ */
1594
+ async findAll() {
1595
+ return this.orderModel.find();
1596
+ }
1597
+ /**
1598
+ * Find orders for a customer.
1599
+ */
1600
+ async findByCustomerId(customerId) {
1601
+ return this.orderModel.findMany({
1602
+ customerId
1603
+ });
1604
+ }
1605
+ };
1606
+ PolarOrderService = _ts_decorate17([
1607
+ Injectable(),
1608
+ _ts_param8(0, InjectModel(PolarOrder)),
1609
+ _ts_metadata17("design:type", Function),
1610
+ _ts_metadata17("design:paramtypes", [
1611
+ typeof Model === "undefined" ? Object : Model
1612
+ ])
1613
+ ], PolarOrderService);
1614
+ }
1615
+ });
1616
+ function _ts_decorate18(decorators, target, key, desc) {
1617
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1618
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1619
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1620
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1621
+ }
1622
+ function _ts_metadata18(k, v) {
1623
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1624
+ }
1625
+ function _ts_param9(paramIndex, decorator) {
1626
+ return function(target, key) {
1627
+ decorator(target, key, paramIndex);
1628
+ };
1629
+ }
1630
+ var PolarApiController;
1631
+ var init_polar_api_controller = __esm({
1632
+ "src/polar-api.controller.ts"() {
1633
+ init_polar_service();
1634
+ init_order_schema();
1635
+ init_access_service();
1636
+ init_benefit_service();
1637
+ init_checkout_service();
1638
+ init_customer_service();
1639
+ init_metrics_service();
1640
+ init_portal_service();
1641
+ init_product_service();
1642
+ init_subscription_service();
1643
+ __name(_ts_decorate18, "_ts_decorate");
1644
+ __name(_ts_metadata18, "_ts_metadata");
1645
+ __name(_ts_param9, "_ts_param");
1646
+ PolarApiController = class {
1647
+ static {
1648
+ __name(this, "PolarApiController");
1649
+ }
1650
+ accessService;
1651
+ benefitService;
1652
+ checkoutService;
1653
+ customerService;
1654
+ metricsService;
1655
+ orderModel;
1656
+ portalService;
1657
+ productService;
1658
+ polarService;
1659
+ subscriptionService;
1660
+ constructor(accessService, benefitService, checkoutService, customerService, metricsService, orderModel, portalService, productService, polarService, subscriptionService) {
1661
+ this.accessService = accessService;
1662
+ this.benefitService = benefitService;
1663
+ this.checkoutService = checkoutService;
1664
+ this.customerService = customerService;
1665
+ this.metricsService = metricsService;
1666
+ this.orderModel = orderModel;
1667
+ this.portalService = portalService;
1668
+ this.productService = productService;
1669
+ this.polarService = polarService;
1670
+ this.subscriptionService = subscriptionService;
1671
+ }
1672
+ // =========================================================================
1673
+ // Public Endpoints
1674
+ // =========================================================================
1675
+ /**
1676
+ * Create a Polar Checkout session.
1677
+ * POST /polar/checkout
1678
+ */
1679
+ async createCheckout(dto) {
1680
+ try {
1681
+ return await this.checkoutService.createCheckoutSession(dto);
1682
+ } catch (error) {
1683
+ if (error instanceof HttpException) throw error;
1684
+ throw new HttpException(error instanceof Error ? error.message : "Failed to create checkout session", HttpStatus.INTERNAL_SERVER_ERROR);
1685
+ }
1686
+ }
1687
+ /**
1688
+ * Create a Polar Customer Portal session.
1689
+ * POST /polar/portal
1690
+ */
1691
+ async createPortal(dto) {
1692
+ try {
1693
+ return await this.portalService.createPortalSession(dto);
1694
+ } catch (error) {
1695
+ if (error instanceof HttpException) throw error;
1696
+ throw new HttpException(error instanceof Error ? error.message : "Failed to create portal session", HttpStatus.INTERNAL_SERVER_ERROR);
1697
+ }
1698
+ }
1699
+ /**
1700
+ * List active products.
1701
+ * GET /polar/products
1702
+ */
1703
+ async listProducts() {
1704
+ return this.productService.findActiveProducts();
1705
+ }
1706
+ /**
1707
+ * Get a user's active subscription.
1708
+ * GET /polar/subscription/:userId
1709
+ */
1710
+ async getUserSubscription(userId) {
1711
+ const customer = await this.customerService.findByUserId(userId);
1712
+ if (!customer) {
1713
+ return {
1714
+ subscription: null
1715
+ };
1716
+ }
1717
+ const subscription = await this.subscriptionService.findActiveByCustomerId(customer.polarCustomerId);
1718
+ return {
1719
+ subscription
1720
+ };
1721
+ }
1722
+ /**
1723
+ * Get subscription access info and feature flags for a user.
1724
+ * GET /polar/access/:userId
1725
+ */
1726
+ async getAccess(userId) {
1727
+ return this.accessService.getAccess(userId);
1728
+ }
1729
+ // =========================================================================
1730
+ // Admin Endpoints
1731
+ // =========================================================================
1732
+ /**
1733
+ * Get dashboard metrics.
1734
+ * GET /polar/admin/metrics
1735
+ */
1736
+ async getMetrics() {
1737
+ return this.metricsService.getMetrics();
1738
+ }
1739
+ /**
1740
+ * List all customers (admin).
1741
+ * GET /polar/admin/customers
1742
+ */
1743
+ async listCustomers() {
1744
+ return this.customerService.findAll();
1745
+ }
1746
+ /**
1747
+ * List all subscriptions (admin).
1748
+ * GET /polar/admin/subscriptions
1749
+ */
1750
+ async listSubscriptions() {
1751
+ return this.subscriptionService.findAll();
1752
+ }
1753
+ /**
1754
+ * Cancel (revoke) a subscription (admin).
1755
+ * POST /polar/admin/subscriptions/:id/cancel
1756
+ */
1757
+ async cancelSubscription(polarSubscriptionId) {
1758
+ await this.subscriptionService.revoke(polarSubscriptionId);
1759
+ return {
1760
+ canceled: true
1761
+ };
1762
+ }
1763
+ /**
1764
+ * List all products (admin).
1765
+ * GET /polar/admin/products
1766
+ */
1767
+ async listAllProducts() {
1768
+ return this.productService.findAllProducts();
1769
+ }
1770
+ /**
1771
+ * Sync products from Polar API (admin).
1772
+ * POST /polar/admin/sync-products
1773
+ */
1774
+ async syncProducts() {
1775
+ let productCount = 0;
1776
+ for await (const page of await this.polarService.client.products.list({})) {
1777
+ for (const product of page.result.items) {
1778
+ await this.productService.syncProduct({
1779
+ id: product.id,
1780
+ name: product.name,
1781
+ description: product.description ?? void 0,
1782
+ isRecurring: product.isRecurring,
1783
+ isArchived: product.isArchived,
1784
+ organizationId: product.organizationId,
1785
+ metadata: product.metadata
1786
+ });
1787
+ productCount++;
1788
+ }
1789
+ }
1790
+ return {
1791
+ synced: true,
1792
+ products: productCount
1793
+ };
1794
+ }
1795
+ /**
1796
+ * List all orders (admin).
1797
+ * GET /polar/admin/orders
1798
+ */
1799
+ async listOrders() {
1800
+ return this.orderModel.find();
1801
+ }
1802
+ /**
1803
+ * List all benefits (admin).
1804
+ * GET /polar/admin/benefits
1805
+ */
1806
+ async listBenefits() {
1807
+ return this.benefitService.findAll();
1808
+ }
1809
+ /**
1810
+ * List all benefit grants (admin).
1811
+ * GET /polar/admin/benefit-grants
1812
+ */
1813
+ async listBenefitGrants() {
1814
+ return this.benefitService.findGrantsAll();
1815
+ }
1816
+ };
1817
+ _ts_decorate18([
1818
+ Post("checkout"),
1819
+ _ts_param9(0, Body()),
1820
+ _ts_metadata18("design:type", Function),
1821
+ _ts_metadata18("design:paramtypes", [
1822
+ typeof CreateCheckoutDto === "undefined" ? Object : CreateCheckoutDto
1823
+ ]),
1824
+ _ts_metadata18("design:returntype", Promise)
1825
+ ], PolarApiController.prototype, "createCheckout", null);
1826
+ _ts_decorate18([
1827
+ Post("portal"),
1828
+ _ts_param9(0, Body()),
1829
+ _ts_metadata18("design:type", Function),
1830
+ _ts_metadata18("design:paramtypes", [
1831
+ typeof CreatePortalDto === "undefined" ? Object : CreatePortalDto
1832
+ ]),
1833
+ _ts_metadata18("design:returntype", Promise)
1834
+ ], PolarApiController.prototype, "createPortal", null);
1835
+ _ts_decorate18([
1836
+ Get("products"),
1837
+ _ts_metadata18("design:type", Function),
1838
+ _ts_metadata18("design:paramtypes", []),
1839
+ _ts_metadata18("design:returntype", Promise)
1840
+ ], PolarApiController.prototype, "listProducts", null);
1841
+ _ts_decorate18([
1842
+ Get("subscription/:userId"),
1843
+ _ts_param9(0, Param("userId")),
1844
+ _ts_metadata18("design:type", Function),
1845
+ _ts_metadata18("design:paramtypes", [
1846
+ String
1847
+ ]),
1848
+ _ts_metadata18("design:returntype", Promise)
1849
+ ], PolarApiController.prototype, "getUserSubscription", null);
1850
+ _ts_decorate18([
1851
+ Get("access/:userId"),
1852
+ RestrictedRoute(),
1853
+ _ts_param9(0, Param("userId")),
1854
+ _ts_metadata18("design:type", Function),
1855
+ _ts_metadata18("design:paramtypes", [
1856
+ String
1857
+ ]),
1858
+ _ts_metadata18("design:returntype", Promise)
1859
+ ], PolarApiController.prototype, "getAccess", null);
1860
+ _ts_decorate18([
1861
+ Get("admin/metrics"),
1862
+ RestrictedRoute(),
1863
+ _ts_metadata18("design:type", Function),
1864
+ _ts_metadata18("design:paramtypes", []),
1865
+ _ts_metadata18("design:returntype", Promise)
1866
+ ], PolarApiController.prototype, "getMetrics", null);
1867
+ _ts_decorate18([
1868
+ Get("admin/customers"),
1869
+ RestrictedRoute(),
1870
+ _ts_metadata18("design:type", Function),
1871
+ _ts_metadata18("design:paramtypes", []),
1872
+ _ts_metadata18("design:returntype", Promise)
1873
+ ], PolarApiController.prototype, "listCustomers", null);
1874
+ _ts_decorate18([
1875
+ Get("admin/subscriptions"),
1876
+ RestrictedRoute(),
1877
+ _ts_metadata18("design:type", Function),
1878
+ _ts_metadata18("design:paramtypes", []),
1879
+ _ts_metadata18("design:returntype", Promise)
1880
+ ], PolarApiController.prototype, "listSubscriptions", null);
1881
+ _ts_decorate18([
1882
+ Post("admin/subscriptions/:id/cancel"),
1883
+ RestrictedRoute(),
1884
+ _ts_param9(0, Param("id")),
1885
+ _ts_metadata18("design:type", Function),
1886
+ _ts_metadata18("design:paramtypes", [
1887
+ String
1888
+ ]),
1889
+ _ts_metadata18("design:returntype", Promise)
1890
+ ], PolarApiController.prototype, "cancelSubscription", null);
1891
+ _ts_decorate18([
1892
+ Get("admin/products"),
1893
+ RestrictedRoute(),
1894
+ _ts_metadata18("design:type", Function),
1895
+ _ts_metadata18("design:paramtypes", []),
1896
+ _ts_metadata18("design:returntype", Promise)
1897
+ ], PolarApiController.prototype, "listAllProducts", null);
1898
+ _ts_decorate18([
1899
+ Post("admin/sync-products"),
1900
+ RestrictedRoute(),
1901
+ _ts_metadata18("design:type", Function),
1902
+ _ts_metadata18("design:paramtypes", []),
1903
+ _ts_metadata18("design:returntype", Promise)
1904
+ ], PolarApiController.prototype, "syncProducts", null);
1905
+ _ts_decorate18([
1906
+ Get("admin/orders"),
1907
+ RestrictedRoute(),
1908
+ _ts_metadata18("design:type", Function),
1909
+ _ts_metadata18("design:paramtypes", []),
1910
+ _ts_metadata18("design:returntype", Promise)
1911
+ ], PolarApiController.prototype, "listOrders", null);
1912
+ _ts_decorate18([
1913
+ Get("admin/benefits"),
1914
+ RestrictedRoute(),
1915
+ _ts_metadata18("design:type", Function),
1916
+ _ts_metadata18("design:paramtypes", []),
1917
+ _ts_metadata18("design:returntype", Promise)
1918
+ ], PolarApiController.prototype, "listBenefits", null);
1919
+ _ts_decorate18([
1920
+ Get("admin/benefit-grants"),
1921
+ RestrictedRoute(),
1922
+ _ts_metadata18("design:type", Function),
1923
+ _ts_metadata18("design:paramtypes", []),
1924
+ _ts_metadata18("design:returntype", Promise)
1925
+ ], PolarApiController.prototype, "listBenefitGrants", null);
1926
+ PolarApiController = _ts_decorate18([
1927
+ Controller("polar"),
1928
+ _ts_param9(5, InjectModel(PolarOrder)),
1929
+ _ts_metadata18("design:type", Function),
1930
+ _ts_metadata18("design:paramtypes", [
1931
+ typeof PolarAccessService === "undefined" ? Object : PolarAccessService,
1932
+ typeof PolarBenefitService === "undefined" ? Object : PolarBenefitService,
1933
+ typeof PolarCheckoutService === "undefined" ? Object : PolarCheckoutService,
1934
+ typeof PolarCustomerService === "undefined" ? Object : PolarCustomerService,
1935
+ typeof PolarMetricsService === "undefined" ? Object : PolarMetricsService,
1936
+ typeof Model === "undefined" ? Object : Model,
1937
+ typeof PolarPortalService === "undefined" ? Object : PolarPortalService,
1938
+ typeof PolarProductService === "undefined" ? Object : PolarProductService,
1939
+ typeof PolarService === "undefined" ? Object : PolarService,
1940
+ typeof PolarSubscriptionService === "undefined" ? Object : PolarSubscriptionService
1941
+ ])
1942
+ ], PolarApiController);
1943
+ }
1944
+ });
1945
+ function _ts_decorate19(decorators, target, key, desc) {
1946
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1947
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1948
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1949
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1950
+ }
1951
+ function _ts_metadata19(k, v) {
1952
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1953
+ }
1954
+ function _ts_param10(paramIndex, decorator) {
1955
+ return function(target, key) {
1956
+ decorator(target, key, paramIndex);
1957
+ };
1958
+ }
1959
+ var PolarWebhookService;
1960
+ var init_polar_webhook_service = __esm({
1961
+ "src/polar-webhook.service.ts"() {
1962
+ init_processed_event_schema();
1963
+ init_benefit_service();
1964
+ init_customer_service();
1965
+ init_order_service();
1966
+ init_product_service();
1967
+ init_subscription_service();
1968
+ __name(_ts_decorate19, "_ts_decorate");
1969
+ __name(_ts_metadata19, "_ts_metadata");
1970
+ __name(_ts_param10, "_ts_param");
1971
+ PolarWebhookService = class _PolarWebhookService {
1972
+ static {
1973
+ __name(this, "PolarWebhookService");
1974
+ }
1975
+ processedEventModel;
1976
+ customerService;
1977
+ productService;
1978
+ subscriptionService;
1979
+ orderService;
1980
+ benefitService;
1981
+ emailService;
1982
+ logger;
1983
+ constructor(processedEventModel, customerService, productService, subscriptionService, orderService, benefitService, emailService) {
1984
+ this.processedEventModel = processedEventModel;
1985
+ this.customerService = customerService;
1986
+ this.productService = productService;
1987
+ this.subscriptionService = subscriptionService;
1988
+ this.orderService = orderService;
1989
+ this.benefitService = benefitService;
1990
+ this.emailService = emailService;
1991
+ this.logger = new Logger(_PolarWebhookService.name);
1992
+ }
1993
+ /**
1994
+ * Process a verified Polar event with idempotency.
1995
+ * Returns silently if the event was already processed.
1996
+ */
1997
+ async processEvent(event) {
1998
+ const eventId = "data" in event && event.data && "id" in event.data ? event.data.id : `${event.type}-${Date.now()}`;
1999
+ const existing = await this.findProcessedEvent(eventId);
2000
+ if (existing) {
2001
+ this.logger.log(`Event ${eventId} already processed, skipping`);
2002
+ return;
2003
+ }
2004
+ try {
2005
+ await this.dispatchEvent(event);
2006
+ await this.recordProcessedEvent(eventId, event.type);
2007
+ } catch (error) {
2008
+ this.logger.error(`Failed to process event ${eventId} (${event.type}): ${error instanceof Error ? error.message : String(error)}`);
2009
+ }
2010
+ }
2011
+ /**
2012
+ * Dispatch event to the appropriate handler.
2013
+ */
2014
+ async dispatchEvent(event) {
2015
+ switch (event.type) {
2016
+ case "customer.created":
2017
+ case "customer.updated":
2018
+ await this.customerService.upsertFromWebhook({
2019
+ id: event.data.id,
2020
+ email: event.data.email,
2021
+ name: event.data.name ?? void 0,
2022
+ externalId: event.data.externalId ?? void 0,
2023
+ metadata: event.data.metadata
2024
+ });
2025
+ break;
2026
+ case "customer.deleted":
2027
+ await this.customerService.deleteByPolarId(event.data.id);
2028
+ break;
2029
+ case "product.created":
2030
+ case "product.updated":
2031
+ await this.productService.syncProduct({
2032
+ id: event.data.id,
2033
+ name: event.data.name,
2034
+ description: event.data.description ?? void 0,
2035
+ isRecurring: event.data.isRecurring,
2036
+ isArchived: event.data.isArchived,
2037
+ organizationId: event.data.organizationId,
2038
+ metadata: event.data.metadata
2039
+ });
2040
+ break;
2041
+ case "subscription.created":
2042
+ case "subscription.updated":
2043
+ case "subscription.active":
2044
+ case "subscription.canceled":
2045
+ case "subscription.uncanceled":
2046
+ case "subscription.revoked":
2047
+ case "subscription.past_due":
2048
+ await this.subscriptionService.syncSubscription({
2049
+ id: event.data.id,
2050
+ customerId: event.data.customerId,
2051
+ productId: event.data.productId,
2052
+ status: event.data.status,
2053
+ amount: event.data.amount,
2054
+ currency: event.data.currency,
2055
+ recurringInterval: event.data.recurringInterval,
2056
+ currentPeriodStart: event.data.currentPeriodStart,
2057
+ currentPeriodEnd: event.data.currentPeriodEnd,
2058
+ cancelAtPeriodEnd: event.data.cancelAtPeriodEnd,
2059
+ startedAt: event.data.startedAt ?? void 0,
2060
+ endedAt: event.data.endedAt ?? void 0
2061
+ });
2062
+ break;
2063
+ case "order.created":
2064
+ case "order.paid":
2065
+ case "order.updated":
2066
+ await this.orderService.syncOrder({
2067
+ id: event.data.id,
2068
+ customerId: event.data.customerId,
2069
+ productId: event.data.productId ?? "",
2070
+ subscriptionId: event.data.subscriptionId ?? void 0,
2071
+ status: event.data.paid ? "paid" : "pending",
2072
+ totalAmount: event.data.totalAmount,
2073
+ currency: event.data.currency,
2074
+ billingReason: event.data.billingReason,
2075
+ createdAt: event.data.createdAt
2076
+ });
2077
+ break;
2078
+ case "order.refunded":
2079
+ await this.orderService.syncOrder({
2080
+ id: event.data.id,
2081
+ customerId: event.data.customerId,
2082
+ productId: event.data.productId ?? "",
2083
+ subscriptionId: event.data.subscriptionId ?? void 0,
2084
+ status: "refunded",
2085
+ totalAmount: event.data.totalAmount,
2086
+ currency: event.data.currency,
2087
+ billingReason: event.data.billingReason,
2088
+ createdAt: event.data.createdAt
2089
+ });
2090
+ break;
2091
+ case "benefit.created":
2092
+ case "benefit.updated":
2093
+ await this.benefitService.syncBenefit({
2094
+ id: event.data.id,
2095
+ type: event.data.type,
2096
+ description: event.data.description,
2097
+ organizationId: event.data.organizationId,
2098
+ selectable: event.data.selectable,
2099
+ deletable: event.data.deletable
2100
+ });
2101
+ break;
2102
+ case "benefit_grant.created":
2103
+ case "benefit_grant.updated":
2104
+ await this.benefitService.syncBenefitGrant({
2105
+ id: event.data.id,
2106
+ benefitId: event.data.benefitId,
2107
+ customerId: event.data.customerId,
2108
+ subscriptionId: event.data.subscriptionId ?? void 0,
2109
+ isGranted: event.data.isGranted,
2110
+ isRevoked: event.data.isRevoked,
2111
+ grantedAt: event.data.isGranted ? event.data.modifiedAt ?? /* @__PURE__ */ new Date() : void 0
2112
+ });
2113
+ break;
2114
+ case "benefit_grant.revoked":
2115
+ await this.benefitService.syncBenefitGrant({
2116
+ id: event.data.id,
2117
+ benefitId: event.data.benefitId,
2118
+ customerId: event.data.customerId,
2119
+ subscriptionId: event.data.subscriptionId ?? void 0,
2120
+ isGranted: false,
2121
+ isRevoked: true,
2122
+ revokedAt: event.data.modifiedAt ?? /* @__PURE__ */ new Date()
2123
+ });
2124
+ break;
2125
+ default:
2126
+ this.logger.log(`Unhandled event type: ${event.type}`);
2127
+ }
2128
+ }
2129
+ // =========================================================================
2130
+ // Idempotency Helpers
2131
+ // =========================================================================
2132
+ async findProcessedEvent(eventId) {
2133
+ const result = await this.processedEventModel.findOne({
2134
+ polarEventId: eventId
2135
+ });
2136
+ return result !== null;
2137
+ }
2138
+ async recordProcessedEvent(eventId, eventType) {
2139
+ try {
2140
+ await this.processedEventModel.create({
2141
+ polarEventId: eventId,
2142
+ eventType,
2143
+ processedAt: /* @__PURE__ */ new Date()
2144
+ });
2145
+ } catch (error) {
2146
+ this.logger.warn(`Failed to record processed event ${eventId}: ${error instanceof Error ? error.message : String(error)}`);
2147
+ }
2148
+ }
2149
+ };
2150
+ PolarWebhookService = _ts_decorate19([
2151
+ Injectable(),
2152
+ _ts_param10(0, InjectModel(PolarProcessedEvent)),
2153
+ _ts_param10(6, Optional()),
2154
+ _ts_metadata19("design:type", Function),
2155
+ _ts_metadata19("design:paramtypes", [
2156
+ typeof Model === "undefined" ? Object : Model,
2157
+ typeof PolarCustomerService === "undefined" ? Object : PolarCustomerService,
2158
+ typeof PolarProductService === "undefined" ? Object : PolarProductService,
2159
+ typeof PolarSubscriptionService === "undefined" ? Object : PolarSubscriptionService,
2160
+ typeof PolarOrderService === "undefined" ? Object : PolarOrderService,
2161
+ typeof PolarBenefitService === "undefined" ? Object : PolarBenefitService,
2162
+ typeof EmailService === "undefined" ? Object : EmailService
2163
+ ])
2164
+ ], PolarWebhookService);
2165
+ }
2166
+ });
2167
+ function _ts_decorate20(decorators, target, key, desc) {
2168
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2169
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2170
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2171
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2172
+ }
2173
+ function _ts_metadata20(k, v) {
2174
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2175
+ }
2176
+ function _ts_param11(paramIndex, decorator) {
2177
+ return function(target, key) {
2178
+ decorator(target, key, paramIndex);
2179
+ };
2180
+ }
2181
+ var PolarWebhookController;
2182
+ var init_polar_webhook_controller = __esm({
2183
+ "src/polar-webhook.controller.ts"() {
2184
+ init_polar_webhook_service();
2185
+ init_polar_service();
2186
+ __name(_ts_decorate20, "_ts_decorate");
2187
+ __name(_ts_metadata20, "_ts_metadata");
2188
+ __name(_ts_param11, "_ts_param");
2189
+ PolarWebhookController = class {
2190
+ static {
2191
+ __name(this, "PolarWebhookController");
2192
+ }
2193
+ polarService;
2194
+ webhookService;
2195
+ constructor(polarService, webhookService) {
2196
+ this.polarService = polarService;
2197
+ this.webhookService = webhookService;
2198
+ }
2199
+ async handleWebhook(req, headers) {
2200
+ this.polarService.verifyRawBodyAvailable(req);
2201
+ const { webhookSecret } = this.polarService.pluginConfig;
2202
+ if (!webhookSecret) {
2203
+ throw new Error("[PolarPlugin] webhookSecret is required for webhook verification");
2204
+ }
2205
+ let event;
2206
+ try {
2207
+ event = validateEvent(req.rawBody.toString(), headers, webhookSecret);
2208
+ } catch (error) {
2209
+ if (error instanceof WebhookVerificationError) {
2210
+ throw error;
2211
+ }
2212
+ throw error;
2213
+ }
2214
+ await this.webhookService.processEvent(event);
2215
+ return {
2216
+ received: true
2217
+ };
2218
+ }
2219
+ };
2220
+ _ts_decorate20([
2221
+ Post(),
2222
+ HttpCode(200),
2223
+ _ts_param11(0, Req()),
2224
+ _ts_param11(1, Headers()),
2225
+ _ts_metadata20("design:type", Function),
2226
+ _ts_metadata20("design:paramtypes", [
2227
+ Object,
2228
+ typeof Record === "undefined" ? Object : Record
2229
+ ]),
2230
+ _ts_metadata20("design:returntype", Promise)
2231
+ ], PolarWebhookController.prototype, "handleWebhook", null);
2232
+ PolarWebhookController = _ts_decorate20([
2233
+ Controller("polar/webhooks"),
2234
+ _ts_metadata20("design:type", Function),
2235
+ _ts_metadata20("design:paramtypes", [
2236
+ typeof PolarService === "undefined" ? Object : PolarService,
2237
+ typeof PolarWebhookService === "undefined" ? Object : PolarWebhookService
2238
+ ])
2239
+ ], PolarWebhookController);
2240
+ }
2241
+ });
2242
+
2243
+ // src/polar.module.ts
2244
+ var polar_module_exports = {};
2245
+ __export(polar_module_exports, {
2246
+ PolarModule: () => PolarModule
2247
+ });
2248
+ function _ts_decorate21(decorators, target, key, desc) {
2249
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2250
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2251
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2252
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2253
+ }
2254
+ var PolarModule;
2255
+ var init_polar_module = __esm({
2256
+ "src/polar.module.ts"() {
2257
+ init_polar_api_controller();
2258
+ init_polar_webhook_controller();
2259
+ init_polar_webhook_service();
2260
+ init_polar_service();
2261
+ init_benefit_grant_schema();
2262
+ init_benefit_schema();
2263
+ init_customer_schema();
2264
+ init_order_schema();
2265
+ init_processed_event_schema();
2266
+ init_product_schema();
2267
+ init_subscription_schema();
2268
+ init_access_service();
2269
+ init_benefit_service();
2270
+ init_checkout_service();
2271
+ init_customer_service();
2272
+ init_metrics_service();
2273
+ init_order_service();
2274
+ init_portal_service();
2275
+ init_product_service();
2276
+ init_subscription_service();
2277
+ __name(_ts_decorate21, "_ts_decorate");
2278
+ PolarModule = class {
2279
+ static {
2280
+ __name(this, "PolarModule");
2281
+ }
2282
+ };
2283
+ PolarModule = _ts_decorate21([
2284
+ Module({
2285
+ imports: [
2286
+ DatabaseModule.forFeature(PolarCustomer),
2287
+ DatabaseModule.forFeature(PolarProduct),
2288
+ DatabaseModule.forFeature(PolarSubscription),
2289
+ DatabaseModule.forFeature(PolarOrder),
2290
+ DatabaseModule.forFeature(PolarBenefit),
2291
+ DatabaseModule.forFeature(PolarBenefitGrant),
2292
+ DatabaseModule.forFeature(PolarProcessedEvent)
2293
+ ],
2294
+ controllers: [
2295
+ PolarApiController,
2296
+ PolarWebhookController
2297
+ ],
2298
+ providers: [
2299
+ PolarService,
2300
+ PolarWebhookService,
2301
+ PolarCustomerService,
2302
+ PolarProductService,
2303
+ PolarSubscriptionService,
2304
+ PolarOrderService,
2305
+ PolarBenefitService,
2306
+ PolarCheckoutService,
2307
+ PolarPortalService,
2308
+ PolarAccessService,
2309
+ PolarMetricsService
2310
+ ],
2311
+ exports: [
2312
+ PolarService,
2313
+ PolarCustomerService,
2314
+ PolarProductService,
2315
+ PolarSubscriptionService,
2316
+ PolarOrderService,
2317
+ PolarBenefitService,
2318
+ PolarCheckoutService,
2319
+ PolarPortalService,
2320
+ PolarAccessService
2321
+ ]
2322
+ })
2323
+ ], PolarModule);
2324
+ }
2325
+ });
2326
+ function _ts_decorate22(decorators, target, key, desc) {
2327
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2328
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2329
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2330
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2331
+ }
2332
+ __name(_ts_decorate22, "_ts_decorate");
2333
+ var PolarPlugin = class _PolarPlugin {
2334
+ static {
2335
+ __name(this, "PolarPlugin");
2336
+ }
2337
+ /** Environment variables used by this plugin */
2338
+ static envVars = [
2339
+ {
2340
+ name: "POLAR_ACCESS_TOKEN",
2341
+ required: true,
2342
+ description: "Polar API access token"
2343
+ },
2344
+ {
2345
+ name: "POLAR_WEBHOOK_SECRET",
2346
+ required: true,
2347
+ description: "Polar webhook signing secret"
2348
+ },
2349
+ {
2350
+ name: "POLAR_ORGANIZATION_ID",
2351
+ required: false,
2352
+ description: "Polar organization ID"
2353
+ }
2354
+ ];
2355
+ /**
2356
+ * Create a configured plugin provider for MagnetModule.forRoot().
2357
+ * Auto-resolves secret values from environment variables if not provided.
2358
+ *
2359
+ * @example
2360
+ * ```typescript
2361
+ * MagnetModule.forRoot([
2362
+ * PolarPlugin.forRoot({ currency: 'usd' }),
2363
+ * ])
2364
+ * ```
2365
+ */
2366
+ static forRoot(config) {
2367
+ const resolvedConfig = {
2368
+ accessToken: config?.accessToken ?? process.env.POLAR_ACCESS_TOKEN,
2369
+ webhookSecret: config?.webhookSecret ?? process.env.POLAR_WEBHOOK_SECRET,
2370
+ organizationId: config?.organizationId ?? process.env.POLAR_ORGANIZATION_ID,
2371
+ syncProducts: config?.syncProducts,
2372
+ currency: config?.currency,
2373
+ features: config?.features
2374
+ };
2375
+ return {
2376
+ type: "plugin",
2377
+ plugin: _PolarPlugin,
2378
+ options: resolvedConfig,
2379
+ envVars: _PolarPlugin.envVars
2380
+ };
2381
+ }
2382
+ };
2383
+ PolarPlugin = _ts_decorate22([
2384
+ Plugin({
2385
+ name: "polar",
2386
+ description: "Polar.sh payments plugin for Magnet CMS",
2387
+ version: "0.1.0",
2388
+ module: /* @__PURE__ */ __name(() => (init_polar_module(), __toCommonJS(polar_module_exports)).PolarModule, "module"),
2389
+ frontend: {
2390
+ routes: [
2391
+ {
2392
+ path: "polar",
2393
+ componentId: "PolarDashboard",
2394
+ requiresAuth: true,
2395
+ children: [
2396
+ {
2397
+ path: "",
2398
+ componentId: "PolarDashboard"
2399
+ },
2400
+ {
2401
+ path: "customers",
2402
+ componentId: "PolarCustomers"
2403
+ },
2404
+ {
2405
+ path: "products",
2406
+ componentId: "PolarProducts"
2407
+ },
2408
+ {
2409
+ path: "subscriptions",
2410
+ componentId: "PolarSubscriptions"
2411
+ },
2412
+ {
2413
+ path: "orders",
2414
+ componentId: "PolarOrders"
2415
+ },
2416
+ {
2417
+ path: "benefits",
2418
+ componentId: "PolarBenefits"
2419
+ }
2420
+ ]
2421
+ }
2422
+ ],
2423
+ sidebar: [
2424
+ {
2425
+ id: "polar",
2426
+ title: "Polar Payments",
2427
+ url: "/polar",
2428
+ icon: "Zap",
2429
+ order: 31,
2430
+ items: [
2431
+ {
2432
+ id: "polar-dashboard",
2433
+ title: "Dashboard",
2434
+ url: "/polar",
2435
+ icon: "BarChart3"
2436
+ },
2437
+ {
2438
+ id: "polar-customers",
2439
+ title: "Customers",
2440
+ url: "/polar/customers",
2441
+ icon: "Users"
2442
+ },
2443
+ {
2444
+ id: "polar-products",
2445
+ title: "Products",
2446
+ url: "/polar/products",
2447
+ icon: "Package"
2448
+ },
2449
+ {
2450
+ id: "polar-subscriptions",
2451
+ title: "Subscriptions",
2452
+ url: "/polar/subscriptions",
2453
+ icon: "RefreshCw"
2454
+ },
2455
+ {
2456
+ id: "polar-orders",
2457
+ title: "Orders",
2458
+ url: "/polar/orders",
2459
+ icon: "Receipt"
2460
+ },
2461
+ {
2462
+ id: "polar-benefits",
2463
+ title: "Benefits",
2464
+ url: "/polar/benefits",
2465
+ icon: "Gift"
2466
+ }
2467
+ ]
2468
+ }
2469
+ ]
2470
+ }
2471
+ })
2472
+ ], PolarPlugin);
2473
+
2474
+ export { PolarAccessService, PolarBenefit, PolarBenefitGrant, PolarBenefitService, PolarCheckoutService, PolarCustomer, PolarCustomerService, PolarMetricsService, PolarModule, PolarOrder, PolarOrderService, PolarPlugin, PolarPortalService, PolarProcessedEvent, PolarProduct, PolarProductService, PolarService, PolarSubscription, PolarSubscriptionService, init_access_service, init_benefit_grant_schema, init_benefit_schema, init_benefit_service, init_checkout_service, init_customer_schema, init_customer_service, init_metrics_service, init_order_schema, init_order_service, init_polar_module, init_polar_service, init_portal_service, init_processed_event_schema, init_product_schema, init_product_service, init_subscription_schema, init_subscription_service };