@saasicat/nest 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/admin/index.d.cts +2 -2
  2. package/dist/admin/index.d.ts +2 -2
  3. package/dist/{admin-manifest.config-DyrQNT7M.d.cts → admin-manifest.config-DxTfZ8-L.d.cts} +1 -1
  4. package/dist/{admin-manifest.config-DyrQNT7M.d.ts → admin-manifest.config-DxTfZ8-L.d.ts} +1 -1
  5. package/dist/{aggregation-CJ3qQf92.d.cts → aggregation-Bt1i_whS.d.cts} +1 -8
  6. package/dist/{aggregation-Dvz9e8X2.d.ts → aggregation-DGCyoN5d.d.ts} +1 -8
  7. package/dist/billing/index.cjs +13 -2
  8. package/dist/billing/index.d.cts +5 -5
  9. package/dist/billing/index.d.ts +5 -5
  10. package/dist/billing/index.js +2 -2
  11. package/dist/catalog/index.d.cts +1 -1
  12. package/dist/catalog/index.d.ts +1 -1
  13. package/dist/{chunk-YXGHPILG.js → chunk-NFOSITWB.js} +7 -0
  14. package/dist/{chunk-47JT54VW.js → chunk-NWLOILP6.js} +4 -3
  15. package/dist/{chunk-RIGLQ4BV.js → chunk-S2OZ5RIM.js} +9 -4
  16. package/dist/discovery/index.d.cts +2 -2
  17. package/dist/discovery/index.d.ts +2 -2
  18. package/dist/{discovery.scanner-CUYLKlYT.d.cts → discovery.scanner-DLgEvuoy.d.cts} +1 -1
  19. package/dist/{discovery.scanner-CUYLKlYT.d.ts → discovery.scanner-DLgEvuoy.d.ts} +1 -1
  20. package/dist/{saas-platform.module-k1DQg4De.d.ts → enforce-quota.interceptor-3HmbeHTM.d.ts} +59 -4
  21. package/dist/{saas-platform.module-C7-H9eYB.d.cts → enforce-quota.interceptor-HmdZFg41.d.cts} +59 -4
  22. package/dist/entitlement/index.cjs +8 -0
  23. package/dist/entitlement/index.d.cts +18 -2
  24. package/dist/entitlement/index.d.ts +18 -2
  25. package/dist/entitlement/index.js +3 -1
  26. package/dist/index.cjs +29 -16
  27. package/dist/index.d.cts +4 -4
  28. package/dist/index.d.ts +4 -4
  29. package/dist/index.js +4 -2
  30. package/dist/platform/index.cjs +5 -1
  31. package/dist/platform/index.d.cts +9 -62
  32. package/dist/platform/index.d.ts +9 -62
  33. package/dist/platform/index.js +2 -2
  34. package/dist/testing/index.cjs +15 -1
  35. package/dist/testing/index.d.cts +5 -3
  36. package/dist/testing/index.d.ts +5 -3
  37. package/dist/testing/index.js +13 -3
  38. package/package.json +5 -3
