@saasicat/nest 0.26.1 → 1.0.0-rc.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 (76) hide show
  1. package/LICENSE +90 -201
  2. package/dist/.build-stamp +1 -0
  3. package/dist/_entries.cjs +3175 -2756
  4. package/dist/admin/index.d.cts +2 -2
  5. package/dist/admin/index.d.ts +2 -2
  6. package/dist/admin/index.js +2 -2
  7. package/dist/{admin-stats.service-HUZIU448.d.cts → admin-stats.service-BroyovpL.d.cts} +1 -1
  8. package/dist/{admin-stats.service-Db2exT_d.d.ts → admin-stats.service-G53IEkkt.d.ts} +1 -1
  9. package/dist/billing/index.d.cts +7 -7
  10. package/dist/billing/index.d.ts +7 -7
  11. package/dist/billing/index.js +38 -36
  12. package/dist/catalog/index.d.cts +13 -1
  13. package/dist/catalog/index.d.ts +13 -1
  14. package/dist/catalog/index.js +10 -8
  15. package/dist/checkout-offer/index.js +2 -2
  16. package/dist/chunk-2FR6ZL7R.js +0 -0
  17. package/dist/chunk-2SLTRKXC.js +0 -0
  18. package/dist/{chunk-7ZPFQXHM.js → chunk-3UZW7TU4.js} +1 -1
  19. package/dist/{chunk-XTVAFJ3P.js → chunk-AEEK64XD.js} +3 -3
  20. package/dist/chunk-AOQJEYOL.js +20 -0
  21. package/dist/chunk-H3W6QDQH.js +85 -0
  22. package/dist/{chunk-YYUXKLXK.js → chunk-I7GTA3RX.js} +2 -2
  23. package/dist/{chunk-SN5UOC43.js → chunk-IPOLCDKN.js} +11 -11
  24. package/dist/{chunk-B7NRY2LV.js → chunk-IVEA6M3B.js} +2 -40
  25. package/dist/chunk-JCAZT727.js +1883 -0
  26. package/dist/chunk-JTLKWP3Q.js +792 -0
  27. package/dist/{chunk-E56W4U2P.js → chunk-O2J2HDXA.js} +4 -4
  28. package/dist/{chunk-WKVBNTYC.js → chunk-OUDSQ3PU.js} +6 -6
  29. package/dist/{chunk-MJ32VNZD.js → chunk-P5D5CYO2.js} +18 -18
  30. package/dist/{chunk-L4SUWH5B.js → chunk-QUZU2M33.js} +2 -2
  31. package/dist/{chunk-WPUVJRIN.js → chunk-S6BAD5XM.js} +10 -10
  32. package/dist/{chunk-7X5MSAIL.js → chunk-SH7J5IU7.js} +9 -9
  33. package/dist/{chunk-37HEKVDH.js → chunk-V4OJ43K2.js} +10 -10
  34. package/dist/{chunk-NYLON2VC.js → chunk-VBRYPU7V.js} +2 -2
  35. package/dist/{chunk-B6IWLV7R.js → chunk-VTMCMVYQ.js} +6 -6
  36. package/dist/{chunk-YWDLYOFN.js → chunk-WSPHIIGS.js} +429 -1205
  37. package/dist/{chunk-5ZXBXYXU.js → chunk-WXYJHZCN.js} +3 -3
  38. package/dist/{chunk-6WL6VQ7Z.js → chunk-XBYAFEOR.js} +2 -2
  39. package/dist/{chunk-NNNXXUPT.js → chunk-XEW6YXL5.js} +28 -93
  40. package/dist/chunk-Y43SGD5J.js +50 -0
  41. package/dist/{define-saasicat-BK6RRWWG.d.ts → define-saasicat-BFgeoVG9.d.ts} +28 -5
  42. package/dist/{define-saasicat-D30I-WET.d.cts → define-saasicat-CNUWjfNK.d.cts} +28 -5
  43. package/dist/discovery/index.js +4 -4
  44. package/dist/{enforce-quota.interceptor-B9QueAFf.d.ts → enforce-quota.interceptor-BYqmdFB5.d.ts} +3 -3
  45. package/dist/{enforce-quota.interceptor-DY6CLjoP.d.cts → enforce-quota.interceptor-BxIR63Wn.d.cts} +3 -3
  46. package/dist/entitlement/index.js +9 -6
  47. package/dist/index.d.cts +10 -10
  48. package/dist/index.d.ts +10 -10
  49. package/dist/index.js +61 -52
  50. package/dist/{saas-platform.module-D1mUZPrz.d.ts → module-options-BymIkAsh.d.ts} +68 -55
  51. package/dist/{saas-platform.module-CgalxzcT.d.cts → module-options-DgwBKVpC.d.cts} +68 -55
  52. package/dist/platform/index.d.cts +204 -22
  53. package/dist/platform/index.d.ts +204 -22
  54. package/dist/platform/index.js +49 -25
  55. package/dist/promo/index.d.cts +3 -3
  56. package/dist/promo/index.d.ts +3 -3
  57. package/dist/promo/index.js +3 -3
  58. package/dist/{module-BE17XFLg.d.ts → promo.module-CnzddtJ0.d.ts} +1 -1
  59. package/dist/{module-CHMIyWlf.d.cts → promo.module-DokmUGmm.d.cts} +1 -1
  60. package/dist/registration/index.d.cts +1 -1
  61. package/dist/registration/index.d.ts +1 -1
  62. package/dist/registration/index.js +1 -1
  63. package/dist/subscription-contract/index.js +6 -3
  64. package/dist/{tenant-billing.controller-BSlpFqVA.d.ts → tenant-billing.controller-BQPy5yXh.d.ts} +2 -2
  65. package/dist/{tenant-billing.controller-DHSUrT_N.d.cts → tenant-billing.controller-CODIYzlI.d.cts} +2 -2
  66. package/dist/{subscription-bundles.module-BDbODWvA.d.ts → tenant-billing.module-B0stLoJn.d.ts} +51 -51
  67. package/dist/{subscription-bundles.module-Cfi-lFWF.d.cts → tenant-billing.module-BxJS6fX4.d.cts} +51 -51
  68. package/dist/testing/index.d.cts +14 -14
  69. package/dist/testing/index.d.ts +14 -14
  70. package/dist/testing/index.js +31 -29
  71. package/package.json +6 -6
  72. package/dist/chunk-L4KTQ6CL.js +0 -20
  73. package/dist/chunk-TCBYOFAC.js +0 -1464
  74. /package/dist/{chunk-FY4EJTV4.js → chunk-OYNHOY45.js} +0 -0
  75. /package/dist/{service-D48clObR.d.cts → promo.service-D48clObR.d.cts} +0 -0
  76. /package/dist/{service-D48clObR.d.ts → promo.service-D48clObR.d.ts} +0 -0
