@saasicat/nest 0.26.0 → 0.27.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.
Files changed (43) hide show
  1. package/LICENSE +90 -201
  2. package/dist/_entries.cjs +3265 -2846
  3. package/dist/billing/index.d.cts +4 -4
  4. package/dist/billing/index.d.ts +4 -4
  5. package/dist/billing/index.js +33 -31
  6. package/dist/catalog/index.js +5 -5
  7. package/dist/checkout-offer/index.js +2 -2
  8. package/dist/chunk-2FR6ZL7R.js +0 -0
  9. package/dist/chunk-2JTISFUZ.js +792 -0
  10. package/dist/chunk-2SLTRKXC.js +0 -0
  11. package/dist/chunk-3E6ONOMG.js +50 -0
  12. package/dist/{chunk-UOWK2HYG.js → chunk-7ZPFQXHM.js} +1 -1
  13. package/dist/{chunk-B7NRY2LV.js → chunk-CJFAOD7K.js} +1 -39
  14. package/dist/{chunk-J62YI25C.js → chunk-EHKMPP6J.js} +1194 -775
  15. package/dist/{chunk-RPO4IVUY.js → chunk-F4B2NJUZ.js} +26 -91
  16. package/dist/chunk-H4DOTO7S.js +85 -0
  17. package/dist/{chunk-V3MRZ7SH.js → chunk-UHD6FJBQ.js} +421 -1197
  18. package/dist/{define-saasicat-BK6RRWWG.d.ts → define-saasicat-3ois8t8s.d.ts} +26 -3
  19. package/dist/{define-saasicat-D30I-WET.d.cts → define-saasicat-CFxut1VR.d.cts} +26 -3
  20. package/dist/{enforce-quota.interceptor-B9QueAFf.d.ts → enforce-quota.interceptor-CYDNvAQz.d.ts} +3 -3
  21. package/dist/{enforce-quota.interceptor-DY6CLjoP.d.cts → enforce-quota.interceptor-N80KC34N.d.cts} +3 -3
  22. package/dist/entitlement/index.js +7 -4
  23. package/dist/index.d.cts +5 -5
  24. package/dist/index.d.ts +5 -5
  25. package/dist/index.js +87 -79
  26. package/dist/{saas-platform.module-D1mUZPrz.d.ts → module-options-ByJL7FZm.d.ts} +40 -27
  27. package/dist/{saas-platform.module-CgalxzcT.d.cts → module-options-klrPnWGF.d.cts} +40 -27
  28. package/dist/platform/index.d.cts +201 -19
  29. package/dist/platform/index.d.ts +201 -19
  30. package/dist/platform/index.js +58 -33
  31. package/dist/promo/index.js +2 -2
  32. package/dist/subscription-contract/index.js +5 -2
  33. package/dist/{tenant-billing.controller-DHSUrT_N.d.cts → tenant-billing.controller-CAMMdfn1.d.cts} +1 -1
  34. package/dist/{tenant-billing.controller-BSlpFqVA.d.ts → tenant-billing.controller-CYYK0CpT.d.ts} +1 -1
  35. package/dist/{subscription-bundles.module-BDbODWvA.d.ts → tenant-billing.module-B0stLoJn.d.ts} +51 -51
  36. package/dist/{subscription-bundles.module-Cfi-lFWF.d.cts → tenant-billing.module-BxJS6fX4.d.cts} +51 -51
  37. package/dist/testing/index.d.cts +8 -8
  38. package/dist/testing/index.d.ts +8 -8
  39. package/dist/testing/index.js +13 -11
  40. package/package.json +4 -4
  41. package/dist/{chunk-QB7MICKQ.js → chunk-7X5MSAIL.js} +9 -9
  42. package/dist/{chunk-FY4EJTV4.js → chunk-OYNHOY45.js} +0 -0
  43. package/dist/{chunk-I4XD43AN.js → chunk-XTVAFJ3P.js} +3 -3
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-37HEKVDH.js";
4
4
  import {
5
5
  SubscriptionContractService
6
- } from "./chunk-B7NRY2LV.js";
6
+ } from "./chunk-CJFAOD7K.js";
7
7
  import {
8
8
  AUDIT_CONTEXT_RESOLVER_TOKEN,
9
9
  PENDING_PLAN_QUERY_PORT_TOKEN,
@@ -16,13 +16,18 @@ import {
16
16
  USER_EMAIL_RESOLVER_TOKEN,
17
17
  USER_ID_RESOLVER_TOKEN
18
18
  } from "./chunk-WPUVJRIN.js";
19
+ import {
20
+ AdminAuditService
21
+ } from "./chunk-E56W4U2P.js";
22
+ import {
23
+ SaaSiCatPublicRoute
24
+ } from "./chunk-YSC46BGM.js";
19
25
  import {
20
26
  EntitlementService,
21
27
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
22
28
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN,
23
- isLimitExceededError,
24
29
  toEffectiveLimitsSnapshot
25
- } from "./chunk-RPO4IVUY.js";
30
+ } from "./chunk-F4B2NJUZ.js";
26
31
  import {
27
32
  PLAN_CATALOG_TOKEN,
28
33
  findPlan,
@@ -32,6 +37,9 @@ import {
32
37
  import {
33
38
  SUBSCRIPTION_CONTRACT_REPOSITORY_TOKEN
34
39
  } from "./chunk-NYLON2VC.js";
40
+ import {
41
+ codedError
42
+ } from "./chunk-EBJJNTW6.js";
35
43
  import {
36
44
  ENTITLEMENT_SERVICE_TOKEN
37
45
  } from "./chunk-WKVBNTYC.js";
@@ -40,15 +48,6 @@ import {
40
48
  CATALOG_ENTRY_REPOSITORY_TOKEN,
41
49
  PLAN_REPOSITORY_TOKEN
42
50
  } from "./chunk-L4KTQ6CL.js";
43
- import {
44
- AdminAuditService
45
- } from "./chunk-E56W4U2P.js";
46
- import {
47
- SaaSiCatPublicRoute
48
- } from "./chunk-YSC46BGM.js";
49
- import {
50
- codedError
51
- } from "./chunk-EBJJNTW6.js";
52
51
  import {
53
52
  asProvider
54
53
  } from "./chunk-SABTXESR.js";
@@ -92,88 +91,6 @@ function periodEndWithMinLead(startedAt, cycle, now, minLeadDays = 42) {
92
91
  }
93
92
  __name(periodEndWithMinLead, "periodEndWithMinLead");
94
93
 
95
- // src/billing/version-publish.ts
96
- var PublishValidationError = class extends Error {
97
- static {
98
- __name(this, "PublishValidationError");
99
- }
100
- code;
101
- constructor(code, message) {
102
- super(message), this.code = code;
103
- this.name = "PublishValidationError";
104
- }
105
- };
106
- function assertChangeNote(changeNote) {
107
- const trimmed = (changeNote ?? "").trim();
108
- if (trimmed.length === 0) {
109
- throw new PublishValidationError("CHANGE_NOTE_REQUIRED", "changeNote is required when publishing a version.");
110
- }
111
- return trimmed;
112
- }
113
- __name(assertChangeNote, "assertChangeNote");
114
- function assertDraftPublishable(draft, draftId) {
115
- if (!draft) {
116
- throw new PublishValidationError("NOT_FOUND", `PlanVersion ${draftId} not found`);
117
- }
118
- if (draft.publishedAt !== null) {
119
- throw new PublishValidationError("ALREADY_PUBLISHED", `PlanVersion ${draftId} has already been published.`);
120
- }
121
- if (!draft.baseVersionId) {
122
- throw new PublishValidationError("NO_BASE_VERSION", `Draft ${draftId} has no baseVersion \u2014 probably a manually created v1 that may only be published via a migration.`);
123
- }
124
- }
125
- __name(assertDraftPublishable, "assertDraftPublishable");
126
- function assertBaseVersionFresh(base, baseId, planContext) {
127
- if (!base) {
128
- throw new PublishValidationError("BASE_NOT_FOUND", `baseVersion ${baseId} no longer exists.`);
129
- }
130
- if (base.supersededAt !== null) {
131
- throw new PublishValidationError("BASE_SUPERSEDED", `The draft is based on a superseded version (${planContext}). Rebase the draft onto the current live version, or create a new one.`);
132
- }
133
- }
134
- __name(assertBaseVersionFresh, "assertBaseVersionFresh");
135
- function assertOptimisticLockHeld(updateCount, draftId) {
136
- if (updateCount !== 1) {
137
- throw new PublishValidationError("OPTIMISTIC_LOCK_CONFLICT", `Draft ${draftId} has meanwhile been published by another admin.`);
138
- }
139
- }
140
- __name(assertOptimisticLockHeld, "assertOptimisticLockHeld");
141
-
142
- // src/billing/version-renewal.ts
143
- function decideRenewal(sub, now) {
144
- if (!sub.pendingPlanVersionId || !sub.pendingPlanVersionEffectiveAt) return "SKIP";
145
- if (sub.pendingPlanVersionEffectiveAt > now) return "SKIP";
146
- if (sub.pendingPlanVersionNonRegressive || sub.pendingPlanVersionAccepted) {
147
- return "ROLL_FORWARD";
148
- }
149
- return "CLEAR_PENDING";
150
- }
151
- __name(decideRenewal, "decideRenewal");
152
- function clearPendingPlanVersionFields() {
153
- return {
154
- pendingPlanVersionId: null,
155
- pendingPlanVersionEffectiveAt: null,
156
- pendingPlanVersionAccepted: false,
157
- pendingPlanVersionAcceptedAt: null,
158
- pendingPlanVersionAcceptedByUserId: null,
159
- pendingPlanVersionNotifiedAt: null,
160
- pendingPlanVersionReminderSentAt: null
161
- };
162
- }
163
- __name(clearPendingPlanVersionFields, "clearPendingPlanVersionFields");
164
- function computeNextPeriod(sub, now) {
165
- if (sub.canceledAt !== null) return null;
166
- if (sub.currentPeriodEnd === null) return null;
167
- if (sub.currentPeriodEnd > now) return null;
168
- const newStart = sub.currentPeriodEnd;
169
- const newEnd = periodEndAfter(newStart, sub.billingCycle, now);
170
- return {
171
- currentPeriodStart: newStart,
172
- currentPeriodEnd: newEnd
173
- };
174
- }
175
- __name(computeNextPeriod, "computeNextPeriod");
176
-
177
94
  // src/billing/feature-guard-marker.ts
178
95
  var FEATURE_GUARD_MARKER = /* @__PURE__ */ Symbol.for("saasicat/nest/feature-guard");
179
96
  function isPlatformFeatureGuard(target) {
@@ -189,628 +106,35 @@ import { SetMetadata } from "@nestjs/common";
189
106
  var REQUIRE_FEATURE_KEY = "require-feature";
190
107
  var RequireFeature = /* @__PURE__ */ __name((...features) => SetMetadata(REQUIRE_FEATURE_KEY, features), "RequireFeature");
191
108
 
192
- // src/billing/feature-guard.tokens.ts
193
- var FEATURE_GUARD_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/FeatureGuardConfig");
194
-
195
- // src/billing/feature.guard.ts
196
- import { ForbiddenException, Inject, Injectable, Logger, Optional } from "@nestjs/common";
197
- import { Reflector } from "@nestjs/core";
198
- import { AUTH_ERROR_CODES, FEATURE_NOT_LICENSED } from "@saasicat/types";
199
-
200
- // src/billing/upsell.tokens.ts
201
- var UPSELL_OFFER_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/UpsellOfferResolver");
202
- var UPSELL_OFFER_CURRENCY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/UpsellOfferCurrency");
203
-
204
- // src/billing/feature.guard.ts
205
- function _ts_decorate(decorators, target, key, desc) {
206
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
207
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
208
- 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;
209
- return c > 3 && r && Object.defineProperty(target, key, r), r;
210
- }
211
- __name(_ts_decorate, "_ts_decorate");
212
- function _ts_metadata(k, v) {
213
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
214
- }
215
- __name(_ts_metadata, "_ts_metadata");
216
- function _ts_param(paramIndex, decorator) {
217
- return function(target, key) {
218
- decorator(target, key, paramIndex);
219
- };
220
- }
221
- __name(_ts_param, "_ts_param");
222
- var FeatureGuard = class _FeatureGuard {
223
- static {
224
- __name(this, "FeatureGuard");
225
- }
226
- reflector;
227
- entitlements;
228
- config;
229
- upsellResolver;
230
- /** Lets `FeatureGuardCoverageCheck` recognise this guard across CJS entries. */
231
- static [FEATURE_GUARD_MARKER] = true;
232
- logger = new Logger(_FeatureGuard.name);
233
- constructor(reflector, entitlements, config = null, upsellResolver = null) {
234
- this.reflector = reflector;
235
- this.entitlements = entitlements;
236
- this.config = config;
237
- this.upsellResolver = upsellResolver;
238
- }
239
- async canActivate(context) {
240
- const required = this.reflector.getAllAndOverride(REQUIRE_FEATURE_KEY, [
241
- context.getHandler(),
242
- context.getClass()
243
- ]);
244
- if (!required || required.length === 0) return true;
245
- const request = context.switchToHttp().getRequest();
246
- const user = request.user;
247
- if (!user) {
248
- throw new ForbiddenException({
249
- code: AUTH_ERROR_CODES.NOT_AUTHENTICATED,
250
- message: "Not authenticated"
251
- });
252
- }
253
- const role = this.config?.userRoleResolver ? this.config.userRoleResolver(user) : user.role ?? user.platformRole;
254
- if (role === "SUPER_ADMIN") return true;
255
- const tenantId = this.config?.tenantIdResolver ? this.config.tenantIdResolver(request) : request.tenantId ?? user.tenantId;
256
- if (!tenantId) {
257
- throw new ForbiddenException({
258
- code: AUTH_ERROR_CODES.NO_TENANT_ASSIGNED,
259
- message: "No tenant assigned"
260
- });
261
- }
262
- const compute = /* @__PURE__ */ __name(() => this.entitlements.computeLimits(tenantId), "compute");
263
- const limits = this.config?.tenantContextRunner ? await this.config.tenantContextRunner(tenantId, compute) : await compute();
264
- const allowed = required.some((f) => limits.features.has(f));
265
- if (!allowed) {
266
- throw await this.buildNotLicensedException(required, tenantId);
267
- }
268
- return true;
269
- }
270
- /**
271
- * Upsell response (#36): the 403 body is always the full
272
- * `FeatureNotLicensedBody`, so a consumer that matches on `code` can read
273
- * `featureKey`/`offers` unconditionally. Without a registered
274
- * `UpsellOfferResolver` there is simply nothing to offer — `offers` is
275
- * empty, the same degradation a failing resolver produces.
276
- *
277
- * Deliberately 403 + `code` field instead of 402 — rationale in
278
- * `@saasicat/types` upsell.types.ts (402 is reserved / inconsistently
279
- * supported; SPA interceptors must not treat the 403 as an auth error, the
280
- * distinction runs through `code`).
281
- *
282
- * The message must keep starting with the word `Feature` — consumers
283
- * classify the response by that prefix.
284
- */
285
- async buildNotLicensedException(required, tenantId) {
286
- const body = {
287
- code: FEATURE_NOT_LICENSED,
288
- featureKey: required[0],
289
- featureKeys: required,
290
- offers: this.upsellResolver ? await this.resolveOffersSafe(required, tenantId) : [],
291
- message: `Feature ${required.join(" / ")} is not included in the current plan.`
292
- };
293
- return new ForbiddenException(body);
294
- }
295
- /**
296
- * A resolver error must not turn the semantically correct 403 into a 500 —
297
- * degrade to empty offers and log.
298
- */
299
- async resolveOffersSafe(required, tenantId) {
300
- try {
301
- return await this.upsellResolver.resolveOffers(required, tenantId);
302
- } catch (error) {
303
- this.logger.warn(`UpsellOfferResolver failed for [${required.join(", ")}]: ${String(error)}`);
304
- return [];
305
- }
306
- }
307
- };
308
- FeatureGuard = _ts_decorate([
309
- Injectable(),
310
- _ts_param(0, Inject(Reflector)),
311
- _ts_param(1, Inject(ENTITLEMENT_SERVICE_TOKEN)),
312
- _ts_param(2, Optional()),
313
- _ts_param(2, Inject(FEATURE_GUARD_CONFIG_TOKEN)),
314
- _ts_param(3, Optional()),
315
- _ts_param(3, Inject(UPSELL_OFFER_RESOLVER_TOKEN)),
316
- _ts_metadata("design:type", Function),
317
- _ts_metadata("design:paramtypes", [
318
- typeof Reflector === "undefined" ? Object : Reflector,
319
- typeof EntitlementService === "undefined" ? Object : EntitlementService,
320
- Object,
321
- Object
322
- ])
323
- ], FeatureGuard);
324
-
325
- // src/billing/catalog-bundle-upsell-resolver.ts
326
- import { Inject as Inject2, Injectable as Injectable2, Optional as Optional2 } from "@nestjs/common";
327
- import { buildFeatureRequiresIndex, collectUnsatisfiedRequires } from "@saasicat/types";
328
-
329
109
  // src/billing/public-catalog.tokens.ts
330
110
  var PUBLIC_CATALOG_PROJECT_KEY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PublicCatalogProjectKey");
331
111
  var PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PublicCatalogBundleRepository");
332
112
  var PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PublicCatalogMarketingRepository");
333
113
  var PUBLIC_CATALOG_CATALOG_ENTRY_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PublicCatalogCatalogEntryRepository");
334
114
 
335
- // src/billing/catalog-bundle-upsell-resolver.ts
336
- function _ts_decorate2(decorators, target, key, desc) {
337
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
338
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
339
- 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;
340
- return c > 3 && r && Object.defineProperty(target, key, r), r;
341
- }
342
- __name(_ts_decorate2, "_ts_decorate");
343
- function _ts_metadata2(k, v) {
344
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
345
- }
346
- __name(_ts_metadata2, "_ts_metadata");
347
- function _ts_param2(paramIndex, decorator) {
348
- return function(target, key) {
349
- decorator(target, key, paramIndex);
350
- };
351
- }
352
- __name(_ts_param2, "_ts_param");
353
- var DEFAULT_CURRENCY = "EUR";
354
- var CatalogBundleUpsellResolver = class {
355
- static {
356
- __name(this, "CatalogBundleUpsellResolver");
357
- }
358
- bundleRepo;
359
- projectKey;
360
- catalogEntryRepo;
361
- currency;
362
- constructor(bundleRepo, projectKey, catalogEntryRepo = null, currency = null) {
363
- this.bundleRepo = bundleRepo;
364
- this.projectKey = projectKey;
365
- this.catalogEntryRepo = catalogEntryRepo;
366
- this.currency = currency;
367
- }
368
- async resolveOffers(featureKeys, tenantId) {
369
- void tenantId;
370
- if (featureKeys.length === 0) return [];
371
- const missing = new Set(featureKeys);
372
- const wanted = /* @__PURE__ */ new Set([
373
- ...featureKeys,
374
- ...await this.lookupUnmetRequires(featureKeys)
375
- ]);
376
- const ranked = [];
377
- for (const live of await this.listLiveMarketedBundles()) {
378
- const features = live.features;
379
- if (!features.some((key) => missing.has(key))) continue;
380
- ranked.push({
381
- offer: this.toOffer(live),
382
- coverage: features.filter((key) => wanted.has(key)).length
383
- });
384
- }
385
- return ranked.sort(compareRankedOffers).map((r) => r.offer);
386
- }
387
- /**
388
- * Uncovered dependencies of the missing features (#35) — feed into the
389
- * coverage ranking. Without a CatalogEntryRepository: empty (ranking
390
- * degrades to price).
391
- */
392
- async lookupUnmetRequires(featureKeys) {
393
- if (!this.catalogEntryRepo) return [];
394
- const rows = await this.catalogEntryRepo.listFeatures({
395
- projectKey: this.projectKey
396
- });
397
- return collectUnsatisfiedRequires(featureKeys, buildFeatureRequiresIndex(rows));
398
- }
399
- /** Only published-and-live AND marketed — non-marketed bundles are not an offer. */
400
- async listLiveMarketedBundles() {
401
- const stems = await this.bundleRepo.list({
402
- projectKey: this.projectKey,
403
- excludeDeleted: true
404
- });
405
- const out = [];
406
- for (const stem of stems) {
407
- const live = await this.bundleRepo.findLatestLive(stem.id);
408
- if (live?.marketed) out.push(live);
409
- }
410
- return out;
411
- }
412
- toOffer(live) {
413
- return {
414
- bundleKey: live.bundleKey,
415
- bundleVersionId: live.id,
416
- priceMonthlyNet: parsePrice(live.monthlyNet),
417
- currency: this.currency ?? DEFAULT_CURRENCY,
418
- label: live.label
419
- };
420
- }
421
- };
422
- CatalogBundleUpsellResolver = _ts_decorate2([
423
- Injectable2(),
424
- _ts_param2(0, Inject2(PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN)),
425
- _ts_param2(1, Inject2(PUBLIC_CATALOG_PROJECT_KEY_TOKEN)),
426
- _ts_param2(2, Optional2()),
427
- _ts_param2(2, Inject2(PUBLIC_CATALOG_CATALOG_ENTRY_REPOSITORY_TOKEN)),
428
- _ts_param2(3, Optional2()),
429
- _ts_param2(3, Inject2(UPSELL_OFFER_CURRENCY_TOKEN)),
430
- _ts_metadata2("design:type", Function),
431
- _ts_metadata2("design:paramtypes", [
432
- typeof BundleRepository === "undefined" ? Object : BundleRepository,
433
- String,
434
- Object,
435
- Object
436
- ])
437
- ], CatalogBundleUpsellResolver);
438
- function parsePrice(decimal) {
439
- if (decimal === null) return null;
440
- const n = Number.parseFloat(decimal);
441
- return Number.isFinite(n) ? n : null;
442
- }
443
- __name(parsePrice, "parsePrice");
444
- function compareRankedOffers(a, b) {
445
- if (a.coverage !== b.coverage) return b.coverage - a.coverage;
446
- const priceA = a.offer.priceMonthlyNet ?? Number.POSITIVE_INFINITY;
447
- const priceB = b.offer.priceMonthlyNet ?? Number.POSITIVE_INFINITY;
448
- if (priceA !== priceB) return priceA - priceB;
449
- return a.offer.bundleKey.localeCompare(b.offer.bundleKey);
450
- }
451
- __name(compareRankedOffers, "compareRankedOffers");
452
-
453
- // src/billing/limit-exceeded.filter.ts
454
- import { Catch, HttpStatus, Logger as Logger2 } from "@nestjs/common";
455
- import { BaseExceptionFilter } from "@nestjs/core";
456
- import { BILLING_ERROR_CODES } from "@saasicat/types";
457
- function _ts_decorate3(decorators, target, key, desc) {
458
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
459
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
460
- 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;
461
- return c > 3 && r && Object.defineProperty(target, key, r), r;
462
- }
463
- __name(_ts_decorate3, "_ts_decorate");
464
- var LimitExceededFilter = class _LimitExceededFilter extends BaseExceptionFilter {
465
- static {
466
- __name(this, "LimitExceededFilter");
467
- }
468
- logger = new Logger2(_LimitExceededFilter.name);
469
- catch(exception, host) {
470
- if (!isLimitExceededError(exception)) {
471
- super.catch(exception, host);
472
- return;
473
- }
474
- const ctx = host.switchToHttp();
475
- const response = ctx.getResponse();
476
- const request = ctx.getRequest();
477
- this.logger.warn(`Limit ${exception.dimension} exceeded: ${exception.used}/${exception.max} on ${request.method ?? "?"} ${request.url ?? ""}`);
478
- response.status(HttpStatus.PAYMENT_REQUIRED).send({
479
- statusCode: HttpStatus.PAYMENT_REQUIRED,
480
- error: "PaymentRequired",
481
- code: BILLING_ERROR_CODES.LIMIT_EXCEEDED,
482
- // Deprecated: superseded by `code`, kept until consumers have
483
- // migrated. Same value, only under the older field name.
484
- reason: BILLING_ERROR_CODES.LIMIT_EXCEEDED,
485
- dimension: exception.dimension,
486
- used: exception.used,
487
- max: exception.max,
488
- message: exception.message
489
- });
490
- }
491
- };
492
- LimitExceededFilter = _ts_decorate3([
493
- Catch()
494
- ], LimitExceededFilter);
495
-
496
- // src/billing/plan-catalog-loader.ts
497
- import { readFileSync } from "fs";
498
- import { resolve as resolvePath } from "path";
499
- import yaml from "js-yaml";
500
- import Ajv2020 from "ajv/dist/2020.js";
501
- import addFormats from "ajv-formats";
502
- import { planCatalogSchema } from "@saasicat/spec";
503
- var PlanCatalogValidationError = class extends Error {
504
- static {
505
- __name(this, "PlanCatalogValidationError");
506
- }
507
- source;
508
- errors;
509
- constructor(source, errors) {
510
- const messages = errors.map((e) => `${e.instancePath || "/"}: ${e.message ?? "unknown"}`).join("\n ");
511
- super(`Plan catalog validation failed for ${source}:
512
- ${messages}`), this.source = source, this.errors = errors;
513
- this.name = "PlanCatalogValidationError";
514
- }
515
- };
516
- function loadPlanCatalogFromFile(opts) {
517
- const absolutePath = resolvePath(opts.path);
518
- const raw = readFileSync(absolutePath, "utf-8");
519
- return loadPlanCatalogFromString(raw, {
520
- source: absolutePath,
521
- crossFieldChecks: opts.crossFieldChecks ?? true
522
- });
523
- }
524
- __name(loadPlanCatalogFromFile, "loadPlanCatalogFromFile");
525
- function loadPlanCatalogFromString(yamlContent, opts) {
526
- const parsed = yaml.load(yamlContent);
527
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
528
- throw new Error(`The YAML content of ${opts.source} is not an object`);
529
- }
530
- const ajv = new Ajv2020({
531
- strict: false,
532
- allErrors: true
533
- });
534
- addFormats.default(ajv);
535
- const validate = ajv.compile(planCatalogSchema);
536
- if (!validate(parsed)) {
537
- throw new PlanCatalogValidationError(opts.source, validate.errors ?? []);
538
- }
539
- const catalog = parsed;
540
- if (opts.crossFieldChecks ?? true) {
541
- validateConsistency(catalog, opts.source);
542
- }
543
- return catalog;
544
- }
545
- __name(loadPlanCatalogFromString, "loadPlanCatalogFromString");
546
- function validateConsistency(catalog, source) {
547
- const errors = [];
548
- const declaredFeatureKeys = new Set((catalog.features ?? []).map((f) => f.key));
549
- const planIds = /* @__PURE__ */ new Set();
550
- for (const plan of catalog.plans ?? []) {
551
- if (planIds.has(plan.id)) {
552
- errors.push(`plans[].id: duplicate plan id "${plan.id}"`);
553
- }
554
- planIds.add(plan.id);
555
- if (catalog.features) {
556
- for (const fk of plan.features) {
557
- if (!declaredFeatureKeys.has(fk)) {
558
- errors.push(`plans[id=${plan.id}].features: Unknown featureKey "${fk}" \u2014 not declared in catalog.features`);
559
- }
560
- }
561
- }
562
- }
563
- if (errors.length > 0) {
564
- const err = new Error(`Plan catalog consistency error in ${source}:
565
- ${errors.join("\n ")}`);
566
- err.name = "PlanCatalogConsistencyError";
567
- throw err;
568
- }
569
- }
570
- __name(validateConsistency, "validateConsistency");
571
-
572
- // src/billing/plan-catalog-importer.service.ts
573
- import { Inject as Inject3, Injectable as Injectable3 } from "@nestjs/common";
574
- function _ts_decorate4(decorators, target, key, desc) {
575
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
576
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
577
- 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;
578
- return c > 3 && r && Object.defineProperty(target, key, r), r;
579
- }
580
- __name(_ts_decorate4, "_ts_decorate");
581
- function _ts_metadata3(k, v) {
582
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
583
- }
584
- __name(_ts_metadata3, "_ts_metadata");
585
- function _ts_param3(paramIndex, decorator) {
586
- return function(target, key) {
587
- decorator(target, key, paramIndex);
588
- };
589
- }
590
- __name(_ts_param3, "_ts_param");
591
- var PLAN_CATALOG_IMPORT_SINK_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PlanCatalogImportSink");
592
- var IMPORT_CHANGE_NOTE = "Initial import from saas.yaml";
593
- var PlanCatalogImporterService = class {
594
- static {
595
- __name(this, "PlanCatalogImporterService");
596
- }
597
- sink;
598
- constructor(sink) {
599
- this.sink = sink;
600
- }
601
- /**
602
- * Import directly from a YAML string. Apps pass the contents of the
603
- * `saas.yaml` through via the HTTP body; CLI tools can read the file
604
- * contents themselves beforehand.
605
- *
606
- * @throws on a schema failure of the YAML (validated first via the loader).
607
- */
608
- async importFromYaml(yamlContent, opts = {}) {
609
- const catalog = loadPlanCatalogFromString(yamlContent, {
610
- source: opts.source ?? "http-import",
611
- crossFieldChecks: opts.crossFieldChecks ?? true
612
- });
613
- return this.importCatalog(catalog);
614
- }
615
- async importCatalog(catalog) {
616
- const report = {
617
- plansCreated: 0,
618
- plansSkipped: 0,
619
- planVersionsCreated: 0,
620
- planVersionsSkipped: 0,
621
- featureEntriesCreated: 0,
622
- featureEntriesSkipped: 0,
623
- warnings: []
624
- };
625
- for (const feature of catalog.features ?? []) {
626
- const result = await this.sink.upsertFeatureCatalogEntry({
627
- projectKey: catalog.projectKey,
628
- featureKey: feature.key,
629
- label: feature.label,
630
- icon: feature.icon,
631
- tier: feature.tier,
632
- plannedOnly: feature.plannedOnly
633
- });
634
- if (result.created) report.featureEntriesCreated++;
635
- else report.featureEntriesSkipped++;
636
- }
637
- for (const plan of catalog.plans ?? []) {
638
- const planResult = await this.sink.upsertPlan({
639
- projectKey: catalog.projectKey,
640
- planKey: plan.id,
641
- label: plan.name ?? plan.id,
642
- description: plan.tagline ?? null
643
- });
644
- if (planResult.created) report.plansCreated++;
645
- else report.plansSkipped++;
646
- if (plan.monthlyNet === null || plan.monthlyNet === void 0) {
647
- report.warnings.push(`Plan '${plan.id}' has no monthlyNet \u2014 skipped (on-request plans need a manual plan version).`);
648
- continue;
649
- }
650
- const versionResult = await this.sink.upsertPlanVersion({
651
- planKey: plan.id,
652
- version: 1,
653
- features: plan.features,
654
- quotas: plan.quotas,
655
- monthlyNet: plan.monthlyNet.toFixed(2),
656
- yearlyNet: (plan.yearlyNet ?? plan.monthlyNet * 10).toFixed(2),
657
- marketed: plan.marketed ?? true,
658
- publish: true,
659
- changeNote: IMPORT_CHANGE_NOTE
660
- });
661
- if (versionResult.created) report.planVersionsCreated++;
662
- else report.planVersionsSkipped++;
663
- }
664
- return report;
665
- }
666
- };
667
- PlanCatalogImporterService = _ts_decorate4([
668
- Injectable3(),
669
- _ts_param3(0, Inject3(PLAN_CATALOG_IMPORT_SINK_TOKEN)),
670
- _ts_metadata3("design:type", Function),
671
- _ts_metadata3("design:paramtypes", [
672
- typeof PlanCatalogImportSink === "undefined" ? Object : PlanCatalogImportSink
673
- ])
674
- ], PlanCatalogImporterService);
675
-
676
- // src/billing/plan-catalog-importer.module.ts
677
- import { Module } from "@nestjs/common";
678
-
679
- // src/billing/plan-catalog-importer.controller.ts
680
- import { Body, Controller, Inject as Inject4, Post, UseGuards } from "@nestjs/common";
681
- import { IsBoolean, IsOptional, IsString, MinLength } from "class-validator";
682
- function _ts_decorate5(decorators, target, key, desc) {
683
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
684
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
685
- 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;
686
- return c > 3 && r && Object.defineProperty(target, key, r), r;
687
- }
688
- __name(_ts_decorate5, "_ts_decorate");
689
- function _ts_metadata4(k, v) {
690
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
691
- }
692
- __name(_ts_metadata4, "_ts_metadata");
693
- function _ts_param4(paramIndex, decorator) {
694
- return function(target, key) {
695
- decorator(target, key, paramIndex);
696
- };
697
- }
698
- __name(_ts_param4, "_ts_param");
699
- var PlanCatalogImportDto = class {
700
- static {
701
- __name(this, "PlanCatalogImportDto");
702
- }
703
- yamlContent;
704
- crossFieldChecks;
705
- };
706
- _ts_decorate5([
707
- IsString(),
708
- MinLength(1),
709
- _ts_metadata4("design:type", String)
710
- ], PlanCatalogImportDto.prototype, "yamlContent", void 0);
711
- _ts_decorate5([
712
- IsOptional(),
713
- IsBoolean(),
714
- _ts_metadata4("design:type", Boolean)
715
- ], PlanCatalogImportDto.prototype, "crossFieldChecks", void 0);
716
- function buildPlanCatalogImporterController(guards) {
717
- let GeneratedPlanCatalogImporterController = class GeneratedPlanCatalogImporterController {
718
- static {
719
- __name(this, "GeneratedPlanCatalogImporterController");
720
- }
721
- service;
722
- constructor(service) {
723
- this.service = service;
724
- }
725
- async import(dto) {
726
- return this.service.importFromYaml(dto.yamlContent, {
727
- crossFieldChecks: dto.crossFieldChecks
728
- });
729
- }
730
- };
731
- _ts_decorate5([
732
- Post("import"),
733
- _ts_param4(0, Body()),
734
- _ts_metadata4("design:type", Function),
735
- _ts_metadata4("design:paramtypes", [
736
- typeof PlanCatalogImportDto === "undefined" ? Object : PlanCatalogImportDto
737
- ]),
738
- _ts_metadata4("design:returntype", Promise)
739
- ], GeneratedPlanCatalogImporterController.prototype, "import", null);
740
- GeneratedPlanCatalogImporterController = _ts_decorate5([
741
- Controller("admin/billing/plan-catalog"),
742
- UseGuards(...guards),
743
- _ts_param4(0, Inject4(PlanCatalogImporterService)),
744
- _ts_metadata4("design:type", Function),
745
- _ts_metadata4("design:paramtypes", [
746
- typeof PlanCatalogImporterService === "undefined" ? Object : PlanCatalogImporterService
747
- ])
748
- ], GeneratedPlanCatalogImporterController);
749
- return GeneratedPlanCatalogImporterController;
750
- }
751
- __name(buildPlanCatalogImporterController, "buildPlanCatalogImporterController");
752
-
753
- // src/billing/plan-catalog-importer.module.ts
754
- function _ts_decorate6(decorators, target, key, desc) {
755
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
756
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
757
- 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;
758
- return c > 3 && r && Object.defineProperty(target, key, r), r;
759
- }
760
- __name(_ts_decorate6, "_ts_decorate");
761
- var PlanCatalogImporterModule = class _PlanCatalogImporterModule {
762
- static {
763
- __name(this, "PlanCatalogImporterModule");
764
- }
765
- static forRoot(options) {
766
- const providers = [
767
- ...options.extraProviders ?? [],
768
- asProvider(PLAN_CATALOG_IMPORT_SINK_TOKEN, options.sink),
769
- PlanCatalogImporterService
770
- ];
771
- const controllers = [];
772
- if (options.controller) {
773
- controllers.push(buildPlanCatalogImporterController(options.controller.guards));
774
- }
775
- return {
776
- module: _PlanCatalogImporterModule,
777
- global: options.global ?? false,
778
- imports: options.imports ?? [],
779
- controllers,
780
- providers,
781
- exports: [
782
- PlanCatalogImporterService
783
- ]
784
- };
785
- }
786
- };
787
- PlanCatalogImporterModule = _ts_decorate6([
788
- Module({})
789
- ], PlanCatalogImporterModule);
790
-
791
115
  // src/billing/feature-ui-registry.tokens.ts
792
116
  var FEATURE_UI_REGISTRY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/FeatureUiRegistry");
793
117
 
794
118
  // src/billing/public-catalog.controller.ts
795
- import { Controller as Controller2, Get, Inject as Inject5, Optional as Optional3, Query } from "@nestjs/common";
796
- import { buildFeatureRequiresIndex as buildFeatureRequiresIndex2, collectUnsatisfiedRequires as collectUnsatisfiedRequires2 } from "@saasicat/types";
797
- function _ts_decorate7(decorators, target, key, desc) {
119
+ import { Controller, Get, Inject, Optional, Query } from "@nestjs/common";
120
+ import { buildFeatureRequiresIndex, collectUnsatisfiedRequires } from "@saasicat/types";
121
+ function _ts_decorate(decorators, target, key, desc) {
798
122
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
799
123
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
800
124
  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;
801
125
  return c > 3 && r && Object.defineProperty(target, key, r), r;
802
126
  }
803
- __name(_ts_decorate7, "_ts_decorate");
804
- function _ts_metadata5(k, v) {
127
+ __name(_ts_decorate, "_ts_decorate");
128
+ function _ts_metadata(k, v) {
805
129
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
806
130
  }
807
- __name(_ts_metadata5, "_ts_metadata");
808
- function _ts_param5(paramIndex, decorator) {
131
+ __name(_ts_metadata, "_ts_metadata");
132
+ function _ts_param(paramIndex, decorator) {
809
133
  return function(target, key) {
810
134
  decorator(target, key, paramIndex);
811
135
  };
812
136
  }
813
- __name(_ts_param5, "_ts_param");
137
+ __name(_ts_param, "_ts_param");
814
138
  var PublicCatalogController = class {
815
139
  static {
816
140
  __name(this, "PublicCatalogController");
@@ -913,7 +237,7 @@ var PublicCatalogController = class {
913
237
  const rows = await this.catalogEntryRepo.listFeatures({
914
238
  projectKey: this.projectKey
915
239
  });
916
- return buildFeatureRequiresIndex2(rows);
240
+ return buildFeatureRequiresIndex(rows);
917
241
  } catch {
918
242
  return /* @__PURE__ */ new Map();
919
243
  }
@@ -953,54 +277,54 @@ var PublicCatalogController = class {
953
277
  quotas: live.quotas,
954
278
  monthlyNet: live.monthlyNet,
955
279
  yearlyNet: live.yearlyNet,
956
- requiresFeatures: collectUnsatisfiedRequires2(features, requiresIndex),
280
+ requiresFeatures: collectUnsatisfiedRequires(features, requiresIndex),
957
281
  marketing
958
282
  };
959
283
  }
960
284
  };
961
- _ts_decorate7([
285
+ _ts_decorate([
962
286
  Get("plans"),
963
- _ts_param5(0, Query("lang")),
964
- _ts_param5(1, Query("locale")),
965
- _ts_metadata5("design:type", Function),
966
- _ts_metadata5("design:paramtypes", [
287
+ _ts_param(0, Query("lang")),
288
+ _ts_param(1, Query("locale")),
289
+ _ts_metadata("design:type", Function),
290
+ _ts_metadata("design:paramtypes", [
967
291
  String,
968
292
  void 0
969
293
  ]),
970
- _ts_metadata5("design:returntype", Promise)
294
+ _ts_metadata("design:returntype", Promise)
971
295
  ], PublicCatalogController.prototype, "listPlans", null);
972
- _ts_decorate7([
296
+ _ts_decorate([
973
297
  Get("feature-registry"),
974
- _ts_metadata5("design:type", Function),
975
- _ts_metadata5("design:paramtypes", []),
976
- _ts_metadata5("design:returntype", Promise)
298
+ _ts_metadata("design:type", Function),
299
+ _ts_metadata("design:paramtypes", []),
300
+ _ts_metadata("design:returntype", Promise)
977
301
  ], PublicCatalogController.prototype, "listFeatureRegistry", null);
978
- _ts_decorate7([
302
+ _ts_decorate([
979
303
  Get("bundles"),
980
- _ts_param5(0, Query("lang")),
981
- _ts_param5(1, Query("locale")),
982
- _ts_metadata5("design:type", Function),
983
- _ts_metadata5("design:paramtypes", [
304
+ _ts_param(0, Query("lang")),
305
+ _ts_param(1, Query("locale")),
306
+ _ts_metadata("design:type", Function),
307
+ _ts_metadata("design:paramtypes", [
984
308
  String,
985
309
  void 0
986
310
  ]),
987
- _ts_metadata5("design:returntype", Promise)
311
+ _ts_metadata("design:returntype", Promise)
988
312
  ], PublicCatalogController.prototype, "listBundles", null);
989
- PublicCatalogController = _ts_decorate7([
990
- Controller2("billing"),
313
+ PublicCatalogController = _ts_decorate([
314
+ Controller("billing"),
991
315
  SaaSiCatPublicRoute(),
992
- _ts_param5(0, Inject5(PLAN_CATALOG_TOKEN)),
993
- _ts_param5(1, Inject5(FEATURE_UI_REGISTRY_TOKEN)),
994
- _ts_param5(2, Optional3()),
995
- _ts_param5(2, Inject5(PUBLIC_CATALOG_PROJECT_KEY_TOKEN)),
996
- _ts_param5(3, Optional3()),
997
- _ts_param5(3, Inject5(PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN)),
998
- _ts_param5(4, Optional3()),
999
- _ts_param5(4, Inject5(PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN)),
1000
- _ts_param5(5, Optional3()),
1001
- _ts_param5(5, Inject5(PUBLIC_CATALOG_CATALOG_ENTRY_REPOSITORY_TOKEN)),
1002
- _ts_metadata5("design:type", Function),
1003
- _ts_metadata5("design:paramtypes", [
316
+ _ts_param(0, Inject(PLAN_CATALOG_TOKEN)),
317
+ _ts_param(1, Inject(FEATURE_UI_REGISTRY_TOKEN)),
318
+ _ts_param(2, Optional()),
319
+ _ts_param(2, Inject(PUBLIC_CATALOG_PROJECT_KEY_TOKEN)),
320
+ _ts_param(3, Optional()),
321
+ _ts_param(3, Inject(PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN)),
322
+ _ts_param(4, Optional()),
323
+ _ts_param(4, Inject(PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN)),
324
+ _ts_param(5, Optional()),
325
+ _ts_param(5, Inject(PUBLIC_CATALOG_CATALOG_ENTRY_REPOSITORY_TOKEN)),
326
+ _ts_metadata("design:type", Function),
327
+ _ts_metadata("design:paramtypes", [
1004
328
  typeof PlanCatalog === "undefined" ? Object : PlanCatalog,
1005
329
  typeof FeatureUiRegistry === "undefined" ? Object : FeatureUiRegistry,
1006
330
  Object,
@@ -1011,14 +335,14 @@ PublicCatalogController = _ts_decorate7([
1011
335
  ], PublicCatalogController);
1012
336
 
1013
337
  // src/billing/public-catalog.module.ts
1014
- import { Module as Module2 } from "@nestjs/common";
1015
- function _ts_decorate8(decorators, target, key, desc) {
338
+ import { Module } from "@nestjs/common";
339
+ function _ts_decorate2(decorators, target, key, desc) {
1016
340
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1017
341
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1018
342
  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;
1019
343
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1020
344
  }
1021
- __name(_ts_decorate8, "_ts_decorate");
345
+ __name(_ts_decorate2, "_ts_decorate");
1022
346
  var PublicCatalogModule = class _PublicCatalogModule {
1023
347
  static {
1024
348
  __name(this, "PublicCatalogModule");
@@ -1059,30 +383,30 @@ var PublicCatalogModule = class _PublicCatalogModule {
1059
383
  };
1060
384
  }
1061
385
  };
1062
- PublicCatalogModule = _ts_decorate8([
1063
- Module2({})
386
+ PublicCatalogModule = _ts_decorate2([
387
+ Module({})
1064
388
  ], PublicCatalogModule);
1065
389
 
1066
390
  // src/billing/composed-tenant-auth.guard.ts
1067
- import { ForbiddenException as ForbiddenException2, Inject as Inject6, Injectable as Injectable4, Optional as Optional4 } from "@nestjs/common";
1068
- import { AUTH_ERROR_CODES as AUTH_ERROR_CODES2 } from "@saasicat/types";
1069
- function _ts_decorate9(decorators, target, key, desc) {
391
+ import { ForbiddenException, Inject as Inject2, Injectable, Optional as Optional2 } from "@nestjs/common";
392
+ import { AUTH_ERROR_CODES } from "@saasicat/types";
393
+ function _ts_decorate3(decorators, target, key, desc) {
1070
394
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1071
395
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1072
396
  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;
1073
397
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1074
398
  }
1075
- __name(_ts_decorate9, "_ts_decorate");
1076
- function _ts_metadata6(k, v) {
399
+ __name(_ts_decorate3, "_ts_decorate");
400
+ function _ts_metadata2(k, v) {
1077
401
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1078
402
  }
1079
- __name(_ts_metadata6, "_ts_metadata");
1080
- function _ts_param6(paramIndex, decorator) {
403
+ __name(_ts_metadata2, "_ts_metadata");
404
+ function _ts_param2(paramIndex, decorator) {
1081
405
  return function(target, key) {
1082
406
  decorator(target, key, paramIndex);
1083
407
  };
1084
408
  }
1085
- __name(_ts_param6, "_ts_param");
409
+ __name(_ts_param2, "_ts_param");
1086
410
  var ComposedTenantAuthGuard = class {
1087
411
  static {
1088
412
  __name(this, "ComposedTenantAuthGuard");
@@ -1093,8 +417,8 @@ var ComposedTenantAuthGuard = class {
1093
417
  }
1094
418
  async canActivate(context) {
1095
419
  if (!this.guards || this.guards.length === 0) {
1096
- throw new ForbiddenException2({
1097
- code: AUTH_ERROR_CODES2.AUTH_GUARDS_NOT_CONFIGURED,
420
+ throw new ForbiddenException({
421
+ code: AUTH_ERROR_CODES.AUTH_GUARDS_NOT_CONFIGURED,
1098
422
  message: "TenantBillingModule.forRoot.authGuards is not configured."
1099
423
  });
1100
424
  }
@@ -1105,26 +429,26 @@ var ComposedTenantAuthGuard = class {
1105
429
  return true;
1106
430
  }
1107
431
  };
1108
- ComposedTenantAuthGuard = _ts_decorate9([
1109
- Injectable4(),
1110
- _ts_param6(0, Optional4()),
1111
- _ts_param6(0, Inject6(TENANT_AUTH_GUARDS_TOKEN)),
1112
- _ts_metadata6("design:type", Function),
1113
- _ts_metadata6("design:paramtypes", [
432
+ ComposedTenantAuthGuard = _ts_decorate3([
433
+ Injectable(),
434
+ _ts_param2(0, Optional2()),
435
+ _ts_param2(0, Inject2(TENANT_AUTH_GUARDS_TOKEN)),
436
+ _ts_metadata2("design:type", Function),
437
+ _ts_metadata2("design:paramtypes", [
1114
438
  Object
1115
439
  ])
1116
440
  ], ComposedTenantAuthGuard);
1117
441
 
1118
442
  // src/billing/tenant-admin.guard.ts
1119
- import { ForbiddenException as ForbiddenException3, Injectable as Injectable5 } from "@nestjs/common";
1120
- import { AUTH_ERROR_CODES as AUTH_ERROR_CODES3 } from "@saasicat/types";
1121
- function _ts_decorate10(decorators, target, key, desc) {
443
+ import { ForbiddenException as ForbiddenException2, Injectable as Injectable2 } from "@nestjs/common";
444
+ import { AUTH_ERROR_CODES as AUTH_ERROR_CODES2 } from "@saasicat/types";
445
+ function _ts_decorate4(decorators, target, key, desc) {
1122
446
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1123
447
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1124
448
  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;
1125
449
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1126
450
  }
1127
- __name(_ts_decorate10, "_ts_decorate");
451
+ __name(_ts_decorate4, "_ts_decorate");
1128
452
  var ADMIN_ROLES = /* @__PURE__ */ new Set([
1129
453
  "TENANT_ADMIN",
1130
454
  "SUPER_ADMIN"
@@ -1136,23 +460,23 @@ var TenantAdminGuard = class {
1136
460
  canActivate(context) {
1137
461
  const request = context.switchToHttp().getRequest();
1138
462
  if (!request.user) {
1139
- throw new ForbiddenException3({
1140
- code: AUTH_ERROR_CODES3.NOT_AUTHENTICATED,
463
+ throw new ForbiddenException2({
464
+ code: AUTH_ERROR_CODES2.NOT_AUTHENTICATED,
1141
465
  message: "Not authenticated"
1142
466
  });
1143
467
  }
1144
468
  const role = request.user.platformRole ?? request.user.role;
1145
469
  if (!role || !ADMIN_ROLES.has(role)) {
1146
- throw new ForbiddenException3({
1147
- code: AUTH_ERROR_CODES3.TENANT_ADMIN_REQUIRED,
470
+ throw new ForbiddenException2({
471
+ code: AUTH_ERROR_CODES2.TENANT_ADMIN_REQUIRED,
1148
472
  message: "This action requires the TENANT_ADMIN role."
1149
473
  });
1150
474
  }
1151
475
  return true;
1152
476
  }
1153
477
  };
1154
- TenantAdminGuard = _ts_decorate10([
1155
- Injectable5()
478
+ TenantAdminGuard = _ts_decorate4([
479
+ Injectable2()
1156
480
  ], TenantAdminGuard);
1157
481
 
1158
482
  // src/billing/self-service-policy.ts
@@ -1183,25 +507,25 @@ function round2(n) {
1183
507
  __name(round2, "round2");
1184
508
 
1185
509
  // src/billing/plan-change-preview.service.ts
1186
- import { Inject as Inject7, Injectable as Injectable6, NotFoundException, Optional as Optional5 } from "@nestjs/common";
1187
- import { BILLING_ERROR_CODES as BILLING_ERROR_CODES2 } from "@saasicat/types";
1188
- function _ts_decorate11(decorators, target, key, desc) {
510
+ import { Inject as Inject3, Injectable as Injectable3, NotFoundException, Optional as Optional3 } from "@nestjs/common";
511
+ import { BILLING_ERROR_CODES } from "@saasicat/types";
512
+ function _ts_decorate5(decorators, target, key, desc) {
1189
513
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1190
514
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1191
515
  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;
1192
516
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1193
517
  }
1194
- __name(_ts_decorate11, "_ts_decorate");
1195
- function _ts_metadata7(k, v) {
518
+ __name(_ts_decorate5, "_ts_decorate");
519
+ function _ts_metadata3(k, v) {
1196
520
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1197
521
  }
1198
- __name(_ts_metadata7, "_ts_metadata");
1199
- function _ts_param7(paramIndex, decorator) {
522
+ __name(_ts_metadata3, "_ts_metadata");
523
+ function _ts_param3(paramIndex, decorator) {
1200
524
  return function(target, key) {
1201
525
  decorator(target, key, paramIndex);
1202
526
  };
1203
527
  }
1204
- __name(_ts_param7, "_ts_param");
528
+ __name(_ts_param3, "_ts_param");
1205
529
  var PlanChangePreviewService = class {
1206
530
  static {
1207
531
  __name(this, "PlanChangePreviewService");
@@ -1224,7 +548,7 @@ var PlanChangePreviewService = class {
1224
548
  const sub = await this.subscriptions.findForTenant(tenantId);
1225
549
  if (!sub) {
1226
550
  throw new NotFoundException({
1227
- code: BILLING_ERROR_CODES2.SUBSCRIPTION_NOT_FOUND,
551
+ code: BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
1228
552
  message: `No subscription for tenant ${tenantId}`,
1229
553
  params: {
1230
554
  tenantId
@@ -1234,7 +558,7 @@ var PlanChangePreviewService = class {
1234
558
  const targetPlanDef = findPlan(this.catalog, targetPlan);
1235
559
  if (!targetPlanDef) {
1236
560
  throw new NotFoundException({
1237
- code: BILLING_ERROR_CODES2.PLAN_NOT_IN_CATALOG,
561
+ code: BILLING_ERROR_CODES.PLAN_NOT_IN_CATALOG,
1238
562
  message: `Plan "${targetPlan}" is not in the catalog (${this.catalog.projectKey})`,
1239
563
  params: {
1240
564
  planKey: targetPlan,
@@ -1401,18 +725,18 @@ var PlanChangePreviewService = class {
1401
725
  });
1402
726
  }
1403
727
  };
1404
- PlanChangePreviewService = _ts_decorate11([
1405
- Injectable6(),
1406
- _ts_param7(0, Inject7(PLAN_CATALOG_TOKEN)),
1407
- _ts_param7(1, Inject7(ENTITLEMENT_SERVICE_TOKEN)),
1408
- _ts_param7(2, Inject7(SUBSCRIPTION_USAGE_PORT_TOKEN)),
1409
- _ts_param7(3, Inject7(USAGE_SNAPSHOT_PORT_TOKEN)),
1410
- _ts_param7(4, Optional5()),
1411
- _ts_param7(4, Inject7(SELF_SERVICE_BLOCKED_PLANS_TOKEN)),
1412
- _ts_param7(5, Optional5()),
1413
- _ts_param7(5, Inject7(TRIAL_PROJECTION_PORT_TOKEN)),
1414
- _ts_metadata7("design:type", Function),
1415
- _ts_metadata7("design:paramtypes", [
728
+ PlanChangePreviewService = _ts_decorate5([
729
+ Injectable3(),
730
+ _ts_param3(0, Inject3(PLAN_CATALOG_TOKEN)),
731
+ _ts_param3(1, Inject3(ENTITLEMENT_SERVICE_TOKEN)),
732
+ _ts_param3(2, Inject3(SUBSCRIPTION_USAGE_PORT_TOKEN)),
733
+ _ts_param3(3, Inject3(USAGE_SNAPSHOT_PORT_TOKEN)),
734
+ _ts_param3(4, Optional3()),
735
+ _ts_param3(4, Inject3(SELF_SERVICE_BLOCKED_PLANS_TOKEN)),
736
+ _ts_param3(5, Optional3()),
737
+ _ts_param3(5, Inject3(TRIAL_PROJECTION_PORT_TOKEN)),
738
+ _ts_metadata3("design:type", Function),
739
+ _ts_metadata3("design:paramtypes", [
1416
740
  typeof PlanCatalog === "undefined" ? Object : PlanCatalog,
1417
741
  typeof EntitlementService === "undefined" ? Object : EntitlementService,
1418
742
  typeof SubscriptionUsagePort === "undefined" ? Object : SubscriptionUsagePort,
@@ -1430,32 +754,30 @@ function isFloatQuota(key) {
1430
754
  }
1431
755
  __name(isFloatQuota, "isFloatQuota");
1432
756
 
1433
- // src/billing/pending-plan-materialization.service.ts
1434
- import { Inject as Inject8, Injectable as Injectable7, Logger as Logger3, Optional as Optional6 } from "@nestjs/common";
1435
-
1436
757
  // src/billing/contract-freeze.tokens.ts
1437
758
  var CONTRACT_FREEZE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/ContractFreezePort");
1438
759
  var CONTRACT_FREEZE_SOURCE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/ContractFreezeSourcePort");
1439
760
  var CONTRACT_FREEZE_PROJECT_KEY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/ContractFreezeProjectKey");
1440
761
 
1441
762
  // src/billing/pending-plan-materialization.service.ts
1442
- function _ts_decorate12(decorators, target, key, desc) {
763
+ import { Inject as Inject4, Injectable as Injectable4, Logger, Optional as Optional4 } from "@nestjs/common";
764
+ function _ts_decorate6(decorators, target, key, desc) {
1443
765
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1444
766
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1445
767
  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;
1446
768
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1447
769
  }
1448
- __name(_ts_decorate12, "_ts_decorate");
1449
- function _ts_metadata8(k, v) {
770
+ __name(_ts_decorate6, "_ts_decorate");
771
+ function _ts_metadata4(k, v) {
1450
772
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1451
773
  }
1452
- __name(_ts_metadata8, "_ts_metadata");
1453
- function _ts_param8(paramIndex, decorator) {
774
+ __name(_ts_metadata4, "_ts_metadata");
775
+ function _ts_param4(paramIndex, decorator) {
1454
776
  return function(target, key) {
1455
777
  decorator(target, key, paramIndex);
1456
778
  };
1457
779
  }
1458
- __name(_ts_param8, "_ts_param");
780
+ __name(_ts_param4, "_ts_param");
1459
781
  var PendingPlanMaterializationService = class _PendingPlanMaterializationService {
1460
782
  static {
1461
783
  __name(this, "PendingPlanMaterializationService");
@@ -1464,7 +786,7 @@ var PendingPlanMaterializationService = class _PendingPlanMaterializationService
1464
786
  subscriptionWrite;
1465
787
  entitlements;
1466
788
  contractFreeze;
1467
- logger = new Logger3(_PendingPlanMaterializationService.name);
789
+ logger = new Logger(_PendingPlanMaterializationService.name);
1468
790
  constructor(query, subscriptionWrite, entitlements, contractFreeze = null) {
1469
791
  this.query = query;
1470
792
  this.subscriptionWrite = subscriptionWrite;
@@ -1510,14 +832,14 @@ var PendingPlanMaterializationService = class _PendingPlanMaterializationService
1510
832
  }
1511
833
  }
1512
834
  };
1513
- PendingPlanMaterializationService = _ts_decorate12([
1514
- Injectable7(),
1515
- _ts_param8(0, Inject8(PENDING_PLAN_QUERY_PORT_TOKEN)),
1516
- _ts_param8(1, Inject8(SUBSCRIPTION_WRITE_PORT_TOKEN)),
1517
- _ts_param8(3, Optional6()),
1518
- _ts_param8(3, Inject8(CONTRACT_FREEZE_PORT_TOKEN)),
1519
- _ts_metadata8("design:type", Function),
1520
- _ts_metadata8("design:paramtypes", [
835
+ PendingPlanMaterializationService = _ts_decorate6([
836
+ Injectable4(),
837
+ _ts_param4(0, Inject4(PENDING_PLAN_QUERY_PORT_TOKEN)),
838
+ _ts_param4(1, Inject4(SUBSCRIPTION_WRITE_PORT_TOKEN)),
839
+ _ts_param4(3, Optional4()),
840
+ _ts_param4(3, Inject4(CONTRACT_FREEZE_PORT_TOKEN)),
841
+ _ts_metadata4("design:type", Function),
842
+ _ts_metadata4("design:paramtypes", [
1521
843
  typeof PendingPlanQueryPort === "undefined" ? Object : PendingPlanQueryPort,
1522
844
  typeof TenantSubscriptionWritePort === "undefined" ? Object : TenantSubscriptionWritePort,
1523
845
  typeof EntitlementService === "undefined" ? Object : EntitlementService,
@@ -1526,24 +848,24 @@ PendingPlanMaterializationService = _ts_decorate12([
1526
848
  ], PendingPlanMaterializationService);
1527
849
 
1528
850
  // src/billing/subscription-contract-freeze.service.ts
1529
- import { Inject as Inject9, Injectable as Injectable8 } from "@nestjs/common";
1530
- function _ts_decorate13(decorators, target, key, desc) {
851
+ import { Inject as Inject5, Injectable as Injectable5 } from "@nestjs/common";
852
+ function _ts_decorate7(decorators, target, key, desc) {
1531
853
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1532
854
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1533
855
  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;
1534
856
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1535
857
  }
1536
- __name(_ts_decorate13, "_ts_decorate");
1537
- function _ts_metadata9(k, v) {
858
+ __name(_ts_decorate7, "_ts_decorate");
859
+ function _ts_metadata5(k, v) {
1538
860
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1539
861
  }
1540
- __name(_ts_metadata9, "_ts_metadata");
1541
- function _ts_param9(paramIndex, decorator) {
862
+ __name(_ts_metadata5, "_ts_metadata");
863
+ function _ts_param5(paramIndex, decorator) {
1542
864
  return function(target, key) {
1543
865
  decorator(target, key, paramIndex);
1544
866
  };
1545
867
  }
1546
- __name(_ts_param9, "_ts_param");
868
+ __name(_ts_param5, "_ts_param");
1547
869
  var SubscriptionContractFreezeService = class {
1548
870
  static {
1549
871
  __name(this, "SubscriptionContractFreezeService");
@@ -1629,15 +951,15 @@ var SubscriptionContractFreezeService = class {
1629
951
  this.entitlements.invalidateTenant(tenantId);
1630
952
  }
1631
953
  };
1632
- SubscriptionContractFreezeService = _ts_decorate13([
1633
- Injectable8(),
1634
- _ts_param9(0, Inject9(PLAN_CATALOG_TOKEN)),
1635
- _ts_param9(1, Inject9(ENTITLEMENT_SERVICE_TOKEN)),
1636
- _ts_param9(2, Inject9(SubscriptionContractService)),
1637
- _ts_param9(3, Inject9(CONTRACT_FREEZE_PROJECT_KEY_TOKEN)),
1638
- _ts_param9(4, Inject9(CONTRACT_FREEZE_SOURCE_PORT_TOKEN)),
1639
- _ts_metadata9("design:type", Function),
1640
- _ts_metadata9("design:paramtypes", [
954
+ SubscriptionContractFreezeService = _ts_decorate7([
955
+ Injectable5(),
956
+ _ts_param5(0, Inject5(PLAN_CATALOG_TOKEN)),
957
+ _ts_param5(1, Inject5(ENTITLEMENT_SERVICE_TOKEN)),
958
+ _ts_param5(2, Inject5(SubscriptionContractService)),
959
+ _ts_param5(3, Inject5(CONTRACT_FREEZE_PROJECT_KEY_TOKEN)),
960
+ _ts_param5(4, Inject5(CONTRACT_FREEZE_SOURCE_PORT_TOKEN)),
961
+ _ts_metadata5("design:type", Function),
962
+ _ts_metadata5("design:paramtypes", [
1641
963
  typeof PlanCatalog === "undefined" ? Object : PlanCatalog,
1642
964
  typeof EntitlementService === "undefined" ? Object : EntitlementService,
1643
965
  typeof SubscriptionContractService === "undefined" ? Object : SubscriptionContractService,
@@ -1650,29 +972,19 @@ function round22(value) {
1650
972
  }
1651
973
  __name(round22, "round2");
1652
974
 
1653
- // src/billing/trial-carryover.ts
1654
- var MS_PER_DAY = 864e5;
1655
- function computeCarriedTrialEndsAt(currentTrialDays, newTrialDays, currentTrialEndsAt, now) {
1656
- const daysRemaining = Math.max(0, Math.ceil((currentTrialEndsAt.getTime() - now.getTime()) / MS_PER_DAY));
1657
- const usedDays = Math.max(0, currentTrialDays - daysRemaining);
1658
- const newDays = Math.max(0, newTrialDays - usedDays);
1659
- return new Date(now.getTime() + newDays * MS_PER_DAY);
1660
- }
1661
- __name(computeCarriedTrialEndsAt, "computeCarriedTrialEndsAt");
1662
-
1663
975
  // src/billing/dto/tenant-billing.dto.ts
1664
- import { IsBoolean as IsBoolean2, IsOptional as IsOptional2, IsString as IsString2, Matches } from "class-validator";
1665
- function _ts_decorate14(decorators, target, key, desc) {
976
+ import { IsBoolean, IsOptional, IsString, Matches } from "class-validator";
977
+ function _ts_decorate8(decorators, target, key, desc) {
1666
978
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1667
979
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1668
980
  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;
1669
981
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1670
982
  }
1671
- __name(_ts_decorate14, "_ts_decorate");
1672
- function _ts_metadata10(k, v) {
983
+ __name(_ts_decorate8, "_ts_decorate");
984
+ function _ts_metadata6(k, v) {
1673
985
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1674
986
  }
1675
- __name(_ts_metadata10, "_ts_metadata");
987
+ __name(_ts_metadata6, "_ts_metadata");
1676
988
  var PLAN_OR_CYCLE_PATTERN = /^[A-Z][A-Z0-9_]*$/;
1677
989
  var PreviewPlanChangeDto = class {
1678
990
  static {
@@ -1681,19 +993,19 @@ var PreviewPlanChangeDto = class {
1681
993
  plan;
1682
994
  billingCycle;
1683
995
  };
1684
- _ts_decorate14([
1685
- IsString2(),
996
+ _ts_decorate8([
997
+ IsString(),
1686
998
  Matches(PLAN_OR_CYCLE_PATTERN, {
1687
999
  message: "plan must be SCREAMING_SNAKE_CASE"
1688
1000
  }),
1689
- _ts_metadata10("design:type", String)
1001
+ _ts_metadata6("design:type", String)
1690
1002
  ], PreviewPlanChangeDto.prototype, "plan", void 0);
1691
- _ts_decorate14([
1692
- IsString2(),
1003
+ _ts_decorate8([
1004
+ IsString(),
1693
1005
  Matches(PLAN_OR_CYCLE_PATTERN, {
1694
1006
  message: "billingCycle must be SCREAMING_SNAKE_CASE (e.g. MONTHLY, YEARLY)"
1695
1007
  }),
1696
- _ts_metadata10("design:type", String)
1008
+ _ts_metadata6("design:type", String)
1697
1009
  ], PreviewPlanChangeDto.prototype, "billingCycle", void 0);
1698
1010
  var ChangePlanDto = class extends PreviewPlanChangeDto {
1699
1011
  static {
@@ -1702,10 +1014,10 @@ var ChangePlanDto = class extends PreviewPlanChangeDto {
1702
1014
  /** Immediate change (true) vs. change at period end (false/undefined). */
1703
1015
  effectiveImmediately;
1704
1016
  };
1705
- _ts_decorate14([
1706
- IsOptional2(),
1707
- IsBoolean2(),
1708
- _ts_metadata10("design:type", Boolean)
1017
+ _ts_decorate8([
1018
+ IsOptional(),
1019
+ IsBoolean(),
1020
+ _ts_metadata6("design:type", Boolean)
1709
1021
  ], ChangePlanDto.prototype, "effectiveImmediately", void 0);
1710
1022
  var CancelSubscriptionDto = class {
1711
1023
  static {
@@ -1714,25 +1026,25 @@ var CancelSubscriptionDto = class {
1714
1026
  /** true = cancel immediately (status CANCELED). false/undefined = at period end. */
1715
1027
  immediately;
1716
1028
  };
1717
- _ts_decorate14([
1718
- IsOptional2(),
1719
- IsBoolean2(),
1720
- _ts_metadata10("design:type", Boolean)
1029
+ _ts_decorate8([
1030
+ IsOptional(),
1031
+ IsBoolean(),
1032
+ _ts_metadata6("design:type", Boolean)
1721
1033
  ], CancelSubscriptionDto.prototype, "immediately", void 0);
1722
1034
 
1723
1035
  // src/billing/dto/onboarding-subscription.dto.ts
1724
- import { ArrayMaxSize, IsArray, IsOptional as IsOptional3, IsString as IsString3, IsUUID, Matches as Matches2 } from "class-validator";
1725
- function _ts_decorate15(decorators, target, key, desc) {
1036
+ import { ArrayMaxSize, IsArray, IsOptional as IsOptional2, IsString as IsString2, IsUUID, Matches as Matches2 } from "class-validator";
1037
+ function _ts_decorate9(decorators, target, key, desc) {
1726
1038
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1727
1039
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1728
1040
  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;
1729
1041
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1730
1042
  }
1731
- __name(_ts_decorate15, "_ts_decorate");
1732
- function _ts_metadata11(k, v) {
1043
+ __name(_ts_decorate9, "_ts_decorate");
1044
+ function _ts_metadata7(k, v) {
1733
1045
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1734
1046
  }
1735
- __name(_ts_metadata11, "_ts_metadata");
1047
+ __name(_ts_metadata7, "_ts_metadata");
1736
1048
  var PLAN_OR_CYCLE_PATTERN2 = /^[A-Z][A-Z0-9_]*$/;
1737
1049
  var PROMO_CODE_PATTERN = /^[A-Z0-9_-]{4,32}$/i;
1738
1050
  var CompleteOnboardingSubscriptionDto = class {
@@ -1752,62 +1064,58 @@ var CompleteOnboardingSubscriptionDto = class {
1752
1064
  */
1753
1065
  bundleVersionIds;
1754
1066
  };
1755
- _ts_decorate15([
1756
- IsString3(),
1067
+ _ts_decorate9([
1068
+ IsString2(),
1757
1069
  Matches2(PLAN_OR_CYCLE_PATTERN2, {
1758
1070
  message: "plan must be SCREAMING_SNAKE_CASE"
1759
1071
  }),
1760
- _ts_metadata11("design:type", String)
1072
+ _ts_metadata7("design:type", String)
1761
1073
  ], CompleteOnboardingSubscriptionDto.prototype, "plan", void 0);
1762
- _ts_decorate15([
1763
- IsString3(),
1074
+ _ts_decorate9([
1075
+ IsString2(),
1764
1076
  Matches2(PLAN_OR_CYCLE_PATTERN2, {
1765
1077
  message: "billingCycle must be SCREAMING_SNAKE_CASE (e.g. MONTHLY, YEARLY)"
1766
1078
  }),
1767
- _ts_metadata11("design:type", String)
1079
+ _ts_metadata7("design:type", String)
1768
1080
  ], CompleteOnboardingSubscriptionDto.prototype, "billingCycle", void 0);
1769
- _ts_decorate15([
1770
- IsOptional3(),
1771
- IsString3(),
1081
+ _ts_decorate9([
1082
+ IsOptional2(),
1083
+ IsString2(),
1772
1084
  Matches2(PROMO_CODE_PATTERN, {
1773
1085
  message: 'promoCode must consist of A\u2013Z, 0\u20139, "-", "_" (4\u201332 characters)'
1774
1086
  }),
1775
- _ts_metadata11("design:type", String)
1087
+ _ts_metadata7("design:type", String)
1776
1088
  ], CompleteOnboardingSubscriptionDto.prototype, "promoCode", void 0);
1777
- _ts_decorate15([
1778
- IsOptional3(),
1089
+ _ts_decorate9([
1090
+ IsOptional2(),
1779
1091
  IsArray(),
1780
1092
  ArrayMaxSize(10),
1781
1093
  IsUUID("all", {
1782
1094
  each: true
1783
1095
  }),
1784
- _ts_metadata11("design:type", Array)
1096
+ _ts_metadata7("design:type", Array)
1785
1097
  ], CompleteOnboardingSubscriptionDto.prototype, "bundleVersionIds", void 0);
1786
1098
 
1787
- // src/billing/tenant-billing.controller.ts
1788
- import { BadRequestException, Body as Body2, Controller as Controller3, ForbiddenException as ForbiddenException4, Get as Get2, HttpCode, HttpStatus as HttpStatus2, Inject as Inject11, Logger as Logger4, NotFoundException as NotFoundException3, Optional as Optional8, Post as Post2, Req, UseGuards as UseGuards2 } from "@nestjs/common";
1789
- import { AUTH_ERROR_CODES as AUTH_ERROR_CODES4, BILLING_ERROR_CODES as BILLING_ERROR_CODES4 } from "@saasicat/types";
1790
-
1791
1099
  // src/billing/subscription-bundles.service.ts
1792
- import { Inject as Inject10, Injectable as Injectable9, NotFoundException as NotFoundException2, Optional as Optional7, UnprocessableEntityException } from "@nestjs/common";
1793
- import { BILLING_ERROR_CODES as BILLING_ERROR_CODES3, CATALOG_ERROR_CODES } from "@saasicat/types";
1794
- function _ts_decorate16(decorators, target, key, desc) {
1100
+ import { Inject as Inject6, Injectable as Injectable6, NotFoundException as NotFoundException2, Optional as Optional5, UnprocessableEntityException } from "@nestjs/common";
1101
+ import { BILLING_ERROR_CODES as BILLING_ERROR_CODES2, CATALOG_ERROR_CODES } from "@saasicat/types";
1102
+ function _ts_decorate10(decorators, target, key, desc) {
1795
1103
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1796
1104
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1797
1105
  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;
1798
1106
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1799
1107
  }
1800
- __name(_ts_decorate16, "_ts_decorate");
1801
- function _ts_metadata12(k, v) {
1108
+ __name(_ts_decorate10, "_ts_decorate");
1109
+ function _ts_metadata8(k, v) {
1802
1110
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1803
1111
  }
1804
- __name(_ts_metadata12, "_ts_metadata");
1805
- function _ts_param10(paramIndex, decorator) {
1112
+ __name(_ts_metadata8, "_ts_metadata");
1113
+ function _ts_param6(paramIndex, decorator) {
1806
1114
  return function(target, key) {
1807
1115
  decorator(target, key, paramIndex);
1808
1116
  };
1809
1117
  }
1810
- __name(_ts_param10, "_ts_param");
1118
+ __name(_ts_param6, "_ts_param");
1811
1119
  var SubscriptionBundlesService = class {
1812
1120
  static {
1813
1121
  __name(this, "SubscriptionBundlesService");
@@ -1866,7 +1174,7 @@ var SubscriptionBundlesService = class {
1866
1174
  }
1867
1175
  if (this.blockedBundles?.bundleKeys?.includes(bundleVersion.bundleKey)) {
1868
1176
  throw new UnprocessableEntityException({
1869
- code: BILLING_ERROR_CODES3.BUNDLE_NOT_SELF_SERVICE,
1177
+ code: BILLING_ERROR_CODES2.BUNDLE_NOT_SELF_SERVICE,
1870
1178
  message: `Bundle '${bundleVersion.bundleKey}' is only activated via a special contract. Please contact the contract manager.`,
1871
1179
  params: {
1872
1180
  bundleKey: bundleVersion.bundleKey
@@ -1876,7 +1184,7 @@ var SubscriptionBundlesService = class {
1876
1184
  const planIds = bundleVersion.compatibility?.planIds ?? [];
1877
1185
  if (planIds.length > 0 && !planIds.includes(input.currentPlanKey)) {
1878
1186
  throw new UnprocessableEntityException({
1879
- code: BILLING_ERROR_CODES3.BUNDLE_INCOMPATIBLE_WITH_PLAN,
1187
+ code: BILLING_ERROR_CODES2.BUNDLE_INCOMPATIBLE_WITH_PLAN,
1880
1188
  message: `BundleVersion '${input.bundleVersionId}' is not compatible with plan '${input.currentPlanKey}'. Allowed: [${planIds.join(", ")}].`,
1881
1189
  params: {
1882
1190
  bundleVersionId: input.bundleVersionId,
@@ -1888,7 +1196,7 @@ var SubscriptionBundlesService = class {
1888
1196
  const active = await this.repo.listActiveBySubscription(input.subscriptionId);
1889
1197
  if (active.some((b) => b.bundleVersionId === input.bundleVersionId)) {
1890
1198
  throw new UnprocessableEntityException({
1891
- code: BILLING_ERROR_CODES3.BUNDLE_ALREADY_SUBSCRIBED,
1199
+ code: BILLING_ERROR_CODES2.BUNDLE_ALREADY_SUBSCRIBED,
1892
1200
  message: `Subscription '${input.subscriptionId}' has already actively booked this bundle.`,
1893
1201
  params: {
1894
1202
  subscriptionId: input.subscriptionId
@@ -1909,7 +1217,7 @@ var SubscriptionBundlesService = class {
1909
1217
  const existing = await this.repo.findById(input.subscriptionBundleId);
1910
1218
  if (!existing) {
1911
1219
  throw new NotFoundException2({
1912
- code: BILLING_ERROR_CODES3.SUBSCRIPTION_BUNDLE_NOT_FOUND,
1220
+ code: BILLING_ERROR_CODES2.SUBSCRIPTION_BUNDLE_NOT_FOUND,
1913
1221
  message: `SubscriptionBundle '${input.subscriptionBundleId}' not found`,
1914
1222
  params: {
1915
1223
  subscriptionBundleId: input.subscriptionBundleId
@@ -1918,7 +1226,7 @@ var SubscriptionBundlesService = class {
1918
1226
  }
1919
1227
  if (existing.canceledAt !== null) {
1920
1228
  throw new UnprocessableEntityException({
1921
- code: BILLING_ERROR_CODES3.SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED,
1229
+ code: BILLING_ERROR_CODES2.SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED,
1922
1230
  message: `SubscriptionBundle '${input.subscriptionBundleId}' is already cancelled.`,
1923
1231
  params: {
1924
1232
  subscriptionBundleId: input.subscriptionBundleId
@@ -1944,7 +1252,7 @@ var SubscriptionBundlesService = class {
1944
1252
  const existing = await this.repo.findById(subscriptionBundleId);
1945
1253
  if (!existing) {
1946
1254
  throw new NotFoundException2({
1947
- code: BILLING_ERROR_CODES3.SUBSCRIPTION_BUNDLE_NOT_FOUND,
1255
+ code: BILLING_ERROR_CODES2.SUBSCRIPTION_BUNDLE_NOT_FOUND,
1948
1256
  message: `SubscriptionBundle '${subscriptionBundleId}' not found`,
1949
1257
  params: {
1950
1258
  subscriptionBundleId
@@ -1953,7 +1261,7 @@ var SubscriptionBundlesService = class {
1953
1261
  }
1954
1262
  if (existing.canceledAt === null) {
1955
1263
  throw new UnprocessableEntityException({
1956
- code: BILLING_ERROR_CODES3.SUBSCRIPTION_BUNDLE_NOT_CANCELLED,
1264
+ code: BILLING_ERROR_CODES2.SUBSCRIPTION_BUNDLE_NOT_CANCELLED,
1957
1265
  message: `SubscriptionBundle '${subscriptionBundleId}' is not cancelled.`,
1958
1266
  params: {
1959
1267
  subscriptionBundleId
@@ -1962,23 +1270,23 @@ var SubscriptionBundlesService = class {
1962
1270
  }
1963
1271
  if (existing.canceledEffectiveAt !== null && existing.canceledEffectiveAt <= /* @__PURE__ */ new Date()) {
1964
1272
  throw new UnprocessableEntityException({
1965
- code: BILLING_ERROR_CODES3.SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE,
1273
+ code: BILLING_ERROR_CODES2.SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE,
1966
1274
  message: "Cancellation already in effect \u2014 book the bundle again."
1967
1275
  });
1968
1276
  }
1969
1277
  return this.repo.reactivate(subscriptionBundleId);
1970
1278
  }
1971
1279
  };
1972
- SubscriptionBundlesService = _ts_decorate16([
1973
- Injectable9(),
1974
- _ts_param10(0, Inject10(SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN)),
1975
- _ts_param10(1, Inject10(BUNDLE_REPOSITORY_TOKEN)),
1976
- _ts_param10(2, Optional7()),
1977
- _ts_param10(2, Inject10(SUBSCRIPTION_BUNDLE_CONFIG_TOKEN)),
1978
- _ts_param10(3, Optional7()),
1979
- _ts_param10(3, Inject10(SELF_SERVICE_BLOCKED_BUNDLES_TOKEN)),
1980
- _ts_metadata12("design:type", Function),
1981
- _ts_metadata12("design:paramtypes", [
1280
+ SubscriptionBundlesService = _ts_decorate10([
1281
+ Injectable6(),
1282
+ _ts_param6(0, Inject6(SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN)),
1283
+ _ts_param6(1, Inject6(BUNDLE_REPOSITORY_TOKEN)),
1284
+ _ts_param6(2, Optional5()),
1285
+ _ts_param6(2, Inject6(SUBSCRIPTION_BUNDLE_CONFIG_TOKEN)),
1286
+ _ts_param6(3, Optional5()),
1287
+ _ts_param6(3, Inject6(SELF_SERVICE_BLOCKED_BUNDLES_TOKEN)),
1288
+ _ts_metadata8("design:type", Function),
1289
+ _ts_metadata8("design:paramtypes", [
1982
1290
  typeof SubscriptionBundleRepository === "undefined" ? Object : SubscriptionBundleRepository,
1983
1291
  typeof BundleRepository === "undefined" ? Object : BundleRepository,
1984
1292
  typeof SubscriptionBundleConfig === "undefined" ? Object : SubscriptionBundleConfig,
@@ -1999,23 +1307,25 @@ function addMonths(date, months) {
1999
1307
  __name(addMonths, "addMonths");
2000
1308
 
2001
1309
  // src/billing/tenant-billing.controller.ts
2002
- function _ts_decorate17(decorators, target, key, desc) {
1310
+ import { BadRequestException, Body, Controller as Controller2, ForbiddenException as ForbiddenException3, Get as Get2, HttpCode, HttpStatus, Inject as Inject7, Logger as Logger2, NotFoundException as NotFoundException3, Optional as Optional6, Post, Req, UseGuards } from "@nestjs/common";
1311
+ import { AUTH_ERROR_CODES as AUTH_ERROR_CODES3, BILLING_ERROR_CODES as BILLING_ERROR_CODES3 } from "@saasicat/types";
1312
+ function _ts_decorate11(decorators, target, key, desc) {
2003
1313
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2004
1314
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2005
1315
  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;
2006
1316
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2007
1317
  }
2008
- __name(_ts_decorate17, "_ts_decorate");
2009
- function _ts_metadata13(k, v) {
1318
+ __name(_ts_decorate11, "_ts_decorate");
1319
+ function _ts_metadata9(k, v) {
2010
1320
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2011
1321
  }
2012
- __name(_ts_metadata13, "_ts_metadata");
2013
- function _ts_param11(paramIndex, decorator) {
1322
+ __name(_ts_metadata9, "_ts_metadata");
1323
+ function _ts_param7(paramIndex, decorator) {
2014
1324
  return function(target, key) {
2015
1325
  decorator(target, key, paramIndex);
2016
1326
  };
2017
1327
  }
2018
- __name(_ts_param11, "_ts_param");
1328
+ __name(_ts_param7, "_ts_param");
2019
1329
  var TenantBillingController = class _TenantBillingController {
2020
1330
  static {
2021
1331
  __name(this, "TenantBillingController");
@@ -2052,7 +1362,7 @@ var TenantBillingController = class _TenantBillingController {
2052
1362
  this.contractFreeze = contractFreeze;
2053
1363
  this.trialProjection = trialProjection;
2054
1364
  }
2055
- logger = new Logger4(_TenantBillingController.name);
1365
+ logger = new Logger2(_TenantBillingController.name);
2056
1366
  // ---------------------------------------------------------------------
2057
1367
  // Reads (Phase B) — all authenticated tenant users
2058
1368
  // ---------------------------------------------------------------------
@@ -2070,7 +1380,7 @@ var TenantBillingController = class _TenantBillingController {
2070
1380
  ]);
2071
1381
  if (!sub) {
2072
1382
  throw new NotFoundException3({
2073
- code: BILLING_ERROR_CODES4.SUBSCRIPTION_NOT_FOUND,
1383
+ code: BILLING_ERROR_CODES3.SUBSCRIPTION_NOT_FOUND,
2074
1384
  message: `No subscription for tenant ${tenantId}`,
2075
1385
  params: {
2076
1386
  tenantId
@@ -2124,8 +1434,8 @@ var TenantBillingController = class _TenantBillingController {
2124
1434
  const userId = this.requireUserId(req);
2125
1435
  const blockedTargets = this.blockedPlans?.asTarget ?? [];
2126
1436
  if (blockedTargets.includes(dto.plan)) {
2127
- throw new ForbiddenException4({
2128
- code: BILLING_ERROR_CODES4.PLAN_NOT_SELF_SERVICE,
1437
+ throw new ForbiddenException3({
1438
+ code: BILLING_ERROR_CODES3.PLAN_NOT_SELF_SERVICE,
2129
1439
  message: `${dto.plan} is not activated via self-service.`,
2130
1440
  params: {
2131
1441
  planKey: dto.plan
@@ -2135,7 +1445,7 @@ var TenantBillingController = class _TenantBillingController {
2135
1445
  const sub = await this.subscriptionUsage.findForTenant(tenantId);
2136
1446
  if (!sub) {
2137
1447
  throw new NotFoundException3({
2138
- code: BILLING_ERROR_CODES4.SUBSCRIPTION_NOT_FOUND,
1448
+ code: BILLING_ERROR_CODES3.SUBSCRIPTION_NOT_FOUND,
2139
1449
  message: `No subscription for tenant ${tenantId}`,
2140
1450
  params: {
2141
1451
  tenantId
@@ -2145,7 +1455,7 @@ var TenantBillingController = class _TenantBillingController {
2145
1455
  const blockers = await this.planPreview.assertChangeAllowed(tenantId, dto.plan, dto.billingCycle);
2146
1456
  if (blockers.length > 0) {
2147
1457
  throw new BadRequestException({
2148
- code: BILLING_ERROR_CODES4.PLAN_CHANGE_BLOCKED,
1458
+ code: BILLING_ERROR_CODES3.PLAN_CHANGE_BLOCKED,
2149
1459
  message: "Plan change is blocked.",
2150
1460
  blockers
2151
1461
  });
@@ -2216,8 +1526,8 @@ var TenantBillingController = class _TenantBillingController {
2216
1526
  const warnings = [];
2217
1527
  const blockedTargets = this.blockedPlans?.asTarget ?? [];
2218
1528
  if (blockedTargets.includes(dto.plan)) {
2219
- throw new ForbiddenException4({
2220
- code: BILLING_ERROR_CODES4.PLAN_NOT_SELF_SERVICE,
1529
+ throw new ForbiddenException3({
1530
+ code: BILLING_ERROR_CODES3.PLAN_NOT_SELF_SERVICE,
2221
1531
  message: `${dto.plan} is not activated via self-service.`,
2222
1532
  params: {
2223
1533
  planKey: dto.plan
@@ -2227,7 +1537,7 @@ var TenantBillingController = class _TenantBillingController {
2227
1537
  const sub = await this.subscriptionUsage.findForTenant(tenantId);
2228
1538
  if (!sub) {
2229
1539
  throw new NotFoundException3({
2230
- code: BILLING_ERROR_CODES4.SUBSCRIPTION_NOT_FOUND,
1540
+ code: BILLING_ERROR_CODES3.SUBSCRIPTION_NOT_FOUND,
2231
1541
  message: `No subscription for tenant ${tenantId}`,
2232
1542
  params: {
2233
1543
  tenantId
@@ -2237,7 +1547,7 @@ var TenantBillingController = class _TenantBillingController {
2237
1547
  const blockers = await this.planPreview.assertChangeAllowed(tenantId, dto.plan, dto.billingCycle);
2238
1548
  if (blockers.length > 0) {
2239
1549
  throw new BadRequestException({
2240
- code: BILLING_ERROR_CODES4.PLAN_CHANGE_BLOCKED,
1550
+ code: BILLING_ERROR_CODES3.PLAN_CHANGE_BLOCKED,
2241
1551
  message: "Plan change during onboarding is blocked.",
2242
1552
  blockers
2243
1553
  });
@@ -2274,7 +1584,7 @@ var TenantBillingController = class _TenantBillingController {
2274
1584
  } catch (err) {
2275
1585
  const reason = err instanceof Error ? err.message : null;
2276
1586
  throw new BadRequestException({
2277
- code: BILLING_ERROR_CODES4.ONBOARDING_CREATE_FAILED,
1587
+ code: BILLING_ERROR_CODES3.ONBOARDING_CREATE_FAILED,
2278
1588
  message: reason ? `Onboarding creation failed: ${reason}` : "Onboarding creation failed",
2279
1589
  params: {
2280
1590
  reason
@@ -2357,7 +1667,7 @@ var TenantBillingController = class _TenantBillingController {
2357
1667
  const sub = await this.subscriptionUsage.findForTenant(tenantId);
2358
1668
  if (!sub) {
2359
1669
  throw new NotFoundException3({
2360
- code: BILLING_ERROR_CODES4.SUBSCRIPTION_NOT_FOUND,
1670
+ code: BILLING_ERROR_CODES3.SUBSCRIPTION_NOT_FOUND,
2361
1671
  message: `No subscription for tenant ${tenantId}`,
2362
1672
  params: {
2363
1673
  tenantId
@@ -2366,7 +1676,7 @@ var TenantBillingController = class _TenantBillingController {
2366
1676
  }
2367
1677
  if (!sub.pendingPlanVersion) {
2368
1678
  throw new BadRequestException({
2369
- code: BILLING_ERROR_CODES4.NO_PENDING_PLAN_VERSION,
1679
+ code: BILLING_ERROR_CODES3.NO_PENDING_PLAN_VERSION,
2370
1680
  message: "There is no pending plan version awaiting confirmation."
2371
1681
  });
2372
1682
  }
@@ -2414,7 +1724,7 @@ var TenantBillingController = class _TenantBillingController {
2414
1724
  const tenantId = resolver(req);
2415
1725
  if (!tenantId) {
2416
1726
  throw new NotFoundException3({
2417
- code: AUTH_ERROR_CODES4.TENANT_CONTEXT_MISSING,
1727
+ code: AUTH_ERROR_CODES3.TENANT_CONTEXT_MISSING,
2418
1728
  message: "No tenant ID found on the request"
2419
1729
  });
2420
1730
  }
@@ -2425,7 +1735,7 @@ var TenantBillingController = class _TenantBillingController {
2425
1735
  const userId = resolver(req);
2426
1736
  if (!userId) {
2427
1737
  throw new NotFoundException3({
2428
- code: AUTH_ERROR_CODES4.TENANT_CONTEXT_MISSING,
1738
+ code: AUTH_ERROR_CODES3.TENANT_CONTEXT_MISSING,
2429
1739
  message: "No user ID found on the request"
2430
1740
  });
2431
1741
  }
@@ -2507,113 +1817,113 @@ var TenantBillingController = class _TenantBillingController {
2507
1817
  }
2508
1818
  }
2509
1819
  };
2510
- _ts_decorate17([
1820
+ _ts_decorate11([
2511
1821
  Get2("entitlement"),
2512
- _ts_param11(0, Req()),
2513
- _ts_metadata13("design:type", Function),
2514
- _ts_metadata13("design:paramtypes", [
1822
+ _ts_param7(0, Req()),
1823
+ _ts_metadata9("design:type", Function),
1824
+ _ts_metadata9("design:paramtypes", [
2515
1825
  typeof RequestLike === "undefined" ? Object : RequestLike
2516
1826
  ]),
2517
- _ts_metadata13("design:returntype", Promise)
1827
+ _ts_metadata9("design:returntype", Promise)
2518
1828
  ], TenantBillingController.prototype, "getEntitlement", null);
2519
- _ts_decorate17([
1829
+ _ts_decorate11([
2520
1830
  Get2("usage"),
2521
- _ts_param11(0, Req()),
2522
- _ts_metadata13("design:type", Function),
2523
- _ts_metadata13("design:paramtypes", [
1831
+ _ts_param7(0, Req()),
1832
+ _ts_metadata9("design:type", Function),
1833
+ _ts_metadata9("design:paramtypes", [
2524
1834
  typeof RequestLike === "undefined" ? Object : RequestLike
2525
1835
  ]),
2526
- _ts_metadata13("design:returntype", Promise)
1836
+ _ts_metadata9("design:returntype", Promise)
2527
1837
  ], TenantBillingController.prototype, "getUsage", null);
2528
- _ts_decorate17([
2529
- Post2("plan/preview"),
2530
- HttpCode(HttpStatus2.OK),
2531
- UseGuards2(TenantAdminGuard),
2532
- _ts_param11(0, Req()),
2533
- _ts_param11(1, Body2()),
2534
- _ts_metadata13("design:type", Function),
2535
- _ts_metadata13("design:paramtypes", [
1838
+ _ts_decorate11([
1839
+ Post("plan/preview"),
1840
+ HttpCode(HttpStatus.OK),
1841
+ UseGuards(TenantAdminGuard),
1842
+ _ts_param7(0, Req()),
1843
+ _ts_param7(1, Body()),
1844
+ _ts_metadata9("design:type", Function),
1845
+ _ts_metadata9("design:paramtypes", [
2536
1846
  typeof RequestLike === "undefined" ? Object : RequestLike,
2537
1847
  typeof PreviewPlanChangeDto === "undefined" ? Object : PreviewPlanChangeDto
2538
1848
  ]),
2539
- _ts_metadata13("design:returntype", Promise)
1849
+ _ts_metadata9("design:returntype", Promise)
2540
1850
  ], TenantBillingController.prototype, "previewPlanChange", null);
2541
- _ts_decorate17([
2542
- Post2("plan"),
2543
- UseGuards2(TenantAdminGuard),
2544
- _ts_param11(0, Req()),
2545
- _ts_param11(1, Body2()),
2546
- _ts_metadata13("design:type", Function),
2547
- _ts_metadata13("design:paramtypes", [
1851
+ _ts_decorate11([
1852
+ Post("plan"),
1853
+ UseGuards(TenantAdminGuard),
1854
+ _ts_param7(0, Req()),
1855
+ _ts_param7(1, Body()),
1856
+ _ts_metadata9("design:type", Function),
1857
+ _ts_metadata9("design:paramtypes", [
2548
1858
  typeof RequestLike === "undefined" ? Object : RequestLike,
2549
1859
  typeof ChangePlanDto === "undefined" ? Object : ChangePlanDto
2550
1860
  ]),
2551
- _ts_metadata13("design:returntype", Promise)
1861
+ _ts_metadata9("design:returntype", Promise)
2552
1862
  ], TenantBillingController.prototype, "changePlan", null);
2553
- _ts_decorate17([
2554
- Post2("onboarding/initial-subscription"),
2555
- UseGuards2(TenantAdminGuard),
2556
- _ts_param11(0, Req()),
2557
- _ts_param11(1, Body2()),
2558
- _ts_metadata13("design:type", Function),
2559
- _ts_metadata13("design:paramtypes", [
1863
+ _ts_decorate11([
1864
+ Post("onboarding/initial-subscription"),
1865
+ UseGuards(TenantAdminGuard),
1866
+ _ts_param7(0, Req()),
1867
+ _ts_param7(1, Body()),
1868
+ _ts_metadata9("design:type", Function),
1869
+ _ts_metadata9("design:paramtypes", [
2560
1870
  typeof RequestLike === "undefined" ? Object : RequestLike,
2561
1871
  typeof CompleteOnboardingSubscriptionDto === "undefined" ? Object : CompleteOnboardingSubscriptionDto
2562
1872
  ]),
2563
- _ts_metadata13("design:returntype", Promise)
1873
+ _ts_metadata9("design:returntype", Promise)
2564
1874
  ], TenantBillingController.prototype, "completeOnboardingSubscription", null);
2565
- _ts_decorate17([
2566
- Post2("subscription/accept-pending-version"),
2567
- UseGuards2(TenantAdminGuard),
2568
- _ts_param11(0, Req()),
2569
- _ts_metadata13("design:type", Function),
2570
- _ts_metadata13("design:paramtypes", [
1875
+ _ts_decorate11([
1876
+ Post("subscription/accept-pending-version"),
1877
+ UseGuards(TenantAdminGuard),
1878
+ _ts_param7(0, Req()),
1879
+ _ts_metadata9("design:type", Function),
1880
+ _ts_metadata9("design:paramtypes", [
2571
1881
  typeof RequestLike === "undefined" ? Object : RequestLike
2572
1882
  ]),
2573
- _ts_metadata13("design:returntype", Promise)
1883
+ _ts_metadata9("design:returntype", Promise)
2574
1884
  ], TenantBillingController.prototype, "acceptPendingPlanVersion", null);
2575
- _ts_decorate17([
2576
- Post2("cancel"),
2577
- UseGuards2(TenantAdminGuard),
2578
- _ts_param11(0, Req()),
2579
- _ts_param11(1, Body2()),
2580
- _ts_metadata13("design:type", Function),
2581
- _ts_metadata13("design:paramtypes", [
1885
+ _ts_decorate11([
1886
+ Post("cancel"),
1887
+ UseGuards(TenantAdminGuard),
1888
+ _ts_param7(0, Req()),
1889
+ _ts_param7(1, Body()),
1890
+ _ts_metadata9("design:type", Function),
1891
+ _ts_metadata9("design:paramtypes", [
2582
1892
  typeof RequestLike === "undefined" ? Object : RequestLike,
2583
1893
  typeof CancelSubscriptionDto === "undefined" ? Object : CancelSubscriptionDto
2584
1894
  ]),
2585
- _ts_metadata13("design:returntype", Promise)
1895
+ _ts_metadata9("design:returntype", Promise)
2586
1896
  ], TenantBillingController.prototype, "cancelSubscription", null);
2587
- TenantBillingController = _ts_decorate17([
2588
- Controller3("billing"),
2589
- UseGuards2(ComposedTenantAuthGuard),
2590
- _ts_param11(0, Inject11(ENTITLEMENT_SERVICE_TOKEN)),
2591
- _ts_param11(1, Inject11(PlanChangePreviewService)),
2592
- _ts_param11(2, Inject11(SUBSCRIPTION_USAGE_PORT_TOKEN)),
2593
- _ts_param11(3, Inject11(USAGE_SNAPSHOT_PORT_TOKEN)),
2594
- _ts_param11(4, Inject11(SUBSCRIPTION_WRITE_PORT_TOKEN)),
2595
- _ts_param11(5, Optional8()),
2596
- _ts_param11(5, Inject11(TENANT_ID_RESOLVER_TOKEN)),
2597
- _ts_param11(6, Optional8()),
2598
- _ts_param11(6, Inject11(USER_ID_RESOLVER_TOKEN)),
2599
- _ts_param11(7, Optional8()),
2600
- _ts_param11(7, Inject11(SELF_SERVICE_BLOCKED_PLANS_TOKEN)),
2601
- _ts_param11(8, Optional8()),
2602
- _ts_param11(8, Inject11(PromoCodesService)),
2603
- _ts_param11(9, Optional8()),
2604
- _ts_param11(9, Inject11(AdminAuditService)),
2605
- _ts_param11(10, Optional8()),
2606
- _ts_param11(10, Inject11(USER_EMAIL_RESOLVER_TOKEN)),
2607
- _ts_param11(11, Optional8()),
2608
- _ts_param11(11, Inject11(AUDIT_CONTEXT_RESOLVER_TOKEN)),
2609
- _ts_param11(12, Optional8()),
2610
- _ts_param11(12, Inject11(SubscriptionBundlesService)),
2611
- _ts_param11(13, Optional8()),
2612
- _ts_param11(13, Inject11(CONTRACT_FREEZE_PORT_TOKEN)),
2613
- _ts_param11(14, Optional8()),
2614
- _ts_param11(14, Inject11(TRIAL_PROJECTION_PORT_TOKEN)),
2615
- _ts_metadata13("design:type", Function),
2616
- _ts_metadata13("design:paramtypes", [
1897
+ TenantBillingController = _ts_decorate11([
1898
+ Controller2("billing"),
1899
+ UseGuards(ComposedTenantAuthGuard),
1900
+ _ts_param7(0, Inject7(ENTITLEMENT_SERVICE_TOKEN)),
1901
+ _ts_param7(1, Inject7(PlanChangePreviewService)),
1902
+ _ts_param7(2, Inject7(SUBSCRIPTION_USAGE_PORT_TOKEN)),
1903
+ _ts_param7(3, Inject7(USAGE_SNAPSHOT_PORT_TOKEN)),
1904
+ _ts_param7(4, Inject7(SUBSCRIPTION_WRITE_PORT_TOKEN)),
1905
+ _ts_param7(5, Optional6()),
1906
+ _ts_param7(5, Inject7(TENANT_ID_RESOLVER_TOKEN)),
1907
+ _ts_param7(6, Optional6()),
1908
+ _ts_param7(6, Inject7(USER_ID_RESOLVER_TOKEN)),
1909
+ _ts_param7(7, Optional6()),
1910
+ _ts_param7(7, Inject7(SELF_SERVICE_BLOCKED_PLANS_TOKEN)),
1911
+ _ts_param7(8, Optional6()),
1912
+ _ts_param7(8, Inject7(PromoCodesService)),
1913
+ _ts_param7(9, Optional6()),
1914
+ _ts_param7(9, Inject7(AdminAuditService)),
1915
+ _ts_param7(10, Optional6()),
1916
+ _ts_param7(10, Inject7(USER_EMAIL_RESOLVER_TOKEN)),
1917
+ _ts_param7(11, Optional6()),
1918
+ _ts_param7(11, Inject7(AUDIT_CONTEXT_RESOLVER_TOKEN)),
1919
+ _ts_param7(12, Optional6()),
1920
+ _ts_param7(12, Inject7(SubscriptionBundlesService)),
1921
+ _ts_param7(13, Optional6()),
1922
+ _ts_param7(13, Inject7(CONTRACT_FREEZE_PORT_TOKEN)),
1923
+ _ts_param7(14, Optional6()),
1924
+ _ts_param7(14, Inject7(TRIAL_PROJECTION_PORT_TOKEN)),
1925
+ _ts_metadata9("design:type", Function),
1926
+ _ts_metadata9("design:paramtypes", [
2617
1927
  typeof EntitlementService === "undefined" ? Object : EntitlementService,
2618
1928
  typeof PlanChangePreviewService === "undefined" ? Object : PlanChangePreviewService,
2619
1929
  typeof SubscriptionUsagePort === "undefined" ? Object : SubscriptionUsagePort,
@@ -2633,14 +1943,14 @@ TenantBillingController = _ts_decorate17([
2633
1943
  ], TenantBillingController);
2634
1944
 
2635
1945
  // src/billing/tenant-billing.module.ts
2636
- import { Module as Module3 } from "@nestjs/common";
2637
- function _ts_decorate18(decorators, target, key, desc) {
1946
+ import { Module as Module2 } from "@nestjs/common";
1947
+ function _ts_decorate12(decorators, target, key, desc) {
2638
1948
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2639
1949
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2640
1950
  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;
2641
1951
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2642
1952
  }
2643
- __name(_ts_decorate18, "_ts_decorate");
1953
+ __name(_ts_decorate12, "_ts_decorate");
2644
1954
  var TenantBillingModule = class _TenantBillingModule {
2645
1955
  static {
2646
1956
  __name(this, "TenantBillingModule");
@@ -2729,91 +2039,30 @@ var TenantBillingModule = class _TenantBillingModule {
2729
2039
  };
2730
2040
  }
2731
2041
  };
2732
- TenantBillingModule = _ts_decorate18([
2733
- Module3({})
2042
+ TenantBillingModule = _ts_decorate12([
2043
+ Module2({})
2734
2044
  ], TenantBillingModule);
2735
2045
 
2736
- // src/billing/configurator-catalog-builder.ts
2737
- import { Injectable as Injectable10 } from "@nestjs/common";
2738
- function _ts_decorate19(decorators, target, key, desc) {
2739
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2740
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2741
- 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;
2742
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2743
- }
2744
- __name(_ts_decorate19, "_ts_decorate");
2745
- var ConfiguratorCatalogBuilder = class {
2746
- static {
2747
- __name(this, "ConfiguratorCatalogBuilder");
2748
- }
2749
- async build(input) {
2750
- const { sources, marketing } = input;
2751
- const planRows = await sources.listLivePlans();
2752
- const planMarketingByPlanId = new Map(marketing.listPlanMarketing().map((m) => [
2753
- m.planId,
2754
- m
2755
- ]));
2756
- return {
2757
- cycleDiscount: marketing.getCycleDiscount(),
2758
- currency: marketing.getCurrency(),
2759
- vatRate: marketing.getVatRate(),
2760
- models: planRows.filter((row) => row.marketed).map((row) => buildModel(row, planMarketingByPlanId)).filter((m) => m !== null)
2761
- };
2762
- }
2763
- };
2764
- ConfiguratorCatalogBuilder = _ts_decorate19([
2765
- Injectable10()
2766
- ], ConfiguratorCatalogBuilder);
2767
- function buildModel(row, marketing) {
2768
- const m = marketing.get(row.planId);
2769
- if (!m) return null;
2770
- return {
2771
- id: row.planId.toLowerCase(),
2772
- code: m.code,
2773
- name: m.name,
2774
- glyph: m.glyph,
2775
- tagline: m.tagline,
2776
- planId: row.planId,
2777
- monthlyNet: row.monthlyNet,
2778
- yearlyNet: row.yearlyNet,
2779
- tags: m.tags,
2780
- includedFeatureKeys: row.features,
2781
- quotaBase: normalizeQuotas(row.quotas),
2782
- ...m.popular ? {
2783
- popular: true
2784
- } : {}
2785
- };
2786
- }
2787
- __name(buildModel, "buildModel");
2788
- function normalizeQuotas(quotas) {
2789
- const out = {};
2790
- for (const [k, v] of Object.entries(quotas)) {
2791
- out[k] = v === -1 ? Number.MAX_SAFE_INTEGER : v;
2792
- }
2793
- return out;
2794
- }
2795
- __name(normalizeQuotas, "normalizeQuotas");
2796
-
2797
2046
  // src/billing/subscription-bundle-preview.service.ts
2798
- import { Inject as Inject12, Injectable as Injectable11, NotFoundException as NotFoundException4, Optional as Optional9 } from "@nestjs/common";
2799
- import { BILLING_ERROR_CODES as BILLING_ERROR_CODES5, CATALOG_ERROR_CODES as CATALOG_ERROR_CODES2, buildFeatureRequiresIndex as buildFeatureRequiresIndex3, collectUnsatisfiedRequires as collectUnsatisfiedRequires3 } from "@saasicat/types";
2800
- function _ts_decorate20(decorators, target, key, desc) {
2047
+ import { Inject as Inject8, Injectable as Injectable7, NotFoundException as NotFoundException4, Optional as Optional7 } from "@nestjs/common";
2048
+ import { BILLING_ERROR_CODES as BILLING_ERROR_CODES4, CATALOG_ERROR_CODES as CATALOG_ERROR_CODES2, buildFeatureRequiresIndex as buildFeatureRequiresIndex2, collectUnsatisfiedRequires as collectUnsatisfiedRequires2 } from "@saasicat/types";
2049
+ function _ts_decorate13(decorators, target, key, desc) {
2801
2050
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2802
2051
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2803
2052
  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;
2804
2053
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2805
2054
  }
2806
- __name(_ts_decorate20, "_ts_decorate");
2807
- function _ts_metadata14(k, v) {
2055
+ __name(_ts_decorate13, "_ts_decorate");
2056
+ function _ts_metadata10(k, v) {
2808
2057
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2809
2058
  }
2810
- __name(_ts_metadata14, "_ts_metadata");
2811
- function _ts_param12(paramIndex, decorator) {
2059
+ __name(_ts_metadata10, "_ts_metadata");
2060
+ function _ts_param8(paramIndex, decorator) {
2812
2061
  return function(target, key) {
2813
2062
  decorator(target, key, paramIndex);
2814
2063
  };
2815
2064
  }
2816
- __name(_ts_param12, "_ts_param");
2065
+ __name(_ts_param8, "_ts_param");
2817
2066
  var SubscriptionBundlePreviewService = class {
2818
2067
  static {
2819
2068
  __name(this, "SubscriptionBundlePreviewService");
@@ -2895,7 +2144,7 @@ var SubscriptionBundlePreviewService = class {
2895
2144
  const existing = await this.subscriptionBundles.findById(input.subscriptionBundleId);
2896
2145
  if (!existing || existing.subscriptionId !== ctx.subscriptionId) {
2897
2146
  throw new NotFoundException4({
2898
- code: BILLING_ERROR_CODES5.SUBSCRIPTION_BUNDLE_NOT_FOUND,
2147
+ code: BILLING_ERROR_CODES4.SUBSCRIPTION_BUNDLE_NOT_FOUND,
2899
2148
  message: `SubscriptionBundle '${input.subscriptionBundleId}' not found`,
2900
2149
  params: {
2901
2150
  subscriptionBundleId: input.subscriptionBundleId
@@ -2916,7 +2165,7 @@ var SubscriptionBundlePreviewService = class {
2916
2165
  const warnings = [];
2917
2166
  if (existing.canceledAt !== null) {
2918
2167
  blockers.push({
2919
- code: BILLING_ERROR_CODES5.SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED,
2168
+ code: BILLING_ERROR_CODES4.SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED,
2920
2169
  message: "This bundle booking is already cancelled."
2921
2170
  });
2922
2171
  }
@@ -3016,12 +2265,12 @@ var SubscriptionBundlePreviewService = class {
3016
2265
  const entries = await this.catalogEntries.listFeatures({
3017
2266
  projectKey
3018
2267
  });
3019
- const requiresIndex = buildFeatureRequiresIndex3(entries);
2268
+ const requiresIndex = buildFeatureRequiresIndex2(entries);
3020
2269
  const covered = /* @__PURE__ */ new Set([
3021
2270
  ...planFeatures,
3022
2271
  ...activeBundleVersions.flatMap((bv) => bv.features ?? [])
3023
2272
  ]);
3024
- return collectUnsatisfiedRequires3(bundleVersion.features ?? [], requiresIndex).filter((key) => !covered.has(key));
2273
+ return collectUnsatisfiedRequires2(bundleVersion.features ?? [], requiresIndex).filter((key) => !covered.has(key));
3025
2274
  }
3026
2275
  /** `projectKey` lives on the bundle stem, not on the version. */
3027
2276
  async resolveProjectKey(bundleVersion) {
@@ -3029,20 +2278,20 @@ var SubscriptionBundlePreviewService = class {
3029
2278
  return stem?.projectKey ?? null;
3030
2279
  }
3031
2280
  };
3032
- SubscriptionBundlePreviewService = _ts_decorate20([
3033
- Injectable11(),
3034
- _ts_param12(0, Inject12(SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN)),
3035
- _ts_param12(1, Inject12(BUNDLE_REPOSITORY_TOKEN)),
3036
- _ts_param12(2, Optional9()),
3037
- _ts_param12(2, Inject12(PLAN_REPOSITORY_TOKEN)),
3038
- _ts_param12(3, Optional9()),
3039
- _ts_param12(3, Inject12(CATALOG_ENTRY_REPOSITORY_TOKEN)),
3040
- _ts_param12(4, Optional9()),
3041
- _ts_param12(4, Inject12(SELF_SERVICE_BLOCKED_BUNDLES_TOKEN)),
3042
- _ts_param12(5, Optional9()),
3043
- _ts_param12(5, Inject12(SUBSCRIPTION_BUNDLE_CONFIG_TOKEN)),
3044
- _ts_metadata14("design:type", Function),
3045
- _ts_metadata14("design:paramtypes", [
2281
+ SubscriptionBundlePreviewService = _ts_decorate13([
2282
+ Injectable7(),
2283
+ _ts_param8(0, Inject8(SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN)),
2284
+ _ts_param8(1, Inject8(BUNDLE_REPOSITORY_TOKEN)),
2285
+ _ts_param8(2, Optional7()),
2286
+ _ts_param8(2, Inject8(PLAN_REPOSITORY_TOKEN)),
2287
+ _ts_param8(3, Optional7()),
2288
+ _ts_param8(3, Inject8(CATALOG_ENTRY_REPOSITORY_TOKEN)),
2289
+ _ts_param8(4, Optional7()),
2290
+ _ts_param8(4, Inject8(SELF_SERVICE_BLOCKED_BUNDLES_TOKEN)),
2291
+ _ts_param8(5, Optional7()),
2292
+ _ts_param8(5, Inject8(SUBSCRIPTION_BUNDLE_CONFIG_TOKEN)),
2293
+ _ts_metadata10("design:type", Function),
2294
+ _ts_metadata10("design:paramtypes", [
3046
2295
  typeof SubscriptionBundleRepository === "undefined" ? Object : SubscriptionBundleRepository,
3047
2296
  typeof BundleRepository === "undefined" ? Object : BundleRepository,
3048
2297
  Object,
@@ -3075,26 +2324,23 @@ function toSnapshot(bundleVersion) {
3075
2324
  }
3076
2325
  __name(toSnapshot, "toSnapshot");
3077
2326
 
3078
- // src/billing/subscription-bundles.module.ts
3079
- import { Module as Module4 } from "@nestjs/common";
3080
-
3081
2327
  // src/billing/tenant-subscription-bundles.controller.ts
3082
- import { BadRequestException as BadRequestException2, Body as Body3, Controller as Controller4, Delete, Get as Get3, HttpCode as HttpCode2, HttpStatus as HttpStatus3, Inject as Inject13, Logger as Logger5, NotFoundException as NotFoundException5, Optional as Optional10, Param, ParseUUIDPipe, Post as Post3, Req as Req2, UseGuards as UseGuards3 } from "@nestjs/common";
3083
- import { AUTH_ERROR_CODES as AUTH_ERROR_CODES5, BILLING_ERROR_CODES as BILLING_ERROR_CODES6 } from "@saasicat/types";
2328
+ import { BadRequestException as BadRequestException2, Body as Body2, Controller as Controller3, Delete, Get as Get3, HttpCode as HttpCode2, HttpStatus as HttpStatus2, Inject as Inject9, Logger as Logger3, NotFoundException as NotFoundException5, Optional as Optional8, Param, ParseUUIDPipe, Post as Post2, Req as Req2, UseGuards as UseGuards2 } from "@nestjs/common";
2329
+ import { AUTH_ERROR_CODES as AUTH_ERROR_CODES4, BILLING_ERROR_CODES as BILLING_ERROR_CODES5 } from "@saasicat/types";
3084
2330
 
3085
2331
  // src/billing/dto/subscription-bundles.dto.ts
3086
- import { IsInt, IsOptional as IsOptional4, IsUUID as IsUUID2, Matches as Matches3, Max, Min } from "class-validator";
3087
- function _ts_decorate21(decorators, target, key, desc) {
2332
+ import { IsInt, IsOptional as IsOptional3, IsUUID as IsUUID2, Matches as Matches3, Max, Min } from "class-validator";
2333
+ function _ts_decorate14(decorators, target, key, desc) {
3088
2334
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3089
2335
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3090
2336
  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;
3091
2337
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3092
2338
  }
3093
- __name(_ts_decorate21, "_ts_decorate");
3094
- function _ts_metadata15(k, v) {
2339
+ __name(_ts_decorate14, "_ts_decorate");
2340
+ function _ts_metadata11(k, v) {
3095
2341
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3096
2342
  }
3097
- __name(_ts_metadata15, "_ts_metadata");
2343
+ __name(_ts_metadata11, "_ts_metadata");
3098
2344
  var ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}(T.*)?$/;
3099
2345
  var AddSubscriptionBundleDto = class {
3100
2346
  static {
@@ -3108,16 +2354,16 @@ var AddSubscriptionBundleDto = class {
3108
2354
  */
3109
2355
  minimumTermMonths;
3110
2356
  };
3111
- _ts_decorate21([
2357
+ _ts_decorate14([
3112
2358
  IsUUID2(),
3113
- _ts_metadata15("design:type", String)
2359
+ _ts_metadata11("design:type", String)
3114
2360
  ], AddSubscriptionBundleDto.prototype, "bundleVersionId", void 0);
3115
- _ts_decorate21([
3116
- IsOptional4(),
2361
+ _ts_decorate14([
2362
+ IsOptional3(),
3117
2363
  IsInt(),
3118
2364
  Min(0),
3119
2365
  Max(120),
3120
- _ts_metadata15("design:type", Number)
2366
+ _ts_metadata11("design:type", Number)
3121
2367
  ], AddSubscriptionBundleDto.prototype, "minimumTermMonths", void 0);
3122
2368
  var PreviewSubscriptionBundleDto = class {
3123
2369
  static {
@@ -3130,22 +2376,22 @@ var PreviewSubscriptionBundleDto = class {
3130
2376
  /** Add preview only — override analogous to `AddSubscriptionBundleDto`. */
3131
2377
  minimumTermMonths;
3132
2378
  };
3133
- _ts_decorate21([
3134
- IsOptional4(),
2379
+ _ts_decorate14([
2380
+ IsOptional3(),
3135
2381
  IsUUID2(),
3136
- _ts_metadata15("design:type", String)
2382
+ _ts_metadata11("design:type", String)
3137
2383
  ], PreviewSubscriptionBundleDto.prototype, "bundleVersionId", void 0);
3138
- _ts_decorate21([
3139
- IsOptional4(),
2384
+ _ts_decorate14([
2385
+ IsOptional3(),
3140
2386
  IsUUID2(),
3141
- _ts_metadata15("design:type", String)
2387
+ _ts_metadata11("design:type", String)
3142
2388
  ], PreviewSubscriptionBundleDto.prototype, "subscriptionBundleId", void 0);
3143
- _ts_decorate21([
3144
- IsOptional4(),
2389
+ _ts_decorate14([
2390
+ IsOptional3(),
3145
2391
  IsInt(),
3146
2392
  Min(0),
3147
2393
  Max(120),
3148
- _ts_metadata15("design:type", Number)
2394
+ _ts_metadata11("design:type", Number)
3149
2395
  ], PreviewSubscriptionBundleDto.prototype, "minimumTermMonths", void 0);
3150
2396
  var CancelSubscriptionBundleDto = class {
3151
2397
  static {
@@ -3158,32 +2404,32 @@ var CancelSubscriptionBundleDto = class {
3158
2404
  */
3159
2405
  canceledAt;
3160
2406
  };
3161
- _ts_decorate21([
3162
- IsOptional4(),
2407
+ _ts_decorate14([
2408
+ IsOptional3(),
3163
2409
  Matches3(ISO_DATE_PATTERN, {
3164
2410
  message: "canceledAt must be an ISO date (YYYY-MM-DD)"
3165
2411
  }),
3166
- _ts_metadata15("design:type", String)
2412
+ _ts_metadata11("design:type", String)
3167
2413
  ], CancelSubscriptionBundleDto.prototype, "canceledAt", void 0);
3168
2414
 
3169
2415
  // src/billing/tenant-subscription-bundles.controller.ts
3170
- function _ts_decorate22(decorators, target, key, desc) {
2416
+ function _ts_decorate15(decorators, target, key, desc) {
3171
2417
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3172
2418
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3173
2419
  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;
3174
2420
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3175
2421
  }
3176
- __name(_ts_decorate22, "_ts_decorate");
3177
- function _ts_metadata16(k, v) {
2422
+ __name(_ts_decorate15, "_ts_decorate");
2423
+ function _ts_metadata12(k, v) {
3178
2424
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3179
2425
  }
3180
- __name(_ts_metadata16, "_ts_metadata");
3181
- function _ts_param13(paramIndex, decorator) {
2426
+ __name(_ts_metadata12, "_ts_metadata");
2427
+ function _ts_param9(paramIndex, decorator) {
3182
2428
  return function(target, key) {
3183
2429
  decorator(target, key, paramIndex);
3184
2430
  };
3185
2431
  }
3186
- __name(_ts_param13, "_ts_param");
2432
+ __name(_ts_param9, "_ts_param");
3187
2433
  function buildTenantSubscriptionBundlesController(extraGuards = []) {
3188
2434
  let GeneratedTenantSubscriptionBundlesController = class GeneratedTenantSubscriptionBundlesController2 {
3189
2435
  static {
@@ -3194,7 +2440,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3194
2440
  subscriptionUsage;
3195
2441
  tenantIdResolver;
3196
2442
  contractFreeze;
3197
- logger = new Logger5("TenantSubscriptionBundlesController");
2443
+ logger = new Logger3("TenantSubscriptionBundlesController");
3198
2444
  /** Keeps the "no contractFreeze hook" warning to one line per process. */
3199
2445
  static warnedAboutMissingFreeze = false;
3200
2446
  constructor(service, previewService, subscriptionUsage, tenantIdResolver, contractFreeze = null) {
@@ -3226,7 +2472,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3226
2472
  const hasCancel = Boolean(dto.subscriptionBundleId);
3227
2473
  if (hasAdd === hasCancel) {
3228
2474
  throw new BadRequestException2({
3229
- code: BILLING_ERROR_CODES6.BUNDLE_PREVIEW_ARGUMENT_AMBIGUOUS,
2475
+ code: BILLING_ERROR_CODES5.BUNDLE_PREVIEW_ARGUMENT_AMBIGUOUS,
3230
2476
  message: "Exactly one of bundleVersionId (add preview) or subscriptionBundleId (cancel preview) must be given."
3231
2477
  });
3232
2478
  }
@@ -3268,7 +2514,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3268
2514
  }
3269
2515
  requireSubscriptionPk(sub) {
3270
2516
  if (!sub.id) {
3271
- throw new NotFoundException5(codedError(BILLING_ERROR_CODES6.SUBSCRIPTION_PK_MISSING));
2517
+ throw new NotFoundException5(codedError(BILLING_ERROR_CODES5.SUBSCRIPTION_PK_MISSING));
3272
2518
  }
3273
2519
  return sub.id;
3274
2520
  }
@@ -3276,7 +2522,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3276
2522
  const tenantId = this.tenantIdResolver(req);
3277
2523
  if (!tenantId) {
3278
2524
  throw new NotFoundException5({
3279
- code: AUTH_ERROR_CODES5.TENANT_CONTEXT_MISSING,
2525
+ code: AUTH_ERROR_CODES4.TENANT_CONTEXT_MISSING,
3280
2526
  message: "No tenant ID found on the request"
3281
2527
  });
3282
2528
  }
@@ -3286,7 +2532,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3286
2532
  const sub = await this.subscriptionUsage.findForTenant(tenantId);
3287
2533
  if (!sub) {
3288
2534
  throw new NotFoundException5({
3289
- code: BILLING_ERROR_CODES6.SUBSCRIPTION_NOT_FOUND,
2535
+ code: BILLING_ERROR_CODES5.SUBSCRIPTION_NOT_FOUND,
3290
2536
  message: `No subscription for tenant ${tenantId}`,
3291
2537
  params: {
3292
2538
  tenantId
@@ -3314,75 +2560,75 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3314
2560
  }
3315
2561
  }
3316
2562
  };
3317
- _ts_decorate22([
2563
+ _ts_decorate15([
3318
2564
  Get3(),
3319
- _ts_param13(0, Req2()),
3320
- _ts_metadata16("design:type", Function),
3321
- _ts_metadata16("design:paramtypes", [
2565
+ _ts_param9(0, Req2()),
2566
+ _ts_metadata12("design:type", Function),
2567
+ _ts_metadata12("design:paramtypes", [
3322
2568
  typeof RequestLike === "undefined" ? Object : RequestLike
3323
2569
  ]),
3324
- _ts_metadata16("design:returntype", Promise)
2570
+ _ts_metadata12("design:returntype", Promise)
3325
2571
  ], GeneratedTenantSubscriptionBundlesController.prototype, "list", null);
3326
- _ts_decorate22([
3327
- Post3(),
3328
- _ts_param13(0, Req2()),
3329
- _ts_param13(1, Body3()),
3330
- _ts_metadata16("design:type", Function),
3331
- _ts_metadata16("design:paramtypes", [
2572
+ _ts_decorate15([
2573
+ Post2(),
2574
+ _ts_param9(0, Req2()),
2575
+ _ts_param9(1, Body2()),
2576
+ _ts_metadata12("design:type", Function),
2577
+ _ts_metadata12("design:paramtypes", [
3332
2578
  typeof RequestLike === "undefined" ? Object : RequestLike,
3333
2579
  typeof AddSubscriptionBundleDto === "undefined" ? Object : AddSubscriptionBundleDto
3334
2580
  ]),
3335
- _ts_metadata16("design:returntype", Promise)
2581
+ _ts_metadata12("design:returntype", Promise)
3336
2582
  ], GeneratedTenantSubscriptionBundlesController.prototype, "add", null);
3337
- _ts_decorate22([
3338
- Post3("preview"),
3339
- HttpCode2(HttpStatus3.OK),
3340
- _ts_param13(0, Req2()),
3341
- _ts_param13(1, Body3()),
3342
- _ts_metadata16("design:type", Function),
3343
- _ts_metadata16("design:paramtypes", [
2583
+ _ts_decorate15([
2584
+ Post2("preview"),
2585
+ HttpCode2(HttpStatus2.OK),
2586
+ _ts_param9(0, Req2()),
2587
+ _ts_param9(1, Body2()),
2588
+ _ts_metadata12("design:type", Function),
2589
+ _ts_metadata12("design:paramtypes", [
3344
2590
  typeof RequestLike === "undefined" ? Object : RequestLike,
3345
2591
  typeof PreviewSubscriptionBundleDto === "undefined" ? Object : PreviewSubscriptionBundleDto
3346
2592
  ]),
3347
- _ts_metadata16("design:returntype", Promise)
2593
+ _ts_metadata12("design:returntype", Promise)
3348
2594
  ], GeneratedTenantSubscriptionBundlesController.prototype, "preview", null);
3349
- _ts_decorate22([
2595
+ _ts_decorate15([
3350
2596
  Delete(":id"),
3351
- HttpCode2(HttpStatus3.OK),
3352
- _ts_param13(0, Req2()),
3353
- _ts_param13(1, Param("id", new ParseUUIDPipe())),
3354
- _ts_param13(2, Body3()),
3355
- _ts_metadata16("design:type", Function),
3356
- _ts_metadata16("design:paramtypes", [
2597
+ HttpCode2(HttpStatus2.OK),
2598
+ _ts_param9(0, Req2()),
2599
+ _ts_param9(1, Param("id", new ParseUUIDPipe())),
2600
+ _ts_param9(2, Body2()),
2601
+ _ts_metadata12("design:type", Function),
2602
+ _ts_metadata12("design:paramtypes", [
3357
2603
  typeof RequestLike === "undefined" ? Object : RequestLike,
3358
2604
  String,
3359
2605
  typeof CancelSubscriptionBundleDto === "undefined" ? Object : CancelSubscriptionBundleDto
3360
2606
  ]),
3361
- _ts_metadata16("design:returntype", Promise)
2607
+ _ts_metadata12("design:returntype", Promise)
3362
2608
  ], GeneratedTenantSubscriptionBundlesController.prototype, "cancel", null);
3363
- _ts_decorate22([
3364
- Post3(":id/reactivate"),
3365
- HttpCode2(HttpStatus3.OK),
3366
- _ts_param13(0, Req2()),
3367
- _ts_param13(1, Param("id", new ParseUUIDPipe())),
3368
- _ts_metadata16("design:type", Function),
3369
- _ts_metadata16("design:paramtypes", [
2609
+ _ts_decorate15([
2610
+ Post2(":id/reactivate"),
2611
+ HttpCode2(HttpStatus2.OK),
2612
+ _ts_param9(0, Req2()),
2613
+ _ts_param9(1, Param("id", new ParseUUIDPipe())),
2614
+ _ts_metadata12("design:type", Function),
2615
+ _ts_metadata12("design:paramtypes", [
3370
2616
  typeof RequestLike === "undefined" ? Object : RequestLike,
3371
2617
  String
3372
2618
  ]),
3373
- _ts_metadata16("design:returntype", Promise)
2619
+ _ts_metadata12("design:returntype", Promise)
3374
2620
  ], GeneratedTenantSubscriptionBundlesController.prototype, "reactivate", null);
3375
- GeneratedTenantSubscriptionBundlesController = _ts_decorate22([
3376
- Controller4("billing/subscription-bundles"),
3377
- UseGuards3(ComposedTenantAuthGuard, ...extraGuards),
3378
- _ts_param13(0, Inject13(SubscriptionBundlesService)),
3379
- _ts_param13(1, Inject13(SubscriptionBundlePreviewService)),
3380
- _ts_param13(2, Inject13(SUBSCRIPTION_USAGE_PORT_TOKEN)),
3381
- _ts_param13(3, Inject13(TENANT_ID_RESOLVER_TOKEN)),
3382
- _ts_param13(4, Optional10()),
3383
- _ts_param13(4, Inject13(CONTRACT_FREEZE_PORT_TOKEN)),
3384
- _ts_metadata16("design:type", Function),
3385
- _ts_metadata16("design:paramtypes", [
2621
+ GeneratedTenantSubscriptionBundlesController = _ts_decorate15([
2622
+ Controller3("billing/subscription-bundles"),
2623
+ UseGuards2(ComposedTenantAuthGuard, ...extraGuards),
2624
+ _ts_param9(0, Inject9(SubscriptionBundlesService)),
2625
+ _ts_param9(1, Inject9(SubscriptionBundlePreviewService)),
2626
+ _ts_param9(2, Inject9(SUBSCRIPTION_USAGE_PORT_TOKEN)),
2627
+ _ts_param9(3, Inject9(TENANT_ID_RESOLVER_TOKEN)),
2628
+ _ts_param9(4, Optional8()),
2629
+ _ts_param9(4, Inject9(CONTRACT_FREEZE_PORT_TOKEN)),
2630
+ _ts_metadata12("design:type", Function),
2631
+ _ts_metadata12("design:paramtypes", [
3386
2632
  typeof SubscriptionBundlesService === "undefined" ? Object : SubscriptionBundlesService,
3387
2633
  typeof SubscriptionBundlePreviewService === "undefined" ? Object : SubscriptionBundlePreviewService,
3388
2634
  typeof SubscriptionUsagePort === "undefined" ? Object : SubscriptionUsagePort,
@@ -3395,13 +2641,14 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3395
2641
  __name(buildTenantSubscriptionBundlesController, "buildTenantSubscriptionBundlesController");
3396
2642
 
3397
2643
  // src/billing/subscription-bundles.module.ts
3398
- function _ts_decorate23(decorators, target, key, desc) {
2644
+ import { Module as Module3 } from "@nestjs/common";
2645
+ function _ts_decorate16(decorators, target, key, desc) {
3399
2646
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3400
2647
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3401
2648
  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;
3402
2649
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3403
2650
  }
3404
- __name(_ts_decorate23, "_ts_decorate");
2651
+ __name(_ts_decorate16, "_ts_decorate");
3405
2652
  var SubscriptionBundleModule = class _SubscriptionBundleModule {
3406
2653
  static {
3407
2654
  __name(this, "SubscriptionBundleModule");
@@ -3457,43 +2704,22 @@ var SubscriptionBundleModule = class _SubscriptionBundleModule {
3457
2704
  };
3458
2705
  }
3459
2706
  };
3460
- SubscriptionBundleModule = _ts_decorate23([
3461
- Module4({})
2707
+ SubscriptionBundleModule = _ts_decorate16([
2708
+ Module3({})
3462
2709
  ], SubscriptionBundleModule);
3463
2710
 
3464
2711
  export {
3465
2712
  periodEndAfter,
3466
2713
  initialPeriodWindow,
3467
2714
  periodEndWithMinLead,
3468
- PublishValidationError,
3469
- assertChangeNote,
3470
- assertDraftPublishable,
3471
- assertBaseVersionFresh,
3472
- assertOptimisticLockHeld,
3473
- decideRenewal,
3474
- clearPendingPlanVersionFields,
3475
- computeNextPeriod,
3476
2715
  FEATURE_GUARD_MARKER,
3477
2716
  isPlatformFeatureGuard,
3478
2717
  REQUIRE_FEATURE_KEY,
3479
2718
  RequireFeature,
3480
- FEATURE_GUARD_CONFIG_TOKEN,
3481
- UPSELL_OFFER_RESOLVER_TOKEN,
3482
- UPSELL_OFFER_CURRENCY_TOKEN,
3483
- FeatureGuard,
3484
2719
  PUBLIC_CATALOG_PROJECT_KEY_TOKEN,
3485
2720
  PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN,
3486
2721
  PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN,
3487
- CatalogBundleUpsellResolver,
3488
- LimitExceededFilter,
3489
- PlanCatalogValidationError,
3490
- loadPlanCatalogFromFile,
3491
- loadPlanCatalogFromString,
3492
- PLAN_CATALOG_IMPORT_SINK_TOKEN,
3493
- PlanCatalogImporterService,
3494
- PlanCatalogImportDto,
3495
- buildPlanCatalogImporterController,
3496
- PlanCatalogImporterModule,
2722
+ PUBLIC_CATALOG_CATALOG_ENTRY_REPOSITORY_TOKEN,
3497
2723
  FEATURE_UI_REGISTRY_TOKEN,
3498
2724
  PublicCatalogController,
3499
2725
  PublicCatalogModule,
@@ -3508,7 +2734,6 @@ export {
3508
2734
  CONTRACT_FREEZE_PROJECT_KEY_TOKEN,
3509
2735
  PendingPlanMaterializationService,
3510
2736
  SubscriptionContractFreezeService,
3511
- computeCarriedTrialEndsAt,
3512
2737
  PreviewPlanChangeDto,
3513
2738
  ChangePlanDto,
3514
2739
  CancelSubscriptionDto,
@@ -3518,7 +2743,6 @@ export {
3518
2743
  addMonths,
3519
2744
  TenantBillingController,
3520
2745
  TenantBillingModule,
3521
- ConfiguratorCatalogBuilder,
3522
2746
  SubscriptionBundlePreviewService,
3523
2747
  resolveBundlePriceNet,
3524
2748
  buildTenantSubscriptionBundlesController,