@saasicat/nest 0.27.0 → 1.0.0-rc.1

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 (103) hide show
  1. package/README.md +1 -1
  2. package/dist/.build-stamp +1 -0
  3. package/dist/_entries.cjs +460 -460
  4. package/dist/admin/index.d.cts +6 -6
  5. package/dist/admin/index.d.ts +6 -6
  6. package/dist/admin/index.js +3 -3
  7. package/dist/{admin-audit.service-9IqXMlZm.d.cts → admin-audit.service-4P3Djdxk.d.cts} +1 -1
  8. package/dist/{admin-audit.service-9IqXMlZm.d.ts → admin-audit.service-4P3Djdxk.d.ts} +1 -1
  9. package/dist/{admin-resources.module-DGgGSdzN.d.cts → admin-resources.module-CpvzcfCc.d.cts} +2 -2
  10. package/dist/{admin-resources.module-BY5r_1MG.d.ts → admin-resources.module-DF5_Q7RD.d.ts} +2 -2
  11. package/dist/{admin-stats.service-HUZIU448.d.cts → admin-stats.service-DfKupywR.d.cts} +3 -3
  12. package/dist/{admin-stats.service-Db2exT_d.d.ts → admin-stats.service-TYiSUwIR.d.ts} +3 -3
  13. package/dist/{aggregation-DP5zfKbU.d.ts → aggregation-B3CD0v_d.d.cts} +2 -2
  14. package/dist/{aggregation-mZ7WZROK.d.cts → aggregation-BFzW07DE.d.ts} +2 -2
  15. package/dist/billing/index.d.cts +13 -13
  16. package/dist/billing/index.d.ts +13 -13
  17. package/dist/billing/index.js +15 -15
  18. package/dist/catalog/index.d.cts +17 -5
  19. package/dist/catalog/index.d.ts +17 -5
  20. package/dist/catalog/index.js +12 -10
  21. package/dist/{catalog.module-D-_pQDNA.d.cts → catalog.module-BDDO6iwq.d.cts} +1 -1
  22. package/dist/{catalog.module-CQr1FpkI.d.ts → catalog.module-BTnMsE6u.d.ts} +1 -1
  23. package/dist/checkout-offer/index.d.cts +3 -3
  24. package/dist/checkout-offer/index.d.ts +3 -3
  25. package/dist/checkout-offer/index.js +2 -2
  26. package/dist/{checkout-offer.module-Ca3_TieR.d.ts → checkout-offer.module-CMtiQJTT.d.ts} +1 -1
  27. package/dist/{checkout-offer.module-DmlpPevf.d.cts → checkout-offer.module-CVpWrzbe.d.cts} +1 -1
  28. package/dist/{checkout-offer.service-BX51dljL.d.ts → checkout-offer.service-BLOv2HOo.d.cts} +1 -1
  29. package/dist/{checkout-offer.service-BX51dljL.d.cts → checkout-offer.service-BLOv2HOo.d.ts} +1 -1
  30. package/dist/{chunk-EBJJNTW6.js → chunk-57V6ZTI6.js} +1 -1
  31. package/dist/{chunk-37HEKVDH.js → chunk-7TVZI3KY.js} +11 -11
  32. package/dist/chunk-AOQJEYOL.js +20 -0
  33. package/dist/{chunk-3E6ONOMG.js → chunk-AU3OOREM.js} +2 -2
  34. package/dist/{chunk-H4DOTO7S.js → chunk-BGS4CWV2.js} +5 -5
  35. package/dist/{chunk-YYUXKLXK.js → chunk-I7GTA3RX.js} +2 -2
  36. package/dist/{chunk-7ZPFQXHM.js → chunk-IQTQLQD3.js} +5 -5
  37. package/dist/{chunk-CJFAOD7K.js → chunk-KFT5AIIH.js} +2 -2
  38. package/dist/{chunk-XTVAFJ3P.js → chunk-L23MLBEC.js} +7 -7
  39. package/dist/{chunk-SN5UOC43.js → chunk-LTT736P3.js} +15 -15
  40. package/dist/{chunk-WPUVJRIN.js → chunk-N3L3AICU.js} +11 -11
  41. package/dist/{chunk-MJ32VNZD.js → chunk-NARZ2WWK.js} +22 -22
  42. package/dist/{chunk-E56W4U2P.js → chunk-O2J2HDXA.js} +4 -4
  43. package/dist/{chunk-WKVBNTYC.js → chunk-OUDSQ3PU.js} +6 -6
  44. package/dist/{chunk-F4B2NJUZ.js → chunk-PK6C5R7B.js} +15 -15
  45. package/dist/{chunk-L4SUWH5B.js → chunk-QUZU2M33.js} +2 -2
  46. package/dist/{chunk-NYLON2VC.js → chunk-VBRYPU7V.js} +2 -2
  47. package/dist/{chunk-2JTISFUZ.js → chunk-VG2NU3CG.js} +11 -11
  48. package/dist/{chunk-7X5MSAIL.js → chunk-VNADKD5U.js} +23 -23
  49. package/dist/{chunk-UHD6FJBQ.js → chunk-W6YEIY4R.js} +46 -46
  50. package/dist/{chunk-5ZXBXYXU.js → chunk-WXYJHZCN.js} +3 -3
  51. package/dist/{chunk-6WL6VQ7Z.js → chunk-XBYAFEOR.js} +2 -2
  52. package/dist/{chunk-EHKMPP6J.js → chunk-XMA4XYC5.js} +40 -40
  53. package/dist/{chunk-B6IWLV7R.js → chunk-YZPVQUIW.js} +8 -8
  54. package/dist/{define-saasicat-CFxut1VR.d.cts → define-saasicat-B5RmWiD2.d.cts} +8 -8
  55. package/dist/{define-saasicat-3ois8t8s.d.ts → define-saasicat-DN-dRObd.d.ts} +8 -8
  56. package/dist/discovery/index.d.cts +4 -4
  57. package/dist/discovery/index.d.ts +4 -4
  58. package/dist/discovery/index.js +7 -7
  59. package/dist/{discovery.scanner-DLgEvuoy.d.cts → discovery.scanner-9cMqF95o.d.cts} +1 -1
  60. package/dist/{discovery.scanner-DLgEvuoy.d.ts → discovery.scanner-9cMqF95o.d.ts} +1 -1
  61. package/dist/{enforce-quota.interceptor-N80KC34N.d.cts → enforce-quota.interceptor-CnieZsdB.d.cts} +3 -3
  62. package/dist/{enforce-quota.interceptor-CYDNvAQz.d.ts → enforce-quota.interceptor-Cseo35Ki.d.ts} +3 -3
  63. package/dist/entitlement/index.d.cts +4 -4
  64. package/dist/entitlement/index.d.ts +4 -4
  65. package/dist/entitlement/index.js +8 -8
  66. package/dist/index.d.cts +23 -23
  67. package/dist/index.d.ts +23 -23
  68. package/dist/index.js +137 -136
  69. package/dist/{module-options-klrPnWGF.d.cts → module-options-CjeSSaBf.d.cts} +35 -35
  70. package/dist/{module-options-ByJL7FZm.d.ts → module-options-DtcJqwjv.d.ts} +35 -35
  71. package/dist/{plan-resolution-CFCoUkrE.d.cts → plan-resolution-Cgo_TR1H.d.cts} +1 -1
  72. package/dist/{plan-resolution-CFCoUkrE.d.ts → plan-resolution-Cgo_TR1H.d.ts} +1 -1
  73. package/dist/{plan-versions.service-B-YoE4SZ.d.ts → plan-versions.service-DChhbK6h.d.ts} +2 -2
  74. package/dist/{plan-versions.service-_saKzb50.d.cts → plan-versions.service-TPEtbN0r.d.cts} +2 -2
  75. package/dist/platform/index.d.cts +29 -29
  76. package/dist/platform/index.d.ts +29 -29
  77. package/dist/platform/index.js +32 -33
  78. package/dist/promo/index.d.cts +4 -4
  79. package/dist/promo/index.d.ts +4 -4
  80. package/dist/promo/index.js +4 -4
  81. package/dist/{module-BE17XFLg.d.ts → promo.module-BUKcUWDf.d.ts} +2 -2
  82. package/dist/{module-CHMIyWlf.d.cts → promo.module-BY2YHHLn.d.cts} +2 -2
  83. package/dist/{service-D48clObR.d.cts → promo.service-2qFgqF-a.d.cts} +1 -1
  84. package/dist/{service-D48clObR.d.ts → promo.service-2qFgqF-a.d.ts} +1 -1
  85. package/dist/registration/index.d.cts +3 -3
  86. package/dist/registration/index.d.ts +3 -3
  87. package/dist/registration/index.js +2 -2
  88. package/dist/subscription-contract/index.d.cts +3 -3
  89. package/dist/subscription-contract/index.d.ts +3 -3
  90. package/dist/subscription-contract/index.js +3 -3
  91. package/dist/{subscription-contract.module-B2uNvUJL.d.cts → subscription-contract.module-CEK8HS5-.d.cts} +1 -1
  92. package/dist/{subscription-contract.module-edyhBr4n.d.ts → subscription-contract.module-fDFdQ0jm.d.ts} +1 -1
  93. package/dist/{subscription-contract.service--cm47ZJJ.d.cts → subscription-contract.service-hD87MKyg.d.cts} +1 -1
  94. package/dist/{subscription-contract.service--cm47ZJJ.d.ts → subscription-contract.service-hD87MKyg.d.ts} +1 -1
  95. package/dist/{tenant-billing.controller-CAMMdfn1.d.cts → tenant-billing.controller-B6UTheK_.d.cts} +5 -5
  96. package/dist/{tenant-billing.controller-CYYK0CpT.d.ts → tenant-billing.controller-DpgHCT9r.d.ts} +5 -5
  97. package/dist/{tenant-billing.module-BxJS6fX4.d.cts → tenant-billing.module-BznC3XtW.d.cts} +1 -1
  98. package/dist/{tenant-billing.module-B0stLoJn.d.ts → tenant-billing.module-wUbsQSFG.d.ts} +1 -1
  99. package/dist/testing/index.d.cts +19 -19
  100. package/dist/testing/index.d.ts +19 -19
  101. package/dist/testing/index.js +33 -33
  102. package/package.json +5 -5
  103. package/dist/chunk-L4KTQ6CL.js +0 -20
package/dist/_entries.cjs CHANGED
@@ -80,14 +80,14 @@ __export(admin_exports, {
80
80
  buildAdminStatsController: () => buildAdminStatsController
81
81
  });
82
82
 
83
- // src/admin/tokens.ts
84
- var MFA_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/MfaPort");
85
- var AUDIT_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/AuditPort");
86
- var RLS_BYPASS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RlsBypassPort");
83
+ // src/admin/admin.tokens.ts
84
+ var MFA_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/MfaPort");
85
+ var AUDIT_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/AuditPort");
86
+ var RLS_BYPASS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RlsBypassPort");
87
87
 
88
88
  // src/admin/super-admin.guard.ts
89
89
  var import_common = require("@nestjs/common");
