@saasicat/nest 1.0.0-rc.7 → 1.0.0-rc.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/.build-stamp +1 -1
  2. package/dist/_entries.cjs +116 -34
  3. package/dist/admin/index.js +2 -2
  4. package/dist/billing/index.d.cts +21 -7
  5. package/dist/billing/index.d.ts +21 -7
  6. package/dist/billing/index.js +11 -9
  7. package/dist/catalog/index.js +4 -4
  8. package/dist/{chunk-SO2NH2A6.js → chunk-5LE5AZUP.js} +4 -4
  9. package/dist/{chunk-7JEXCHMU.js → chunk-6FQ3G4IF.js} +1 -1
  10. package/dist/{chunk-BYINBUNY.js → chunk-FVD4TGER.js} +10 -3
  11. package/dist/{chunk-E74DRQJM.js → chunk-GG5NHRH5.js} +1 -1
  12. package/dist/{chunk-UUFUSKX2.js → chunk-H7SF4EUR.js} +2 -0
  13. package/dist/{chunk-EASFDWXV.js → chunk-HFQNSOIU.js} +4 -4
  14. package/dist/{chunk-DRMSHMOB.js → chunk-KBRELZT4.js} +1 -1
  15. package/dist/{chunk-MEVY2ZZG.js → chunk-L4VVZ4O5.js} +1 -1
  16. package/dist/{chunk-RCZ7ZGKU.js → chunk-OI7P6ZED.js} +19 -18
  17. package/dist/{chunk-NT4ZGXPA.js → chunk-W67WBRW5.js} +110 -39
  18. package/dist/{define-saasicat-DVKyc8oT.d.ts → define-saasicat-DKyoOmEC.d.ts} +1 -1
  19. package/dist/{define-saasicat-BrlUxP9g.d.cts → define-saasicat-j-CoHjoG.d.cts} +1 -1
  20. package/dist/{enforce-quota.interceptor-DEAyTI-x.d.ts → enforce-quota.interceptor-CLPZKiJC.d.ts} +2 -2
  21. package/dist/{enforce-quota.interceptor-DvuVXX_y.d.cts → enforce-quota.interceptor-CLS6xJ-E.d.cts} +2 -2
  22. package/dist/entitlement/index.js +4 -4
  23. package/dist/index.d.cts +6 -6
  24. package/dist/index.d.ts +6 -6
  25. package/dist/index.js +38 -36
  26. package/dist/{module-options-5-kVLwuv.d.cts → module-options-BDb8Tam7.d.cts} +8 -1
  27. package/dist/{module-options-DVmppjem.d.ts → module-options-DF3H6q3A.d.ts} +8 -1
  28. package/dist/platform/index.d.cts +7 -7
  29. package/dist/platform/index.d.ts +7 -7
  30. package/dist/platform/index.js +21 -21
  31. package/dist/promo/index.js +4 -4
  32. package/dist/subscription-contract/index.js +3 -3
  33. package/dist/{tenant-billing.controller-CGfCLtzu.d.cts → tenant-billing.controller-BqYJjjRi.d.cts} +121 -3
  34. package/dist/{tenant-billing.controller-D9rtguyx.d.ts → tenant-billing.controller-DhNqJDoU.d.ts} +121 -3
  35. package/dist/{tenant-billing.module-BVXDucZj.d.cts → tenant-billing.module-D96e9tYP.d.cts} +2 -137
  36. package/dist/{tenant-billing.module-C7rgy1jA.d.ts → tenant-billing.module-ZBfERe3L.d.ts} +2 -137
  37. package/dist/testing/index.d.cts +4 -4
  38. package/dist/testing/index.d.ts +4 -4
  39. package/dist/testing/index.js +15 -15
  40. package/package.json +3 -3
  41. package/dist/{chunk-L33BM4EN.js → chunk-DFQETRBL.js} +6 -6
  42. package/dist/{chunk-65ADCLHU.js → chunk-F7P2X2DR.js} +3 -3
  43. package/dist/{chunk-3Y4USRJS.js → chunk-LTT736P3.js} +3 -3
package/dist/.build-stamp CHANGED
@@ -1 +1 @@
1
- d2641f050887af0afe7e26844778e4a66660b2f17d7ded07dc67cb60d62c29b0
1
+ aec99b9d672b86bd7310c62f4ec0587e8708c675222a1792a640af85a8cdd6b2
package/dist/_entries.cjs CHANGED
@@ -1639,6 +1639,7 @@ __export(billing_exports, {
1639
1639
  FEATURE_GUARD_MARKER: () => FEATURE_GUARD_MARKER,
1640
1640
  FeatureGuard: () => FeatureGuard,
1641
1641
  LimitExceededFilter: () => LimitExceededFilter,
1642
+ NO_NOTICE_PERIOD: () => NO_NOTICE_PERIOD,
1642
1643
  PENDING_PLAN_QUERY_PORT_TOKEN: () => PENDING_PLAN_QUERY_PORT_TOKEN,
1643
1644
  PLAN_CATALOG_IMPORT_SINK_TOKEN: () => PLAN_CATALOG_IMPORT_SINK_TOKEN,
1644
1645
  PLAN_CATALOG_READ_SINK_TOKEN: () => PLAN_CATALOG_READ_SINK_TOKEN,
@@ -1954,9 +1955,12 @@ function decideCancellation(input) {
1954
1955
  };
1955
1956
  }
1956
1957
  __name(decideCancellation, "decideCancellation");
1958
+ var NO_NOTICE_PERIOD = {
1959
+ monthly: 0,
1960
+ yearly: 0
1961
+ };
1957
1962
  function noticeDaysFor(periods, billingCycle) {
1958
- if (!periods) return 0;
1959
- return (billingCycle === "YEARLY" ? periods.yearly : periods.monthly) ?? 0;
1963
+ return billingCycle === "YEARLY" ? periods.yearly : periods.monthly;
1960
1964
  }
1961
1965
  __name(noticeDaysFor, "noticeDaysFor");
1962
1966
  function decideCancellationFor(sub, now, noticePeriodDays) {
@@ -2144,6 +2148,7 @@ function buildPlanCatalogFromSnapshot(settings, snapshot) {
2144
2148
  app: settings.app,
2145
2149
  currency: settings.currency,
2146
2150
  vatRate: settings.vatRate,
2151
+ tenantBilling: settings.tenantBilling,
2147
2152
  ...settings.marketing ? {
2148
2153
  marketing: settings.marketing
2149
2154
  } : {},
@@ -2183,6 +2188,7 @@ var PlanCatalogModule = class _PlanCatalogModule {
2183
2188
  app: options.app,
2184
2189
  currency: options.currency,
2185
2190
  vatRate: options.vatRate,
2191
+ tenantBilling: options.tenantBilling,
2186
2192
  marketing: options.marketing
2187
2193
  }, snapshot);
2188
2194
  }, "useFactory"),
