@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
@@ -9,19 +9,19 @@ import {
9
9
  StaticPlanResolver,
10
10
  TenantManifestService,
11
11
  buildTenantManifestController
12
- } from "../chunk-QJVPRD3R.js";
12
+ } from "../chunk-SG34XT7J.js";
13
13
  import "../chunk-P6MYZMXQ.js";
14
14
  import "../chunk-Q53N43LQ.js";
15
15
  import "../chunk-E56W4U2P.js";
16
16
  import "../chunk-AJ3EPELS.js";
17
17
  import "../chunk-M6CZQYPY.js";
18
- import "../chunk-YXGHPILG.js";
19
- import "../chunk-MV6LW5UB.js";
18
+ import "../chunk-K42EQPBB.js";
20
19
  import "../chunk-NYLON2VC.js";
21
20
  import "../chunk-7MLGHWKO.js";
22
21
  import "../chunk-XCZ3TTFK.js";
23
- import "../chunk-SABTXESR.js";
24
22
  import "../chunk-L4SUWH5B.js";
23
+ import "../chunk-MV6LW5UB.js";
24
+ import "../chunk-SABTXESR.js";
25
25
  import "../chunk-SHUYVCID.js";
26
26
  export {
27
27
  EnforceQuotaInterceptor,
@@ -1,4 +1,5 @@
1
- import { PendingRegistrationRepository, RegistrationOtpDelivery, UserAccountLookup, SlugAvailabilityCheck, PlanCatalogLookup, PaymentProvider, PaymentEventLog, ActivationOrchestrator, RegistrationAuditLogger, RegistrationResumeTokenSigner, RegistrationResumeDelivery, RegistrationConfiguratorLookup, RegistrationPromoPreview, RegistrationBusinessTypeLookup, PublicSignupPlan, SelectPlanInput, RegistrationAuditContext, SelectPlanResult, StartCheckoutInput, StartCheckoutResult, HandlePaymentEventInput, HandlePaymentEventResult, CleanupResult, StartRegistrationInput, StartRegistrationResult, VerifyRegistrationOtpResult, ResumeRegistrationInput, ResumeRegistrationResult, ConfiguratorCatalog, SaveRegistrationConfigInput, SaveRegistrationConfigResult, ConfiguratorPriceBreakdown, RegistrationConfigSelection } from '@saasicat/types';
1
+ import { PendingRegistrationRepository, RegistrationOtpDelivery, UserAccountLookup, SlugAvailabilityCheck, PasswordHasher, PlanCatalogLookup, PaymentProvider, PaymentEventLog, ActivationOrchestrator, RegistrationAuditLogger, RegistrationResumeTokenSigner, RegistrationResumeDelivery, RegistrationConfiguratorLookup, RegistrationPromoPreview, RegistrationBusinessTypeLookup, PublicSignupPlan, SelectPlanInput, RegistrationAuditContext, SelectPlanResult, StartCheckoutInput, StartCheckoutResult, HandlePaymentEventInput, HandlePaymentEventResult, CleanupResult, StartRegistrationInput, StartRegistrationResult, VerifyRegistrationOtpResult, ResumeRegistrationInput, ResumeRegistrationResult, ConfiguratorCatalog, SaveRegistrationConfigInput, SaveRegistrationConfigResult, ConfiguratorPriceBreakdown, RegistrationConfigSelection } from '@saasicat/types';
2
+ export { PasswordHasher } from '@saasicat/types';
2
3
  import { CanActivate, ExecutionContext, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
3
4
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
4
5
  export { CronExpression } from '@nestjs/schedule';
@@ -39,10 +40,6 @@ declare const REGISTRATION_PROMO_PREVIEW_TOKEN: unique symbol;
39
40
  declare const REGISTRATION_BUSINESS_TYPE_LOOKUP_TOKEN: unique symbol;
40
41
  /** Optionally injectable configuration — falls back to default TTLs from saas-platform-types. */
41
42
  declare const REGISTRATION_CONFIG_TOKEN: unique symbol;
42
- interface PasswordHasher {
43
- hash(plain: string): Promise<string>;
44
- verify(hash: string, plain: string): Promise<boolean>;
45
- }
46
43
 
47
44
  /**
48
45
  * Orchestrates step 1 (capture registration data) and step 2 (OTP verification)
@@ -441,4 +438,4 @@ declare function resolveModel(catalog: ConfiguratorCatalog, modelId: string): {
441
438
  yearlyNet: number;
442
439
  };
443
440
 
444
- export { ACTIVATION_ORCHESTRATOR_TOKEN, BaseIpRateLimitGuard, ContinueRegistrationDto, PASSWORD_HASHER_TOKEN, PAYMENT_EVENT_LOG_TOKEN, PAYMENT_PROVIDER_TOKEN, PENDING_REGISTRATION_REPOSITORY_TOKEN, PLAN_CATALOG_LOOKUP_TOKEN, type PasswordHasher, PaymentWebhookDto, PendingRegistrationService, PreviewRegistrationPromoDto, type PromoEvaluation, REGISTRATION_AUDIT_LOGGER_TOKEN, REGISTRATION_BUSINESS_TYPE_LOOKUP_TOKEN, REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN, REGISTRATION_CONFIG_TOKEN, REGISTRATION_OTP_DELIVERY_TOKEN, REGISTRATION_PROMO_PREVIEW_TOKEN, REGISTRATION_RESUME_BASE_URL_TOKEN, REGISTRATION_RESUME_DELIVERY_TOKEN, REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN, RegisterStartDto, RegistrationCleanupCron, RegistrationModule, type RegistrationModuleOptions, ResendRegistrationOtpDto, SLUG_AVAILABILITY_CHECK_TOKEN, SaveRegistrationConfigDto, SaveRegistrationConfigSelectionDto, SelectRegistrationPlanDto, StartRegistrationCheckoutDto, USER_ACCOUNT_LOOKUP_TOKEN, VerifyRegistrationOtpDto, computeBreakdown, generateOtpCode, hashOtpCode, resolveModel, slugify, verifyOtpCode };
441
+ export { ACTIVATION_ORCHESTRATOR_TOKEN, BaseIpRateLimitGuard, ContinueRegistrationDto, PASSWORD_HASHER_TOKEN, PAYMENT_EVENT_LOG_TOKEN, PAYMENT_PROVIDER_TOKEN, PENDING_REGISTRATION_REPOSITORY_TOKEN, PLAN_CATALOG_LOOKUP_TOKEN, PaymentWebhookDto, PendingRegistrationService, PreviewRegistrationPromoDto, type PromoEvaluation, REGISTRATION_AUDIT_LOGGER_TOKEN, REGISTRATION_BUSINESS_TYPE_LOOKUP_TOKEN, REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN, REGISTRATION_CONFIG_TOKEN, REGISTRATION_OTP_DELIVERY_TOKEN, REGISTRATION_PROMO_PREVIEW_TOKEN, REGISTRATION_RESUME_BASE_URL_TOKEN, REGISTRATION_RESUME_DELIVERY_TOKEN, REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN, RegisterStartDto, RegistrationCleanupCron, RegistrationModule, type RegistrationModuleOptions, ResendRegistrationOtpDto, SLUG_AVAILABILITY_CHECK_TOKEN, SaveRegistrationConfigDto, SaveRegistrationConfigSelectionDto, SelectRegistrationPlanDto, StartRegistrationCheckoutDto, USER_ACCOUNT_LOOKUP_TOKEN, VerifyRegistrationOtpDto, computeBreakdown, generateOtpCode, hashOtpCode, resolveModel, slugify, verifyOtpCode };
@@ -1,4 +1,5 @@
1
- import { PendingRegistrationRepository, RegistrationOtpDelivery, UserAccountLookup, SlugAvailabilityCheck, PlanCatalogLookup, PaymentProvider, PaymentEventLog, ActivationOrchestrator, RegistrationAuditLogger, RegistrationResumeTokenSigner, RegistrationResumeDelivery, RegistrationConfiguratorLookup, RegistrationPromoPreview, RegistrationBusinessTypeLookup, PublicSignupPlan, SelectPlanInput, RegistrationAuditContext, SelectPlanResult, StartCheckoutInput, StartCheckoutResult, HandlePaymentEventInput, HandlePaymentEventResult, CleanupResult, StartRegistrationInput, StartRegistrationResult, VerifyRegistrationOtpResult, ResumeRegistrationInput, ResumeRegistrationResult, ConfiguratorCatalog, SaveRegistrationConfigInput, SaveRegistrationConfigResult, ConfiguratorPriceBreakdown, RegistrationConfigSelection } from '@saasicat/types';
1
+ import { PendingRegistrationRepository, RegistrationOtpDelivery, UserAccountLookup, SlugAvailabilityCheck, PasswordHasher, PlanCatalogLookup, PaymentProvider, PaymentEventLog, ActivationOrchestrator, RegistrationAuditLogger, RegistrationResumeTokenSigner, RegistrationResumeDelivery, RegistrationConfiguratorLookup, RegistrationPromoPreview, RegistrationBusinessTypeLookup, PublicSignupPlan, SelectPlanInput, RegistrationAuditContext, SelectPlanResult, StartCheckoutInput, StartCheckoutResult, HandlePaymentEventInput, HandlePaymentEventResult, CleanupResult, StartRegistrationInput, StartRegistrationResult, VerifyRegistrationOtpResult, ResumeRegistrationInput, ResumeRegistrationResult, ConfiguratorCatalog, SaveRegistrationConfigInput, SaveRegistrationConfigResult, ConfiguratorPriceBreakdown, RegistrationConfigSelection } from '@saasicat/types';
2
+ export { PasswordHasher } from '@saasicat/types';
2
3
  import { CanActivate, ExecutionContext, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
3
4
  import { P as ProviderSpec } from '../di-CcNeq9v-.js';
4
5
  export { CronExpression } from '@nestjs/schedule';
@@ -39,10 +40,6 @@ declare const REGISTRATION_PROMO_PREVIEW_TOKEN: unique symbol;
39
40
  declare const REGISTRATION_BUSINESS_TYPE_LOOKUP_TOKEN: unique symbol;
40
41
  /** Optionally injectable configuration — falls back to default TTLs from saas-platform-types. */
41
42
  declare const REGISTRATION_CONFIG_TOKEN: unique symbol;
42
- interface PasswordHasher {
43
- hash(plain: string): Promise<string>;
44
- verify(hash: string, plain: string): Promise<boolean>;
45
- }
46
43
 
47
44
  /**
48
45
  * Orchestrates step 1 (capture registration data) and step 2 (OTP verification)
@@ -441,4 +438,4 @@ declare function resolveModel(catalog: ConfiguratorCatalog, modelId: string): {
441
438
  yearlyNet: number;
442
439
  };
443
440
 
444
- export { ACTIVATION_ORCHESTRATOR_TOKEN, BaseIpRateLimitGuard, ContinueRegistrationDto, PASSWORD_HASHER_TOKEN, PAYMENT_EVENT_LOG_TOKEN, PAYMENT_PROVIDER_TOKEN, PENDING_REGISTRATION_REPOSITORY_TOKEN, PLAN_CATALOG_LOOKUP_TOKEN, type PasswordHasher, PaymentWebhookDto, PendingRegistrationService, PreviewRegistrationPromoDto, type PromoEvaluation, REGISTRATION_AUDIT_LOGGER_TOKEN, REGISTRATION_BUSINESS_TYPE_LOOKUP_TOKEN, REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN, REGISTRATION_CONFIG_TOKEN, REGISTRATION_OTP_DELIVERY_TOKEN, REGISTRATION_PROMO_PREVIEW_TOKEN, REGISTRATION_RESUME_BASE_URL_TOKEN, REGISTRATION_RESUME_DELIVERY_TOKEN, REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN, RegisterStartDto, RegistrationCleanupCron, RegistrationModule, type RegistrationModuleOptions, ResendRegistrationOtpDto, SLUG_AVAILABILITY_CHECK_TOKEN, SaveRegistrationConfigDto, SaveRegistrationConfigSelectionDto, SelectRegistrationPlanDto, StartRegistrationCheckoutDto, USER_ACCOUNT_LOOKUP_TOKEN, VerifyRegistrationOtpDto, computeBreakdown, generateOtpCode, hashOtpCode, resolveModel, slugify, verifyOtpCode };
441
+ export { ACTIVATION_ORCHESTRATOR_TOKEN, BaseIpRateLimitGuard, ContinueRegistrationDto, PASSWORD_HASHER_TOKEN, PAYMENT_EVENT_LOG_TOKEN, PAYMENT_PROVIDER_TOKEN, PENDING_REGISTRATION_REPOSITORY_TOKEN, PLAN_CATALOG_LOOKUP_TOKEN, PaymentWebhookDto, PendingRegistrationService, PreviewRegistrationPromoDto, type PromoEvaluation, REGISTRATION_AUDIT_LOGGER_TOKEN, REGISTRATION_BUSINESS_TYPE_LOOKUP_TOKEN, REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN, REGISTRATION_CONFIG_TOKEN, REGISTRATION_OTP_DELIVERY_TOKEN, REGISTRATION_PROMO_PREVIEW_TOKEN, REGISTRATION_RESUME_BASE_URL_TOKEN, REGISTRATION_RESUME_DELIVERY_TOKEN, REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN, RegisterStartDto, RegistrationCleanupCron, RegistrationModule, type RegistrationModuleOptions, ResendRegistrationOtpDto, SLUG_AVAILABILITY_CHECK_TOKEN, SaveRegistrationConfigDto, SaveRegistrationConfigSelectionDto, SelectRegistrationPlanDto, StartRegistrationCheckoutDto, USER_ACCOUNT_LOOKUP_TOKEN, VerifyRegistrationOtpDto, computeBreakdown, generateOtpCode, hashOtpCode, resolveModel, slugify, verifyOtpCode };
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/testing/index.ts
32
32
  var testing_exports = {};
33
33
  __export(testing_exports, {
34
+ EnforceQuotaInterceptor: () => EnforceQuotaInterceptor,
34
35
  FakeBundleRepository: () => FakeBundleRepository,
35
36
  FakeBusinessTypeRepository: () => FakeBusinessTypeRepository,
36
37
  FakeMarketingProjectionRepository: () => FakeMarketingProjectionRepository,
@@ -40,6 +41,10 @@ __export(testing_exports, {
40
41
  FakeSubscriptionContractRepository: () => FakeSubscriptionContractRepository,
41
42
  FakeSubscriptionRepository: () => FakeSubscriptionRepository,
42
43
  FakeTransactionRunner: () => FakeTransactionRunner,
44
+ PLAN_RESOLVER_PORT_TOKEN: () => PLAN_RESOLVER_PORT_TOKEN,
45
+ StaticEntitlementService: () => StaticEntitlementService,
46
+ StaticFeatureGuard: () => StaticFeatureGuard,
47
+ StaticPlanResolver: () => StaticPlanResolver,
43
48
  StubAuditPort: () => StubAuditPort,
44
49
  StubMfaPort: () => StubMfaPort,
45
50
  StubRlsBypassPort: () => StubRlsBypassPort,
@@ -1141,6 +1146,7 @@ var import_common23 = require("@nestjs/common");
1141
1146
  // src/platform/saas-platform.module.ts
1142
1147
  var import_common22 = require("@nestjs/common");
1143
1148
  var import_core6 = require("@nestjs/core");
1149
+ var import_types2 = require("@saasicat/types");
1144
1150
 
1145
1151
  // src/core/di.ts
1146
1152
  function asProvider(token, impl) {
@@ -2983,6 +2989,7 @@ function assertNoReplacesCycle(index) {
2983
2989
  __name(assertNoReplacesCycle, "assertNoReplacesCycle");
2984
2990
 
2985
2991
  // src/entitlement/limit-exceeded-error.ts
2992
+ var LIMIT_EXCEEDED = "LIMIT_EXCEEDED";
2986
2993
  var LimitExceededError = class extends Error {
2987
2994
  static {
2988
2995
  __name(this, "LimitExceededError");
@@ -2990,6 +2997,7 @@ var LimitExceededError = class extends Error {
2990
2997
  dimension;
2991
2998
  max;
2992
2999
  used;
3000
+ code = LIMIT_EXCEEDED;
2993
3001
  constructor(dimension, max, used) {
2994
3002
  super(`Limit f\xFCr ${dimension} erreicht: ${used}/${max}.`), this.dimension = dimension, this.max = max, this.used = used;
2995
3003
  this.name = "LimitExceededError";
@@ -3743,30 +3751,59 @@ var SaasPlatformModule = class _SaasPlatformModule {
3743
3751
  __name(this, "SaasPlatformModule");
3744
3752
  }
3745
3753
  static forRoot(options) {
3746
- if (!options.planCatalog && !options.adapters.planCatalogReadSink) {
3747
- throw new Error("SaasPlatformModule.forRoot: entweder `planCatalog` (Quickstart) oder `adapters.planCatalogReadSink` (DB-Hydration) muss gesetzt sein.");
3754
+ const explicit = options.adapters ?? {};
3755
+ const persistence = options.persistence;
3756
+ const adapters = {
3757
+ mfa: explicit.mfa ?? persistence?.core.mfa,
3758
+ audit: explicit.audit ?? persistence?.core.audit,
3759
+ rlsBypass: explicit.rlsBypass ?? persistence?.core.rlsBypass,
3760
+ planCatalogReadSink: explicit.planCatalogReadSink ?? persistence?.planCatalogReadSink,
3761
+ planResolver: explicit.planResolver,
3762
+ subscriptionRepository: explicit.subscriptionRepository ?? persistence?.entitlement?.subscriptionRepository,
3763
+ planVersionRepository: explicit.planVersionRepository ?? persistence?.entitlement?.planVersionRepository,
3764
+ transactionRunner: explicit.transactionRunner ?? persistence?.core.transactionRunner
3765
+ };
3766
+ const missingCore = [
3767
+ "mfa",
3768
+ "audit",
3769
+ "rlsBypass"
3770
+ ].filter((key) => adapters[key] === void 0);
3771
+ if (missingCore.length) {
3772
+ throw new Error(`SaasPlatformModule.forRoot: adapters missing (provide them via \`adapters\` or a \`persistence\` bundle): ${missingCore.join(", ")}`);
3773
+ }
3774
+ if (!options.planCatalog && (!adapters.planCatalogReadSink || !options.dbCatalog)) {
3775
+ 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 }).");
3748
3776
  }
3749
3777
  if (options.entitlement) {
3750
3778
  const missing = [];
3751
- if (!options.adapters.subscriptionRepository) missing.push("subscriptionRepository");
3752
- if (!options.adapters.planVersionRepository) missing.push("planVersionRepository");
3753
- if (!options.adapters.transactionRunner) missing.push("transactionRunner");
3779
+ if (!adapters.subscriptionRepository) missing.push("subscriptionRepository");
3780
+ if (!adapters.planVersionRepository) missing.push("planVersionRepository");
3781
+ if (!adapters.transactionRunner) missing.push("transactionRunner");
3754
3782
  if (missing.length) {
3755
- throw new Error(`SaasPlatformModule.forRoot: entitlement aktiv, aber Adapter fehlen: ${missing.join(", ")}`);
3783
+ throw new Error(`SaasPlatformModule.forRoot: entitlement active, but adapters are missing: ${missing.join(", ")}`);
3784
+ }
3785
+ if (persistence) {
3786
+ (0, import_types2.assertPersistenceCapabilities)(persistence.capabilities, {
3787
+ transactions: true,
3788
+ pessimisticLocking: true
3789
+ }, "SaasPlatformModule entitlement (transactional enforceLimit)");
3756
3790
  }
3757
3791
  }
3792
+ const dbCatalog = options.dbCatalog;
3758
3793
  const planCatalogModule = options.planCatalog ? PlanCatalogModule.forRootWithCatalog(options.planCatalog, {
3759
3794
  global: true
3760
3795
  }) : PlanCatalogModule.forRoot({
3761
- projectKey: "",
3762
- currency: "",
3763
- vatRate: 0,
3764
- sink: options.adapters.planCatalogReadSink,
3796
+ projectKey: dbCatalog.projectKey,
3797
+ app: dbCatalog.app,
3798
+ currency: dbCatalog.currency,
3799
+ vatRate: dbCatalog.vatRate,
3800
+ marketing: dbCatalog.marketing,
3801
+ sink: adapters.planCatalogReadSink,
3765
3802
  imports: options.imports
3766
3803
  });
3767
3804
  const appInfo = options.app ?? {
3768
- key: options.planCatalog?.projectKey ?? "app",
3769
- version: options.planCatalog?.app?.version ?? "0.0.0"
3805
+ key: options.planCatalog?.projectKey ?? options.dbCatalog?.projectKey ?? "app",
3806
+ version: options.planCatalog?.app?.version ?? options.dbCatalog?.app?.version ?? "0.0.0"
3770
3807
  };
3771
3808
  const imports = [
3772
3809
  planCatalogModule,
@@ -3779,9 +3816,9 @@ var SaasPlatformModule = class _SaasPlatformModule {
3779
3816
  snapshotPath: options.discoverySnapshotPath === void 0 ? "var/discovery-snapshot.json" : options.discoverySnapshotPath
3780
3817
  }),
3781
3818
  AdminModule.forRoot({
3782
- mfaPort: options.adapters.mfa,
3783
- auditPort: options.adapters.audit,
3784
- rlsBypassPort: options.adapters.rlsBypass,
3819
+ mfaPort: adapters.mfa,
3820
+ auditPort: adapters.audit,
3821
+ rlsBypassPort: adapters.rlsBypass,
3785
3822
  global: true
3786
3823
  }),
3787
3824
  AdminManifestModule.forRoot({
@@ -3792,18 +3829,21 @@ var SaasPlatformModule = class _SaasPlatformModule {
3792
3829
  ];
3793
3830
  if (options.entitlement) {
3794
3831
  imports.push(EntitlementModule.forRoot({
3795
- subscriptionRepository: options.adapters.subscriptionRepository,
3796
- planVersionRepository: options.adapters.planVersionRepository,
3797
- transactionRunner: options.adapters.transactionRunner,
3798
- resolutionConfig: options.entitlement.resolutionConfig
3832
+ subscriptionRepository: adapters.subscriptionRepository,
3833
+ planVersionRepository: adapters.planVersionRepository,
3834
+ transactionRunner: adapters.transactionRunner,
3835
+ resolutionConfig: options.entitlement.resolutionConfig,
3836
+ subscriptionContractRepository: persistence?.entitlement?.subscriptionContractRepository,
3837
+ subscriptionBundleRepository: persistence?.entitlement?.subscriptionBundleRepository,
3838
+ bundleRepository: persistence?.entitlement?.bundleRepository
3799
3839
  }));
3800
3840
  }
3801
3841
  const lightweightProviders = [];
3802
3842
  const lightweightExports = [];
3803
- const hasResolver = !!options.adapters.planResolver;
3843
+ const hasResolver = !!adapters.planResolver;
3804
3844
  const hasFallback = !!options.defaultPlanId;
3805
3845
  if (hasResolver || hasFallback) {
3806
- lightweightProviders.push(hasResolver ? asProvider(PLAN_RESOLVER_PORT_TOKEN, options.adapters.planResolver) : {
3846
+ lightweightProviders.push(hasResolver ? asProvider(PLAN_RESOLVER_PORT_TOKEN, adapters.planResolver) : {
3807
3847
  provide: PLAN_RESOLVER_PORT_TOKEN,
3808
3848
  useValue: new StaticPlanResolver(options.defaultPlanId)
3809
3849
  }, StaticEntitlementService, StaticFeatureGuard, EnforceQuotaInterceptor, ...options.quotaProviders ?? [], {
@@ -3837,11 +3877,13 @@ var SaasPlatformModule = class _SaasPlatformModule {
3837
3877
  PlanCatalogModule,
3838
3878
  DiscoveryModule,
3839
3879
  AdminModule,
3880
+ // ADMIN_MANIFEST_CONFIG travels transitively: re-exporting an
3881
+ // imported module's token directly is an UnknownExportException
3882
+ // at boot — the module export below already carries it.
3840
3883
  AdminManifestModule,
3841
3884
  ...options.entitlement ? [
3842
3885
  EntitlementModule
3843
3886
  ] : [],
3844
- ADMIN_MANIFEST_CONFIG,
3845
3887
  ...lightweightExports
3846
3888
  ],
3847
3889
  global: true
@@ -3926,6 +3968,7 @@ function createSaasPlatformTestModule(options) {
3926
3968
  __name(createSaasPlatformTestModule, "createSaasPlatformTestModule");
3927
3969
  // Annotate the CommonJS export names for ESM import in node:
3928
3970
  0 && (module.exports = {
3971
+ EnforceQuotaInterceptor,
3929
3972
  FakeBundleRepository,
3930
3973
  FakeBusinessTypeRepository,
3931
3974
  FakeMarketingProjectionRepository,
@@ -3935,6 +3978,10 @@ __name(createSaasPlatformTestModule, "createSaasPlatformTestModule");
3935
3978
  FakeSubscriptionContractRepository,
3936
3979
  FakeSubscriptionRepository,
3937
3980
  FakeTransactionRunner,
3981
+ PLAN_RESOLVER_PORT_TOKEN,
3982
+ StaticEntitlementService,
3983
+ StaticFeatureGuard,
3984
+ StaticPlanResolver,
3938
3985
  StubAuditPort,
3939
3986
  StubMfaPort,
3940
3987
  StubRlsBypassPort,
@@ -1,11 +1,13 @@
1
1
  import { BundleRepository, BundleRow, BundleVersionRow, BundleListFilter, CreateBundleData, UpdateBundleData, CreateBundleVersionDraftData, UpdateBundleVersionDraftData, VersionChange, BusinessTypeRepository, BusinessTypeRow, BusinessTypeVersionRow, BusinessTypeListFilter, CreateBusinessTypeData, UpdateBusinessTypeData, CreateBusinessTypeVersionDraftData, UpdateBusinessTypeVersionDraftData, MarketingProjectionRepository, MarketingProjectionRow, MarketingProjectionFilter, CreateMarketingProjectionData, UpdateMarketingProjectionData, PlanRepository, PlanRow, PlanVersionRow, PlanListFilter, CreatePlanData, UpdatePlanData, CreatePlanVersionDraftData, UpdatePlanVersionDraftData, PlanVersionRepository, PlanVersionRecord, TransactionContext, SubscriptionBundleRepository, SubscriptionBundleRecord, CreateSubscriptionBundleData, CancelSubscriptionBundleData, SubscriptionContractRepository, SubscriptionContractFilter, SubscriptionContractRecord, CreateSubscriptionContractData, TerminateSubscriptionContractData, SubscriptionRepository, SubscriptionRecord, TransactionRunner, PlanCatalog, QuotaProvider } from '@saasicat/types';
2
2
  import { Type, DynamicModule } from '@nestjs/common';
3
- import { S as SaasPlatformModuleOptions } from '../saas-platform.module-CgZ2omgg.cjs';
3
+ import { c as SaasPlatformAdapters } from '../enforce-quota.interceptor-HmdZFg41.cjs';
4
+ export { E as EnforceQuotaInterceptor, P as PLAN_RESOLVER_PORT_TOKEN, S as StaticEntitlementService, g as StaticFeatureGuard, i as StaticPlanResolver } from '../enforce-quota.interceptor-HmdZFg41.cjs';
4
5
  import '../di-CcNeq9v-.cjs';
5
- import '../admin-manifest.config-DyrQNT7M.cjs';
6
- import '../discovery.scanner-CUYLKlYT.cjs';
6
+ import '../admin-manifest.config-DxTfZ8-L.cjs';
7
+ import '../discovery.scanner-DLgEvuoy.cjs';
7
8
  import '@nestjs/core';
8
9
  import '../plan-resolution-CFCoUkrE.cjs';
10
+ import 'rxjs';
9
11
 
10
12
  /**
11
13
  * In-memory FakeSubscriptionRepository — stores subscriptions by
@@ -263,11 +265,7 @@ interface CreateSaasPlatformTestModuleOptions {
263
265
  /** QuotaProvider classes for the `EnforceQuotaInterceptor`. */
264
266
  quotaProviders?: Array<Type<QuotaProvider>>;
265
267
  /** Overrides — if the test needs a different adapter. */
266
- overrides?: Partial<{
267
- mfa: SaasPlatformModuleOptions['adapters']['mfa'];
268
- audit: SaasPlatformModuleOptions['adapters']['audit'];
269
- rlsBypass: SaasPlatformModuleOptions['adapters']['rlsBypass'];
270
- }>;
268
+ overrides?: Partial<Pick<SaasPlatformAdapters, 'mfa' | 'audit' | 'rlsBypass'>>;
271
269
  }
272
270
  /**
273
271
  * Returns a `DynamicModule` that sets up the SaasPlatformModule with stub
@@ -1,11 +1,13 @@
1
1
  import { BundleRepository, BundleRow, BundleVersionRow, BundleListFilter, CreateBundleData, UpdateBundleData, CreateBundleVersionDraftData, UpdateBundleVersionDraftData, VersionChange, BusinessTypeRepository, BusinessTypeRow, BusinessTypeVersionRow, BusinessTypeListFilter, CreateBusinessTypeData, UpdateBusinessTypeData, CreateBusinessTypeVersionDraftData, UpdateBusinessTypeVersionDraftData, MarketingProjectionRepository, MarketingProjectionRow, MarketingProjectionFilter, CreateMarketingProjectionData, UpdateMarketingProjectionData, PlanRepository, PlanRow, PlanVersionRow, PlanListFilter, CreatePlanData, UpdatePlanData, CreatePlanVersionDraftData, UpdatePlanVersionDraftData, PlanVersionRepository, PlanVersionRecord, TransactionContext, SubscriptionBundleRepository, SubscriptionBundleRecord, CreateSubscriptionBundleData, CancelSubscriptionBundleData, SubscriptionContractRepository, SubscriptionContractFilter, SubscriptionContractRecord, CreateSubscriptionContractData, TerminateSubscriptionContractData, SubscriptionRepository, SubscriptionRecord, TransactionRunner, PlanCatalog, QuotaProvider } from '@saasicat/types';
2
2
  import { Type, DynamicModule } from '@nestjs/common';
3
- import { S as SaasPlatformModuleOptions } from '../saas-platform.module-DT9TnCzk.js';
3
+ import { c as SaasPlatformAdapters } from '../enforce-quota.interceptor-3HmbeHTM.js';
4
+ export { E as EnforceQuotaInterceptor, P as PLAN_RESOLVER_PORT_TOKEN, S as StaticEntitlementService, g as StaticFeatureGuard, i as StaticPlanResolver } from '../enforce-quota.interceptor-3HmbeHTM.js';
4
5
  import '../di-CcNeq9v-.js';
5
- import '../admin-manifest.config-DyrQNT7M.js';
6
- import '../discovery.scanner-CUYLKlYT.js';
6
+ import '../admin-manifest.config-DxTfZ8-L.js';
7
+ import '../discovery.scanner-DLgEvuoy.js';
7
8
  import '@nestjs/core';
8
9
  import '../plan-resolution-CFCoUkrE.js';
10
+ import 'rxjs';
9
11
 
10
12
  /**
11
13
  * In-memory FakeSubscriptionRepository — stores subscriptions by
@@ -263,11 +265,7 @@ interface CreateSaasPlatformTestModuleOptions {
263
265
  /** QuotaProvider classes for the `EnforceQuotaInterceptor`. */
264
266
  quotaProviders?: Array<Type<QuotaProvider>>;
265
267
  /** Overrides — if the test needs a different adapter. */
266
- overrides?: Partial<{
267
- mfa: SaasPlatformModuleOptions['adapters']['mfa'];
268
- audit: SaasPlatformModuleOptions['adapters']['audit'];
269
- rlsBypass: SaasPlatformModuleOptions['adapters']['rlsBypass'];
270
- }>;
268
+ overrides?: Partial<Pick<SaasPlatformAdapters, 'mfa' | 'audit' | 'rlsBypass'>>;
271
269
  }