@@ -1,1464 +0,0 @@
1
- import {
2
- PromoCodesModule
3
- } from "./chunk-B6IWLV7R.js";
4
- import {
5
- AdminManifestModule,
6
- AdminManifestService,
7
- AdminModule,
8
- AdminResourcesModule,
9
- AdminStatsModule,
10
- MfaService,
11
- SuperAdminGuard
12
- } from "./chunk-SN5UOC43.js";
13
- import {
14
- FEATURE_GUARD_MARKER,
15
- PublicCatalogModule,
16
- REQUIRE_FEATURE_KEY,
17
- SubscriptionBundleModule,
18
- TenantBillingModule,
19
- isPlatformFeatureGuard
20
- } from "./chunk-YWDLYOFN.js";
21
- import {
22
- SubscriptionContractModule
23
- } from "./chunk-B7NRY2LV.js";
24
- import {
25
- CatalogModule
26
- } from "./chunk-7X5MSAIL.js";
27
- import {
28
- CheckoutOfferModule
29
- } from "./chunk-XTVAFJ3P.js";
30
- import {
31
- SaaSiCatPublicRoute
32
- } from "./chunk-YSC46BGM.js";
33
- import {
34
- DiscoveryModule
35
- } from "./chunk-6WL6VQ7Z.js";
36
- import {
37
- EntitlementModule,
38
- LimitExceededError
39
- } from "./chunk-NNNXXUPT.js";
40
- import {
41
- PLAN_CATALOG_TOKEN,
42
- PlanCatalogModule
43
- } from "./chunk-DQKCK7DX.js";
44
- import {
45
- codedError
46
- } from "./chunk-EBJJNTW6.js";
47
- import {
48
- asProvider
49
- } from "./chunk-SABTXESR.js";
50
- import {
51
- ENFORCE_QUOTA_KEY
52
- } from "./chunk-L4SUWH5B.js";
53
- import {
54
- __name
55
- } from "./chunk-SHUYVCID.js";
56
-
57
- // src/setup/tokens.ts
58
- var SETUP_PROVISIONING_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SetupProvisioningPort");
59
- var SETUP_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SetupConfig");
60
-
61
- // src/setup/setup.service.ts
62
- import { BadRequestException, ConflictException, ForbiddenException, Inject, Injectable, UnauthorizedException } from "@nestjs/common";
63
- import { isPlatformUserExistsError, SETUP_ERROR_CODES } from "@saasicat/types";
64
- import { randomBytes, timingSafeEqual } from "crypto";
65
- import QRCode from "qrcode";
66
- function _ts_decorate(decorators, target, key, desc) {
67
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
68
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
69
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
70
- return c > 3 && r && Object.defineProperty(target, key, r), r;
71
- }
72
- __name(_ts_decorate, "_ts_decorate");
73
- function _ts_metadata(k, v) {
74
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
75
- }
76
- __name(_ts_metadata, "_ts_metadata");
77
- function _ts_param(paramIndex, decorator) {
78
- return function(target, key) {
79
- decorator(target, key, paramIndex);
80
- };
81
- }
82
- __name(_ts_param, "_ts_param");
83
- var GENERATED_PASSWORD_BYTES = 12;
84
- function timingSafeEqualStr(a, b) {
85
- const ab = Buffer.from(a, "utf8");
86
- const bb = Buffer.from(b, "utf8");
87
- if (ab.length !== bb.length) return false;
88
- return timingSafeEqual(ab, bb);
89
- }
90
- __name(timingSafeEqualStr, "timingSafeEqualStr");
91
- var SetupService = class {
92
- static {
93
- __name(this, "SetupService");
94
- }
95
- users;
96
- config;
97
- mfa;
98
- constructor(users, config, mfa) {
99
- this.users = users;
100
- this.config = config;
101
- this.mfa = mfa;
102
- }
103
- async status() {
104
- return {
105
- needsSetup: await this.users.countSuperAdmins() === 0
106
- };
107
- }
108
- async setup(req) {
109
- this.assertToken(req.token);
110
- await this.assertNoSuperAdmin();
111
- const email = req.email.trim().toLowerCase();
112
- if (!email.includes("@")) {
113
- throw new BadRequestException(codedError(SETUP_ERROR_CODES.INVALID_EMAIL));
114
- }
115
- const generated = !req.password;
116
- const password = req.password ?? randomBytes(GENERATED_PASSWORD_BYTES).toString("base64url");
117
- let user;
118
- try {
119
- user = await this.users.createSuperAdmin({
120
- email,
121
- password
122
- });
123
- } catch (err) {
124
- if (isPlatformUserExistsError(err)) {
125
- throw new ConflictException({
126
- code: SETUP_ERROR_CODES.EMAIL_EXISTS,
127
- message: err.message
128
- });
129
- }
130
- throw err;
131
- }
132
- const totp = await this.mfa.setup(user.id, user.email, this.config.mfaIssuer);
133
- const qrDataUrl = await QRCode.toDataURL(totp.otpauthUri, {
134
- width: 220,
135
- margin: 1
136
- });
137
- return {
138
- userId: user.id,
139
- email: user.email,
140
- otpauthUri: totp.otpauthUri,
141
- qrDataUrl,
142
- secret: totp.secret,
143
- ...generated ? {
144
- generatedPassword: password
145
- } : {}
146
- };
147
- }
148
- async confirmMfa(req) {
149
- this.assertToken(req.token);
150
- const ok = await this.mfa.verify({
151
- userId: req.userId,
152
- code: req.code
153
- });
154
- return {
155
- ok
156
- };
157
- }
158
- assertToken(token) {
159
- const expected = process.env[this.config.setupTokenEnvVar]?.trim();
160
- if (!expected) {
161
- throw new ForbiddenException({
162
- code: SETUP_ERROR_CODES.SETUP_DISABLED,
163
- message: `${this.config.setupTokenEnvVar} is not set \u2014 setup is disabled.`,
164
- params: {
165
- envVar: this.config.setupTokenEnvVar
166
- }
167
- });
168
- }
169
- if (!token || !timingSafeEqualStr(token, expected)) {
170
- throw new UnauthorizedException(codedError(SETUP_ERROR_CODES.INVALID_SETUP_TOKEN));
171
- }
172
- }
173
- async assertNoSuperAdmin() {
174
- if (await this.users.countSuperAdmins() > 0) {
175
- throw new ConflictException(codedError(SETUP_ERROR_CODES.SETUP_ALREADY_DONE));
176
- }
177
- }
178
- };
179
- SetupService = _ts_decorate([
180
- Injectable(),
181
- _ts_param(0, Inject(SETUP_PROVISIONING_PORT_TOKEN)),
182
- _ts_param(1, Inject(SETUP_CONFIG_TOKEN)),
183
- _ts_metadata("design:type", Function),
184
- _ts_metadata("design:paramtypes", [
185
- typeof SuperAdminProvisioningPort === "undefined" ? Object : SuperAdminProvisioningPort,
186
- typeof SetupConfig === "undefined" ? Object : SetupConfig,
187
- typeof MfaService === "undefined" ? Object : MfaService
188
- ])
189
- ], SetupService);
190
-
191
- // src/setup/setup.controller.ts
192
- import { Body, Controller, Get, Post } from "@nestjs/common";
193
- import { IsEmail, IsNotEmpty, IsOptional, IsString, MinLength } from "class-validator";
194
- function _ts_decorate2(decorators, target, key, desc) {
195
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
196
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
197
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
198
- return c > 3 && r && Object.defineProperty(target, key, r), r;
199
- }
200
- __name(_ts_decorate2, "_ts_decorate");
201
- function _ts_metadata2(k, v) {
202
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
203
- }
204
- __name(_ts_metadata2, "_ts_metadata");
205
- function _ts_param2(paramIndex, decorator) {
206
- return function(target, key) {
207
- decorator(target, key, paramIndex);
208
- };
209
- }
210
- __name(_ts_param2, "_ts_param");
211
- var SetupDto = class SetupDto2 {
212
- static {
213
- __name(this, "SetupDto");
214
- }
215
- token;
216
- email;
217
- password;
218
- };
219
- _ts_decorate2([
220
- IsString(),
221
- IsNotEmpty(),
222
- _ts_metadata2("design:type", String)
223
- ], SetupDto.prototype, "token", void 0);
224
- _ts_decorate2([
225
- IsEmail(),
226
- _ts_metadata2("design:type", String)
227
- ], SetupDto.prototype, "email", void 0);
228
- _ts_decorate2([
229
- IsOptional(),
230
- IsString(),
231
- MinLength(8),
232
- _ts_metadata2("design:type", String)
233
- ], SetupDto.prototype, "password", void 0);
234
- var SetupConfirmMfaDto = class SetupConfirmMfaDto2 {
235
- static {
236
- __name(this, "SetupConfirmMfaDto");
237
- }
238
- token;
239
- userId;
240
- code;
241
- };
242
- _ts_decorate2([
243
- IsString(),
244
- IsNotEmpty(),
245
- _ts_metadata2("design:type", String)
246
- ], SetupConfirmMfaDto.prototype, "token", void 0);
247
- _ts_decorate2([
248
- IsString(),
249
- IsNotEmpty(),
250
- _ts_metadata2("design:type", String)
251
- ], SetupConfirmMfaDto.prototype, "userId", void 0);
252
- _ts_decorate2([
253
- IsString(),
254
- IsNotEmpty(),
255
- _ts_metadata2("design:type", String)
256
- ], SetupConfirmMfaDto.prototype, "code", void 0);
257
- var SetupController = class {
258
- static {
259
- __name(this, "SetupController");
260
- }
261
- setup;
262
- constructor(setup) {
263
- this.setup = setup;
264
- }
265
- status() {
266
- return this.setup.status();
267
- }
268
- run(dto) {
269
- return this.setup.setup(dto);
270
- }
271
- confirm(dto) {
272
- return this.setup.confirmMfa(dto);
273
- }
274
- };
275
- _ts_decorate2([
276
- Get("status"),
277
- _ts_metadata2("design:type", Function),
278
- _ts_metadata2("design:paramtypes", []),
279
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
280
- ], SetupController.prototype, "status", null);
281
- _ts_decorate2([
282
- Post(),
283
- _ts_param2(0, Body()),
284
- _ts_metadata2("design:type", Function),
285
- _ts_metadata2("design:paramtypes", [
286
- typeof SetupDto === "undefined" ? Object : SetupDto
287
- ]),
288
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
289
- ], SetupController.prototype, "run", null);
290
- _ts_decorate2([
291
- Post("confirm-mfa"),
292
- _ts_param2(0, Body()),
293
- _ts_metadata2("design:type", Function),
294
- _ts_metadata2("design:paramtypes", [
295
- typeof SetupConfirmMfaDto === "undefined" ? Object : SetupConfirmMfaDto
296
- ]),
297
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
298
- ], SetupController.prototype, "confirm", null);
299
- SetupController = _ts_decorate2([
300
- Controller("admin/setup"),
301
- SaaSiCatPublicRoute(),
302
- _ts_metadata2("design:type", Function),
303
- _ts_metadata2("design:paramtypes", [
304
- typeof SetupService === "undefined" ? Object : SetupService
305
- ])
306
- ], SetupController);
307
-
308
- // src/setup/setup.module.ts
309
- import { Module } from "@nestjs/common";
310
- function _ts_decorate3(decorators, target, key, desc) {
311
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
312
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
313
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
314
- return c > 3 && r && Object.defineProperty(target, key, r), r;
315
- }
316
- __name(_ts_decorate3, "_ts_decorate");
317
- var DEFAULT_SETUP_TOKEN_ENV_VAR = "SETUP_TOKEN";
318
- var DEFAULT_MFA_ISSUER = "SuperAdmin";
319
- var SetupModule = class _SetupModule {
320
- static {
321
- __name(this, "SetupModule");
322
- }
323
- static forRoot(options) {
324
- return {
325
- module: _SetupModule,
326
- global: options.global ?? false,
327
- imports: options.imports ?? [],
328
- controllers: [
329
- SetupController
330
- ],
331
- providers: [
332
- asProvider(SETUP_PROVISIONING_PORT_TOKEN, options.provisioningPort),
333
- {
334
- provide: SETUP_CONFIG_TOKEN,
335
- useValue: {
336
- setupTokenEnvVar: options.setupTokenEnvVar ?? DEFAULT_SETUP_TOKEN_ENV_VAR,
337
- mfaIssuer: options.mfaIssuer ?? DEFAULT_MFA_ISSUER
338
- }
339
- },
340
- SetupService,
341
- ...options.extraProviders ?? []
342
- ],
343
- exports: [
344
- SetupService
345
- ]
346
- };
347
- }
348
- };
349
- SetupModule = _ts_decorate3([
350
- Module({})
351
- ], SetupModule);
352
-
353
- // src/platform/plan-resolver.port.ts
354
- var PLAN_RESOLVER_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/PlanResolverPort");
355
- var StaticPlanResolver = class {
356
- static {
357
- __name(this, "StaticPlanResolver");
358
- }
359
- planId;
360
- constructor(planId) {
361
- this.planId = planId;
362
- }
363
- async getPlanIdForTenant() {
364
- return this.planId;
365
- }
366
- };
367
-
368
- // src/platform/static-entitlement.service.ts
369
- import { Inject as Inject2, Injectable as Injectable2 } from "@nestjs/common";
370
- function _ts_decorate4(decorators, target, key, desc) {
371
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
372
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
373
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
374
- return c > 3 && r && Object.defineProperty(target, key, r), r;
375
- }
376
- __name(_ts_decorate4, "_ts_decorate");
377
- function _ts_metadata3(k, v) {
378
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
379
- }
380
- __name(_ts_metadata3, "_ts_metadata");
381
- function _ts_param3(paramIndex, decorator) {
382
- return function(target, key) {
383
- decorator(target, key, paramIndex);
384
- };
385
- }
386
- __name(_ts_param3, "_ts_param");
387
- var StaticEntitlementService = class {
388
- static {
389
- __name(this, "StaticEntitlementService");
390
- }
391
- catalog;
392
- resolver;
393
- constructor(catalog, resolver) {
394
- this.catalog = catalog;
395
- this.resolver = resolver;
396
- }
397
- /**
398
- * Returns the effective features + quotas of a tenant from the
399
- * plan catalog. When the plan is missing: an empty snapshot (no feature,
400
- * all quotas at 0).
401
- */
402
- async snapshot(tenantId) {
403
- const planId = await this.resolver.getPlanIdForTenant(tenantId);
404
- if (!planId) {
405
- return {
406
- planId: null,
407
- features: [],
408
- quotas: {}
409
- };
410
- }
411
- const plan = this.findPlan(planId);
412
- if (!plan) {
413
- return {
414
- planId,
415
- features: [],
416
- quotas: {}
417
- };
418
- }
419
- return {
420
- planId,
421
- features: plan.features ?? [],
422
- quotas: plan.quotas ?? {}
423
- };
424
- }
425
- /** Convenience helper for tests / synchronous checks in the UI manifest. */
426
- async hasFeature(tenantId, featureKey) {
427
- const snap = await this.snapshot(tenantId);
428
- return snap.features.includes(featureKey);
429
- }
430
- async quotaLimit(tenantId, quotaKey) {
431
- const snap = await this.snapshot(tenantId);
432
- const value = snap.quotas[quotaKey];
433
- return value === void 0 ? null : value;
434
- }
435
- findPlan(planId) {
436
- return (this.catalog.plans ?? []).find((p) => p.id === planId);
437
- }
438
- };
439
- StaticEntitlementService = _ts_decorate4([
440
- Injectable2(),
441
- _ts_param3(0, Inject2(PLAN_CATALOG_TOKEN)),
442
- _ts_param3(1, Inject2(PLAN_RESOLVER_PORT_TOKEN)),
443
- _ts_metadata3("design:type", Function),
444
- _ts_metadata3("design:paramtypes", [
445
- typeof PlanCatalog === "undefined" ? Object : PlanCatalog,
446
- typeof PlanResolverPort === "undefined" ? Object : PlanResolverPort
447
- ])
448
- ], StaticEntitlementService);
449
-
450
- // src/platform/feature-guard-coverage.check.ts
451
- import { Inject as Inject3, Injectable as Injectable3, Logger } from "@nestjs/common";
452
- import { DiscoveryService, MetadataScanner } from "@nestjs/core";
453
- function _ts_decorate5(decorators, target, key, desc) {
454
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
455
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
456
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
457
- return c > 3 && r && Object.defineProperty(target, key, r), r;
458
- }
459
- __name(_ts_decorate5, "_ts_decorate");
460
- function _ts_metadata4(k, v) {
461
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
462
- }
463
- __name(_ts_metadata4, "_ts_metadata");
464
- function _ts_param4(paramIndex, decorator) {
465
- return function(target, key) {
466
- decorator(target, key, paramIndex);
467
- };
468
- }
469
- __name(_ts_param4, "_ts_param");
470
- var GUARDS_METADATA = "__guards__";
471
- var METHOD_METADATA = "method";
472
- var FeatureGuardCoverageCheck = class {
473
- static {
474
- __name(this, "FeatureGuardCoverageCheck");
475
- }
476
- discoveryService;
477
- metadataScanner;
478
- logger = new Logger("SaaSiCat");
479
- constructor(discoveryService, metadataScanner) {
480
- this.discoveryService = discoveryService;
481
- this.metadataScanner = metadataScanner;
482
- }
483
- onApplicationBootstrap() {
484
- const uncovered = this.findUncoveredRoutes();
485
- if (uncovered.length === 0) return;
486
- const list = uncovered.map((r) => ` ${r.controller}.${r.handler} \u2014 requires ${r.features.join(" or ")}`).join("\n");
487
- this.logger.warn(`globalFeatureGuard is off and ${uncovered.length} annotated route(s) have no feature guard in front of them, so they serve unlicensed traffic:
488
- ${list}
489
- Bind one behind your auth guard \u2014 @UseGuards(JwtAuthGuard, StaticFeatureGuard), or FeatureGuard from @saasicat/nest/billing on the V3 entitlement path. A guard of your own that wraps either one is not recognised here; if that is what these routes use, they are covered.`);
490
- }
491
- /**
492
- * Annotated handlers whose own guards and whose controller's guards contain
493
- * no recognisable feature guard.
494
- *
495
- * Deliberately conservative in one direction only: an unrecognised wrapper
496
- * is reported (and the message says so) rather than assumed safe, because
497
- * the named route is cheap to check. The reverse — staying silent about a
498
- * route with no guard at all — is the failure this exists to prevent.
499
- */
500
- findUncoveredRoutes() {
501
- const uncovered = [];
502
- for (const wrapper of this.discoveryService.getControllers()) {
503
- const instance = wrapper.instance;
504
- if (!instance || typeof instance !== "object") continue;
505
- const ctor = instance.constructor;
506
- if (!ctor) continue;
507
- const classGuards = readGuards(ctor);
508
- const prototype = Object.getPrototypeOf(instance);
509
- for (const method of this.metadataScanner.getAllMethodNames(prototype)) {
510
- const handler = instance[method];
511
- if (typeof handler !== "function") continue;
512
- if (Reflect.getMetadata(METHOD_METADATA, handler) === void 0) continue;
513
- const features = readFeatures(handler) ?? readFeatures(ctor) ?? /* not annotated */
514
- null;
515
- if (!features || features.length === 0) continue;
516
- const guards = [
517
- ...classGuards,
518
- ...readGuards(handler)
519
- ];
520
- if (guards.some(isPlatformFeatureGuard)) continue;
521
- uncovered.push({
522
- controller: ctor.name,
523
- handler: method,
524
- features
525
- });
526
- }
527
- }
528
- return uncovered;
529
- }
530
- };
531
- FeatureGuardCoverageCheck = _ts_decorate5([
532
- Injectable3(),
533
- _ts_param4(0, Inject3(DiscoveryService)),
534
- _ts_param4(1, Inject3(MetadataScanner)),
535
- _ts_metadata4("design:type", Function),
536
- _ts_metadata4("design:paramtypes", [
537
- typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
538
- typeof MetadataScanner === "undefined" ? Object : MetadataScanner
539
- ])
540
- ], FeatureGuardCoverageCheck);
541
- function readFeatures(target) {
542
- const value = Reflect.getMetadata(REQUIRE_FEATURE_KEY, target);
543
- return Array.isArray(value) ? value : null;
544
- }
545
- __name(readFeatures, "readFeatures");
546
- function readGuards(target) {
547
- const value = Reflect.getMetadata(GUARDS_METADATA, target);
548
- if (!Array.isArray(value)) return [];
549
- return value.flatMap((guard) => typeof guard === "function" ? [
550
- guard
551
- ] : [
552
- guard,
553
- guard?.constructor
554
- ]);
555
- }
556
- __name(readGuards, "readGuards");
557
-
558
- // src/platform/static-feature.guard.ts
559
- import { ForbiddenException as ForbiddenException2, Inject as Inject4, Injectable as Injectable4, Optional } from "@nestjs/common";
560
- import { Reflector } from "@nestjs/core";
561
- import { AUTH_ERROR_CODES, FEATURE_NOT_LICENSED } from "@saasicat/types";
562
- function _ts_decorate6(decorators, target, key, desc) {
563
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
564
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
565
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
566
- return c > 3 && r && Object.defineProperty(target, key, r), r;
567
- }
568
- __name(_ts_decorate6, "_ts_decorate");
569
- function _ts_metadata5(k, v) {
570
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
571
- }
572
- __name(_ts_metadata5, "_ts_metadata");
573
- function _ts_param5(paramIndex, decorator) {
574
- return function(target, key) {
575
- decorator(target, key, paramIndex);
576
- };
577
- }
578
- __name(_ts_param5, "_ts_param");
579
- var STATIC_FEATURE_GUARD_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/StaticFeatureGuardConfig");
580
- var StaticFeatureGuard = class {
581
- static {
582
- __name(this, "StaticFeatureGuard");
583
- }
584
- reflector;
585
- entitlements;
586
- config;
587
- /** Lets `FeatureGuardCoverageCheck` recognise this guard across CJS entries. */
588
- static [FEATURE_GUARD_MARKER] = true;
589
- constructor(reflector, entitlements, config = null) {
590
- this.reflector = reflector;
591
- this.entitlements = entitlements;
592
- this.config = config;
593
- }
594
- async canActivate(context) {
595
- const required = this.reflector.getAllAndOverride(REQUIRE_FEATURE_KEY, [
596
- context.getHandler(),
597
- context.getClass()
598
- ]);
599
- if (!required || required.length === 0) return true;
600
- const request = context.switchToHttp().getRequest();
601
- const user = request.user;
602
- if (!user) {
603
- throw new ForbiddenException2({
604
- code: AUTH_ERROR_CODES.NOT_AUTHENTICATED,
605
- message: "Not authenticated"
606
- });
607
- }
608
- const role = this.config?.userRoleResolver ? this.config.userRoleResolver(user) : user.role ?? user.platformRole;
609
- if (role === "SUPER_ADMIN") return true;
610
- const tenantId = this.config?.tenantIdResolver ? this.config.tenantIdResolver(request) : request.tenantId ?? user.tenantId;
611
- if (!tenantId) {
612
- throw new ForbiddenException2({
613
- code: AUTH_ERROR_CODES.NO_TENANT_ASSIGNED,
614
- message: "No tenant assigned"
615
- });
616
- }
617
- const snap = await this.entitlements.snapshot(tenantId);
618
- const allowed = required.some((f) => snap.features.includes(f));
619
- if (!allowed) {
620
- const body = {
621
- code: FEATURE_NOT_LICENSED,
622
- featureKey: required[0],
623
- featureKeys: required,
624
- offers: [],
625
- message: `Feature ${required.join(" / ")} is not included in the current plan.`
626
- };
627
- throw new ForbiddenException2(body);
628
- }
629
- return true;
630
- }
631
- };
632
- StaticFeatureGuard = _ts_decorate6([
633
- Injectable4(),
634
- _ts_param5(0, Inject4(Reflector)),
635
- _ts_param5(1, Inject4(StaticEntitlementService)),
636
- _ts_param5(2, Optional()),
637
- _ts_param5(2, Inject4(STATIC_FEATURE_GUARD_CONFIG_TOKEN)),
638
- _ts_metadata5("design:type", Function),
639
- _ts_metadata5("design:paramtypes", [
640
- typeof Reflector === "undefined" ? Object : Reflector,
641
- typeof StaticEntitlementService === "undefined" ? Object : StaticEntitlementService,
642
- Object
643
- ])
644
- ], StaticFeatureGuard);
645
-
646
- // src/platform/enforce-quota.interceptor.ts
647
- import { Inject as Inject5, Injectable as Injectable5, Optional as Optional2 } from "@nestjs/common";
648
- import { Reflector as Reflector2 } from "@nestjs/core";
649
- import { from } from "rxjs";
650
- import { switchMap } from "rxjs/operators";
651
- function _ts_decorate7(decorators, target, key, desc) {
652
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
653
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
654
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
655
- return c > 3 && r && Object.defineProperty(target, key, r), r;
656
- }
657
- __name(_ts_decorate7, "_ts_decorate");
658
- function _ts_metadata6(k, v) {
659
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
660
- }
661
- __name(_ts_metadata6, "_ts_metadata");
662
- function _ts_param6(paramIndex, decorator) {
663
- return function(target, key) {
664
- decorator(target, key, paramIndex);
665
- };
666
- }
667
- __name(_ts_param6, "_ts_param");
668
- var QUOTA_PROVIDERS_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/QuotaProviders");
669
- var EnforceQuotaInterceptor = class {
670
- static {
671
- __name(this, "EnforceQuotaInterceptor");
672
- }
673
- reflector;
674
- entitlements;
675
- providers;
676
- constructor(reflector, entitlements, providers = null) {
677
- this.reflector = reflector;
678
- this.entitlements = entitlements;
679
- this.providers = providers;
680
- }
681
- intercept(context, next) {
682
- const meta = this.reflector.getAllAndOverride(ENFORCE_QUOTA_KEY, [
683
- context.getHandler(),
684
- context.getClass()
685
- ]);
686
- if (!meta?.quotaKey) return next.handle();
687
- return from(this.check(context, meta)).pipe(switchMap(() => next.handle()));
688
- }
689
- async check(context, meta) {
690
- const request = context.switchToHttp().getRequest();
691
- const user = request.user;
692
- if (!user) return;
693
- const role = user.role ?? user.platformRole;
694
- if (role === "SUPER_ADMIN") return;
695
- const tenantId = request.tenantId ?? user.tenantId;
696
- if (!tenantId) return;
697
- const provider = (this.providers ?? []).find((p) => p.key === meta.quotaKey);
698
- if (!provider) {
699
- return;
700
- }
701
- const limit = await this.entitlements.quotaLimit(tenantId, meta.quotaKey);
702
- if (limit === null || limit === -1) return;
703
- const current = await provider.count(tenantId);
704
- const delta = meta.incrementBy ?? 1;
705
- if (current + delta > limit) {
706
- throw new LimitExceededError(meta.quotaKey, limit, current);
707
- }
708
- }
709
- };
710
- EnforceQuotaInterceptor = _ts_decorate7([
711
- Injectable5(),
712
- _ts_param6(0, Inject5(Reflector2)),
713
- _ts_param6(1, Inject5(StaticEntitlementService)),
714
- _ts_param6(2, Optional2()),
715
- _ts_param6(2, Inject5(QUOTA_PROVIDERS_TOKEN)),
716
- _ts_metadata6("design:type", Function),
717
- _ts_metadata6("design:paramtypes", [
718
- typeof Reflector2 === "undefined" ? Object : Reflector2,
719
- typeof StaticEntitlementService === "undefined" ? Object : StaticEntitlementService,
720
- Object
721
- ])
722
- ], EnforceQuotaInterceptor);
723
-
724
- // src/platform/quota-providers-usage-snapshot.ts
725
- var QuotaProvidersUsageSnapshot = class {
726
- static {
727
- __name(this, "QuotaProvidersUsageSnapshot");
728
- }
729
- providers;
730
- constructor(providers) {
731
- this.providers = providers;
732
- }
733
- async snapshot(tenantId) {
734
- const entries = await Promise.all(this.providers.map(async (provider) => [
735
- provider.key,
736
- await provider.count(tenantId)
737
- ]));
738
- return Object.fromEntries(entries);
739
- }
740
- };
741
-
742
- // src/platform/subscription-plan-resolver.ts
743
- var DEFAULT_ACTIVE_STATUSES = /* @__PURE__ */ new Set([
744
- "ACTIVE",
745
- "TRIAL"
746
- ]);
747
- var SubscriptionPlanResolver = class {
748
- static {
749
- __name(this, "SubscriptionPlanResolver");
750
- }
751
- subscriptions;
752
- activeStatuses;
753
- constructor(subscriptions, activeStatuses = DEFAULT_ACTIVE_STATUSES) {
754
- this.subscriptions = subscriptions;
755
- this.activeStatuses = activeStatuses;
756
- }
757
- async getPlanIdForTenant(tenantId) {
758
- const subscription = await this.subscriptions.findByTenantId(tenantId);
759
- if (!subscription || !this.activeStatuses.has(subscription.status)) return null;
760
- return subscription.plan;
761
- }
762
- };
763
-
764
- // src/platform/tenant-manifest.service.ts
765
- import { Injectable as Injectable6 } from "@nestjs/common";
766
- function _ts_decorate8(decorators, target, key, desc) {
767
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
768
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
769
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
770
- return c > 3 && r && Object.defineProperty(target, key, r), r;
771
- }
772
- __name(_ts_decorate8, "_ts_decorate");
773
- function _ts_metadata7(k, v) {
774
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
775
- }
776
- __name(_ts_metadata7, "_ts_metadata");
777
- var TenantManifestService = class {
778
- static {
779
- __name(this, "TenantManifestService");
780
- }
781
- entitlements;
782
- navItems = [];
783
- constructor(entitlements) {
784
- this.entitlements = entitlements;
785
- }
786
- /**
787
- * Call in the app's `OnModuleInit`: registers app navigation for the
788
- * Tenant UI. Idempotent: the same `id` overwrites.
789
- */
790
- registerNavItem(item) {
791
- const existing = this.navItems.findIndex((i) => i.id === item.id);
792
- if (existing >= 0) this.navItems[existing] = item;
793
- else this.navItems.push(item);
794
- }
795
- /** Bulk variant. */
796
- registerNavItems(items) {
797
- for (const item of items) this.registerNavItem(item);
798
- }
799
- /**
800
- * Returns the filtered manifest for a Tenant. NavItems with
801
- * `requiresFeature` are filtered out server-side as soon as none of the
802
- * required features are present in the entitlement snapshot.
803
- */
804
- async getManifest(tenantId) {
805
- const snap = await this.entitlements.snapshot(tenantId);
806
- const featureSet = new Set(snap.features);
807
- const visible = this.navItems.filter((item) => isVisible(item, featureSet)).map((item) => ({
808
- ...item
809
- })).sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
810
- return {
811
- schemaVersion: 1,
812
- tenant: {
813
- id: tenantId
814
- },
815
- planId: snap.planId,
816
- features: snap.features,
817
- quotas: snap.quotas,
818
- navigation: visible
819
- };
820
- }
821
- };
822
- TenantManifestService = _ts_decorate8([
823
- Injectable6(),
824
- _ts_metadata7("design:type", Function),
825
- _ts_metadata7("design:paramtypes", [
826
- typeof StaticEntitlementService === "undefined" ? Object : StaticEntitlementService
827
- ])
828
- ], TenantManifestService);
829
- function isVisible(item, features) {
830
- if (!item.requiresFeature) return true;
831
- const required = Array.isArray(item.requiresFeature) ? item.requiresFeature : [
832
- item.requiresFeature
833
- ];
834
- return required.some((f) => features.has(f));
835
- }
836
- __name(isVisible, "isVisible");
837
-
838
- // src/platform/tenant-manifest.controller.ts
839
- import { Controller as Controller2, Get as Get2, Inject as Inject6, Req, UseGuards } from "@nestjs/common";
840
- function _ts_decorate9(decorators, target, key, desc) {
841
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
842
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
843
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
844
- return c > 3 && r && Object.defineProperty(target, key, r), r;
845
- }
846
- __name(_ts_decorate9, "_ts_decorate");
847
- function _ts_metadata8(k, v) {
848
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
849
- }
850
- __name(_ts_metadata8, "_ts_metadata");
851
- function _ts_param7(paramIndex, decorator) {
852
- return function(target, key) {
853
- decorator(target, key, paramIndex);
854
- };
855
- }
856
- __name(_ts_param7, "_ts_param");
857
- function buildTenantManifestController(options) {
858
- const path = options.path ?? "tenant/manifest";
859
- let GeneratedTenantManifestController = class GeneratedTenantManifestController {
860
- static {
861
- __name(this, "GeneratedTenantManifestController");
862
- }
863
- svc;
864
- constructor(svc) {
865
- this.svc = svc;
866
- }
867
- async get(req) {
868
- const tenantId = req.user?.tenantId ?? req.tenantId;
869
- if (!tenantId) {
870
- throw new Error("No tenant on the request \u2014 TenantManifest requires user.tenantId.");
871
- }
872
- return this.svc.getManifest(tenantId);
873
- }
874
- };
875
- _ts_decorate9([
876
- Get2(),
877
- _ts_param7(0, Req()),
878
- _ts_metadata8("design:type", Function),
879
- _ts_metadata8("design:paramtypes", [
880
- typeof RequestWithUser === "undefined" ? Object : RequestWithUser
881
- ]),
882
- _ts_metadata8("design:returntype", Promise)
883
- ], GeneratedTenantManifestController.prototype, "get", null);
884
- GeneratedTenantManifestController = _ts_decorate9([
885
- Controller2(path),
886
- UseGuards(...options.guards),
887
- _ts_param7(0, Inject6(TenantManifestService)),
888
- _ts_metadata8("design:type", Function),
889
- _ts_metadata8("design:paramtypes", [
890
- typeof TenantManifestService === "undefined" ? Object : TenantManifestService
891
- ])
892
- ], GeneratedTenantManifestController);
893
- return GeneratedTenantManifestController;
894
- }
895
- __name(buildTenantManifestController, "buildTenantManifestController");
896
-
897
- // src/platform/saas-platform.module.ts
898
- import { Logger as Logger2, Module as Module2 } from "@nestjs/common";
899
- import { APP_GUARD, APP_INTERCEPTOR } from "@nestjs/core";
900
- import { assertPersistenceCapabilities } from "@saasicat/types";
901
- import { DiscoveryModule as NestDiscoveryModule } from "@nestjs/core";
902
- function _ts_decorate10(decorators, target, key, desc) {
903
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
904
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
905
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
906
- return c > 3 && r && Object.defineProperty(target, key, r), r;
907
- }
908
- __name(_ts_decorate10, "_ts_decorate");
909
- var PLATFORM_LOGGER = new Logger2("SaaSiCat");
910
- var PLATFORM_SUBSCRIPTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/PlatformSubscriptionRepository");
911
- var STANDARD_MANIFEST_REGISTRATION_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform-nest/StandardManifestRegistration");
912
- function buildStandardManifestContribution(catalog, adminResources, promoCodes) {
913
- const capabilities = {
914
- "discovery.read": true
915
- };
916
- if (catalog && catalog.adminControllers !== false) {
917
- Object.assign(capabilities, {
918
- "plans.read": true,
919
- "plans.publish": true,
920
- "bundles.read": true,
921
- "bundles.write": true,
922
- "bundles.publish": true,
923
- "marketingProjections.read": true,
924
- "marketingProjections.write": true
925
- });
926
- }
927
- const navigation = {};
928
- if (adminResources) {
929
- Object.assign(capabilities, {
930
- "tenants.read": true,
931
- "tenants.suspend": true,
932
- "tenants.reactivate": true,
933
- "users.read": true,
934
- "audit.read": true,
935
- "subscriptions.read": true
936
- });
937
- navigation.standardPages = {
938
- subscriptions: {
939
- enabled: true,
940
- requiredCapability: "subscriptions.read"
941
- }
942
- };
943
- }
944
- if (promoCodes) {
945
- Object.assign(capabilities, {
946
- "promoCodes.read": true,
947
- "promoCodes.write": true,
948
- "promoCodes.delete": true
949
- });
950
- navigation.standardPages = {
951
- ...navigation.standardPages ?? {},
952
- promoCodes: {
953
- enabled: true,
954
- requiredCapability: "promoCodes.read"
955
- }
956
- };
957
- }
958
- return {
959
- capabilities,
960
- navigation: navigation.standardPages ? navigation : void 0
961
- };
962
- }
963
- __name(buildStandardManifestContribution, "buildStandardManifestContribution");
964
- function normalizeTenantAuthGuards(guards) {
965
- if (!Array.isArray(guards)) return guards;
966
- return {
967
- useFactory: /* @__PURE__ */ __name((...instances) => instances, "useFactory"),
968
- inject: guards
969
- };
970
- }
971
- __name(normalizeTenantAuthGuards, "normalizeTenantAuthGuards");
972
- function quotaUsageSnapshotProvider(quotaProviders) {
973
- return {
974
- useFactory: /* @__PURE__ */ __name((...providers) => new QuotaProvidersUsageSnapshot(providers), "useFactory"),
975
- inject: quotaProviders
976
- };
977
- }
978
- __name(quotaUsageSnapshotProvider, "quotaUsageSnapshotProvider");
979
- function buildMinimalManifestConfig() {
980
- return {
981
- useFactory: /* @__PURE__ */ __name((catalog) => ({
982
- project: {
983
- key: catalog.projectKey,
984
- displayName: catalog.app?.name ?? catalog.projectKey,
985
- label: catalog.app?.label,
986
- icon: catalog.app?.icon,
987
- logoUrl: catalog.app?.logoUrl,
988
- environment: process.env.NODE_ENV === "production" ? "production" : "development",
989
- availableLocales: catalog.marketing?.availableLocales,
990
- defaultLocale: catalog.marketing?.availableLocales?.[0]
991
- },
992
- build: {
993
- platformPackageVersion: "0.0.0",
994
- appVersion: "0.0.0"
995
- },
996
- planCatalogSnapshot: {
997
- source: "saas-platform-module",
998
- hash: "sha256-quickstart",
999
- currency: catalog.currency,
1000
- vatRate: catalog.vatRate,
1001
- plans: catalog.plans ?? [],
1002
- features: catalog.features ?? []
1003
- }
1004
- }), "useFactory"),
1005
- inject: [
1006
- PLAN_CATALOG_TOKEN
1007
- ]
1008
- };
1009
- }
1010
- __name(buildMinimalManifestConfig, "buildMinimalManifestConfig");
1011
- var SaasPlatformModule = class _SaasPlatformModule {
1012
- static {
1013
- __name(this, "SaasPlatformModule");
1014
- }
1015
- static forRoot(options) {
1016
- const explicit = options.adapters ?? {};
1017
- const persistence = options.persistence;
1018
- const catalogConfig = options.catalog || null;
1019
- const tenantBillingConfig = options.tenantBilling || null;
1020
- const subscriptionBundlesConfig = options.subscriptionBundles || null;
1021
- const adminResourcesConfig = options.adminResources || null;
1022
- const promoCodesConfig = options.promoCodes || null;
1023
- const setupConfig = options.setup || null;
1024
- const adminStatsConfig = options.adminStats || null;
1025
- const checkoutOfferConfig = options.checkoutOffer || null;
1026
- const subscriptionContractConfig = options.subscriptionContract || null;
1027
- const requiresFullEntitlement = Boolean(options.entitlement || tenantBillingConfig || subscriptionBundlesConfig);
1028
- const adapters = {
1029
- mfa: explicit.mfa ?? persistence?.core.mfa,
1030
- audit: explicit.audit ?? persistence?.core.audit,
1031
- rlsBypass: explicit.rlsBypass ?? persistence?.core.rlsBypass,
1032
- planCatalogReadSink: explicit.planCatalogReadSink ?? persistence?.planCatalogReadSink,
1033
- planResolver: explicit.planResolver,
1034
- subscriptionRepository: explicit.subscriptionRepository ?? persistence?.entitlement?.subscriptionRepository,
1035
- planVersionRepository: explicit.planVersionRepository ?? persistence?.entitlement?.planVersionRepository,
1036
- transactionRunner: explicit.transactionRunner ?? persistence?.core.transactionRunner
1037
- };
1038
- const missingCore = [
1039
- "mfa",
1040
- "audit",
1041
- "rlsBypass"
1042
- ].filter((key) => adapters[key] === void 0);
1043
- if (missingCore.length) {
1044
- throw new Error(`SaasPlatformModule.forRoot: adapters missing (provide them via \`adapters\` or a \`persistence\` bundle): ${missingCore.join(", ")}`);
1045
- }
1046
- const mfaPort = adapters.mfa;
1047
- const auditPort = adapters.audit;
1048
- const rlsBypassPort = adapters.rlsBypass;
1049
- if (!options.planCatalog && (!adapters.planCatalogReadSink || !options.dbCatalog)) {
1050
- 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 }).");
1051
- }
1052
- if (catalogConfig && !persistence?.catalog) {
1053
- throw new Error("SaasPlatformModule.forRoot: catalog is enabled, but `persistence.catalog` is missing. Use a complete persistence bundle or wire CatalogModule directly.");
1054
- }
1055
- if (adminResourcesConfig && adminResourcesConfig !== true && !adminResourcesConfig.resources && !persistence?.adminResources) {
1056
- throw new Error("SaasPlatformModule.forRoot: adminResources is enabled, but `persistence.adminResources` is missing.");
1057
- }
1058
- if (promoCodesConfig && (!persistence?.promo || !adapters.transactionRunner)) {
1059
- throw new Error("SaasPlatformModule.forRoot: promoCodes requires `persistence.promo` and a transactionRunner.");
1060
- }
1061
- if (setupConfig && !((setupConfig === true ? void 0 : setupConfig.provisioningPort) ?? persistence?.core.superAdminProvisioning)) {
1062
- throw new Error("SaasPlatformModule.forRoot: setup is enabled, but no provisioningPort is available (set `setup.provisioningPort` or `persistence.core.superAdminProvisioning`).");
1063
- }
1064
- if (adminStatsConfig && !adminStatsConfig.auditStatsPort && !persistence?.core.auditStats) {
1065
- throw new Error("SaasPlatformModule.forRoot: adminStats is enabled, but no auditStatsPort is available (set `adminStats.auditStatsPort` or `persistence.core.auditStats`).");
1066
- }
1067
- if (subscriptionContractConfig) {
1068
- const explicitRepository = subscriptionContractConfig === true ? void 0 : subscriptionContractConfig.subscriptionContractRepository;
1069
- if (!explicitRepository && !persistence?.entitlement?.subscriptionContractRepository) {
1070
- throw new Error("SaasPlatformModule.forRoot: subscriptionContract is enabled, but no repository is available (set `subscriptionContract.subscriptionContractRepository` or use a compatible persistence bundle).");
1071
- }
1072
- }
1073
- if (promoCodesConfig && promoCodesConfig !== true && promoCodesConfig.includePublicController !== false && !promoCodesConfig.firstTimeCustomerCheck) {
1074
- throw new Error("SaasPlatformModule.forRoot: public promo preview requires `firstTimeCustomerCheck`.");
1075
- }
1076
- if (adminResourcesConfig === true && !persistence?.adminResources) {
1077
- throw new Error("SaasPlatformModule.forRoot: adminResources is enabled, but `persistence.adminResources` is missing.");
1078
- }
1079
- if (tenantBillingConfig && !persistence?.tenantBilling) {
1080
- const missing = [
1081
- !tenantBillingConfig.subscriptionUsagePort && "subscriptionUsagePort",
1082
- !tenantBillingConfig.subscriptionWritePort && "subscriptionWritePort"
1083
- ].filter(Boolean);
1084
- if (missing.length) {
1085
- throw new Error(`SaasPlatformModule.forRoot: tenantBilling is enabled, but adapters are missing: ${missing.join(", ")}`);
1086
- }
1087
- }
1088
- if (subscriptionBundlesConfig && !tenantBillingConfig) {
1089
- throw new Error("SaasPlatformModule.forRoot: subscriptionBundles requires tenantBilling so auth and subscription usage can be shared.");
1090
- }
1091
- if (subscriptionBundlesConfig) {
1092
- const missing = [];
1093
- if (!persistence?.entitlement?.subscriptionBundleRepository) {
1094
- missing.push("subscriptionBundleRepository");
1095
- }
1096
- if (!persistence?.catalog?.bundleRepository) {
1097
- missing.push("bundleRepository");
1098
- }
1099
- if (missing.length) {
1100
- throw new Error(`SaasPlatformModule.forRoot: subscriptionBundles is enabled, but persistence adapters are missing: ${missing.join(", ")}`);
1101
- }
1102
- }
1103
- if (requiresFullEntitlement) {
1104
- const missing = [];
1105
- if (!adapters.subscriptionRepository) missing.push("subscriptionRepository");
1106
- if (!adapters.planVersionRepository) missing.push("planVersionRepository");
1107
- if (!adapters.transactionRunner) missing.push("transactionRunner");
1108
- if (missing.length) {
1109
- throw new Error(`SaasPlatformModule.forRoot: entitlement active or required by the standard stack, but adapters are missing: ${missing.join(", ")}`);
1110
- }
1111
- if (persistence) {
1112
- assertPersistenceCapabilities(persistence.capabilities, {
1113
- transactions: true,
1114
- pessimisticLocking: true
1115
- }, "SaasPlatformModule entitlement (transactional enforceLimit)");
1116
- }
1117
- }
1118
- const dbCatalog = options.dbCatalog;
1119
- const planCatalogModule = options.planCatalog ? PlanCatalogModule.forRootWithCatalog(options.planCatalog, {
1120
- global: true
1121
- }) : PlanCatalogModule.forRoot({
1122
- projectKey: dbCatalog.projectKey,
1123
- app: dbCatalog.app,
1124
- currency: dbCatalog.currency,
1125
- vatRate: dbCatalog.vatRate,
1126
- marketing: dbCatalog.marketing,
1127
- sink: adapters.planCatalogReadSink,
1128
- imports: options.imports
1129
- });
1130
- const appInfo = options.app ?? {
1131
- key: options.planCatalog?.projectKey ?? options.dbCatalog?.projectKey ?? "app",
1132
- version: options.planCatalog?.app?.version ?? options.dbCatalog?.app?.version ?? "0.0.0"
1133
- };
1134
- const imports = [
1135
- // Make injected client/auth providers visible to the high-level
1136
- // module's own quota providers and automatic plan resolver too.
1137
- ...options.imports ?? [],
1138
- planCatalogModule,
1139
- DiscoveryModule.forRoot({
1140
- app: appInfo,
1141
- controller: {
1142
- guards: options.controller.guards
1143
- },
1144
- imports: options.imports,
1145
- snapshotPath: options.discoverySnapshotPath === void 0 ? "var/discovery-snapshot.json" : options.discoverySnapshotPath
1146
- }),
1147
- AdminModule.forRoot({
1148
- mfaPort,
1149
- auditPort,
1150
- rlsBypassPort,
1151
- imports: options.imports,
1152
- global: true
1153
- }),
1154
- AdminManifestModule.forRoot({
1155
- config: options.adminManifestConfig ?? buildMinimalManifestConfig(),
1156
- extraProviders: options.adminManifestExtraProviders,
1157
- includeManifestController: options.includeManifestController,
1158
- guards: options.controller.guards,
1159
- reloadGuards: options.reloadGuards,
1160
- imports: options.imports,
1161
- // Global like AdminModule above: apps register their manifest
1162
- // contribution by injecting AdminManifestService into one of
1163
- // their own modules (handbook §6.6). Re-exporting the module
1164
- // from here does not make that injection resolvable.
1165
- global: true
1166
- })
1167
- ];
1168
- if (requiresFullEntitlement) {
1169
- imports.push(EntitlementModule.forRoot({
1170
- subscriptionRepository: adapters.subscriptionRepository,
1171
- planVersionRepository: adapters.planVersionRepository,
1172
- transactionRunner: adapters.transactionRunner,
1173
- resolutionConfig: options.entitlement ? options.entitlement.resolutionConfig : void 0,
1174
- subscriptionContractRepository: persistence?.entitlement?.subscriptionContractRepository,
1175
- subscriptionBundleRepository: persistence?.entitlement?.subscriptionBundleRepository,
1176
- bundleRepository: persistence?.entitlement?.bundleRepository,
1177
- imports: options.imports,
1178
- global: Boolean(tenantBillingConfig || subscriptionBundlesConfig)
1179
- }));
1180
- }
1181
- if (catalogConfig) {
1182
- const catalog = persistence?.catalog;
1183
- imports.push(CatalogModule.forRoot({
1184
- planRepository: catalog.planRepository,
1185
- bundleRepository: catalog.bundleRepository,
1186
- catalogEntryRepository: catalog.catalogEntryRepository,
1187
- marketingProjectionRepository: catalog.marketingProjectionRepository,
1188
- promotionRepository: catalog.promotionRepository,
1189
- marketingSettingsRepository: catalog.marketingSettingsRepository,
1190
- controller: catalogConfig.adminControllers === false ? void 0 : {
1191
- guards: options.controller.guards
1192
- },
1193
- imports: catalogConfig.imports ?? options.imports,
1194
- extraProviders: catalogConfig.extraProviders,
1195
- strictModeCheckMode: catalogConfig.strictModeCheckMode,
1196
- autoSyncDiscoveryAtBoot: catalogConfig.autoSyncDiscoveryAtBoot,
1197
- marketedOnlyFeatures: catalogConfig.marketedOnlyFeatures,
1198
- featureUiRegistry: catalogConfig.featureUiRegistry,
1199
- publicMarketingCatalog: catalogConfig.publicMarketingCatalog
1200
- }));
1201
- if (catalogConfig.publicCatalog !== false) {
1202
- imports.push(PublicCatalogModule.forRoot({
1203
- featureUiRegistry: catalogConfig.featureUiRegistry,
1204
- projectKey: appInfo.key,
1205
- bundleRepository: catalog.bundleRepository,
1206
- marketingRepository: catalog.marketingProjectionRepository,
1207
- catalogEntryRepository: catalog.catalogEntryRepository,
1208
- imports: catalogConfig.imports ?? options.imports
1209
- }));
1210
- }
1211
- }
1212
- if (adminResourcesConfig) {
1213
- const config = adminResourcesConfig === true ? {} : adminResourcesConfig;
1214
- imports.push(AdminResourcesModule.forRoot({
1215
- resources: config.resources ?? persistence?.adminResources?.resources,
1216
- guards: config.guards ?? [
1217
- ...options.controller.guards,
1218
- SuperAdminGuard
1219
- ],
1220
- imports: config.imports ?? options.imports
1221
- }));
1222
- }
1223
- if (promoCodesConfig) {
1224
- const config = promoCodesConfig === true ? {} : promoCodesConfig;
1225
- const promo = persistence?.promo;
1226
- const { firstTimeCustomerCheck, adminGuards, imports: promoImports, includePublicController, adminController, ...promoOptions } = config;
1227
- imports.push(PromoCodesModule.forRoot({
1228
- ...promoOptions,
1229
- promoCodeRepository: promo.promoCodeRepository,
1230
- redemptionRepository: promo.redemptionRepository,
1231
- validationLogRepository: promo.validationLogRepository,
1232
- subscriptionLookup: promo.subscriptionLookup,
1233
- revenueAggregator: promo.revenueAggregator,
1234
- transactionRunner: adapters.transactionRunner,
1235
- firstTimeCustomerCheck: firstTimeCustomerCheck ?? {
1236
- hasExistingCustomerForEmail: /* @__PURE__ */ __name(async () => false, "hasExistingCustomerForEmail")
1237
- },
1238
- includePublicController: includePublicController ?? false,
1239
- adminController: adminController === false ? false : {
1240
- guards: adminGuards ?? [
1241
- ...options.controller.guards,
1242
- SuperAdminGuard
1243
- ]
1244
- },
1245
- imports: promoImports ?? options.imports
1246
- }));
1247
- }
1248
- let sharedTenantAuthGuards;
1249
- let sharedSubscriptionUsagePort;
1250
- let quotaProvidersHostedByTenantBilling = false;
1251
- if (tenantBillingConfig) {
1252
- const tenantSlice = persistence?.tenantBilling;
1253
- const { authGuards, subscriptionUsagePort, usageSnapshotPort, subscriptionWritePort, imports: tenantImports, extraProviders, extraExports, ...tenantOptions } = tenantBillingConfig;
1254
- const quotaProviders = options.quotaProviders ?? [];
1255
- quotaProvidersHostedByTenantBilling = quotaProviders.length > 0;
1256
- sharedTenantAuthGuards = normalizeTenantAuthGuards(authGuards);
1257
- sharedSubscriptionUsagePort = subscriptionUsagePort ?? tenantSlice?.subscriptionUsagePort;
1258
- const resolvedUsageSnapshotPort = usageSnapshotPort ?? tenantSlice?.usageSnapshotPort ?? quotaUsageSnapshotProvider(options.quotaProviders ?? []);
1259
- imports.push(TenantBillingModule.forRoot({
1260
- ...tenantOptions,
1261
- authGuards: sharedTenantAuthGuards,
1262
- subscriptionUsagePort: sharedSubscriptionUsagePort,
1263
- usageSnapshotPort: resolvedUsageSnapshotPort,
1264
- subscriptionWritePort: subscriptionWritePort ?? tenantSlice?.subscriptionWritePort,
1265
- imports: tenantImports ?? options.imports,
1266
- extraProviders: [
1267
- ...quotaProviders,
1268
- ...extraProviders ?? []
1269
- ],
1270
- extraExports: [
1271
- ...quotaProviders,
1272
- ...extraExports ?? []
1273
- ]
1274
- }));
1275
- }
1276
- if (subscriptionBundlesConfig) {
1277
- const config = subscriptionBundlesConfig === true ? {} : subscriptionBundlesConfig;
1278
- const { controller, imports: bundleImports, extraProviders, ...bundleOptions } = config;
1279
- imports.push(SubscriptionBundleModule.forRoot({
1280
- ...bundleOptions,
1281
- subscriptionBundleRepository: persistence?.entitlement?.subscriptionBundleRepository,
1282
- bundleRepository: persistence?.catalog?.bundleRepository,
1283
- controller: controller === false ? void 0 : {
1284
- ...controller ?? {},
1285
- authGuards: sharedTenantAuthGuards,
1286
- subscriptionUsagePort: sharedSubscriptionUsagePort
1287
- },
1288
- imports: bundleImports ?? tenantBillingConfig?.imports ?? options.imports,
1289
- extraProviders
1290
- }));
1291
- }
1292
- if (setupConfig) {
1293
- const config = setupConfig === true ? {} : setupConfig;
1294
- imports.push(SetupModule.forRoot({
1295
- ...config,
1296
- provisioningPort: config.provisioningPort ?? persistence?.core.superAdminProvisioning,
1297
- imports: config.imports ?? options.imports
1298
- }));
1299
- }
1300
- if (adminStatsConfig) {
1301
- imports.push(AdminStatsModule.forRoot({
1302
- ...adminStatsConfig,
1303
- guards: adminStatsConfig.guards ?? [
1304
- ...options.controller.guards,
1305
- SuperAdminGuard
1306
- ],
1307
- auditStatsPort: adminStatsConfig.auditStatsPort ?? persistence?.core.auditStats,
1308
- imports: adminStatsConfig.imports ?? options.imports
1309
- }));
1310
- }
1311
- if (checkoutOfferConfig) {
1312
- imports.push(CheckoutOfferModule.forRoot({
1313
- ...checkoutOfferConfig,
1314
- bundleRepository: checkoutOfferConfig.bundleRepository ?? persistence?.catalog?.bundleRepository,
1315
- planRepository: checkoutOfferConfig.planRepository ?? persistence?.catalog?.planRepository,
1316
- catalogEntryRepository: checkoutOfferConfig.catalogEntryRepository ?? persistence?.catalog?.catalogEntryRepository,
1317
- imports: checkoutOfferConfig.imports ?? options.imports
1318
- }));
1319
- }
1320
- if (subscriptionContractConfig) {
1321
- const config = subscriptionContractConfig === true ? {} : subscriptionContractConfig;
1322
- imports.push(SubscriptionContractModule.forRoot({
1323
- ...config,
1324
- subscriptionContractRepository: config.subscriptionContractRepository ?? persistence?.entitlement?.subscriptionContractRepository,
1325
- imports: config.imports ?? options.imports
1326
- }));
1327
- }
1328
- const lightweightProviders = [];
1329
- const lightweightExports = [];
1330
- if (options.autoManifest !== false) {
1331
- const contribution = buildStandardManifestContribution(catalogConfig, adminResourcesConfig, promoCodesConfig);
1332
- lightweightProviders.push({
1333
- provide: STANDARD_MANIFEST_REGISTRATION_TOKEN,
1334
- useFactory: /* @__PURE__ */ __name((manifest) => {
1335
- manifest.register(contribution);
1336
- return contribution;
1337
- }, "useFactory"),
1338
- inject: [
1339
- AdminManifestService
1340
- ]
1341
- });
1342
- }
1343
- const hasExplicitResolver = !!adapters.planResolver;
1344
- const hasSubscriptionResolver = Boolean(tenantBillingConfig && adapters.subscriptionRepository);
1345
- const hasResolver = hasExplicitResolver || hasSubscriptionResolver;
1346
- const hasFallback = !!options.defaultPlanId;
1347
- if (hasResolver || hasFallback) {
1348
- if (hasSubscriptionResolver && !hasExplicitResolver) {
1349
- lightweightProviders.push(asProvider(PLATFORM_SUBSCRIPTION_REPOSITORY_TOKEN, adapters.subscriptionRepository));
1350
- }
1351
- lightweightProviders.push(hasExplicitResolver ? asProvider(PLAN_RESOLVER_PORT_TOKEN, adapters.planResolver) : hasSubscriptionResolver ? {
1352
- provide: PLAN_RESOLVER_PORT_TOKEN,
1353
- useFactory: /* @__PURE__ */ __name((subscriptions) => new SubscriptionPlanResolver(subscriptions), "useFactory"),
1354
- inject: [
1355
- PLATFORM_SUBSCRIPTION_REPOSITORY_TOKEN
1356
- ]
1357
- } : {
1358
- provide: PLAN_RESOLVER_PORT_TOKEN,
1359
- useValue: new StaticPlanResolver(options.defaultPlanId)
1360
- }, StaticEntitlementService, StaticFeatureGuard, EnforceQuotaInterceptor, ...quotaProvidersHostedByTenantBilling ? [] : options.quotaProviders ?? [], {
1361
- provide: QUOTA_PROVIDERS_TOKEN,
1362
- useFactory: /* @__PURE__ */ __name((...providers) => providers, "useFactory"),
1363
- inject: options.quotaProviders ?? []
1364
- }, ...options.globalFeatureGuard === false ? [] : [
1365
- {
1366
- provide: APP_GUARD,
1367
- useExisting: StaticFeatureGuard
1368
- }
1369
- ], {
1370
- provide: APP_INTERCEPTOR,
1371
- useExisting: EnforceQuotaInterceptor
1372
- });
1373
- lightweightExports.push(PLAN_RESOLVER_PORT_TOKEN, StaticEntitlementService, StaticFeatureGuard, EnforceQuotaInterceptor, QUOTA_PROVIDERS_TOKEN);
1374
- if (options.globalFeatureGuard === false) {
1375
- lightweightProviders.push(FeatureGuardCoverageCheck);
1376
- imports.push(NestDiscoveryModule);
1377
- }
1378
- } else {
1379
- PLATFORM_LOGGER.warn("No plan resolver configured \u2014 @RequireFeature and @EnforceQuota are INERT. The platform registered neither StaticFeatureGuard nor EnforceQuotaInterceptor, so every annotated route serves unlicensed traffic and every quota is unlimited. Set one of: adapters.planResolver, defaultPlanId, or tenantBilling.");
1380
- }
1381
- const tenantControllers = [];
1382
- if (options.tenantManifest) {
1383
- if (!hasResolver && !hasFallback) {
1384
- throw new Error("SaasPlatformModule.forRoot: tenantManifest requires defaultPlanId, adapters.planResolver or tenantBilling so it can resolve features.");
1385
- }
1386
- lightweightProviders.push(TenantManifestService);
1387
- lightweightExports.push(TenantManifestService);
1388
- tenantControllers.push(buildTenantManifestController(options.tenantManifest === true ? {
1389
- guards: Array.isArray(tenantBillingConfig?.authGuards) ? tenantBillingConfig.authGuards : options.controller.guards
1390
- } : options.tenantManifest));
1391
- }
1392
- return {
1393
- module: _SaasPlatformModule,
1394
- imports,
1395
- providers: lightweightProviders,
1396
- controllers: tenantControllers,
1397
- exports: [
1398
- PlanCatalogModule,
1399
- DiscoveryModule,
1400
- AdminModule,
1401
- // ADMIN_MANIFEST_CONFIG travels transitively: re-exporting an
1402
- // imported module's token directly is an UnknownExportException
1403
- // at boot — the module export below already carries it.
1404
- AdminManifestModule,
1405
- ...requiresFullEntitlement ? [
1406
- EntitlementModule
1407
- ] : [],
1408
- ...catalogConfig ? [
1409
- CatalogModule
1410
- ] : [],
1411
- ...tenantBillingConfig ? [
1412
- TenantBillingModule
1413
- ] : [],
1414
- ...subscriptionBundlesConfig ? [
1415
- SubscriptionBundleModule
1416
- ] : [],
1417
- ...adminResourcesConfig ? [
1418
- AdminResourcesModule
1419
- ] : [],
1420
- ...promoCodesConfig ? [
1421
- PromoCodesModule
1422
- ] : [],
1423
- ...setupConfig ? [
1424
- SetupModule
1425
- ] : [],
1426
- ...adminStatsConfig ? [
1427
- AdminStatsModule
1428
- ] : [],
1429
- ...checkoutOfferConfig ? [
1430
- CheckoutOfferModule
1431
- ] : [],
1432
- ...subscriptionContractConfig ? [
1433
- SubscriptionContractModule
1434
- ] : [],
1435
- ...lightweightExports
1436
- ],
1437
- global: true
1438
- };
1439
- }
1440
- };
1441
- SaasPlatformModule = _ts_decorate10([
1442
- Module2({})
1443
- ], SaasPlatformModule);
1444
-
1445
- export {
1446
- SETUP_PROVISIONING_PORT_TOKEN,
1447
- SETUP_CONFIG_TOKEN,
1448
- SetupService,
1449
- SetupController,
1450
- SetupModule,
1451
- PLAN_RESOLVER_PORT_TOKEN,
1452
- StaticPlanResolver,
1453
- StaticEntitlementService,
1454
- FeatureGuardCoverageCheck,
1455
- STATIC_FEATURE_GUARD_CONFIG_TOKEN,
1456
- StaticFeatureGuard,
1457
- QUOTA_PROVIDERS_TOKEN,
1458
- EnforceQuotaInterceptor,
1459
- QuotaProvidersUsageSnapshot,
1460
- SubscriptionPlanResolver,
1461
- TenantManifestService,
1462
- buildTenantManifestController,
1463
- SaasPlatformModule
1464
- };