@saasicat/nest 0.3.0 → 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 (41) 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-47JT54VW.js → chunk-SG34XT7J.js} +7 -6
  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-k1DQg4De.d.ts → enforce-quota.interceptor-3HmbeHTM.d.ts} +59 -4
  23. package/dist/{saas-platform.module-C7-H9eYB.d.cts → enforce-quota.interceptor-HmdZFg41.d.cts} +59 -4
  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 +4 -4
  30. package/dist/index.d.ts +4 -4
  31. package/dist/index.js +81 -79
  32. package/dist/platform/index.cjs +5 -1
  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/testing/index.cjs +15 -1
  37. package/dist/testing/index.d.cts +5 -3
  38. package/dist/testing/index.d.ts +5 -3
  39. package/dist/testing/index.js +15 -5
  40. package/package.json +5 -3
  41. package/dist/{chunk-V7HUZ6UQ.js → chunk-FN65XZKH.js} +6 -6
package/dist/index.js CHANGED
@@ -1,12 +1,3 @@
1
- import {
2
- PreviewPromoCodeDto,
3
- PromoCodeExpirer,
4
- PromoCodePublicController,
5
- PromoCodeRateLimitGuard,
6
- PromoCodesModule,
7
- hashIp,
8
- ipFingerprint
9
- } from "./chunk-2VNZYRDV.js";
10
1
  import {
11
2
  ACTIVATION_ORCHESTRATOR_TOKEN,
12
3
  BaseIpRateLimitGuard,
@@ -56,6 +47,21 @@ import {
56
47
  PROMO_CODE_STATS_PORT_TOKEN,
57
48
  SUBSCRIPTION_STATS_PORT_TOKEN
58
49
  } from "./chunk-YNEW3L63.js";
50
+ import {
51
+ ADMIN_MANIFEST_CONFIG,
52
+ AdminBypassRlsInterceptor,
53
+ AdminManifestModule,
54
+ AdminManifestService,
55
+ AdminModule,
56
+ AdminPublicBootController,
57
+ MfaGuard,
58
+ MfaService,
59
+ PLATFORM_CORE_CONTRIBUTION_TOKEN,
60
+ PLATFORM_CORE_MANIFEST_CONTRIBUTION,
61
+ REQUIRE_MFA_KEY,
62
+ RequireMfa,
63
+ SuperAdminGuard
64
+ } from "./chunk-P6MYZMXQ.js";
59
65
  import {
60
66
  CONTRACT_FREEZE_PORT_TOKEN,
61
67
  CONTRACT_FREEZE_PROJECT_KEY_TOKEN,
@@ -115,23 +121,7 @@ import {
115
121
  periodEndWithMinLead,
116
122
  resolveBundleCancelEffectiveAt,
117
123
  resolveBundlePriceNet
118
- } from "./chunk-RIGLQ4BV.js";
119
- import {
120
- PROMO_CODE_REDEMPTION_REPOSITORY_TOKEN,
121
- PROMO_CODE_REPOSITORY_TOKEN,
122
- PROMO_CODE_VALIDATION_LOG_REPOSITORY_TOKEN,
123
- PROMO_FIRST_TIME_CUSTOMER_CHECK_TOKEN,
124
- PROMO_REVENUE_DEDUCTION_AGGREGATOR_TOKEN,
125
- PROMO_SERVICE_CONFIG_TOKEN,
126
- PROMO_SUBSCRIPTION_LOOKUP_TOKEN,
127
- PROMO_TRANSACTION_RUNNER_TOKEN,
128
- PromoCodesService,
129
- addCycles,
130
- buildLabel,
131
- computeDiscountGross,
132
- computeDiscountedGross,
133
- computeRegularStartsAt
134
- } from "./chunk-ZL4LLE2Z.js";
124
+ } from "./chunk-VHEHZMHB.js";
135
125
  import {
136
126
  SubscriptionContractModule,
137
127
  SubscriptionContractService,
@@ -139,6 +129,10 @@ import {
139
129
  sortContractLineItemsForInvoice,
140
130
  subscriptionContractToInvoiceSnapshot
141
131
  } from "./chunk-2PNX2QL2.js";
132
+ import {
133
+ REQUIRE_FEATURE_KEY,
134
+ RequireFeature
135
+ } from "./chunk-Q53N43LQ.js";
142
136
  import {
143
137
  ADVISORY_STRICT_MODE_CODES,
144
138
  BundlesService,
@@ -204,7 +198,7 @@ import {
204
198
  validateBusinessTypeDraft,
205
199
  validatePlanDraft,
206
200
  validateSeedAgainstSnapshot
207
- } from "./chunk-V7HUZ6UQ.js";
201
+ } from "./chunk-FN65XZKH.js";
208
202
  import {
209
203
  AUDIT_CONTEXT_RESOLVER_TOKEN,
210
204
  PENDING_PLAN_QUERY_PORT_TOKEN,
@@ -219,6 +213,12 @@ import {
219
213
  classifyBundleVersionDiff,
220
214
  classifyPlanDiff
221
215
  } from "./chunk-WPUVJRIN.js";
216
+ import {
217
+ AUDIT_PORT_TOKEN,
218
+ AdminAuditService,
219
+ MFA_PORT_TOKEN,
220
+ RLS_BYPASS_PORT_TOKEN
221
+ } from "./chunk-E56W4U2P.js";
222
222
  import {
223
223
  CHECKOUT_OFFER_REPOSITORY_TOKEN,
224
224
  CheckoutOfferModule,
@@ -235,46 +235,21 @@ import {
235
235
  RequiresCapability,
236
236
  runHeadlessDiscoveryScan
237
237
  } from "./chunk-HRU3CP57.js";
238
- import {
239
- DiscoverySnapshotNotFoundError,
240
- loadDiscoverySnapshotFromFile
241
- } from "./chunk-ABB2CRAS.js";
242
- import "./chunk-2FR6ZL7R.js";
243
- import {
244
- ADMIN_MANIFEST_CONFIG,
245
- AdminBypassRlsInterceptor,
246
- AdminManifestModule,
247
- AdminManifestService,
248
- AdminModule,
249
- AdminPublicBootController,
250
- MfaGuard,
251
- MfaService,
252
- PLATFORM_CORE_CONTRIBUTION_TOKEN,
253
- PLATFORM_CORE_MANIFEST_CONTRIBUTION,
254
- REQUIRE_MFA_KEY,
255
- RequireMfa,
256
- SuperAdminGuard
257
- } from "./chunk-P6MYZMXQ.js";
258
- import {
259
- REQUIRE_FEATURE_KEY,
260
- RequireFeature
261
- } from "./chunk-Q53N43LQ.js";
262
- import {
263
- AUDIT_PORT_TOKEN,
264
- AdminAuditService,
265
- MFA_PORT_TOKEN,
266
- RLS_BYPASS_PORT_TOKEN
267
- } from "./chunk-E56W4U2P.js";
268
238
  import {
269
239
  DiscoveryModule,
270
240
  buildDiscoveryController
271
241
  } from "./chunk-AJ3EPELS.js";
242
+ import {
243
+ DiscoverySnapshotNotFoundError,
244
+ loadDiscoverySnapshotFromFile
245
+ } from "./chunk-ABB2CRAS.js";
272
246
  import {
273
247
  DISCOVERY_APP_INFO_TOKEN,
274
248
  DISCOVERY_SNAPSHOT_PATH_TOKEN,
275
249
  DiscoveryScanner,
276
250
  computeSnapshotHash
277
251
  } from "./chunk-M6CZQYPY.js";
252
+ import "./chunk-2FR6ZL7R.js";
278
253
  import {
279
254
  EntitlementModule,
280
255
  EntitlementService,
@@ -294,27 +269,10 @@ import {
294
269
  filterPlannedOnlyFeatures,
295
270
  hasAnyFeature,
296
271
  hasFeature,
272
+ isLimitExceededError,
297
273
  resolveEntitlementPlan,
298
274
  toEffectiveLimitsSnapshot
299
- } from "./chunk-YXGHPILG.js";
300
- import {
301
- PLAN_CATALOG_READ_SINK_TOKEN,
302
- PLAN_CATALOG_TOKEN,
303
- PlanCatalogModule,
304
- buildPlanCatalogFromSnapshot,
305
- computeIncludedVat,
306
- findPlan,
307
- getActiveFeatureKeys,
308
- getMarketedPlans,
309
- getPlanOrThrow,
310
- getPlanPriceGross,
311
- getPlanPriceNet,
312
- getPlanQuota,
313
- grossFromNet,
314
- isFeatureInPlan,
315
- isFeaturePlannedOnly,
316
- round2
317
- } from "./chunk-MV6LW5UB.js";
275
+ } from "./chunk-K42EQPBB.js";
318
276
  import {
319
277
  SUBSCRIPTION_CONTRACT_REPOSITORY_TOKEN
320
278
  } from "./chunk-NYLON2VC.js";
@@ -334,9 +292,6 @@ import {
334
292
  PLAN_REPOSITORY_TOKEN,
335
293
  PROMOTION_REPOSITORY_TOKEN
336
294
  } from "./chunk-XCZ3TTFK.js";
337
- import {
338
- asProvider
339
- } from "./chunk-SABTXESR.js";
340
295
  import {
341
296
  DEFINES_QUOTA_KEY,
342
297
  DISCOVERY_SNAPSHOT_TOKEN,
@@ -344,6 +299,52 @@ import {
344
299
  IMPLEMENTS_CAPABILITY_KEY,
345
300
  REQUIRES_CAPABILITY_KEY
346
301
  } from "./chunk-L4SUWH5B.js";
302
+ import {
303
+ PreviewPromoCodeDto,
304
+ PromoCodeExpirer,
305
+ PromoCodePublicController,
306
+ PromoCodeRateLimitGuard,
307
+ PromoCodesModule,
308
+ hashIp,
309
+ ipFingerprint
310
+ } from "./chunk-2VNZYRDV.js";
311
+ import {
312
+ PROMO_CODE_REDEMPTION_REPOSITORY_TOKEN,
313
+ PROMO_CODE_REPOSITORY_TOKEN,
314
+ PROMO_CODE_VALIDATION_LOG_REPOSITORY_TOKEN,
315
+ PROMO_FIRST_TIME_CUSTOMER_CHECK_TOKEN,
316
+ PROMO_REVENUE_DEDUCTION_AGGREGATOR_TOKEN,
317
+ PROMO_SERVICE_CONFIG_TOKEN,
318
+ PROMO_SUBSCRIPTION_LOOKUP_TOKEN,
319
+ PROMO_TRANSACTION_RUNNER_TOKEN,
320
+ PromoCodesService,
321
+ addCycles,
322
+ buildLabel,
323
+ computeDiscountGross,
324
+ computeDiscountedGross,
325
+ computeRegularStartsAt
326
+ } from "./chunk-ZL4LLE2Z.js";
327
+ import {
328
+ PLAN_CATALOG_READ_SINK_TOKEN,
329
+ PLAN_CATALOG_TOKEN,
330
+ PlanCatalogModule,
331
+ buildPlanCatalogFromSnapshot,
332
+ computeIncludedVat,
333
+ findPlan,
334
+ getActiveFeatureKeys,
335
+ getMarketedPlans,
336
+ getPlanOrThrow,
337
+ getPlanPriceGross,
338
+ getPlanPriceNet,
339
+ getPlanQuota,
340
+ grossFromNet,
341
+ isFeatureInPlan,
342
+ isFeaturePlannedOnly,
343
+ round2
344
+ } from "./chunk-MV6LW5UB.js";
345
+ import {
346
+ asProvider
347
+ } from "./chunk-SABTXESR.js";
347
348
  import {
348
349
  __name
349
350
  } from "./chunk-SHUYVCID.js";
@@ -927,6 +928,7 @@ export {
927
928
  ipFingerprint,
928
929
  isFeatureInPlan,
929
930
  isFeaturePlannedOnly,
931
+ isLimitExceededError,
930
932
  loadApprovedCatalogKeys,
931
933
  loadDiscoverySnapshotFromFile,
932
934
  loadPlanCatalogFromFile,
@@ -1890,6 +1890,7 @@ function assertNoReplacesCycle(index) {
1890
1890
  __name(assertNoReplacesCycle, "assertNoReplacesCycle");
1891
1891
 
1892
1892
  // src/entitlement/limit-exceeded-error.ts
1893
+ var LIMIT_EXCEEDED = "LIMIT_EXCEEDED";
1893
1894
  var LimitExceededError = class extends Error {
1894
1895
  static {
1895
1896
  __name(this, "LimitExceededError");
@@ -1897,6 +1898,7 @@ var LimitExceededError = class extends Error {
1897
1898
  dimension;
1898
1899
  max;
1899
1900
  used;
1901
+ code = LIMIT_EXCEEDED;
1900
1902
  constructor(dimension, max, used) {
1901
1903
  super(`Limit f\xFCr ${dimension} erreicht: ${used}/${max}.`), this.dimension = dimension, this.max = max, this.used = used;
1902
1904
  this.name = "LimitExceededError";
@@ -2776,11 +2778,13 @@ var SaasPlatformModule = class _SaasPlatformModule {
2776
2778
  PlanCatalogModule,
2777
2779
  DiscoveryModule,
2778
2780
  AdminModule,
2781
+ // ADMIN_MANIFEST_CONFIG travels transitively: re-exporting an
2782
+ // imported module's token directly is an UnknownExportException
2783
+ // at boot — the module export below already carries it.
2779
2784
  AdminManifestModule,
2780
2785
  ...options.entitlement ? [
2781
2786
  EntitlementModule
2782
2787
  ] : [],
2783
- ADMIN_MANIFEST_CONFIG,
2784
2788
  ...lightweightExports
2785
2789
  ],
2786
2790
  global: true
@@ -1,66 +1,13 @@
1
- import { P as PlanResolverPort } from '../saas-platform.module-C7-H9eYB.cjs';
2
- export { a as PLAN_RESOLVER_PORT_TOKEN, S as SaasPlatformAdapters, b as SaasPlatformModule, c as SaasPlatformModuleOptions, d as StaticPlanResolver, T as TenantManifestControllerOptions, e as buildTenantManifestController } from '../saas-platform.module-C7-H9eYB.cjs';
3
- import { PlanCatalog, QuotaProvider } from '@saasicat/types';
4
- import { CanActivate, ExecutionContext, NestInterceptor, CallHandler } from '@nestjs/common';
5
- import { Reflector } from '@nestjs/core';
6
- import { Observable } from 'rxjs';
1
+ import { S as StaticEntitlementService } from '../enforce-quota.interceptor-HmdZFg41.cjs';
2
+ export { E as EnforceQuotaInterceptor, P as PLAN_RESOLVER_PORT_TOKEN, a as PlanResolverPort, Q as QUOTA_PROVIDERS_TOKEN, b as STATIC_FEATURE_GUARD_CONFIG_TOKEN, c as SaasPlatformAdapters, d as SaasPlatformModule, e as SaasPlatformModuleOptions, f as StaticEntitlementSnapshot, g as StaticFeatureGuard, h as StaticFeatureGuardConfig, i as StaticPlanResolver, T as TenantManifestControllerOptions, j as buildTenantManifestController } from '../enforce-quota.interceptor-HmdZFg41.cjs';
3
+ import '@nestjs/common';
4
+ import '@saasicat/types';
7
5
  import '../di-CcNeq9v-.cjs';
8
- import '../admin-manifest.config-DyrQNT7M.cjs';
9
- import '../discovery.scanner-CUYLKlYT.cjs';
6
+ import '../admin-manifest.config-DxTfZ8-L.cjs';
7
+ import '../discovery.scanner-DLgEvuoy.cjs';
8
+ import '@nestjs/core';
10
9
  import '../plan-resolution-CFCoUkrE.cjs';
11
-
12
- interface StaticEntitlementSnapshot {
13
- planId: string | null;
14
- features: readonly string[];
15
- /** quotaKey → limit (`-1` = unlimited). */
16
- quotas: Readonly<Record<string, number>>;
17
- }
18
- declare class StaticEntitlementService {
19
- private readonly catalog;
20
- private readonly resolver;
21
- constructor(catalog: PlanCatalog, resolver: PlanResolverPort);
22
- /**
23
- * Returns the effective features + quotas of a tenant from the
24
- * plan catalog. When the plan is missing: an empty snapshot (no feature,
25
- * all quotas at 0).
26
- */
27
- snapshot(tenantId: string): Promise<StaticEntitlementSnapshot>;
28
- /** Convenience helper for tests / synchronous checks in the UI manifest. */
29
- hasFeature(tenantId: string, featureKey: string): Promise<boolean>;
30
- quotaLimit(tenantId: string, quotaKey: string): Promise<number | null>;
31
- private findPlan;
32
- }
33
-
34
- declare const STATIC_FEATURE_GUARD_CONFIG_TOKEN: unique symbol;
35
- interface StaticFeatureGuardConfig {
36
- /**
37
- * Resolver for the user role (e.g. `(user) => user.platformRole`).
38
- * SUPER_ADMIN gets a bypass.
39
- */
40
- userRoleResolver?: (user: unknown) => string | undefined;
41
- /**
42
- * Resolver for the tenant ID from the request. Default:
43
- * `request.tenantId ?? request.user?.tenantId`.
44
- */
45
- tenantIdResolver?: (request: unknown) => string | undefined;
46
- }
47
- declare class StaticFeatureGuard implements CanActivate {
48
- private readonly reflector;
49
- private readonly entitlements;
50
- private readonly config;
51
- constructor(reflector: Reflector, entitlements: StaticEntitlementService, config?: StaticFeatureGuardConfig | null);
52
- canActivate(context: ExecutionContext): Promise<boolean>;
53
- }
54
-
55
- declare const QUOTA_PROVIDERS_TOKEN: unique symbol;
56
- declare class EnforceQuotaInterceptor implements NestInterceptor {
57
- private readonly reflector;
58
- private readonly entitlements;
59
- private readonly providers;
60
- constructor(reflector: Reflector, entitlements: StaticEntitlementService, providers?: ReadonlyArray<QuotaProvider> | null);
61
- intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
62
- private check;
63
- }
10
+ import 'rxjs';
64
11
 
65
12
  interface TenantNavItem {
66
13
  /** Unique slug, e.g. "notes", "billing", "settings". */
@@ -115,4 +62,4 @@ declare class TenantManifestService {
115
62
  getManifest(tenantId: string): Promise<TenantManifest>;
116
63
  }
117
64
 
118
- export { EnforceQuotaInterceptor, PlanResolverPort, QUOTA_PROVIDERS_TOKEN, STATIC_FEATURE_GUARD_CONFIG_TOKEN, StaticEntitlementService, type StaticEntitlementSnapshot, StaticFeatureGuard, type StaticFeatureGuardConfig, type TenantManifest, TenantManifestService, type TenantNavItem };
65
+ export { StaticEntitlementService, type TenantManifest, TenantManifestService, type TenantNavItem };
@@ -1,66 +1,13 @@
1
- import { P as PlanResolverPort } from '../saas-platform.module-k1DQg4De.js';
2
- export { a as PLAN_RESOLVER_PORT_TOKEN, S as SaasPlatformAdapters, b as SaasPlatformModule, c as SaasPlatformModuleOptions, d as StaticPlanResolver, T as TenantManifestControllerOptions, e as buildTenantManifestController } from '../saas-platform.module-k1DQg4De.js';
3
- import { PlanCatalog, QuotaProvider } from '@saasicat/types';
4
- import { CanActivate, ExecutionContext, NestInterceptor, CallHandler } from '@nestjs/common';
5
- import { Reflector } from '@nestjs/core';
6
- import { Observable } from 'rxjs';
1
+ import { S as StaticEntitlementService } from '../enforce-quota.interceptor-3HmbeHTM.js';
2
+ export { E as EnforceQuotaInterceptor, P as PLAN_RESOLVER_PORT_TOKEN, a as PlanResolverPort, Q as QUOTA_PROVIDERS_TOKEN, b as STATIC_FEATURE_GUARD_CONFIG_TOKEN, c as SaasPlatformAdapters, d as SaasPlatformModule, e as SaasPlatformModuleOptions, f as StaticEntitlementSnapshot, g as StaticFeatureGuard, h as StaticFeatureGuardConfig, i as StaticPlanResolver, T as TenantManifestControllerOptions, j as buildTenantManifestController } from '../enforce-quota.interceptor-3HmbeHTM.js';
3
+ import '@nestjs/common';
4
+ import '@saasicat/types';
7
5
  import '../di-CcNeq9v-.js';
8
- import '../admin-manifest.config-DyrQNT7M.js';
9
- import '../discovery.scanner-CUYLKlYT.js';
6
+ import '../admin-manifest.config-DxTfZ8-L.js';
7
+ import '../discovery.scanner-DLgEvuoy.js';
8
+ import '@nestjs/core';
10
9
  import '../plan-resolution-CFCoUkrE.js';
11
-
12
- interface StaticEntitlementSnapshot {
13
- planId: string | null;
14
- features: readonly string[];
15
- /** quotaKey → limit (`-1` = unlimited). */
16
- quotas: Readonly<Record<string, number>>;
17
- }
18
- declare class StaticEntitlementService {
19
- private readonly catalog;
20
- private readonly resolver;
21
- constructor(catalog: PlanCatalog, resolver: PlanResolverPort);
22
- /**
23
- * Returns the effective features + quotas of a tenant from the
24
- * plan catalog. When the plan is missing: an empty snapshot (no feature,
25
- * all quotas at 0).
26
- */
27
- snapshot(tenantId: string): Promise<StaticEntitlementSnapshot>;
28
- /** Convenience helper for tests / synchronous checks in the UI manifest. */
29
- hasFeature(tenantId: string, featureKey: string): Promise<boolean>;
30
- quotaLimit(tenantId: string, quotaKey: string): Promise<number | null>;
31
- private findPlan;
32
- }
33
-
34
- declare const STATIC_FEATURE_GUARD_CONFIG_TOKEN: unique symbol;
35
- interface StaticFeatureGuardConfig {
36
- /**
37
- * Resolver for the user role (e.g. `(user) => user.platformRole`).
38
- * SUPER_ADMIN gets a bypass.
39
- */
40
- userRoleResolver?: (user: unknown) => string | undefined;
41
- /**
42
- * Resolver for the tenant ID from the request. Default:
43
- * `request.tenantId ?? request.user?.tenantId`.
44
- */
45
- tenantIdResolver?: (request: unknown) => string | undefined;
46
- }
47
- declare class StaticFeatureGuard implements CanActivate {
48
- private readonly reflector;
49
- private readonly entitlements;
50
- private readonly config;
51
- constructor(reflector: Reflector, entitlements: StaticEntitlementService, config?: StaticFeatureGuardConfig | null);
52
- canActivate(context: ExecutionContext): Promise<boolean>;
53
- }
54
-
55
- declare const QUOTA_PROVIDERS_TOKEN: unique symbol;
56
- declare class EnforceQuotaInterceptor implements NestInterceptor {
57
- private readonly reflector;
58
- private readonly entitlements;
59
- private readonly providers;
60
- constructor(reflector: Reflector, entitlements: StaticEntitlementService, providers?: ReadonlyArray<QuotaProvider> | null);
61
- intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
62
- private check;
63
- }
10
+ import 'rxjs';
64
11
 
65
12
  interface TenantNavItem {
66
13
  /** Unique slug, e.g. "notes", "billing", "settings". */
@@ -115,4 +62,4 @@ declare class TenantManifestService {
115
62
  getManifest(tenantId: string): Promise<TenantManifest>;
116
63
  }
117
64
 
118
- export { EnforceQuotaInterceptor, PlanResolverPort, QUOTA_PROVIDERS_TOKEN, STATIC_FEATURE_GUARD_CONFIG_TOKEN, StaticEntitlementService, type StaticEntitlementSnapshot, StaticFeatureGuard, type StaticFeatureGuardConfig, type TenantManifest, TenantManifestService, type TenantNavItem };
65
+ export { StaticEntitlementService, type TenantManifest, TenantManifestService, type TenantNavItem };
@@ -9,19 +9,19 @@ import {
9
9
  StaticPlanResolver,
10
10
  TenantManifestService,
11
11
  buildTenantManifestController
12
- } from "../chunk-47JT54VW.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,
@@ -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,
@@ -2984,6 +2989,7 @@ function assertNoReplacesCycle(index) {
2984
2989
  __name(assertNoReplacesCycle, "assertNoReplacesCycle");
2985
2990
 
2986
2991
  // src/entitlement/limit-exceeded-error.ts
2992
+ var LIMIT_EXCEEDED = "LIMIT_EXCEEDED";
2987
2993
  var LimitExceededError = class extends Error {
2988
2994
  static {
2989
2995
  __name(this, "LimitExceededError");
@@ -2991,6 +2997,7 @@ var LimitExceededError = class extends Error {
2991
2997
  dimension;
2992
2998
  max;
2993
2999
  used;
3000
+ code = LIMIT_EXCEEDED;
2994
3001
  constructor(dimension, max, used) {
2995
3002
  super(`Limit f\xFCr ${dimension} erreicht: ${used}/${max}.`), this.dimension = dimension, this.max = max, this.used = used;
2996
3003
  this.name = "LimitExceededError";
@@ -3870,11 +3877,13 @@ var SaasPlatformModule = class _SaasPlatformModule {
3870
3877
  PlanCatalogModule,
3871
3878
  DiscoveryModule,
3872
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.
3873
3883
  AdminManifestModule,
3874
3884
  ...options.entitlement ? [
3875
3885
  EntitlementModule
3876
3886
  ] : [],
3877
- ADMIN_MANIFEST_CONFIG,
3878
3887
  ...lightweightExports
3879
3888
  ],
3880
3889
  global: true
@@ -3959,6 +3968,7 @@ function createSaasPlatformTestModule(options) {
3959
3968
  __name(createSaasPlatformTestModule, "createSaasPlatformTestModule");
3960
3969
  // Annotate the CommonJS export names for ESM import in node:
3961
3970
  0 && (module.exports = {
3971
+ EnforceQuotaInterceptor,
3962
3972
  FakeBundleRepository,
3963
3973
  FakeBusinessTypeRepository,
3964
3974
  FakeMarketingProjectionRepository,
@@ -3968,6 +3978,10 @@ __name(createSaasPlatformTestModule, "createSaasPlatformTestModule");
3968
3978
  FakeSubscriptionContractRepository,
3969
3979
  FakeSubscriptionRepository,
3970
3980
  FakeTransactionRunner,
3981
+ PLAN_RESOLVER_PORT_TOKEN,
3982
+ StaticEntitlementService,
3983
+ StaticFeatureGuard,
3984
+ StaticPlanResolver,
3971
3985
  StubAuditPort,
3972
3986
  StubMfaPort,
3973
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 SaasPlatformAdapters } from '../saas-platform.module-C7-H9eYB.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
@@ -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 SaasPlatformAdapters } from '../saas-platform.module-k1DQg4De.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
@@ -1,18 +1,23 @@
1
1
  import {
2
- SaasPlatformModule
3
- } from "../chunk-47JT54VW.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.3.0",
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.3.0",
141
- "@saasicat/types": "^0.3.0"
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";