272
270
  /**
273
271
  * Returns a `DynamicModule` that sets up the SaasPlatformModule with stub
@@ -1,18 +1,23 @@
1
1
  import {
2
- SaasPlatformModule
3
- } from "../chunk-QJVPRD3R.js";
2
+ EnforceQuotaInterceptor,
3
+ PLAN_RESOLVER_PORT_TOKEN,
4
+ SaasPlatformModule,
5
+ StaticEntitlementService,
6
+ StaticFeatureGuard,
7
+ StaticPlanResolver
8
+ } from "../chunk-SG34XT7J.js";
4
9
  import "../chunk-P6MYZMXQ.js";
5
10
  import "../chunk-Q53N43LQ.js";
6
11
  import "../chunk-E56W4U2P.js";
7
12
  import "../chunk-AJ3EPELS.js";
8
13
  import "../chunk-M6CZQYPY.js";
9
- import "../chunk-YXGHPILG.js";
10
- import "../chunk-MV6LW5UB.js";
14
+ import "../chunk-K42EQPBB.js";
11
15
  import "../chunk-NYLON2VC.js";
12
16
  import "../chunk-7MLGHWKO.js";
13
17
  import "../chunk-XCZ3TTFK.js";
14
- import "../chunk-SABTXESR.js";
15
18
  import "../chunk-L4SUWH5B.js";
19
+ import "../chunk-MV6LW5UB.js";
20
+ import "../chunk-SABTXESR.js";
16
21
  import {
17
22
  __name
18
23
  } from "../chunk-SHUYVCID.js";
@@ -1179,6 +1184,7 @@ function createSaasPlatformTestModule(options) {
1179
1184
  }
1180
1185
  __name(createSaasPlatformTestModule, "createSaasPlatformTestModule");
1181
1186
  export {
1187
+ EnforceQuotaInterceptor,
1182
1188
  FakeBundleRepository,
1183
1189
  FakeBusinessTypeRepository,
1184
1190
  FakeMarketingProjectionRepository,
@@ -1188,6 +1194,10 @@ export {
1188
1194
  FakeSubscriptionContractRepository,
1189
1195
  FakeSubscriptionRepository,
1190
1196
  FakeTransactionRunner,
1197
+ PLAN_RESOLVER_PORT_TOKEN,
1198
+ StaticEntitlementService,
1199
+ StaticFeatureGuard,
1200
+ StaticPlanResolver,
1191
1201
  StubAuditPort,
1192
1202
  StubMfaPort,
1193
1203
  StubRlsBypassPort,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasicat/nest",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "NestJS implementation of the SaaS platform: billing, promo codes, admin backend, audit, MFA, adapter ports.",
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.2.1",
141
- "@saasicat/types": "^0.2.1"
140
+ "@saasicat/spec": "^0.4.0",
141
+ "@saasicat/types": "^0.4.0"
142
142
  },
143
143
  "peerDependencies": {
144
144
  "@nestjs/common": "^11.0.0",
@@ -152,12 +152,14 @@
152
152
  "@nestjs/common": "^11.0.0",
153
153
  "@nestjs/core": "^11.0.0",
154
154
  "@nestjs/schedule": "^6.0.0",
155
+ "@nestjs/testing": "^11.1.28",
155
156
  "@swc/core": "^1.15.33",
156
157
  "@types/js-yaml": "^4.0.9",
157
158
  "@types/node": "^25.6.0",
158
159
  "@types/qrcode": "^1.5.5",
159
160
  "class-transformer": "^0.5.1",
160
161
  "class-validator": "^0.14.0",
162
+ "reflect-metadata": "^0.2.2",
161
163
  "rxjs": "^7.0.0",
162
164
  "tsup": "^8.0.0",
163
165
  "typescript": "^6.0.0",
@@ -5,13 +5,13 @@ import {
5
5
  classifyBundleVersionDiff,
6
6
  classifyPlanDiff
7
7
  } from "./chunk-WPUVJRIN.js";
8
+ import {
9
+ AdminAuditService
10
+ } from "./chunk-E56W4U2P.js";
8
11
  import {
9
12
  DiscoverySnapshotNotFoundError,
10
13
  loadDiscoverySnapshotFromFile
11
14
  } from "./chunk-ABB2CRAS.js";
12
- import {
13
- AdminAuditService
14
- } from "./chunk-E56W4U2P.js";
15
15
  import {
16
16
  DiscoveryScanner
17
17
  } from "./chunk-M6CZQYPY.js";
@@ -29,12 +29,12 @@ import {
29
29
  PLAN_REPOSITORY_TOKEN,
30
30
  PROMOTION_REPOSITORY_TOKEN
31
31
  } from "./chunk-XCZ3TTFK.js";
32
- import {
33
- asProvider
34
- } from "./chunk-SABTXESR.js";
35
32
  import {
36
33
  DISCOVERY_SNAPSHOT_TOKEN
37
34
  } from "./chunk-L4SUWH5B.js";
35
+ import {
36
+ asProvider
37
+ } from "./chunk-SABTXESR.js";
38
38
  import {
39
39
  __name
40
40
  } from "./chunk-SHUYVCID.js";