@saasicat/nest 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/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 +12 -12
  11. package/dist/catalog/index.d.cts +1 -1
  12. package/dist/catalog/index.d.ts +1 -1
  13. package/dist/catalog/index.js +3 -3
  14. package/dist/{chunk-YXGHPILG.js → chunk-K42EQPBB.js} +14 -7
  15. package/dist/{chunk-QJVPRD3R.js → chunk-SG34XT7J.js} +61 -27
  16. package/dist/{chunk-RIGLQ4BV.js → chunk-VHEHZMHB.js} +21 -16
  17. package/dist/discovery/index.d.cts +2 -2
  18. package/dist/discovery/index.d.ts +2 -2
  19. package/dist/discovery/index.js +4 -4
  20. package/dist/{discovery.scanner-CUYLKlYT.d.cts → discovery.scanner-DLgEvuoy.d.cts} +1 -1
  21. package/dist/{discovery.scanner-CUYLKlYT.d.ts → discovery.scanner-DLgEvuoy.d.ts} +1 -1
  22. package/dist/{saas-platform.module-DT9TnCzk.d.ts → enforce-quota.interceptor-3HmbeHTM.d.ts} +93 -15
  23. package/dist/{saas-platform.module-CgZ2omgg.d.cts → enforce-quota.interceptor-HmdZFg41.d.cts} +93 -15
  24. package/dist/entitlement/index.cjs +8 -0
  25. package/dist/entitlement/index.d.cts +18 -2
  26. package/dist/entitlement/index.d.ts +18 -2
  27. package/dist/entitlement/index.js +5 -3
  28. package/dist/index.cjs +29 -16
  29. package/dist/index.d.cts +6 -6
  30. package/dist/index.d.ts +6 -6
  31. package/dist/index.js +81 -79
  32. package/dist/platform/index.cjs +59 -22
  33. package/dist/platform/index.d.cts +9 -62
  34. package/dist/platform/index.d.ts +9 -62
  35. package/dist/platform/index.js +4 -4
  36. package/dist/registration/index.d.cts +3 -6
  37. package/dist/registration/index.d.ts +3 -6
  38. package/dist/testing/index.cjs +69 -22
  39. package/dist/testing/index.d.cts +6 -8
  40. package/dist/testing/index.d.ts +6 -8
  41. package/dist/testing/index.js +15 -5
  42. package/package.json +5 -3
  43. package/dist/{chunk-V7HUZ6UQ.js → chunk-FN65XZKH.js} +6 -6
@@ -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,9 +57,12 @@ import {
57
57
  periodEndWithMinLead,
58
58
  resolveBundleCancelEffectiveAt,
59
59
  resolveBundlePriceNet
60
- } from "../chunk-RIGLQ4BV.js";
61
- import "../chunk-ZL4LLE2Z.js";
60
+ } from "../chunk-VHEHZMHB.js";
62
61
  import "../chunk-2PNX2QL2.js";
