@saasicat/nest 0.19.0 → 0.22.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 (59) hide show
  1. package/dist/_entries.cjs +358 -391
  2. package/dist/admin/index.js +2 -1
  3. package/dist/{aggregation-o0LMenvl.d.ts → aggregation-DP5zfKbU.d.ts} +3 -3
  4. package/dist/{aggregation-SKfXu09x.d.cts → aggregation-mZ7WZROK.d.cts} +3 -3
  5. package/dist/billing/index.d.cts +13 -12
  6. package/dist/billing/index.d.ts +13 -12
  7. package/dist/billing/index.js +4 -3
  8. package/dist/catalog/index.d.cts +10 -10
  9. package/dist/catalog/index.d.ts +10 -10
  10. package/dist/catalog/index.js +2 -2
  11. package/dist/{catalog.module-BKObceo0.d.ts → catalog.module-CQr1FpkI.d.ts} +6 -6
  12. package/dist/{catalog.module-Dw2Hrbyu.d.cts → catalog.module-D-_pQDNA.d.cts} +6 -6
  13. package/dist/checkout-offer/index.js +1 -1
  14. package/dist/{chunk-EUU3B6NB.js → chunk-4O6R6ARQ.js} +12 -6
  15. package/dist/{chunk-LXUBCLRK.js → chunk-7X5MSAIL.js} +16 -15
  16. package/dist/{chunk-AFK2IE2L.js → chunk-7ZPFQXHM.js} +1 -1
  17. package/dist/chunk-EBJJNTW6.js +22 -0
  18. package/dist/{chunk-6WA4X5U3.js → chunk-MJ32VNZD.js} +41 -91
  19. package/dist/{chunk-F6DCLVBB.js → chunk-NNNXXUPT.js} +9 -3
  20. package/dist/{chunk-7JIHG53V.js → chunk-SN5UOC43.js} +7 -4
  21. package/dist/{chunk-KUDKD7ZG.js → chunk-UFS344JD.js} +26 -22
  22. package/dist/{chunk-I77VS3YH.js → chunk-UO64MK3Q.js} +18 -24
  23. package/dist/{chunk-QLJHIIOY.js → chunk-VQQWF7MW.js} +7 -3
  24. package/dist/{chunk-ORWIGSNN.js → chunk-XTVAFJ3P.js} +2 -1
  25. package/dist/{define-saasicat-D8c6Bs4T.d.cts → define-saasicat-ByPjtKPy.d.cts} +1 -1
  26. package/dist/{define-saasicat-CqkhnHn-.d.ts → define-saasicat-C99hWAUK.d.ts} +1 -1
  27. package/dist/discovery/index.d.cts +2 -2
  28. package/dist/discovery/index.d.ts +2 -2
  29. package/dist/{enforce-quota.interceptor-Dk0eEtzV.d.cts → enforce-quota.interceptor-BrsU1UYJ.d.cts} +1 -1
  30. package/dist/{enforce-quota.interceptor-Dp8wTYro.d.ts → enforce-quota.interceptor-reO-i71U.d.ts} +1 -1
  31. package/dist/entitlement/index.d.cts +1 -1
  32. package/dist/entitlement/index.d.ts +1 -1
  33. package/dist/entitlement/index.js +2 -1
  34. package/dist/index.d.cts +30 -11
  35. package/dist/index.d.ts +30 -11
  36. package/dist/index.js +14 -10
  37. package/dist/{module-BwD-wAor.d.ts → module-BE17XFLg.d.ts} +1 -1
  38. package/dist/{module-DsDkbawm.d.cts → module-CHMIyWlf.d.cts} +1 -1
  39. package/dist/{plan-versions.service-BB36Q1bg.d.ts → plan-versions.service-B-YoE4SZ.d.ts} +1 -1
  40. package/dist/{plan-versions.service-CUR2Whyr.d.cts → plan-versions.service-_saKzb50.d.cts} +1 -1
  41. package/dist/platform/index.d.cts +11 -11
  42. package/dist/platform/index.d.ts +11 -11
  43. package/dist/platform/index.js +9 -8
  44. package/dist/promo/index.d.cts +3 -3
  45. package/dist/promo/index.d.ts +3 -3
  46. package/dist/promo/index.js +3 -2
  47. package/dist/registration/index.d.cts +1 -1
  48. package/dist/registration/index.d.ts +1 -1
  49. package/dist/registration/index.js +2 -1
  50. package/dist/{saas-platform.module-BQmrDGVU.d.ts → saas-platform.module-DolE41YY.d.ts} +2 -2
  51. package/dist/{saas-platform.module-DducnQ9s.d.cts → saas-platform.module-HCDNZTiE.d.cts} +2 -2
  52. package/dist/{service-DPZ2W1E-.d.cts → service-D48clObR.d.cts} +1 -1
  53. package/dist/{service-DPZ2W1E-.d.ts → service-D48clObR.d.ts} +1 -1
  54. package/dist/{tenant-billing.controller-b1G1yB09.d.ts → tenant-billing.controller-7o4ObzGs.d.ts} +3 -3
  55. package/dist/{tenant-billing.controller-m42YQ_Ei.d.cts → tenant-billing.controller-DubP6-Md.d.cts} +3 -3
  56. package/dist/testing/index.d.cts +6 -6
  57. package/dist/testing/index.d.ts +6 -6
  58. package/dist/testing/index.js +10 -9
  59. package/package.json +3 -3