@@ -4,8 +4,8 @@ import { MfaPort, RlsBypassPort, AuditPort, ManifestContribution, AdminManifest,
4
4
  export { A as AdminAuditService } from '../admin-audit.service-9IqXMlZm.cjs';
5
5
  import { Observable } from 'rxjs';
6
6
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
7
- import { A as AdminManifestConfig } from '../admin-manifest.config-DyrQNT7M.cjs';
8
- export { a as ADMIN_MANIFEST_CONFIG } from '../admin-manifest.config-DyrQNT7M.cjs';
7
+ import { a as AdminManifestConfig } from '../admin-manifest.config-DxTfZ8-L.cjs';
8
+ export { A as ADMIN_MANIFEST_CONFIG } from '../admin-manifest.config-DxTfZ8-L.cjs';
9
9
 
10
10
  declare const MFA_PORT_TOKEN: unique symbol;
11
11
  declare const AUDIT_PORT_TOKEN: unique symbol;
@@ -4,8 +4,8 @@ import { MfaPort, RlsBypassPort, AuditPort, ManifestContribution, AdminManifest,
4
4
  export { A as AdminAuditService } from '../admin-audit.service-9IqXMlZm.js';
5
5
  import { Observable } from 'rxjs';
6
6
  import { P as ProviderSpec } from '../di-CcNeq9v-.js';
7
- import { A as AdminManifestConfig } from '../admin-manifest.config-DyrQNT7M.js';
8
- export { a as ADMIN_MANIFEST_CONFIG } from '../admin-manifest.config-DyrQNT7M.js';
7
+ import { a as AdminManifestConfig } from '../admin-manifest.config-DxTfZ8-L.js';
8
+ export { A as ADMIN_MANIFEST_CONFIG } from '../admin-manifest.config-DxTfZ8-L.js';
9
9
 
10
10
  declare const MFA_PORT_TOKEN: unique symbol;
11
11
  declare const AUDIT_PORT_TOKEN: unique symbol;
@@ -7,4 +7,4 @@ interface AdminManifestConfig {
7
7
  planCatalogSnapshot: AdminManifest['planCatalogSnapshot'];
8
8
  }
9
9
 
10
- export { type AdminManifestConfig as A, ADMIN_MANIFEST_CONFIG as a };
10
+ export { ADMIN_MANIFEST_CONFIG as A, type AdminManifestConfig as a };
@@ -7,4 +7,4 @@ interface AdminManifestConfig {
7
7
  planCatalogSnapshot: AdminManifest['planCatalogSnapshot'];
8
8
  }
9
9
 
10
- export { type AdminManifestConfig as A, ADMIN_MANIFEST_CONFIG as a };
10
+ export { ADMIN_MANIFEST_CONFIG as A, type AdminManifestConfig as a };
@@ -192,13 +192,6 @@ declare class EntitlementService {
192
192
  private writeCache;
193
193
  }
194
194
 
195
- declare class LimitExceededError extends Error {
196
- readonly dimension: string;
197
- readonly max: number;
198
- readonly used: number;
199
- constructor(dimension: string, max: number, used: number);
200
- }
201
-
202
195
  /**
203
196
  * Aggregates the quotas of a BusinessTypeVersion: Σ(bundle quotas) per
204
197
  * QuotaKey, then override via `quotaOverrides[k]` if set.
@@ -285,4 +278,4 @@ declare function hasAnyFeature(limits: EffectiveLimits, features: readonly Featu
285
278
  */
286
279
  declare function toEffectiveLimitsSnapshot(limits: EffectiveLimits): EffectiveLimitsSnapshot;
287
280
 
288
- export { type BundleVersionSnapshot as B, type CustomLimitsShape as C, type EffectiveLimits as E, LimitExceededError as L, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type BusinessTypeVersionSnapshot as a, type EffectiveLimitsSnapshot as b, type EnforceLimitInput as c, EntitlementService as d, type SubscriptionLimitsInput as e, aggregateBusinessTypeQuotas as f, aggregateContractLineItemEntitlements as g, aggregateLimits as h, aggregateSubscriptionBundleQuotas as i, applyCustomLimits as j, collectBusinessTypeFeatures as k, collectSubscriptionBundleFeatures as l, filterActiveSubscriptionBundles as m, filterPlannedOnlyFeatures as n, hasAnyFeature as o, hasFeature as p, toEffectiveLimitsSnapshot as t };
281
+ export { type BundleVersionSnapshot as B, type CustomLimitsShape as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type BusinessTypeVersionSnapshot as a, type EffectiveLimitsSnapshot as b, type EnforceLimitInput as c, EntitlementService as d, type SubscriptionLimitsInput as e, aggregateBusinessTypeQuotas as f, aggregateContractLineItemEntitlements as g, aggregateLimits as h, aggregateSubscriptionBundleQuotas as i, applyCustomLimits as j, collectBusinessTypeFeatures as k, collectSubscriptionBundleFeatures as l, filterActiveSubscriptionBundles as m, filterPlannedOnlyFeatures as n, hasAnyFeature as o, hasFeature as p, toEffectiveLimitsSnapshot as t };
@@ -192,13 +192,6 @@ declare class EntitlementService {
192
192
  private writeCache;
193
193
  }
194
194
 
195
- declare class LimitExceededError extends Error {
196
- readonly dimension: string;
197
- readonly max: number;
198
- readonly used: number;
199
- constructor(dimension: string, max: number, used: number);
200
- }
201
-
202
195
  /**
203
196
  * Aggregates the quotas of a BusinessTypeVersion: Σ(bundle quotas) per
204
197
  * QuotaKey, then override via `quotaOverrides[k]` if set.
@@ -285,4 +278,4 @@ declare function hasAnyFeature(limits: EffectiveLimits, features: readonly Featu
285
278
  */
286
279
  declare function toEffectiveLimitsSnapshot(limits: EffectiveLimits): EffectiveLimitsSnapshot;
287
280
 
288
- export { type BundleVersionSnapshot as B, type CustomLimitsShape as C, type EffectiveLimits as E, LimitExceededError as L, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type BusinessTypeVersionSnapshot as a, type EffectiveLimitsSnapshot as b, type EnforceLimitInput as c, EntitlementService as d, type SubscriptionLimitsInput as e, aggregateBusinessTypeQuotas as f, aggregateContractLineItemEntitlements as g, aggregateLimits as h, aggregateSubscriptionBundleQuotas as i, applyCustomLimits as j, collectBusinessTypeFeatures as k, collectSubscriptionBundleFeatures as l, filterActiveSubscriptionBundles as m, filterPlannedOnlyFeatures as n, hasAnyFeature as o, hasFeature as p, toEffectiveLimitsSnapshot as t };
281
+ export { type BundleVersionSnapshot as B, type CustomLimitsShape as C, type EffectiveLimits as E, type PlanVersionSnapshot as P, type SubscriptionBundleSnapshot as S, type BusinessTypeVersionSnapshot as a, type EffectiveLimitsSnapshot as b, type EnforceLimitInput as c, EntitlementService as d, type SubscriptionLimitsInput as e, aggregateBusinessTypeQuotas as f, aggregateContractLineItemEntitlements as g, aggregateLimits as h, aggregateSubscriptionBundleQuotas as i, applyCustomLimits as j, collectBusinessTypeFeatures as k, collectSubscriptionBundleFeatures as l, filterActiveSubscriptionBundles as m, filterPlannedOnlyFeatures as n, hasAnyFeature as o, hasFeature as p, toEffectiveLimitsSnapshot as t };
@@ -705,6 +705,7 @@ function assertNoReplacesCycle(index) {
705
705
  __name(assertNoReplacesCycle, "assertNoReplacesCycle");
706
706
 
707
707
  // src/entitlement/limit-exceeded-error.ts
708
+ var LIMIT_EXCEEDED = "LIMIT_EXCEEDED";
708
709
  var LimitExceededError = class extends Error {
709
710
  static {
710
711
  __name(this, "LimitExceededError");
@@ -712,11 +713,16 @@ var LimitExceededError = class extends Error {
712
713
  dimension;
713
714
  max;
714
715
  used;
716
+ code = LIMIT_EXCEEDED;
715
717
  constructor(dimension, max, used) {
716
718
  super(`Limit f\xFCr ${dimension} erreicht: ${used}/${max}.`), this.dimension = dimension, this.max = max, this.used = used;
717
719
  this.name = "LimitExceededError";
718
720
  }
719
721
  };
722
+ function isLimitExceededError(err) {
723
+ return err instanceof Error && err.code === LIMIT_EXCEEDED;
724
+ }
725
+ __name(isLimitExceededError, "isLimitExceededError");
720
726
 
721
727
  // src/entitlement/plan-resolution.ts
722
728
  function resolveEntitlementPlan(input, config, now) {
@@ -1231,6 +1237,7 @@ __name(compareRankedOffers, "compareRankedOffers");
1231
1237
 
1232
1238
  // src/billing/limit-exceeded.filter.ts
1233
1239
  var import_common6 = require("@nestjs/common");
1240
+ var import_core2 = require("@nestjs/core");
1234
1241
  function _ts_decorate5(decorators, target, key, desc) {
1235
1242
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1236
1243
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1238,12 +1245,16 @@ function _ts_decorate5(decorators, target, key, desc) {
1238
1245
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1239
1246
  }
1240
1247
  __name(_ts_decorate5, "_ts_decorate");
1241
- var LimitExceededFilter = class _LimitExceededFilter {
1248
+ var LimitExceededFilter = class _LimitExceededFilter extends import_core2.BaseExceptionFilter {
1242
1249
  static {
1243
1250
  __name(this, "LimitExceededFilter");
1244
1251
  }
1245
1252
  logger = new import_common6.Logger(_LimitExceededFilter.name);
1246
1253
  catch(exception, host) {
1254
+ if (!isLimitExceededError(exception)) {
1255
+ super.catch(exception, host);
1256
+ return;
1257
+ }
1247
1258
  const ctx = host.switchToHttp();
1248
1259
  const response = ctx.getResponse();
1249
1260
  const request = ctx.getRequest();
@@ -1260,7 +1271,7 @@ var LimitExceededFilter = class _LimitExceededFilter {
1260
1271
  }
1261
1272
  };
1262
1273
  LimitExceededFilter = _ts_decorate5([
1263
- (0, import_common6.Catch)(LimitExceededError)
1274
+ (0, import_common6.Catch)()
1264
1275
  ], LimitExceededFilter);
1265
1276
 
1266
1277
  // src/billing/plan-catalog-loader.ts
@@ -1,10 +1,10 @@
1
1
  import { BillingCycle, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalog, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, BusinessTypeRepository, SubscriptionUsagePort, UsageSnapshotPort, NewContractLineItemData, TenantSubscriptionWritePort, SubscriptionBundleRepository, SubscriptionBundleView, SubscriptionBundleRecord, SubscriptionUsageRecord, OnboardingSelectionResponse, SubscriptionContractRepository, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog, PlanRepository, BundleVersionRow } from '@saasicat/types';
2
2
  export { BundleVersionFields, ChangeDirection, DiffResult, PlanVersionFields, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/types';
3
3
  import * as _nestjs_common from '@nestjs/common';
4
- import { CanActivate, ExecutionContext, ExceptionFilter, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
4
+ import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
5
5
  export { Type as NestType } from '@nestjs/common';
6
- import { Reflector } from '@nestjs/core';
7
- import { d as EntitlementService, L as LimitExceededError, b as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from '../aggregation-CJ3qQf92.cjs';
6
+ import { Reflector, BaseExceptionFilter } from '@nestjs/core';
7
+ import { d as EntitlementService, b as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from '../aggregation-Bt1i_whS.cjs';
8
8
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
9
9
  import { S as SubscriptionContractService } from '../subscription-contract.service--cm47ZJJ.cjs';
10
10
  import { f as PromoCodesService } from '../service-DX8KbGXl.cjs';
@@ -237,9 +237,9 @@ declare class CatalogBundleUpsellResolver implements UpsellOfferResolver {
237
237
  private toOffer;
238
238
  }
239
239
 
240
- declare class LimitExceededFilter implements ExceptionFilter {
240
+ declare class LimitExceededFilter extends BaseExceptionFilter {
241
241
  private readonly logger;
242
- catch(exception: LimitExceededError, host: ArgumentsHost): void;
242
+ catch(exception: unknown, host: ArgumentsHost): void;
243
243
  }
244
244
 
245
245
  /**
@@ -1,10 +1,10 @@
1
1
  import { BillingCycle, FeatureKey, UpsellOfferResolver, BundleRepository, CatalogEntryRepository, UpsellOffer, PlanCatalog, PlanCatalogReadSink, PlanCatalogReadSnapshot, PlanCatalogImportSink, PlanCatalogImportReport, PlanId, PlanDef, QuotaKey, MarketingTopFeature, FeatureUiRegistry, MarketingProjectionRepository, BusinessTypeRepository, SubscriptionUsagePort, UsageSnapshotPort, NewContractLineItemData, TenantSubscriptionWritePort, SubscriptionBundleRepository, SubscriptionBundleView, SubscriptionBundleRecord, SubscriptionUsageRecord, OnboardingSelectionResponse, SubscriptionContractRepository, ConfiguratorSourcesLookup, ConfiguratorMarketingProvider, ConfiguratorCatalog, PlanRepository, BundleVersionRow } from '@saasicat/types';
2
2
  export { BundleVersionFields, ChangeDirection, DiffResult, PlanVersionFields, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/types';
3
3
  import * as _nestjs_common from '@nestjs/common';
4
- import { CanActivate, ExecutionContext, ExceptionFilter, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
4
+ import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
5
5
  export { Type as NestType } from '@nestjs/common';
6
- import { Reflector } from '@nestjs/core';
7
- import { d as EntitlementService, L as LimitExceededError, b as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from '../aggregation-Dvz9e8X2.js';
6
+ import { Reflector, BaseExceptionFilter } from '@nestjs/core';
7
+ import { d as EntitlementService, b as EffectiveLimitsSnapshot, t as toEffectiveLimitsSnapshot } from '../aggregation-DGCyoN5d.js';
8
8
  import { P as ProviderSpec } from '../di-CcNeq9v-.js';
9
9
  import { S as SubscriptionContractService } from '../subscription-contract.service--cm47ZJJ.js';
10
10
  import { f as PromoCodesService } from '../service-DX8KbGXl.js';
@@ -237,9 +237,9 @@ declare class CatalogBundleUpsellResolver implements UpsellOfferResolver {
237
237
  private toOffer;
238
238
  }
239
239
 
240
- declare class LimitExceededFilter implements ExceptionFilter {
240
+ declare class LimitExceededFilter extends BaseExceptionFilter {
241
241
  private readonly logger;
242
- catch(exception: LimitExceededError, host: ArgumentsHost): void;
242
+ catch(exception: unknown, host: ArgumentsHost): void;
243
243
  }
244
244
 
245
245
  /**
@@ -57,7 +57,7 @@ import {
57
57
  periodEndWithMinLead,
58
58
  resolveBundleCancelEffectiveAt,
59
59
  resolveBundlePriceNet
60
- } from "../chunk-RIGLQ4BV.js";
60
+ } from "../chunk-S2OZ5RIM.js";
61
61
  import "../chunk-ZL4LLE2Z.js";
62
62
  import "../chunk-2PNX2QL2.js";
63
63
  import {
@@ -84,7 +84,7 @@ import "../chunk-E56W4U2P.js";
84
84
  import {
85
85
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
86
86
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN
87
- } from "../chunk-YXGHPILG.js";
87
+ } from "../chunk-NFOSITWB.js";
88
88
  import {
89
89
  PLAN_CATALOG_READ_SINK_TOKEN,
90
90
  PLAN_CATALOG_TOKEN,
@@ -1,5 +1,5 @@
1
1
  import { BundleRepository, DiscoverySnapshot, SubscriptionRepository, PlanRepository, CatalogEntryRepository, BundleRow, BundleVersionRow, CreateBundleData, UpdateBundleData, CreateBundleVersionDraftData, BundleVersionMutationResult, UpdateBundleVersionDraftData, PublishBundleVersionData, BusinessTypeRepository, BusinessTypeRow, BusinessTypeVersionRow, CreateBusinessTypeData, UpdateBusinessTypeData, CreateBusinessTypeVersionDraftData, BusinessTypeVersionMutationResult, UpdateBusinessTypeVersionDraftData, PublishBusinessTypeVersionData, MarketingProjectionRepository, MarketingProjectionFilter, MarketingProjectionRow, CreateMarketingProjectionData, UpdateMarketingProjectionData, FeatureUiRegistry, CapabilityCatalogEntryRow, FeatureCatalogEntryRow, QuotaCatalogEntryRow, ReviewCatalogEntryData, CatalogEntryI18n, UpdateCatalogEntryBaseData, SyncDiscoveryResult, PromotionRepository, PromotionRow, CreatePromotionData, UpdatePromotionData, MarketingSettingsRepository, MarketingSettingsRow, UpdateMarketingSettingsData, PublicMarketingCatalogResponse, PlanRow, CreatePlanData, UpdatePlanData, PlanVersionRow, CreatePlanVersionDraftData, PlanVersionMutationResult, UpdatePlanVersionDraftData, PublishPlanVersionData, StrictModeWarningCode, StrictModeWarning, ApprovedCatalogKeys, DiscoveredQuota, DiscoveryStatus, PromotionType, PromotionValue, PromotionTargetType, PromotionBillingCycle, PromotionI18n } from '@saasicat/types';
2
- import { c as DiscoveryScanner } from '../discovery.scanner-CUYLKlYT.cjs';
2
+ import { c as DiscoveryScanner } from '../discovery.scanner-DLgEvuoy.cjs';
3
3
  import { OnApplicationBootstrap, Type, CanActivate, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
4
4
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
5
5
  import '@nestjs/core';
@@ -1,5 +1,5 @@
1
1
  import { BundleRepository, DiscoverySnapshot, SubscriptionRepository, PlanRepository, CatalogEntryRepository, BundleRow, BundleVersionRow, CreateBundleData, UpdateBundleData, CreateBundleVersionDraftData, BundleVersionMutationResult, UpdateBundleVersionDraftData, PublishBundleVersionData, BusinessTypeRepository, BusinessTypeRow, BusinessTypeVersionRow, CreateBusinessTypeData, UpdateBusinessTypeData, CreateBusinessTypeVersionDraftData, BusinessTypeVersionMutationResult, UpdateBusinessTypeVersionDraftData, PublishBusinessTypeVersionData, MarketingProjectionRepository, MarketingProjectionFilter, MarketingProjectionRow, CreateMarketingProjectionData, UpdateMarketingProjectionData, FeatureUiRegistry, CapabilityCatalogEntryRow, FeatureCatalogEntryRow, QuotaCatalogEntryRow, ReviewCatalogEntryData, CatalogEntryI18n, UpdateCatalogEntryBaseData, SyncDiscoveryResult, PromotionRepository, PromotionRow, CreatePromotionData, UpdatePromotionData, MarketingSettingsRepository, MarketingSettingsRow, UpdateMarketingSettingsData, PublicMarketingCatalogResponse, PlanRow, CreatePlanData, UpdatePlanData, PlanVersionRow, CreatePlanVersionDraftData, PlanVersionMutationResult, UpdatePlanVersionDraftData, PublishPlanVersionData, StrictModeWarningCode, StrictModeWarning, ApprovedCatalogKeys, DiscoveredQuota, DiscoveryStatus, PromotionType, PromotionValue, PromotionTargetType, PromotionBillingCycle, PromotionI18n } from '@saasicat/types';
2
- import { c as DiscoveryScanner } from '../discovery.scanner-CUYLKlYT.js';
2
+ import { c as DiscoveryScanner } from '../discovery.scanner-DLgEvuoy.js';
3
3
  import { OnApplicationBootstrap, Type, CanActivate, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
4
4
  import { P as ProviderSpec } from '../di-CcNeq9v-.js';
5
5
  import '@nestjs/core';
@@ -261,6 +261,7 @@ function assertNoReplacesCycle(index) {
261
261
  __name(assertNoReplacesCycle, "assertNoReplacesCycle");
262
262
 
263
263
  // src/entitlement/limit-exceeded-error.ts
264
+ var LIMIT_EXCEEDED = "LIMIT_EXCEEDED";
264
265
  var LimitExceededError = class extends Error {
265
266
  static {
266
267
  __name(this, "LimitExceededError");
@@ -268,11 +269,16 @@ var LimitExceededError = class extends Error {
268
269
  dimension;
269
270
  max;
270
271
  used;
272
+ code = LIMIT_EXCEEDED;
271
273
  constructor(dimension, max, used) {
272
274
  super(`Limit f\xFCr ${dimension} erreicht: ${used}/${max}.`), this.dimension = dimension, this.max = max, this.used = used;
273
275
  this.name = "LimitExceededError";
274
276
  }
275
277
  };
278
+ function isLimitExceededError(err) {
279
+ return err instanceof Error && err.code === LIMIT_EXCEEDED;
280
+ }
281
+ __name(isLimitExceededError, "isLimitExceededError");
276
282
 
277
283
  // src/entitlement/plan-resolution.ts
278
284
  function resolveEntitlementPlan(input, config, now) {
@@ -608,6 +614,7 @@ export {
608
614
  buildReplacedByIndex,
609
615
  expandReplacedFeatures,
610
616
  LimitExceededError,
617
+ isLimitExceededError,
611
618
  resolveEntitlementPlan,
612
619
  EntitlementService,
613
620
  EntitlementModule
@@ -1,5 +1,4 @@
1
1
  import {
2
- ADMIN_MANIFEST_CONFIG,
3
2
  AdminManifestModule,
4
3
  AdminModule
5
4
  } from "./chunk-P6MYZMXQ.js";
@@ -12,7 +11,7 @@ import {
12
11
  import {
13
12
  EntitlementModule,
14
13
  LimitExceededError
15
- } from "./chunk-YXGHPILG.js";
14
+ } from "./chunk-NFOSITWB.js";
16
15
  import {
17
16
  PLAN_CATALOG_TOKEN,
18
17
  PlanCatalogModule
@@ -577,11 +576,13 @@ var SaasPlatformModule = class _SaasPlatformModule {
577
576
  PlanCatalogModule,
578
577
  DiscoveryModule,
579
578
  AdminModule,
579
+ // ADMIN_MANIFEST_CONFIG travels transitively: re-exporting an
580
+ // imported module's token directly is an UnknownExportException
581
+ // at boot — the module export below already carries it.
580
582
  AdminManifestModule,
581
583
  ...options.entitlement ? [
582
584
  EntitlementModule
583
585
  ] : [],
584
- ADMIN_MANIFEST_CONFIG,
585
586
  ...lightweightExports
586
587
  ],
587
588
  global: true
@@ -24,11 +24,11 @@ import {
24
24
  } from "./chunk-E56W4U2P.js";
25
25
  import {
26
26
  EntitlementService,
27
- LimitExceededError,
28
27
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
29
28
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN,
29
+ isLimitExceededError,
30
30
  toEffectiveLimitsSnapshot
31
- } from "./chunk-YXGHPILG.js";
31
+ } from "./chunk-NFOSITWB.js";
32
32
  import {
33
33
  PLAN_CATALOG_TOKEN,
34
34
  findPlan,
@@ -418,6 +418,7 @@ __name(compareRankedOffers, "compareRankedOffers");
418
418
 
419
419
  // src/billing/limit-exceeded.filter.ts
420
420
  import { Catch, HttpStatus, Logger as Logger2 } from "@nestjs/common";
421
+ import { BaseExceptionFilter } from "@nestjs/core";
421
422
  function _ts_decorate3(decorators, target, key, desc) {
422
423
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
423
424
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -425,12 +426,16 @@ function _ts_decorate3(decorators, target, key, desc) {
425
426
  return c > 3 && r && Object.defineProperty(target, key, r), r;
426
427
  }
427
428
  __name(_ts_decorate3, "_ts_decorate");
428
- var LimitExceededFilter = class _LimitExceededFilter {
429
+ var LimitExceededFilter = class _LimitExceededFilter extends BaseExceptionFilter {
429
430
  static {
430
431
  __name(this, "LimitExceededFilter");
431
432
  }
432
433
  logger = new Logger2(_LimitExceededFilter.name);
433
434
  catch(exception, host) {
435
+ if (!isLimitExceededError(exception)) {
436
+ super.catch(exception, host);
437
+ return;
438
+ }
434
439
  const ctx = host.switchToHttp();
435
440
  const response = ctx.getResponse();
436
441
  const request = ctx.getRequest();
@@ -447,7 +452,7 @@ var LimitExceededFilter = class _LimitExceededFilter {
447
452
  }
448
453
  };
449
454
  LimitExceededFilter = _ts_decorate3([
450
- Catch(LimitExceededError)
455
+ Catch()
451
456
  ], LimitExceededFilter);
452
457
 
453
458
  // src/billing/plan-catalog-loader.ts
@@ -2,8 +2,8 @@ import * as _nestjs_common from '@nestjs/common';
2
2
  import { Type, CanActivate, DynamicModule, ForwardReference, LogLevel } from '@nestjs/common';
3
3
  import { DiscoveredQuotaPolicy, DiscoveryCodeStatus, CapabilityKind, DiscoverySnapshot } from '@saasicat/types';
4
4
  export { DiscoveredCapability, DiscoveredFeature, DiscoveredQuota, DiscoverySnapshot } from '@saasicat/types';
5
- import { D as DiscoveryAppInfo } from '../discovery.scanner-CUYLKlYT.cjs';
6
- export { a as DISCOVERY_APP_INFO_TOKEN, b as DISCOVERY_SNAPSHOT_PATH_TOKEN, c as DiscoveryScanner, d as computeSnapshotHash } from '../discovery.scanner-CUYLKlYT.cjs';
5
+ import { b as DiscoveryAppInfo } from '../discovery.scanner-DLgEvuoy.cjs';
6
+ export { D as DISCOVERY_APP_INFO_TOKEN, a as DISCOVERY_SNAPSHOT_PATH_TOKEN, c as DiscoveryScanner, d as computeSnapshotHash } from '../discovery.scanner-DLgEvuoy.cjs';
7
7
  import '@nestjs/core';
8
8
 
9
9
  /**
@@ -2,8 +2,8 @@ import * as _nestjs_common from '@nestjs/common';
2
2
  import { Type, CanActivate, DynamicModule, ForwardReference, LogLevel } from '@nestjs/common';
3
3
  import { DiscoveredQuotaPolicy, DiscoveryCodeStatus, CapabilityKind, DiscoverySnapshot } from '@saasicat/types';
4
4
  export { DiscoveredCapability, DiscoveredFeature, DiscoveredQuota, DiscoverySnapshot } from '@saasicat/types';
5
- import { D as DiscoveryAppInfo } from '../discovery.scanner-CUYLKlYT.js';
6
- export { a as DISCOVERY_APP_INFO_TOKEN, b as DISCOVERY_SNAPSHOT_PATH_TOKEN, c as DiscoveryScanner, d as computeSnapshotHash } from '../discovery.scanner-CUYLKlYT.js';
5
+ import { b as DiscoveryAppInfo } from '../discovery.scanner-DLgEvuoy.js';
6
+ export { D as DISCOVERY_APP_INFO_TOKEN, a as DISCOVERY_SNAPSHOT_PATH_TOKEN, c as DiscoveryScanner, d as computeSnapshotHash } from '../discovery.scanner-DLgEvuoy.js';
7
7
  import '@nestjs/core';
8
8
 
9
9
  /**
@@ -56,4 +56,4 @@ declare class DiscoveryScanner implements OnApplicationBootstrap {
56
56
  */
57
57
  declare function computeSnapshotHash(snapshot: Omit<DiscoverySnapshot, 'hash'>): string;
58
58
 
59
- export { type DiscoveryAppInfo as D, DISCOVERY_APP_INFO_TOKEN as a, DISCOVERY_SNAPSHOT_PATH_TOKEN as b, DiscoveryScanner as c, computeSnapshotHash as d };
59
+ export { DISCOVERY_APP_INFO_TOKEN as D, DISCOVERY_SNAPSHOT_PATH_TOKEN as a, type DiscoveryAppInfo as b, DiscoveryScanner as c, computeSnapshotHash as d };
@@ -56,4 +56,4 @@ declare class DiscoveryScanner implements OnApplicationBootstrap {
56
56
  */
57
57
  declare function computeSnapshotHash(snapshot: Omit<DiscoverySnapshot, 'hash'>): string;
58
58
 
59
- export { type DiscoveryAppInfo as D, DISCOVERY_APP_INFO_TOKEN as a, DISCOVERY_SNAPSHOT_PATH_TOKEN as b, DiscoveryScanner as c, computeSnapshotHash as d };
59
+ export { DISCOVERY_APP_INFO_TOKEN as D, DISCOVERY_SNAPSHOT_PATH_TOKEN as a, type DiscoveryAppInfo as b, DiscoveryScanner as c, computeSnapshotHash as d };
@@ -1,9 +1,11 @@
1
- import { Type, CanActivate, DynamicModule, ForwardReference, FactoryProvider } from '@nestjs/common';
1
+ import { Type, CanActivate, DynamicModule, ForwardReference, FactoryProvider, ExecutionContext, NestInterceptor, CallHandler } from '@nestjs/common';
2
2
  import { MfaPort, AuditPort, RlsBypassPort, PlanCatalogReadSink, SubscriptionRepository, PlanVersionRepository, TransactionRunner, PlanCatalog, SaasicatPersistenceAdapter, QuotaProvider } from '@saasicat/types';
3
3
  import { P as ProviderSpec } from './di-CcNeq9v-.js';
4
- import { A as AdminManifestConfig } from './admin-manifest.config-DyrQNT7M.js';
5
- import { D as DiscoveryAppInfo } from './discovery.scanner-CUYLKlYT.js';
4
+ import { a as AdminManifestConfig } from './admin-manifest.config-DxTfZ8-L.js';
5
+ import { b as DiscoveryAppInfo } from './discovery.scanner-DLgEvuoy.js';
6
6
  import { E as EntitlementResolutionConfig } from './plan-resolution-CFCoUkrE.js';
7
+ import { Reflector } from '@nestjs/core';
8
+ import { Observable } from 'rxjs';
7
9
 
8
10
  declare const PLAN_RESOLVER_PORT_TOKEN: unique symbol;
9
11
  interface PlanResolverPort {
@@ -200,4 +202,57 @@ declare class SaasPlatformModule {
200
202
  static forRoot(options: SaasPlatformModuleOptions): DynamicModule;
201
203
  }
202
204
 
203
- export { type PlanResolverPort as P, type SaasPlatformAdapters as S, type TenantManifestControllerOptions as T, PLAN_RESOLVER_PORT_TOKEN as a, SaasPlatformModule as b, type SaasPlatformModuleOptions as c, StaticPlanResolver as d, buildTenantManifestController as e };
205
+ interface StaticEntitlementSnapshot {
206
+ planId: string | null;
207
+ features: readonly string[];
208
+ /** quotaKey → limit (`-1` = unlimited). */
209
+ quotas: Readonly<Record<string, number>>;
210
+ }
211
+ declare class StaticEntitlementService {
212
+ private readonly catalog;
213
+ private readonly resolver;
214
+ constructor(catalog: PlanCatalog, resolver: PlanResolverPort);
215
+ /**
216
+ * Returns the effective features + quotas of a tenant from the
217
+ * plan catalog. When the plan is missing: an empty snapshot (no feature,
218
+ * all quotas at 0).
219
+ */
220
+ snapshot(tenantId: string): Promise<StaticEntitlementSnapshot>;
221
+ /** Convenience helper for tests / synchronous checks in the UI manifest. */
222
+ hasFeature(tenantId: string, featureKey: string): Promise<boolean>;
223
+ quotaLimit(tenantId: string, quotaKey: string): Promise<number | null>;
224
+ private findPlan;
225
+ }
226
+
227
+ declare const STATIC_FEATURE_GUARD_CONFIG_TOKEN: unique symbol;
228
+ interface StaticFeatureGuardConfig {
229
+ /**
230
+ * Resolver for the user role (e.g. `(user) => user.platformRole`).
231
+ * SUPER_ADMIN gets a bypass.
232
+ */
233
+ userRoleResolver?: (user: unknown) => string | undefined;
234
+ /**
235
+ * Resolver for the tenant ID from the request. Default:
236
+ * `request.tenantId ?? request.user?.tenantId`.
237
+ */
238
+ tenantIdResolver?: (request: unknown) => string | undefined;
239
+ }
240
+ declare class StaticFeatureGuard implements CanActivate {
241
+ private readonly reflector;
242
+ private readonly entitlements;
243
+ private readonly config;
244
+ constructor(reflector: Reflector, entitlements: StaticEntitlementService, config?: StaticFeatureGuardConfig | null);
245
+ canActivate(context: ExecutionContext): Promise<boolean>;
246
+ }
247
+
248
+ declare const QUOTA_PROVIDERS_TOKEN: unique symbol;
249
+ declare class EnforceQuotaInterceptor implements NestInterceptor {
250
+ private readonly reflector;
251
+ private readonly entitlements;
252
+ private readonly providers;
253
+ constructor(reflector: Reflector, entitlements: StaticEntitlementService, providers?: ReadonlyArray<QuotaProvider> | null);
254
+ intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
255
+ private check;
256
+ }
257
+
258
+ export { EnforceQuotaInterceptor as E, PLAN_RESOLVER_PORT_TOKEN as P, QUOTA_PROVIDERS_TOKEN as Q, StaticEntitlementService as S, type TenantManifestControllerOptions as T, type PlanResolverPort as a, STATIC_FEATURE_GUARD_CONFIG_TOKEN as b, type SaasPlatformAdapters as c, SaasPlatformModule as d, type SaasPlatformModuleOptions as e, type StaticEntitlementSnapshot as f, StaticFeatureGuard as g, type StaticFeatureGuardConfig as h, StaticPlanResolver as i, buildTenantManifestController as j };
@@ -1,9 +1,11 @@
1
- import { Type, CanActivate, DynamicModule, ForwardReference, FactoryProvider } from '@nestjs/common';
1
+ import { Type, CanActivate, DynamicModule, ForwardReference, FactoryProvider, ExecutionContext, NestInterceptor, CallHandler } from '@nestjs/common';
2
2
  import { MfaPort, AuditPort, RlsBypassPort, PlanCatalogReadSink, SubscriptionRepository, PlanVersionRepository, TransactionRunner, PlanCatalog, SaasicatPersistenceAdapter, QuotaProvider } from '@saasicat/types';
3
3
  import { P as ProviderSpec } from './di-CcNeq9v-.cjs';
4
- import { A as AdminManifestConfig } from './admin-manifest.config-DyrQNT7M.cjs';
5
- import { D as DiscoveryAppInfo } from './discovery.scanner-CUYLKlYT.cjs';
4
+ import { a as AdminManifestConfig } from './admin-manifest.config-DxTfZ8-L.cjs';
5
+ import { b as DiscoveryAppInfo } from './discovery.scanner-DLgEvuoy.cjs';
6
6
  import { E as EntitlementResolutionConfig } from './plan-resolution-CFCoUkrE.cjs';
7
+ import { Reflector } from '@nestjs/core';
8
+ import { Observable } from 'rxjs';
7
9
 
8
10
  declare const PLAN_RESOLVER_PORT_TOKEN: unique symbol;
9
11
  interface PlanResolverPort {
@@ -200,4 +202,57 @@ declare class SaasPlatformModule {
200
202
  static forRoot(options: SaasPlatformModuleOptions): DynamicModule;
201
203
  }
202
204
 
203
- export { type PlanResolverPort as P, type SaasPlatformAdapters as S, type TenantManifestControllerOptions as T, PLAN_RESOLVER_PORT_TOKEN as a, SaasPlatformModule as b, type SaasPlatformModuleOptions as c, StaticPlanResolver as d, buildTenantManifestController as e };
205
+ interface StaticEntitlementSnapshot {
206
+ planId: string | null;
207
+ features: readonly string[];
208
+ /** quotaKey → limit (`-1` = unlimited). */
209
+ quotas: Readonly<Record<string, number>>;
210
+ }
211
+ declare class StaticEntitlementService {
212
+ private readonly catalog;
213
+ private readonly resolver;
214
+ constructor(catalog: PlanCatalog, resolver: PlanResolverPort);
215
+ /**
216
+ * Returns the effective features + quotas of a tenant from the
217
+ * plan catalog. When the plan is missing: an empty snapshot (no feature,
218
+ * all quotas at 0).
219
+ */
220
+ snapshot(tenantId: string): Promise<StaticEntitlementSnapshot>;
221
+ /** Convenience helper for tests / synchronous checks in the UI manifest. */
222
+ hasFeature(tenantId: string, featureKey: string): Promise<boolean>;
223
+ quotaLimit(tenantId: string, quotaKey: string): Promise<number | null>;
224
+ private findPlan;
225
+ }
226
+
227
+ declare const STATIC_FEATURE_GUARD_CONFIG_TOKEN: unique symbol;
228
+ interface StaticFeatureGuardConfig {
229
+ /**
230
+ * Resolver for the user role (e.g. `(user) => user.platformRole`).
231
+ * SUPER_ADMIN gets a bypass.
232
+ */
233
+ userRoleResolver?: (user: unknown) => string | undefined;
234
+ /**
235
+ * Resolver for the tenant ID from the request. Default:
236
+ * `request.tenantId ?? request.user?.tenantId`.
237
+ */
238
+ tenantIdResolver?: (request: unknown) => string | undefined;
239
+ }
240
+ declare class StaticFeatureGuard implements CanActivate {
241
+ private readonly reflector;
242
+ private readonly entitlements;
243
+ private readonly config;
244
+ constructor(reflector: Reflector, entitlements: StaticEntitlementService, config?: StaticFeatureGuardConfig | null);
245
+ canActivate(context: ExecutionContext): Promise<boolean>;
246
+ }
247
+
248
+ declare const QUOTA_PROVIDERS_TOKEN: unique symbol;
249
+ declare class EnforceQuotaInterceptor implements NestInterceptor {
250
+ private readonly reflector;
251
+ private readonly entitlements;
252
+ private readonly providers;
253
+ constructor(reflector: Reflector, entitlements: StaticEntitlementService, providers?: ReadonlyArray<QuotaProvider> | null);
254
+ intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
255
+ private check;
256
+ }
257
+
258
+ export { EnforceQuotaInterceptor as E, PLAN_RESOLVER_PORT_TOKEN as P, QUOTA_PROVIDERS_TOKEN as Q, StaticEntitlementService as S, type TenantManifestControllerOptions as T, type PlanResolverPort as a, STATIC_FEATURE_GUARD_CONFIG_TOKEN as b, type SaasPlatformAdapters as c, SaasPlatformModule as d, type SaasPlatformModuleOptions as e, type StaticEntitlementSnapshot as f, StaticFeatureGuard as g, type StaticFeatureGuardConfig as h, StaticPlanResolver as i, buildTenantManifestController as j };
@@ -41,6 +41,7 @@ __export(entitlement_exports, {
41
41
  filterPlannedOnlyFeatures: () => filterPlannedOnlyFeatures,
42
42
  hasAnyFeature: () => hasAnyFeature,
43
43
  hasFeature: () => hasFeature,
44
+ isLimitExceededError: () => isLimitExceededError,
44
45
  resolveEntitlementPlan: () => resolveEntitlementPlan,
45
46
  toEffectiveLimitsSnapshot: () => toEffectiveLimitsSnapshot
46
47
  });
@@ -304,6 +305,7 @@ function resolveEntitlementPlan(input, config, now) {
304
305
  __name(resolveEntitlementPlan, "resolveEntitlementPlan");
305
306
 
306
307
  // src/entitlement/limit-exceeded-error.ts
308
+ var LIMIT_EXCEEDED = "LIMIT_EXCEEDED";
307
309
  var LimitExceededError = class extends Error {
308
310
  static {
309
311
  __name(this, "LimitExceededError");
@@ -311,11 +313,16 @@ var LimitExceededError = class extends Error {
311
313
  dimension;
312
314
  max;
313
315
  used;
316
+ code = LIMIT_EXCEEDED;
314
317
  constructor(dimension, max, used) {
315
318
  super(`Limit f\xFCr ${dimension} erreicht: ${used}/${max}.`), this.dimension = dimension, this.max = max, this.used = used;
316
319
  this.name = "LimitExceededError";
317
320
  }
318
321
  };
322
+ function isLimitExceededError(err) {
323
+ return err instanceof Error && err.code === LIMIT_EXCEEDED;
324
+ }
325
+ __name(isLimitExceededError, "isLimitExceededError");
319
326
 
320
327
  // src/entitlement/service.ts
321
328
  var import_common2 = require("@nestjs/common");
@@ -800,6 +807,7 @@ EntitlementModule = _ts_decorate3([
800
807
  filterPlannedOnlyFeatures,
801
808
  hasAnyFeature,
802
809
  hasFeature,
810
+ isLimitExceededError,
803
811
  resolveEntitlementPlan,
804
812
  toEffectiveLimitsSnapshot
805
813
  });
@@ -1,4 +1,4 @@
1
- export { B as BundleVersionSnapshot, a as BusinessTypeVersionSnapshot, C as CustomLimitsShape, E as EffectiveLimits, b as EffectiveLimitsSnapshot, c as EnforceLimitInput, d as EntitlementService, L as LimitExceededError, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, e as SubscriptionLimitsInput, f as aggregateBusinessTypeQuotas, g as aggregateContractLineItemEntitlements, h as aggregateLimits, i as aggregateSubscriptionBundleQuotas, j as applyCustomLimits, k as collectBusinessTypeFeatures, l as collectSubscriptionBundleFeatures, m as filterActiveSubscriptionBundles, n as filterPlannedOnlyFeatures, o as hasAnyFeature, p as hasFeature, t as toEffectiveLimitsSnapshot } from '../aggregation-CJ3qQf92.cjs';
1
+ export { B as BundleVersionSnapshot, a as BusinessTypeVersionSnapshot, C as CustomLimitsShape, E as EffectiveLimits, b as EffectiveLimitsSnapshot, c as EnforceLimitInput, d as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, e as SubscriptionLimitsInput, f as aggregateBusinessTypeQuotas, g as aggregateContractLineItemEntitlements, h as aggregateLimits, i as aggregateSubscriptionBundleQuotas, j as applyCustomLimits, k as collectBusinessTypeFeatures, l as collectSubscriptionBundleFeatures, m as filterActiveSubscriptionBundles, n as filterPlannedOnlyFeatures, o as hasAnyFeature, p as hasFeature, t as toEffectiveLimitsSnapshot } from '../aggregation-Bt1i_whS.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';
@@ -24,6 +24,22 @@ declare function buildReplacedByIndex(features: readonly FeatureReplacesSource[]
24
24
  */
25
25
  declare function expandReplacedFeatures(granted: ReadonlySet<string>, index: ReplacedByIndex): Set<string>;
26
26
 
27
+ declare class LimitExceededError extends Error {
28
+ readonly dimension: string;
29
+ readonly max: number;
30
+ readonly used: number;
31
+ readonly code = "LIMIT_EXCEEDED";
32
+ constructor(dimension: string, max: number, used: number);
33
+ }
34
+ /**
35
+ * Realm-safe type guard (checks `code` instead of `instanceof`). The tsup
36
+ * multi-entry build duplicates this class into every sub-bundle
37
+ * (platform/billing/entitlement), so an `instanceof` between thrower and
38
+ * catcher from different entries is false — same hazard the token registry
39
+ * solves with `Symbol.for` and `isPlatformUserExistsError` solves for types.
40
+ */
41
+ declare function isLimitExceededError(err: unknown): err is LimitExceededError;
42
+
27
43
  interface EntitlementModuleOptions {
28
44
  /** Consumer implementation of the `SubscriptionRepository` interface. */
29
45
  subscriptionRepository: ProviderSpec<SubscriptionRepository>;
@@ -57,4 +73,4 @@ declare const PLAN_VERSION_REPOSITORY_TOKEN: unique symbol;
57
73
  declare const TRANSACTION_RUNNER_TOKEN: unique symbol;
58
74
  declare const ENTITLEMENT_RESOLUTION_CONFIG_TOKEN: unique symbol;
59
75
 
60
- export { ENTITLEMENT_RESOLUTION_CONFIG_TOKEN, EntitlementModule, type EntitlementModuleOptions, EntitlementResolutionConfig, PLAN_VERSION_REPOSITORY_TOKEN, type ReplacedByIndex, SUBSCRIPTION_REPOSITORY_TOKEN, TRANSACTION_RUNNER_TOKEN, buildReplacedByIndex, expandReplacedFeatures };
76
+ export { ENTITLEMENT_RESOLUTION_CONFIG_TOKEN, EntitlementModule, type EntitlementModuleOptions, EntitlementResolutionConfig, LimitExceededError, PLAN_VERSION_REPOSITORY_TOKEN, type ReplacedByIndex, SUBSCRIPTION_REPOSITORY_TOKEN, TRANSACTION_RUNNER_TOKEN, buildReplacedByIndex, expandReplacedFeatures, isLimitExceededError };