@saasicat/nest 0.12.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/_entries.cjs CHANGED
@@ -2015,6 +2015,53 @@ function aggregateContractLineItemEntitlements(lineItems, fallbackPlan = "UNKNOW
2015
2015
  };
2016
2016
  }
2017
2017
  __name(aggregateContractLineItemEntitlements, "aggregateContractLineItemEntitlements");
2018
+ function contractLimits(contract) {
2019
+ if (contract.entitlementSnapshot) {
2020
+ return {
2021
+ plan: contract.entitlementSnapshot.plan,
2022
+ quotas: {
2023
+ ...contract.entitlementSnapshot.quotas
2024
+ },
2025
+ features: new Set(contract.entitlementSnapshot.features)
2026
+ };
2027
+ }
2028
+ return aggregateContractLineItemEntitlements(contract.lineItems);
2029
+ }
2030
+ __name(contractLimits, "contractLimits");
2031
+ function contractBundleVersionIds(contract) {
2032
+ const ids = new Set(contract.originalBundleVersionIds);
2033
+ for (const item of contract.lineItems) {
2034
+ if (item.kind === "bundle" && item.sourceVersionId) {
2035
+ ids.add(item.sourceVersionId);
2036
+ }
2037
+ }
2038
+ return ids;
2039
+ }
2040
+ __name(contractBundleVersionIds, "contractBundleVersionIds");
2041
+ function mergeSubscriptionBundlesIntoLimits(limits, bundles, coveredBundleVersionIds, catalog, now) {
2042
+ const additional = filterActiveSubscriptionBundles(bundles, now).filter((b) => !coveredBundleVersionIds.has(b.bundleVersionId));
2043
+ if (additional.length === 0) return limits;
2044
+ const quotas = {
2045
+ ...limits.quotas
2046
+ };
2047
+ for (const [key, value] of Object.entries(aggregateSubscriptionBundleQuotas(additional))) {
2048
+ if (quotas[key] === -1 || value === -1) {
2049
+ quotas[key] = -1;
2050
+ } else {
2051
+ quotas[key] = (quotas[key] ?? 0) + value;
2052
+ }
2053
+ }
2054
+ const bundleFeatures = filterPlannedOnlyFeatures(new Set(collectSubscriptionBundleFeatures(additional)), catalog);
2055
+ return {
2056
+ plan: limits.plan,
2057
+ quotas,
2058
+ features: /* @__PURE__ */ new Set([
2059
+ ...limits.features,
2060
+ ...bundleFeatures
2061
+ ])
2062
+ };
2063
+ }
2064
+ __name(mergeSubscriptionBundlesIntoLimits, "mergeSubscriptionBundlesIntoLimits");
2018
2065
  function filterPlannedOnlyFeatures(features, catalog) {
2019
2066
  const out = /* @__PURE__ */ new Set();
2020
2067
  for (const f of features) {
@@ -2287,11 +2334,14 @@ var EntitlementService = class {
2287
2334
  * have a `SubscriptionRecord` (e.g. within a transaction).
2288
2335
  */
2289
2336
  async deriveLimits(sub, now, tx) {
2290
- const contractLimits = await this.deriveLimitsFromContract(sub.tenantId, now);
2291
- if (contractLimits) return this.withReplacedFeatureAliases(contractLimits);
2337
+ const contract = await this.findActiveContract(sub.tenantId, now, tx);
2338
+ if (contract) {
2339
+ const bundles = await this.loadSubscriptionBundleSnapshots(sub.id, now, tx);
2340
+ return this.withReplacedFeatureAliases(mergeSubscriptionBundlesIntoLimits(contractLimits(contract), bundles, contractBundleVersionIds(contract), this.catalog, now));
2341
+ }
2292
2342
  const effectivePlan = resolveEntitlementPlan(sub, this.resolutionConfig ?? {}, now);
2293
2343
  const planVersion = effectivePlan === sub.plan ? sub.planVersion : await this.findActivePlanVersionOrFallback(effectivePlan, now, tx);
2294
- const subscriptionBundles = await this.loadSubscriptionBundleSnapshots(sub.id, now);
2344
+ const subscriptionBundles = await this.loadSubscriptionBundleSnapshots(sub.id, now, tx);
2295
2345
  return this.withReplacedFeatureAliases(aggregateLimits({
2296
2346
  plan: effectivePlan,
2297
2347
  planVersion,
@@ -2315,20 +2365,9 @@ var EntitlementService = class {
2315
2365
  features: expandReplacedFeatures(limits.features, this.replacedByIndex)
2316
2366
  };
2317
2367
  }
2318
- async deriveLimitsFromContract(tenantId, now) {
2368
+ async findActiveContract(tenantId, now, tx) {
2319
2369
  if (!this.subscriptionContracts) return null;
2320
- const contract = await this.subscriptionContracts.findActiveByTenantId(tenantId, now);
2321
- if (!contract) return null;
2322
- if (contract.entitlementSnapshot) {
2323
- return {
2324
- plan: contract.entitlementSnapshot.plan,
2325
- quotas: {
2326
- ...contract.entitlementSnapshot.quotas
2327
- },
2328
- features: new Set(contract.entitlementSnapshot.features)
2329
- };
2330
- }
2331
- return aggregateContractLineItemEntitlements(contract.lineItems);
2370
+ return this.subscriptionContracts.findActiveByTenantId(tenantId, now, tx);
2332
2371
  }
2333
2372
  /**
2334
2373
  * Loads a subscription's active bundle bookings and resolves the
@@ -2337,17 +2376,18 @@ var EntitlementService = class {
2337
2376
  * returns an empty list — apps without a bundle schema stay unchanged
2338
2377
  * (plan-only aggregation).
2339
2378
  */
2340
- async loadSubscriptionBundleSnapshots(subscriptionId, now) {
2379
+ async loadSubscriptionBundleSnapshots(subscriptionId, now, tx) {
2341
2380
  if (!this.subscriptionBundles || !this.bundles) return [];
2342
- const active = await this.subscriptionBundles.listActiveBySubscription(subscriptionId, now);
2381
+ const active = await this.subscriptionBundles.listActiveBySubscription(subscriptionId, now, tx);
2343
2382
  if (active.length === 0) return [];
2344
2383
  return Promise.all(active.map(async (booking) => {
2345
- const bv = await this.bundles.findVersionById(booking.bundleVersionId);
2384
+ const bv = await this.bundles.findVersionById(booking.bundleVersionId, tx);
2346
2385
  if (!bv) {
2347
2386
  throw new Error(`BundleVersion '${booking.bundleVersionId}' aus aktiver SubscriptionBundle nicht gefunden`);
2348
2387
  }
2349
2388
  return {
2350
2389
  bundleKey: bv.bundleKey,
2390
+ bundleVersionId: booking.bundleVersionId,
2351
2391
  features: bv.features,
2352
2392
  quotas: bv.quotas,
2353
2393
  canceledEffectiveAt: booking.canceledEffectiveAt
@@ -3436,12 +3476,15 @@ __export(entitlement_exports, {
3436
3476
  applyCustomLimits: () => applyCustomLimits,
3437
3477
  buildReplacedByIndex: () => buildReplacedByIndex,
3438
3478
  collectSubscriptionBundleFeatures: () => collectSubscriptionBundleFeatures,
3479
+ contractBundleVersionIds: () => contractBundleVersionIds,
3480
+ contractLimits: () => contractLimits,
3439
3481
  expandReplacedFeatures: () => expandReplacedFeatures,
3440
3482
  filterActiveSubscriptionBundles: () => filterActiveSubscriptionBundles,
3441
3483
  filterPlannedOnlyFeatures: () => filterPlannedOnlyFeatures,
3442
3484
  hasAnyFeature: () => hasAnyFeature,
3443
3485
  hasFeature: () => hasFeature,
3444
3486
  isLimitExceededError: () => isLimitExceededError,
3487
+ mergeSubscriptionBundlesIntoLimits: () => mergeSubscriptionBundlesIntoLimits,
3445
3488
  resolveEntitlementPlan: () => resolveEntitlementPlan,
3446
3489
  toEffectiveLimitsSnapshot: () => toEffectiveLimitsSnapshot
3447
3490
  });
@@ -6235,7 +6278,7 @@ function _ts_param26(paramIndex, decorator) {
6235
6278
  }
6236
6279
  __name(_ts_param26, "_ts_param");
6237
6280
  function buildTenantSubscriptionBundlesController(extraGuards = []) {
6238
- let GeneratedTenantSubscriptionBundlesController = class GeneratedTenantSubscriptionBundlesController {
6281
+ let GeneratedTenantSubscriptionBundlesController = class GeneratedTenantSubscriptionBundlesController2 {
6239
6282
  static {
6240
6283
  __name(this, "GeneratedTenantSubscriptionBundlesController");
6241
6284
  }
@@ -6245,6 +6288,8 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
6245
6288
  tenantIdResolver;
6246
6289
  contractFreeze;
6247
6290
  logger = new import_common39.Logger("TenantSubscriptionBundlesController");
6291
+ /** Keeps the "no contractFreeze hook" warning to one line per process. */
6292
+ static warnedAboutMissingFreeze = false;
6248
6293
  constructor(service, previewService, subscriptionUsage, tenantIdResolver, contractFreeze = null) {
6249
6294
  this.service = service;
6250
6295
  this.previewService = previewService;
@@ -6336,7 +6381,13 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
6336
6381
  * only if the consumer has wired the ContractFreezePort.
6337
6382
  */
6338
6383
  async refreezeContract(tenantId, sub) {
6339
- if (!this.contractFreeze) return;
6384
+ if (!this.contractFreeze) {
6385
+ if (!GeneratedTenantSubscriptionBundlesController2.warnedAboutMissingFreeze) {
6386
+ GeneratedTenantSubscriptionBundlesController2.warnedAboutMissingFreeze = true;
6387
+ this.logger.warn("Bundle mutation without a configured contractFreeze hook \u2014 the SubscriptionContract is not re-materialized. Configure `contractFreeze` in TenantBillingModule.forRoot() if this app uses contracts.");
6388
+ }
6389
+ return;
6390
+ }
6340
6391
  try {
6341
6392
  await this.contractFreeze.freezeOnPlanChange(tenantId, sub.planVersion.planId, sub.billingCycle, /* @__PURE__ */ new Date());
6342
6393
  } catch (err) {
@@ -16624,6 +16675,8 @@ __export(src_exports, {
16624
16675
  computeProration: () => computeProration,
16625
16676
  computeRegularStartsAt: () => computeRegularStartsAt,
16626
16677
  computeSnapshotHash: () => computeSnapshotHash,
16678
+ contractBundleVersionIds: () => contractBundleVersionIds,
16679
+ contractLimits: () => contractLimits,
16627
16680
  contractLineItemToInvoiceLineItem: () => contractLineItemToInvoiceLineItem,
16628
16681
  decideRenewal: () => decideRenewal,
16629
16682
  expandReplacedFeatures: () => expandReplacedFeatures,
@@ -16654,6 +16707,7 @@ __export(src_exports, {
16654
16707
  loadDiscoverySnapshotFromFile: () => loadDiscoverySnapshotFromFile,
16655
16708
  loadPlanCatalogFromFile: () => loadPlanCatalogFromFile,
16656
16709
  loadPlanCatalogFromString: () => loadPlanCatalogFromString,
16710
+ mergeSubscriptionBundlesIntoLimits: () => mergeSubscriptionBundlesIntoLimits,
16657
16711
  periodEndAfter: () => periodEndAfter,
16658
16712
  periodEndWithMinLead: () => periodEndWithMinLead,
16659
16713
  preflightExitCode: () => preflightExitCode,
@@ -1,4 +1,4 @@
1
- import { PlanId, QuotaKey, FeatureKey, PlanCatalog, SubscriptionRepository, PlanVersionRepository, TransactionRunner, SubscriptionBundleRepository, BundleRepository, SubscriptionContractRepository, DiscoverySnapshot, SubscriptionRecord, TransactionContext, ContractLineItemRecord } from '@saasicat/types';
1
+ import { PlanId, QuotaKey, FeatureKey, PlanCatalog, SubscriptionRepository, PlanVersionRepository, TransactionRunner, SubscriptionBundleRepository, BundleRepository, SubscriptionContractRepository, DiscoverySnapshot, SubscriptionRecord, TransactionContext, ContractLineItemRecord, SubscriptionContractRecord } from '@saasicat/types';
2
2
  import { E as EntitlementResolutionConfig } from './plan-resolution-CFCoUkrE.cjs';
3
3
 
4
4
  /**
@@ -27,6 +27,12 @@ interface PlanVersionSnapshot {
27
27
  */
28
28
  interface SubscriptionBundleSnapshot {
29
29
  bundleKey: string;
30
+ /**
31
+ * Booked `BundleVersion`. Lets the contract path tell bundles that are
32
+ * already part of a frozen contract from ones booked afterwards, so their
33
+ * quotas are not counted twice.
34
+ */
35
+ bundleVersionId: string;
30
36
  features: FeatureKey[];
31
37
  quotas: Record<QuotaKey, number>;
32
38
  /**
@@ -140,7 +146,7 @@ declare class EntitlementService {
140
146
  * A no-op without a snapshot or without replaces declarations.
141
147
  */
142
148
  private withReplacedFeatureAliases;
143
- private deriveLimitsFromContract;
149
+ private findActiveContract;
144
150
  /**
145
151
  * Loads a subscription's active bundle bookings and resolves the
146
152
  * `BundleVersion` features/quotas per entry. Without a registered
@@ -186,6 +192,32 @@ declare function collectSubscriptionBundleFeatures(bundles: readonly Subscriptio
186
192
  * `quotaEffectsSnapshot` are the contractual truth.
187
193
  */
188
194
  declare function aggregateContractLineItemEntitlements(lineItems: readonly Pick<ContractLineItemRecord, 'kind' | 'sourceKey' | 'featuresSnapshot' | 'quotaEffectsSnapshot'>[], fallbackPlan?: string): EffectiveLimits;
195
+ /**
196
+ * Limits as frozen in the contract: the entitlement snapshot when present,
197
+ * otherwise aggregated from the line items.
198
+ */
199
+ declare function contractLimits(contract: Pick<SubscriptionContractRecord, 'entitlementSnapshot' | 'lineItems'>): EffectiveLimits;
200
+ /**
201
+ * `BundleVersion`s the contract already accounts for — from the freeze
202
+ * (`originalBundleVersionIds`) and from its bundle line items.
203
+ */
204
+ declare function contractBundleVersionIds(contract: Pick<SubscriptionContractRecord, 'originalBundleVersionIds' | 'lineItems'>): Set<string>;
205
+ /**
206
+ * Adds bundle bookings on top of limits that came from a contract.
207
+ *
208
+ * A contract freezes what was agreed at signing time. Bundles booked *later*
209
+ * are separate purchases and must take effect immediately — otherwise the
210
+ * purchase stays without consequence until someone re-freezes the contract.
211
+ * Bundles that are already part of the contract (`coveredBundleVersionIds`,
212
+ * i.e. `originalBundleVersionIds` plus the bundle line items) are skipped, so
213
+ * their quotas are not counted twice.
214
+ *
215
+ * Features are a set union, quotas add up with `-1` (unlimited) dominance, and
216
+ * `plannedOnly` features stay out — same rules as `aggregateLimits`. The
217
+ * contract's own features are passed through untouched: what was agreed stays
218
+ * agreed.
219
+ */
220
+ declare function mergeSubscriptionBundlesIntoLimits(limits: EffectiveLimits, bundles: readonly SubscriptionBundleSnapshot[], coveredBundleVersionIds: ReadonlySet<string>, catalog: PlanCatalog, now: Date): EffectiveLimits;
189
221
  /**
190
222
  * Consistently filters out `plannedOnly` features — regardless of whether they
191
223
  * come from the plan, a bundle or customLimits. `plannedOnly` means: the feature
@@ -225,4 +257,4 @@ declare function hasAnyFeature(limits: EffectiveLimits, features: readonly Featu
225
257
  */
226
258
  declare function toEffectiveLimitsSnapshot(limits: EffectiveLimits): EffectiveLimitsSnapshot;
227
259
 
228
- export { type CustomLimitsShape as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type EffectiveLimitsSnapshot as a, type EnforceLimitInput as b, EntitlementService as c, type SubscriptionLimitsInput as d, aggregateContractLineItemEntitlements as e, aggregateLimits as f, aggregateSubscriptionBundleQuotas as g, applyCustomLimits as h, collectSubscriptionBundleFeatures as i, filterActiveSubscriptionBundles as j, filterPlannedOnlyFeatures as k, hasAnyFeature as l, hasFeature as m, toEffectiveLimitsSnapshot as t };
260
+ export { type CustomLimitsShape as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type EffectiveLimitsSnapshot as a, type EnforceLimitInput as b, EntitlementService as c, type SubscriptionLimitsInput as d, aggregateContractLineItemEntitlements as e, aggregateLimits as f, aggregateSubscriptionBundleQuotas as g, applyCustomLimits as h, collectSubscriptionBundleFeatures as i, contractBundleVersionIds as j, contractLimits as k, filterActiveSubscriptionBundles as l, filterPlannedOnlyFeatures as m, hasAnyFeature as n, hasFeature as o, mergeSubscriptionBundlesIntoLimits as p, toEffectiveLimitsSnapshot as t };
@@ -1,4 +1,4 @@
1
- import { PlanId, QuotaKey, FeatureKey, PlanCatalog, SubscriptionRepository, PlanVersionRepository, TransactionRunner, SubscriptionBundleRepository, BundleRepository, SubscriptionContractRepository, DiscoverySnapshot, SubscriptionRecord, TransactionContext, ContractLineItemRecord } from '@saasicat/types';
1
+ import { PlanId, QuotaKey, FeatureKey, PlanCatalog, SubscriptionRepository, PlanVersionRepository, TransactionRunner, SubscriptionBundleRepository, BundleRepository, SubscriptionContractRepository, DiscoverySnapshot, SubscriptionRecord, TransactionContext, ContractLineItemRecord, SubscriptionContractRecord } from '@saasicat/types';
2
2
  import { E as EntitlementResolutionConfig } from './plan-resolution-CFCoUkrE.js';
3
3
 
4
4
  /**
@@ -27,6 +27,12 @@ interface PlanVersionSnapshot {
27
27
  */
28
28
  interface SubscriptionBundleSnapshot {
29
29
  bundleKey: string;
30
+ /**
31
+ * Booked `BundleVersion`. Lets the contract path tell bundles that are
32
+ * already part of a frozen contract from ones booked afterwards, so their
33
+ * quotas are not counted twice.
34
+ */
35
+ bundleVersionId: string;
30
36
  features: FeatureKey[];
31
37
  quotas: Record<QuotaKey, number>;
32
38
  /**
@@ -140,7 +146,7 @@ declare class EntitlementService {
140
146
  * A no-op without a snapshot or without replaces declarations.
141
147
  */
142
148
  private withReplacedFeatureAliases;
143
- private deriveLimitsFromContract;
149
+ private findActiveContract;
144
150
  /**
145
151
  * Loads a subscription's active bundle bookings and resolves the
146
152
  * `BundleVersion` features/quotas per entry. Without a registered
@@ -186,6 +192,32 @@ declare function collectSubscriptionBundleFeatures(bundles: readonly Subscriptio
186
192
  * `quotaEffectsSnapshot` are the contractual truth.
187
193
  */
188
194
  declare function aggregateContractLineItemEntitlements(lineItems: readonly Pick<ContractLineItemRecord, 'kind' | 'sourceKey' | 'featuresSnapshot' | 'quotaEffectsSnapshot'>[], fallbackPlan?: string): EffectiveLimits;
195
+ /**
196
+ * Limits as frozen in the contract: the entitlement snapshot when present,
197
+ * otherwise aggregated from the line items.
198
+ */
199
+ declare function contractLimits(contract: Pick<SubscriptionContractRecord, 'entitlementSnapshot' | 'lineItems'>): EffectiveLimits;
200
+ /**
201
+ * `BundleVersion`s the contract already accounts for — from the freeze
202
+ * (`originalBundleVersionIds`) and from its bundle line items.
203
+ */
204
+ declare function contractBundleVersionIds(contract: Pick<SubscriptionContractRecord, 'originalBundleVersionIds' | 'lineItems'>): Set<string>;
205
+ /**
206
+ * Adds bundle bookings on top of limits that came from a contract.
207
+ *
208
+ * A contract freezes what was agreed at signing time. Bundles booked *later*
209
+ * are separate purchases and must take effect immediately — otherwise the
210
+ * purchase stays without consequence until someone re-freezes the contract.
211
+ * Bundles that are already part of the contract (`coveredBundleVersionIds`,
212
+ * i.e. `originalBundleVersionIds` plus the bundle line items) are skipped, so
213
+ * their quotas are not counted twice.
214
+ *
215
+ * Features are a set union, quotas add up with `-1` (unlimited) dominance, and
216
+ * `plannedOnly` features stay out — same rules as `aggregateLimits`. The
217
+ * contract's own features are passed through untouched: what was agreed stays
218
+ * agreed.
219
+ */
220
+ declare function mergeSubscriptionBundlesIntoLimits(limits: EffectiveLimits, bundles: readonly SubscriptionBundleSnapshot[], coveredBundleVersionIds: ReadonlySet<string>, catalog: PlanCatalog, now: Date): EffectiveLimits;
189
221
  /**
190
222
  * Consistently filters out `plannedOnly` features — regardless of whether they
191
223
  * come from the plan, a bundle or customLimits. `plannedOnly` means: the feature
@@ -225,4 +257,4 @@ declare function hasAnyFeature(limits: EffectiveLimits, features: readonly Featu
225
257
  */
226
258
  declare function toEffectiveLimitsSnapshot(limits: EffectiveLimits): EffectiveLimitsSnapshot;
227
259
 
228
- export { type CustomLimitsShape as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type EffectiveLimitsSnapshot as a, type EnforceLimitInput as b, EntitlementService as c, type SubscriptionLimitsInput as d, aggregateContractLineItemEntitlements as e, aggregateLimits as f, aggregateSubscriptionBundleQuotas as g, applyCustomLimits as h, collectSubscriptionBundleFeatures as i, filterActiveSubscriptionBundles as j, filterPlannedOnlyFeatures as k, hasAnyFeature as l, hasFeature as m, toEffectiveLimitsSnapshot as t };
260
+ export { type CustomLimitsShape as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type EffectiveLimitsSnapshot as a, type EnforceLimitInput as b, EntitlementService as c, type SubscriptionLimitsInput as d, aggregateContractLineItemEntitlements as e, aggregateLimits as f, aggregateSubscriptionBundleQuotas as g, applyCustomLimits as h, collectSubscriptionBundleFeatures as i, contractBundleVersionIds as j, contractLimits as k, filterActiveSubscriptionBundles as l, filterPlannedOnlyFeatures as m, hasAnyFeature as n, hasFeature as o, mergeSubscriptionBundlesIntoLimits as p, toEffectiveLimitsSnapshot as t };
@@ -4,11 +4,11 @@ import * as _nestjs_common from '@nestjs/common';
4
4
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
5
5
  export { Type as NestType } from '@nestjs/common';
6
6
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
7
- import { c as EntitlementService } from '../aggregation-CfI0bOsQ.cjs';
7
+ import { c as EntitlementService } from '../aggregation-SKfXu09x.cjs';
8
8
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
9
9
  import { f as ContractFreezePort, g as ContractFreezeSourcePort } from '../subscription-bundles.module-DCpV-Pb5.cjs';
10
10
  export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, 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 SelfServiceBlockedPlans, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, u as TenantIdResolver, v as TrialProjectionInput, w as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN, z as UserEmailResolver, B as UserIdResolver } from '../subscription-bundles.module-DCpV-Pb5.cjs';
11
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../subscription-bundle-preview.service-BkJXHAeP.cjs';
11
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../subscription-bundle-preview.service-B4Ye8L2F.cjs';
12
12
  import { S as SubscriptionContractService } from '../subscription-contract.service--cm47ZJJ.cjs';
13
13
  import '../plan-resolution-CFCoUkrE.cjs';
14
14
  import '../service-DX8KbGXl.cjs';
@@ -4,11 +4,11 @@ import * as _nestjs_common from '@nestjs/common';
4
4
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
5
5
  export { Type as NestType } from '@nestjs/common';
6
6
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
7
- import { c as EntitlementService } from '../aggregation-BibpEO0t.js';
7
+ import { c as EntitlementService } from '../aggregation-o0LMenvl.js';
8
8
  import { P as ProviderSpec } from '../di-CcNeq9v-.js';
9
9
  import { f as ContractFreezePort, g as ContractFreezeSourcePort } from '../subscription-bundles.module-BQmoozm5.js';
10
10
  export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, 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 SelfServiceBlockedPlans, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, u as TenantIdResolver, v as TrialProjectionInput, w as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN, z as UserEmailResolver, B as UserIdResolver } from '../subscription-bundles.module-BQmoozm5.js';
11
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../subscription-bundle-preview.service-DBbrE_cw.js';
11
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../subscription-bundle-preview.service-BgQ776mv.js';
12
12
  import { S as SubscriptionContractService } from '../subscription-contract.service--cm47ZJJ.js';
13
13
  import '../plan-resolution-CFCoUkrE.js';
14
14
  import '../service-DX8KbGXl.js';
@@ -58,7 +58,7 @@ import {
58
58
  periodEndWithMinLead,
59
59
  resolveBundleCancelEffectiveAt,
60
60
  resolveBundlePriceNet
61
- } from "../chunk-F3VV6EXG.js";
61
+ } from "../chunk-RKVY775D.js";
62
62
  import "../chunk-E7AJ42AB.js";
63
63
  import "../chunk-2PNX2QL2.js";
64
64
  import {
@@ -80,7 +80,7 @@ import "../chunk-MDIZUVIK.js";
80
80
  import {
81
81
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
82
82
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN
83
- } from "../chunk-GBDUH6DO.js";
83
+ } from "../chunk-EXOLOJFZ.js";
84
84
  import {
85
85
  PLAN_CATALOG_READ_SINK_TOKEN,
86
86
  PLAN_CATALOG_TOKEN,
@@ -76,6 +76,53 @@ function aggregateContractLineItemEntitlements(lineItems, fallbackPlan = "UNKNOW
76
76
  };
77
77
  }
78
78
  __name(aggregateContractLineItemEntitlements, "aggregateContractLineItemEntitlements");
79
+ function contractLimits(contract) {
80
+ if (contract.entitlementSnapshot) {
81
+ return {
82
+ plan: contract.entitlementSnapshot.plan,
83
+ quotas: {
84
+ ...contract.entitlementSnapshot.quotas
85
+ },
86
+ features: new Set(contract.entitlementSnapshot.features)
87
+ };
88
+ }
89
+ return aggregateContractLineItemEntitlements(contract.lineItems);
90
+ }
91
+ __name(contractLimits, "contractLimits");
92
+ function contractBundleVersionIds(contract) {
93
+ const ids = new Set(contract.originalBundleVersionIds);
94
+ for (const item of contract.lineItems) {
95
+ if (item.kind === "bundle" && item.sourceVersionId) {
96
+ ids.add(item.sourceVersionId);
97
+ }
98
+ }
99
+ return ids;
100
+ }
101
+ __name(contractBundleVersionIds, "contractBundleVersionIds");
102
+ function mergeSubscriptionBundlesIntoLimits(limits, bundles, coveredBundleVersionIds, catalog, now) {
103
+ const additional = filterActiveSubscriptionBundles(bundles, now).filter((b) => !coveredBundleVersionIds.has(b.bundleVersionId));
104
+ if (additional.length === 0) return limits;
105
+ const quotas = {
106
+ ...limits.quotas
107
+ };
108
+ for (const [key, value] of Object.entries(aggregateSubscriptionBundleQuotas(additional))) {
109
+ if (quotas[key] === -1 || value === -1) {
110
+ quotas[key] = -1;
111
+ } else {
112
+ quotas[key] = (quotas[key] ?? 0) + value;
113
+ }
114
+ }
115
+ const bundleFeatures = filterPlannedOnlyFeatures(new Set(collectSubscriptionBundleFeatures(additional)), catalog);
116
+ return {
117
+ plan: limits.plan,
118
+ quotas,
119
+ features: /* @__PURE__ */ new Set([
120
+ ...limits.features,
121
+ ...bundleFeatures
122
+ ])
123
+ };
124
+ }
125
+ __name(mergeSubscriptionBundlesIntoLimits, "mergeSubscriptionBundlesIntoLimits");
79
126
  function filterPlannedOnlyFeatures(features, catalog) {
80
127
  const out = /* @__PURE__ */ new Set();
81
128
  for (const f of features) {
@@ -348,11 +395,14 @@ var EntitlementService = class {
348
395
  * have a `SubscriptionRecord` (e.g. within a transaction).
349
396
  */
350
397
  async deriveLimits(sub, now, tx) {
351
- const contractLimits = await this.deriveLimitsFromContract(sub.tenantId, now);
352
- if (contractLimits) return this.withReplacedFeatureAliases(contractLimits);
398
+ const contract = await this.findActiveContract(sub.tenantId, now, tx);
399
+ if (contract) {
400
+ const bundles = await this.loadSubscriptionBundleSnapshots(sub.id, now, tx);
401
+ return this.withReplacedFeatureAliases(mergeSubscriptionBundlesIntoLimits(contractLimits(contract), bundles, contractBundleVersionIds(contract), this.catalog, now));
402
+ }
353
403
  const effectivePlan = resolveEntitlementPlan(sub, this.resolutionConfig ?? {}, now);
354
404
  const planVersion = effectivePlan === sub.plan ? sub.planVersion : await this.findActivePlanVersionOrFallback(effectivePlan, now, tx);
355
- const subscriptionBundles = await this.loadSubscriptionBundleSnapshots(sub.id, now);
405
+ const subscriptionBundles = await this.loadSubscriptionBundleSnapshots(sub.id, now, tx);
356
406
  return this.withReplacedFeatureAliases(aggregateLimits({
357
407
  plan: effectivePlan,
358
408
  planVersion,
@@ -376,20 +426,9 @@ var EntitlementService = class {
376
426
  features: expandReplacedFeatures(limits.features, this.replacedByIndex)
377
427
  };
378
428
  }
379
- async deriveLimitsFromContract(tenantId, now) {
429
+ async findActiveContract(tenantId, now, tx) {
380
430
  if (!this.subscriptionContracts) return null;
381
- const contract = await this.subscriptionContracts.findActiveByTenantId(tenantId, now);
382
- if (!contract) return null;
383
- if (contract.entitlementSnapshot) {
384
- return {
385
- plan: contract.entitlementSnapshot.plan,
386
- quotas: {
387
- ...contract.entitlementSnapshot.quotas
388
- },
389
- features: new Set(contract.entitlementSnapshot.features)
390
- };
391
- }
392
- return aggregateContractLineItemEntitlements(contract.lineItems);
431
+ return this.subscriptionContracts.findActiveByTenantId(tenantId, now, tx);
393
432
  }
394
433
  /**
395
434
  * Loads a subscription's active bundle bookings and resolves the
@@ -398,17 +437,18 @@ var EntitlementService = class {
398
437
  * returns an empty list — apps without a bundle schema stay unchanged
399
438
  * (plan-only aggregation).
400
439
  */
401
- async loadSubscriptionBundleSnapshots(subscriptionId, now) {
440
+ async loadSubscriptionBundleSnapshots(subscriptionId, now, tx) {
402
441
  if (!this.subscriptionBundles || !this.bundles) return [];
403
- const active = await this.subscriptionBundles.listActiveBySubscription(subscriptionId, now);
442
+ const active = await this.subscriptionBundles.listActiveBySubscription(subscriptionId, now, tx);
404
443
  if (active.length === 0) return [];
405
444
  return Promise.all(active.map(async (booking) => {
406
- const bv = await this.bundles.findVersionById(booking.bundleVersionId);
445
+ const bv = await this.bundles.findVersionById(booking.bundleVersionId, tx);
407
446
  if (!bv) {
408
447
  throw new Error(`BundleVersion '${booking.bundleVersionId}' aus aktiver SubscriptionBundle nicht gefunden`);
409
448
  }
410
449
  return {
411
450
  bundleKey: bv.bundleKey,
451
+ bundleVersionId: booking.bundleVersionId,
412
452
  features: bv.features,
413
453
  quotas: bv.quotas,
414
454
  canceledEffectiveAt: booking.canceledEffectiveAt
@@ -575,6 +615,9 @@ export {
575
615
  aggregateSubscriptionBundleQuotas,
576
616
  collectSubscriptionBundleFeatures,
577
617
  aggregateContractLineItemEntitlements,
618
+ contractLimits,
619
+ contractBundleVersionIds,
620
+ mergeSubscriptionBundlesIntoLimits,
578
621
  filterPlannedOnlyFeatures,
579
622
  applyCustomLimits,
580
623
  aggregateLimits,
@@ -13,7 +13,7 @@ import {
13
13
  REQUIRE_FEATURE_KEY,
14
14
  SubscriptionBundleModule,
15
15
  TenantBillingModule
16
- } from "./chunk-F3VV6EXG.js";
16
+ } from "./chunk-RKVY775D.js";
17
17
  import {
18
18
  CatalogModule
19
19
  } from "./chunk-33TP26MR.js";
@@ -23,7 +23,7 @@ import {
23
23
  import {
24
24
  EntitlementModule,
25
25
  LimitExceededError
26
- } from "./chunk-GBDUH6DO.js";
26
+ } from "./chunk-EXOLOJFZ.js";
27
27
  import {
28
28
  PLAN_CATALOG_TOKEN,
29
29
  PlanCatalogModule
@@ -25,7 +25,7 @@ import {
25
25
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN,
26
26
  isLimitExceededError,
27
27
  toEffectiveLimitsSnapshot
28
- } from "./chunk-GBDUH6DO.js";
28
+ } from "./chunk-EXOLOJFZ.js";
29
29
  import {
30
30
  PLAN_CATALOG_TOKEN,
31
31
  findPlan,
@@ -3005,7 +3005,7 @@ function _ts_param13(paramIndex, decorator) {
3005
3005
  }
3006
3006
  __name(_ts_param13, "_ts_param");
3007
3007
  function buildTenantSubscriptionBundlesController(extraGuards = []) {
3008
- let GeneratedTenantSubscriptionBundlesController = class GeneratedTenantSubscriptionBundlesController {
3008
+ let GeneratedTenantSubscriptionBundlesController = class GeneratedTenantSubscriptionBundlesController2 {
3009
3009
  static {
3010
3010
  __name(this, "GeneratedTenantSubscriptionBundlesController");
3011
3011
  }
@@ -3015,6 +3015,8 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3015
3015
  tenantIdResolver;
3016
3016
  contractFreeze;
3017
3017
  logger = new Logger5("TenantSubscriptionBundlesController");
3018
+ /** Keeps the "no contractFreeze hook" warning to one line per process. */
3019
+ static warnedAboutMissingFreeze = false;
3018
3020
  constructor(service, previewService, subscriptionUsage, tenantIdResolver, contractFreeze = null) {
3019
3021
  this.service = service;
3020
3022
  this.previewService = previewService;
@@ -3106,7 +3108,13 @@ function buildTenantSubscriptionBundlesController(extraGuards = []) {
3106
3108
  * only if the consumer has wired the ContractFreezePort.
3107
3109
  */
3108
3110
  async refreezeContract(tenantId, sub) {
3109
- if (!this.contractFreeze) return;
3111
+ if (!this.contractFreeze) {
3112
+ if (!GeneratedTenantSubscriptionBundlesController2.warnedAboutMissingFreeze) {
3113
+ GeneratedTenantSubscriptionBundlesController2.warnedAboutMissingFreeze = true;
3114
+ this.logger.warn("Bundle mutation without a configured contractFreeze hook \u2014 the SubscriptionContract is not re-materialized. Configure `contractFreeze` in TenantBillingModule.forRoot() if this app uses contracts.");
3115
+ }
3116
+ return;
3117
+ }
3110
3118
  try {
3111
3119
  await this.contractFreeze.freezeOnPlanChange(tenantId, sub.planVersion.planId, sub.billingCycle, /* @__PURE__ */ new Date());
3112
3120
  } catch (err) {
@@ -1,4 +1,4 @@
1
- export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as filterActiveSubscriptionBundles, k as filterPlannedOnlyFeatures, l as hasAnyFeature, m as hasFeature, t as toEffectiveLimitsSnapshot } from '../aggregation-CfI0bOsQ.cjs';
1
+ export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as contractBundleVersionIds, k as contractLimits, l as filterActiveSubscriptionBundles, m as filterPlannedOnlyFeatures, n as hasAnyFeature, o as hasFeature, p as mergeSubscriptionBundlesIntoLimits, t as toEffectiveLimitsSnapshot } from '../aggregation-SKfXu09x.cjs';
2
2
  import { DiscoveredFeature, SubscriptionRepository, PlanVersionRepository, TransactionRunner, SubscriptionContractRepository, SubscriptionBundleRepository, BundleRepository } from '@saasicat/types';
3
3
  import { E as EntitlementResolutionConfig } from '../plan-resolution-CFCoUkrE.cjs';
4
4
  export { a as EntitlementResolutionInput, r as resolveEntitlementPlan } from '../plan-resolution-CFCoUkrE.cjs';
@@ -1,4 +1,4 @@
1
- export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as filterActiveSubscriptionBundles, k as filterPlannedOnlyFeatures, l as hasAnyFeature, m as hasFeature, t as toEffectiveLimitsSnapshot } from '../aggregation-BibpEO0t.js';
1
+ export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as contractBundleVersionIds, k as contractLimits, l as filterActiveSubscriptionBundles, m as filterPlannedOnlyFeatures, n as hasAnyFeature, o as hasFeature, p as mergeSubscriptionBundlesIntoLimits, t as toEffectiveLimitsSnapshot } from '../aggregation-o0LMenvl.js';
2
2
  import { DiscoveredFeature, SubscriptionRepository, PlanVersionRepository, TransactionRunner, SubscriptionContractRepository, SubscriptionBundleRepository, BundleRepository } from '@saasicat/types';
3
3
  import { E as EntitlementResolutionConfig } from '../plan-resolution-CFCoUkrE.js';
4
4
  export { a as EntitlementResolutionInput, r as resolveEntitlementPlan } from '../plan-resolution-CFCoUkrE.js';
@@ -8,15 +8,18 @@ import {
8
8
  applyCustomLimits,
9
9
  buildReplacedByIndex,
10
10
  collectSubscriptionBundleFeatures,
11
+ contractBundleVersionIds,
12
+ contractLimits,
11
13
  expandReplacedFeatures,
12
14
  filterActiveSubscriptionBundles,
13
15
  filterPlannedOnlyFeatures,
14
16
  hasAnyFeature,
15
17
  hasFeature,
16
18
  isLimitExceededError,
19
+ mergeSubscriptionBundlesIntoLimits,
17
20
  resolveEntitlementPlan,
18
21
  toEffectiveLimitsSnapshot
19
- } from "../chunk-GBDUH6DO.js";
22
+ } from "../chunk-EXOLOJFZ.js";
20
23
  import "../chunk-R2QOSVAA.js";
21
24
  import "../chunk-NYLON2VC.js";
22
25
  import {
@@ -45,12 +48,15 @@ export {
45
48
  applyCustomLimits,
46
49
  buildReplacedByIndex,
47
50
  collectSubscriptionBundleFeatures,
51
+ contractBundleVersionIds,
52
+ contractLimits,
48
53
  expandReplacedFeatures,
49
54
  filterActiveSubscriptionBundles,
50
55
  filterPlannedOnlyFeatures,
51
56
  hasAnyFeature,
52
57
  hasFeature,
53
58
  isLimitExceededError,
59
+ mergeSubscriptionBundlesIntoLimits,
54
60
  resolveEntitlementPlan,
55
61
  toEffectiveLimitsSnapshot
56
62
  };
package/dist/index.d.cts CHANGED
@@ -7,8 +7,8 @@ export { AjvErrorLike, CatalogBundleUpsellResolver, ConfiguratorCatalogBuilder,
7
7
  import { SetupStatusResponse, SetupResult, SetupConfirmMfaResponse } from '@saasicat/types';
8
8
  export { BundleVersionFields, ChangeDirection, DiffResult, DiscoveredCapability, DiscoveredFeature, DiscoveredQuota, DiscoverySnapshot, PasswordHasher, PlanVersionFields, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/types';
9
9
  export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, f as ContractFreezePort, g as ContractFreezeSourcePort, D as DuePendingPlanChange, 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 SelfServiceBlockedPlans, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, u as TenantIdResolver, v as TrialProjectionInput, w as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN, z as UserEmailResolver, B as UserIdResolver } from './subscription-bundles.module-DCpV-Pb5.cjs';
10
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from './subscription-bundle-preview.service-BkJXHAeP.cjs';
11
- export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as filterActiveSubscriptionBundles, k as filterPlannedOnlyFeatures, l as hasAnyFeature, m as hasFeature, t as toEffectiveLimitsSnapshot } from './aggregation-CfI0bOsQ.cjs';
10
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from './subscription-bundle-preview.service-B4Ye8L2F.cjs';
11
+ export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as contractBundleVersionIds, k as contractLimits, l as filterActiveSubscriptionBundles, m as filterPlannedOnlyFeatures, n as hasAnyFeature, o as hasFeature, p as mergeSubscriptionBundlesIntoLimits, t as toEffectiveLimitsSnapshot } from './aggregation-SKfXu09x.cjs';
12
12
  export { ENTITLEMENT_RESOLUTION_CONFIG_TOKEN, ENTITLEMENT_SERVICE_TOKEN, EntitlementModule, EntitlementModuleOptions, LimitExceededError, PLAN_VERSION_REPOSITORY_TOKEN, ReplacedByIndex, SUBSCRIPTION_REPOSITORY_TOKEN, TRANSACTION_RUNNER_TOKEN, buildReplacedByIndex, expandReplacedFeatures, isLimitExceededError } from './entitlement/index.cjs';
13
13
  export { E as EntitlementResolutionConfig, a as EntitlementResolutionInput, r as resolveEntitlementPlan } from './plan-resolution-CFCoUkrE.cjs';
14
14
  export { ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN, AUDIT_PORT_TOKEN, AUDIT_STATS_PORT_TOKEN, AdminPublicBootController, AdminStatsController, MFA_PORT_TOKEN, PLATFORM_CORE_MANIFEST_CONTRIBUTION, PROMO_CODE_STATS_PORT_TOKEN, RLS_BYPASS_PORT_TOKEN, SUBSCRIPTION_STATS_PORT_TOKEN } from './admin/index.cjs';
package/dist/index.d.ts CHANGED
@@ -7,8 +7,8 @@ export { AjvErrorLike, CatalogBundleUpsellResolver, ConfiguratorCatalogBuilder,
7
7
  import { SetupStatusResponse, SetupResult, SetupConfirmMfaResponse } from '@saasicat/types';
8
8
  export { BundleVersionFields, ChangeDirection, DiffResult, DiscoveredCapability, DiscoveredFeature, DiscoveredQuota, DiscoverySnapshot, PasswordHasher, PlanVersionFields, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/types';
9
9
  export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, f as ContractFreezePort, g as ContractFreezeSourcePort, D as DuePendingPlanChange, 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 SelfServiceBlockedPlans, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, u as TenantIdResolver, v as TrialProjectionInput, w as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN, z as UserEmailResolver, B as UserIdResolver } from './subscription-bundles.module-BQmoozm5.js';
10
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from './subscription-bundle-preview.service-DBbrE_cw.js';
11
- export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as filterActiveSubscriptionBundles, k as filterPlannedOnlyFeatures, l as hasAnyFeature, m as hasFeature, t as toEffectiveLimitsSnapshot } from './aggregation-BibpEO0t.js';
10
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from './subscription-bundle-preview.service-BgQ776mv.js';
11
+ export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as contractBundleVersionIds, k as contractLimits, l as filterActiveSubscriptionBundles, m as filterPlannedOnlyFeatures, n as hasAnyFeature, o as hasFeature, p as mergeSubscriptionBundlesIntoLimits, t as toEffectiveLimitsSnapshot } from './aggregation-o0LMenvl.js';
12
12
  export { ENTITLEMENT_RESOLUTION_CONFIG_TOKEN, ENTITLEMENT_SERVICE_TOKEN, EntitlementModule, EntitlementModuleOptions, LimitExceededError, PLAN_VERSION_REPOSITORY_TOKEN, ReplacedByIndex, SUBSCRIPTION_REPOSITORY_TOKEN, TRANSACTION_RUNNER_TOKEN, buildReplacedByIndex, expandReplacedFeatures, isLimitExceededError } from './entitlement/index.js';
13
13
  export { E as EntitlementResolutionConfig, a as EntitlementResolutionInput, r as resolveEntitlementPlan } from './plan-resolution-CFCoUkrE.js';
14
14
  export { ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN, AUDIT_PORT_TOKEN, AUDIT_STATS_PORT_TOKEN, AdminPublicBootController, AdminStatsController, MFA_PORT_TOKEN, PLATFORM_CORE_MANIFEST_CONTRIBUTION, PROMO_CODE_STATS_PORT_TOKEN, RLS_BYPASS_PORT_TOKEN, SUBSCRIPTION_STATS_PORT_TOKEN } from './admin/index.js';
package/dist/index.js CHANGED
@@ -167,7 +167,7 @@ import {
167
167
  periodEndWithMinLead,
168
168
  resolveBundleCancelEffectiveAt,
169
169
  resolveBundlePriceNet
170
- } from "./chunk-F3VV6EXG.js";
170
+ } from "./chunk-RKVY775D.js";
171
171
  import {
172
172
  PROMO_CODE_REDEMPTION_REPOSITORY_TOKEN,
173
173
  PROMO_CODE_REPOSITORY_TOKEN,
@@ -291,15 +291,18 @@ import {
291
291
  applyCustomLimits,
292
292
  buildReplacedByIndex,
293
293
  collectSubscriptionBundleFeatures,
294
+ contractBundleVersionIds,
295
+ contractLimits,
294
296
  expandReplacedFeatures,
295
297
  filterActiveSubscriptionBundles,
296
298
  filterPlannedOnlyFeatures,
297
299
  hasAnyFeature,
298
300
  hasFeature,
299
301
  isLimitExceededError,
302
+ mergeSubscriptionBundlesIntoLimits,
300
303
  resolveEntitlementPlan,
301
304
  toEffectiveLimitsSnapshot
302
- } from "./chunk-GBDUH6DO.js";
305
+ } from "./chunk-EXOLOJFZ.js";
303
306
  import {
304
307
  PLAN_CATALOG_READ_SINK_TOKEN,
305
308
  PLAN_CATALOG_TOKEN,
@@ -595,6 +598,8 @@ export {
595
598
  computeProration,
596
599
  computeRegularStartsAt,
597
600
  computeSnapshotHash,
601
+ contractBundleVersionIds,
602
+ contractLimits,
598
603
  contractLineItemToInvoiceLineItem,
599
604
  decideRenewal,
600
605
  expandReplacedFeatures,
@@ -625,6 +630,7 @@ export {
625
630
  loadDiscoverySnapshotFromFile,
626
631
  loadPlanCatalogFromFile,
627
632
  loadPlanCatalogFromString,
633
+ mergeSubscriptionBundlesIntoLimits,
628
634
  periodEndAfter,
629
635
  periodEndWithMinLead,
630
636
  preflightExitCode,
@@ -4,8 +4,8 @@ import { SubscriptionRepository, UsageSnapshotPort, QuotaProvider } from '@saasi
4
4
  export { A as AdminBypassRlsInterceptor, a as AdminManifestModule, b as AdminManifestModuleOptions, c as AdminManifestService, d as AdminModule, e as AdminModuleOptions, f as AdminStatsModule, g as AdminStatsModuleOptions, h as AdminStatsService, M as MfaGuard, j as MfaService, S as SuperAdminGuard } from '../admin-stats.module-v4SVvWzj.cjs';
5
5
  export { A as AdminAuditService } from '../admin-audit.service-9IqXMlZm.cjs';
6
6
  export { e as AdminResourcesService } from '../admin-resources.module-BZN_yBFj.cjs';
7
- export { c as EntitlementService } from '../aggregation-CfI0bOsQ.cjs';
8
- export { d as ComposedTenantAuthGuard, P as PendingPlanMaterializationService, h as PlanChangePreviewService, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController } from '../subscription-bundle-preview.service-BkJXHAeP.cjs';
7
+ export { c as EntitlementService } from '../aggregation-SKfXu09x.cjs';
8
+ export { d as ComposedTenantAuthGuard, P as PendingPlanMaterializationService, h as PlanChangePreviewService, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController } from '../subscription-bundle-preview.service-B4Ye8L2F.cjs';
9
9
  export { B as BundlesService, C as CatalogEntriesService, M as MarketingProjectionsService, b as MarketingSettingsService, P as PlanVersionsService, c as PlansService, d as PromotionsService, e as PublicMarketingCatalogService } from '../plan-versions.service-CUR2Whyr.cjs';
10
10
  export { c as DiscoveryScanner } from '../discovery.scanner-DLgEvuoy.cjs';
11
11
  export { P as PromoCodeRateLimitGuard } from '../rate-limit.guard-dntqAlfZ.cjs';
@@ -4,8 +4,8 @@ import { SubscriptionRepository, UsageSnapshotPort, QuotaProvider } from '@saasi
4
4
  export { A as AdminBypassRlsInterceptor, a as AdminManifestModule, b as AdminManifestModuleOptions, c as AdminManifestService, d as AdminModule, e as AdminModuleOptions, f as AdminStatsModule, g as AdminStatsModuleOptions, h as AdminStatsService, M as MfaGuard, j as MfaService, S as SuperAdminGuard } from '../admin-stats.module-15ac5KY3.js';
5
5
  export { A as AdminAuditService } from '../admin-audit.service-9IqXMlZm.js';
6
6
  export { e as AdminResourcesService } from '../admin-resources.module-Cms8MY6h.js';
7
- export { c as EntitlementService } from '../aggregation-BibpEO0t.js';
8
- export { d as ComposedTenantAuthGuard, P as PendingPlanMaterializationService, h as PlanChangePreviewService, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController } from '../subscription-bundle-preview.service-DBbrE_cw.js';
7
+ export { c as EntitlementService } from '../aggregation-o0LMenvl.js';
8
+ export { d as ComposedTenantAuthGuard, P as PendingPlanMaterializationService, h as PlanChangePreviewService, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController } from '../subscription-bundle-preview.service-BgQ776mv.js';
9
9
  export { B as BundlesService, C as CatalogEntriesService, M as MarketingProjectionsService, b as MarketingSettingsService, P as PlanVersionsService, c as PlansService, d as PromotionsService, e as PublicMarketingCatalogService } from '../plan-versions.service-BB36Q1bg.js';
10
10
  export { c as DiscoveryScanner } from '../discovery.scanner-DLgEvuoy.js';
11
11
  export { P as PromoCodeRateLimitGuard } from '../rate-limit.guard-dntqAlfZ.js';
@@ -11,7 +11,7 @@ import {
11
11
  SubscriptionPlanResolver,
12
12
  TenantManifestService,
13
13
  buildTenantManifestController
14
- } from "../chunk-PUXLPUVH.js";
14
+ } from "../chunk-I2EKGQUG.js";
15
15
  import {
16
16
  SetupModule,
17
17
  SetupService
@@ -41,7 +41,7 @@ import {
41
41
  SubscriptionBundlesService,
42
42
  TenantAdminGuard,
43
43
  TenantBillingController
44
- } from "../chunk-F3VV6EXG.js";
44
+ } from "../chunk-RKVY775D.js";
45
45
  import {
46
46
  PromoCodesService
47
47
  } from "../chunk-E7AJ42AB.js";
@@ -74,7 +74,7 @@ import {
74
74
  } from "../chunk-Z3FWN3HJ.js";
75
75
  import {
76
76
  EntitlementService
77
- } from "../chunk-GBDUH6DO.js";
77
+ } from "../chunk-EXOLOJFZ.js";
78
78
  import "../chunk-R2QOSVAA.js";
79
79
  import "../chunk-NYLON2VC.js";
80
80
  import "../chunk-WKVBNTYC.js";
@@ -1,7 +1,7 @@
1
1
  import { CanActivate, ExecutionContext } from '@nestjs/common';
2
2
  import { b as AuthGuardList, m as SelfServiceBlockedPlans, w as TrialProjectionPort, h as PendingPlanQueryPort, f as ContractFreezePort, l as SelfServiceBlockedBundles, u as TenantIdResolver, B as UserIdResolver, z as UserEmailResolver, a as AuditContextResolver } from './subscription-bundles.module-DCpV-Pb5.cjs';
3
3
  import { PlanCatalog, SubscriptionUsagePort, UsageSnapshotPort, TenantSubscriptionWritePort, SubscriptionBundleRepository, BundleRepository, SubscriptionBundleView, SubscriptionBundleRecord, SubscriptionUsageRecord, OnboardingSelectionResponse, PlanRepository, CatalogEntryRepository, BundleVersionRow } from '@saasicat/types';
4
- import { c as EntitlementService, a as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from './aggregation-CfI0bOsQ.cjs';
4
+ import { c as EntitlementService, a as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from './aggregation-SKfXu09x.cjs';
5
5
  import { f as PromoCodesService } from './service-DX8KbGXl.cjs';
6
6
  import { A as AdminAuditService } from './admin-audit.service-9IqXMlZm.cjs';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { CanActivate, ExecutionContext } from '@nestjs/common';
2
2
  import { b as AuthGuardList, m as SelfServiceBlockedPlans, w as TrialProjectionPort, h as PendingPlanQueryPort, f as ContractFreezePort, l as SelfServiceBlockedBundles, u as TenantIdResolver, B as UserIdResolver, z as UserEmailResolver, a as AuditContextResolver } from './subscription-bundles.module-BQmoozm5.js';
3
3
  import { PlanCatalog, SubscriptionUsagePort, UsageSnapshotPort, TenantSubscriptionWritePort, SubscriptionBundleRepository, BundleRepository, SubscriptionBundleView, SubscriptionBundleRecord, SubscriptionUsageRecord, OnboardingSelectionResponse, PlanRepository, CatalogEntryRepository, BundleVersionRow } from '@saasicat/types';
4
- import { c as EntitlementService, a as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from './aggregation-BibpEO0t.js';
4
+ import { c as EntitlementService, a as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from './aggregation-o0LMenvl.js';
5
5
  import { f as PromoCodesService } from './service-DX8KbGXl.js';
6
6
  import { A as AdminAuditService } from './admin-audit.service-9IqXMlZm.js';
7
7
 
@@ -5,10 +5,10 @@ import {
5
5
  StaticEntitlementService,
6
6
  StaticFeatureGuard,
7
7
  StaticPlanResolver
8
- } from "../chunk-PUXLPUVH.js";
8
+ } from "../chunk-I2EKGQUG.js";
9
9
  import "../chunk-IRWZC3GC.js";
10
10
  import "../chunk-FVT7KTUI.js";
11
- import "../chunk-F3VV6EXG.js";
11
+ import "../chunk-RKVY775D.js";
12
12
  import "../chunk-E7AJ42AB.js";
13
13
  import "../chunk-2PNX2QL2.js";
14
14
  import "../chunk-33TP26MR.js";
@@ -17,7 +17,7 @@ import "../chunk-E56W4U2P.js";
17
17
  import "../chunk-MDIZUVIK.js";
18
18
  import "../chunk-V34AA7C7.js";
19
19
  import "../chunk-Z3FWN3HJ.js";
20
- import "../chunk-GBDUH6DO.js";
20
+ import "../chunk-EXOLOJFZ.js";
21
21
  import "../chunk-R2QOSVAA.js";
22
22
  import "../chunk-NYLON2VC.js";
23
23
  import "../chunk-WKVBNTYC.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasicat/nest",
3
- "version": "0.12.1",
3
+ "version": "0.14.0",
4
4
  "description": "NestJS implementation of SaaSiCat: capability discovery, catalog packaging, contracts, entitlement enforcement, billing and admin APIs.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -137,8 +137,8 @@
137
137
  "js-yaml": "^4.1.0",
138
138
  "otplib": "^13.4.1",
139
139
  "qrcode": "^1.5.4",
140
- "@saasicat/spec": "^0.12.1",
141
- "@saasicat/types": "^0.12.1"
140
+ "@saasicat/spec": "^0.14.0",
141
+ "@saasicat/types": "^0.14.0"
142
142
  },
143
143
  "peerDependencies": {
144
144
  "@nestjs/common": "^11.0.0",