62
+ import {
63
+ REQUIRE_FEATURE_KEY,
64
+ RequireFeature
65
+ } from "../chunk-Q53N43LQ.js";
63
66
  import {
64
67
  AUDIT_CONTEXT_RESOLVER_TOKEN,
65
68
  PENDING_PLAN_QUERY_PORT_TOKEN,
@@ -74,17 +77,18 @@ import {
74
77
  classifyBundleVersionDiff,
75
78
  classifyPlanDiff
76
79
  } from "../chunk-WPUVJRIN.js";
80
+ import "../chunk-E56W4U2P.js";
77
81
  import "../chunk-MDIZUVIK.js";
78
82
  import "../chunk-2FR6ZL7R.js";
79
- import {
80
- REQUIRE_FEATURE_KEY,
81
- RequireFeature
82
- } from "../chunk-Q53N43LQ.js";
83
- import "../chunk-E56W4U2P.js";
84
83
  import {
85
84
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
86
85
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN
87
- } from "../chunk-YXGHPILG.js";
86
+ } from "../chunk-K42EQPBB.js";
87
+ import "../chunk-NYLON2VC.js";
88
+ import "../chunk-7MLGHWKO.js";
89
+ import "../chunk-XCZ3TTFK.js";
90
+ import "../chunk-L4SUWH5B.js";
91
+ import "../chunk-ZL4LLE2Z.js";
88
92
  import {
89
93
  PLAN_CATALOG_READ_SINK_TOKEN,
90
94
  PLAN_CATALOG_TOKEN,
@@ -100,11 +104,7 @@ import {
100
104
  isFeatureInPlan,
101
105
  isFeaturePlannedOnly
102
106
  } from "../chunk-MV6LW5UB.js";
103
- import "../chunk-NYLON2VC.js";
104
- import "../chunk-7MLGHWKO.js";
105
- import "../chunk-XCZ3TTFK.js";
106
107
  import "../chunk-SABTXESR.js";
107
- import "../chunk-L4SUWH5B.js";
108
108
  import "../chunk-SHUYVCID.js";
109
109
  export {
110
110
  AUDIT_CONTEXT_RESOLVER_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';
@@ -63,10 +63,10 @@ import {
63
63
  validateBusinessTypeDraft,
64
64
  validatePlanDraft,
65
65
  validateSeedAgainstSnapshot
66
- } from "../chunk-V7HUZ6UQ.js";
66
+ } from "../chunk-FN65XZKH.js";
67
67
  import "../chunk-WPUVJRIN.js";
68
- import "../chunk-ABB2CRAS.js";
69
68
  import "../chunk-E56W4U2P.js";
69
+ import "../chunk-ABB2CRAS.js";
70
70
  import "../chunk-M6CZQYPY.js";
71
71
  import "../chunk-7MLGHWKO.js";
72
72
  import {
@@ -79,8 +79,8 @@ import {
79
79
  PLAN_REPOSITORY_TOKEN,
80
80
  PROMOTION_REPOSITORY_TOKEN
81
81
  } from "../chunk-XCZ3TTFK.js";
82
- import "../chunk-SABTXESR.js";
83
82
  import "../chunk-L4SUWH5B.js";
83
+ import "../chunk-SABTXESR.js";
84
84
  import "../chunk-SHUYVCID.js";
85
85
  export {
86
86
  ADVISORY_STRICT_MODE_CODES,
@@ -1,7 +1,3 @@
1
- import {
2
- PLAN_CATALOG_TOKEN,
3
- isFeaturePlannedOnly
4
- } from "./chunk-MV6LW5UB.js";
5
1
  import {
6
2
  SUBSCRIPTION_CONTRACT_REPOSITORY_TOKEN
7
3
  } from "./chunk-NYLON2VC.js";
@@ -14,12 +10,16 @@ import {
14
10
  import {
15
11
  BUNDLE_REPOSITORY_TOKEN
16
12
  } from "./chunk-XCZ3TTFK.js";
17
- import {
18
- asProvider
19
- } from "./chunk-SABTXESR.js";
20
13
  import {
21
14
  DISCOVERY_SNAPSHOT_TOKEN
22
15
  } from "./chunk-L4SUWH5B.js";
16
+ import {
17
+ PLAN_CATALOG_TOKEN,
18
+ isFeaturePlannedOnly
19
+ } from "./chunk-MV6LW5UB.js";
20
+ import {
21
+ asProvider
22
+ } from "./chunk-SABTXESR.js";
23
23
  import {
24
24
  __name
25
25
  } from "./chunk-SHUYVCID.js";
@@ -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,10 @@ import {
12
11
  import {
13
12
  EntitlementModule,
14
13
  LimitExceededError
15
- } from "./chunk-YXGHPILG.js";
14
+ } from "./chunk-K42EQPBB.js";
15
+ import {
16
+ ENFORCE_QUOTA_KEY
17
+ } from "./chunk-L4SUWH5B.js";
16
18
  import {
17
19
  PLAN_CATALOG_TOKEN,
18
20
  PlanCatalogModule
@@ -20,9 +22,6 @@ import {
20
22
  import {
21
23
  asProvider
22
24
  } from "./chunk-SABTXESR.js";
23
- import {
24
- ENFORCE_QUOTA_KEY
25
- } from "./chunk-L4SUWH5B.js";
26
25
  import {
27
26
  __name
28
27
  } from "./chunk-SHUYVCID.js";
@@ -406,6 +405,7 @@ __name(buildTenantManifestController, "buildTenantManifestController");
406
405
  // src/platform/saas-platform.module.ts
407
406
  import { Module } from "@nestjs/common";
408
407
  import { APP_GUARD, APP_INTERCEPTOR } from "@nestjs/core";
408
+ import { assertPersistenceCapabilities } from "@saasicat/types";
409
409
  function _ts_decorate6(decorators, target, key, desc) {
410
410
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
411
411
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -450,30 +450,59 @@ var SaasPlatformModule = class _SaasPlatformModule {
450
450
  __name(this, "SaasPlatformModule");
451
451
  }
452
452
  static forRoot(options) {
453
- if (!options.planCatalog && !options.adapters.planCatalogReadSink) {
454
- throw new Error("SaasPlatformModule.forRoot: entweder `planCatalog` (Quickstart) oder `adapters.planCatalogReadSink` (DB-Hydration) muss gesetzt sein.");
453
+ const explicit = options.adapters ?? {};
454
+ const persistence = options.persistence;
455
+ const adapters = {
456
+ mfa: explicit.mfa ?? persistence?.core.mfa,
457
+ audit: explicit.audit ?? persistence?.core.audit,
458
+ rlsBypass: explicit.rlsBypass ?? persistence?.core.rlsBypass,
459
+ planCatalogReadSink: explicit.planCatalogReadSink ?? persistence?.planCatalogReadSink,
460
+ planResolver: explicit.planResolver,
461
+ subscriptionRepository: explicit.subscriptionRepository ?? persistence?.entitlement?.subscriptionRepository,
462
+ planVersionRepository: explicit.planVersionRepository ?? persistence?.entitlement?.planVersionRepository,
463
+ transactionRunner: explicit.transactionRunner ?? persistence?.core.transactionRunner
464
+ };
465
+ const missingCore = [
466
+ "mfa",
467
+ "audit",
468
+ "rlsBypass"
469
+ ].filter((key) => adapters[key] === void 0);
470
+ if (missingCore.length) {
471
+ throw new Error(`SaasPlatformModule.forRoot: adapters missing (provide them via \`adapters\` or a \`persistence\` bundle): ${missingCore.join(", ")}`);
472
+ }
473
+ if (!options.planCatalog && (!adapters.planCatalogReadSink || !options.dbCatalog)) {
474
+ throw new Error("SaasPlatformModule.forRoot: either set `planCatalog` (quickstart YAML path) or, for DB hydration, BOTH a planCatalogReadSink (`adapters`/`persistence`) AND `dbCatalog` ({ projectKey, currency, vatRate }).");
455
475
  }
456
476
  if (options.entitlement) {
457
477
  const missing = [];
458
- if (!options.adapters.subscriptionRepository) missing.push("subscriptionRepository");
459
- if (!options.adapters.planVersionRepository) missing.push("planVersionRepository");
460
- if (!options.adapters.transactionRunner) missing.push("transactionRunner");
478
+ if (!adapters.subscriptionRepository) missing.push("subscriptionRepository");
479
+ if (!adapters.planVersionRepository) missing.push("planVersionRepository");
480
+ if (!adapters.transactionRunner) missing.push("transactionRunner");
461
481
  if (missing.length) {
462
- throw new Error(`SaasPlatformModule.forRoot: entitlement aktiv, aber Adapter fehlen: ${missing.join(", ")}`);
482
+ throw new Error(`SaasPlatformModule.forRoot: entitlement active, but adapters are missing: ${missing.join(", ")}`);
483
+ }
484
+ if (persistence) {
485
+ assertPersistenceCapabilities(persistence.capabilities, {
486
+ transactions: true,
487
+ pessimisticLocking: true
488
+ }, "SaasPlatformModule entitlement (transactional enforceLimit)");
463
489
  }
464
490
  }
491
+ const dbCatalog = options.dbCatalog;
465
492
  const planCatalogModule = options.planCatalog ? PlanCatalogModule.forRootWithCatalog(options.planCatalog, {
466
493
  global: true
467
494
  }) : PlanCatalogModule.forRoot({
468
- projectKey: "",
469
- currency: "",
470
- vatRate: 0,
471
- sink: options.adapters.planCatalogReadSink,
495
+ projectKey: dbCatalog.projectKey,
496
+ app: dbCatalog.app,
497
+ currency: dbCatalog.currency,
498
+ vatRate: dbCatalog.vatRate,
499
+ marketing: dbCatalog.marketing,
500
+ sink: adapters.planCatalogReadSink,
472
501
  imports: options.imports
473
502
  });
474
503
  const appInfo = options.app ?? {
475
- key: options.planCatalog?.projectKey ?? "app",
476
- version: options.planCatalog?.app?.version ?? "0.0.0"
504
+ key: options.planCatalog?.projectKey ?? options.dbCatalog?.projectKey ?? "app",
505
+ version: options.planCatalog?.app?.version ?? options.dbCatalog?.app?.version ?? "0.0.0"
477
506
  };
478
507
  const imports = [
479
508
  planCatalogModule,
@@ -486,9 +515,9 @@ var SaasPlatformModule = class _SaasPlatformModule {
486
515
  snapshotPath: options.discoverySnapshotPath === void 0 ? "var/discovery-snapshot.json" : options.discoverySnapshotPath
487
516
  }),
488
517
  AdminModule.forRoot({
489
- mfaPort: options.adapters.mfa,
490
- auditPort: options.adapters.audit,
491
- rlsBypassPort: options.adapters.rlsBypass,
518
+ mfaPort: adapters.mfa,
519
+ auditPort: adapters.audit,
520
+ rlsBypassPort: adapters.rlsBypass,
492
521
  global: true
493
522
  }),
494
523
  AdminManifestModule.forRoot({
@@ -499,18 +528,21 @@ var SaasPlatformModule = class _SaasPlatformModule {
499
528
  ];
500
529
  if (options.entitlement) {
501
530
  imports.push(EntitlementModule.forRoot({
502
- subscriptionRepository: options.adapters.subscriptionRepository,
503
- planVersionRepository: options.adapters.planVersionRepository,
504
- transactionRunner: options.adapters.transactionRunner,
505
- resolutionConfig: options.entitlement.resolutionConfig
531
+ subscriptionRepository: adapters.subscriptionRepository,
532
+ planVersionRepository: adapters.planVersionRepository,
533
+ transactionRunner: adapters.transactionRunner,
534
+ resolutionConfig: options.entitlement.resolutionConfig,
535
+ subscriptionContractRepository: persistence?.entitlement?.subscriptionContractRepository,
536
+ subscriptionBundleRepository: persistence?.entitlement?.subscriptionBundleRepository,
537
+ bundleRepository: persistence?.entitlement?.bundleRepository
506
538
  }));
507
539
  }
508
540
  const lightweightProviders = [];
509
541
  const lightweightExports = [];
510
- const hasResolver = !!options.adapters.planResolver;
542
+ const hasResolver = !!adapters.planResolver;
511
543
  const hasFallback = !!options.defaultPlanId;
512
544
  if (hasResolver || hasFallback) {
513
- lightweightProviders.push(hasResolver ? asProvider(PLAN_RESOLVER_PORT_TOKEN, options.adapters.planResolver) : {
545
+ lightweightProviders.push(hasResolver ? asProvider(PLAN_RESOLVER_PORT_TOKEN, adapters.planResolver) : {
514
546
  provide: PLAN_RESOLVER_PORT_TOKEN,
515
547
  useValue: new StaticPlanResolver(options.defaultPlanId)
516
548
  }, StaticEntitlementService, StaticFeatureGuard, EnforceQuotaInterceptor, ...options.quotaProviders ?? [], {
@@ -544,11 +576,13 @@ var SaasPlatformModule = class _SaasPlatformModule {
544
576
  PlanCatalogModule,
545
577
  DiscoveryModule,
546
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.
547
582
  AdminManifestModule,
548
583
  ...options.entitlement ? [
549
584
  EntitlementModule
550
585
  ] : [],
551
- ADMIN_MANIFEST_CONFIG,
552
586
  ...lightweightExports
553
587
  ],
554
588
  global: true
@@ -1,9 +1,9 @@
1
- import {
2
- PromoCodesService
3
- } from "./chunk-ZL4LLE2Z.js";
4
1
  import {
5
2
  SubscriptionContractService
6
3
  } from "./chunk-2PNX2QL2.js";
4
+ import {
5
+ REQUIRE_FEATURE_KEY
6
+ } from "./chunk-Q53N43LQ.js";
7
7
  import {
8
8
  AUDIT_CONTEXT_RESOLVER_TOKEN,
9
9
  PENDING_PLAN_QUERY_PORT_TOKEN,
@@ -16,25 +16,16 @@ import {
16
16
  USER_EMAIL_RESOLVER_TOKEN,
17
17
  USER_ID_RESOLVER_TOKEN
18
18
  } from "./chunk-WPUVJRIN.js";
19
- import {
20
- REQUIRE_FEATURE_KEY
21
- } from "./chunk-Q53N43LQ.js";
22
19
  import {
23
20
  AdminAuditService
24
21
  } from "./chunk-E56W4U2P.js";
25
22
  import {
26
23
  EntitlementService,
27
- LimitExceededError,
28
24
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
29
25
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN,
26
+ isLimitExceededError,
30
27
  toEffectiveLimitsSnapshot
31
- } from "./chunk-YXGHPILG.js";
32
- import {
33
- PLAN_CATALOG_TOKEN,
34
- findPlan,
35
- getMarketedPlans,
36
- getPlanPriceNet
37
- } from "./chunk-MV6LW5UB.js";
28
+ } from "./chunk-K42EQPBB.js";
38
29
  import {
39
30
  SUBSCRIPTION_CONTRACT_REPOSITORY_TOKEN
40
31
  } from "./chunk-NYLON2VC.js";
@@ -43,6 +34,15 @@ import {
43
34
  CATALOG_ENTRY_REPOSITORY_TOKEN,
44
35
  PLAN_REPOSITORY_TOKEN
45
36
  } from "./chunk-XCZ3TTFK.js";
37
+ import {
38
+ PromoCodesService
39
+ } from "./chunk-ZL4LLE2Z.js";
40
+ import {
41
+ PLAN_CATALOG_TOKEN,
42
+ findPlan,
43
+ getMarketedPlans,
44
+ getPlanPriceNet
45
+ } from "./chunk-MV6LW5UB.js";
46
46
  import {
47
47
  asProvider
48
48
  } from "./chunk-SABTXESR.js";
@@ -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
  /**
@@ -5,14 +5,14 @@ import {
5
5
  RequiresCapability,
6
6
  runHeadlessDiscoveryScan
7
7
  } from "../chunk-HRU3CP57.js";
8
- import {
9
- DiscoverySnapshotNotFoundError,
10
- loadDiscoverySnapshotFromFile
11
- } from "../chunk-ABB2CRAS.js";
12
8
  import {
13
9
  DiscoveryModule,
14
10
  buildDiscoveryController
15
11
  } from "../chunk-AJ3EPELS.js";
12
+ import {
13
+ DiscoverySnapshotNotFoundError,
14
+ loadDiscoverySnapshotFromFile
15
+ } from "../chunk-ABB2CRAS.js";
16
16
  import {
17
17
  DISCOVERY_APP_INFO_TOKEN,
18
18
  DISCOVERY_SNAPSHOT_PATH_TOKEN,