@@ -3174,6 +3180,13 @@ var import_js_yaml = __toESM(require("js-yaml"), 1);
3174
3180
  var import__ = __toESM(require("ajv/dist/2020.js"), 1);
3175
3181
  var import_ajv_formats = __toESM(require("ajv-formats"), 1);
3176
3182
  var import_spec = require("@saasicat/spec");
3183
+ function locate(error) {
3184
+ const segments = (error.instancePath ?? "").split("/").filter(Boolean);
3185
+ const missing = error.params?.missingProperty;
3186
+ if (missing) segments.push(missing);
3187
+ return segments.length > 0 ? segments.join(".") : "(document root)";
3188
+ }
3189
+ __name(locate, "locate");
3177
3190
  var PLAN_CATALOG_UNREADABLE_ERROR = "PlanCatalogUnreadableError";
3178
3191
  var PlanCatalogValidationError = class extends Error {
3179
3192
  static {
@@ -3182,7 +3195,7 @@ var PlanCatalogValidationError = class extends Error {
3182
3195
  source;
3183
3196
  errors;
3184
3197
  constructor(source, errors) {
3185
- const messages = errors.map((e) => `${e.instancePath || "/"}: ${e.message ?? "unknown"}`).join("\n ");
3198
+ const messages = errors.map((e) => `${locate(e)}: ${e.message ?? "unknown"}`).join("\n ");
3186
3199
  super(`Plan catalog validation failed for ${source}:
3187
3200
  ${messages}`), this.source = source, this.errors = errors;
3188
3201
  this.name = "PlanCatalogValidationError";
@@ -4023,12 +4036,12 @@ var PlanChangePreviewService = class {
4023
4036
  const landsAt = ctx.canceledEffectiveAt ?? ctx.canceledAt;
4024
4037
  if (landsAt !== null && landsAt <= now) {
4025
4038
  blockers.push({
4026
- code: "SUBSCRIPTION_ENDED",
4039
+ code: import_core17.BILLING_ERROR_CODES.SUBSCRIPTION_ENDED,
4027
4040
  message: "This subscription has ended. Its plan can no longer be changed."
4028
4041
  });
4029
4042
  } else if (landsAt !== null && cycleDirection !== "SAME") {
4030
4043
  blockers.push({
4031
- code: "CANCELLATION_LOCKS_THE_CYCLE",
4044
+ code: import_core17.BILLING_ERROR_CODES.CANCELLATION_LOCKS_THE_CYCLE,
4032
4045
  message: "This subscription is cancelled, so its billing cycle cannot change. The plan can."
4033
4046
  });
4034
4047
  }
@@ -4036,47 +4049,74 @@ var PlanChangePreviewService = class {
4036
4049
  const blockedSources = this.blockedPlans?.asSource ?? [];
4037
4050
  if (blockedTargets.includes(targetPlan)) {
4038
4051
  blockers.push({
4039
- code: `${targetPlan}_NOT_SELF_SERVICE`,
4040
- message: `${targetSnap.name} is only activated via a special contract. Please contact the contract manager.`
4052
+ code: import_core17.BILLING_ERROR_CODES.PLAN_NOT_SELF_SERVICE,
4053
+ message: `${targetSnap.name} is only activated via a special contract. Please contact the contract manager.`,
4054
+ params: {
4055
+ planName: targetSnap.name,
4056
+ planKey: targetPlan
4057
+ }
4041
4058
  });
4042
4059
  }
4043
4060
  if (blockedSources.includes(sub.plan)) {
4044
4061
  blockers.push({
4045
- code: `${sub.plan}_LOCKED`,
4046
- message: `Active ${currentSnap.name} special contract \u2014 please contact the contract manager to change plans.`
4062
+ code: import_core17.BILLING_ERROR_CODES.PLAN_LOCKED,
4063
+ message: `Active ${currentSnap.name} special contract \u2014 please contact the contract manager to change plans.`,
4064
+ params: {
4065
+ planName: currentSnap.name,
4066
+ planKey: sub.plan
4067
+ }
4047
4068
  });
4048
4069
  }
4049
4070
  for (const [key, row] of Object.entries(limitsCheck)) {
4050
4071
  if (!row.exceeded) continue;
4051
4072
  const usedDisplay = isFloatQuota(key) ? row.used.toFixed(1) : row.used.toString();
4052
4073
  blockers.push({
4053
- code: `${key.toUpperCase()}_OVER_TARGET`,
4054
- message: `Current usage ${usedDisplay} exceeds the target limit ${row.targetMax} (${key}) in the ${targetSnap.name} plan. Please reduce usage first.`
4074
+ code: import_core17.BILLING_ERROR_CODES.QUOTA_OVER_TARGET,
4075
+ message: `Current usage ${usedDisplay} exceeds the target limit ${row.targetMax} (${key}) in the ${targetSnap.name} plan. Please reduce usage first.`,
4076
+ params: {
4077
+ used: usedDisplay,
4078
+ targetMax: row.targetMax,
4079
+ quotaKey: key,
4080
+ planName: targetSnap.name
4081
+ }
4055
4082
  });
4056
4083
  }
4057
4084
  if (featuresLost.length > 0) {
4058
4085
  warnings.push({
4059
- code: "FEATURES_LOST",
4060
- message: `Switching means losing access to ${featuresLost.length} feature${featuresLost.length === 1 ? "" : "s"}. Existing data is retained and never deleted \u2014 upgrading again unlocks it.`
4086
+ code: featuresLost.length === 1 ? import_core17.BILLING_ERROR_CODES.FEATURE_LOST : import_core17.BILLING_ERROR_CODES.FEATURES_LOST,
4087
+ message: `Switching means losing access to ${featuresLost.length} feature${featuresLost.length === 1 ? "" : "s"}. Existing data is retained and never deleted \u2014 upgrading again unlocks it.`,
4088
+ params: {
4089
+ count: featuresLost.length
4090
+ }
4061
4091
  });
4062
4092
  }
4063
4093
  if (changeType === "NOOP") {
4064
4094
  warnings.push({
4065
- code: "NO_CHANGE",
4095
+ code: import_core17.BILLING_ERROR_CODES.NO_CHANGE,
4066
4096
  message: "Target plan and billing cycle already match the current state."
4067
4097
  });
4068
4098
  }
4069
4099
  if (planDirection === "UP" && cycleDirection === "SHORTER") {
4070
4100
  warnings.push({
4071
- code: "CYCLE_SHORTENS_AT_TERM_END",
4072
- message: `A ${targetCycle.toLowerCase()} ${targetSnap.name} cannot start inside the ${sub.billingCycle.toLowerCase()} term you are in. The upgrade takes effect when that term ends; to have it today, keep the ${sub.billingCycle.toLowerCase()} cycle.`
4101
+ code: import_core17.BILLING_ERROR_CODES.CYCLE_SHORTENS_AT_TERM_END,
4102
+ message: `A ${targetCycle.toLowerCase()} ${targetSnap.name} cannot start inside the ${sub.billingCycle.toLowerCase()} term you are in. The upgrade takes effect when that term ends; to have it today, keep the ${sub.billingCycle.toLowerCase()} cycle.`,
4103
+ params: {
4104
+ targetCycle: targetCycle.toLowerCase(),
4105
+ currentCycle: sub.billingCycle.toLowerCase(),
4106
+ planName: targetSnap.name
4107
+ }
4073
4108
  });
4074
4109
  }
4075
4110
  const changeLandsAt = effectiveAt ?? now;
4076
4111
  for (const booking of await this.bookingsOutlastingCycle(sub, targetCycle, changeLandsAt)) {
4077
4112
  blockers.push({
4078
- code: import_core17.BILLING_ERROR_CODES.BUNDLE_CYCLE_EXCEEDS_PLAN,
4079
- message: `A yearly add-on is booked until ${booking.until}. A ${targetCycle.toLowerCase()} plan cannot carry it \u2014 cancel the add-on first, or keep the yearly cycle.`
4113
+ code: import_core17.BILLING_ERROR_CODES.BUNDLE_BOOKING_OUTLASTS_TARGET_CYCLE,
4114
+ message: `A yearly bundle is booked until ${booking.until}. A monthly plan cannot carry it \u2014 cancel the bundle first, or keep the yearly cycle.`,
4115
+ params: {
4116
+ billingCycle: "yearly",
4117
+ planCycle: targetCycle.toLowerCase(),
4118
+ until: booking.until
4119
+ }
4080
4120
  });
4081
4121
  }
4082
4122
  const projectedTrialEndsAt = this.trialProjection && sub.status === "TRIAL" ? await this.trialProjection.projectTrialEndsAt({
@@ -6101,7 +6141,7 @@ var TenantBillingController = class _TenantBillingController {
6101
6141
  contractFreeze;
6102
6142
  trialProjection;
6103
6143
  cancellationNoticeDays;
6104
- constructor(entitlements, planPreview, subscriptionUsage, usageSnapshot, subscriptionWrite, tenantIdResolver = null, userIdResolver = null, blockedPlans = null, promoCodes = null, auditService = null, userEmailResolver = null, auditContextResolver = null, subscriptionBundles = null, contractFreeze = null, trialProjection = null, cancellationNoticeDays = {}) {
6144
+ constructor(entitlements, planPreview, subscriptionUsage, usageSnapshot, subscriptionWrite, tenantIdResolver = null, userIdResolver = null, blockedPlans = null, promoCodes = null, auditService = null, userEmailResolver = null, auditContextResolver = null, subscriptionBundles = null, contractFreeze = null, trialProjection = null, cancellationNoticeDays = NO_NOTICE_PERIOD) {
6105
6145
  this.entitlements = entitlements;
6106
6146
  this.planPreview = planPreview;
6107
6147
  this.subscriptionUsage = subscriptionUsage;
@@ -6210,8 +6250,19 @@ var TenantBillingController = class _TenantBillingController {
6210
6250
  if (blockedTargets.includes(dto.plan)) {
6211
6251
  throw new import_common34.ForbiddenException({
6212
6252
  code: import_core22.BILLING_ERROR_CODES.PLAN_NOT_SELF_SERVICE,
6213
- message: `${dto.plan} is not activated via self-service.`,
6253
+ // Says what the shipped catalogue says, so an app that has not
6254
+ // translated this code and one that has do not refuse in two
6255
+ // different sentences.
6256
+ message: `${dto.plan} is only activated via a special contract. Please contact the contract manager.`,
6257
+ // `planName` is the key here, and that is the best label this
6258
+ // check has: it decides before any catalogue is read, from
6259
+ // nothing but the key the request sent. The plan-change
6260
+ // preview does have a catalogue and passes the real name,
6261
+ // which is the one a tenant recognises. Either way the
6262
+ // template's `{planName}` resolves to a word rather than a
6263
+ // brace — `error-params-contract.test.js` holds that.
6214
6264
  params: {
6265
+ planName: dto.plan,
6215
6266
  planKey: dto.plan
6216
6267
  }
6217
6268
  });
@@ -6345,8 +6396,10 @@ var TenantBillingController = class _TenantBillingController {
6345
6396
  if (blockedTargets.includes(dto.plan)) {
6346
6397
  throw new import_common34.ForbiddenException({
6347
6398
  code: import_core22.BILLING_ERROR_CODES.PLAN_NOT_SELF_SERVICE,
6348
- message: `${dto.plan} is not activated via self-service.`,
6399
+ message: `${dto.plan} is only activated via a special contract. Please contact the contract manager.`,
6400
+ // The key as the label — see the note on the plan-change route.
6349
6401
  params: {
6402
+ planName: dto.plan,
6350
6403
  planKey: dto.plan
6351
6404
  }
6352
6405
  });
@@ -6911,6 +6964,7 @@ TenantBillingController = _ts_decorate35([
6911
6964
 
6912
6965
  // src/billing/tenant-billing.module.ts
6913
6966
  var import_common35 = require("@nestjs/common");
6967
+ var import_spec2 = require("@saasicat/spec");
6914
6968
  function _ts_decorate36(decorators, target, key, desc) {
6915
6969
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6916
6970
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -6918,6 +6972,27 @@ function _ts_decorate36(decorators, target, key, desc) {
6918
6972
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6919
6973
  }
6920
6974
  __name(_ts_decorate36, "_ts_decorate");
6975
+ function settingFromCatalog(catalog, key) {
6976
+ const settings = catalog.tenantBilling;
6977
+ const value = settings?.[key];
6978
+ if (value === void 0) {
6979
+ throw new Error(`The plan catalogue carries no tenantBilling.${key}. It is a required section of config/saas.yaml and the loader refuses a file without it, so a catalogue that reaches here without one was built in code: check the \`dbCatalog\` block, which forwards \`tenantBilling\` from that same file, or the object passed to \`planCatalog\`.`);
6980
+ }
6981
+ return value;
6982
+ }
6983
+ __name(settingFromCatalog, "settingFromCatalog");
6984
+ var MOVED_TO_THE_FILE = Object.keys(import_spec2.planCatalogSchema.properties?.tenantBilling?.properties ?? // Refuses to guess rather than falling back to an empty list: an empty
6985
+ // one would turn this guard off without saying so.
6986
+ (() => {
6987
+ throw new Error("plan-catalog.schema.json declares no tenantBilling properties \u2014 @saasicat/spec and @saasicat/nest are out of step.");
6988
+ })());
6989
+ function assertNoMovedOptions(options) {
6990
+ const given = options;
6991
+ const passed = MOVED_TO_THE_FILE.filter((key) => given[key] !== void 0);
6992
+ if (passed.length === 0) return;
6993
+ throw new Error(`TenantBillingModule.forRoot() no longer accepts ${passed.join(" and ")} \u2014 this moved to config/saas.yaml under \`tenantBilling:\`. Move the value there (both members of each setting are required) and delete it here. The file is the one place these live, so a fallback here would be the second home that change exists to close. See docs/guides/upgrade-to-1.0.md.`);
6994
+ }
6995
+ __name(assertNoMovedOptions, "assertNoMovedOptions");
6921
6996
  var TenantBillingModule = class _TenantBillingModule {
6922
6997
  static {
6923
6998
  __name(this, "TenantBillingModule");
@@ -6932,18 +7007,20 @@ var TenantBillingModule = class _TenantBillingModule {
6932
7007
  TenantAdminGuard,
6933
7008
  PlanChangePreviewService
6934
7009
  ];
6935
- if (options.cancellationNoticeDays) {
6936
- providers.push({
6937
- provide: CANCELLATION_NOTICE_DAYS_TOKEN,
6938
- useValue: options.cancellationNoticeDays
6939
- });
6940
- }
6941
- if (options.selfServiceBlockedPlans) {
6942
- providers.push({
6943
- provide: SELF_SERVICE_BLOCKED_PLANS_TOKEN,
6944
- useValue: options.selfServiceBlockedPlans
6945
- });
6946
- }
7010
+ assertNoMovedOptions(options);
7011
+ providers.push({
7012
+ provide: CANCELLATION_NOTICE_DAYS_TOKEN,
7013
+ useFactory: /* @__PURE__ */ __name((catalog) => settingFromCatalog(catalog, "cancellationNoticeDays"), "useFactory"),
7014
+ inject: [
7015
+ PLAN_CATALOG_TOKEN
7016
+ ]
7017
+ }, {
7018
+ provide: SELF_SERVICE_BLOCKED_PLANS_TOKEN,
7019
+ useFactory: /* @__PURE__ */ __name((catalog) => settingFromCatalog(catalog, "selfServiceBlockedPlans"), "useFactory"),
7020
+ inject: [
7021
+ PLAN_CATALOG_TOKEN
7022
+ ]
7023
+ });
6947
7024
  if (options.subscriptionBundleRepository) {
6948
7025
  providers.push(asProvider(SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN, options.subscriptionBundleRepository));
6949
7026
  }
@@ -7616,6 +7693,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
7616
7693
  ], GeneratedTenantSubscriptionBundlesController.prototype, "prices", null);
7617
7694
  _ts_decorate39([
7618
7695
  (0, import_common38.Post)(),
7696
+ (0, import_common38.UseGuards)(TenantAdminGuard),
7619
7697
  _ts_param26(0, (0, import_common38.Req)()),
7620
7698
  _ts_param26(1, (0, import_common38.Body)()),
7621
7699
  _ts_metadata29("design:type", Function),
@@ -7639,6 +7717,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
7639
7717
  ], GeneratedTenantSubscriptionBundlesController.prototype, "preview", null);
7640
7718
  _ts_decorate39([
7641
7719
  (0, import_common38.Delete)(":id"),
7720
+ (0, import_common38.UseGuards)(TenantAdminGuard),
7642
7721
  (0, import_common38.HttpCode)(import_common38.HttpStatus.OK),
7643
7722
  _ts_param26(0, (0, import_common38.Req)()),
7644
7723
  _ts_param26(1, (0, import_common38.Param)("id", new import_common38.ParseUUIDPipe())),
@@ -7653,6 +7732,7 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
7653
7732
  ], GeneratedTenantSubscriptionBundlesController.prototype, "cancel", null);
7654
7733
  _ts_decorate39([
7655
7734
  (0, import_common38.Post)(":id/reactivate"),
7735
+ (0, import_common38.UseGuards)(TenantAdminGuard),
7656
7736
  (0, import_common38.HttpCode)(import_common38.HttpStatus.OK),
7657
7737
  _ts_param26(0, (0, import_common38.Req)()),
7658
7738
  _ts_param26(1, (0, import_common38.Param)("id", new import_common38.ParseUUIDPipe())),
@@ -14526,7 +14606,7 @@ var RULE_SPECS = [
14526
14606
  id: "catalog.identity-or-sink",
14527
14607
  when: /* @__PURE__ */ __name((c) => !c.options.planCatalog, "when"),
14528
14608
  assert: /* @__PURE__ */ __name((c) => Boolean(c.adapters.planCatalogReadSink && c.options.dbCatalog), "assert"),
14529
- message: "no plan catalogue is reachable. Either set `planCatalog` (the quickstart YAML path) or, for DB hydration, BOTH a `planCatalogReadSink` (via `adapters` or `persistence`) AND `dbCatalog` ({ app, currency, vatRate }). Without the identity the app boots with a silently empty catalogue."
14609
+ message: "no plan catalogue is reachable. Either set `planCatalog` (the quickstart YAML path) or, for DB hydration, BOTH a `planCatalogReadSink` (via `adapters` or `persistence`) AND `dbCatalog` ({ app, currency, vatRate, tenantBilling }). Without the identity the app boots with a silently empty catalogue."
14530
14610
  },
14531
14611
  {
14532
14612
  id: "catalog.app-is-named",
@@ -16177,6 +16257,7 @@ function composePlanCatalog(options, sink) {
16177
16257
  app: dbCatalog.app,
16178
16258
  currency: dbCatalog.currency,
16179
16259
  vatRate: dbCatalog.vatRate,
16260
+ tenantBilling: dbCatalog.tenantBilling,
16180
16261
  marketing: dbCatalog.marketing,
16181
16262
  sink,
16182
16263
  imports: options.imports
@@ -18616,6 +18697,7 @@ __export(src_exports, {
18616
18697
  MarketingSettingsService: () => MarketingSettingsService,
18617
18698
  MfaGuard: () => MfaGuard,
18618
18699
  MfaService: () => MfaService,
18700
+ NO_NOTICE_PERIOD: () => NO_NOTICE_PERIOD,
18619
18701
  PASSWORD_HASHER_TOKEN: () => PASSWORD_HASHER_TOKEN,
18620
18702
  PAYMENT_EVENT_LOG_TOKEN: () => PAYMENT_EVENT_LOG_TOKEN,
18621
18703
  PAYMENT_PROVIDER_TOKEN: () => PAYMENT_PROVIDER_TOKEN,
@@ -25,15 +25,15 @@ import {
25
25
  SuperAdminGuard,
26
26
  SuspendTenantDto,
27
27
  buildAdminStatsController
28
- } from "../chunk-3Y4USRJS.js";
28
+ } from "../chunk-LTT736P3.js";
29
29
  import {
30
30
  AUDIT_PORT_TOKEN,
31
31
  AdminAuditService,
32
32
  MFA_PORT_TOKEN,
33
33
  RLS_BYPASS_PORT_TOKEN
34
34
  } from "../chunk-O2J2HDXA.js";
35
- import "../chunk-57V6ZTI6.js";
36
35
  import "../chunk-YSC46BGM.js";
36
+ import "../chunk-57V6ZTI6.js";
37
37
  import "../chunk-SABTXESR.js";
38
38
  import "../chunk-SHUYVCID.js";
39
39
  export {
@@ -1,18 +1,18 @@
1
1
  import { BillingCycle, BundleVersionRow, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalog, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog } from '@saasicat/core';
2
- export { BundleVersionFields, ChangeDirection, DiffResult, PlanVersionFields, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/core';
3
- import { F as FEATURE_GUARD_MARKER, j as ContractFreezePort, k as ContractFreezeSourcePort } from '../tenant-billing.module-BVXDucZj.cjs';
4
- export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CANCELLATION_NOTICE_DAYS_TOKEN, c as CONTRACT_FREEZE_PORT_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as CancellableSubscription, f as CancellationDecision, g as CancellationInput, h as CancellationNoticePeriods, i as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, M as MarkedFeatureGuard, P as PENDING_PLAN_QUERY_PORT_TOKEN, l as PendingPlanQueryPort, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, m as SELF_SERVICE_BLOCKED_PLANS_TOKEN, n as SUBSCRIPTION_USAGE_PORT_TOKEN, o as SUBSCRIPTION_WRITE_PORT_TOKEN, p as SelfServiceBlockedBundles, q as SelfServiceBlockedPlans, r as SubscriptionBundleControllerOptions, s as SubscriptionBundleModule, t as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, u as TENANT_ID_RESOLVER_TOKEN, v as TRIAL_PROJECTION_PORT_TOKEN, w as TenantBillingModule, x as TenantBillingModuleOptions, y as TenantIdResolver, z as TrialProjectionInput, B as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, E as USER_EMAIL_RESOLVER_TOKEN, G as USER_ID_RESOLVER_TOKEN, H as UserEmailResolver, I as UserIdResolver, J as decideCancellation, K as decideCancellationFor, L as isPlatformFeatureGuard, N as noticeDaysFor } from '../tenant-billing.module-BVXDucZj.cjs';
2
+ export { BundleVersionFields, CancellationNoticePeriods, ChangeDirection, DiffResult, PlanVersionFields, SelfServiceBlockedPlans, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/core';
3
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as CancellableSubscription, c as CancellationDecision, d as CancellationInput, e as ChangePlanDto, f as CompleteOnboardingSubscriptionDto, g as ComposedTenantAuthGuard, h as CycleDirection, L as LimitsCheckRow, N as NO_NOTICE_PERIOD, P as PendingPlanMaterializationService, i as PlanChangeContext, j as PlanChangePreviewDto, k as PlanChangePreviewIssue, l as PlanChangePreviewService, m as PlanChangeType, n as PlanDirection, o as PlanSnapshotDto, p as PreviewPlanChangeDto, q as ProrationDto, r as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, s as SubscriptionBundleCancelPreviewDto, t as SubscriptionBundleConfig, u as SubscriptionBundlePreviewContext, v as SubscriptionBundlePreviewIssue, w as SubscriptionBundlePreviewService, x as SubscriptionBundlesService, T as TenantAdminGuard, y as TenantBillingController, U as UsageResponse, z as addMonths, D as clampToParent, E as computeProration, F as decideCancellation, G as decideCancellationFor, H as noticeDaysFor, I as resolveBundleCancelEffectiveAt } from '../tenant-billing.controller-BqYJjjRi.cjs';
4
+ import { F as FEATURE_GUARD_MARKER, f as ContractFreezePort, g as ContractFreezeSourcePort } from '../tenant-billing.module-D96e9tYP.cjs';
5
+ export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CANCELLATION_NOTICE_DAYS_TOKEN, c as CONTRACT_FREEZE_PORT_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, M as MarkedFeatureGuard, P as PENDING_PLAN_QUERY_PORT_TOKEN, h as PendingPlanQueryPort, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SUBSCRIPTION_USAGE_PORT_TOKEN, k as SUBSCRIPTION_WRITE_PORT_TOKEN, l as SelfServiceBlockedBundles, m as SubscriptionBundleControllerOptions, n as SubscriptionBundleModule, o as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, p as TENANT_ID_RESOLVER_TOKEN, q as TRIAL_PROJECTION_PORT_TOKEN, r as TenantBillingModule, s as TenantBillingModuleOptions, t as TenantIdResolver, u as TrialProjectionInput, v as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, w as USER_EMAIL_RESOLVER_TOKEN, x as USER_ID_RESOLVER_TOKEN, y as UserEmailResolver, z as UserIdResolver, B as isPlatformFeatureGuard } from '../tenant-billing.module-D96e9tYP.cjs';
5
6
  import * as _nestjs_common from '@nestjs/common';
6
7
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
7
8
  export { Type as NestType } from '@nestjs/common';
8
9
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
9
10
  import { c as EntitlementService } from '../aggregation-Bsg1g9Q0.cjs';
10
11
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
11
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, e as CycleDirection, L as LimitsCheckRow, P as PendingPlanMaterializationService, f as PlanChangeContext, g as PlanChangePreviewDto, h as PlanChangePreviewIssue, i as PlanChangePreviewService, j as PlanChangeType, k as PlanDirection, l as PlanSnapshotDto, m as PreviewPlanChangeDto, n as ProrationDto, o as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, p as SubscriptionBundleCancelPreviewDto, q as SubscriptionBundleConfig, r as SubscriptionBundlePreviewContext, s as SubscriptionBundlePreviewIssue, t as SubscriptionBundlePreviewService, u as SubscriptionBundlesService, T as TenantAdminGuard, v as TenantBillingController, U as UsageResponse, w as addMonths, x as clampToParent, y as computeProration, z as resolveBundleCancelEffectiveAt } from '../tenant-billing.controller-CGfCLtzu.cjs';
12
12
  import { S as SubscriptionContractService } from '../subscription-contract.service-hD87MKyg.cjs';
13
- import '../plan-resolution-CwUy_OqC.cjs';
14
13
  import '../promo.service-BJbKAmw3.cjs';
15
14
  import '../admin-audit.service-4P3Djdxk.cjs';
15
+ import '../plan-resolution-CwUy_OqC.cjs';
16
16
 
17
17
  /**
18
18
  * One period onwards, on `anchorDay` where the month has one.
@@ -550,6 +550,9 @@ interface AjvErrorLike {
550
550
  instancePath?: string;
551
551
  message?: string;
552
552
  schemaPath?: string;
553
+ params?: {
554
+ missingProperty?: string;
555
+ };
553
556
  }
554
557
  /**
555
558
  * `Error.name` for a document that could not be read as a catalog at all.
@@ -603,6 +606,12 @@ interface PlanCatalogModuleOptions {
603
606
  app: PlanCatalog['app'];
604
607
  currency: string;
605
608
  vatRate: number;
609
+ /**
610
+ * Commercial self-service settings from `config/saas.yaml#tenantBilling`.
611
+ * The read sink loads plans and features; settings are never in the
612
+ * database, so they can only come from the file.
613
+ */
614
+ tenantBilling: PlanCatalog['tenantBilling'];
606
615
  /**
607
616
  * App-wide marketing configuration — including the
608
617
  * `availableLocales` pool. Flows into `PLAN_CATALOG_TOKEN.marketing`
@@ -633,6 +642,12 @@ interface PlanCatalogBuildSettings {
633
642
  app: PlanCatalog['app'];
634
643
  currency: string;
635
644
  vatRate: number;
645
+ /**
646
+ * Commercial self-service settings from `config/saas.yaml#tenantBilling`.
647
+ * Required, like the two above: the database carries plans and features,
648
+ * never the settings, so this can only come from the file.
649
+ */
650
+ tenantBilling: PlanCatalog['tenantBilling'];
636
651
  /** App-wide marketing configuration. Optional. */
637
652
  marketing?: PlanCatalog['marketing'];
638
653
  }
@@ -941,8 +956,7 @@ declare const SUBSCRIPTION_BUNDLE_CONFIG_TOKEN: unique symbol;
941
956
 
942
957
  /**
943
958
  * Factory analogous to `buildBundlesController` etc. — the consumer can pass
944
- * additional guards (e.g. RoleGuard) in addition to the platform default
945
- * `ComposedTenantAuthGuard`.
959
+ * additional guards (e.g. RoleGuard) in addition to the platform defaults.
946
960
  */
947
961
  declare function buildTenantSubscriptionBundlesController(extraGuards?: Array<Type<CanActivate>>): Type;
948
962
 
@@ -1,18 +1,18 @@
1
1
  import { BillingCycle, BundleVersionRow, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalog, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog } from '@saasicat/core';
2
- export { BundleVersionFields, ChangeDirection, DiffResult, PlanVersionFields, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/core';
3
- import { F as FEATURE_GUARD_MARKER, j as ContractFreezePort, k as ContractFreezeSourcePort } from '../tenant-billing.module-C7rgy1jA.js';
4
- export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CANCELLATION_NOTICE_DAYS_TOKEN, c as CONTRACT_FREEZE_PORT_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as CancellableSubscription, f as CancellationDecision, g as CancellationInput, h as CancellationNoticePeriods, i as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, M as MarkedFeatureGuard, P as PENDING_PLAN_QUERY_PORT_TOKEN, l as PendingPlanQueryPort, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, m as SELF_SERVICE_BLOCKED_PLANS_TOKEN, n as SUBSCRIPTION_USAGE_PORT_TOKEN, o as SUBSCRIPTION_WRITE_PORT_TOKEN, p as SelfServiceBlockedBundles, q as SelfServiceBlockedPlans, r as SubscriptionBundleControllerOptions, s as SubscriptionBundleModule, t as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, u as TENANT_ID_RESOLVER_TOKEN, v as TRIAL_PROJECTION_PORT_TOKEN, w as TenantBillingModule, x as TenantBillingModuleOptions, y as TenantIdResolver, z as TrialProjectionInput, B as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, E as USER_EMAIL_RESOLVER_TOKEN, G as USER_ID_RESOLVER_TOKEN, H as UserEmailResolver, I as UserIdResolver, J as decideCancellation, K as decideCancellationFor, L as isPlatformFeatureGuard, N as noticeDaysFor } from '../tenant-billing.module-C7rgy1jA.js';
2
+ export { BundleVersionFields, CancellationNoticePeriods, ChangeDirection, DiffResult, PlanVersionFields, SelfServiceBlockedPlans, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/core';
3
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as CancellableSubscription, c as CancellationDecision, d as CancellationInput, e as ChangePlanDto, f as CompleteOnboardingSubscriptionDto, g as ComposedTenantAuthGuard, h as CycleDirection, L as LimitsCheckRow, N as NO_NOTICE_PERIOD, P as PendingPlanMaterializationService, i as PlanChangeContext, j as PlanChangePreviewDto, k as PlanChangePreviewIssue, l as PlanChangePreviewService, m as PlanChangeType, n as PlanDirection, o as PlanSnapshotDto, p as PreviewPlanChangeDto, q as ProrationDto, r as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, s as SubscriptionBundleCancelPreviewDto, t as SubscriptionBundleConfig, u as SubscriptionBundlePreviewContext, v as SubscriptionBundlePreviewIssue, w as SubscriptionBundlePreviewService, x as SubscriptionBundlesService, T as TenantAdminGuard, y as TenantBillingController, U as UsageResponse, z as addMonths, D as clampToParent, E as computeProration, F as decideCancellation, G as decideCancellationFor, H as noticeDaysFor, I as resolveBundleCancelEffectiveAt } from '../tenant-billing.controller-DhNqJDoU.js';
4
+ import { F as FEATURE_GUARD_MARKER, f as ContractFreezePort, g as ContractFreezeSourcePort } from '../tenant-billing.module-ZBfERe3L.js';
5
+ export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CANCELLATION_NOTICE_DAYS_TOKEN, c as CONTRACT_FREEZE_PORT_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, M as MarkedFeatureGuard, P as PENDING_PLAN_QUERY_PORT_TOKEN, h as PendingPlanQueryPort, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SUBSCRIPTION_USAGE_PORT_TOKEN, k as SUBSCRIPTION_WRITE_PORT_TOKEN, l as SelfServiceBlockedBundles, m as SubscriptionBundleControllerOptions, n as SubscriptionBundleModule, o as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, p as TENANT_ID_RESOLVER_TOKEN, q as TRIAL_PROJECTION_PORT_TOKEN, r as TenantBillingModule, s as TenantBillingModuleOptions, t as TenantIdResolver, u as TrialProjectionInput, v as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, w as USER_EMAIL_RESOLVER_TOKEN, x as USER_ID_RESOLVER_TOKEN, y as UserEmailResolver, z as UserIdResolver, B as isPlatformFeatureGuard } from '../tenant-billing.module-ZBfERe3L.js';
5
6
  import * as _nestjs_common from '@nestjs/common';
6
7
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
7
8
  export { Type as NestType } from '@nestjs/common';
8
9
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
9
10
  import { c as EntitlementService } from '../aggregation-53yv4-rr.js';
10
11
  import { P as ProviderSpec } from '../di-CcNeq9v-.js';
11
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, e as CycleDirection, L as LimitsCheckRow, P as PendingPlanMaterializationService, f as PlanChangeContext, g as PlanChangePreviewDto, h as PlanChangePreviewIssue, i as PlanChangePreviewService, j as PlanChangeType, k as PlanDirection, l as PlanSnapshotDto, m as PreviewPlanChangeDto, n as ProrationDto, o as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, p as SubscriptionBundleCancelPreviewDto, q as SubscriptionBundleConfig, r as SubscriptionBundlePreviewContext, s as SubscriptionBundlePreviewIssue, t as SubscriptionBundlePreviewService, u as SubscriptionBundlesService, T as TenantAdminGuard, v as TenantBillingController, U as UsageResponse, w as addMonths, x as clampToParent, y as computeProration, z as resolveBundleCancelEffectiveAt } from '../tenant-billing.controller-D9rtguyx.js';
12
12
  import { S as SubscriptionContractService } from '../subscription-contract.service-hD87MKyg.js';
13
- import '../plan-resolution-CwUy_OqC.js';
14
13
  import '../promo.service-BJbKAmw3.js';
15
14
  import '../admin-audit.service-4P3Djdxk.js';
15
+ import '../plan-resolution-CwUy_OqC.js';
16
16
 
17
17
  /**
18
18
  * One period onwards, on `anchorDay` where the month has one.
@@ -550,6 +550,9 @@ interface AjvErrorLike {
550
550
  instancePath?: string;
551
551
  message?: string;
552
552
  schemaPath?: string;
553
+ params?: {
554
+ missingProperty?: string;
555
+ };
553
556
  }
554
557
  /**
555
558
  * `Error.name` for a document that could not be read as a catalog at all.
@@ -603,6 +606,12 @@ interface PlanCatalogModuleOptions {
603
606
  app: PlanCatalog['app'];
604
607
  currency: string;
605
608
  vatRate: number;
609
+ /**
610
+ * Commercial self-service settings from `config/saas.yaml#tenantBilling`.
611
+ * The read sink loads plans and features; settings are never in the
612
+ * database, so they can only come from the file.
613
+ */
614
+ tenantBilling: PlanCatalog['tenantBilling'];
606
615
  /**
607
616
  * App-wide marketing configuration — including the
608
617
  * `availableLocales` pool. Flows into `PLAN_CATALOG_TOKEN.marketing`
@@ -633,6 +642,12 @@ interface PlanCatalogBuildSettings {
633
642
  app: PlanCatalog['app'];
634
643
  currency: string;
635
644
  vatRate: number;
645
+ /**
646
+ * Commercial self-service settings from `config/saas.yaml#tenantBilling`.
647
+ * Required, like the two above: the database carries plans and features,
648
+ * never the settings, so this can only come from the file.
649
+ */
650
+ tenantBilling: PlanCatalog['tenantBilling'];
636
651
  /** App-wide marketing configuration. Optional. */
637
652
  marketing?: PlanCatalog['marketing'];
638
653
  }
@@ -941,8 +956,7 @@ declare const SUBSCRIPTION_BUNDLE_CONFIG_TOKEN: unique symbol;
941
956
 
942
957
  /**
943
958
  * Factory analogous to `buildBundlesController` etc. — the consumer can pass
944
- * additional guards (e.g. RoleGuard) in addition to the platform default
945
- * `ComposedTenantAuthGuard`.
959
+ * additional guards (e.g. RoleGuard) in addition to the platform defaults.
946
960
  */
947
961
  declare function buildTenantSubscriptionBundlesController(extraGuards?: Array<Type<CanActivate>>): Type;
948
962
 
@@ -24,7 +24,7 @@ import {
24
24
  decideRenewal,
25
25
  loadPlanCatalogFromFile,
26
26
  loadPlanCatalogFromString
27
- } from "../chunk-BYINBUNY.js";
27
+ } from "../chunk-FVD4TGER.js";
28
28
  import {
29
29
  AddSubscriptionBundleDto,
30
30
  BILLING_FEATURE_UI_REGISTRY_TOKEN,
@@ -38,6 +38,7 @@ import {
38
38
  ComposedTenantAuthGuard,
39
39
  DEFAULT_BUNDLE_MINIMUM_TERM_MONTHS,
40
40
  FEATURE_GUARD_MARKER,
41
+ NO_NOTICE_PERIOD,
41
42
  PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN,
42
43
  PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN,
43
44
  PendingPlanMaterializationService,
@@ -78,9 +79,9 @@ import {
78
79
  resolveBundleCancelEffectiveAt,
79
80
  resolvePlanAnchorDay,
80
81
  retreatOneCycle
81
- } from "../chunk-NT4ZGXPA.js";
82
- import "../chunk-7JEXCHMU.js";
83
- import "../chunk-65ADCLHU.js";
82
+ } from "../chunk-W67WBRW5.js";
83
+ import "../chunk-6FQ3G4IF.js";
84
+ import "../chunk-F7P2X2DR.js";
84
85
  import {
85
86
  AUDIT_CONTEXT_RESOLVER_TOKEN,
86
87
  CANCELLATION_NOTICE_DAYS_TOKEN,
@@ -99,10 +100,12 @@ import {
99
100
  resolveBundlePriceNet
100
101
  } from "../chunk-X7CWHRSK.js";
101
102
  import "../chunk-O2J2HDXA.js";
103
+ import "../chunk-BSK6YBLI.js";
104
+ import "../chunk-YSC46BGM.js";
102
105
  import {
103
106
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
104
107
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN
105
- } from "../chunk-SO2NH2A6.js";
108
+ } from "../chunk-5LE5AZUP.js";
106
109
  import {
107
110
  PLAN_CATALOG_READ_SINK_TOKEN,
108
111
  PLAN_CATALOG_TOKEN,
@@ -117,15 +120,13 @@ import {
117
120
  getPlanQuota,
118
121
  isFeatureInPlan,
119
122
  isFeaturePlannedOnly
120
- } from "../chunk-UUFUSKX2.js";
123
+ } from "../chunk-H7SF4EUR.js";
121
124
  import "../chunk-VBRYPU7V.js";
122
125
  import "../chunk-57V6ZTI6.js";
123
126
  import "../chunk-OUDSQ3PU.js";
124
- import "../chunk-QUZU2M33.js";
125
- import "../chunk-BSK6YBLI.js";
126
- import "../chunk-YSC46BGM.js";
127
127
  import "../chunk-AOQJEYOL.js";
128
128
  import "../chunk-SABTXESR.js";
129
+ import "../chunk-QUZU2M33.js";
129
130
  import "../chunk-SHUYVCID.js";
130
131
  export {
131
132
  AUDIT_CONTEXT_RESOLVER_TOKEN,
@@ -147,6 +148,7 @@ export {
147
148
  FEATURE_GUARD_MARKER,
148
149
  FeatureGuard,
149
150
  LimitExceededFilter,
151
+ NO_NOTICE_PERIOD,
150
152
  PENDING_PLAN_QUERY_PORT_TOKEN,
151
153
  PLAN_CATALOG_IMPORT_SINK_TOKEN,
152
154
  PLAN_CATALOG_READ_SINK_TOKEN,
@@ -6,7 +6,7 @@ import {
6
6
  runSeedGateFromFile,
7
7
  seedGateExitCode,
8
8
  validateSeedAgainstSnapshot
9
- } from "../chunk-E74DRQJM.js";
9
+ } from "../chunk-GG5NHRH5.js";
10
10
  import "../chunk-74SCJ4HF.js";
11
11
  import {
12
12
  ADVISORY_STRICT_MODE_CODES,
@@ -57,13 +57,12 @@ import {
57
57
  resolveValidityWindow,
58
58
  validateBundleDraft,
59
59
  validatePlanDraft
60
- } from "../chunk-L33BM4EN.js";
60
+ } from "../chunk-DFQETRBL.js";
61
61
  import "../chunk-X7CWHRSK.js";
62
62
  import "../chunk-O2J2HDXA.js";
63
+ import "../chunk-YSC46BGM.js";
63
64
  import "../chunk-WXYJHZCN.js";
64
65
  import "../chunk-OUDSQ3PU.js";
65
- import "../chunk-QUZU2M33.js";
66
- import "../chunk-YSC46BGM.js";
67
66
  import {
68
67
  BUNDLE_REPOSITORY_TOKEN,
69
68
  CATALOG_ENTRY_REPOSITORY_TOKEN,
@@ -75,6 +74,7 @@ import {
75
74
  PROMOTION_REPOSITORY_TOKEN
76
75
  } from "../chunk-AOQJEYOL.js";
77
76
  import "../chunk-SABTXESR.js";
77
+ import "../chunk-QUZU2M33.js";
78
78
  import "../chunk-SHUYVCID.js";
79
79
  export {
80
80
  ADVISORY_STRICT_MODE_CODES,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PLAN_CATALOG_TOKEN,
3
3
  isFeaturePlannedOnly
4
- } from "./chunk-UUFUSKX2.js";
4
+ } from "./chunk-H7SF4EUR.js";
5
5
  import {
6
6
  SUBSCRIPTION_CONTRACT_REPOSITORY_TOKEN
7
7
  } from "./chunk-VBRYPU7V.js";
@@ -14,12 +14,12 @@ import {
14
14
  SUBSCRIPTION_REPOSITORY_TOKEN,
15
15
  TRANSACTION_RUNNER_TOKEN
16
16
  } from "./chunk-OUDSQ3PU.js";
17
- import {
18
- DISCOVERY_SNAPSHOT_TOKEN
19
- } from "./chunk-QUZU2M33.js";
20
17
  import {
21
18
  BUNDLE_REPOSITORY_TOKEN
22
19
  } from "./chunk-AOQJEYOL.js";
20
+ import {
21
+ DISCOVERY_SNAPSHOT_TOKEN
22
+ } from "./chunk-QUZU2M33.js";
23
23
  import {
24
24
  __name
25
25
  } from "./chunk-SHUYVCID.js";
@@ -3,7 +3,7 @@ import {
3
3
  computeIncludedVat,
4
4
  getPlanPriceGross,
5
5
  round2
6
- } from "./chunk-UUFUSKX2.js";
6
+ } from "./chunk-H7SF4EUR.js";
7
7
  import {
8
8
  __name
9
9
  } from "./chunk-SHUYVCID.js";