90
- var import_types = require("@saasicat/types");
90
+ var import_core = require("@saasicat/core");
91
91
  function _ts_decorate(decorators, target, key, desc) {
92
92
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
93
93
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -103,14 +103,14 @@ var SuperAdminGuard = class {
103
103
  const request = context.switchToHttp().getRequest();
104
104
  if (!request.user) {
105
105
  throw new import_common.ForbiddenException({
106
- code: import_types.AUTH_ERROR_CODES.NOT_AUTHENTICATED,
106
+ code: import_core.AUTH_ERROR_CODES.NOT_AUTHENTICATED,
107
107
  message: "Not authenticated"
108
108
  });
109
109
  }
110
110
  const role = request.user.platformRole ?? request.user.role;
111
111
  if (role !== "SUPER_ADMIN") {
112
112
  throw new import_common.ForbiddenException({
113
- code: import_types.AUTH_ERROR_CODES.SUPER_ADMIN_REQUIRED,
113
+ code: import_core.AUTH_ERROR_CODES.SUPER_ADMIN_REQUIRED,
114
114
  message: "Only the SUPER_ADMIN role is allowed"
115
115
  });
116
116
  }
@@ -123,13 +123,13 @@ SuperAdminGuard = _ts_decorate([
123
123
 
124
124
  // src/admin/mfa.guard.ts
125
125
  var import_common3 = require("@nestjs/common");
126
- var import_core = require("@nestjs/core");
127
- var import_types3 = require("@saasicat/types");
126
+ var import_core3 = require("@nestjs/core");
127
+ var import_core4 = require("@saasicat/core");
128
128
 
129
129
  // src/errors/coded-error.ts
130
- var import_types2 = require("@saasicat/types");
130
+ var import_core2 = require("@saasicat/core");
131
131
  function codedError(code, params) {
132
- const message = (0, import_types2.formatErrorMessage)(import_types2.ERROR_MESSAGES_EN[code], params ?? {});
132
+ const message = (0, import_core2.formatErrorMessage)(import_core2.ERROR_MESSAGES_EN[code], params ?? {});
133
133
  return params ? {
134
134
  code,
135
135
  message,
@@ -141,7 +141,7 @@ function codedError(code, params) {
141
141
  }
142
142
  __name(codedError, "codedError");
143
143
 
144
- // src/admin/mfa.ts
144
+ // src/admin/mfa.service.ts
145
145
  var import_common2 = require("@nestjs/common");
146
146
  var import_otplib = require("otplib");
147
147
  function _ts_decorate2(decorators, target, key, desc) {
@@ -261,7 +261,7 @@ function _ts_param2(paramIndex, decorator) {
261
261
  };
262
262
  }
263
263
  __name(_ts_param2, "_ts_param");
264
- var REQUIRE_MFA_KEY = "saas-platform/require-mfa";
264
+ var REQUIRE_MFA_KEY = "saasicat/nest/require-mfa";
265
265
  var RequireMfa = /* @__PURE__ */ __name(() => (0, import_common3.SetMetadata)(REQUIRE_MFA_KEY, true), "RequireMfa");
266
266
  var MfaGuard = class _MfaGuard {
267
267
  static {
@@ -287,7 +287,7 @@ var MfaGuard = class _MfaGuard {
287
287
  const user = request.user;
288
288
  if (!user) {
289
289
  throw new import_common3.UnauthorizedException({
290
- ...codedError(import_types3.AUTH_ERROR_CODES.NOT_AUTHENTICATED),
290
+ ...codedError(import_core4.AUTH_ERROR_CODES.NOT_AUTHENTICATED),
291
291
  // `reason` is superseded by `code` and will be removed.
292
292
  reason: "NOT_AUTHENTICATED"
293
293
  });
@@ -295,7 +295,7 @@ var MfaGuard = class _MfaGuard {
295
295
  const enabled = await this.mfaService.isEnabled(user.id);
296
296
  if (!enabled) {
297
297
  throw new import_common3.UnauthorizedException({
298
- code: import_types3.AUTH_ERROR_CODES.MFA_NOT_SET_UP,
298
+ code: import_core4.AUTH_ERROR_CODES.MFA_NOT_SET_UP,
299
299
  // `reason` is superseded by `code` and will be removed.
300
300
  reason: "MFA_NOT_SET_UP",
301
301
  message: "Run the MFA setup via the CLI first."
@@ -305,7 +305,7 @@ var MfaGuard = class _MfaGuard {
305
305
  const code = Array.isArray(headerVal) ? headerVal[0] : headerVal;
306
306
  if (!code) {
307
307
  throw new import_common3.UnauthorizedException({
308
- code: import_types3.AUTH_ERROR_CODES.MFA_REQUIRED,
308
+ code: import_core4.AUTH_ERROR_CODES.MFA_REQUIRED,
309
309
  // `reason` is superseded by `code` and will be removed.
310
310
  reason: "MFA_REQUIRED",
311
311
  message: "TOTP code required in the X-Mfa-Code header."
@@ -317,7 +317,7 @@ var MfaGuard = class _MfaGuard {
317
317
  });
318
318
  if (!valid) {
319
319
  throw new import_common3.UnauthorizedException({
320
- code: import_types3.AUTH_ERROR_CODES.MFA_FAILED,
320
+ code: import_core4.AUTH_ERROR_CODES.MFA_FAILED,
321
321
  // `reason` is superseded by `code` and will be removed.
322
322
  reason: "MFA_FAILED",
323
323
  message: "Invalid TOTP code."
@@ -328,10 +328,10 @@ var MfaGuard = class _MfaGuard {
328
328
  };
329
329
  MfaGuard = _ts_decorate3([
330
330
  (0, import_common3.Injectable)(),
331
- _ts_param2(0, (0, import_common3.Inject)(import_core.Reflector)),
331
+ _ts_param2(0, (0, import_common3.Inject)(import_core3.Reflector)),
332
332
  _ts_metadata2("design:type", Function),
333
333
  _ts_metadata2("design:paramtypes", [
334
- typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
334
+ typeof import_core3.Reflector === "undefined" ? Object : import_core3.Reflector,
335
335
  typeof MfaService === "undefined" ? Object : MfaService
336
336
  ])
337
337
  ], MfaGuard);
@@ -455,7 +455,7 @@ AdminBypassRlsInterceptor = _ts_decorate5([
455
455
  ])
456
456
  ], AdminBypassRlsInterceptor);
457
457
 
458
- // src/admin/module.ts
458
+ // src/admin/admin.module.ts
459
459
  var import_common6 = require("@nestjs/common");
460
460
 
461
461
  // src/core/di.ts
@@ -475,7 +475,7 @@ function asProvider(token, impl) {
475
475
  }
476
476
  __name(asProvider, "asProvider");
477
477
 
478
- // src/admin/module.ts
478
+ // src/admin/admin.module.ts
479
479
  function _ts_decorate6(decorators, target, key, desc) {
480
480
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
481
481
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -521,7 +521,7 @@ AdminModule = _ts_decorate6([
521
521
  ], AdminModule);
522
522
 
523
523
  // src/admin/admin-manifest.config.ts
524
- var ADMIN_MANIFEST_CONFIG = /* @__PURE__ */ Symbol.for("saas-platform/AdminManifestConfig");
524
+ var ADMIN_MANIFEST_CONFIG = /* @__PURE__ */ Symbol.for("saasicat/nest/AdminManifestConfig");
525
525
 
526
526
  // src/admin/admin-manifest.service.ts
527
527
  var import_common7 = require("@nestjs/common");
@@ -543,7 +543,7 @@ function _ts_param5(paramIndex, decorator) {
543
543
  };
544
544
  }
545
545
  __name(_ts_param5, "_ts_param");
546
- var PLATFORM_CORE_CONTRIBUTION_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PlatformCoreContribution");
546
+ var PLATFORM_CORE_CONTRIBUTION_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PlatformCoreContribution");
547
547
  var AdminManifestService = class _AdminManifestService {
548
548
  static {
549
549
  __name(this, "AdminManifestService");
@@ -1149,10 +1149,10 @@ AdminManifestModule = _ts_decorate9([
1149
1149
  ], AdminManifestModule);
1150
1150
 
1151
1151
  // src/admin/admin-stats.tokens.ts
1152
- var SUBSCRIPTION_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionStatsPort");
1153
- var PROMO_CODE_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoCodeStatsPort");
1154
- var AUDIT_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/AuditStatsPort");
1155
- var ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/AdminStatsAuditWindowDays");
1152
+ var SUBSCRIPTION_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SubscriptionStatsPort");
1153
+ var PROMO_CODE_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoCodeStatsPort");
1154
+ var AUDIT_STATS_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/AuditStatsPort");
1155
+ var ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/AdminStatsAuditWindowDays");
1156
1156
 
1157
1157
  // src/admin/admin-stats.service.ts
1158
1158
  var import_common11 = require("@nestjs/common");
@@ -1353,7 +1353,7 @@ AdminStatsModule = _ts_decorate12([
1353
1353
  // src/admin/admin-resources.module.ts
1354
1354
  var import_common14 = require("@nestjs/common");
1355
1355
  var import_class_validator = require("class-validator");
1356
- var import_types4 = require("@saasicat/types");
1356
+ var import_core5 = require("@saasicat/core");
1357
1357
  function _ts_decorate13(decorators, target, key, desc) {
1358
1358
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1359
1359
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1371,7 +1371,7 @@ function _ts_param10(paramIndex, decorator) {
1371
1371
  };
1372
1372
  }
1373
1373
  __name(_ts_param10, "_ts_param");
1374
- var ADMIN_RESOURCES_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/AdminResourcesPort");
1374
+ var ADMIN_RESOURCES_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/AdminResourcesPort");
1375
1375
  var SuspendTenantDto = class {
1376
1376
  static {
1377
1377
  __name(this, "SuspendTenantDto");
@@ -1401,7 +1401,7 @@ var AdminResourcesService = class {
1401
1401
  const tenant = await this.resources.getTenantDetail(slug);
1402
1402
  if (!tenant) {
1403
1403
  throw new import_common14.NotFoundException({
1404
- code: import_types4.BILLING_ERROR_CODES.TENANT_NOT_FOUND,
1404
+ code: import_core5.BILLING_ERROR_CODES.TENANT_NOT_FOUND,
1405
1405
  message: `Tenant ${slug} not found`,
1406
1406
  params: {
1407
1407
  slug
@@ -1435,7 +1435,7 @@ var AdminResourcesService = class {
1435
1435
  const result = await this.resources.setTenantActive(slug, active, subscriptionStatus);
1436
1436
  if (!result) {
1437
1437
  throw new import_common14.NotFoundException({
1438
- code: import_types4.BILLING_ERROR_CODES.TENANT_NOT_FOUND,
1438
+ code: import_core5.BILLING_ERROR_CODES.TENANT_NOT_FOUND,
1439
1439
  message: `Tenant ${slug} not found`,
1440
1440
  params: {
1441
1441
  slug
@@ -1621,6 +1621,7 @@ AdminResourcesModule = _ts_decorate13([
1621
1621
  var billing_exports = {};
1622
1622
  __export(billing_exports, {
1623
1623
  AUDIT_CONTEXT_RESOLVER_TOKEN: () => AUDIT_CONTEXT_RESOLVER_TOKEN,
1624
+ BILLING_FEATURE_UI_REGISTRY_TOKEN: () => BILLING_FEATURE_UI_REGISTRY_TOKEN,
1624
1625
  CONTRACT_FREEZE_PORT_TOKEN: () => CONTRACT_FREEZE_PORT_TOKEN,
1625
1626
  CONTRACT_FREEZE_PROJECT_KEY_TOKEN: () => CONTRACT_FREEZE_PROJECT_KEY_TOKEN,
1626
1627
  CONTRACT_FREEZE_SOURCE_PORT_TOKEN: () => CONTRACT_FREEZE_SOURCE_PORT_TOKEN,
@@ -1632,7 +1633,6 @@ __export(billing_exports, {
1632
1633
  ConfiguratorCatalogBuilder: () => ConfiguratorCatalogBuilder,
1633
1634
  FEATURE_GUARD_CONFIG_TOKEN: () => FEATURE_GUARD_CONFIG_TOKEN,
1634
1635
  FEATURE_GUARD_MARKER: () => FEATURE_GUARD_MARKER,
1635
- FEATURE_UI_REGISTRY_TOKEN: () => FEATURE_UI_REGISTRY_TOKEN2,
1636
1636
  FeatureGuard: () => FeatureGuard,
1637
1637
  LimitExceededFilter: () => LimitExceededFilter,
1638
1638
  PENDING_PLAN_QUERY_PORT_TOKEN: () => PENDING_PLAN_QUERY_PORT_TOKEN,
@@ -1684,8 +1684,8 @@ __export(billing_exports, {
1684
1684
  buildPlanCatalogFromSnapshot: () => buildPlanCatalogFromSnapshot,
1685
1685
  buildPlanCatalogImporterController: () => buildPlanCatalogImporterController,
1686
1686
  buildTenantSubscriptionBundlesController: () => buildTenantSubscriptionBundlesController,
1687
- classifyBundleVersionDiff: () => import_types5.classifyBundleVersionDiff,
1688
- classifyPlanDiff: () => import_types5.classifyPlanDiff,
1687
+ classifyBundleVersionDiff: () => import_core6.classifyBundleVersionDiff,
1688
+ classifyPlanDiff: () => import_core6.classifyPlanDiff,
1689
1689
  clearPendingPlanVersionFields: () => clearPendingPlanVersionFields,
1690
1690
  computeCarriedTrialEndsAt: () => computeCarriedTrialEndsAt,
1691
1691
  computeNextPeriod: () => computeNextPeriod,
@@ -1747,7 +1747,7 @@ function periodEndWithMinLead(startedAt, cycle, now, minLeadDays = 42) {
1747
1747
  __name(periodEndWithMinLead, "periodEndWithMinLead");
1748
1748
 
1749
1749
  // src/billing/version-diff.ts
1750
- var import_types5 = require("@saasicat/types");
1750
+ var import_core6 = require("@saasicat/core");
1751
1751
 
1752
1752
  // src/billing/version-publish.ts
1753
1753
  var PublishValidationError = class extends Error {
@@ -1847,26 +1847,26 @@ var REQUIRE_FEATURE_KEY = "require-feature";
1847
1847
  var RequireFeature = /* @__PURE__ */ __name((...features) => (0, import_common15.SetMetadata)(REQUIRE_FEATURE_KEY, features), "RequireFeature");
1848
1848
 
1849
1849
  // src/billing/feature-guard.tokens.ts
1850
- var FEATURE_GUARD_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/FeatureGuardConfig");
1850
+ var FEATURE_GUARD_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/FeatureGuardConfig");
1851
1851
 
1852
1852
  // src/billing/feature.guard.ts
1853
1853
  var import_common18 = require("@nestjs/common");
1854
- var import_core2 = require("@nestjs/core");
1855
- var import_types7 = require("@saasicat/types");
1854
+ var import_core8 = require("@nestjs/core");
1855
+ var import_core9 = require("@saasicat/core");
1856
1856
 
1857
- // src/entitlement/service.ts
1857
+ // src/entitlement/entitlement.service.ts
1858
1858
  var import_common17 = require("@nestjs/common");
1859
- var import_types6 = require("@saasicat/types");
1859
+ var import_core7 = require("@saasicat/core");
1860
1860
 
1861
- // src/catalog/tokens.ts
1862
- var PLAN_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PlanRepository");
1863
- var BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/BundleRepository");
1864
- var MARKETING_PROJECTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/MarketingProjectionRepository");
1865
- var CATALOG_ENTRY_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/CatalogEntryRepository");
1866
- var PROMOTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromotionRepository");
1867
- var MARKETING_SETTINGS_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/MarketingSettingsRepository");
1868
- var CATALOG_SERVICE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/CatalogServiceConfig");
1869
- var FEATURE_UI_REGISTRY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/CatalogFeatureUiRegistry");
1861
+ // src/catalog/catalog.tokens.ts
1862
+ var PLAN_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PlanRepository");
1863
+ var BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/BundleRepository");
1864
+ var MARKETING_PROJECTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/MarketingProjectionRepository");
1865
+ var CATALOG_ENTRY_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/CatalogEntryRepository");
1866
+ var PROMOTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromotionRepository");
1867
+ var MARKETING_SETTINGS_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/MarketingSettingsRepository");
1868
+ var CATALOG_SERVICE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/CatalogServiceConfig");
1869
+ var CATALOG_FEATURE_UI_REGISTRY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/CatalogFeatureUiRegistry");
1870
1870
 
1871
1871
  // src/billing/plan-catalog.module.ts
1872
1872
  var import_common16 = require("@nestjs/common");
@@ -1996,18 +1996,18 @@ PlanCatalogModule = _ts_decorate14([
1996
1996
  ], PlanCatalogModule);
1997
1997
 
1998
1998
  // src/billing/subscription-bundles.tokens.ts
1999
- var SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionBundleRepository");
2000
- var SUBSCRIPTION_BUNDLE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionBundleConfig");
1999
+ var SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SubscriptionBundleRepository");
2000
+ var SUBSCRIPTION_BUNDLE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SubscriptionBundleConfig");
2001
2001
 
2002
- // src/subscription-contract/tokens.ts
2003
- var SUBSCRIPTION_CONTRACT_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionContractRepository");
2002
+ // src/subscription-contract/subscription-contract.tokens.ts
2003
+ var SUBSCRIPTION_CONTRACT_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SubscriptionContractRepository");
2004
2004
 
2005
- // src/discovery/tokens.ts
2005
+ // src/discovery/discovery.tokens.ts
2006
2006
  var IMPLEMENTS_CAPABILITY_KEY = "discovery:implements-capability";
2007
2007
  var REQUIRES_CAPABILITY_KEY = "discovery:requires-capability";
2008
2008
  var DEFINES_QUOTA_KEY = "discovery:defines-quota";
2009
2009
  var ENFORCE_QUOTA_KEY = "discovery:enforce-quota";
2010
- var DISCOVERY_SNAPSHOT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/DiscoverySnapshot");
2010
+ var DISCOVERY_SNAPSHOT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/DiscoverySnapshot");
2011
2011
 
2012
2012
  // src/promo/math.ts
2013
2013
  function round2(n) {
@@ -2354,14 +2354,14 @@ function resolveEntitlementPlan(input, config, now) {
2354
2354
  }
2355
2355
  __name(resolveEntitlementPlan, "resolveEntitlementPlan");
2356
2356
 
2357
- // src/entitlement/tokens.ts
2358
- var ENTITLEMENT_SERVICE_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/EntitlementService");
2359
- var SUBSCRIPTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionRepository");
2360
- var PLAN_VERSION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PlanVersionRepository");
2361
- var TRANSACTION_RUNNER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/TransactionRunner");
2362
- var ENTITLEMENT_RESOLUTION_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/EntitlementResolutionConfig");
2357
+ // src/entitlement/entitlement.tokens.ts
2358
+ var ENTITLEMENT_SERVICE_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/EntitlementService");
2359
+ var SUBSCRIPTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SubscriptionRepository");
2360
+ var PLAN_VERSION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PlanVersionRepository");
2361
+ var TRANSACTION_RUNNER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/TransactionRunner");
2362
+ var ENTITLEMENT_RESOLUTION_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/EntitlementResolutionConfig");
2363
2363
 
2364
- // src/entitlement/service.ts
2364
+ // src/entitlement/entitlement.service.ts
2365
2365
  function _ts_decorate15(decorators, target, key, desc) {
2366
2366
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2367
2367
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -2423,7 +2423,7 @@ var EntitlementService = class {
2423
2423
  const sub = await this.subscriptions.findByTenantId(tenantId);
2424
2424
  if (!sub) {
2425
2425
  throw new import_common17.NotFoundException({
2426
- code: import_types6.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
2426
+ code: import_core7.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
2427
2427
  message: `No subscription for tenant ${tenantId}`,
2428
2428
  params: {
2429
2429
  tenantId
@@ -2524,7 +2524,7 @@ var EntitlementService = class {
2524
2524
  const sub = await this.subscriptions.findByTenantIdLocked(input.tenantId, tx);
2525
2525
  if (!sub) {
2526
2526
  throw new import_common17.NotFoundException({
2527
- code: import_types6.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
2527
+ code: import_core7.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
2528
2528
  message: `No subscription for tenant ${input.tenantId}`,
2529
2529
  params: {
2530
2530
  tenantId: input.tenantId
@@ -2534,7 +2534,7 @@ var EntitlementService = class {
2534
2534
  const limits = await this.deriveLimits(sub, now, tx);
2535
2535
  const max = limits.quotas[input.dimension];
2536
2536
  if (max === void 0) {
2537
- throw new import_common17.InternalServerErrorException(codedError(import_types6.BILLING_ERROR_CODES.QUOTA_DIMENSION_UNKNOWN, {
2537
+ throw new import_common17.InternalServerErrorException(codedError(import_core7.BILLING_ERROR_CODES.QUOTA_DIMENSION_UNKNOWN, {
2538
2538
  dimension: input.dimension,
2539
2539
  projectKey: this.catalog.projectKey
2540
2540
  }));
@@ -2560,7 +2560,7 @@ var EntitlementService = class {
2560
2560
  if (!v) {
2561
2561
  const asOfDate = asOf.toISOString().slice(0, 10);
2562
2562
  throw new import_common17.NotFoundException({
2563
- code: import_types6.BILLING_ERROR_CODES.NO_ACTIVE_PLAN_VERSION,
2563
+ code: import_core7.BILLING_ERROR_CODES.NO_ACTIVE_PLAN_VERSION,
2564
2564
  message: `No plan version for ${planId} active as of ${asOfDate} \u2014 neither the validFrom window is satisfied nor is a latest-live version available.`,
2565
2565
  params: {
2566
2566
  planId,
@@ -2625,8 +2625,8 @@ EntitlementService = _ts_decorate15([
2625
2625
  ], EntitlementService);
2626
2626
 
2627
2627
  // src/billing/upsell.tokens.ts
2628
- var UPSELL_OFFER_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/UpsellOfferResolver");
2629
- var UPSELL_OFFER_CURRENCY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/UpsellOfferCurrency");
2628
+ var UPSELL_OFFER_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/UpsellOfferResolver");
2629
+ var UPSELL_OFFER_CURRENCY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/UpsellOfferCurrency");
2630
2630
 
2631
2631
  // src/billing/feature.guard.ts
2632
2632
  function _ts_decorate16(decorators, target, key, desc) {
@@ -2673,7 +2673,7 @@ var FeatureGuard = class _FeatureGuard {
2673
2673
  const user = request.user;
2674
2674
  if (!user) {
2675
2675
  throw new import_common18.ForbiddenException({
2676
- code: import_types7.AUTH_ERROR_CODES.NOT_AUTHENTICATED,
2676
+ code: import_core9.AUTH_ERROR_CODES.NOT_AUTHENTICATED,
2677
2677
  message: "Not authenticated"
2678
2678
  });
2679
2679
  }
@@ -2682,7 +2682,7 @@ var FeatureGuard = class _FeatureGuard {
2682
2682
  const tenantId = this.config?.tenantIdResolver ? this.config.tenantIdResolver(request) : request.tenantId ?? user.tenantId;
2683
2683
  if (!tenantId) {
2684
2684
  throw new import_common18.ForbiddenException({
2685
- code: import_types7.AUTH_ERROR_CODES.NO_TENANT_ASSIGNED,
2685
+ code: import_core9.AUTH_ERROR_CODES.NO_TENANT_ASSIGNED,
2686
2686
  message: "No tenant assigned"
2687
2687
  });
2688
2688
  }
@@ -2702,7 +2702,7 @@ var FeatureGuard = class _FeatureGuard {
2702
2702
  * empty, the same degradation a failing resolver produces.
2703
2703
  *
2704
2704
  * Deliberately 403 + `code` field instead of 402 — rationale in
2705
- * `@saasicat/types` upsell.types.ts (402 is reserved / inconsistently
2705
+ * `@saasicat/core` upsell.types.ts (402 is reserved / inconsistently
2706
2706
  * supported; SPA interceptors must not treat the 403 as an auth error, the
2707
2707
  * distinction runs through `code`).
2708
2708
  *
@@ -2711,7 +2711,7 @@ var FeatureGuard = class _FeatureGuard {
2711
2711
  */
2712
2712
  async buildNotLicensedException(required, tenantId) {
2713
2713
  const body = {
2714
- code: import_types7.FEATURE_NOT_LICENSED,
2714
+ code: import_core9.FEATURE_NOT_LICENSED,
2715
2715
  featureKey: required[0],
2716
2716
  featureKeys: required,
2717
2717
  offers: this.upsellResolver ? await this.resolveOffersSafe(required, tenantId) : [],
@@ -2734,7 +2734,7 @@ var FeatureGuard = class _FeatureGuard {
2734
2734
  };
2735
2735
  FeatureGuard = _ts_decorate16([
2736
2736
  (0, import_common18.Injectable)(),
2737
- _ts_param12(0, (0, import_common18.Inject)(import_core2.Reflector)),
2737
+ _ts_param12(0, (0, import_common18.Inject)(import_core8.Reflector)),
2738
2738
  _ts_param12(1, (0, import_common18.Inject)(ENTITLEMENT_SERVICE_TOKEN)),
2739
2739
  _ts_param12(2, (0, import_common18.Optional)()),
2740
2740
  _ts_param12(2, (0, import_common18.Inject)(FEATURE_GUARD_CONFIG_TOKEN)),
@@ -2742,7 +2742,7 @@ FeatureGuard = _ts_decorate16([
2742
2742
  _ts_param12(3, (0, import_common18.Inject)(UPSELL_OFFER_RESOLVER_TOKEN)),
2743
2743
  _ts_metadata12("design:type", Function),
2744
2744
  _ts_metadata12("design:paramtypes", [
2745
- typeof import_core2.Reflector === "undefined" ? Object : import_core2.Reflector,
2745
+ typeof import_core8.Reflector === "undefined" ? Object : import_core8.Reflector,
2746
2746
  typeof EntitlementService === "undefined" ? Object : EntitlementService,
2747
2747
  Object,
2748
2748
  Object
@@ -2751,13 +2751,13 @@ FeatureGuard = _ts_decorate16([
2751
2751
 
2752
2752
  // src/billing/catalog-bundle-upsell-resolver.ts
2753
2753
  var import_common19 = require("@nestjs/common");
2754
- var import_types8 = require("@saasicat/types");
2754
+ var import_core10 = require("@saasicat/core");
2755
2755
 
2756
2756
  // src/billing/public-catalog.tokens.ts
2757
- var PUBLIC_CATALOG_PROJECT_KEY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PublicCatalogProjectKey");
2758
- var PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PublicCatalogBundleRepository");
2759
- var PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PublicCatalogMarketingRepository");
2760
- var PUBLIC_CATALOG_CATALOG_ENTRY_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PublicCatalogCatalogEntryRepository");
2757
+ var PUBLIC_CATALOG_PROJECT_KEY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PublicCatalogProjectKey");
2758
+ var PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PublicCatalogBundleRepository");
2759
+ var PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PublicCatalogMarketingRepository");
2760
+ var PUBLIC_CATALOG_CATALOG_ENTRY_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PublicCatalogCatalogEntryRepository");
2761
2761
 
2762
2762
  // src/billing/catalog-bundle-upsell-resolver.ts
2763
2763
  function _ts_decorate17(decorators, target, key, desc) {
@@ -2821,7 +2821,7 @@ var CatalogBundleUpsellResolver = class {
2821
2821
  const rows = await this.catalogEntryRepo.listFeatures({
2822
2822
  projectKey: this.projectKey
2823
2823
  });
2824
- return (0, import_types8.collectUnsatisfiedRequires)(featureKeys, (0, import_types8.buildFeatureRequiresIndex)(rows));
2824
+ return (0, import_core10.collectUnsatisfiedRequires)(featureKeys, (0, import_core10.buildFeatureRequiresIndex)(rows));
2825
2825
  }
2826
2826
  /** Only published-and-live AND marketed — non-marketed bundles are not an offer. */
2827
2827
  async listLiveMarketedBundles() {
@@ -2879,8 +2879,8 @@ __name(compareRankedOffers, "compareRankedOffers");
2879
2879
 
2880
2880
  // src/billing/limit-exceeded.filter.ts
2881
2881
  var import_common20 = require("@nestjs/common");
2882
- var import_core3 = require("@nestjs/core");
2883
- var import_types9 = require("@saasicat/types");
2882
+ var import_core11 = require("@nestjs/core");
2883
+ var import_core12 = require("@saasicat/core");
2884
2884
  function _ts_decorate18(decorators, target, key, desc) {
2885
2885
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2886
2886
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -2888,7 +2888,7 @@ function _ts_decorate18(decorators, target, key, desc) {
2888
2888
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2889
2889
  }
2890
2890
  __name(_ts_decorate18, "_ts_decorate");
2891
- var LimitExceededFilter = class _LimitExceededFilter extends import_core3.BaseExceptionFilter {
2891
+ var LimitExceededFilter = class _LimitExceededFilter extends import_core11.BaseExceptionFilter {
2892
2892
  static {
2893
2893
  __name(this, "LimitExceededFilter");
2894
2894
  }
@@ -2905,10 +2905,10 @@ var LimitExceededFilter = class _LimitExceededFilter extends import_core3.BaseEx
2905
2905
  response.status(import_common20.HttpStatus.PAYMENT_REQUIRED).send({
2906
2906
  statusCode: import_common20.HttpStatus.PAYMENT_REQUIRED,
2907
2907
  error: "PaymentRequired",
2908
- code: import_types9.BILLING_ERROR_CODES.LIMIT_EXCEEDED,
2908
+ code: import_core12.BILLING_ERROR_CODES.LIMIT_EXCEEDED,
2909
2909
  // Deprecated: superseded by `code`, kept until consumers have
2910
2910
  // migrated. Same value, only under the older field name.
2911
- reason: import_types9.BILLING_ERROR_CODES.LIMIT_EXCEEDED,
2911
+ reason: import_core12.BILLING_ERROR_CODES.LIMIT_EXCEEDED,
2912
2912
  dimension: exception.dimension,
2913
2913
  used: exception.used,
2914
2914
  max: exception.max,
@@ -3015,7 +3015,7 @@ function _ts_param14(paramIndex, decorator) {
3015
3015
  };
3016
3016
  }
3017
3017
  __name(_ts_param14, "_ts_param");
3018
- var PLAN_CATALOG_IMPORT_SINK_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PlanCatalogImportSink");
3018
+ var PLAN_CATALOG_IMPORT_SINK_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PlanCatalogImportSink");
3019
3019
  var IMPORT_CHANGE_NOTE = "Initial import from saas.yaml";
3020
3020
  var PlanCatalogImporterService = class {
3021
3021
  static {
@@ -3216,11 +3216,11 @@ PlanCatalogImporterModule = _ts_decorate21([
3216
3216
  ], PlanCatalogImporterModule);
3217
3217
 
3218
3218
  // src/billing/feature-ui-registry.tokens.ts
3219
- var FEATURE_UI_REGISTRY_TOKEN2 = /* @__PURE__ */ Symbol.for("saas-platform/FeatureUiRegistry");
3219
+ var BILLING_FEATURE_UI_REGISTRY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/BillingFeatureUiRegistry");
3220
3220
 
3221
3221
  // src/billing/public-catalog.controller.ts
3222
3222
  var import_common24 = require("@nestjs/common");
3223
- var import_types10 = require("@saasicat/types");
3223
+ var import_core13 = require("@saasicat/core");
3224
3224
  function _ts_decorate22(decorators, target, key, desc) {
3225
3225
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3226
3226
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -3340,7 +3340,7 @@ var PublicCatalogController = class {
3340
3340
  const rows = await this.catalogEntryRepo.listFeatures({
3341
3341
  projectKey: this.projectKey
3342
3342
  });
3343
- return (0, import_types10.buildFeatureRequiresIndex)(rows);
3343
+ return (0, import_core13.buildFeatureRequiresIndex)(rows);
3344
3344
  } catch {
3345
3345
  return /* @__PURE__ */ new Map();
3346
3346
  }
@@ -3380,7 +3380,7 @@ var PublicCatalogController = class {
3380
3380
  quotas: live.quotas,
3381
3381
  monthlyNet: live.monthlyNet,
3382
3382
  yearlyNet: live.yearlyNet,
3383
- requiresFeatures: (0, import_types10.collectUnsatisfiedRequires)(features, requiresIndex),
3383
+ requiresFeatures: (0, import_core13.collectUnsatisfiedRequires)(features, requiresIndex),
3384
3384
  marketing
3385
3385
  };
3386
3386
  }
@@ -3417,7 +3417,7 @@ PublicCatalogController = _ts_decorate22([
3417
3417
  (0, import_common24.Controller)("billing"),
3418
3418
  SaaSiCatPublicRoute(),
3419
3419
  _ts_param16(0, (0, import_common24.Inject)(PLAN_CATALOG_TOKEN)),
3420
- _ts_param16(1, (0, import_common24.Inject)(FEATURE_UI_REGISTRY_TOKEN2)),
3420
+ _ts_param16(1, (0, import_common24.Inject)(BILLING_FEATURE_UI_REGISTRY_TOKEN)),
3421
3421
  _ts_param16(2, (0, import_common24.Optional)()),
3422
3422
  _ts_param16(2, (0, import_common24.Inject)(PUBLIC_CATALOG_PROJECT_KEY_TOKEN)),
3423
3423
  _ts_param16(3, (0, import_common24.Optional)()),
@@ -3454,7 +3454,7 @@ var PublicCatalogModule = class _PublicCatalogModule {
3454
3454
  const providers = [
3455
3455
  ...options.extraProviders ?? [],
3456
3456
  {
3457
- provide: FEATURE_UI_REGISTRY_TOKEN2,
3457
+ provide: BILLING_FEATURE_UI_REGISTRY_TOKEN,
3458
3458
  useValue: options.featureUiRegistry
3459
3459
  }
3460
3460
  ];
@@ -3481,7 +3481,7 @@ var PublicCatalogModule = class _PublicCatalogModule {
3481
3481
  ],
3482
3482
  providers,
3483
3483
  exports: [
3484
- FEATURE_UI_REGISTRY_TOKEN2
3484
+ BILLING_FEATURE_UI_REGISTRY_TOKEN
3485
3485
  ]
3486
3486
  };
3487
3487
  }
@@ -3491,20 +3491,20 @@ PublicCatalogModule = _ts_decorate23([
3491
3491
  ], PublicCatalogModule);
3492
3492
 
3493
3493
  // src/billing/tenant-billing.tokens.ts
3494
- var TENANT_AUTH_GUARDS_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/TenantAuthGuards");
3495
- var TENANT_ID_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/TenantIdResolver");
3496
- var USER_ID_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/UserIdResolver");
3497
- var USER_EMAIL_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/UserEmailResolver");
3498
- var AUDIT_CONTEXT_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/AuditContextResolver");
3499
- var SUBSCRIPTION_USAGE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionUsagePort");
3500
- var USAGE_SNAPSHOT_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/UsageSnapshotPort");
3501
- var SUBSCRIPTION_WRITE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/TenantSubscriptionWritePort");
3502
- var TRIAL_PROJECTION_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/TrialProjectionPort");
3503
- var PENDING_PLAN_QUERY_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PendingPlanQueryPort");
3494
+ var TENANT_AUTH_GUARDS_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/TenantAuthGuards");
3495
+ var TENANT_ID_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/TenantIdResolver");
3496
+ var USER_ID_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/UserIdResolver");
3497
+ var USER_EMAIL_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/UserEmailResolver");
3498
+ var AUDIT_CONTEXT_RESOLVER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/AuditContextResolver");
3499
+ var SUBSCRIPTION_USAGE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SubscriptionUsagePort");
3500
+ var USAGE_SNAPSHOT_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/UsageSnapshotPort");
3501
+ var SUBSCRIPTION_WRITE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/TenantSubscriptionWritePort");
3502
+ var TRIAL_PROJECTION_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/TrialProjectionPort");
3503
+ var PENDING_PLAN_QUERY_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PendingPlanQueryPort");
3504
3504
 
3505
3505
  // src/billing/composed-tenant-auth.guard.ts
3506
3506
  var import_common26 = require("@nestjs/common");
3507
- var import_types11 = require("@saasicat/types");
3507
+ var import_core14 = require("@saasicat/core");
3508
3508
  function _ts_decorate24(decorators, target, key, desc) {
3509
3509
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3510
3510
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -3533,7 +3533,7 @@ var ComposedTenantAuthGuard = class {
3533
3533
  async canActivate(context) {
3534
3534
  if (!this.guards || this.guards.length === 0) {
3535
3535
  throw new import_common26.ForbiddenException({
3536
- code: import_types11.AUTH_ERROR_CODES.AUTH_GUARDS_NOT_CONFIGURED,
3536
+ code: import_core14.AUTH_ERROR_CODES.AUTH_GUARDS_NOT_CONFIGURED,
3537
3537
  message: "TenantBillingModule.forRoot.authGuards is not configured."
3538
3538
  });
3539
3539
  }
@@ -3556,7 +3556,7 @@ ComposedTenantAuthGuard = _ts_decorate24([
3556
3556
 
3557
3557
  // src/billing/tenant-admin.guard.ts
3558
3558
  var import_common27 = require("@nestjs/common");
3559
- var import_types12 = require("@saasicat/types");
3559
+ var import_core15 = require("@saasicat/core");
3560
3560
  function _ts_decorate25(decorators, target, key, desc) {
3561
3561
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3562
3562
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -3576,14 +3576,14 @@ var TenantAdminGuard = class {
3576
3576
  const request = context.switchToHttp().getRequest();
3577
3577
  if (!request.user) {
3578
3578
  throw new import_common27.ForbiddenException({
3579
- code: import_types12.AUTH_ERROR_CODES.NOT_AUTHENTICATED,
3579
+ code: import_core15.AUTH_ERROR_CODES.NOT_AUTHENTICATED,
3580
3580
  message: "Not authenticated"
3581
3581
  });
3582
3582
  }
3583
3583
  const role = request.user.platformRole ?? request.user.role;
3584
3584
  if (!role || !ADMIN_ROLES.has(role)) {
3585
3585
  throw new import_common27.ForbiddenException({
3586
- code: import_types12.AUTH_ERROR_CODES.TENANT_ADMIN_REQUIRED,
3586
+ code: import_core15.AUTH_ERROR_CODES.TENANT_ADMIN_REQUIRED,
3587
3587
  message: "This action requires the TENANT_ADMIN role."
3588
3588
  });
3589
3589
  }
@@ -3595,8 +3595,8 @@ TenantAdminGuard = _ts_decorate25([
3595
3595
  ], TenantAdminGuard);
3596
3596
 
3597
3597
  // src/billing/self-service-policy.ts
3598
- var SELF_SERVICE_BLOCKED_PLANS_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SelfServiceBlockedPlans");
3599
- var SELF_SERVICE_BLOCKED_BUNDLES_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SelfServiceBlockedBundles");
3598
+ var SELF_SERVICE_BLOCKED_PLANS_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SelfServiceBlockedPlans");
3599
+ var SELF_SERVICE_BLOCKED_BUNDLES_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SelfServiceBlockedBundles");
3600
3600
 
3601
3601
  // src/billing/proration.ts
3602
3602
  var DAY_MS2 = 864e5;
@@ -3623,7 +3623,7 @@ __name(round22, "round2");
3623
3623
 
3624
3624
  // src/billing/plan-change-preview.service.ts
3625
3625
  var import_common28 = require("@nestjs/common");
3626
- var import_types13 = require("@saasicat/types");
3626
+ var import_core16 = require("@saasicat/core");
3627
3627
  function _ts_decorate26(decorators, target, key, desc) {
3628
3628
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3629
3629
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -3663,7 +3663,7 @@ var PlanChangePreviewService = class {
3663
3663
  const sub = await this.subscriptions.findForTenant(tenantId);
3664
3664
  if (!sub) {
3665
3665
  throw new import_common28.NotFoundException({
3666
- code: import_types13.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
3666
+ code: import_core16.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
3667
3667
  message: `No subscription for tenant ${tenantId}`,
3668
3668
  params: {
3669
3669
  tenantId
@@ -3673,7 +3673,7 @@ var PlanChangePreviewService = class {
3673
3673
  const targetPlanDef = findPlan(this.catalog, targetPlan);
3674
3674
  if (!targetPlanDef) {
3675
3675
  throw new import_common28.NotFoundException({
3676
- code: import_types13.BILLING_ERROR_CODES.PLAN_NOT_IN_CATALOG,
3676
+ code: import_core16.BILLING_ERROR_CODES.PLAN_NOT_IN_CATALOG,
3677
3677
  message: `Plan "${targetPlan}" is not in the catalog (${this.catalog.projectKey})`,
3678
3678
  params: {
3679
3679
  planKey: targetPlan,
@@ -3873,9 +3873,9 @@ __name(isFloatQuota, "isFloatQuota");
3873
3873
  var import_common29 = require("@nestjs/common");
3874
3874
 
3875
3875
  // src/billing/contract-freeze.tokens.ts
3876
- var CONTRACT_FREEZE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/ContractFreezePort");
3877
- var CONTRACT_FREEZE_SOURCE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/ContractFreezeSourcePort");
3878
- var CONTRACT_FREEZE_PROJECT_KEY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/ContractFreezeProjectKey");
3876
+ var CONTRACT_FREEZE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/ContractFreezePort");
3877
+ var CONTRACT_FREEZE_SOURCE_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/ContractFreezeSourcePort");
3878
+ var CONTRACT_FREEZE_PROJECT_KEY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/ContractFreezeProjectKey");
3879
3879
 
3880
3880
  // src/billing/pending-plan-materialization.service.ts
3881
3881
  function _ts_decorate27(decorators, target, key, desc) {
@@ -4051,7 +4051,7 @@ function cloneJsonValue(value) {
4051
4051
  __name(cloneJsonValue, "cloneJsonValue");
4052
4052
 
4053
4053
  // src/subscription-contract/subscription-contract.service.ts
4054
- var import_types14 = require("@saasicat/types");
4054
+ var import_core17 = require("@saasicat/core");
4055
4055
  function _ts_decorate28(decorators, target, key, desc) {
4056
4056
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4057
4057
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -4084,7 +4084,7 @@ var SubscriptionContractService = class {
4084
4084
  const row = await this.repo.findById(contractId);
4085
4085
  if (!row) {
4086
4086
  throw new import_common30.NotFoundException({
4087
- code: import_types14.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_NOT_FOUND,
4087
+ code: import_core17.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_NOT_FOUND,
4088
4088
  message: `SubscriptionContract '${contractId}' not found`,
4089
4089
  params: {
4090
4090
  contractId
@@ -4100,7 +4100,7 @@ var SubscriptionContractService = class {
4100
4100
  const contract = await this.repo.findActiveByTenantId(tenantId, asOf);
4101
4101
  if (!contract) {
4102
4102
  throw new import_common30.NotFoundException({
4103
- code: import_types14.CONTRACT_ERROR_CODES.NO_ACTIVE_SUBSCRIPTION_CONTRACT,
4103
+ code: import_core17.CONTRACT_ERROR_CODES.NO_ACTIVE_SUBSCRIPTION_CONTRACT,
4104
4104
  message: `No active subscription contract for tenant ${tenantId}`,
4105
4105
  params: {
4106
4106
  tenantId,
@@ -4140,7 +4140,7 @@ var SubscriptionContractService = class {
4140
4140
  createDataFromOffer(offer, options) {
4141
4141
  if (offer.status !== "consumed") {
4142
4142
  throw new import_common30.ConflictException({
4143
- code: import_types14.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_NOT_CONSUMED,
4143
+ code: import_core17.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_NOT_CONSUMED,
4144
4144
  message: `CheckoutOffer '${offer.id}' must be consumed before the contract is created`,
4145
4145
  params: {
4146
4146
  offerId: offer.id,
@@ -4179,7 +4179,7 @@ var SubscriptionContractService = class {
4179
4179
  const source = offer.lineItems ?? [];
4180
4180
  if (source.length === 0) {
4181
4181
  throw new import_common30.UnprocessableEntityException({
4182
- code: import_types14.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_LINE_ITEMS_REQUIRED,
4182
+ code: import_core17.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_LINE_ITEMS_REQUIRED,
4183
4183
  message: "A checkout offer can yield only one contract, and only once its line items are frozen."
4184
4184
  });
4185
4185
  }
@@ -4218,7 +4218,7 @@ var SubscriptionContractService = class {
4218
4218
  const date = value instanceof Date ? new Date(value) : new Date(value);
4219
4219
  if (Number.isNaN(date.getTime())) {
4220
4220
  throw new import_common30.UnprocessableEntityException({
4221
- code: import_types14.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_INVALID_DATE,
4221
+ code: import_core17.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_INVALID_DATE,
4222
4222
  message: `${field} must be a valid date.`,
4223
4223
  params: {
4224
4224
  field
@@ -4242,20 +4242,20 @@ var SubscriptionContractService = class {
4242
4242
  assertCreateData(data) {
4243
4243
  if (data.lineItems.length === 0) {
4244
4244
  throw new import_common30.UnprocessableEntityException({
4245
- code: import_types14.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_LINE_ITEMS_REQUIRED,
4245
+ code: import_core17.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_LINE_ITEMS_REQUIRED,
4246
4246
  message: "A subscription contract requires at least one line item."
4247
4247
  });
4248
4248
  }
4249
4249
  if (data.effectiveUntil && data.effectiveUntil <= data.effectiveFrom) {
4250
4250
  throw new import_common30.UnprocessableEntityException({
4251
- code: import_types14.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_INVALID_WINDOW,
4251
+ code: import_core17.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_INVALID_WINDOW,
4252
4252
  message: "effectiveUntil must be after effectiveFrom."
4253
4253
  });
4254
4254
  }
4255
4255
  const planLineItems = data.lineItems.filter((item) => item.kind === "plan");
4256
4256
  if (planLineItems.length !== 1) {
4257
4257
  throw new import_common30.UnprocessableEntityException({
4258
- code: import_types14.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_PLAN_LINE_ITEM_REQUIRED,
4258
+ code: import_core17.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_PLAN_LINE_ITEM_REQUIRED,
4259
4259
  message: "A subscription contract requires exactly one plan base item."
4260
4260
  });
4261
4261
  }
@@ -4263,7 +4263,7 @@ var SubscriptionContractService = class {
4263
4263
  assertTerminable(existing, data) {
4264
4264
  if (existing.status === "terminated" || existing.status === "superseded") {
4265
4265
  throw new import_common30.ConflictException({
4266
- code: import_types14.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_ALREADY_CLOSED,
4266
+ code: import_core17.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_ALREADY_CLOSED,
4267
4267
  message: `SubscriptionContract '${existing.id}' is already closed`,
4268
4268
  params: {
4269
4269
  contractId: existing.id,
@@ -4273,7 +4273,7 @@ var SubscriptionContractService = class {
4273
4273
  }
4274
4274
  if (data.effectiveUntil <= existing.effectiveFrom) {
4275
4275
  throw new import_common30.UnprocessableEntityException({
4276
- code: import_types14.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_TERMINATION_BEFORE_START,
4276
+ code: import_core17.CONTRACT_ERROR_CODES.SUBSCRIPTION_CONTRACT_TERMINATION_BEFORE_START,
4277
4277
  message: "effectiveUntil must be after the effectiveFrom of the contract."
4278
4278
  });
4279
4279
  }
@@ -4634,21 +4634,21 @@ _ts_decorate31([
4634
4634
 
4635
4635
  // src/billing/tenant-billing.controller.ts
4636
4636
  var import_common34 = require("@nestjs/common");
4637
- var import_types17 = require("@saasicat/types");
4637
+ var import_core20 = require("@saasicat/core");
4638
4638
 
4639
- // src/promo/service.ts
4639
+ // src/promo/promo.service.ts
4640
4640
  var import_common32 = require("@nestjs/common");
4641
- var import_types15 = require("@saasicat/types");
4641
+ var import_core18 = require("@saasicat/core");
4642
4642
 
4643
- // src/promo/tokens.ts
4644
- var PROMO_CODE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoCodeRepository");
4645
- var PROMO_CODE_REDEMPTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoCodeRedemptionRepository");
4646
- var PROMO_CODE_VALIDATION_LOG_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoCodeValidationLogRepository");
4647
- var PROMO_FIRST_TIME_CUSTOMER_CHECK_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoFirstTimeCustomerCheck");
4648
- var PROMO_SUBSCRIPTION_LOOKUP_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoSubscriptionLookup");
4649
- var PROMO_REVENUE_DEDUCTION_AGGREGATOR_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoRevenueDeductionAggregator");
4650
- var PROMO_TRANSACTION_RUNNER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoTransactionRunner");
4651
- var PROMO_SERVICE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PromoServiceConfig");
4643
+ // src/promo/promo.tokens.ts
4644
+ var PROMO_CODE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoCodeRepository");
4645
+ var PROMO_CODE_REDEMPTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoCodeRedemptionRepository");
4646
+ var PROMO_CODE_VALIDATION_LOG_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoCodeValidationLogRepository");
4647
+ var PROMO_FIRST_TIME_CUSTOMER_CHECK_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoFirstTimeCustomerCheck");
4648
+ var PROMO_SUBSCRIPTION_LOOKUP_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoSubscriptionLookup");
4649
+ var PROMO_REVENUE_DEDUCTION_AGGREGATOR_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoRevenueDeductionAggregator");
4650
+ var PROMO_TRANSACTION_RUNNER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoTransactionRunner");
4651
+ var PROMO_SERVICE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PromoServiceConfig");
4652
4652
 
4653
4653
  // src/promo/calculator.ts
4654
4654
  function computeDiscountGross(plan, code) {
@@ -4724,7 +4724,7 @@ function buildLabel(code, cycle, options = {}) {
4724
4724
  }
4725
4725
  __name(buildLabel, "buildLabel");
4726
4726
 
4727
- // src/promo/service.ts
4727
+ // src/promo/promo.service.ts
4728
4728
  function _ts_decorate32(decorators, target, key, desc) {
4729
4729
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4730
4730
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -4751,7 +4751,7 @@ var DURATION_MIN = 1;
4751
4751
  var DURATION_MAX = 24;
4752
4752
  function notRedeemable(reason) {
4753
4753
  return new import_common32.BadRequestException({
4754
- code: import_types15.PROMO_ERROR_CODES.PROMO_CODE_NOT_REDEEMABLE,
4754
+ code: import_core18.PROMO_ERROR_CODES.PROMO_CODE_NOT_REDEEMABLE,
4755
4755
  message: `Code cannot be redeemed: ${reason}`,
4756
4756
  params: {
4757
4757
  reason
@@ -4788,7 +4788,7 @@ var PromoCodesService = class {
4788
4788
  const code = input.code.trim().toUpperCase();
4789
4789
  if (!CODE_PATTERN.test(code)) {
4790
4790
  throw new import_common32.BadRequestException({
4791
- code: import_types15.PROMO_ERROR_CODES.PROMO_CODE_FORMAT_INVALID,
4791
+ code: import_core18.PROMO_ERROR_CODES.PROMO_CODE_FORMAT_INVALID,
4792
4792
  message: 'The code may only contain upper-case letters, digits, "-" and "_" (4\u201332 characters).',
4793
4793
  params: {
4794
4794
  promoCode: code,
@@ -4800,7 +4800,7 @@ var PromoCodesService = class {
4800
4800
  if (input.valueType === "PERCENT") {
4801
4801
  if (!(input.value > PERCENT_MIN_EXCLUSIVE && input.value <= PERCENT_MAX)) {
4802
4802
  throw new import_common32.BadRequestException({
4803
- code: import_types15.PROMO_ERROR_CODES.PROMO_PERCENT_OUT_OF_RANGE,
4803
+ code: import_core18.PROMO_ERROR_CODES.PROMO_PERCENT_OUT_OF_RANGE,
4804
4804
  message: "The percentage must be between 0 and 100.",
4805
4805
  params: {
4806
4806
  value: input.value,
@@ -4811,7 +4811,7 @@ var PromoCodesService = class {
4811
4811
  }
4812
4812
  } else if (!(input.value > 0)) {
4813
4813
  throw new import_common32.BadRequestException({
4814
- code: import_types15.PROMO_ERROR_CODES.PROMO_AMOUNT_NOT_POSITIVE,
4814
+ code: import_core18.PROMO_ERROR_CODES.PROMO_AMOUNT_NOT_POSITIVE,
4815
4815
  message: "The amount must be positive.",
4816
4816
  params: {
4817
4817
  value: input.value,
@@ -4822,7 +4822,7 @@ var PromoCodesService = class {
4822
4822
  if (input.durationType === "ONCE") {
4823
4823
  if (input.durationValue != null) {
4824
4824
  throw new import_common32.BadRequestException({
4825
- code: import_types15.PROMO_ERROR_CODES.PROMO_ONE_OFF_WITH_DURATION,
4825
+ code: import_core18.PROMO_ERROR_CODES.PROMO_ONE_OFF_WITH_DURATION,
4826
4826
  message: "A one-off discount must not set a duration.",
4827
4827
  params: {
4828
4828
  durationValue: input.durationValue
@@ -4833,7 +4833,7 @@ var PromoCodesService = class {
4833
4833
  const v = input.durationValue;
4834
4834
  if (v == null || v < DURATION_MIN || v > DURATION_MAX) {
4835
4835
  throw new import_common32.BadRequestException({
4836
- code: import_types15.PROMO_ERROR_CODES.PROMO_DURATION_INVALID,
4836
+ code: import_core18.PROMO_ERROR_CODES.PROMO_DURATION_INVALID,
4837
4837
  message: "Invalid duration (at most 24 months or billing periods).",
4838
4838
  params: {
4839
4839
  durationValue: v ?? null,
@@ -4845,7 +4845,7 @@ var PromoCodesService = class {
4845
4845
  }
4846
4846
  if (input.validFrom && input.validUntil && input.validFrom >= input.validUntil) {
4847
4847
  throw new import_common32.BadRequestException({
4848
- code: import_types15.PROMO_ERROR_CODES.PROMO_VALIDITY_WINDOW_INVALID,
4848
+ code: import_core18.PROMO_ERROR_CODES.PROMO_VALIDITY_WINDOW_INVALID,
4849
4849
  message: "Invalid validity window.",
4850
4850
  params: {
4851
4851
  validFrom: input.validFrom.toISOString(),
@@ -4858,7 +4858,7 @@ var PromoCodesService = class {
4858
4858
  for (const p of plans) {
4859
4859
  if (blocked.includes(p)) {
4860
4860
  throw new import_common32.BadRequestException({
4861
- code: import_types15.PROMO_ERROR_CODES.PROMO_PLAN_NOT_DISCOUNTABLE,
4861
+ code: import_core18.PROMO_ERROR_CODES.PROMO_PLAN_NOT_DISCOUNTABLE,
4862
4862
  message: `${p}-Plan cannot be discounted.`,
4863
4863
  params: {
4864
4864
  plan: p
@@ -4868,7 +4868,7 @@ var PromoCodesService = class {
4868
4868
  }
4869
4869
  if (input.minimumPlanAmountGross != null && input.minimumPlanAmountGross <= 0) {
4870
4870
  throw new import_common32.BadRequestException({
4871
- code: import_types15.PROMO_ERROR_CODES.PROMO_MIN_AMOUNT_NOT_POSITIVE,
4871
+ code: import_core18.PROMO_ERROR_CODES.PROMO_MIN_AMOUNT_NOT_POSITIVE,
4872
4872
  message: "The minimum plan gross amount must be positive.",
4873
4873
  params: {
4874
4874
  value: input.minimumPlanAmountGross,
@@ -4880,7 +4880,7 @@ var PromoCodesService = class {
4880
4880
  const lowestApplicableGross = this.lowestApplicablePlanGross(plans);
4881
4881
  if (lowestApplicableGross != null && input.value >= lowestApplicableGross) {
4882
4882
  throw new import_common32.BadRequestException({
4883
- code: import_types15.PROMO_ERROR_CODES.PROMO_WOULD_PRODUCE_ZERO_INVOICE,
4883
+ code: import_core18.PROMO_ERROR_CODES.PROMO_WOULD_PRODUCE_ZERO_INVOICE,
4884
4884
  message: "For absolute amounts the discount must stay below the lowest applicable plan price, or allowZeroInvoice must be enabled.",
4885
4885
  params: {
4886
4886
  value: input.value,
@@ -4892,7 +4892,7 @@ var PromoCodesService = class {
4892
4892
  const exists = await this.promoRepo.findByCode(code);
4893
4893
  if (exists) {
4894
4894
  throw new import_common32.BadRequestException({
4895
- code: import_types15.PROMO_ERROR_CODES.PROMO_CODE_ALREADY_EXISTS,
4895
+ code: import_core18.PROMO_ERROR_CODES.PROMO_CODE_ALREADY_EXISTS,
4896
4896
  message: "The code already exists.",
4897
4897
  params: {
4898
4898
  promoCode: code
@@ -4908,7 +4908,7 @@ var PromoCodesService = class {
4908
4908
  const existing = await this.promoRepo.findById(id);
4909
4909
  if (!existing) {
4910
4910
  throw new import_common32.NotFoundException({
4911
- code: import_types15.PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
4911
+ code: import_core18.PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
4912
4912
  message: "Code not found",
4913
4913
  params: {
4914
4914
  promoCodeId: id,
@@ -4919,7 +4919,7 @@ var PromoCodesService = class {
4919
4919
  if (input.maxRedemptions != null && existing.maxRedemptions != null) {
4920
4920
  if (input.maxRedemptions < existing.maxRedemptions) {
4921
4921
  throw new import_common32.BadRequestException({
4922
- code: import_types15.PROMO_ERROR_CODES.PROMO_MAX_REDEMPTIONS_LOWERED,
4922
+ code: import_core18.PROMO_ERROR_CODES.PROMO_MAX_REDEMPTIONS_LOWERED,
4923
4923
  message: "maxRedemptions cannot be lowered.",
4924
4924
  params: {
4925
4925
  current: existing.maxRedemptions,
@@ -4934,7 +4934,7 @@ var PromoCodesService = class {
4934
4934
  const redemptions = await this.redemptionRepo.countByPromoCode(id);
4935
4935
  if (redemptions > 0) {
4936
4936
  throw new import_common32.BadRequestException({
4937
- code: import_types15.PROMO_ERROR_CODES.PROMO_CODE_HAS_REDEMPTIONS,
4937
+ code: import_core18.PROMO_ERROR_CODES.PROMO_CODE_HAS_REDEMPTIONS,
4938
4938
  message: "The code already has redemptions \u2014 it cannot be soft-deleted. Pause it instead.",
4939
4939
  params: {
4940
4940
  promoCodeId: id,
@@ -4953,7 +4953,7 @@ var PromoCodesService = class {
4953
4953
  const code = await this.promoRepo.findById(id);
4954
4954
  if (!code || code.deletedAt) {
4955
4955
  throw new import_common32.NotFoundException({
4956
- code: import_types15.PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
4956
+ code: import_core18.PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
4957
4957
  message: "Code not found",
4958
4958
  params: {
4959
4959
  promoCodeId: id,
@@ -5089,7 +5089,7 @@ var PromoCodesService = class {
5089
5089
  const promo = await this.promoRepo.findByCode(code, tx);
5090
5090
  if (!promo || promo.deletedAt) {
5091
5091
  throw new import_common32.BadRequestException({
5092
- code: import_types15.PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
5092
+ code: import_core18.PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
5093
5093
  // The lookup runs on the code string, so there is no id to report.
5094
5094
  message: "Code not found",
5095
5095
  params: {
@@ -5101,7 +5101,7 @@ var PromoCodesService = class {
5101
5101
  const sub = await this.subscriptionLookup.findById(input.subscriptionId, tx);
5102
5102
  if (!sub) {
5103
5103
  throw new import_common32.NotFoundException({
5104
- code: import_types15.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5104
+ code: import_core18.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5105
5105
  message: "Subscription not found",
5106
5106
  params: {
5107
5107
  tenantId: input.tenantId
@@ -5110,7 +5110,7 @@ var PromoCodesService = class {
5110
5110
  }
5111
5111
  if (sub.tenantId !== input.tenantId) {
5112
5112
  throw new import_common32.BadRequestException({
5113
- code: import_types15.BILLING_ERROR_CODES.SUBSCRIPTION_TENANT_MISMATCH,
5113
+ code: import_core18.BILLING_ERROR_CODES.SUBSCRIPTION_TENANT_MISMATCH,
5114
5114
  message: "Subscription does not belong to the tenant",
5115
5115
  params: {
5116
5116
  subscriptionId: sub.id,
@@ -5243,7 +5243,7 @@ PromoCodesService = _ts_decorate32([
5243
5243
 
5244
5244
  // src/billing/subscription-bundles.service.ts
5245
5245
  var import_common33 = require("@nestjs/common");
5246
- var import_types16 = require("@saasicat/types");
5246
+ var import_core19 = require("@saasicat/core");
5247
5247
  function _ts_decorate33(decorators, target, key, desc) {
5248
5248
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5249
5249
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -5292,7 +5292,7 @@ var SubscriptionBundlesService = class {
5292
5292
  const bundleVersion = await this.bundles.findVersionById(input.bundleVersionId);
5293
5293
  if (!bundleVersion) {
5294
5294
  throw new import_common33.NotFoundException({
5295
- code: import_types16.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
5295
+ code: import_core19.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
5296
5296
  message: `BundleVersion '${input.bundleVersionId}' not found`,
5297
5297
  params: {
5298
5298
  bundleVersionId: input.bundleVersionId
@@ -5301,7 +5301,7 @@ var SubscriptionBundlesService = class {
5301
5301
  }
5302
5302
  if (bundleVersion.publishedAt === null) {
5303
5303
  throw new import_common33.UnprocessableEntityException({
5304
- code: import_types16.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_PUBLISHED,
5304
+ code: import_core19.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_PUBLISHED,
5305
5305
  message: `BundleVersion '${input.bundleVersionId}' is not published and cannot be booked.`,
5306
5306
  params: {
5307
5307
  bundleVersionId: input.bundleVersionId
@@ -5310,7 +5310,7 @@ var SubscriptionBundlesService = class {
5310
5310
  }
5311
5311
  if (bundleVersion.supersededAt !== null) {
5312
5312
  throw new import_common33.UnprocessableEntityException({
5313
- code: import_types16.CATALOG_ERROR_CODES.BUNDLE_VERSION_SUPERSEDED,
5313
+ code: import_core19.CATALOG_ERROR_CODES.BUNDLE_VERSION_SUPERSEDED,
5314
5314
  message: `BundleVersion '${input.bundleVersionId}' has been superseded by a newer version.`,
5315
5315
  params: {
5316
5316
  bundleVersionId: input.bundleVersionId
@@ -5319,7 +5319,7 @@ var SubscriptionBundlesService = class {
5319
5319
  }
5320
5320
  if (this.blockedBundles?.bundleKeys?.includes(bundleVersion.bundleKey)) {
5321
5321
  throw new import_common33.UnprocessableEntityException({
5322
- code: import_types16.BILLING_ERROR_CODES.BUNDLE_NOT_SELF_SERVICE,
5322
+ code: import_core19.BILLING_ERROR_CODES.BUNDLE_NOT_SELF_SERVICE,
5323
5323
  message: `Bundle '${bundleVersion.bundleKey}' is only activated via a special contract. Please contact the contract manager.`,
5324
5324
  params: {
5325
5325
  bundleKey: bundleVersion.bundleKey
@@ -5329,7 +5329,7 @@ var SubscriptionBundlesService = class {
5329
5329
  const planIds = bundleVersion.compatibility?.planIds ?? [];
5330
5330
  if (planIds.length > 0 && !planIds.includes(input.currentPlanKey)) {
5331
5331
  throw new import_common33.UnprocessableEntityException({
5332
- code: import_types16.BILLING_ERROR_CODES.BUNDLE_INCOMPATIBLE_WITH_PLAN,
5332
+ code: import_core19.BILLING_ERROR_CODES.BUNDLE_INCOMPATIBLE_WITH_PLAN,
5333
5333
  message: `BundleVersion '${input.bundleVersionId}' is not compatible with plan '${input.currentPlanKey}'. Allowed: [${planIds.join(", ")}].`,
5334
5334
  params: {
5335
5335
  bundleVersionId: input.bundleVersionId,
@@ -5341,7 +5341,7 @@ var SubscriptionBundlesService = class {
5341
5341
  const active = await this.repo.listActiveBySubscription(input.subscriptionId);
5342
5342
  if (active.some((b) => b.bundleVersionId === input.bundleVersionId)) {
5343
5343
  throw new import_common33.UnprocessableEntityException({
5344
- code: import_types16.BILLING_ERROR_CODES.BUNDLE_ALREADY_SUBSCRIBED,
5344
+ code: import_core19.BILLING_ERROR_CODES.BUNDLE_ALREADY_SUBSCRIBED,
5345
5345
  message: `Subscription '${input.subscriptionId}' has already actively booked this bundle.`,
5346
5346
  params: {
5347
5347
  subscriptionId: input.subscriptionId
@@ -5362,7 +5362,7 @@ var SubscriptionBundlesService = class {
5362
5362
  const existing = await this.repo.findById(input.subscriptionBundleId);
5363
5363
  if (!existing) {
5364
5364
  throw new import_common33.NotFoundException({
5365
- code: import_types16.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_NOT_FOUND,
5365
+ code: import_core19.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_NOT_FOUND,
5366
5366
  message: `SubscriptionBundle '${input.subscriptionBundleId}' not found`,
5367
5367
  params: {
5368
5368
  subscriptionBundleId: input.subscriptionBundleId
@@ -5371,7 +5371,7 @@ var SubscriptionBundlesService = class {
5371
5371
  }
5372
5372
  if (existing.canceledAt !== null) {
5373
5373
  throw new import_common33.UnprocessableEntityException({
5374
- code: import_types16.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED,
5374
+ code: import_core19.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED,
5375
5375
  message: `SubscriptionBundle '${input.subscriptionBundleId}' is already cancelled.`,
5376
5376
  params: {
5377
5377
  subscriptionBundleId: input.subscriptionBundleId
@@ -5397,7 +5397,7 @@ var SubscriptionBundlesService = class {
5397
5397
  const existing = await this.repo.findById(subscriptionBundleId);
5398
5398
  if (!existing) {
5399
5399
  throw new import_common33.NotFoundException({
5400
- code: import_types16.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_NOT_FOUND,
5400
+ code: import_core19.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_NOT_FOUND,
5401
5401
  message: `SubscriptionBundle '${subscriptionBundleId}' not found`,
5402
5402
  params: {
5403
5403
  subscriptionBundleId
@@ -5406,7 +5406,7 @@ var SubscriptionBundlesService = class {
5406
5406
  }
5407
5407
  if (existing.canceledAt === null) {
5408
5408
  throw new import_common33.UnprocessableEntityException({
5409
- code: import_types16.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_NOT_CANCELLED,
5409
+ code: import_core19.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_NOT_CANCELLED,
5410
5410
  message: `SubscriptionBundle '${subscriptionBundleId}' is not cancelled.`,
5411
5411
  params: {
5412
5412
  subscriptionBundleId
@@ -5415,7 +5415,7 @@ var SubscriptionBundlesService = class {
5415
5415
  }
5416
5416
  if (existing.canceledEffectiveAt !== null && existing.canceledEffectiveAt <= /* @__PURE__ */ new Date()) {
5417
5417
  throw new import_common33.UnprocessableEntityException({
5418
- code: import_types16.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE,
5418
+ code: import_core19.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE,
5419
5419
  message: "Cancellation already in effect \u2014 book the bundle again."
5420
5420
  });
5421
5421
  }
@@ -5523,7 +5523,7 @@ var TenantBillingController = class _TenantBillingController {
5523
5523
  ]);
5524
5524
  if (!sub) {
5525
5525
  throw new import_common34.NotFoundException({
5526
- code: import_types17.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5526
+ code: import_core20.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5527
5527
  message: `No subscription for tenant ${tenantId}`,
5528
5528
  params: {
5529
5529
  tenantId
@@ -5578,7 +5578,7 @@ var TenantBillingController = class _TenantBillingController {
5578
5578
  const blockedTargets = this.blockedPlans?.asTarget ?? [];
5579
5579
  if (blockedTargets.includes(dto.plan)) {
5580
5580
  throw new import_common34.ForbiddenException({
5581
- code: import_types17.BILLING_ERROR_CODES.PLAN_NOT_SELF_SERVICE,
5581
+ code: import_core20.BILLING_ERROR_CODES.PLAN_NOT_SELF_SERVICE,
5582
5582
  message: `${dto.plan} is not activated via self-service.`,
5583
5583
  params: {
5584
5584
  planKey: dto.plan
@@ -5588,7 +5588,7 @@ var TenantBillingController = class _TenantBillingController {
5588
5588
  const sub = await this.subscriptionUsage.findForTenant(tenantId);
5589
5589
  if (!sub) {
5590
5590
  throw new import_common34.NotFoundException({
5591
- code: import_types17.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5591
+ code: import_core20.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5592
5592
  message: `No subscription for tenant ${tenantId}`,
5593
5593
  params: {
5594
5594
  tenantId
@@ -5598,7 +5598,7 @@ var TenantBillingController = class _TenantBillingController {
5598
5598
  const blockers = await this.planPreview.assertChangeAllowed(tenantId, dto.plan, dto.billingCycle);
5599
5599
  if (blockers.length > 0) {
5600
5600
  throw new import_common34.BadRequestException({
5601
- code: import_types17.BILLING_ERROR_CODES.PLAN_CHANGE_BLOCKED,
5601
+ code: import_core20.BILLING_ERROR_CODES.PLAN_CHANGE_BLOCKED,
5602
5602
  message: "Plan change is blocked.",
5603
5603
  blockers
5604
5604
  });
@@ -5670,7 +5670,7 @@ var TenantBillingController = class _TenantBillingController {
5670
5670
  const blockedTargets = this.blockedPlans?.asTarget ?? [];
5671
5671
  if (blockedTargets.includes(dto.plan)) {
5672
5672
  throw new import_common34.ForbiddenException({
5673
- code: import_types17.BILLING_ERROR_CODES.PLAN_NOT_SELF_SERVICE,
5673
+ code: import_core20.BILLING_ERROR_CODES.PLAN_NOT_SELF_SERVICE,
5674
5674
  message: `${dto.plan} is not activated via self-service.`,
5675
5675
  params: {
5676
5676
  planKey: dto.plan
@@ -5680,7 +5680,7 @@ var TenantBillingController = class _TenantBillingController {
5680
5680
  const sub = await this.subscriptionUsage.findForTenant(tenantId);
5681
5681
  if (!sub) {
5682
5682
  throw new import_common34.NotFoundException({
5683
- code: import_types17.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5683
+ code: import_core20.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5684
5684
  message: `No subscription for tenant ${tenantId}`,
5685
5685
  params: {
5686
5686
  tenantId
@@ -5690,7 +5690,7 @@ var TenantBillingController = class _TenantBillingController {
5690
5690
  const blockers = await this.planPreview.assertChangeAllowed(tenantId, dto.plan, dto.billingCycle);
5691
5691
  if (blockers.length > 0) {
5692
5692
  throw new import_common34.BadRequestException({
5693
- code: import_types17.BILLING_ERROR_CODES.PLAN_CHANGE_BLOCKED,
5693
+ code: import_core20.BILLING_ERROR_CODES.PLAN_CHANGE_BLOCKED,
5694
5694
  message: "Plan change during onboarding is blocked.",
5695
5695
  blockers
5696
5696
  });
@@ -5727,7 +5727,7 @@ var TenantBillingController = class _TenantBillingController {
5727
5727
  } catch (err) {
5728
5728
  const reason = err instanceof Error ? err.message : null;
5729
5729
  throw new import_common34.BadRequestException({
5730
- code: import_types17.BILLING_ERROR_CODES.ONBOARDING_CREATE_FAILED,
5730
+ code: import_core20.BILLING_ERROR_CODES.ONBOARDING_CREATE_FAILED,
5731
5731
  message: reason ? `Onboarding creation failed: ${reason}` : "Onboarding creation failed",
5732
5732
  params: {
5733
5733
  reason
@@ -5810,7 +5810,7 @@ var TenantBillingController = class _TenantBillingController {
5810
5810
  const sub = await this.subscriptionUsage.findForTenant(tenantId);
5811
5811
  if (!sub) {
5812
5812
  throw new import_common34.NotFoundException({
5813
- code: import_types17.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5813
+ code: import_core20.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
5814
5814
  message: `No subscription for tenant ${tenantId}`,
5815
5815
  params: {
5816
5816
  tenantId
@@ -5819,7 +5819,7 @@ var TenantBillingController = class _TenantBillingController {
5819
5819
  }
5820
5820
  if (!sub.pendingPlanVersion) {
5821
5821
  throw new import_common34.BadRequestException({
5822
- code: import_types17.BILLING_ERROR_CODES.NO_PENDING_PLAN_VERSION,
5822
+ code: import_core20.BILLING_ERROR_CODES.NO_PENDING_PLAN_VERSION,
5823
5823
  message: "There is no pending plan version awaiting confirmation."
5824
5824
  });
5825
5825
  }
@@ -5867,7 +5867,7 @@ var TenantBillingController = class _TenantBillingController {
5867
5867
  const tenantId = resolver(req);
5868
5868
  if (!tenantId) {
5869
5869
  throw new import_common34.NotFoundException({
5870
- code: import_types17.AUTH_ERROR_CODES.TENANT_CONTEXT_MISSING,
5870
+ code: import_core20.AUTH_ERROR_CODES.TENANT_CONTEXT_MISSING,
5871
5871
  message: "No tenant ID found on the request"
5872
5872
  });
5873
5873
  }
@@ -5878,7 +5878,7 @@ var TenantBillingController = class _TenantBillingController {
5878
5878
  const userId = resolver(req);
5879
5879
  if (!userId) {
5880
5880
  throw new import_common34.NotFoundException({
5881
- code: import_types17.AUTH_ERROR_CODES.TENANT_CONTEXT_MISSING,
5881
+ code: import_core20.AUTH_ERROR_CODES.TENANT_CONTEXT_MISSING,
5882
5882
  message: "No user ID found on the request"
5883
5883
  });
5884
5884
  }
@@ -6249,7 +6249,7 @@ __name(normalizeQuotas, "normalizeQuotas");
6249
6249
 
6250
6250
  // src/billing/subscription-bundle-preview.service.ts
6251
6251
  var import_common37 = require("@nestjs/common");
6252
- var import_types18 = require("@saasicat/types");
6252
+ var import_core21 = require("@saasicat/core");
6253
6253
  function _ts_decorate37(decorators, target, key, desc) {
6254
6254
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6255
6255
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -6289,7 +6289,7 @@ var SubscriptionBundlePreviewService = class {
6289
6289
  const bundleVersion = await this.bundles.findVersionById(input.bundleVersionId);
6290
6290
  if (!bundleVersion) {
6291
6291
  throw new import_common37.NotFoundException({
6292
- code: import_types18.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
6292
+ code: import_core21.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
6293
6293
  message: `BundleVersion '${input.bundleVersionId}' not found`,
6294
6294
  params: {
6295
6295
  bundleVersionId: input.bundleVersionId
@@ -6348,7 +6348,7 @@ var SubscriptionBundlePreviewService = class {
6348
6348
  const existing = await this.subscriptionBundles.findById(input.subscriptionBundleId);
6349
6349
  if (!existing || existing.subscriptionId !== ctx.subscriptionId) {
6350
6350
  throw new import_common37.NotFoundException({
6351
- code: import_types18.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_NOT_FOUND,
6351
+ code: import_core21.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_NOT_FOUND,
6352
6352
  message: `SubscriptionBundle '${input.subscriptionBundleId}' not found`,
6353
6353
  params: {
6354
6354
  subscriptionBundleId: input.subscriptionBundleId
@@ -6358,7 +6358,7 @@ var SubscriptionBundlePreviewService = class {
6358
6358
  const bundleVersion = await this.bundles.findVersionById(existing.bundleVersionId);
6359
6359
  if (!bundleVersion) {
6360
6360
  throw new import_common37.NotFoundException({
6361
- code: import_types18.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
6361
+ code: import_core21.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
6362
6362
  message: `BundleVersion '${existing.bundleVersionId}' not found`,
6363
6363
  params: {
6364
6364
  bundleVersionId: existing.bundleVersionId
@@ -6369,7 +6369,7 @@ var SubscriptionBundlePreviewService = class {
6369
6369
  const warnings = [];
6370
6370
  if (existing.canceledAt !== null) {
6371
6371
  blockers.push({
6372
- code: import_types18.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED,
6372
+ code: import_core21.BILLING_ERROR_CODES.SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED,
6373
6373
  message: "This bundle booking is already cancelled."
6374
6374
  });
6375
6375
  }
@@ -6469,12 +6469,12 @@ var SubscriptionBundlePreviewService = class {
6469
6469
  const entries = await this.catalogEntries.listFeatures({
6470
6470
  projectKey
6471
6471
  });
6472
- const requiresIndex = (0, import_types18.buildFeatureRequiresIndex)(entries);
6472
+ const requiresIndex = (0, import_core21.buildFeatureRequiresIndex)(entries);
6473
6473
  const covered = /* @__PURE__ */ new Set([
6474
6474
  ...planFeatures,
6475
6475
  ...activeBundleVersions.flatMap((bv) => bv.features ?? [])
6476
6476
  ]);
6477
- return (0, import_types18.collectUnsatisfiedRequires)(bundleVersion.features ?? [], requiresIndex).filter((key) => !covered.has(key));
6477
+ return (0, import_core21.collectUnsatisfiedRequires)(bundleVersion.features ?? [], requiresIndex).filter((key) => !covered.has(key));
6478
6478
  }
6479
6479
  /** `projectKey` lives on the bundle stem, not on the version. */
6480
6480
  async resolveProjectKey(bundleVersion) {
@@ -6533,7 +6533,7 @@ var import_common39 = require("@nestjs/common");
6533
6533
 
6534
6534
  // src/billing/tenant-subscription-bundles.controller.ts
6535
6535
  var import_common38 = require("@nestjs/common");
6536
- var import_types19 = require("@saasicat/types");
6536
+ var import_core22 = require("@saasicat/core");
6537
6537
 
6538
6538
  // src/billing/dto/subscription-bundles.dto.ts
6539
6539
  var import_class_validator5 = require("class-validator");
@@ -6679,7 +6679,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
6679
6679
  const hasCancel = Boolean(dto.subscriptionBundleId);
6680
6680
  if (hasAdd === hasCancel) {
6681
6681
  throw new import_common38.BadRequestException({
6682
- code: import_types19.BILLING_ERROR_CODES.BUNDLE_PREVIEW_ARGUMENT_AMBIGUOUS,
6682
+ code: import_core22.BILLING_ERROR_CODES.BUNDLE_PREVIEW_ARGUMENT_AMBIGUOUS,
6683
6683
  message: "Exactly one of bundleVersionId (add preview) or subscriptionBundleId (cancel preview) must be given."
6684
6684
  });
6685
6685
  }
@@ -6721,7 +6721,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
6721
6721
  }
6722
6722
  requireSubscriptionPk(sub) {
6723
6723
  if (!sub.id) {
6724
- throw new import_common38.NotFoundException(codedError(import_types19.BILLING_ERROR_CODES.SUBSCRIPTION_PK_MISSING));
6724
+ throw new import_common38.NotFoundException(codedError(import_core22.BILLING_ERROR_CODES.SUBSCRIPTION_PK_MISSING));
6725
6725
  }
6726
6726
  return sub.id;
6727
6727
  }
@@ -6729,7 +6729,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
6729
6729
  const tenantId = this.tenantIdResolver(req);
6730
6730
  if (!tenantId) {
6731
6731
  throw new import_common38.NotFoundException({
6732
- code: import_types19.AUTH_ERROR_CODES.TENANT_CONTEXT_MISSING,
6732
+ code: import_core22.AUTH_ERROR_CODES.TENANT_CONTEXT_MISSING,
6733
6733
  message: "No tenant ID found on the request"
6734
6734
  });
6735
6735
  }
@@ -6739,7 +6739,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
6739
6739
  const sub = await this.subscriptionUsage.findForTenant(tenantId);
6740
6740
  if (!sub) {
6741
6741
  throw new import_common38.NotFoundException({
6742
- code: import_types19.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
6742
+ code: import_core22.BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
6743
6743
  message: `No subscription for tenant ${tenantId}`,
6744
6744
  params: {
6745
6745
  tenantId
@@ -6921,6 +6921,7 @@ __export(catalog_exports, {
6921
6921
  BUNDLE_REPOSITORY_TOKEN: () => BUNDLE_REPOSITORY_TOKEN,
6922
6922
  BundlesService: () => BundlesService,
6923
6923
  CATALOG_ENTRY_REPOSITORY_TOKEN: () => CATALOG_ENTRY_REPOSITORY_TOKEN,
6924
+ CATALOG_FEATURE_UI_REGISTRY_TOKEN: () => CATALOG_FEATURE_UI_REGISTRY_TOKEN,
6924
6925
  CATALOG_SERVICE_CONFIG_TOKEN: () => CATALOG_SERVICE_CONFIG_TOKEN,
6925
6926
  CatalogEntriesService: () => CatalogEntriesService,
6926
6927
  CatalogModule: () => CatalogModule,
@@ -6982,14 +6983,14 @@ __export(catalog_exports, {
6982
6983
 
6983
6984
  // src/catalog/bundles.service.ts
6984
6985
  var import_common41 = require("@nestjs/common");
6985
- var import_types20 = require("@saasicat/types");
6986
+ var import_core24 = require("@saasicat/core");
6986
6987
 
6987
6988
  // src/discovery/discovery.scanner.ts
6988
6989
  var import_node_crypto2 = require("crypto");
6989
6990
  var import_node_fs2 = require("fs");
6990
6991
  var import_node_path2 = require("path");
6991
6992
  var import_common40 = require("@nestjs/common");
6992
- var import_core4 = require("@nestjs/core");
6993
+ var import_core23 = require("@nestjs/core");
6993
6994
  function _ts_decorate41(decorators, target, key, desc) {
6994
6995
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6995
6996
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -7011,8 +7012,8 @@ var DEFAULT_APP_INFO = {
7011
7012
  key: "unknown",
7012
7013
  version: "0.0.0"
7013
7014
  };
7014
- var DISCOVERY_APP_INFO_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/DiscoveryAppInfo");
7015
- var DISCOVERY_SNAPSHOT_PATH_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/DiscoverySnapshotPath");
7015
+ var DISCOVERY_APP_INFO_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/DiscoveryAppInfo");
7016
+ var DISCOVERY_SNAPSHOT_PATH_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/DiscoverySnapshotPath");
7016
7017
  var DiscoveryScanner = class _DiscoveryScanner {
7017
7018
  static {
7018
7019
  __name(this, "DiscoveryScanner");
@@ -7174,18 +7175,18 @@ var DiscoveryScanner = class _DiscoveryScanner {
7174
7175
  };
7175
7176
  DiscoveryScanner = _ts_decorate41([
7176
7177
  (0, import_common40.Injectable)(),
7177
- _ts_param27(0, (0, import_common40.Inject)(import_core4.DiscoveryService)),
7178
- _ts_param27(1, (0, import_common40.Inject)(import_core4.MetadataScanner)),
7179
- _ts_param27(2, (0, import_common40.Inject)(import_core4.Reflector)),
7178
+ _ts_param27(0, (0, import_common40.Inject)(import_core23.DiscoveryService)),
7179
+ _ts_param27(1, (0, import_common40.Inject)(import_core23.MetadataScanner)),
7180
+ _ts_param27(2, (0, import_common40.Inject)(import_core23.Reflector)),
7180
7181
  _ts_param27(3, (0, import_common40.Optional)()),
7181
7182
  _ts_param27(3, (0, import_common40.Inject)(DISCOVERY_APP_INFO_TOKEN)),
7182
7183
  _ts_param27(4, (0, import_common40.Optional)()),
7183
7184
  _ts_param27(4, (0, import_common40.Inject)(DISCOVERY_SNAPSHOT_PATH_TOKEN)),
7184
7185
  _ts_metadata30("design:type", Function),
7185
7186
  _ts_metadata30("design:paramtypes", [
7186
- typeof import_core4.DiscoveryService === "undefined" ? Object : import_core4.DiscoveryService,
7187
- typeof import_core4.MetadataScanner === "undefined" ? Object : import_core4.MetadataScanner,
7188
- typeof import_core4.Reflector === "undefined" ? Object : import_core4.Reflector,
7187
+ typeof import_core23.DiscoveryService === "undefined" ? Object : import_core23.DiscoveryService,
7188
+ typeof import_core23.MetadataScanner === "undefined" ? Object : import_core23.MetadataScanner,
7189
+ typeof import_core23.Reflector === "undefined" ? Object : import_core23.Reflector,
7189
7190
  typeof DiscoveryAppInfo === "undefined" ? Object : DiscoveryAppInfo,
7190
7191
  Object
7191
7192
  ])
@@ -7506,7 +7507,7 @@ var BundlesService = class _BundlesService {
7506
7507
  const bundle2 = await this.repo.findById(bundleId);
7507
7508
  if (!bundle2) {
7508
7509
  throw new import_common41.NotFoundException({
7509
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_NOT_FOUND,
7510
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_NOT_FOUND,
7510
7511
  message: `Bundle '${bundleId}' not found`,
7511
7512
  params: {
7512
7513
  bundleId
@@ -7523,7 +7524,7 @@ var BundlesService = class _BundlesService {
7523
7524
  const existing = await this.repo.findByKey(data.projectKey, data.bundleKey);
7524
7525
  if (existing) {
7525
7526
  throw new import_common41.UnprocessableEntityException({
7526
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_ALREADY_EXISTS,
7527
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_ALREADY_EXISTS,
7527
7528
  message: `Bundle '${data.bundleKey}' already exists in project '${data.projectKey}'`,
7528
7529
  params: {
7529
7530
  bundleKey: data.bundleKey,
@@ -7537,7 +7538,7 @@ var BundlesService = class _BundlesService {
7537
7538
  const existing = await this.repo.findById(bundleId);
7538
7539
  if (!existing) {
7539
7540
  throw new import_common41.NotFoundException({
7540
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_NOT_FOUND,
7541
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_NOT_FOUND,
7541
7542
  message: `Bundle '${bundleId}' not found`,
7542
7543
  params: {
7543
7544
  bundleId
@@ -7550,7 +7551,7 @@ var BundlesService = class _BundlesService {
7550
7551
  const existing = await this.repo.findById(bundleId);
7551
7552
  if (!existing) {
7552
7553
  throw new import_common41.NotFoundException({
7553
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_NOT_FOUND,
7554
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_NOT_FOUND,
7554
7555
  message: `Bundle '${bundleId}' not found`,
7555
7556
  params: {
7556
7557
  bundleId
@@ -7569,7 +7570,7 @@ var BundlesService = class _BundlesService {
7569
7570
  const existing = await this.repo.findVersionById(versionId);
7570
7571
  if (!existing) {
7571
7572
  throw new import_common41.NotFoundException({
7572
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
7573
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
7573
7574
  message: `BundleVersion '${versionId}' not found`,
7574
7575
  params: {
7575
7576
  bundleVersionId: versionId
@@ -7578,7 +7579,7 @@ var BundlesService = class _BundlesService {
7578
7579
  }
7579
7580
  if (existing.publishedAt !== null) {
7580
7581
  throw new import_common41.UnprocessableEntityException({
7581
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_ALREADY_PUBLISHED,
7582
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_ALREADY_PUBLISHED,
7582
7583
  message: `BundleVersion '${versionId}' is already published and cannot be discarded.`,
7583
7584
  params: {
7584
7585
  versionId
@@ -7587,7 +7588,7 @@ var BundlesService = class _BundlesService {
7587
7588
  }
7588
7589
  if (typeof this.repo.deleteDraft !== "function") {
7589
7590
  throw new import_common41.UnprocessableEntityException({
7590
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED,
7591
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED,
7591
7592
  message: "Discard is not implemented in the current repository. Implement BundleRepository.deleteDraft."
7592
7593
  });
7593
7594
  }
@@ -7603,7 +7604,7 @@ var BundlesService = class _BundlesService {
7603
7604
  const version = await this.repo.findVersionById(versionId);
7604
7605
  if (!version) {
7605
7606
  throw new import_common41.NotFoundException({
7606
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
7607
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
7607
7608
  message: `BundleVersion '${versionId}' not found`,
7608
7609
  params: {
7609
7610
  bundleVersionId: versionId
@@ -7651,7 +7652,7 @@ var BundlesService = class _BundlesService {
7651
7652
  const bundle2 = await this.repo.findById(data.bundleId);
7652
7653
  if (!bundle2) {
7653
7654
  throw new import_common41.NotFoundException({
7654
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_NOT_FOUND,
7655
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_NOT_FOUND,
7655
7656
  message: `Bundle '${data.bundleId}' not found`,
7656
7657
  params: {
7657
7658
  bundleId: data.bundleId
@@ -7661,7 +7662,7 @@ var BundlesService = class _BundlesService {
7661
7662
  const existingDraft = await this.repo.findCurrentDraft(data.bundleId);
7662
7663
  if (existingDraft) {
7663
7664
  throw new import_common41.UnprocessableEntityException({
7664
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_DRAFT_ALREADY_EXISTS,
7665
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_DRAFT_ALREADY_EXISTS,
7665
7666
  message: `Bundle '${bundle2.bundleKey}' already has a draft version v${existingDraft.version}; publish or discard it first`,
7666
7667
  params: {
7667
7668
  bundleKey: bundle2.bundleKey,
@@ -7700,7 +7701,7 @@ var BundlesService = class _BundlesService {
7700
7701
  const existing = await this.repo.findVersionById(versionId);
7701
7702
  if (!existing) {
7702
7703
  throw new import_common41.NotFoundException({
7703
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
7704
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
7704
7705
  message: `BundleVersion '${versionId}' not found`,
7705
7706
  params: {
7706
7707
  bundleVersionId: versionId
@@ -7710,10 +7711,10 @@ var BundlesService = class _BundlesService {
7710
7711
  const [annotated] = await this.annotateEditability([
7711
7712
  existing
7712
7713
  ]);
7713
- const { editable } = (0, import_types20.isVersionEditable)(annotated);
7714
+ const { editable } = (0, import_core24.isVersionEditable)(annotated);
7714
7715
  if (!editable) {
7715
7716
  throw new import_common41.UnprocessableEntityException({
7716
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_EDITABLE,
7717
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_EDITABLE,
7717
7718
  message: `BundleVersion '${versionId}' is not editable. Only drafts and published versions are editable that are latest-in-chain, bind no subscription yet, and whose validFrom lies in the future.`,
7718
7719
  params: {
7719
7720
  versionId
@@ -7749,7 +7750,7 @@ var BundlesService = class _BundlesService {
7749
7750
  const draft = await this.repo.findVersionById(versionId);
7750
7751
  if (!draft) {
7751
7752
  throw new import_common41.NotFoundException({
7752
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
7753
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_NOT_FOUND,
7753
7754
  message: `BundleVersion '${versionId}' not found`,
7754
7755
  params: {
7755
7756
  bundleVersionId: versionId
@@ -7758,7 +7759,7 @@ var BundlesService = class _BundlesService {
7758
7759
  }
7759
7760
  if (draft.publishedAt !== null) {
7760
7761
  throw new import_common41.UnprocessableEntityException({
7761
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_ALREADY_PUBLISHED,
7762
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_ALREADY_PUBLISHED,
7762
7763
  message: `BundleVersion '${versionId}' is already published`,
7763
7764
  params: {
7764
7765
  versionId
@@ -7776,7 +7777,7 @@ var BundlesService = class _BundlesService {
7776
7777
  const explicitZero = /* @__PURE__ */ __name((v) => v !== null && v !== void 0 && Number.parseFloat(String(v)) <= 0, "explicitZero");
7777
7778
  if (explicitZero(draft.monthlyNet) || explicitZero(draft.yearlyNet)) {
7778
7779
  throw new import_common41.UnprocessableEntityException({
7779
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_ZERO_PRICE,
7780
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_ZERO_PRICE,
7780
7781
  message: "A bundle version cannot be published with an explicit price of 0.00 (guard against seed placeholders). For free bundles leave it null, or set allowZeroPrice.",
7781
7782
  monthlyNet: draft.monthlyNet,
7782
7783
  yearlyNet: draft.yearlyNet
@@ -7787,14 +7788,14 @@ var BundlesService = class _BundlesService {
7787
7788
  const validFromInput = publishMeta.validFrom ?? draft.validFrom;
7788
7789
  if (!validFromInput) {
7789
7790
  throw new import_common41.UnprocessableEntityException({
7790
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_REQUIRED,
7791
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_REQUIRED,
7791
7792
  message: "validFrom must be set when publishing (on the draft or the publish call).."
7792
7793
  });
7793
7794
  }
7794
7795
  const validFrom = new Date(validFromInput);
7795
7796
  if (Number.isNaN(validFrom.getTime())) {
7796
7797
  throw new import_common41.UnprocessableEntityException({
7797
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_INVALID,
7798
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_INVALID,
7798
7799
  message: `validFrom '${validFromInput}' is not a valid date`,
7799
7800
  params: {
7800
7801
  validFrom: validFromInput
@@ -7805,7 +7806,7 @@ var BundlesService = class _BundlesService {
7805
7806
  const prevFrom = new Date(previous.validFrom);
7806
7807
  if (validFrom <= prevFrom) {
7807
7808
  throw new import_common41.UnprocessableEntityException({
7808
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_AFTER_PREVIOUS,
7809
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_AFTER_PREVIOUS,
7809
7810
  message: `validFrom (${validFrom.toISOString()}) must be strictly after the validFrom of the previous version (${previous.validFrom}).`,
7810
7811
  params: {
7811
7812
  validFrom: validFrom.toISOString(),
@@ -7819,7 +7820,7 @@ var BundlesService = class _BundlesService {
7819
7820
  const requiredStart = new Date(prevUntil.getTime() + dayMs);
7820
7821
  if (validFrom.getTime() !== requiredStart.getTime()) {
7821
7822
  throw new import_common41.UnprocessableEntityException({
7822
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_GAPLESS,
7823
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_GAPLESS,
7823
7824
  message: `The predecessor has validUntil=${previous.validUntil.slice(0, 10)} \u2014 the successor must start seamlessly on the next day (${requiredStart.toISOString().slice(0, 10)}). Received: ${validFrom.toISOString().slice(0, 10)}.`,
7824
7825
  params: {
7825
7826
  received: validFrom.toISOString().slice(0, 10)
@@ -7834,7 +7835,7 @@ var BundlesService = class _BundlesService {
7834
7835
  const validUntil = validUntilInput ? new Date(validUntilInput) : null;
7835
7836
  if (validUntil && Number.isNaN(validUntil.getTime())) {
7836
7837
  throw new import_common41.UnprocessableEntityException({
7837
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_UNTIL_INVALID,
7838
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_UNTIL_INVALID,
7838
7839
  message: `validUntil '${validUntilInput}' is not a valid date`,
7839
7840
  params: {
7840
7841
  validUntil: validUntilInput
@@ -7843,7 +7844,7 @@ var BundlesService = class _BundlesService {
7843
7844
  }
7844
7845
  if (validUntil && validUntil <= validFrom) {
7845
7846
  throw new import_common41.UnprocessableEntityException({
7846
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_UNTIL_BEFORE_FROM,
7847
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_UNTIL_BEFORE_FROM,
7847
7848
  message: `validUntil (${validUntil.toISOString()}) must be strictly after validFrom (${validFrom.toISOString()}).`,
7848
7849
  params: {
7849
7850
  validUntil: validUntil.toISOString(),
@@ -7851,7 +7852,7 @@ var BundlesService = class _BundlesService {
7851
7852
  }
7852
7853
  });
7853
7854
  }
7854
- const diff = previous ? (0, import_types5.classifyBundleVersionDiff)({
7855
+ const diff = previous ? (0, import_core6.classifyBundleVersionDiff)({
7855
7856
  features: previous.features,
7856
7857
  quotas: previous.quotas,
7857
7858
  monthlyNet: previous.monthlyNet,
@@ -7867,7 +7868,7 @@ var BundlesService = class _BundlesService {
7867
7868
  };
7868
7869
  if (!diff.nonRegressive && !publishMeta.forceRegressive) {
7869
7870
  throw new import_common41.UnprocessableEntityException({
7870
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_REGRESSION,
7871
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_REGRESSION,
7871
7872
  message: "This bundle version is regressive (feature removed / quota lowered / price raised). Publishing requires an explicit `forceRegressive: true` (UI confirmation dialog with MFA).",
7872
7873
  changes: diff.changes
7873
7874
  });
@@ -7907,7 +7908,7 @@ var BundlesService = class _BundlesService {
7907
7908
  const hasHardBlockingWarning = blocking.some((w) => w.code === "BUNDLE_PLAN_KEY_UNKNOWN");
7908
7909
  if (this.mode === "blocking" || hasHardBlockingWarning) {
7909
7910
  throw new import_common41.UnprocessableEntityException({
7910
- code: import_types20.CATALOG_ERROR_CODES.STRICT_MODE_VIOLATIONS,
7911
+ code: import_core24.CATALOG_ERROR_CODES.STRICT_MODE_VIOLATIONS,
7911
7912
  message: "The strict-mode check found drift against the discovery snapshot.",
7912
7913
  warnings
7913
7914
  });
@@ -7921,7 +7922,7 @@ var BundlesService = class _BundlesService {
7921
7922
  if (!validFromInput) {
7922
7923
  if (existing.publishedAt !== null) {
7923
7924
  throw new import_common41.UnprocessableEntityException({
7924
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_REQUIRED,
7925
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_REQUIRED,
7925
7926
  message: "Published bundle versions must keep a validFrom. Set a new future date, or edit the draft before publishing."
7926
7927
  });
7927
7928
  }
@@ -7930,7 +7931,7 @@ var BundlesService = class _BundlesService {
7930
7931
  const validFrom = this.parseRequiredBundleDate(validFromInput, "validFrom", "BUNDLE_VERSION_VALID_FROM_INVALID");
7931
7932
  if (existing.publishedAt !== null && validFrom.getTime() <= Date.now()) {
7932
7933
  throw new import_common41.UnprocessableEntityException({
7933
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_FUTURE,
7934
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_FUTURE,
7934
7935
  message: `validFrom (${validFrom.toISOString()}) must, for a published-but-future bundle version, still lie in the future.`,
7935
7936
  params: {
7936
7937
  validFrom: validFrom.toISOString()
@@ -7939,7 +7940,7 @@ var BundlesService = class _BundlesService {
7939
7940
  }
7940
7941
  if (validUntil && validUntil <= validFrom) {
7941
7942
  throw new import_common41.UnprocessableEntityException({
7942
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_UNTIL_BEFORE_FROM,
7943
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_UNTIL_BEFORE_FROM,
7943
7944
  message: `validUntil (${validUntil.toISOString()}) must be strictly after validFrom (${validFrom.toISOString()}).`,
7944
7945
  params: {
7945
7946
  validUntil: validUntil.toISOString(),
@@ -7953,7 +7954,7 @@ var BundlesService = class _BundlesService {
7953
7954
  if (Number.isNaN(previousValidFrom.getTime())) return;
7954
7955
  if (validFrom <= previousValidFrom) {
7955
7956
  throw new import_common41.UnprocessableEntityException({
7956
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_AFTER_PREVIOUS,
7957
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_AFTER_PREVIOUS,
7957
7958
  message: `validFrom (${validFrom.toISOString()}) must be strictly after the validFrom of the previous version (${previous.validFrom}).`,
7958
7959
  params: {
7959
7960
  validFrom: validFrom.toISOString(),
@@ -7968,7 +7969,7 @@ var BundlesService = class _BundlesService {
7968
7969
  const requiredStart = new Date(previousValidUntil.getTime() + dayMs);
7969
7970
  if (validFrom.getTime() !== requiredStart.getTime()) {
7970
7971
  throw new import_common41.UnprocessableEntityException({
7971
- code: import_types20.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_GAPLESS,
7972
+ code: import_core24.CATALOG_ERROR_CODES.BUNDLE_VERSION_VALID_FROM_NOT_GAPLESS,
7972
7973
  message: `The predecessor has validUntil=${previous.validUntil.slice(0, 10)} \u2014 the successor must start seamlessly on the next day (${requiredStart.toISOString().slice(0, 10)}). Received: ${validFrom.toISOString().slice(0, 10)}.`,
7973
7974
  params: {
7974
7975
  received: validFrom.toISOString().slice(0, 10)
@@ -8031,7 +8032,7 @@ BundlesService = _ts_decorate42([
8031
8032
 
8032
8033
  // src/catalog/marketing-projections.service.ts
8033
8034
  var import_common42 = require("@nestjs/common");
8034
- var import_types21 = require("@saasicat/types");
8035
+ var import_core25 = require("@saasicat/core");
8035
8036
  function _ts_decorate43(decorators, target, key, desc) {
8036
8037
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
8037
8038
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -8064,7 +8065,7 @@ var MarketingProjectionsService = class {
8064
8065
  const row = await this.repo.findById(id);
8065
8066
  if (!row) {
8066
8067
  throw new import_common42.NotFoundException({
8067
- code: import_types21.CATALOG_ERROR_CODES.MARKETING_PROJECTION_NOT_FOUND,
8068
+ code: import_core25.CATALOG_ERROR_CODES.MARKETING_PROJECTION_NOT_FOUND,
8068
8069
  message: `MarketingProjection '${id}' not found`,
8069
8070
  params: {
8070
8071
  projectionId: id
@@ -8078,7 +8079,7 @@ var MarketingProjectionsService = class {
8078
8079
  const existing = await this.repo.findByTarget(data.targetType, data.targetVersionId, locale);
8079
8080
  if (existing) {
8080
8081
  throw new import_common42.ConflictException({
8081
- code: import_types21.CATALOG_ERROR_CODES.MARKETING_PROJECTION_ALREADY_EXISTS,
8082
+ code: import_core25.CATALOG_ERROR_CODES.MARKETING_PROJECTION_ALREADY_EXISTS,
8082
8083
  message: `Marketing projection for ${data.targetType}/${data.targetVersionId}/${locale} already exists \u2014 use PATCH to edit it`,
8083
8084
  params: {
8084
8085
  targetType: data.targetType,
@@ -8096,7 +8097,7 @@ var MarketingProjectionsService = class {
8096
8097
  const existing = await this.repo.findById(id);
8097
8098
  if (!existing) {
8098
8099
  throw new import_common42.NotFoundException({
8099
- code: import_types21.CATALOG_ERROR_CODES.MARKETING_PROJECTION_NOT_FOUND,
8100
+ code: import_core25.CATALOG_ERROR_CODES.MARKETING_PROJECTION_NOT_FOUND,
8100
8101
  message: `MarketingProjection '${id}' not found`,
8101
8102
  params: {
8102
8103
  projectionId: id
@@ -8109,7 +8110,7 @@ var MarketingProjectionsService = class {
8109
8110
  const existing = await this.repo.findById(id);
8110
8111
  if (!existing) {
8111
8112
  throw new import_common42.NotFoundException({
8112
- code: import_types21.CATALOG_ERROR_CODES.MARKETING_PROJECTION_NOT_FOUND,
8113
+ code: import_core25.CATALOG_ERROR_CODES.MARKETING_PROJECTION_NOT_FOUND,
8113
8114
  message: `MarketingProjection '${id}' not found`,
8114
8115
  params: {
8115
8116
  projectionId: id
@@ -8130,7 +8131,7 @@ MarketingProjectionsService = _ts_decorate43([
8130
8131
 
8131
8132
  // src/catalog/catalog-entries.service.ts
8132
8133
  var import_common43 = require("@nestjs/common");
8133
- var import_types22 = require("@saasicat/types");
8134
+ var import_core26 = require("@saasicat/core");
8134
8135
 
8135
8136
  // src/catalog/approval-signature.ts
8136
8137
  function featureApprovalSignature(featureKey, snapshot) {
@@ -8281,7 +8282,7 @@ var CatalogEntriesService = class _CatalogEntriesService {
8281
8282
  const existing = await this.repo.findFeature(projectKey, featureKey);
8282
8283
  if (!existing) {
8283
8284
  throw new import_common43.NotFoundException({
8284
- code: import_types22.CATALOG_ERROR_CODES.FEATURE_NOT_FOUND,
8285
+ code: import_core26.CATALOG_ERROR_CODES.FEATURE_NOT_FOUND,
8285
8286
  message: `Feature '${featureKey}' not found in project '${projectKey}'`,
8286
8287
  params: {
8287
8288
  featureKey,
@@ -8296,7 +8297,7 @@ var CatalogEntriesService = class _CatalogEntriesService {
8296
8297
  const existing = await this.repo.findQuota(projectKey, quotaKey);
8297
8298
  if (!existing) {
8298
8299
  throw new import_common43.NotFoundException({
8299
- code: import_types22.CATALOG_ERROR_CODES.QUOTA_NOT_FOUND,
8300
+ code: import_core26.CATALOG_ERROR_CODES.QUOTA_NOT_FOUND,
8300
8301
  message: `Quota '${quotaKey}' not found in project '${projectKey}'`,
8301
8302
  params: {
8302
8303
  quotaKey,
@@ -8308,7 +8309,7 @@ var CatalogEntriesService = class _CatalogEntriesService {
8308
8309
  const discovered = snapshot.quotas.find((q) => q.quotaKey === quotaKey);
8309
8310
  if (!discovered) {
8310
8311
  throw new import_common43.UnprocessableEntityException({
8311
- code: import_types22.CATALOG_ERROR_CODES.QUOTA_NOT_IN_DISCOVERY_SNAPSHOT,
8312
+ code: import_core26.CATALOG_ERROR_CODES.QUOTA_NOT_IN_DISCOVERY_SNAPSHOT,
8312
8313
  message: `Quota '${quotaKey}' is not in the discovery snapshot \u2014 a quota that is not declared in code cannot be approved`,
8313
8314
  params: {
8314
8315
  quotaKey
@@ -8321,7 +8322,7 @@ var CatalogEntriesService = class _CatalogEntriesService {
8321
8322
  resolveReviewUpdate(existing, target, reviewedBy, signatureOf) {
8322
8323
  if (!REVIEW_TRANSITIONS[existing.discoveryStatus].includes(target)) {
8323
8324
  throw new import_common43.UnprocessableEntityException({
8324
- code: import_types22.CATALOG_ERROR_CODES.DISCOVERY_STATUS_TRANSITION_INVALID,
8325
+ code: import_core26.CATALOG_ERROR_CODES.DISCOVERY_STATUS_TRANSITION_INVALID,
8325
8326
  message: `Transition '${existing.discoveryStatus}' \u2192 '${target}' is not allowed`,
8326
8327
  params: {
8327
8328
  from: existing.discoveryStatus,
@@ -8333,7 +8334,7 @@ var CatalogEntriesService = class _CatalogEntriesService {
8333
8334
  const snapshot = resolveDiscoverySnapshot(this.snapshot, this.scanner);
8334
8335
  if (!snapshot) {
8335
8336
  throw new import_common43.UnprocessableEntityException({
8336
- code: import_types22.CATALOG_ERROR_CODES.DISCOVERY_NOT_INITIALIZED,
8337
+ code: import_core26.CATALOG_ERROR_CODES.DISCOVERY_NOT_INITIALIZED,
8337
8338
  message: "Approval requires a discovery snapshot \u2014 discovery is not initialised (#25)"
8338
8339
  });
8339
8340
  }
@@ -8562,7 +8563,7 @@ CatalogEntriesService = _ts_decorate44([
8562
8563
  _ts_param30(3, (0, import_common43.Optional)()),
8563
8564
  _ts_param30(3, (0, import_common43.Inject)(DiscoveryScanner)),
8564
8565
  _ts_param30(4, (0, import_common43.Optional)()),
8565
- _ts_param30(4, (0, import_common43.Inject)(FEATURE_UI_REGISTRY_TOKEN)),
8566
+ _ts_param30(4, (0, import_common43.Inject)(CATALOG_FEATURE_UI_REGISTRY_TOKEN)),
8566
8567
  _ts_metadata33("design:type", Function),
8567
8568
  _ts_metadata33("design:paramtypes", [
8568
8569
  typeof CatalogEntryRepository === "undefined" ? Object : CatalogEntryRepository,
@@ -9035,7 +9036,7 @@ __name(buildCatalogEntriesController, "buildCatalogEntriesController");
9035
9036
 
9036
9037
  // src/catalog/promotions.service.ts
9037
9038
  var import_common46 = require("@nestjs/common");
9038
- var import_types23 = require("@saasicat/types");
9039
+ var import_core27 = require("@saasicat/core");
9039
9040
  function _ts_decorate48(decorators, target, key, desc) {
9040
9041
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9041
9042
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -9070,7 +9071,7 @@ var PromotionsService = class {
9070
9071
  const row = await this.repo.findById(id);
9071
9072
  if (!row) {
9072
9073
  throw new import_common46.NotFoundException({
9073
- code: import_types23.CATALOG_ERROR_CODES.PROMOTION_NOT_FOUND,
9074
+ code: import_core27.CATALOG_ERROR_CODES.PROMOTION_NOT_FOUND,
9074
9075
  message: `Promotion '${id}' not found`,
9075
9076
  params: {
9076
9077
  promotionId: id
@@ -9086,7 +9087,7 @@ var PromotionsService = class {
9086
9087
  const existing = await this.repo.findById(id);
9087
9088
  if (!existing) {
9088
9089
  throw new import_common46.NotFoundException({
9089
- code: import_types23.CATALOG_ERROR_CODES.PROMOTION_NOT_FOUND,
9090
+ code: import_core27.CATALOG_ERROR_CODES.PROMOTION_NOT_FOUND,
9090
9091
  message: `Promotion '${id}' not found`,
9091
9092
  params: {
9092
9093
  promotionId: id
@@ -9099,7 +9100,7 @@ var PromotionsService = class {
9099
9100
  const existing = await this.repo.findById(id);
9100
9101
  if (!existing) {
9101
9102
  throw new import_common46.NotFoundException({
9102
- code: import_types23.CATALOG_ERROR_CODES.PROMOTION_NOT_FOUND,
9103
+ code: import_core27.CATALOG_ERROR_CODES.PROMOTION_NOT_FOUND,
9103
9104
  message: `Promotion '${id}' not found`,
9104
9105
  params: {
9105
9106
  promotionId: id
@@ -9658,7 +9659,7 @@ __name(buildMarketingSettingsController, "buildMarketingSettingsController");
9658
9659
 
9659
9660
  // src/catalog/public-marketing-catalog.service.ts
9660
9661
  var import_common50 = require("@nestjs/common");
9661
- var import_types24 = require("@saasicat/types");
9662
+ var import_core28 = require("@saasicat/core");
9662
9663
  function _ts_decorate54(decorators, target, key, desc) {
9663
9664
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9664
9665
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -9761,7 +9762,7 @@ var PublicMarketingCatalogService = class {
9761
9762
  });
9762
9763
  }
9763
9764
  out.sort((a, b) => b.priority - a.priority);
9764
- const requiresIndex = (0, import_types24.buildFeatureRequiresIndex)([
9765
+ const requiresIndex = (0, import_core28.buildFeatureRequiresIndex)([
9765
9766
  ...labelMeta.features
9766
9767
  ].map(([featureKey, meta]) => ({
9767
9768
  featureKey,
@@ -9815,7 +9816,7 @@ var PublicMarketingCatalogService = class {
9815
9816
  const features = [
9816
9817
  ...bv.features ?? []
9817
9818
  ];
9818
- const requiresFeatures = (0, import_types24.collectUnsatisfiedRequires)(features, requiresIndex);
9819
+ const requiresFeatures = (0, import_core28.collectUnsatisfiedRequires)(features, requiresIndex);
9819
9820
  return {
9820
9821
  bundleKey: bv.bundleKey,
9821
9822
  label: marketing?.displayLabel || bv.label,
@@ -9959,12 +9960,12 @@ var PublicMarketingCatalogService = class {
9959
9960
  };
9960
9961
  }
9961
9962
  resolvePromo(promotions, targetKey, targetType, locale, monthlyNet, yearlyNet, asOf) {
9962
- const monthlyPromo = (0, import_types24.pickActivePromo)(promotions, targetKey, locale, "monthly", asOf, targetType);
9963
- const yearlyPromo = (0, import_types24.pickActivePromo)(promotions, targetKey, locale, "yearly", asOf, targetType);
9963
+ const monthlyPromo = (0, import_core28.pickActivePromo)(promotions, targetKey, locale, "monthly", asOf, targetType);
9964
+ const yearlyPromo = (0, import_core28.pickActivePromo)(promotions, targetKey, locale, "yearly", asOf, targetType);
9964
9965
  const promo = monthlyPromo ?? yearlyPromo;
9965
9966
  if (!promo) return null;
9966
- const monthlyResult = (0, import_types24.applyPromo)(monthlyPromo, monthlyNet);
9967
- const yearlyResult = (0, import_types24.applyPromo)(yearlyPromo, yearlyNet);
9967
+ const monthlyResult = (0, import_core28.applyPromo)(monthlyPromo, monthlyNet);
9968
+ const yearlyResult = (0, import_core28.applyPromo)(yearlyPromo, yearlyNet);
9968
9969
  const i18n = promo.i18n?.[locale] ?? promo.i18n?.[DEFAULT_LOCALE] ?? {};
9969
9970
  return {
9970
9971
  type: promo.type,
@@ -10071,7 +10072,7 @@ __name(parseAsOf, "parseAsOf");
10071
10072
 
10072
10073
  // src/catalog/plans.service.ts
10073
10074
  var import_common52 = require("@nestjs/common");
10074
- var import_types25 = require("@saasicat/types");
10075
+ var import_core29 = require("@saasicat/core");
10075
10076
  function _ts_decorate56(decorators, target, key, desc) {
10076
10077
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
10077
10078
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -10120,7 +10121,7 @@ var PlansService = class {
10120
10121
  const plan = await this.repo.findById(planId);
10121
10122
  if (!plan) {
10122
10123
  throw new import_common52.NotFoundException({
10123
- code: import_types25.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10124
+ code: import_core29.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10124
10125
  message: `Plan '${planId}' not found`,
10125
10126
  params: {
10126
10127
  planId
@@ -10133,7 +10134,7 @@ var PlansService = class {
10133
10134
  const existing = await this.repo.findByKey(data.projectKey, data.planKey);
10134
10135
  if (existing) {
10135
10136
  throw new import_common52.UnprocessableEntityException({
10136
- code: import_types25.CATALOG_ERROR_CODES.PLAN_ALREADY_EXISTS,
10137
+ code: import_core29.CATALOG_ERROR_CODES.PLAN_ALREADY_EXISTS,
10137
10138
  message: `Plan '${data.planKey}' already exists in project '${data.projectKey}'`,
10138
10139
  params: {
10139
10140
  planKey: data.planKey,
@@ -10147,7 +10148,7 @@ var PlansService = class {
10147
10148
  const existing = await this.repo.findById(planId);
10148
10149
  if (!existing) {
10149
10150
  throw new import_common52.NotFoundException({
10150
- code: import_types25.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10151
+ code: import_core29.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10151
10152
  message: `Plan '${planId}' not found`,
10152
10153
  params: {
10153
10154
  planId
@@ -10160,7 +10161,7 @@ var PlansService = class {
10160
10161
  const existing = await this.repo.findById(planId);
10161
10162
  if (!existing) {
10162
10163
  throw new import_common52.NotFoundException({
10163
- code: import_types25.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10164
+ code: import_core29.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10164
10165
  message: `Plan '${planId}' not found`,
10165
10166
  params: {
10166
10167
  planId
@@ -10185,7 +10186,7 @@ var PlansService = class {
10185
10186
  const existing = await this.repo.findById(planId);
10186
10187
  if (!existing) {
10187
10188
  throw new import_common52.NotFoundException({
10188
- code: import_types25.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10189
+ code: import_core29.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10189
10190
  message: `Plan '${planId}' not found`,
10190
10191
  params: {
10191
10192
  planId
@@ -10196,7 +10197,7 @@ var PlansService = class {
10196
10197
  await this.assertNoDrafts(existing.planKey);
10197
10198
  if (typeof this.repo.hardDelete !== "function") {
10198
10199
  throw new import_common52.UnprocessableEntityException({
10199
- code: import_types25.CATALOG_ERROR_CODES.PLAN_HARD_DELETE_NOT_IMPLEMENTED,
10200
+ code: import_core29.CATALOG_ERROR_CODES.PLAN_HARD_DELETE_NOT_IMPLEMENTED,
10200
10201
  message: "Hard delete is not implemented in the current repository. Implement PlanRepository.hardDelete."
10201
10202
  });
10202
10203
  }
@@ -10217,7 +10218,7 @@ var PlansService = class {
10217
10218
  const live = published.filter((v) => v.supersededAt === null).length;
10218
10219
  const superseded = published.length - live;
10219
10220
  throw new import_common52.UnprocessableEntityException({
10220
- code: import_types25.CATALOG_ERROR_CODES.PLAN_HAS_PUBLISHED_VERSIONS,
10221
+ code: import_core29.CATALOG_ERROR_CODES.PLAN_HAS_PUBLISHED_VERSIONS,
10221
10222
  message: `Plan '${planKey}' cannot be ${op === "hard-delete" ? "deleted" : "archived"} \u2014 it has ${published.length} published version(s) (${live} live, ${superseded} superseded). Existing subscriptions reference those versions (contract protection P1), so the plan record must be preserved.`,
10222
10223
  params: {
10223
10224
  planKey,
@@ -10234,7 +10235,7 @@ var PlansService = class {
10234
10235
  const drafts = versions.filter((v) => v.publishedAt === null);
10235
10236
  if (drafts.length === 0) return;
10236
10237
  throw new import_common52.UnprocessableEntityException({
10237
- code: import_types25.CATALOG_ERROR_CODES.PLAN_HAS_DRAFTS,
10238
+ code: import_core29.CATALOG_ERROR_CODES.PLAN_HAS_DRAFTS,
10238
10239
  message: `Plan '${planKey}' still has ${drafts.length} open draft version(s). Discard them first (DELETE /admin/catalog/plan-versions/:id) or publish them.`,
10239
10240
  params: {
10240
10241
  planKey
@@ -10257,7 +10258,7 @@ PlansService = _ts_decorate56([
10257
10258
 
10258
10259
  // src/catalog/plan-versions.service.ts
10259
10260
  var import_common53 = require("@nestjs/common");
10260
- var import_types26 = require("@saasicat/types");
10261
+ var import_core30 = require("@saasicat/core");
10261
10262
  function _ts_decorate57(decorators, target, key, desc) {
10262
10263
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
10263
10264
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -10327,7 +10328,7 @@ var PlanVersionsService = class _PlanVersionsService {
10327
10328
  const existing = await this.repo.findVersionById(versionId);
10328
10329
  if (!existing) {
10329
10330
  throw new import_common53.NotFoundException({
10330
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10331
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10331
10332
  message: `PlanVersion '${versionId}' not found`,
10332
10333
  params: {
10333
10334
  versionId
@@ -10336,7 +10337,7 @@ var PlanVersionsService = class _PlanVersionsService {
10336
10337
  }
10337
10338
  if (existing.publishedAt !== null) {
10338
10339
  throw new import_common53.UnprocessableEntityException({
10339
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_ALREADY_PUBLISHED,
10340
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_ALREADY_PUBLISHED,
10340
10341
  message: `PlanVersion '${versionId}' is already published and cannot be discarded.`,
10341
10342
  params: {
10342
10343
  versionId
@@ -10345,7 +10346,7 @@ var PlanVersionsService = class _PlanVersionsService {
10345
10346
  }
10346
10347
  if (typeof this.repo.deletePlanVersionDraft !== "function") {
10347
10348
  throw new import_common53.UnprocessableEntityException({
10348
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_DISCARD_NOT_IMPLEMENTED,
10349
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_DISCARD_NOT_IMPLEMENTED,
10349
10350
  message: "Discard is not implemented in the current repository. Implement PlanRepository.deletePlanVersionDraft."
10350
10351
  });
10351
10352
  }
@@ -10360,7 +10361,7 @@ var PlanVersionsService = class _PlanVersionsService {
10360
10361
  const plan = await this.repo.findById(planUuid);
10361
10362
  if (!plan) {
10362
10363
  throw new import_common53.NotFoundException({
10363
- code: import_types26.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10364
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10364
10365
  message: `Plan '${planUuid}' not found`,
10365
10366
  params: {
10366
10367
  planId: planUuid
@@ -10374,7 +10375,7 @@ var PlanVersionsService = class _PlanVersionsService {
10374
10375
  const version = await this.repo.findVersionById(versionId);
10375
10376
  if (!version) {
10376
10377
  throw new import_common53.NotFoundException({
10377
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10378
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10378
10379
  message: `PlanVersion '${versionId}' not found`,
10379
10380
  params: {
10380
10381
  versionId
@@ -10418,7 +10419,7 @@ var PlanVersionsService = class _PlanVersionsService {
10418
10419
  const plan = await this.repo.findById(data.planId);
10419
10420
  if (!plan) {
10420
10421
  throw new import_common53.NotFoundException({
10421
- code: import_types26.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10422
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_NOT_FOUND,
10422
10423
  message: `Plan '${data.planId}' not found`,
10423
10424
  params: {
10424
10425
  planId: data.planId
@@ -10429,7 +10430,7 @@ var PlanVersionsService = class _PlanVersionsService {
10429
10430
  const existingDraft = await this.repo.findCurrentDraft(planKey);
10430
10431
  if (existingDraft) {
10431
10432
  throw new import_common53.UnprocessableEntityException({
10432
- code: import_types26.CATALOG_ERROR_CODES.PLAN_DRAFT_ALREADY_EXISTS,
10433
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_DRAFT_ALREADY_EXISTS,
10433
10434
  message: `Plan '${planKey}' already has a draft version v${existingDraft.version}; publish or discard it first`,
10434
10435
  params: {
10435
10436
  planKey,
@@ -10461,7 +10462,7 @@ var PlanVersionsService = class _PlanVersionsService {
10461
10462
  const existing = await this.repo.findVersionById(versionId);
10462
10463
  if (!existing) {
10463
10464
  throw new import_common53.NotFoundException({
10464
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10465
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10465
10466
  message: `PlanVersion '${versionId}' not found`,
10466
10467
  params: {
10467
10468
  versionId
@@ -10471,10 +10472,10 @@ var PlanVersionsService = class _PlanVersionsService {
10471
10472
  const [annotated] = await this.annotateEditability([
10472
10473
  existing
10473
10474
  ]);
10474
- const { editable } = (0, import_types26.isVersionEditable)(annotated);
10475
+ const { editable } = (0, import_core30.isVersionEditable)(annotated);
10475
10476
  if (!editable) {
10476
10477
  throw new import_common53.UnprocessableEntityException({
10477
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_EDITABLE,
10478
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_EDITABLE,
10478
10479
  message: `PlanVersion '${versionId}' is not editable. Only drafts and published versions are editable that are latest-in-chain, bind no subscription yet, and whose validFrom lies in the future.`,
10479
10480
  params: {
10480
10481
  versionId
@@ -10497,7 +10498,7 @@ var PlanVersionsService = class _PlanVersionsService {
10497
10498
  const draft = await this.repo.findVersionById(versionId);
10498
10499
  if (!draft) {
10499
10500
  throw new import_common53.NotFoundException({
10500
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10501
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10501
10502
  message: `PlanVersion '${versionId}' not found`,
10502
10503
  params: {
10503
10504
  versionId
@@ -10506,7 +10507,7 @@ var PlanVersionsService = class _PlanVersionsService {
10506
10507
  }
10507
10508
  if (draft.publishedAt !== null) {
10508
10509
  throw new import_common53.UnprocessableEntityException({
10509
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_ALREADY_PUBLISHED,
10510
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_ALREADY_PUBLISHED,
10510
10511
  message: `PlanVersion '${versionId}' is already published`,
10511
10512
  params: {
10512
10513
  versionId
@@ -10523,7 +10524,7 @@ var PlanVersionsService = class _PlanVersionsService {
10523
10524
  const yearly = Number.parseFloat(String(draft.yearlyNet ?? "0"));
10524
10525
  if (monthly <= 0 || yearly <= 0) {
10525
10526
  throw new import_common53.UnprocessableEntityException({
10526
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_ZERO_PRICE,
10527
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_ZERO_PRICE,
10527
10528
  message: "A plan version cannot be published with a price of 0.00 (guard against seed placeholder). For deliberately free special contracts, set allowZeroPrice.",
10528
10529
  monthlyNet: String(draft.monthlyNet),
10529
10530
  yearlyNet: String(draft.yearlyNet)
@@ -10534,14 +10535,14 @@ var PlanVersionsService = class _PlanVersionsService {
10534
10535
  const validFromInput = publishMeta.validFrom ?? draft.validFrom;
10535
10536
  if (!validFromInput) {
10536
10537
  throw new import_common53.UnprocessableEntityException({
10537
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_FROM_REQUIRED,
10538
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_FROM_REQUIRED,
10538
10539
  message: "validFrom must be set when publishing (on the draft or the publish call).."
10539
10540
  });
10540
10541
  }
10541
10542
  const validFrom = new Date(validFromInput);
10542
10543
  if (Number.isNaN(validFrom.getTime())) {
10543
10544
  throw new import_common53.UnprocessableEntityException({
10544
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_FROM_INVALID,
10545
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_FROM_INVALID,
10545
10546
  message: `validFrom '${validFromInput}' is not a valid date`,
10546
10547
  params: {
10547
10548
  validFrom: validFromInput
@@ -10552,7 +10553,7 @@ var PlanVersionsService = class _PlanVersionsService {
10552
10553
  const prevFrom = new Date(previous.validFrom);
10553
10554
  if (validFrom <= prevFrom) {
10554
10555
  throw new import_common53.UnprocessableEntityException({
10555
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_FROM_NOT_AFTER_PREVIOUS,
10556
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_FROM_NOT_AFTER_PREVIOUS,
10556
10557
  message: `validFrom (${validFrom.toISOString()}) must be strictly after the validFrom of the previous version (${previous.validFrom}).`,
10557
10558
  params: {
10558
10559
  validFrom: validFrom.toISOString(),
@@ -10566,7 +10567,7 @@ var PlanVersionsService = class _PlanVersionsService {
10566
10567
  const requiredStart = new Date(prevUntil.getTime() + dayMs);
10567
10568
  if (validFrom.getTime() !== requiredStart.getTime()) {
10568
10569
  throw new import_common53.UnprocessableEntityException({
10569
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_FROM_NOT_GAPLESS,
10570
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_FROM_NOT_GAPLESS,
10570
10571
  message: `The predecessor has validUntil=${previous.validUntil.slice(0, 10)} \u2014 the successor must start seamlessly on the next day (${requiredStart.toISOString().slice(0, 10)}). Received: ${validFrom.toISOString().slice(0, 10)}.`,
10571
10572
  params: {
10572
10573
  received: validFrom.toISOString().slice(0, 10)
@@ -10581,7 +10582,7 @@ var PlanVersionsService = class _PlanVersionsService {
10581
10582
  const validUntil = validUntilInput ? new Date(validUntilInput) : null;
10582
10583
  if (validUntil && Number.isNaN(validUntil.getTime())) {
10583
10584
  throw new import_common53.UnprocessableEntityException({
10584
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_UNTIL_INVALID,
10585
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_UNTIL_INVALID,
10585
10586
  message: `validUntil '${validUntilInput}' is not a valid date`,
10586
10587
  params: {
10587
10588
  validUntil: validUntilInput
@@ -10590,7 +10591,7 @@ var PlanVersionsService = class _PlanVersionsService {
10590
10591
  }
10591
10592
  if (validUntil && validUntil <= validFrom) {
10592
10593
  throw new import_common53.UnprocessableEntityException({
10593
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_UNTIL_BEFORE_FROM,
10594
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_VALID_UNTIL_BEFORE_FROM,
10594
10595
  message: `validUntil (${validUntil.toISOString()}) must be strictly after validFrom (${validFrom.toISOString()}).`,
10595
10596
  params: {
10596
10597
  validUntil: validUntil.toISOString(),
@@ -10606,13 +10607,13 @@ var PlanVersionsService = class _PlanVersionsService {
10606
10607
  monthlyNet: v.monthlyNet,
10607
10608
  yearlyNet: v.yearlyNet
10608
10609
  }), "fieldsFor");
10609
- const diff = previous ? (0, import_types5.classifyPlanDiff)(fieldsFor(previous), fieldsFor(draft)) : {
10610
+ const diff = previous ? (0, import_core6.classifyPlanDiff)(fieldsFor(previous), fieldsFor(draft)) : {
10610
10611
  changes: [],
10611
10612
  nonRegressive: true
10612
10613
  };
10613
10614
  if (!diff.nonRegressive && !publishMeta.forceRegressive) {
10614
10615
  throw new import_common53.UnprocessableEntityException({
10615
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_REGRESSION,
10616
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_REGRESSION,
10616
10617
  message: "This plan version is regressive (feature removed / quota lowered / price raised). Publishing requires an explicit `forceRegressive: true` (UI confirmation dialog with MFA).",
10617
10618
  changes: diff.changes
10618
10619
  });
@@ -10649,7 +10650,7 @@ var PlanVersionsService = class _PlanVersionsService {
10649
10650
  const existing = await this.repo.findVersionById(versionId);
10650
10651
  if (!existing) {
10651
10652
  throw new import_common53.NotFoundException({
10652
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10653
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_FOUND,
10653
10654
  message: `PlanVersion '${versionId}' not found`,
10654
10655
  params: {
10655
10656
  versionId
@@ -10658,7 +10659,7 @@ var PlanVersionsService = class _PlanVersionsService {
10658
10659
  }
10659
10660
  if (existing.publishedAt === null) {
10660
10661
  throw new import_common53.UnprocessableEntityException({
10661
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_PUBLISHED,
10662
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_NOT_PUBLISHED,
10662
10663
  message: `PlanVersion '${versionId}' is not published and cannot be terminated.`,
10663
10664
  params: {
10664
10665
  versionId
@@ -10667,7 +10668,7 @@ var PlanVersionsService = class _PlanVersionsService {
10667
10668
  }
10668
10669
  if (existing.supersededAt !== null) {
10669
10670
  throw new import_common53.UnprocessableEntityException({
10670
- code: import_types26.CATALOG_ERROR_CODES.PLAN_VERSION_SUPERSEDED,
10671
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_VERSION_SUPERSEDED,
10671
10672
  message: `PlanVersion '${versionId}' has already been superseded by a newer version (supersededAt) and cannot be terminated.`,
10672
10673
  params: {
10673
10674
  versionId
@@ -10676,13 +10677,13 @@ var PlanVersionsService = class _PlanVersionsService {
10676
10677
  }
10677
10678
  if (Number.isNaN(endsAt.getTime())) {
10678
10679
  throw new import_common53.UnprocessableEntityException({
10679
- code: import_types26.CATALOG_ERROR_CODES.PLAN_TERMINATE_INVALID_DATE,
10680
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_TERMINATE_INVALID_DATE,
10680
10681
  message: "endsAt is not a valid date."
10681
10682
  });
10682
10683
  }
10683
10684
  if (endsAt.getTime() <= Date.now()) {
10684
10685
  throw new import_common53.UnprocessableEntityException({
10685
- code: import_types26.CATALOG_ERROR_CODES.PLAN_TERMINATE_DATE_NOT_FUTURE,
10686
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_TERMINATE_DATE_NOT_FUTURE,
10686
10687
  message: `endsAt (${endsAt.toISOString()}) must lie strictly in the future.`,
10687
10688
  params: {
10688
10689
  endsAt: endsAt.toISOString()
@@ -10691,7 +10692,7 @@ var PlanVersionsService = class _PlanVersionsService {
10691
10692
  }
10692
10693
  if (typeof this.repo.terminate !== "function") {
10693
10694
  throw new import_common53.UnprocessableEntityException({
10694
- code: import_types26.CATALOG_ERROR_CODES.PLAN_TERMINATE_NOT_IMPLEMENTED,
10695
+ code: import_core30.CATALOG_ERROR_CODES.PLAN_TERMINATE_NOT_IMPLEMENTED,
10695
10696
  message: "Terminate is not implemented in the current repository. Implement PlanRepository.terminate."
10696
10697
  });
10697
10698
  }
@@ -10710,7 +10711,7 @@ var PlanVersionsService = class _PlanVersionsService {
10710
10711
  if (blockingStrictModeWarnings(warnings).length === 0) return;
10711
10712
  if (this.mode === "blocking") {
10712
10713
  throw new import_common53.UnprocessableEntityException({
10713
- code: import_types26.CATALOG_ERROR_CODES.STRICT_MODE_VIOLATIONS,
10714
+ code: import_core30.CATALOG_ERROR_CODES.STRICT_MODE_VIOLATIONS,
10714
10715
  message: "The strict-mode check found drift against the discovery snapshot.",
10715
10716
  warnings
10716
10717
  });
@@ -12381,7 +12382,7 @@ var CatalogModule = class _CatalogModule {
12381
12382
  }
12382
12383
  },
12383
12384
  {
12384
- provide: FEATURE_UI_REGISTRY_TOKEN,
12385
+ provide: CATALOG_FEATURE_UI_REGISTRY_TOKEN,
12385
12386
  useValue: options.featureUiRegistry ?? null
12386
12387
  },
12387
12388
  BundlesService,
@@ -12657,10 +12658,10 @@ __export(checkout_offer_exports, {
12657
12658
 
12658
12659
  // src/checkout-offer/checkout-offer.service.ts
12659
12660
  var import_common58 = require("@nestjs/common");
12660
- var import_types27 = require("@saasicat/types");
12661
+ var import_core31 = require("@saasicat/core");
12661
12662
 
12662
- // src/checkout-offer/tokens.ts
12663
- var CHECKOUT_OFFER_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/CheckoutOfferRepository");
12663
+ // src/checkout-offer/checkout-offer.tokens.ts
12664
+ var CHECKOUT_OFFER_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/CheckoutOfferRepository");
12664
12665
 
12665
12666
  // src/checkout-offer/checkout-offer.service.ts
12666
12667
  function _ts_decorate66(decorators, target, key, desc) {
@@ -12701,7 +12702,7 @@ var CheckoutOfferService = class {
12701
12702
  const row = await this.repo.findById(id);
12702
12703
  if (!row) {
12703
12704
  throw new import_common58.NotFoundException({
12704
- code: import_types27.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_NOT_FOUND,
12705
+ code: import_core31.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_NOT_FOUND,
12705
12706
  message: `CheckoutOffer '${id}' not found`,
12706
12707
  params: {
12707
12708
  offerId: id
@@ -12760,18 +12761,18 @@ var CheckoutOfferService = class {
12760
12761
  const entries = await this.catalogEntries.listFeatures({
12761
12762
  projectKey: input.projectKey
12762
12763
  });
12763
- const requiresIndex = (0, import_types27.buildFeatureRequiresIndex)(entries);
12764
+ const requiresIndex = (0, import_core31.buildFeatureRequiresIndex)(entries);
12764
12765
  if (requiresIndex.size === 0) return;
12765
12766
  const selected = /* @__PURE__ */ new Set([
12766
12767
  ...await this.resolvePlanFeatures(input),
12767
12768
  ...await this.resolveBundleFeatures(input)
12768
12769
  ]);
12769
- const missingRequires = (0, import_types27.collectUnsatisfiedRequires)([
12770
+ const missingRequires = (0, import_core31.collectUnsatisfiedRequires)([
12770
12771
  ...selected
12771
12772
  ], requiresIndex);
12772
12773
  if (missingRequires.length > 0) {
12773
12774
  throw new import_common58.UnprocessableEntityException({
12774
- code: import_types27.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_FEATURE_DEPENDENCY_UNSATISFIED,
12775
+ code: import_core31.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_FEATURE_DEPENDENCY_UNSATISFIED,
12775
12776
  message: `The selected plan does not cover all feature dependencies: [${missingRequires.join(", ")}] are missing from the plan + selected bundles.`,
12776
12777
  missingRequires
12777
12778
  });
@@ -12852,7 +12853,7 @@ var CheckoutOfferService = class {
12852
12853
  }
12853
12854
  if (violations.length > 0) {
12854
12855
  throw new import_common58.UnprocessableEntityException({
12855
- code: import_types27.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_BUNDLE_VERSION_NOT_BOOKABLE,
12856
+ code: import_core31.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_BUNDLE_VERSION_NOT_BOOKABLE,
12856
12857
  message: "At least one bundle version from the checkout offer is no longer bookable.",
12857
12858
  violations
12858
12859
  });
@@ -12907,14 +12908,14 @@ var CheckoutOfferService = class {
12907
12908
  const hasPlan = lineItems.some((item) => item.kind === "plan");
12908
12909
  if (!hasPlan) {
12909
12910
  throw new import_common58.UnprocessableEntityException({
12910
- code: import_types27.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_PLAN_LINE_ITEM_REQUIRED,
12911
+ code: import_core31.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_PLAN_LINE_ITEM_REQUIRED,
12911
12912
  message: "A checkout offer requires a frozen plan line item."
12912
12913
  });
12913
12914
  }
12914
12915
  const missingBundleVersionIds = input.bundleVersionIds.filter((versionId) => !lineItems.some((item) => item.kind === "bundle" && item.sourceVersionId === versionId));
12915
12916
  if (missingBundleVersionIds.length > 0) {
12916
12917
  throw new import_common58.UnprocessableEntityException({
12917
- code: import_types27.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_BUNDLE_LINE_ITEMS_REQUIRED,
12918
+ code: import_core31.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_BUNDLE_LINE_ITEMS_REQUIRED,
12918
12919
  message: "Every selected bundle version requires a frozen bundle line item.",
12919
12920
  bundleVersionIds: missingBundleVersionIds
12920
12921
  });
@@ -12948,7 +12949,7 @@ var CheckoutOfferService = class {
12948
12949
  assertOpen(existing, action) {
12949
12950
  if (existing.status === "consumed") {
12950
12951
  throw new import_common58.ConflictException({
12951
- code: import_types27.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_ALREADY_CONSUMED,
12952
+ code: import_core31.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_ALREADY_CONSUMED,
12952
12953
  message: `Checkout offer '${existing.id}' has already been consumed and cannot be ${action}`,
12953
12954
  params: {
12954
12955
  offerId: existing.id,
@@ -12958,7 +12959,7 @@ var CheckoutOfferService = class {
12958
12959
  }
12959
12960
  if (existing.status === "expired") {
12960
12961
  throw new import_common58.ConflictException({
12961
- code: import_types27.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_EXPIRED,
12962
+ code: import_core31.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_EXPIRED,
12962
12963
  message: `Checkout offer '${existing.id}' has expired and cannot be ${action}`,
12963
12964
  params: {
12964
12965
  offerId: existing.id,
@@ -12969,7 +12970,7 @@ var CheckoutOfferService = class {
12969
12970
  }
12970
12971
  if (this.isExpired(existing)) {
12971
12972
  throw new import_common58.ConflictException({
12972
- code: import_types27.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_EXPIRED,
12973
+ code: import_core31.CONTRACT_ERROR_CODES.CHECKOUT_OFFER_EXPIRED,
12973
12974
  message: `CheckoutOffer '${existing.id}' has expired and cannot be ${action}`,
12974
12975
  params: {
12975
12976
  offerId: existing.id,
@@ -12994,7 +12995,7 @@ var CheckoutOfferService = class {
12994
12995
  if (!value) return false;
12995
12996
  const validUntil = new Date(value).getTime();
12996
12997
  if (Number.isNaN(validUntil)) return true;
12997
- return validUntil < (0, import_types27.startOfUtcDay)(new Date(nowMs)).getTime();
12998
+ return validUntil < (0, import_core31.startOfUtcDay)(new Date(nowMs)).getTime();
12998
12999
  }
12999
13000
  };
13000
13001
  CheckoutOfferService = _ts_decorate66([
@@ -13387,7 +13388,7 @@ var EnforceQuota = /* @__PURE__ */ __name((quotaKey, options = {}) => (0, import
13387
13388
 
13388
13389
  // src/discovery/discovery.module.ts
13389
13390
  var import_common63 = require("@nestjs/common");
13390
- var import_core5 = require("@nestjs/core");
13391
+ var import_core32 = require("@nestjs/core");
13391
13392
 
13392
13393
  // src/discovery/discovery.controller.ts
13393
13394
  var import_common62 = require("@nestjs/common");
@@ -13511,7 +13512,7 @@ var DiscoveryModule = class _DiscoveryModule {
13511
13512
  return {
13512
13513
  module: _DiscoveryModule,
13513
13514
  imports: [
13514
- import_core5.DiscoveryModule,
13515
+ import_core32.DiscoveryModule,
13515
13516
  ...options.imports ?? []
13516
13517
  ],
13517
13518
  controllers,
@@ -13529,11 +13530,11 @@ DiscoveryModule = _ts_decorate71([
13529
13530
  ], DiscoveryModule);
13530
13531
 
13531
13532
  // src/discovery/headless-scan.ts
13532
- var import_core6 = require("@nestjs/core");
13533
+ var import_core33 = require("@nestjs/core");
13533
13534
  async function runHeadlessDiscoveryScan(appModule, options = {}) {
13534
13535
  const exit = options.exit ?? ((code) => process.exit(code));
13535
13536
  try {
13536
- const app = await import_core6.NestFactory.createApplicationContext(appModule, {
13537
+ const app = await import_core33.NestFactory.createApplicationContext(appModule, {
13537
13538
  logger: options.logger ?? [
13538
13539
  "error",
13539
13540
  "warn",
@@ -13594,7 +13595,7 @@ __export(entitlement_exports, {
13594
13595
  toEffectiveLimitsSnapshot: () => toEffectiveLimitsSnapshot
13595
13596
  });
13596
13597
 
13597
- // src/entitlement/module.ts
13598
+ // src/entitlement/entitlement.module.ts
13598
13599
  var import_common64 = require("@nestjs/common");
13599
13600
  function _ts_decorate72(decorators, target, key, desc) {
13600
13601
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -13694,9 +13695,8 @@ __export(platform_exports, {
13694
13695
  SAASICAT_PUBLIC_ROUTE_KEY: () => SAASICAT_PUBLIC_ROUTE_KEY,
13695
13696
  STATIC_FEATURE_GUARD_CONFIG_TOKEN: () => STATIC_FEATURE_GUARD_CONFIG_TOKEN,
13696
13697
  SaaSiCatConfigurationError: () => SaaSiCatConfigurationError,
13697
- SaaSiCatModule: () => SaasPlatformModule,
13698
+ SaaSiCatModule: () => SaaSiCatModule,
13698
13699
  SaaSiCatPublicRoute: () => SaaSiCatPublicRoute,
13699
- SaasPlatformModule: () => SaasPlatformModule,
13700
13700
  SetupModule: () => SetupModule,
13701
13701
  SetupService: () => SetupService,
13702
13702
  StaticEntitlementService: () => StaticEntitlementService,
@@ -13722,13 +13722,13 @@ __export(platform_exports, {
13722
13722
  isSaaSiCatPublicRoute: () => isSaaSiCatPublicRoute
13723
13723
  });
13724
13724
 
13725
- // src/platform/saas-platform.module.ts
13725
+ // src/platform/saasicat.module.ts
13726
13726
  var import_common80 = require("@nestjs/common");
13727
- var import_core11 = require("@nestjs/core");
13727
+ var import_core42 = require("@nestjs/core");
13728
13728
 
13729
13729
  // src/platform/enforcement-chain.check.ts
13730
13730
  var import_common65 = require("@nestjs/common");
13731
- var import_core7 = require("@nestjs/core");
13731
+ var import_core34 = require("@nestjs/core");
13732
13732
  function _ts_decorate73(decorators, target, key, desc) {
13733
13733
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
13734
13734
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -13748,7 +13748,7 @@ function _ts_param47(paramIndex, decorator) {
13748
13748
  __name(_ts_param47, "_ts_param");
13749
13749
  var GUARDS_METADATA = "__guards__";
13750
13750
  var METHOD_METADATA = "method";
13751
- var ENFORCEMENT_CHAIN_STATE_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/EnforcementChainState");
13751
+ var ENFORCEMENT_CHAIN_STATE_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/EnforcementChainState");
13752
13752
  var EnforcementChainCheck = class {
13753
13753
  static {
13754
13754
  __name(this, "EnforcementChainCheck");
@@ -13836,14 +13836,14 @@ Two things this cannot see, and the way out of each: a guard of your own that wr
13836
13836
  };
13837
13837
  EnforcementChainCheck = _ts_decorate73([
13838
13838
  (0, import_common65.Injectable)(),
13839
- _ts_param47(0, (0, import_common65.Inject)(import_core7.DiscoveryService)),
13840
- _ts_param47(1, (0, import_common65.Inject)(import_core7.MetadataScanner)),
13839
+ _ts_param47(0, (0, import_common65.Inject)(import_core34.DiscoveryService)),
13840
+ _ts_param47(1, (0, import_common65.Inject)(import_core34.MetadataScanner)),
13841
13841
  _ts_param47(2, (0, import_common65.Optional)()),
13842
13842
  _ts_param47(2, (0, import_common65.Inject)(ENFORCEMENT_CHAIN_STATE_TOKEN)),
13843
13843
  _ts_metadata58("design:type", Function),
13844
13844
  _ts_metadata58("design:paramtypes", [
13845
- typeof import_core7.DiscoveryService === "undefined" ? Object : import_core7.DiscoveryService,
13846
- typeof import_core7.MetadataScanner === "undefined" ? Object : import_core7.MetadataScanner,
13845
+ typeof import_core34.DiscoveryService === "undefined" ? Object : import_core34.DiscoveryService,
13846
+ typeof import_core34.MetadataScanner === "undefined" ? Object : import_core34.MetadataScanner,
13847
13847
  typeof EnforcementChainState === "undefined" ? Object : EnforcementChainState
13848
13848
  ])
13849
13849
  ], EnforcementChainCheck);
@@ -13879,7 +13879,7 @@ function readGuards(target) {
13879
13879
  __name(readGuards, "readGuards");
13880
13880
 
13881
13881
  // src/platform/validation/rules.ts
13882
- var import_types28 = require("@saasicat/types");
13882
+ var import_core35 = require("@saasicat/core");
13883
13883
  var DOCS_BASE = "https://github.com/uelker70/saasicat/blob/main/docs/reference/options.md";
13884
13884
  var headingSlug = /* @__PURE__ */ __name((text) => text.trim().toLowerCase().replace(/[^a-z0-9 -]/g, "").replace(/ /g, "-"), "headingSlug");
13885
13885
  var docsUrlFor = /* @__PURE__ */ __name((id) => `${DOCS_BASE}#${headingSlug(id)}`, "docsUrlFor");
@@ -13994,10 +13994,10 @@ var RULE_SPECS = [
13994
13994
  // shared helper keeps the class, the code and the wording identical to
13995
13995
  // what a consumer catches today.
13996
13996
  error: /* @__PURE__ */ __name((c) => {
13997
- (0, import_types28.assertPersistenceCapabilities)(bundle(c).capabilities, {
13997
+ (0, import_core35.assertPersistenceCapabilities)(bundle(c).capabilities, {
13998
13998
  transactions: true,
13999
13999
  pessimisticLocking: true
14000
- }, "SaasPlatformModule entitlement (transactional enforceLimit)");
14000
+ }, "SaaSiCatModule entitlement (transactional enforceLimit)");
14001
14001
  throw new Error("persistence capabilities check did not fail as expected");
14002
14002
  }, "error")
14003
14003
  },
@@ -14172,13 +14172,13 @@ var import_class_validator14 = require("class-validator");
14172
14172
 
14173
14173
  // src/setup/setup.service.ts
14174
14174
  var import_common66 = require("@nestjs/common");
14175
- var import_types29 = require("@saasicat/types");
14175
+ var import_core36 = require("@saasicat/core");
14176
14176
  var import_node_crypto3 = require("crypto");
14177
14177
  var import_qrcode = __toESM(require("qrcode"), 1);
14178
14178
 
14179
- // src/setup/tokens.ts
14180
- var SETUP_PROVISIONING_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SetupProvisioningPort");
14181
- var SETUP_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SetupConfig");
14179
+ // src/setup/setup.tokens.ts
14180
+ var SETUP_PROVISIONING_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SetupProvisioningPort");
14181
+ var SETUP_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SetupConfig");
14182
14182
 
14183
14183
  // src/setup/setup.service.ts
14184
14184
  function _ts_decorate74(decorators, target, key, desc) {
@@ -14228,7 +14228,7 @@ var SetupService = class {
14228
14228
  await this.assertNoSuperAdmin();
14229
14229
  const email = req.email.trim().toLowerCase();
14230
14230
  if (!email.includes("@")) {
14231
- throw new import_common66.BadRequestException(codedError(import_types29.SETUP_ERROR_CODES.INVALID_EMAIL));
14231
+ throw new import_common66.BadRequestException(codedError(import_core36.SETUP_ERROR_CODES.INVALID_EMAIL));
14232
14232
  }
14233
14233
  const generated = !req.password;
14234
14234
  const password = req.password ?? (0, import_node_crypto3.randomBytes)(GENERATED_PASSWORD_BYTES).toString("base64url");
@@ -14239,9 +14239,9 @@ var SetupService = class {
14239
14239
  password
14240
14240
  });
14241
14241
  } catch (err) {
14242
- if ((0, import_types29.isPlatformUserExistsError)(err)) {
14242
+ if ((0, import_core36.isPlatformUserExistsError)(err)) {
14243
14243
  throw new import_common66.ConflictException({
14244
- code: import_types29.SETUP_ERROR_CODES.EMAIL_EXISTS,
14244
+ code: import_core36.SETUP_ERROR_CODES.EMAIL_EXISTS,
14245
14245
  message: err.message
14246
14246
  });
14247
14247
  }
@@ -14277,7 +14277,7 @@ var SetupService = class {
14277
14277
  const expected = process.env[this.config.setupTokenEnvVar]?.trim();
14278
14278
  if (!expected) {
14279
14279
  throw new import_common66.ForbiddenException({
14280
- code: import_types29.SETUP_ERROR_CODES.SETUP_DISABLED,
14280
+ code: import_core36.SETUP_ERROR_CODES.SETUP_DISABLED,
14281
14281
  message: `${this.config.setupTokenEnvVar} is not set \u2014 setup is disabled.`,
14282
14282
  params: {
14283
14283
  envVar: this.config.setupTokenEnvVar
@@ -14285,12 +14285,12 @@ var SetupService = class {
14285
14285
  });
14286
14286
  }
14287
14287
  if (!token || !timingSafeEqualStr(token, expected)) {
14288
- throw new import_common66.UnauthorizedException(codedError(import_types29.SETUP_ERROR_CODES.INVALID_SETUP_TOKEN));
14288
+ throw new import_common66.UnauthorizedException(codedError(import_core36.SETUP_ERROR_CODES.INVALID_SETUP_TOKEN));
14289
14289
  }
14290
14290
  }
14291
14291
  async assertNoSuperAdmin() {
14292
14292
  if (await this.users.countSuperAdmins() > 0) {
14293
- throw new import_common66.ConflictException(codedError(import_types29.SETUP_ERROR_CODES.SETUP_ALREADY_DONE));
14293
+ throw new import_common66.ConflictException(codedError(import_core36.SETUP_ERROR_CODES.SETUP_ALREADY_DONE));
14294
14294
  }
14295
14295
  }
14296
14296
  };
@@ -14555,10 +14555,10 @@ function composeSubscriptionContract({ options, persistence }) {
14555
14555
  }
14556
14556
  __name(composeSubscriptionContract, "composeSubscriptionContract");
14557
14557
 
14558
- // src/promo/module.ts
14558
+ // src/promo/promo.module.ts
14559
14559
  var import_common74 = require("@nestjs/common");
14560
14560
 
14561
- // src/promo/expirer.ts
14561
+ // src/promo/promo-code-expirer.service.ts
14562
14562
  var import_common70 = require("@nestjs/common");
14563
14563
  var import_schedule = require("@nestjs/schedule");
14564
14564
  function _ts_decorate78(decorators, target, key, desc) {
@@ -14618,12 +14618,12 @@ PromoCodeExpirer = _ts_decorate78([
14618
14618
  ])
14619
14619
  ], PromoCodeExpirer);
14620
14620
 
14621
- // src/promo/controller.ts
14621
+ // src/promo/promo.controller.ts
14622
14622
  var import_common72 = require("@nestjs/common");
14623
14623
 
14624
14624
  // src/promo/rate-limit.guard.ts
14625
14625
  var import_common71 = require("@nestjs/common");
14626
- var import_types30 = require("@saasicat/types");
14626
+ var import_core37 = require("@saasicat/core");
14627
14627
  function _ts_decorate79(decorators, target, key, desc) {
14628
14628
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14629
14629
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -14637,7 +14637,7 @@ var SESSION_WINDOW_MS = 60 * 6e4;
14637
14637
  var SESSION_LIMIT = 50;
14638
14638
  function rateLimited(windowMs) {
14639
14639
  return new import_common71.HttpException({
14640
- ...codedError(import_types30.REGISTRATION_ERROR_CODES.RATE_LIMITED, {
14640
+ ...codedError(import_core37.REGISTRATION_ERROR_CODES.RATE_LIMITED, {
14641
14641
  retryAfterSeconds: Math.ceil(windowMs / 1e3)
14642
14642
  }),
14643
14643
  retryAfterSeconds: Math.ceil(windowMs / 1e3),
@@ -14750,7 +14750,7 @@ _ts_decorate80([
14750
14750
  _ts_metadata62("design:type", String)
14751
14751
  ], PreviewPromoCodeDto.prototype, "email", void 0);
14752
14752
 
14753
- // src/promo/controller.ts
14753
+ // src/promo/promo.controller.ts
14754
14754
  function _ts_decorate81(decorators, target, key, desc) {
14755
14755
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14756
14756
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -14810,7 +14810,7 @@ PromoCodePublicController = _ts_decorate81([
14810
14810
  ])
14811
14811
  ], PromoCodePublicController);
14812
14812
 
14813
- // src/promo/admin-controller.ts
14813
+ // src/promo/promo-admin.controller.ts
14814
14814
  var import_common73 = require("@nestjs/common");
14815
14815
 
14816
14816
  // src/promo/dto/promo-admin.dto.ts
@@ -15066,7 +15066,7 @@ _ts_decorate82([
15066
15066
  _ts_metadata64("design:type", Object)
15067
15067
  ], UpdatePromoCodeDto.prototype, "revenueDeductionAccount", void 0);
15068
15068
 
15069
- // src/promo/admin-controller.ts
15069
+ // src/promo/promo-admin.controller.ts
15070
15070
  function _ts_decorate83(decorators, target, key, desc) {
15071
15071
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
15072
15072
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -15232,7 +15232,7 @@ function parseDate(value) {
15232
15232
  }
15233
15233
  __name(parseDate, "parseDate");
15234
15234
 
15235
- // src/promo/module.ts
15235
+ // src/promo/promo.module.ts
15236
15236
  function _ts_decorate84(decorators, target, key, desc) {
15237
15237
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
15238
15238
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -15433,8 +15433,8 @@ function composeFeatures(ctx) {
15433
15433
  __name(composeFeatures, "composeFeatures");
15434
15434
 
15435
15435
  // src/platform/compose/manifest.ts
15436
- var PLATFORM_SUBSCRIPTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/PlatformSubscriptionRepository");
15437
- var STANDARD_MANIFEST_REGISTRATION_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/StandardManifestRegistration");
15436
+ var PLATFORM_SUBSCRIPTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PlatformSubscriptionRepository");
15437
+ var STANDARD_MANIFEST_REGISTRATION_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/StandardManifestRegistration");
15438
15438
  function buildStandardManifestContribution(catalog, adminResources, promoCodes) {
15439
15439
  const capabilities = {
15440
15440
  "discovery.read": true
@@ -15505,7 +15505,7 @@ function buildMinimalManifestConfig() {
15505
15505
  appVersion: "0.0.0"
15506
15506
  },
15507
15507
  planCatalogSnapshot: {
15508
- source: "saas-platform-module",
15508
+ source: "saasicat-module",
15509
15509
  hash: "sha256-quickstart",
15510
15510
  currency: catalog.currency,
15511
15511
  vatRate: catalog.vatRate,
@@ -15656,7 +15656,7 @@ var import_common76 = require("@nestjs/common");
15656
15656
  var import_common75 = require("@nestjs/common");
15657
15657
 
15658
15658
  // src/platform/plan-resolver.port.ts
15659
- var PLAN_RESOLVER_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/PlanResolverPort");
15659
+ var PLAN_RESOLVER_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PlanResolverPort");
15660
15660
  var StaticPlanResolver = class {
15661
15661
  static {
15662
15662
  __name(this, "StaticPlanResolver");
@@ -15909,11 +15909,11 @@ function composeTenantManifest(ctx) {
15909
15909
  __name(composeTenantManifest, "composeTenantManifest");
15910
15910
 
15911
15911
  // src/platform/compose/enforcement-runtime.ts
15912
- var import_core10 = require("@nestjs/core");
15912
+ var import_core41 = require("@nestjs/core");
15913
15913
 
15914
15914
  // src/platform/enforce-quota.interceptor.ts
15915
15915
  var import_common78 = require("@nestjs/common");
15916
- var import_core8 = require("@nestjs/core");
15916
+ var import_core38 = require("@nestjs/core");
15917
15917
  var import_rxjs2 = require("rxjs");
15918
15918
  var import_operators2 = require("rxjs/operators");
15919
15919
  function _ts_decorate88(decorators, target, key, desc) {
@@ -15933,7 +15933,7 @@ function _ts_param55(paramIndex, decorator) {
15933
15933
  };
15934
15934
  }
15935
15935
  __name(_ts_param55, "_ts_param");
15936
- var QUOTA_PROVIDERS_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/QuotaProviders");
15936
+ var QUOTA_PROVIDERS_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/QuotaProviders");
15937
15937
  var EnforceQuotaInterceptor = class {
15938
15938
  static {
15939
15939
  __name(this, "EnforceQuotaInterceptor");
@@ -15977,13 +15977,13 @@ var EnforceQuotaInterceptor = class {
15977
15977
  };
15978
15978
  EnforceQuotaInterceptor = _ts_decorate88([
15979
15979
  (0, import_common78.Injectable)(),
15980
- _ts_param55(0, (0, import_common78.Inject)(import_core8.Reflector)),
15980
+ _ts_param55(0, (0, import_common78.Inject)(import_core38.Reflector)),
15981
15981
  _ts_param55(1, (0, import_common78.Inject)(StaticEntitlementService)),
15982
15982
  _ts_param55(2, (0, import_common78.Optional)()),
15983
15983
  _ts_param55(2, (0, import_common78.Inject)(QUOTA_PROVIDERS_TOKEN)),
15984
15984
  _ts_metadata69("design:type", Function),
15985
15985
  _ts_metadata69("design:paramtypes", [
15986
- typeof import_core8.Reflector === "undefined" ? Object : import_core8.Reflector,
15986
+ typeof import_core38.Reflector === "undefined" ? Object : import_core38.Reflector,
15987
15987
  typeof StaticEntitlementService === "undefined" ? Object : StaticEntitlementService,
15988
15988
  Object
15989
15989
  ])
@@ -15991,8 +15991,8 @@ EnforceQuotaInterceptor = _ts_decorate88([
15991
15991
 
15992
15992
  // src/platform/static-feature.guard.ts
15993
15993
  var import_common79 = require("@nestjs/common");
15994
- var import_core9 = require("@nestjs/core");
15995
- var import_types31 = require("@saasicat/types");
15994
+ var import_core39 = require("@nestjs/core");
15995
+ var import_core40 = require("@saasicat/core");
15996
15996
  function _ts_decorate89(decorators, target, key, desc) {
15997
15997
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
15998
15998
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -16010,7 +16010,7 @@ function _ts_param56(paramIndex, decorator) {
16010
16010
  };
16011
16011
  }
16012
16012
  __name(_ts_param56, "_ts_param");
16013
- var STATIC_FEATURE_GUARD_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/StaticFeatureGuardConfig");
16013
+ var STATIC_FEATURE_GUARD_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/StaticFeatureGuardConfig");
16014
16014
  var StaticFeatureGuard = class {
16015
16015
  static {
16016
16016
  __name(this, "StaticFeatureGuard");
@@ -16035,7 +16035,7 @@ var StaticFeatureGuard = class {
16035
16035
  const user = request.user;
16036
16036
  if (!user) {
16037
16037
  throw new import_common79.ForbiddenException({
16038
- code: import_types31.AUTH_ERROR_CODES.NOT_AUTHENTICATED,
16038
+ code: import_core40.AUTH_ERROR_CODES.NOT_AUTHENTICATED,
16039
16039
  message: "Not authenticated"
16040
16040
  });
16041
16041
  }
@@ -16044,7 +16044,7 @@ var StaticFeatureGuard = class {
16044
16044
  const tenantId = this.config?.tenantIdResolver ? this.config.tenantIdResolver(request) : request.tenantId ?? user.tenantId;
16045
16045
  if (!tenantId) {
16046
16046
  throw new import_common79.ForbiddenException({
16047
- code: import_types31.AUTH_ERROR_CODES.NO_TENANT_ASSIGNED,
16047
+ code: import_core40.AUTH_ERROR_CODES.NO_TENANT_ASSIGNED,
16048
16048
  message: "No tenant assigned"
16049
16049
  });
16050
16050
  }
@@ -16052,7 +16052,7 @@ var StaticFeatureGuard = class {
16052
16052
  const allowed = required.some((f) => snap.features.includes(f));
16053
16053
  if (!allowed) {
16054
16054
  const body = {
16055
- code: import_types31.FEATURE_NOT_LICENSED,
16055
+ code: import_core40.FEATURE_NOT_LICENSED,
16056
16056
  featureKey: required[0],
16057
16057
  featureKeys: required,
16058
16058
  offers: [],
@@ -16065,13 +16065,13 @@ var StaticFeatureGuard = class {
16065
16065
  };
16066
16066
  StaticFeatureGuard = _ts_decorate89([
16067
16067
  (0, import_common79.Injectable)(),
16068
- _ts_param56(0, (0, import_common79.Inject)(import_core9.Reflector)),
16068
+ _ts_param56(0, (0, import_common79.Inject)(import_core39.Reflector)),
16069
16069
  _ts_param56(1, (0, import_common79.Inject)(StaticEntitlementService)),
16070
16070
  _ts_param56(2, (0, import_common79.Optional)()),
16071
16071
  _ts_param56(2, (0, import_common79.Inject)(STATIC_FEATURE_GUARD_CONFIG_TOKEN)),
16072
16072
  _ts_metadata70("design:type", Function),
16073
16073
  _ts_metadata70("design:paramtypes", [
16074
- typeof import_core9.Reflector === "undefined" ? Object : import_core9.Reflector,
16074
+ typeof import_core39.Reflector === "undefined" ? Object : import_core39.Reflector,
16075
16075
  typeof StaticEntitlementService === "undefined" ? Object : StaticEntitlementService,
16076
16076
  Object
16077
16077
  ])
@@ -16135,7 +16135,7 @@ function composeEnforcementRuntime(ctx, resolution) {
16135
16135
  },
16136
16136
  ...options.globalFeatureGuard === false ? [] : [
16137
16137
  {
16138
- provide: import_core10.APP_GUARD,
16138
+ provide: import_core41.APP_GUARD,
16139
16139
  useExisting: StaticFeatureGuard
16140
16140
  }
16141
16141
  ],
@@ -16143,7 +16143,7 @@ function composeEnforcementRuntime(ctx, resolution) {
16143
16143
  // guards, so it sees the authenticated request even when the app binds
16144
16144
  // its own guard chain.
16145
16145
  {
16146
- provide: import_core10.APP_INTERCEPTOR,
16146
+ provide: import_core41.APP_INTERCEPTOR,
16147
16147
  useExisting: EnforceQuotaInterceptor
16148
16148
  }
16149
16149
  );
@@ -16179,7 +16179,7 @@ function planResolverProvider(ctx, resolution) {
16179
16179
  }
16180
16180
  __name(planResolverProvider, "planResolverProvider");
16181
16181
 
16182
- // src/platform/saas-platform.module.ts
16182
+ // src/platform/saasicat.module.ts
16183
16183
  function _ts_decorate90(decorators, target, key, desc) {
16184
16184
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16185
16185
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -16195,9 +16195,9 @@ function enforcementChainState(state) {
16195
16195
  };
16196
16196
  }
16197
16197
  __name(enforcementChainState, "enforcementChainState");
16198
- var SaasPlatformModule = class _SaasPlatformModule {
16198
+ var SaaSiCatModule = class _SaaSiCatModule {
16199
16199
  static {
16200
- __name(this, "SaasPlatformModule");
16200
+ __name(this, "SaaSiCatModule");
16201
16201
  }
16202
16202
  static forRoot(options) {
16203
16203
  const explicit = options.adapters ?? {};
@@ -16282,12 +16282,12 @@ var SaasPlatformModule = class _SaasPlatformModule {
16282
16282
  globalGuardOptedOut: options.globalFeatureGuard === false
16283
16283
  }));
16284
16284
  }
16285
- if (options.enforcementChainCheck !== false) imports.push(import_core11.DiscoveryModule);
16285
+ if (options.enforcementChainCheck !== false) imports.push(import_core42.DiscoveryModule);
16286
16286
  const tenantManifest = composeTenantManifest(composition);
16287
16287
  lightweightProviders.push(...tenantManifest.providers);
16288
16288
  lightweightExports.push(...tenantManifest.exports);
16289
16289
  return {
16290
- module: _SaasPlatformModule,
16290
+ module: _SaaSiCatModule,
16291
16291
  imports,
16292
16292
  providers: lightweightProviders,
16293
16293
  controllers: tenantManifest.controllers,
@@ -16296,9 +16296,9 @@ var SaasPlatformModule = class _SaasPlatformModule {
16296
16296
  };
16297
16297
  }
16298
16298
  };
16299
- SaasPlatformModule = _ts_decorate90([
16299
+ SaaSiCatModule = _ts_decorate90([
16300
16300
  (0, import_common80.Module)({})
16301
- ], SaasPlatformModule);
16301
+ ], SaaSiCatModule);
16302
16302
 
16303
16303
  // src/platform/define-saasicat.ts
16304
16304
  function defineSaaSiCat(options) {
@@ -16409,28 +16409,28 @@ function slugify(name) {
16409
16409
  }
16410
16410
  __name(slugify, "slugify");
16411
16411
 
16412
- // src/registration/tokens.ts
16413
- var PENDING_REGISTRATION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PendingRegistrationRepository");
16414
- var REGISTRATION_OTP_DELIVERY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RegistrationOtpDelivery");
16415
- var USER_ACCOUNT_LOOKUP_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/UserAccountLookup");
16416
- var SLUG_AVAILABILITY_CHECK_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SlugAvailabilityCheck");
16417
- var PASSWORD_HASHER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PasswordHasher");
16418
- var PLAN_CATALOG_LOOKUP_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PlanCatalogLookup");
16419
- var PAYMENT_PROVIDER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PaymentProvider");
16420
- var PAYMENT_EVENT_LOG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/PaymentEventLog");
16421
- var ACTIVATION_ORCHESTRATOR_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/ActivationOrchestrator");
16422
- var REGISTRATION_AUDIT_LOGGER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RegistrationAuditLogger");
16423
- var REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RegistrationResumeTokenSigner");
16424
- var REGISTRATION_RESUME_DELIVERY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RegistrationResumeDelivery");
16425
- var REGISTRATION_RESUME_BASE_URL_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RegistrationResumeBaseUrl");
16426
- var REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RegistrationConfiguratorLookup");
16427
- var REGISTRATION_PROMO_PREVIEW_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RegistrationPromoPreview");
16428
- var REGISTRATION_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/RegistrationConfig");
16412
+ // src/registration/registration.tokens.ts
16413
+ var PENDING_REGISTRATION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PendingRegistrationRepository");
16414
+ var REGISTRATION_OTP_DELIVERY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RegistrationOtpDelivery");
16415
+ var USER_ACCOUNT_LOOKUP_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/UserAccountLookup");
16416
+ var SLUG_AVAILABILITY_CHECK_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/SlugAvailabilityCheck");
16417
+ var PASSWORD_HASHER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PasswordHasher");
16418
+ var PLAN_CATALOG_LOOKUP_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PlanCatalogLookup");
16419
+ var PAYMENT_PROVIDER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PaymentProvider");
16420
+ var PAYMENT_EVENT_LOG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PaymentEventLog");
16421
+ var ACTIVATION_ORCHESTRATOR_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/ActivationOrchestrator");
16422
+ var REGISTRATION_AUDIT_LOGGER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RegistrationAuditLogger");
16423
+ var REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RegistrationResumeTokenSigner");
16424
+ var REGISTRATION_RESUME_DELIVERY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RegistrationResumeDelivery");
16425
+ var REGISTRATION_RESUME_BASE_URL_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RegistrationResumeBaseUrl");
16426
+ var REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RegistrationConfiguratorLookup");
16427
+ var REGISTRATION_PROMO_PREVIEW_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RegistrationPromoPreview");
16428
+ var REGISTRATION_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/RegistrationConfig");
16429
16429
 
16430
16430
  // src/registration/pending-registration.service.ts
16431
16431
  var import_common81 = require("@nestjs/common");
16432
- var import_types32 = require("@saasicat/types");
16433
- var import_types33 = require("@saasicat/types");
16432
+ var import_core43 = require("@saasicat/core");
16433
+ var import_core44 = require("@saasicat/core");
16434
16434
 
16435
16435
  // src/registration/pricing.ts
16436
16436
  function round24(value) {
@@ -16558,20 +16558,20 @@ var PendingRegistrationService = class _PendingRegistrationService {
16558
16558
  async selectPlan(input, context) {
16559
16559
  const pending = await this.repo.findById(input.pendingRegistrationId);
16560
16560
  if (!pending) {
16561
- throw new import_common81.NotFoundException(codedError(import_types32.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_NOT_FOUND));
16561
+ throw new import_common81.NotFoundException(codedError(import_core43.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_NOT_FOUND));
16562
16562
  }
16563
16563
  if (pending.expiresAt.getTime() < Date.now()) {
16564
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_EXPIRED));
16564
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_EXPIRED));
16565
16565
  }
16566
16566
  if (pending.status !== "EMAIL_VERIFIED" && pending.status !== "PLAN_SELECTED" && pending.status !== "CHECKOUT_STARTED") {
16567
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.INVALID_REGISTRATION_STATE));
16567
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.INVALID_REGISTRATION_STATE));
16568
16568
  }
16569
16569
  const plan = await this.planCatalog.findPublicSignupPlan(input.planId);
16570
16570
  if (!plan) {
16571
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.PLAN_NOT_AVAILABLE));
16571
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.PLAN_NOT_AVAILABLE));
16572
16572
  }
16573
16573
  const now = /* @__PURE__ */ new Date();
16574
- const expiresAt = new Date(now.getTime() + import_types33.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3);
16574
+ const expiresAt = new Date(now.getTime() + import_core44.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3);
16575
16575
  const updated = await this.repo.update(pending.id, {
16576
16576
  status: "PLAN_SELECTED",
16577
16577
  currentStep: 4,
@@ -16584,27 +16584,27 @@ var PendingRegistrationService = class _PendingRegistrationService {
16584
16584
  return {
16585
16585
  pendingRegistrationId: updated.id,
16586
16586
  status: updated.status,
16587
- nextStep: import_types33.REGISTRATION_STEP_BY_STATUS[updated.status],
16587
+ nextStep: import_core44.REGISTRATION_STEP_BY_STATUS[updated.status],
16588
16588
  selectedPlanId: updated.selectedPlanId ?? plan.id
16589
16589
  };
16590
16590
  }
16591
16591
  async startCheckout(input, context) {
16592
16592
  const pending = await this.repo.findById(input.pendingRegistrationId);
16593
16593
  if (!pending) {
16594
- throw new import_common81.NotFoundException(codedError(import_types32.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_NOT_FOUND));
16594
+ throw new import_common81.NotFoundException(codedError(import_core43.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_NOT_FOUND));
16595
16595
  }
16596
16596
  if (pending.expiresAt.getTime() < Date.now()) {
16597
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_EXPIRED));
16597
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_EXPIRED));
16598
16598
  }
16599
16599
  if (pending.status !== "PLAN_SELECTED" && pending.status !== "CHECKOUT_STARTED") {
16600
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.PLAN_NOT_SELECTED));
16600
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.PLAN_NOT_SELECTED));
16601
16601
  }
16602
16602
  if (!pending.selectedPlanId) {
16603
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.PLAN_NOT_SELECTED));
16603
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.PLAN_NOT_SELECTED));
16604
16604
  }
16605
16605
  const plan = await this.planCatalog.findPublicSignupPlan(pending.selectedPlanId);
16606
16606
  if (!plan) {
16607
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.PLAN_NOT_AVAILABLE));
16607
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.PLAN_NOT_AVAILABLE));
16608
16608
  }
16609
16609
  const session = await this.paymentProvider.createCheckoutSession({
16610
16610
  pendingRegistrationId: pending.id,
@@ -16614,7 +16614,7 @@ var PendingRegistrationService = class _PendingRegistrationService {
16614
16614
  cancelUrl: input.cancelUrl
16615
16615
  });
16616
16616
  const now = /* @__PURE__ */ new Date();
16617
- const expiresAt = new Date(now.getTime() + import_types33.PENDING_CHECKOUT_TTL_DAYS * 24 * 60 * 60 * 1e3);
16617
+ const expiresAt = new Date(now.getTime() + import_core44.PENDING_CHECKOUT_TTL_DAYS * 24 * 60 * 60 * 1e3);
16618
16618
  const updated = await this.repo.update(pending.id, {
16619
16619
  status: "CHECKOUT_STARTED",
16620
16620
  currentStep: 4,
@@ -16629,7 +16629,7 @@ var PendingRegistrationService = class _PendingRegistrationService {
16629
16629
  return {
16630
16630
  pendingRegistrationId: updated.id,
16631
16631
  status: updated.status,
16632
- nextStep: import_types33.REGISTRATION_STEP_BY_STATUS[updated.status],
16632
+ nextStep: import_core44.REGISTRATION_STEP_BY_STATUS[updated.status],
16633
16633
  checkoutSessionId: session.sessionId,
16634
16634
  checkoutUrl: session.checkoutUrl
16635
16635
  };
@@ -16785,8 +16785,8 @@ var PendingRegistrationService = class _PendingRegistrationService {
16785
16785
  const code = generateOtpCode();
16786
16786
  const otpHash = hashOtpCode(code);
16787
16787
  const now = /* @__PURE__ */ new Date();
16788
- const otpExpiresAt = new Date(now.getTime() + import_types33.OTP_TTL_MINUTES * 60 * 1e3);
16789
- const expiresAt = new Date(now.getTime() + import_types33.PENDING_EMAIL_TTL_HOURS * 60 * 60 * 1e3);
16788
+ const otpExpiresAt = new Date(now.getTime() + import_core44.OTP_TTL_MINUTES * 60 * 1e3);
16789
+ const expiresAt = new Date(now.getTime() + import_core44.PENDING_EMAIL_TTL_HOURS * 60 * 60 * 1e3);
16790
16790
  const pending = await this.repo.create({
16791
16791
  tenantName: input.tenantName.trim(),
16792
16792
  tenantSlug: slug,
@@ -16813,12 +16813,12 @@ var PendingRegistrationService = class _PendingRegistrationService {
16813
16813
  await this.record("OTP_VERIFY_FAILED", null, context, {
16814
16814
  reason: "unknown_email"
16815
16815
  });
16816
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.OTP_INVALID));
16816
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.OTP_INVALID));
16817
16817
  }
16818
16818
  if (pending.status !== "PENDING_EMAIL_VERIFICATION") {
16819
16819
  return {
16820
16820
  status: pending.status,
16821
- nextStep: import_types33.REGISTRATION_STEP_BY_STATUS[pending.status],
16821
+ nextStep: import_core44.REGISTRATION_STEP_BY_STATUS[pending.status],
16822
16822
  pendingRegistrationId: pending.id
16823
16823
  };
16824
16824
  }
@@ -16826,33 +16826,33 @@ var PendingRegistrationService = class _PendingRegistrationService {
16826
16826
  await this.record("OTP_VERIFY_FAILED", pending.id, context, {
16827
16827
  reason: "no_otp_set"
16828
16828
  });
16829
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.OTP_INVALID));
16829
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.OTP_INVALID));
16830
16830
  }
16831
16831
  if (pending.otpExpiresAt.getTime() < Date.now()) {
16832
16832
  await this.record("OTP_VERIFY_FAILED", pending.id, context, {
16833
16833
  reason: "expired"
16834
16834
  });
16835
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.OTP_EXPIRED));
16835
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.OTP_EXPIRED));
16836
16836
  }
16837
16837
  const maxAttempts = resolveOtpVerifyMaxAttempts();
16838
16838
  if (pending.otpAttemptCount >= maxAttempts) {
16839
16839
  await this.record("OTP_VERIFY_FAILED", pending.id, context, {
16840
16840
  reason: "locked"
16841
16841
  });
16842
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.OTP_LOCKED));
16842
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.OTP_LOCKED));
16843
16843
  }
16844
16844
  const attemptCount = await this.repo.incrementOtpAttemptCount(pending.id);
16845
16845
  if (attemptCount > maxAttempts) {
16846
16846
  await this.record("OTP_VERIFY_FAILED", pending.id, context, {
16847
16847
  reason: "locked"
16848
16848
  });
16849
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.OTP_LOCKED));
16849
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.OTP_LOCKED));
16850
16850
  }
16851
16851
  if (!verifyOtpCode(pending.otpHash, code)) {
16852
16852
  await this.record("OTP_VERIFY_FAILED", pending.id, context, {
16853
16853
  reason: "wrong_code"
16854
16854
  });
16855
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.OTP_INVALID));
16855
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.OTP_INVALID));
16856
16856
  }
16857
16857
  const now = /* @__PURE__ */ new Date();
16858
16858
  const updated = await this.repo.update(pending.id, {
@@ -16861,12 +16861,12 @@ var PendingRegistrationService = class _PendingRegistrationService {
16861
16861
  emailVerifiedAt: now,
16862
16862
  otpHash: null,
16863
16863
  otpExpiresAt: null,
16864
- expiresAt: new Date(now.getTime() + import_types33.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3)
16864
+ expiresAt: new Date(now.getTime() + import_core44.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3)
16865
16865
  });
16866
16866
  await this.record("OTP_VERIFIED", updated.id, context);
16867
16867
  return {
16868
16868
  status: updated.status,
16869
- nextStep: import_types33.REGISTRATION_STEP_BY_STATUS[updated.status],
16869
+ nextStep: import_core44.REGISTRATION_STEP_BY_STATUS[updated.status],
16870
16870
  pendingRegistrationId: updated.id
16871
16871
  };
16872
16872
  }
@@ -16891,15 +16891,15 @@ var PendingRegistrationService = class _PendingRegistrationService {
16891
16891
  }
16892
16892
  async regenerateOtp(pending) {
16893
16893
  const now = /* @__PURE__ */ new Date();
16894
- const windowMs = import_types33.OTP_RATE_LIMIT_WINDOW_MINUTES * 60 * 1e3;
16894
+ const windowMs = import_core44.OTP_RATE_LIMIT_WINDOW_MINUTES * 60 * 1e3;
16895
16895
  const withinWindow = pending.lastOtpSentAt !== null && now.getTime() - pending.lastOtpSentAt.getTime() < windowMs;
16896
- if (withinWindow && pending.otpSendCount >= import_types33.OTP_RATE_LIMIT_MAX_SENDS) {
16896
+ if (withinWindow && pending.otpSendCount >= import_core44.OTP_RATE_LIMIT_MAX_SENDS) {
16897
16897
  this.logger.warn(`OTP rate limit reached for ${pending.email} \u2014 send is being skipped.`);
16898
16898
  return;
16899
16899
  }
16900
16900
  const code = generateOtpCode();
16901
16901
  const otpHash = hashOtpCode(code);
16902
- const otpExpiresAt = new Date(now.getTime() + import_types33.OTP_TTL_MINUTES * 60 * 1e3);
16902
+ const otpExpiresAt = new Date(now.getTime() + import_core44.OTP_TTL_MINUTES * 60 * 1e3);
16903
16903
  const otpSendCount = withinWindow ? pending.otpSendCount + 1 : 1;
16904
16904
  await this.repo.update(pending.id, {
16905
16905
  otpHash,
@@ -16936,7 +16936,7 @@ var PendingRegistrationService = class _PendingRegistrationService {
16936
16936
  }
16937
16937
  const token = await this.resumeTokenSigner.sign({
16938
16938
  pendingRegistrationId: pending.id,
16939
- ttlMinutes: import_types32.REGISTRATION_RESUME_TTL_MINUTES
16939
+ ttlMinutes: import_core43.REGISTRATION_RESUME_TTL_MINUTES
16940
16940
  });
16941
16941
  const base = (this.resumeBaseUrl ?? "http://localhost").replace(/\/+$/, "");
16942
16942
  const url = `${base}/login?resume=${encodeURIComponent(token)}`;
@@ -16963,20 +16963,20 @@ var PendingRegistrationService = class _PendingRegistrationService {
16963
16963
  */
16964
16964
  async resumeWithToken(input, context) {
16965
16965
  if (!this.resumeTokenSigner) {
16966
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.RESUME_NOT_CONFIGURED));
16966
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.RESUME_NOT_CONFIGURED));
16967
16967
  }
16968
16968
  let decoded;
16969
16969
  try {
16970
16970
  decoded = await this.resumeTokenSigner.verify(input.token);
16971
16971
  } catch {
16972
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.RESUME_TOKEN_INVALID));
16972
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.RESUME_TOKEN_INVALID));
16973
16973
  }
16974
16974
  const pending = await this.repo.findById(decoded.pendingRegistrationId);
16975
16975
  if (!pending) {
16976
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.RESUME_TOKEN_INVALID));
16976
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.RESUME_TOKEN_INVALID));
16977
16977
  }
16978
16978
  if (pending.expiresAt.getTime() < Date.now()) {
16979
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_EXPIRED));
16979
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_EXPIRED));
16980
16980
  }
16981
16981
  await this.record("REGISTRATION_NEUTRAL_REPLAY", pending.id, context, {
16982
16982
  via: "resume_token",
@@ -16985,7 +16985,7 @@ var PendingRegistrationService = class _PendingRegistrationService {
16985
16985
  return {
16986
16986
  pendingRegistrationId: pending.id,
16987
16987
  status: pending.status,
16988
- nextStep: import_types33.REGISTRATION_STEP_BY_STATUS[pending.status],
16988
+ nextStep: import_core44.REGISTRATION_STEP_BY_STATUS[pending.status],
16989
16989
  snapshot: toSnapshot2(pending)
16990
16990
  };
16991
16991
  }
@@ -17004,7 +17004,7 @@ var PendingRegistrationService = class _PendingRegistrationService {
17004
17004
  /** Returns the (app-specific) configurator catalog. */
17005
17005
  async getConfiguratorCatalog() {
17006
17006
  if (!this.configuratorLookup) {
17007
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.CONFIGURATOR_NOT_CONFIGURED));
17007
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.CONFIGURATOR_NOT_CONFIGURED));
17008
17008
  }
17009
17009
  return this.configuratorLookup.getCatalog();
17010
17010
  }
@@ -17021,22 +17021,22 @@ var PendingRegistrationService = class _PendingRegistrationService {
17021
17021
  */
17022
17022
  async saveConfiguration(input, context) {
17023
17023
  if (!this.configuratorLookup) {
17024
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.CONFIGURATOR_NOT_CONFIGURED));
17024
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.CONFIGURATOR_NOT_CONFIGURED));
17025
17025
  }
17026
17026
  const pending = await this.repo.findById(input.pendingRegistrationId);
17027
17027
  if (!pending) {
17028
- throw new import_common81.NotFoundException(codedError(import_types32.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_NOT_FOUND));
17028
+ throw new import_common81.NotFoundException(codedError(import_core43.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_NOT_FOUND));
17029
17029
  }
17030
17030
  if (pending.expiresAt.getTime() < Date.now()) {
17031
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_EXPIRED));
17031
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_EXPIRED));
17032
17032
  }
17033
17033
  if (pending.status !== "EMAIL_VERIFIED" && pending.status !== "PLAN_SELECTED" && pending.status !== "CHECKOUT_STARTED") {
17034
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.INVALID_REGISTRATION_STATE));
17034
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.INVALID_REGISTRATION_STATE));
17035
17035
  }
17036
17036
  const catalog = await this.configuratorLookup.getCatalog();
17037
17037
  const model = catalog.models.find((m) => m.id === input.selection.modelId);
17038
17038
  if (!model) {
17039
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.MODEL_NOT_AVAILABLE));
17039
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.MODEL_NOT_AVAILABLE));
17040
17040
  }
17041
17041
  let promoEval;
17042
17042
  if (input.selection.appliedPromoCode && this.promoPreview) {
@@ -17068,7 +17068,7 @@ var PendingRegistrationService = class _PendingRegistrationService {
17068
17068
  };
17069
17069
  }
17070
17070
  const now = /* @__PURE__ */ new Date();
17071
- const expiresAt = new Date(now.getTime() + import_types33.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3);
17071
+ const expiresAt = new Date(now.getTime() + import_core44.PENDING_ONBOARDING_TTL_DAYS * 24 * 60 * 60 * 1e3);
17072
17072
  const updated = await this.repo.update(pending.id, {
17073
17073
  status: "PLAN_SELECTED",
17074
17074
  currentStep: 4,
@@ -17087,7 +17087,7 @@ var PendingRegistrationService = class _PendingRegistrationService {
17087
17087
  return {
17088
17088
  pendingRegistrationId: updated.id,
17089
17089
  status: updated.status,
17090
- nextStep: import_types33.REGISTRATION_STEP_BY_STATUS[updated.status],
17090
+ nextStep: import_core44.REGISTRATION_STEP_BY_STATUS[updated.status],
17091
17091
  selection: input.selection,
17092
17092
  breakdown
17093
17093
  };
@@ -17100,20 +17100,20 @@ var PendingRegistrationService = class _PendingRegistrationService {
17100
17100
  */
17101
17101
  async previewConfigPromo(pendingRegistrationId, code) {
17102
17102
  if (!this.configuratorLookup) {
17103
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.CONFIGURATOR_NOT_CONFIGURED));
17103
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.CONFIGURATOR_NOT_CONFIGURED));
17104
17104
  }
17105
17105
  const pending = await this.repo.findById(pendingRegistrationId);
17106
17106
  if (!pending) {
17107
- throw new import_common81.NotFoundException(codedError(import_types32.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_NOT_FOUND));
17107
+ throw new import_common81.NotFoundException(codedError(import_core43.REGISTRATION_ERROR_CODES.PENDING_REGISTRATION_NOT_FOUND));
17108
17108
  }
17109
17109
  const config = pending.configJson;
17110
17110
  if (!config) {
17111
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.CONFIG_NOT_SAVED));
17111
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.CONFIG_NOT_SAVED));
17112
17112
  }
17113
17113
  const catalog = await this.configuratorLookup.getCatalog();
17114
17114
  const model = catalog.models.find((m) => m.id === config.modelId);
17115
17115
  if (!model) {
17116
- throw new import_common81.BadRequestException(codedError(import_types32.REGISTRATION_ERROR_CODES.MODEL_NOT_AVAILABLE));
17116
+ throw new import_common81.BadRequestException(codedError(import_core43.REGISTRATION_ERROR_CODES.MODEL_NOT_AVAILABLE));
17117
17117
  }
17118
17118
  let promoEval;
17119
17119
  if (code && this.promoPreview) {
@@ -17221,9 +17221,9 @@ function normalizeEmail(value) {
17221
17221
  __name(normalizeEmail, "normalizeEmail");
17222
17222
  function resolveOtpVerifyMaxAttempts() {
17223
17223
  const raw = process.env.SAAS_PLATFORM_OTP_VERIFY_MAX_ATTEMPTS;
17224
- if (!raw) return import_types33.OTP_VERIFY_MAX_ATTEMPTS;
17224
+ if (!raw) return import_core44.OTP_VERIFY_MAX_ATTEMPTS;
17225
17225
  const parsed = Number.parseInt(raw, 10);
17226
- return Number.isInteger(parsed) && parsed > 0 ? parsed : import_types33.OTP_VERIFY_MAX_ATTEMPTS;
17226
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : import_core44.OTP_VERIFY_MAX_ATTEMPTS;
17227
17227
  }
17228
17228
  __name(resolveOtpVerifyMaxAttempts, "resolveOtpVerifyMaxAttempts");
17229
17229
  function toSnapshot2(pending) {
@@ -17318,7 +17318,7 @@ RegistrationCleanupCron = _ts_decorate92([
17318
17318
 
17319
17319
  // src/registration/ip-rate-limit.guard.ts
17320
17320
  var import_common83 = require("@nestjs/common");
17321
- var import_types34 = require("@saasicat/types");
17321
+ var import_core45 = require("@saasicat/core");
17322
17322
  function _ts_decorate93(decorators, target, key, desc) {
17323
17323
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
17324
17324
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -17347,7 +17347,7 @@ var BaseIpRateLimitGuard = class {
17347
17347
  const key = ipFingerprint2(req);
17348
17348
  if (this.exceeded(key)) {
17349
17349
  throw new import_common83.HttpException({
17350
- ...codedError(import_types34.REGISTRATION_ERROR_CODES.RATE_LIMITED, {
17350
+ ...codedError(import_core45.REGISTRATION_ERROR_CODES.RATE_LIMITED, {
17351
17351
  retryAfterSeconds: Math.ceil(this.options.windowMs / 1e3)
17352
17352
  }),
17353
17353
  retryAfterSeconds: Math.ceil(this.options.windowMs / 1e3),
@@ -17387,7 +17387,7 @@ function ipFingerprint2(req) {
17387
17387
  }
17388
17388
  __name(ipFingerprint2, "ipFingerprint");
17389
17389
 
17390
- // src/registration/module.ts
17390
+ // src/registration/registration.module.ts
17391
17391
  var import_common84 = require("@nestjs/common");
17392
17392
  function _ts_decorate94(decorators, target, key, desc) {
17393
17393
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -17884,10 +17884,12 @@ __export(src_exports, {
17884
17884
  AdminStatsController: () => AdminStatsController,
17885
17885
  AdminStatsModule: () => AdminStatsModule,
17886
17886
  AdminStatsService: () => AdminStatsService,
17887
+ BILLING_FEATURE_UI_REGISTRY_TOKEN: () => BILLING_FEATURE_UI_REGISTRY_TOKEN,
17887
17888
  BUNDLE_REPOSITORY_TOKEN: () => BUNDLE_REPOSITORY_TOKEN,
17888
17889
  BaseIpRateLimitGuard: () => BaseIpRateLimitGuard,
17889
17890
  BundlesService: () => BundlesService,
17890
17891
  CATALOG_ENTRY_REPOSITORY_TOKEN: () => CATALOG_ENTRY_REPOSITORY_TOKEN,
17892
+ CATALOG_FEATURE_UI_REGISTRY_TOKEN: () => CATALOG_FEATURE_UI_REGISTRY_TOKEN,
17891
17893
  CATALOG_SERVICE_CONFIG_TOKEN: () => CATALOG_SERVICE_CONFIG_TOKEN,
17892
17894
  CHECKOUT_OFFER_REPOSITORY_TOKEN: () => CHECKOUT_OFFER_REPOSITORY_TOKEN,
17893
17895
  CONTRACT_FREEZE_PORT_TOKEN: () => CONTRACT_FREEZE_PORT_TOKEN,
@@ -17929,7 +17931,6 @@ __export(src_exports, {
17929
17931
  EntitlementService: () => EntitlementService,
17930
17932
  FEATURE_GUARD_CONFIG_TOKEN: () => FEATURE_GUARD_CONFIG_TOKEN,
17931
17933
  FEATURE_GUARD_MARKER: () => FEATURE_GUARD_MARKER,
17932
- FEATURE_UI_REGISTRY_TOKEN: () => FEATURE_UI_REGISTRY_TOKEN2,
17933
17934
  FeatureGuard: () => FeatureGuard,
17934
17935
  IMPLEMENTS_CAPABILITY_KEY: () => IMPLEMENTS_CAPABILITY_KEY,
17935
17936
  ImplementsCapability: () => ImplementsCapability,
@@ -18031,9 +18032,8 @@ __export(src_exports, {
18031
18032
  SUBSCRIPTION_STATS_PORT_TOKEN: () => SUBSCRIPTION_STATS_PORT_TOKEN,
18032
18033
  SUBSCRIPTION_USAGE_PORT_TOKEN: () => SUBSCRIPTION_USAGE_PORT_TOKEN,
18033
18034
  SUBSCRIPTION_WRITE_PORT_TOKEN: () => SUBSCRIPTION_WRITE_PORT_TOKEN,
18034
- SaaSiCatModule: () => SaasPlatformModule,
18035
+ SaaSiCatModule: () => SaaSiCatModule,
18035
18036
  SaaSiCatPublicRoute: () => SaaSiCatPublicRoute,
18036
- SaasPlatformModule: () => SaasPlatformModule,
18037
18037
  SaveRegistrationConfigDto: () => SaveRegistrationConfigDto,
18038
18038
  SaveRegistrationConfigSelectionDto: () => SaveRegistrationConfigSelectionDto,
18039
18039
  SelectRegistrationPlanDto: () => SelectRegistrationPlanDto,
@@ -18104,8 +18104,8 @@ __export(src_exports, {
18104
18104
  buildPublicMarketingCatalogController: () => buildPublicMarketingCatalogController,
18105
18105
  buildReplacedByIndex: () => buildReplacedByIndex,
18106
18106
  buildTenantSubscriptionBundlesController: () => buildTenantSubscriptionBundlesController,
18107
- classifyBundleVersionDiff: () => import_types5.classifyBundleVersionDiff,
18108
- classifyPlanDiff: () => import_types5.classifyPlanDiff,
18107
+ classifyBundleVersionDiff: () => import_core6.classifyBundleVersionDiff,
18108
+ classifyPlanDiff: () => import_core6.classifyPlanDiff,
18109
18109
  clearPendingPlanVersionFields: () => clearPendingPlanVersionFields,
18110
18110
  codedError: () => codedError,
18111
18111
  collectSubscriptionBundleFeatures: () => collectSubscriptionBundleFeatures,
@@ -18207,11 +18207,11 @@ __export(testing_exports, {
18207
18207
  StubAuditPort: () => StubAuditPort,
18208
18208
  StubMfaPort: () => StubMfaPort,
18209
18209
  StubRlsBypassPort: () => StubRlsBypassPort,
18210
- createSaasPlatformTestModule: () => createSaasPlatformTestModule
18210
+ createSaaSiCatTestModule: () => createSaaSiCatTestModule
18211
18211
  });
18212
18212
 
18213
18213
  // src/testing/fake-repositories.ts
18214
- var import_types35 = require("@saasicat/types");
18214
+ var import_core46 = require("@saasicat/core");
18215
18215
  var FakeSubscriptionRepository = class {
18216
18216
  static {
18217
18217
  __name(this, "FakeSubscriptionRepository");
@@ -18518,7 +18518,7 @@ var FakeTransactionRunner = class _FakeTransactionRunner {
18518
18518
  __name(this, "FakeTransactionRunner");
18519
18519
  }
18520
18520
  /** Sentinel value passed through as the TransactionContext. */
18521
- static TX_SENTINEL = /* @__PURE__ */ Symbol.for("FakeTransactionRunner.tx");
18521
+ static TX_SENTINEL = /* @__PURE__ */ Symbol.for("saasicat/nest/FakeTransactionRunner.tx");
18522
18522
  runCount = 0;
18523
18523
  async run(fn) {
18524
18524
  this.runCount += 1;
@@ -18967,7 +18967,7 @@ var FakePlanRepository = class {
18967
18967
  }
18968
18968
  async findActivePlanVersion(planKey, asOf = /* @__PURE__ */ new Date()) {
18969
18969
  const t = asOf.getTime();
18970
- const dayStart = (0, import_types35.startOfUtcDay)(asOf).getTime();
18970
+ const dayStart = (0, import_core46.startOfUtcDay)(asOf).getTime();
18971
18971
  const matches = [
18972
18972
  ...this.versions.values()
18973
18973
  ].filter((v) => {
@@ -19099,7 +19099,7 @@ var FakePlanRepository = class {
19099
19099
  }
19100
19100
  };
19101
19101
 
19102
- // src/testing/create-saas-platform-test-module.ts
19102
+ // src/testing/create-saasicat-test-module.ts
19103
19103
  var import_common85 = require("@nestjs/common");
19104
19104
  function _ts_decorate104(decorators, target, key, desc) {
19105
19105
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -19141,17 +19141,17 @@ var StubRlsBypassPort = class {
19141
19141
  return fn();
19142
19142
  }
19143
19143
  };
19144
- function createSaasPlatformTestModule(options) {
19144
+ function createSaaSiCatTestModule(options) {
19145
19145
  const defaultPlanId = options.defaultPlanId ?? options.planCatalog.plans?.[0]?.id;
19146
- let SaasPlatformTestHost = class SaasPlatformTestHost {
19146
+ let SaaSiCatTestHost = class SaaSiCatTestHost {
19147
19147
  static {
19148
- __name(this, "SaasPlatformTestHost");
19148
+ __name(this, "SaaSiCatTestHost");
19149
19149
  }
19150
19150
  };
19151
- SaasPlatformTestHost = _ts_decorate104([
19151
+ SaaSiCatTestHost = _ts_decorate104([
19152
19152
  (0, import_common85.Module)({
19153
19153
  imports: [
19154
- SaasPlatformModule.forRoot({
19154
+ SaaSiCatModule.forRoot({
19155
19155
  planCatalog: options.planCatalog,
19156
19156
  controller: {
19157
19157
  guards: []
@@ -19166,12 +19166,12 @@ function createSaasPlatformTestModule(options) {
19166
19166
  })
19167
19167
  ]
19168
19168
  })
19169
- ], SaasPlatformTestHost);
19169
+ ], SaaSiCatTestHost);
19170
19170
  return {
19171
- module: SaasPlatformTestHost
19171
+ module: SaaSiCatTestHost
19172
19172
  };
19173
19173
  }
19174
- __name(createSaasPlatformTestModule, "createSaasPlatformTestModule");
19174
+ __name(createSaaSiCatTestModule, "createSaaSiCatTestModule");
19175
19175
  // Annotate the CommonJS export names for ESM import in node:
19176
19176
  0 && (module.exports = {
19177
19177
  adminNs,