@@ -25,7 +25,7 @@ import {
25
25
  SuperAdminGuard,
26
26
  SuspendTenantDto,
27
27
  buildAdminStatsController
28
- } from "../chunk-7JIHG53V.js";
28
+ } from "../chunk-SN5UOC43.js";
29
29
  import {
30
30
  AUDIT_PORT_TOKEN,
31
31
  AdminAuditService,
@@ -33,6 +33,7 @@ import {
33
33
  RLS_BYPASS_PORT_TOKEN
34
34
  } from "../chunk-E56W4U2P.js";
35
35
  import "../chunk-YSC46BGM.js";
36
+ import "../chunk-EBJJNTW6.js";
36
37
  import "../chunk-SABTXESR.js";
37
38
  import "../chunk-SHUYVCID.js";
38
39
  export {
@@ -16,7 +16,7 @@ interface PlanVersionSnapshot {
16
16
  }
17
17
  /**
18
18
  * Snapshot of an active SubscriptionBundle booking (P11.7.3 +
19
- * SPEC_V2 §11.1 M6 Pack 2e). Resolved by the EntitlementService from the
19
+ *). Resolved by the EntitlementService from the
20
20
  * `subscription_bundles` junction + BundleRepository.findVersionById and
21
21
  * passed to `aggregateLimits`.
22
22
  *
@@ -158,7 +158,7 @@ declare class EntitlementService {
158
158
  enforceLimit<T>(input: EnforceLimitInput<T>): Promise<T>;
159
159
  /**
160
160
  * Plan fallback for TRIAL/PENDING_SALES: returns the PlanVersion active
161
- * as of `asOf` (SPEC_V2 §4.2). If the repo does not implement
161
+ * as of `asOf`. If the repo does not implement
162
162
  * `findActive`, we fall back to `findLatestLive` (backward compat for
163
163
  * adapters without `validFrom` columns).
164
164
  */
@@ -172,7 +172,7 @@ declare class EntitlementService {
172
172
  * point in time. Active = `canceledEffectiveAt === null` or
173
173
  * `canceledEffectiveAt > now`.
174
174
  *
175
- * Spec: SPEC_V2 §11.1 M6 Pack 2e + P11.7.3.
175
+ * Spec:
176
176
  */
177
177
  declare function filterActiveSubscriptionBundles(bundles: readonly SubscriptionBundleSnapshot[], now: Date): SubscriptionBundleSnapshot[];
178
178
  /**
@@ -16,7 +16,7 @@ interface PlanVersionSnapshot {
16
16
  }
17
17
  /**
18
18
  * Snapshot of an active SubscriptionBundle booking (P11.7.3 +
19
- * SPEC_V2 §11.1 M6 Pack 2e). Resolved by the EntitlementService from the
19
+ *). Resolved by the EntitlementService from the
20
20
  * `subscription_bundles` junction + BundleRepository.findVersionById and
21
21
  * passed to `aggregateLimits`.
22
22
  *
@@ -158,7 +158,7 @@ declare class EntitlementService {
158
158
  enforceLimit<T>(input: EnforceLimitInput<T>): Promise<T>;
159
159
  /**
160
160
  * Plan fallback for TRIAL/PENDING_SALES: returns the PlanVersion active
161
- * as of `asOf` (SPEC_V2 §4.2). If the repo does not implement
161
+ * as of `asOf`. If the repo does not implement
162
162
  * `findActive`, we fall back to `findLatestLive` (backward compat for
163
163
  * adapters without `validFrom` columns).
164
164
  */
@@ -172,7 +172,7 @@ declare class EntitlementService {
172
172
  * point in time. Active = `canceledEffectiveAt === null` or
173
173
  * `canceledEffectiveAt > now`.
174
174
  *
175
- * Spec: SPEC_V2 §11.1 M6 Pack 2e + P11.7.3.
175
+ * Spec:
176
176
  */
177
177
  declare function filterActiveSubscriptionBundles(bundles: readonly SubscriptionBundleSnapshot[], now: Date): SubscriptionBundleSnapshot[];
178
178
  /**
@@ -4,14 +4,14 @@ import * as _nestjs_common from '@nestjs/common';
4
4
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
5
5
  export { Type as NestType } from '@nestjs/common';
6
6
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
7
- import { c as EntitlementService } from '../aggregation-SKfXu09x.cjs';
7
+ import { c as EntitlementService } from '../aggregation-mZ7WZROK.cjs';
8
8
  import { P as ProviderSpec } from '../di-CcNeq9v-.cjs';
9
9
  import { f as ContractFreezePort, g as ContractFreezeSourcePort } from '../subscription-bundles.module-DCpV-Pb5.cjs';
10
10
  export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, P as PENDING_PLAN_QUERY_PORT_TOKEN, h as PendingPlanQueryPort, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SUBSCRIPTION_USAGE_PORT_TOKEN, k as SUBSCRIPTION_WRITE_PORT_TOKEN, l as SelfServiceBlockedBundles, m as SelfServiceBlockedPlans, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, u as TenantIdResolver, v as TrialProjectionInput, w as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN, z as UserEmailResolver, B as UserIdResolver } from '../subscription-bundles.module-DCpV-Pb5.cjs';
11
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../tenant-billing.controller-m42YQ_Ei.cjs';
11
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../tenant-billing.controller-DubP6-Md.cjs';
12
12
  import { S as SubscriptionContractService } from '../subscription-contract.service--cm47ZJJ.cjs';
13
13
  import '../plan-resolution-CFCoUkrE.cjs';
14
- import '../service-DPZ2W1E-.cjs';
14
+ import '../service-D48clObR.cjs';
15
15
  import '../admin-audit.service-9IqXMlZm.cjs';
16
16
 
17
17
  /**
@@ -197,10 +197,11 @@ declare class FeatureGuard implements CanActivate {
197
197
  constructor(reflector: Reflector, entitlements: EntitlementService, config?: FeatureGuardConfig | null, upsellResolver?: UpsellOfferResolver | null);
198
198
  canActivate(context: ExecutionContext): Promise<boolean>;
199
199
  /**
200
- * Upsell response (#36): with a registered `UpsellOfferResolver` the 403
201
- * becomes machine-readable (`FeatureNotLicensedBody`), so consumer UIs can
202
- * render a purchase offer. Without a resolver the body carries the same
203
- * `code` but no offers.
200
+ * Upsell response (#36): the 403 body is always the full
201
+ * `FeatureNotLicensedBody`, so a consumer that matches on `code` can read
202
+ * `featureKey`/`offers` unconditionally. Without a registered
203
+ * `UpsellOfferResolver` there is simply nothing to offer — `offers` is
204
+ * empty, the same degradation a failing resolver produces.
204
205
  *
205
206
  * Deliberately 403 + `code` field instead of 402 — rationale in
206
207
  * `@saasicat/types` upsell.types.ts (402 is reserved / inconsistently
@@ -303,7 +304,7 @@ interface PlanCatalogModuleOptions {
303
304
  currency: string;
304
305
  vatRate: number;
305
306
  /**
306
- * App-wide marketing configuration (SPEC_V2 §6.5) — including the
307
+ * App-wide marketing configuration — including the
307
308
  * `availableLocales` pool. Flows into `PLAN_CATALOG_TOKEN.marketing`
308
309
  * and from there into the admin manifest (`project.availableLocales`).
309
310
  */
@@ -333,7 +334,7 @@ interface PlanCatalogBuildSettings {
333
334
  app?: PlanCatalog['app'];
334
335
  currency: string;
335
336
  vatRate: number;
336
- /** App-wide marketing configuration (SPEC_V2 §6.5). Optional. */
337
+ /** App-wide marketing configuration. Optional. */
337
338
  marketing?: PlanCatalog['marketing'];
338
339
  }
339
340
  declare function buildPlanCatalogFromSnapshot(settings: PlanCatalogBuildSettings, snapshot: PlanCatalogReadSnapshot): PlanCatalog;
@@ -466,7 +467,7 @@ interface PlanResponseEntry {
466
467
  popular: boolean;
467
468
  quotas: Record<string, number>;
468
469
  features: string[];
469
- /** SPEC_V2 §11.1 M6 — optional, present if a MarketingProjection exists. */
470
+ /** — optional, present if a MarketingProjection exists. */
470
471
  marketing?: MarketingFields;
471
472
  }
472
473
  interface PublicBundleEntry {
@@ -499,7 +500,7 @@ declare class PublicCatalogController {
499
500
  listPlans(lang?: string, localeParam?: string): Promise<PlanResponseEntry[]>;
500
501
  listFeatureRegistry(): Promise<FeatureUiRegistry>;
501
502
  /**
502
- * SPEC_V2 §11.1 M6 Pack 2c — public catalog endpoint for bundles
503
+ * — public catalog endpoint for bundles
503
504
  * (stem list with live versions). If a `MarketingProjection` with
504
505
  * `targetType=BUNDLE` + matching locale exists, it is merged in.
505
506
  */
@@ -519,7 +520,7 @@ interface PublicCatalogModuleOptions {
519
520
  /** Required: consumer-specific FeatureUiRegistry. */
520
521
  featureUiRegistry: FeatureUiRegistry;
521
522
  /**
522
- * SPEC_V2 §11.1 M6 Pack 2c — app identity (e.g. "clubapp"). Used
523
+ * — app identity (e.g. "clubapp"). Used
523
524
  * for marketing lookups + bundle filters.
524
525
  * Optional; if omitted, the new endpoints return empty lists.
525
526
  */
@@ -4,14 +4,14 @@ import * as _nestjs_common from '@nestjs/common';
4
4
  import { CanActivate, ExecutionContext, ArgumentsHost, Type, DynamicModule, ForwardReference, Provider } from '@nestjs/common';
5
5
  export { Type as NestType } from '@nestjs/common';
6
6
  import { Reflector, BaseExceptionFilter } from '@nestjs/core';
7
- import { c as EntitlementService } from '../aggregation-o0LMenvl.js';
7
+ import { c as EntitlementService } from '../aggregation-DP5zfKbU.js';
8
8
  import { P as ProviderSpec } from '../di-CcNeq9v-.js';
9
9
  import { f as ContractFreezePort, g as ContractFreezeSourcePort } from '../subscription-bundles.module-BQmoozm5.js';
10
10
  export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, D as DuePendingPlanChange, P as PENDING_PLAN_QUERY_PORT_TOKEN, h as PendingPlanQueryPort, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SUBSCRIPTION_USAGE_PORT_TOKEN, k as SUBSCRIPTION_WRITE_PORT_TOKEN, l as SelfServiceBlockedBundles, m as SelfServiceBlockedPlans, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, u as TenantIdResolver, v as TrialProjectionInput, w as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN, z as UserEmailResolver, B as UserIdResolver } from '../subscription-bundles.module-BQmoozm5.js';
11
- export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../tenant-billing.controller-b1G1yB09.js';
11
+ export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from '../tenant-billing.controller-7o4ObzGs.js';
12
12
  import { S as SubscriptionContractService } from '../subscription-contract.service--cm47ZJJ.js';
13
13
  import '../plan-resolution-CFCoUkrE.js';
14
- import '../service-DPZ2W1E-.js';
14
+ import '../service-D48clObR.js';
15
15
  import '../admin-audit.service-9IqXMlZm.js';
16
16
 
17
17
  /**
@@ -197,10 +197,11 @@ declare class FeatureGuard implements CanActivate {
197
197
  constructor(reflector: Reflector, entitlements: EntitlementService, config?: FeatureGuardConfig | null, upsellResolver?: UpsellOfferResolver | null);
198
198
  canActivate(context: ExecutionContext): Promise<boolean>;
199
199
  /**
200
- * Upsell response (#36): with a registered `UpsellOfferResolver` the 403
201
- * becomes machine-readable (`FeatureNotLicensedBody`), so consumer UIs can
202
- * render a purchase offer. Without a resolver the body carries the same
203
- * `code` but no offers.
200
+ * Upsell response (#36): the 403 body is always the full
201
+ * `FeatureNotLicensedBody`, so a consumer that matches on `code` can read
202
+ * `featureKey`/`offers` unconditionally. Without a registered
203
+ * `UpsellOfferResolver` there is simply nothing to offer — `offers` is
204
+ * empty, the same degradation a failing resolver produces.
204
205
  *
205
206
  * Deliberately 403 + `code` field instead of 402 — rationale in
206
207
  * `@saasicat/types` upsell.types.ts (402 is reserved / inconsistently
@@ -303,7 +304,7 @@ interface PlanCatalogModuleOptions {
303
304
  currency: string;
304
305
  vatRate: number;
305
306
  /**
306
- * App-wide marketing configuration (SPEC_V2 §6.5) — including the
307
+ * App-wide marketing configuration — including the
307
308
  * `availableLocales` pool. Flows into `PLAN_CATALOG_TOKEN.marketing`
308
309
  * and from there into the admin manifest (`project.availableLocales`).
309
310
  */
@@ -333,7 +334,7 @@ interface PlanCatalogBuildSettings {
333
334
  app?: PlanCatalog['app'];
334
335
  currency: string;
335
336
  vatRate: number;
336
- /** App-wide marketing configuration (SPEC_V2 §6.5). Optional. */
337
+ /** App-wide marketing configuration. Optional. */
337
338
  marketing?: PlanCatalog['marketing'];
338
339
  }
339
340
  declare function buildPlanCatalogFromSnapshot(settings: PlanCatalogBuildSettings, snapshot: PlanCatalogReadSnapshot): PlanCatalog;
@@ -466,7 +467,7 @@ interface PlanResponseEntry {
466
467
  popular: boolean;
467
468
  quotas: Record<string, number>;
468
469
  features: string[];
469
- /** SPEC_V2 §11.1 M6 — optional, present if a MarketingProjection exists. */
470
+ /** — optional, present if a MarketingProjection exists. */
470
471
  marketing?: MarketingFields;
471
472
  }
472
473
  interface PublicBundleEntry {
@@ -499,7 +500,7 @@ declare class PublicCatalogController {
499
500
  listPlans(lang?: string, localeParam?: string): Promise<PlanResponseEntry[]>;
500
501
  listFeatureRegistry(): Promise<FeatureUiRegistry>;
501
502
  /**
502
- * SPEC_V2 §11.1 M6 Pack 2c — public catalog endpoint for bundles
503
+ * — public catalog endpoint for bundles
503
504
  * (stem list with live versions). If a `MarketingProjection` with
504
505
  * `targetType=BUNDLE` + matching locale exists, it is merged in.
505
506
  */
@@ -519,7 +520,7 @@ interface PublicCatalogModuleOptions {
519
520
  /** Required: consumer-specific FeatureUiRegistry. */
520
521
  featureUiRegistry: FeatureUiRegistry;
521
522
  /**
522
- * SPEC_V2 §11.1 M6 Pack 2c — app identity (e.g. "clubapp"). Used
523
+ * — app identity (e.g. "clubapp"). Used
523
524
  * for marketing lookups + bundle filters.
524
525
  * Optional; if omitted, the new endpoints return empty lists.
525
526
  */
@@ -58,8 +58,8 @@ import {
58
58
  periodEndWithMinLead,
59
59
  resolveBundleCancelEffectiveAt,
60
60
  resolveBundlePriceNet
61
- } from "../chunk-I77VS3YH.js";
62
- import "../chunk-QLJHIIOY.js";
61
+ } from "../chunk-UO64MK3Q.js";
62
+ import "../chunk-VQQWF7MW.js";
63
63
  import "../chunk-B7NRY2LV.js";
64
64
  import {
65
65
  AUDIT_CONTEXT_RESOLVER_TOKEN,
@@ -81,7 +81,7 @@ import "../chunk-YSC46BGM.js";
81
81
  import {
82
82
  SUBSCRIPTION_BUNDLE_CONFIG_TOKEN,
83
83
  SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN
84
- } from "../chunk-F6DCLVBB.js";
84
+ } from "../chunk-NNNXXUPT.js";
85
85
  import {
86
86
  PLAN_CATALOG_READ_SINK_TOKEN,
87
87
  PLAN_CATALOG_TOKEN,
@@ -98,6 +98,7 @@ import {
98
98
  isFeaturePlannedOnly
99
99
  } from "../chunk-DQKCK7DX.js";
100
100
  import "../chunk-NYLON2VC.js";
101
+ import "../chunk-EBJJNTW6.js";
101
102
  import "../chunk-WKVBNTYC.js";
102
103
  import "../chunk-L4KTQ6CL.js";
103
104
  import "../chunk-SABTXESR.js";
@@ -1,6 +1,6 @@
1
- export { B as BundlesService, C as CatalogEntriesService, a as CatalogServiceConfig, M as MarketingProjectionsService, b as MarketingSettingsService, P as PlanVersionsService, c as PlansService, d as PromotionsService, e as PublicMarketingCatalogService } from '../plan-versions.service-CUR2Whyr.cjs';
1
+ export { B as BundlesService, C as CatalogEntriesService, a as CatalogServiceConfig, M as MarketingProjectionsService, b as MarketingSettingsService, P as PlanVersionsService, c as PlansService, d as PromotionsService, e as PublicMarketingCatalogService } from '../plan-versions.service-_saKzb50.cjs';
2
2
  import { Type, CanActivate } from '@nestjs/common';
3
- export { C as CatalogControllerConfig, a as CatalogModule, b as CatalogModuleOptions } from '../catalog.module-Dw2Hrbyu.cjs';
3
+ export { C as CatalogControllerConfig, a as CatalogModule, b as CatalogModuleOptions } from '../catalog.module-D-_pQDNA.cjs';
4
4
  import { StrictModeWarningCode, StrictModeWarning, DiscoverySnapshot, ApprovedCatalogKeys, DiscoveredQuota, CatalogEntryRepository, PlanVersionRow, BundleVersionRow, DiscoveryStatus, CatalogEntryI18n, PromotionType, PromotionValue, PromotionTargetType, PromotionBillingCycle, PromotionI18n } from '@saasicat/types';
5
5
  import '../discovery.scanner-DLgEvuoy.cjs';
6
6
  import '@nestjs/core';
@@ -36,7 +36,7 @@ declare function buildPlansController(guards: Array<Type<CanActivate>>): Type;
36
36
  */
37
37
  declare function buildPlanVersionsController(guards: Array<Type<CanActivate>>): Type;
38
38
 
39
- /** Repository for `plans` (SPEC_V2 §11.1 M6 — Plan master CRUD). */
39
+ /** Repository for `plans` (Plan master CRUD). */
40
40
  declare const PLAN_REPOSITORY_TOKEN: unique symbol;
41
41
  /** Repository for `bundles` + `bundle_versions`. */
42
42
  declare const BUNDLE_REPOSITORY_TOKEN: unique symbol;
@@ -44,12 +44,12 @@ declare const BUNDLE_REPOSITORY_TOKEN: unique symbol;
44
44
  declare const MARKETING_PROJECTION_REPOSITORY_TOKEN: unique symbol;
45
45
  /**
46
46
  * Repository for `capability_catalog_entries`, `feature_catalog_entries`
47
- * and `quota_catalog_entries` (Discovery review, SPEC_V2 §6.3).
47
+ * and `quota_catalog_entries` (Discovery review).
48
48
  */
49
49
  declare const CATALOG_ENTRY_REPOSITORY_TOKEN: unique symbol;
50
- /** Repository for `promotions` (time-scheduled price campaigns, SPEC_V2 §9a). */
50
+ /** Repository for `promotions` (time-scheduled price campaigns). */
51
51
  declare const PROMOTION_REPOSITORY_TOKEN: unique symbol;
52
- /** Repository for `marketing_settings` (activeLocales, SPEC_V2 §6.5). */
52
+ /** Repository for `marketing_settings` (activeLocales). */
53
53
  declare const MARKETING_SETTINGS_REPOSITORY_TOKEN: unique symbol;
54
54
  /**
55
55
  * Service configuration: current app identity, strict mode.
@@ -105,7 +105,7 @@ declare function validateBundleDraft(draft: {
105
105
  }, snapshot: DiscoverySnapshot, knownPlanKeys?: Set<string> | null, marketedOnlyFeatures?: ReadonlySet<string>, approved?: ApprovedCatalogKeys | null): StrictModeWarning[];
106
106
  /**
107
107
  * Validates a PlanVersion draft definition against the discovery snapshot
108
- * (SPEC_V2 §8.2 Pack 3a). Returns a (possibly empty) list of
108
+ *. Returns a (possibly empty) list of
109
109
  * warnings.
110
110
  *
111
111
  * Checked:
@@ -347,7 +347,7 @@ declare class PublishBundleVersionDto {
347
347
  allowZeroPrice?: boolean;
348
348
  /**
349
349
  * Required on publish if the draft carries no `validFrom`
350
- * (SPEC_V2 §4.2 + §11.1 M6 Pack 2c, analogous to PublishPlanVersionDto).
350
+ * (analogous to PublishPlanVersionDto).
351
351
  * Service strictly checks > `validFrom` of the predecessor version.
352
352
  */
353
353
  validFrom?: string | null;
@@ -502,7 +502,7 @@ declare class CreatePlanVersionDraftDto {
502
502
  marketed?: boolean;
503
503
  changeNote?: string;
504
504
  baseVersionId?: string | null;
505
- /** Optional in the draft (required at publish). ISO date string. SPEC_V2 §4.2. */
505
+ /** Optional in the draft (required at publish). ISO date string.. */
506
506
  validFrom?: string | null;
507
507
  /** Optional; null = unlimited. ISO date string. */
508
508
  validUntil?: string | null;
@@ -529,7 +529,7 @@ declare class PublishPlanVersionDto {
529
529
  allowZeroPrice?: boolean;
530
530
  /**
531
531
  * Required at publish (on the DTO or draft). The service strictly checks
532
- * `validFrom > predecessor.validFrom`. SPEC_V2 §4.2.
532
+ * `validFrom > predecessor.validFrom`..
533
533
  */
534
534
  validFrom?: string | null;
535
535
  validUntil?: string | null;
@@ -1,6 +1,6 @@
1
- export { B as BundlesService, C as CatalogEntriesService, a as CatalogServiceConfig, M as MarketingProjectionsService, b as MarketingSettingsService, P as PlanVersionsService, c as PlansService, d as PromotionsService, e as PublicMarketingCatalogService } from '../plan-versions.service-BB36Q1bg.js';
1
+ export { B as BundlesService, C as CatalogEntriesService, a as CatalogServiceConfig, M as MarketingProjectionsService, b as MarketingSettingsService, P as PlanVersionsService, c as PlansService, d as PromotionsService, e as PublicMarketingCatalogService } from '../plan-versions.service-B-YoE4SZ.js';
2
2
  import { Type, CanActivate } from '@nestjs/common';
3
- export { C as CatalogControllerConfig, a as CatalogModule, b as CatalogModuleOptions } from '../catalog.module-BKObceo0.js';
3
+ export { C as CatalogControllerConfig, a as CatalogModule, b as CatalogModuleOptions } from '../catalog.module-CQr1FpkI.js';
4
4
  import { StrictModeWarningCode, StrictModeWarning, DiscoverySnapshot, ApprovedCatalogKeys, DiscoveredQuota, CatalogEntryRepository, PlanVersionRow, BundleVersionRow, DiscoveryStatus, CatalogEntryI18n, PromotionType, PromotionValue, PromotionTargetType, PromotionBillingCycle, PromotionI18n } from '@saasicat/types';
5
5
  import '../discovery.scanner-DLgEvuoy.js';
6
6
  import '@nestjs/core';
@@ -36,7 +36,7 @@ declare function buildPlansController(guards: Array<Type<CanActivate>>): Type;
36
36
  */
37
37
  declare function buildPlanVersionsController(guards: Array<Type<CanActivate>>): Type;
38
38
 
39
- /** Repository for `plans` (SPEC_V2 §11.1 M6 — Plan master CRUD). */
39
+ /** Repository for `plans` (Plan master CRUD). */
40
40
  declare const PLAN_REPOSITORY_TOKEN: unique symbol;
41
41
  /** Repository for `bundles` + `bundle_versions`. */
42
42
  declare const BUNDLE_REPOSITORY_TOKEN: unique symbol;
@@ -44,12 +44,12 @@ declare const BUNDLE_REPOSITORY_TOKEN: unique symbol;
44
44
  declare const MARKETING_PROJECTION_REPOSITORY_TOKEN: unique symbol;
45
45
  /**
46
46
  * Repository for `capability_catalog_entries`, `feature_catalog_entries`
47
- * and `quota_catalog_entries` (Discovery review, SPEC_V2 §6.3).
47
+ * and `quota_catalog_entries` (Discovery review).
48
48
  */
49
49
  declare const CATALOG_ENTRY_REPOSITORY_TOKEN: unique symbol;
50
- /** Repository for `promotions` (time-scheduled price campaigns, SPEC_V2 §9a). */
50
+ /** Repository for `promotions` (time-scheduled price campaigns). */
51
51
  declare const PROMOTION_REPOSITORY_TOKEN: unique symbol;
52
- /** Repository for `marketing_settings` (activeLocales, SPEC_V2 §6.5). */
52
+ /** Repository for `marketing_settings` (activeLocales). */
53
53
  declare const MARKETING_SETTINGS_REPOSITORY_TOKEN: unique symbol;
54
54
  /**
55
55
  * Service configuration: current app identity, strict mode.
@@ -105,7 +105,7 @@ declare function validateBundleDraft(draft: {
105
105
  }, snapshot: DiscoverySnapshot, knownPlanKeys?: Set<string> | null, marketedOnlyFeatures?: ReadonlySet<string>, approved?: ApprovedCatalogKeys | null): StrictModeWarning[];
106
106
  /**
107
107
  * Validates a PlanVersion draft definition against the discovery snapshot
108
- * (SPEC_V2 §8.2 Pack 3a). Returns a (possibly empty) list of
108
+ *. Returns a (possibly empty) list of
109
109
  * warnings.
110
110
  *
111
111
  * Checked:
@@ -347,7 +347,7 @@ declare class PublishBundleVersionDto {
347
347
  allowZeroPrice?: boolean;
348
348
  /**
349
349
  * Required on publish if the draft carries no `validFrom`
350
- * (SPEC_V2 §4.2 + §11.1 M6 Pack 2c, analogous to PublishPlanVersionDto).
350
+ * (analogous to PublishPlanVersionDto).
351
351
  * Service strictly checks > `validFrom` of the predecessor version.
352
352
  */
353
353
  validFrom?: string | null;
@@ -502,7 +502,7 @@ declare class CreatePlanVersionDraftDto {
502
502
  marketed?: boolean;
503
503
  changeNote?: string;
504
504
  baseVersionId?: string | null;
505
- /** Optional in the draft (required at publish). ISO date string. SPEC_V2 §4.2. */
505
+ /** Optional in the draft (required at publish). ISO date string.. */
506
506
  validFrom?: string | null;
507
507
  /** Optional; null = unlimited. ISO date string. */
508
508
  validUntil?: string | null;
@@ -529,7 +529,7 @@ declare class PublishPlanVersionDto {
529
529
  allowZeroPrice?: boolean;
530
530
  /**
531
531
  * Required at publish (on the DTO or draft). The service strictly checks
532
- * `validFrom > predecessor.validFrom`. SPEC_V2 §4.2.
532
+ * `validFrom > predecessor.validFrom`..
533
533
  */
534
534
  validFrom?: string | null;
535
535
  validUntil?: string | null;
@@ -6,7 +6,7 @@ import {
6
6
  runSeedGateFromFile,
7
7
  seedGateExitCode,
8
8
  validateSeedAgainstSnapshot
9
- } from "../chunk-AFK2IE2L.js";
9
+ } from "../chunk-7ZPFQXHM.js";
10
10
  import "../chunk-74SCJ4HF.js";
11
11
  import {
12
12
  ADVISORY_STRICT_MODE_CODES,
@@ -56,7 +56,7 @@ import {
56
56
  quotaApprovalSignature,
57
57
  validateBundleDraft,
58
58
  validatePlanDraft
59
- } from "../chunk-LXUBCLRK.js";
59
+ } from "../chunk-7X5MSAIL.js";
60
60
  import "../chunk-WPUVJRIN.js";
61
61
  import "../chunk-E56W4U2P.js";
62
62
  import "../chunk-YSC46BGM.js";
@@ -21,23 +21,23 @@ interface CatalogModuleOptions {
21
21
  marketingProjectionRepository?: ProviderSpec<MarketingProjectionRepository>;
22
22
  /**
23
23
  * Adapter for `capability_/feature_/quota_catalog_entries` persistence
24
- * (discovery review, SPEC_V2 §6.3). Optional — if omitted,
24
+ * (discovery review). Optional — if omitted,
25
25
  * CatalogEntriesService + controller are not registered.
26
26
  */
27
27
  catalogEntryRepository?: ProviderSpec<CatalogEntryRepository>;
28
28
  /**
29
- * Adapter for `promotions` persistence (SPEC_V2 §9a). Optional — if
29
+ * Adapter for `promotions` persistence. Optional — if
30
30
  * omitted, PromotionsService + controller are not registered.
31
31
  */
32
32
  promotionRepository?: ProviderSpec<PromotionRepository>;
33
33
  /**
34
- * Adapter for `marketing_settings` persistence (SPEC_V2 §6.5 —
34
+ * Adapter for `marketing_settings` persistence (
35
35
  * `activeLocales`). Optional.
36
36
  */
37
37
  marketingSettingsRepository?: ProviderSpec<MarketingSettingsRepository>;
38
38
  /**
39
39
  * Auth-free pricing-page endpoint `GET /public/marketing-catalog`
40
- * (SPEC_V2 §9). Registered only when plan-, marketingProjection-
40
+ *. Registered only when plan-, marketingProjection-
41
41
  * and promotionRepository are set. `guards` is usually `[]`.
42
42
  */
43
43
  publicMarketingCatalog?: {
@@ -47,7 +47,7 @@ interface CatalogModuleOptions {
47
47
  vatRate: number;
48
48
  };
49
49
  /**
50
- * SPEC_V2 §11.1 M6 (Pack 1) — adapter for `plans` master-record persistence.
50
+ * — adapter for `plans` master-record persistence.
51
51
  * Optional; if omitted, PlansService + controller are not
52
52
  * registered (apps without a need for the plan editor stay unchanged).
53
53
  */
@@ -82,7 +82,7 @@ interface CatalogModuleOptions {
82
82
  * per feature — the same one passed to `PublicCatalogModule.forRoot`). The
83
83
  * discovery auto-sync seeds EMPTY `FeatureCatalogEntry` fields
84
84
  * (label/description/icon) from it at boot; SuperAdmin edits stay untouched. This
85
- * makes `FeatureCatalogEntry` the SSOT for UI metadata (SPEC_V2 §6.3 / #12).
85
+ * makes `FeatureCatalogEntry` the SSOT for UI metadata.
86
86
  */
87
87
  featureUiRegistry?: FeatureUiRegistry;
88
88
  /**
@@ -21,23 +21,23 @@ interface CatalogModuleOptions {
21
21
  marketingProjectionRepository?: ProviderSpec<MarketingProjectionRepository>;
22
22
  /**
23
23
  * Adapter for `capability_/feature_/quota_catalog_entries` persistence
24
- * (discovery review, SPEC_V2 §6.3). Optional — if omitted,
24
+ * (discovery review). Optional — if omitted,
25
25
  * CatalogEntriesService + controller are not registered.
26
26
  */
27
27
  catalogEntryRepository?: ProviderSpec<CatalogEntryRepository>;
28
28
  /**
29
- * Adapter for `promotions` persistence (SPEC_V2 §9a). Optional — if
29
+ * Adapter for `promotions` persistence. Optional — if
30
30
  * omitted, PromotionsService + controller are not registered.
31
31
  */
32
32
  promotionRepository?: ProviderSpec<PromotionRepository>;
33
33
  /**
34
- * Adapter for `marketing_settings` persistence (SPEC_V2 §6.5 —
34
+ * Adapter for `marketing_settings` persistence (
35
35
  * `activeLocales`). Optional.
36
36
  */
37
37
  marketingSettingsRepository?: ProviderSpec<MarketingSettingsRepository>;
38
38
  /**
39
39
  * Auth-free pricing-page endpoint `GET /public/marketing-catalog`
40
- * (SPEC_V2 §9). Registered only when plan-, marketingProjection-
40
+ *. Registered only when plan-, marketingProjection-
41
41
  * and promotionRepository are set. `guards` is usually `[]`.
42
42
  */
43
43
  publicMarketingCatalog?: {
@@ -47,7 +47,7 @@ interface CatalogModuleOptions {
47
47
  vatRate: number;
48
48
  };
49
49
  /**
50
- * SPEC_V2 §11.1 M6 (Pack 1) — adapter for `plans` master-record persistence.
50
+ * — adapter for `plans` master-record persistence.
51
51
  * Optional; if omitted, PlansService + controller are not
52
52
  * registered (apps without a need for the plan editor stay unchanged).
53
53
  */
@@ -82,7 +82,7 @@ interface CatalogModuleOptions {
82
82
  * per feature — the same one passed to `PublicCatalogModule.forRoot`). The
83
83
  * discovery auto-sync seeds EMPTY `FeatureCatalogEntry` fields
84
84
  * (label/description/icon) from it at boot; SuperAdmin edits stay untouched. This
85
- * makes `FeatureCatalogEntry` the SSOT for UI metadata (SPEC_V2 §6.3 / #12).
85
+ * makes `FeatureCatalogEntry` the SSOT for UI metadata.
86
86
  */
87
87
  featureUiRegistry?: FeatureUiRegistry;
88
88
  /**
@@ -6,7 +6,7 @@ import {
6
6
  CreateCheckoutOfferDto,
7
7
  UpdateCheckoutOfferDto,
8
8
  buildCheckoutOfferController
9
- } from "../chunk-ORWIGSNN.js";
9
+ } from "../chunk-XTVAFJ3P.js";
10
10
  import "../chunk-BSK6YBLI.js";
11
11
  import "../chunk-YSC46BGM.js";
12
12
  import "../chunk-L4KTQ6CL.js";
@@ -8,13 +8,16 @@ import {
8
8
  PROMO_SUBSCRIPTION_LOOKUP_TOKEN,
9
9
  PROMO_TRANSACTION_RUNNER_TOKEN,
10
10
  PromoCodesService
11
- } from "./chunk-QLJHIIOY.js";
11
+ } from "./chunk-VQQWF7MW.js";
12
12
  import {
13
13
  AdminAuditService
14
14
  } from "./chunk-E56W4U2P.js";
15
15
  import {
16
16
  SaaSiCatPublicRoute
17
17
  } from "./chunk-YSC46BGM.js";
18
+ import {
19
+ codedError
20
+ } from "./chunk-EBJJNTW6.js";
18
21
  import {
19
22
  asProvider
20
23
  } from "./chunk-SABTXESR.js";
@@ -96,12 +99,15 @@ var IP_WINDOW_MS = 6e4;
96
99
  var IP_LIMIT = 20;
97
100
  var SESSION_WINDOW_MS = 60 * 6e4;
98
101
  var SESSION_LIMIT = 50;
99
- function rateLimited() {
102
+ function rateLimited(windowMs) {
100
103
  return new HttpException({
104
+ ...codedError(REGISTRATION_ERROR_CODES.RATE_LIMITED, {
105
+ retryAfterSeconds: Math.ceil(windowMs / 1e3)
106
+ }),
107
+ retryAfterSeconds: Math.ceil(windowMs / 1e3),
101
108
  valid: false,
102
109
  // Superseded by `code` — kept until all consumers read `code`.
103
- reason: "RATE_LIMITED",
104
- code: REGISTRATION_ERROR_CODES.RATE_LIMITED
110
+ reason: "RATE_LIMITED"
105
111
  }, HttpStatus.TOO_MANY_REQUESTS);
106
112
  }
107
113
  __name(rateLimited, "rateLimited");
@@ -116,10 +122,10 @@ var PromoCodeRateLimitGuard = class {
116
122
  const ipKey = ipFingerprint(req);
117
123
  const sessionKey = req.user?.id ?? null;
118
124
  if (this.exceeded(this.ipBuckets, ipKey, IP_WINDOW_MS, IP_LIMIT)) {
119
- throw rateLimited();
125
+ throw rateLimited(IP_WINDOW_MS);
120
126
  }
121
127
  if (sessionKey && this.exceeded(this.sessionBuckets, sessionKey, SESSION_WINDOW_MS, SESSION_LIMIT)) {
122
- throw rateLimited();
128
+ throw rateLimited(SESSION_WINDOW_MS);
123
129
  }
124
130
  return true;
125
131
  }