@saasicat/nest 1.0.0-rc.21 → 1.0.0-rc.22
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.
- package/dist/.build-stamp +1 -1
- package/dist/_entries.cjs +4887 -3609
- package/dist/admin/index.js +7 -5
- package/dist/{aggregation-ChpZDh0g.d.ts → aggregation-6fPkeV8i.d.ts} +39 -4
- package/dist/{aggregation-OpnhwzF5.d.cts → aggregation-DjQUc7yd.d.cts} +39 -4
- package/dist/billing/index.d.cts +68 -9
- package/dist/billing/index.d.ts +68 -9
- package/dist/billing/index.js +16 -5
- package/dist/checkout-offer/index.d.cts +2 -2
- package/dist/checkout-offer/index.d.ts +2 -2
- package/dist/checkout-offer/index.js +4 -4
- package/dist/{checkout-offer.service-CCVxG9b2.d.cts → checkout-offer.service-DmVGrT4v.d.cts} +1 -1
- package/dist/{checkout-offer.service-BeHgYikI.d.ts → checkout-offer.service-Yi30L4ry.d.ts} +1 -1
- package/dist/{chunk-WHJSYKNC.js → chunk-3U4N5UYD.js} +1 -1
- package/dist/{chunk-M47BNEY2.js → chunk-3YYLOYUT.js} +1373 -266
- package/dist/{chunk-G6EZWECL.js → chunk-B4YP7REK.js} +94 -26
- package/dist/{chunk-QPVDCKYS.js → chunk-ESEWSAOV.js} +4 -3
- package/dist/{chunk-NDLC5GYK.js → chunk-EU4N5LET.js} +4 -3
- package/dist/{chunk-LLYVYRGJ.js → chunk-F2PF4IXB.js} +1 -275
- package/dist/{chunk-AOS2JPDD.js → chunk-FJIOHAO5.js} +77 -41
- package/dist/{chunk-TOEFN7DN.js → chunk-FPMBQDW7.js} +2 -2
- package/dist/chunk-OSOP4KWL.js +288 -0
- package/dist/{chunk-3RLWML2S.js → chunk-QWKBOLBH.js} +35 -0
- package/dist/{chunk-JBCC6C3M.js → chunk-R3I5X262.js} +5 -4
- package/dist/{chunk-4SDSYV4A.js → chunk-T6WXDGIU.js} +1 -1
- package/dist/{chunk-R5YCJBHY.js → chunk-U5UPEFWC.js} +2 -2
- package/dist/{chunk-XSSWYPP5.js → chunk-UMZCOCT5.js} +1 -1
- package/dist/{chunk-7NJKVC5X.js → chunk-WQNOCOI2.js} +53 -6
- package/dist/{chunk-55QEDAMX.js → chunk-WTAS2CLM.js} +4 -9
- package/dist/{enforce-quota.interceptor-BFyVdWe8.d.cts → enforce-quota.interceptor-B9UhCBXx.d.cts} +2 -2
- package/dist/{enforce-quota.interceptor-GaBXboGx.d.ts → enforce-quota.interceptor-CR2waXNA.d.ts} +2 -2
- package/dist/entitlement/index.d.cts +1 -1
- package/dist/entitlement/index.d.ts +1 -1
- package/dist/entitlement/index.js +4 -2
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +36 -20
- package/dist/{issuer-identity.check-CBO0vcsq.d.cts → issuer-identity.check-BntcNdld.d.cts} +1 -1
- package/dist/{issuer-identity.check-Cz9CEMkZ.d.ts → issuer-identity.check-DFmS8whs.d.ts} +1 -1
- package/dist/{module-options-qAOwinHR.d.cts → module-options-C4S_StYF.d.cts} +2 -2
- package/dist/{module-options-DmQ3G4sZ.d.ts → module-options-DxJI-1iH.d.ts} +2 -2
- package/dist/payments/index.js +2 -2
- package/dist/platform/index.d.cts +25 -16
- package/dist/platform/index.d.ts +25 -16
- package/dist/platform/index.js +16 -14
- package/dist/promo/index.d.cts +11 -4
- package/dist/promo/index.d.ts +11 -4
- package/dist/promo/index.js +5 -3
- package/dist/{promo.module-CKkECmU8.d.cts → promo.module-Ddx-swUV.d.cts} +1 -1
- package/dist/{promo.module-DuIJdK3U.d.ts → promo.module-PsIvDcUp.d.ts} +1 -1
- package/dist/{promo.service-BYBu6dy3.d.cts → promo.service-BextPvx5.d.cts} +23 -1
- package/dist/{promo.service-CFjfF0Xm.d.ts → promo.service-Dqqh0JXn.d.ts} +23 -1
- package/dist/registration/index.d.cts +2 -2
- package/dist/registration/index.d.ts +2 -2
- package/dist/registration/index.js +5 -5
- package/dist/subscription-contract/index.js +2 -2
- package/dist/{tenant-billing.controller-DKbAqTbM.d.cts → tenant-billing.controller-BC6-S5cT.d.cts} +91 -10
- package/dist/{tenant-billing.controller-BLqbsONe.d.ts → tenant-billing.controller-BuQDQ76i.d.ts} +91 -10
- package/dist/{tenant-billing.module-ClbjzocC.d.cts → tenant-billing.module-C6MFfCKq.d.cts} +24 -1
- package/dist/{tenant-billing.module-DohgJJ2m.d.ts → tenant-billing.module-CUCQL0-k.d.ts} +24 -1
- package/dist/testing/index.d.cts +6 -6
- package/dist/testing/index.d.ts +6 -6
- package/dist/testing/index.js +33 -31
- package/package.json +3 -3
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PromoCodesModule
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-T6WXDGIU.js";
|
|
4
4
|
import {
|
|
5
5
|
SubscriptionContractModule
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UMZCOCT5.js";
|
|
7
7
|
import {
|
|
8
8
|
AdminManifestModule,
|
|
9
9
|
AdminManifestService,
|
|
10
10
|
AdminModule,
|
|
11
|
-
AdminResourcesModule,
|
|
12
11
|
AdminStatsModule,
|
|
13
12
|
SuperAdminGuard
|
|
14
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-F2PF4IXB.js";
|
|
15
14
|
import {
|
|
16
15
|
FEATURE_GUARD_MARKER,
|
|
17
16
|
PublicCatalogModule,
|
|
18
17
|
REQUIRE_FEATURE_KEY,
|
|
18
|
+
SubscriberAccountModule,
|
|
19
19
|
SubscriptionBundleModule,
|
|
20
20
|
TenantBillingModule,
|
|
21
21
|
catalogSource,
|
|
22
22
|
isPlatformFeatureGuard,
|
|
23
23
|
loadPlanCatalogFromFile
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-3YYLOYUT.js";
|
|
25
|
+
import {
|
|
26
|
+
AdminResourcesModule
|
|
27
|
+
} from "./chunk-OSOP4KWL.js";
|
|
25
28
|
import {
|
|
26
29
|
CatalogModule,
|
|
27
30
|
WebAuditLogger,
|
|
@@ -33,17 +36,17 @@ import {
|
|
|
33
36
|
} from "./chunk-34XVPR6P.js";
|
|
34
37
|
import {
|
|
35
38
|
CheckoutOfferModule
|
|
36
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-FPMBQDW7.js";
|
|
37
40
|
import {
|
|
38
41
|
DiscoveryModule
|
|
39
42
|
} from "./chunk-S33SO5XX.js";
|
|
40
43
|
import {
|
|
41
44
|
EntitlementModule
|
|
42
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-3U4N5UYD.js";
|
|
43
46
|
import {
|
|
44
47
|
LimitExceededError,
|
|
45
48
|
cancellationHasLanded
|
|
46
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-B4YP7REK.js";
|
|
47
50
|
import {
|
|
48
51
|
findPlan
|
|
49
52
|
} from "./chunk-TBBZWZQT.js";
|
|
@@ -55,10 +58,10 @@ import {
|
|
|
55
58
|
} from "./chunk-QUZU2M33.js";
|
|
56
59
|
import {
|
|
57
60
|
PaymentsModule
|
|
58
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-ESEWSAOV.js";
|
|
59
62
|
import {
|
|
60
63
|
PaymentGatewayRegistry
|
|
61
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-WQNOCOI2.js";
|
|
62
65
|
import {
|
|
63
66
|
RLS_BYPASS_PORT_TOKEN
|
|
64
67
|
} from "./chunk-SZ7RFPXA.js";
|
|
@@ -1705,18 +1708,23 @@ function optionsOf2(slot) {
|
|
|
1705
1708
|
__name(optionsOf2, "optionsOf");
|
|
1706
1709
|
|
|
1707
1710
|
// src/platform/compose/admin-resources.ts
|
|
1708
|
-
function composeAdminResources({ options, persistence }) {
|
|
1711
|
+
function composeAdminResources({ options, persistence, shared }) {
|
|
1709
1712
|
if (!options.adminResources) return [];
|
|
1710
1713
|
const config = optionsOf2(options.adminResources);
|
|
1714
|
+
shared.adminResourcesModule = AdminResourcesModule.forRoot({
|
|
1715
|
+
resources: config.resources ?? persistence?.adminResources?.resources,
|
|
1716
|
+
guards: adminResourceGuards(options),
|
|
1717
|
+
imports: config.imports ?? options.imports
|
|
1718
|
+
});
|
|
1711
1719
|
return [
|
|
1712
|
-
|
|
1713
|
-
resources: config.resources ?? persistence?.adminResources?.resources,
|
|
1714
|
-
guards: config.guards ?? operatorGuards(options),
|
|
1715
|
-
imports: config.imports ?? options.imports
|
|
1716
|
-
})
|
|
1720
|
+
shared.adminResourcesModule
|
|
1717
1721
|
];
|
|
1718
1722
|
}
|
|
1719
1723
|
__name(composeAdminResources, "composeAdminResources");
|
|
1724
|
+
function adminResourceGuards(options) {
|
|
1725
|
+
return optionsOf2(options.adminResources).guards ?? operatorGuards(options);
|
|
1726
|
+
}
|
|
1727
|
+
__name(adminResourceGuards, "adminResourceGuards");
|
|
1720
1728
|
|
|
1721
1729
|
// src/platform/compose/catalog.ts
|
|
1722
1730
|
function composeCatalog({ options, persistence }) {
|
|
@@ -1905,6 +1913,29 @@ function composePromoCodes({ options, adapters, persistence }) {
|
|
|
1905
1913
|
}
|
|
1906
1914
|
__name(composePromoCodes, "composePromoCodes");
|
|
1907
1915
|
|
|
1916
|
+
// src/platform/compose/subscriber-account.ts
|
|
1917
|
+
function servesSubscriberAccounts(options) {
|
|
1918
|
+
return Boolean(options.adminResources && optionsOf2(options.tenantBilling).chargeJournal);
|
|
1919
|
+
}
|
|
1920
|
+
__name(servesSubscriberAccounts, "servesSubscriberAccounts");
|
|
1921
|
+
function composeSubscriberAccount(ctx) {
|
|
1922
|
+
const { adminResourcesModule, tenantBillingModule } = ctx.shared;
|
|
1923
|
+
if (!servesSubscriberAccounts(ctx.options) || !adminResourcesModule || !tenantBillingModule) {
|
|
1924
|
+
return [];
|
|
1925
|
+
}
|
|
1926
|
+
return [
|
|
1927
|
+
SubscriberAccountModule.forRoot({
|
|
1928
|
+
guards: adminResourceGuards(ctx.options),
|
|
1929
|
+
imports: [
|
|
1930
|
+
adminResourcesModule,
|
|
1931
|
+
tenantBillingModule,
|
|
1932
|
+
...optionsOf2(ctx.options.adminResources).imports ?? ctx.options.imports ?? []
|
|
1933
|
+
]
|
|
1934
|
+
})
|
|
1935
|
+
];
|
|
1936
|
+
}
|
|
1937
|
+
__name(composeSubscriberAccount, "composeSubscriberAccount");
|
|
1938
|
+
|
|
1908
1939
|
// src/platform/compose/tenant-bindings.ts
|
|
1909
1940
|
function normalizeTenantAuthGuards(guards) {
|
|
1910
1941
|
if (!Array.isArray(guards)) return guards;
|
|
@@ -1934,29 +1965,30 @@ function composeTenantBilling(ctx) {
|
|
|
1934
1965
|
ctx.shared.quotaProvidersHostedByTenantBilling = quotaProviders.length > 0;
|
|
1935
1966
|
ctx.shared.authGuards = normalizeTenantAuthGuards(authGuards);
|
|
1936
1967
|
ctx.shared.subscriptionUsagePort = subscriptionUsagePort ?? tenantSlice?.subscriptionUsagePort;
|
|
1968
|
+
ctx.shared.tenantBillingModule = TenantBillingModule.forRoot({
|
|
1969
|
+
...tenantOptions,
|
|
1970
|
+
authGuards: ctx.shared.authGuards,
|
|
1971
|
+
// The same adapter `SubscriptionBundleModule` gets. That module
|
|
1972
|
+
// exports the token, but it is a sibling import here rather than an
|
|
1973
|
+
// ancestor, so its exports never reach this module's providers —
|
|
1974
|
+
// and the plan-change rule that reads bookings would resolve to
|
|
1975
|
+
// "none" and allow the move it exists to refuse.
|
|
1976
|
+
subscriptionBundleRepository: ctx.persistence?.entitlement?.subscriptionBundleRepository,
|
|
1977
|
+
subscriptionUsagePort: ctx.shared.subscriptionUsagePort,
|
|
1978
|
+
usageSnapshotPort: usageSnapshotPort ?? tenantSlice?.usageSnapshotPort ?? quotaUsageSnapshotProvider(quotaProviders),
|
|
1979
|
+
subscriptionWritePort: subscriptionWritePort ?? tenantSlice?.subscriptionWritePort,
|
|
1980
|
+
imports: tenantImports ?? ctx.options.imports,
|
|
1981
|
+
extraProviders: [
|
|
1982
|
+
...quotaProviders,
|
|
1983
|
+
...extraProviders ?? []
|
|
1984
|
+
],
|
|
1985
|
+
extraExports: [
|
|
1986
|
+
...quotaProviders,
|
|
1987
|
+
...extraExports ?? []
|
|
1988
|
+
]
|
|
1989
|
+
});
|
|
1937
1990
|
return [
|
|
1938
|
-
|
|
1939
|
-
...tenantOptions,
|
|
1940
|
-
authGuards: ctx.shared.authGuards,
|
|
1941
|
-
// The same adapter `SubscriptionBundleModule` gets. That module
|
|
1942
|
-
// exports the token, but it is a sibling import here rather than an
|
|
1943
|
-
// ancestor, so its exports never reach this module's providers —
|
|
1944
|
-
// and the plan-change rule that reads bookings would resolve to
|
|
1945
|
-
// "none" and allow the move it exists to refuse.
|
|
1946
|
-
subscriptionBundleRepository: ctx.persistence?.entitlement?.subscriptionBundleRepository,
|
|
1947
|
-
subscriptionUsagePort: ctx.shared.subscriptionUsagePort,
|
|
1948
|
-
usageSnapshotPort: usageSnapshotPort ?? tenantSlice?.usageSnapshotPort ?? quotaUsageSnapshotProvider(quotaProviders),
|
|
1949
|
-
subscriptionWritePort: subscriptionWritePort ?? tenantSlice?.subscriptionWritePort,
|
|
1950
|
-
imports: tenantImports ?? ctx.options.imports,
|
|
1951
|
-
extraProviders: [
|
|
1952
|
-
...quotaProviders,
|
|
1953
|
-
...extraProviders ?? []
|
|
1954
|
-
],
|
|
1955
|
-
extraExports: [
|
|
1956
|
-
...quotaProviders,
|
|
1957
|
-
...extraExports ?? []
|
|
1958
|
-
]
|
|
1959
|
-
})
|
|
1991
|
+
ctx.shared.tenantBillingModule
|
|
1960
1992
|
];
|
|
1961
1993
|
}
|
|
1962
1994
|
__name(composeTenantBilling, "composeTenantBilling");
|
|
@@ -1998,7 +2030,9 @@ var FEATURE_COMPOSERS = [
|
|
|
1998
2030
|
composeSetup,
|
|
1999
2031
|
composeAdminStats,
|
|
2000
2032
|
composeCheckoutOffer,
|
|
2001
|
-
composeSubscriptionContract
|
|
2033
|
+
composeSubscriptionContract,
|
|
2034
|
+
// After the admin resources and tenant billing: it imports both.
|
|
2035
|
+
composeSubscriberAccount
|
|
2002
2036
|
];
|
|
2003
2037
|
function composeFeatures(ctx) {
|
|
2004
2038
|
return FEATURE_COMPOSERS.flatMap((compose) => compose(ctx));
|
|
@@ -2501,9 +2535,10 @@ import { DiscoveryModule as NestDiscoveryModule } from "@nestjs/core";
|
|
|
2501
2535
|
import { planCatalogSettingsOf } from "@saasicat/core";
|
|
2502
2536
|
|
|
2503
2537
|
// src/platform/compose/manifest.ts
|
|
2538
|
+
import { SUBSCRIBER_ACCOUNT_CAPABILITY } from "@saasicat/core";
|
|
2504
2539
|
var PLATFORM_SUBSCRIPTION_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/PlatformSubscriptionRepository");
|
|
2505
2540
|
var STANDARD_MANIFEST_REGISTRATION_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/StandardManifestRegistration");
|
|
2506
|
-
function buildStandardManifestContribution(catalog, adminResources, promoCodes) {
|
|
2541
|
+
function buildStandardManifestContribution(catalog, adminResources, promoCodes, subscriberAccounts) {
|
|
2507
2542
|
const capabilities = {
|
|
2508
2543
|
"discovery.read": true,
|
|
2509
2544
|
"settings.read": true
|
|
@@ -2536,6 +2571,7 @@ function buildStandardManifestContribution(catalog, adminResources, promoCodes)
|
|
|
2536
2571
|
}
|
|
2537
2572
|
};
|
|
2538
2573
|
}
|
|
2574
|
+
if (subscriberAccounts) capabilities[SUBSCRIBER_ACCOUNT_CAPABILITY] = true;
|
|
2539
2575
|
if (promoCodes) {
|
|
2540
2576
|
Object.assign(capabilities, {
|
|
2541
2577
|
"promoCodes.read": true,
|
|
@@ -2865,7 +2901,7 @@ var SaaSiCatModule = class _SaaSiCatModule {
|
|
|
2865
2901
|
const lightweightProviders = [];
|
|
2866
2902
|
const lightweightExports = [];
|
|
2867
2903
|
if (options.autoManifest !== false) {
|
|
2868
|
-
const contribution = buildStandardManifestContribution(catalogConfig, adminResourcesConfig, promoCodesConfig);
|
|
2904
|
+
const contribution = buildStandardManifestContribution(catalogConfig, adminResourcesConfig, promoCodesConfig, servesSubscriberAccounts(options));
|
|
2869
2905
|
lightweightProviders.push({
|
|
2870
2906
|
provide: STANDARD_MANIFEST_REGISTRATION_TOKEN,
|
|
2871
2907
|
useFactory: /* @__PURE__ */ __name((manifest) => {
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
CHECKOUT_OFFER_TRANSACTION_RUNNER_TOKEN,
|
|
4
4
|
CheckoutOfferPricing,
|
|
5
5
|
CheckoutOfferService
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WTAS2CLM.js";
|
|
7
7
|
import {
|
|
8
8
|
SubscriptionContractService
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-EU4N5LET.js";
|
|
10
10
|
import {
|
|
11
11
|
SUBSCRIPTION_CONTRACT_REPOSITORY_TOKEN
|
|
12
12
|
} from "./chunk-VBRYPU7V.js";
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EnforceMfa
|
|
3
|
+
} from "./chunk-34XVPR6P.js";
|
|
4
|
+
import {
|
|
5
|
+
AdminAuditService
|
|
6
|
+
} from "./chunk-OOTEXP47.js";
|
|
7
|
+
import {
|
|
8
|
+
asProvider
|
|
9
|
+
} from "./chunk-J7NJRK3K.js";
|
|
10
|
+
import {
|
|
11
|
+
__name
|
|
12
|
+
} from "./chunk-SHUYVCID.js";
|
|
13
|
+
|
|
14
|
+
// src/admin/admin-resources.module.ts
|
|
15
|
+
import { Body, Controller, Get, Inject, Injectable, Module, NotFoundException, Param, Post, Query, Req, UseGuards } from "@nestjs/common";
|
|
16
|
+
import { IsOptional, IsString, MaxLength } from "class-validator";
|
|
17
|
+
import { BILLING_ERROR_CODES } from "@saasicat/core";
|
|
18
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
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;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
}
|
|
24
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
25
|
+
function _ts_metadata(k, v) {
|
|
26
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
27
|
+
}
|
|
28
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
29
|
+
function _ts_param(paramIndex, decorator) {
|
|
30
|
+
return function(target, key) {
|
|
31
|
+
decorator(target, key, paramIndex);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
__name(_ts_param, "_ts_param");
|
|
35
|
+
var ADMIN_RESOURCES_PORT_TOKEN = /* @__PURE__ */ Symbol.for("saasicat/nest/AdminResourcesPort");
|
|
36
|
+
var SuspendTenantDto = class {
|
|
37
|
+
static {
|
|
38
|
+
__name(this, "SuspendTenantDto");
|
|
39
|
+
}
|
|
40
|
+
reason;
|
|
41
|
+
};
|
|
42
|
+
_ts_decorate([
|
|
43
|
+
IsOptional(),
|
|
44
|
+
IsString(),
|
|
45
|
+
MaxLength(500),
|
|
46
|
+
_ts_metadata("design:type", String)
|
|
47
|
+
], SuspendTenantDto.prototype, "reason", void 0);
|
|
48
|
+
var AdminResourcesService = class {
|
|
49
|
+
static {
|
|
50
|
+
__name(this, "AdminResourcesService");
|
|
51
|
+
}
|
|
52
|
+
resources;
|
|
53
|
+
audit;
|
|
54
|
+
constructor(resources, audit) {
|
|
55
|
+
this.resources = resources;
|
|
56
|
+
this.audit = audit;
|
|
57
|
+
}
|
|
58
|
+
listTenants(filter) {
|
|
59
|
+
return this.resources.listTenants(filter);
|
|
60
|
+
}
|
|
61
|
+
async getTenantDetail(slug) {
|
|
62
|
+
const tenant = await this.resources.getTenantDetail(slug);
|
|
63
|
+
if (!tenant) {
|
|
64
|
+
throw new NotFoundException({
|
|
65
|
+
code: BILLING_ERROR_CODES.TENANT_NOT_FOUND,
|
|
66
|
+
message: `Tenant ${slug} not found`,
|
|
67
|
+
params: {
|
|
68
|
+
slug
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return tenant;
|
|
73
|
+
}
|
|
74
|
+
listUsers(filter) {
|
|
75
|
+
return this.resources.listUsers(filter);
|
|
76
|
+
}
|
|
77
|
+
listAudit(filter) {
|
|
78
|
+
return this.resources.listAudit(filter);
|
|
79
|
+
}
|
|
80
|
+
listSubscriptions() {
|
|
81
|
+
return this.resources.listSubscriptions();
|
|
82
|
+
}
|
|
83
|
+
suspendTenant(slug, reason, actor) {
|
|
84
|
+
return this.setTenantActive(slug, false, "PAST_DUE", actor, {
|
|
85
|
+
action: "TENANT_SUSPEND",
|
|
86
|
+
reason: reason ?? ""
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
reactivateTenant(slug, actor) {
|
|
90
|
+
return this.setTenantActive(slug, true, "ACTIVE", actor, {
|
|
91
|
+
action: "TENANT_REACTIVATE",
|
|
92
|
+
reason: ""
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async setTenantActive(slug, active, subscriptionStatus, actor, audit) {
|
|
96
|
+
const result = await this.resources.setTenantActive(slug, active, subscriptionStatus);
|
|
97
|
+
if (!result) {
|
|
98
|
+
throw new NotFoundException({
|
|
99
|
+
code: BILLING_ERROR_CODES.TENANT_NOT_FOUND,
|
|
100
|
+
message: `Tenant ${slug} not found`,
|
|
101
|
+
params: {
|
|
102
|
+
slug
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
await this.audit.log({
|
|
107
|
+
actor,
|
|
108
|
+
entity: "Tenant",
|
|
109
|
+
entityId: result.id,
|
|
110
|
+
action: audit.action,
|
|
111
|
+
changes: {
|
|
112
|
+
slug,
|
|
113
|
+
reason: audit.reason
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
AdminResourcesService = _ts_decorate([
|
|
120
|
+
Injectable(),
|
|
121
|
+
_ts_param(0, Inject(ADMIN_RESOURCES_PORT_TOKEN)),
|
|
122
|
+
_ts_param(1, Inject(AdminAuditService)),
|
|
123
|
+
_ts_metadata("design:type", Function),
|
|
124
|
+
_ts_metadata("design:paramtypes", [
|
|
125
|
+
typeof AdminResourcesPort === "undefined" ? Object : AdminResourcesPort,
|
|
126
|
+
typeof AdminAuditService === "undefined" ? Object : AdminAuditService
|
|
127
|
+
])
|
|
128
|
+
], AdminResourcesService);
|
|
129
|
+
function actorFromRequest(request) {
|
|
130
|
+
const userId = request.user?.id ?? request.user?.userId ?? "unknown";
|
|
131
|
+
return {
|
|
132
|
+
userId,
|
|
133
|
+
email: request.user?.email ?? `${userId}@unknown`,
|
|
134
|
+
source: "web",
|
|
135
|
+
context: request.user?.sessionId ?? "unknown"
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
__name(actorFromRequest, "actorFromRequest");
|
|
139
|
+
function buildAdminResourcesController(guards) {
|
|
140
|
+
let GeneratedAdminResourcesController = class GeneratedAdminResourcesController {
|
|
141
|
+
static {
|
|
142
|
+
__name(this, "GeneratedAdminResourcesController");
|
|
143
|
+
}
|
|
144
|
+
resources;
|
|
145
|
+
constructor(resources) {
|
|
146
|
+
this.resources = resources;
|
|
147
|
+
}
|
|
148
|
+
listTenants(query) {
|
|
149
|
+
return this.resources.listTenants(query);
|
|
150
|
+
}
|
|
151
|
+
getTenant(slug) {
|
|
152
|
+
return this.resources.getTenantDetail(slug);
|
|
153
|
+
}
|
|
154
|
+
suspendTenant(request, slug, dto) {
|
|
155
|
+
return this.resources.suspendTenant(slug, dto.reason, actorFromRequest(request));
|
|
156
|
+
}
|
|
157
|
+
reactivateTenant(request, slug) {
|
|
158
|
+
return this.resources.reactivateTenant(slug, actorFromRequest(request));
|
|
159
|
+
}
|
|
160
|
+
listUsers(query) {
|
|
161
|
+
return this.resources.listUsers(query);
|
|
162
|
+
}
|
|
163
|
+
listAudit(query) {
|
|
164
|
+
return this.resources.listAudit({
|
|
165
|
+
actor: query.actor,
|
|
166
|
+
action: query.action,
|
|
167
|
+
entity: query.entity,
|
|
168
|
+
since: query.since,
|
|
169
|
+
limit: query.limit ? Number.parseInt(query.limit, 10) : void 0
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
listSubscriptions() {
|
|
173
|
+
return this.resources.listSubscriptions();
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
_ts_decorate([
|
|
177
|
+
Get("tenants"),
|
|
178
|
+
_ts_param(0, Query()),
|
|
179
|
+
_ts_metadata("design:type", Function),
|
|
180
|
+
_ts_metadata("design:paramtypes", [
|
|
181
|
+
Object
|
|
182
|
+
]),
|
|
183
|
+
_ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
184
|
+
], GeneratedAdminResourcesController.prototype, "listTenants", null);
|
|
185
|
+
_ts_decorate([
|
|
186
|
+
Get("tenants/:slug"),
|
|
187
|
+
_ts_param(0, Param("slug")),
|
|
188
|
+
_ts_metadata("design:type", Function),
|
|
189
|
+
_ts_metadata("design:paramtypes", [
|
|
190
|
+
String
|
|
191
|
+
]),
|
|
192
|
+
_ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
193
|
+
], GeneratedAdminResourcesController.prototype, "getTenant", null);
|
|
194
|
+
_ts_decorate([
|
|
195
|
+
Post("tenants/:slug/suspend"),
|
|
196
|
+
EnforceMfa(),
|
|
197
|
+
_ts_param(0, Req()),
|
|
198
|
+
_ts_param(1, Param("slug")),
|
|
199
|
+
_ts_param(2, Body()),
|
|
200
|
+
_ts_metadata("design:type", Function),
|
|
201
|
+
_ts_metadata("design:paramtypes", [
|
|
202
|
+
typeof AdminRequest === "undefined" ? Object : AdminRequest,
|
|
203
|
+
String,
|
|
204
|
+
typeof SuspendTenantDto === "undefined" ? Object : SuspendTenantDto
|
|
205
|
+
]),
|
|
206
|
+
_ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
207
|
+
], GeneratedAdminResourcesController.prototype, "suspendTenant", null);
|
|
208
|
+
_ts_decorate([
|
|
209
|
+
Post("tenants/:slug/reactivate"),
|
|
210
|
+
EnforceMfa(),
|
|
211
|
+
_ts_param(0, Req()),
|
|
212
|
+
_ts_param(1, Param("slug")),
|
|
213
|
+
_ts_metadata("design:type", Function),
|
|
214
|
+
_ts_metadata("design:paramtypes", [
|
|
215
|
+
typeof AdminRequest === "undefined" ? Object : AdminRequest,
|
|
216
|
+
String
|
|
217
|
+
]),
|
|
218
|
+
_ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
219
|
+
], GeneratedAdminResourcesController.prototype, "reactivateTenant", null);
|
|
220
|
+
_ts_decorate([
|
|
221
|
+
Get("users"),
|
|
222
|
+
_ts_param(0, Query()),
|
|
223
|
+
_ts_metadata("design:type", Function),
|
|
224
|
+
_ts_metadata("design:paramtypes", [
|
|
225
|
+
Object
|
|
226
|
+
]),
|
|
227
|
+
_ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
228
|
+
], GeneratedAdminResourcesController.prototype, "listUsers", null);
|
|
229
|
+
_ts_decorate([
|
|
230
|
+
Get("audit"),
|
|
231
|
+
_ts_param(0, Query()),
|
|
232
|
+
_ts_metadata("design:type", Function),
|
|
233
|
+
_ts_metadata("design:paramtypes", [
|
|
234
|
+
Object
|
|
235
|
+
]),
|
|
236
|
+
_ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
237
|
+
], GeneratedAdminResourcesController.prototype, "listAudit", null);
|
|
238
|
+
_ts_decorate([
|
|
239
|
+
Get("subscriptions"),
|
|
240
|
+
_ts_metadata("design:type", Function),
|
|
241
|
+
_ts_metadata("design:paramtypes", []),
|
|
242
|
+
_ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
243
|
+
], GeneratedAdminResourcesController.prototype, "listSubscriptions", null);
|
|
244
|
+
GeneratedAdminResourcesController = _ts_decorate([
|
|
245
|
+
Controller("admin"),
|
|
246
|
+
UseGuards(...guards),
|
|
247
|
+
_ts_param(0, Inject(AdminResourcesService)),
|
|
248
|
+
_ts_metadata("design:type", Function),
|
|
249
|
+
_ts_metadata("design:paramtypes", [
|
|
250
|
+
typeof AdminResourcesService === "undefined" ? Object : AdminResourcesService
|
|
251
|
+
])
|
|
252
|
+
], GeneratedAdminResourcesController);
|
|
253
|
+
return GeneratedAdminResourcesController;
|
|
254
|
+
}
|
|
255
|
+
__name(buildAdminResourcesController, "buildAdminResourcesController");
|
|
256
|
+
var AdminResourcesModule = class _AdminResourcesModule {
|
|
257
|
+
static {
|
|
258
|
+
__name(this, "AdminResourcesModule");
|
|
259
|
+
}
|
|
260
|
+
static forRoot(options) {
|
|
261
|
+
return {
|
|
262
|
+
module: _AdminResourcesModule,
|
|
263
|
+
global: options.global ?? false,
|
|
264
|
+
imports: options.imports ?? [],
|
|
265
|
+
controllers: [
|
|
266
|
+
buildAdminResourcesController(options.guards)
|
|
267
|
+
],
|
|
268
|
+
providers: [
|
|
269
|
+
asProvider(ADMIN_RESOURCES_PORT_TOKEN, options.resources),
|
|
270
|
+
AdminResourcesService
|
|
271
|
+
],
|
|
272
|
+
exports: [
|
|
273
|
+
ADMIN_RESOURCES_PORT_TOKEN,
|
|
274
|
+
AdminResourcesService
|
|
275
|
+
]
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
AdminResourcesModule = _ts_decorate([
|
|
280
|
+
Module({})
|
|
281
|
+
], AdminResourcesModule);
|
|
282
|
+
|
|
283
|
+
export {
|
|
284
|
+
ADMIN_RESOURCES_PORT_TOKEN,
|
|
285
|
+
SuspendTenantDto,
|
|
286
|
+
AdminResourcesService,
|
|
287
|
+
AdminResourcesModule
|
|
288
|
+
};
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-TBBZWZQT.js";
|
|
4
4
|
import {
|
|
5
5
|
computeIncludedVat,
|
|
6
|
+
grossFromNet,
|
|
6
7
|
netFromGross,
|
|
7
8
|
round2
|
|
8
9
|
} from "./chunk-6PJE7EWO.js";
|
|
@@ -22,6 +23,14 @@ function computeDiscountGross(plan, code) {
|
|
|
22
23
|
return round2(v);
|
|
23
24
|
}
|
|
24
25
|
__name(computeDiscountGross, "computeDiscountGross");
|
|
26
|
+
function promoCodeDiscountNet(planNet, vatRate, code) {
|
|
27
|
+
const planGross = grossFromNet(planNet, vatRate);
|
|
28
|
+
const discountGross = Math.min(computeDiscountGross({
|
|
29
|
+
gross: planGross
|
|
30
|
+
}, code), planGross);
|
|
31
|
+
return Math.min(planNet, netFromGross(discountGross, vatRate));
|
|
32
|
+
}
|
|
33
|
+
__name(promoCodeDiscountNet, "promoCodeDiscountNet");
|
|
25
34
|
function computeDiscountedGross(planGross, discountGross) {
|
|
26
35
|
return round2(planGross - discountGross);
|
|
27
36
|
}
|
|
@@ -671,6 +680,31 @@ var PromoCodesService = class {
|
|
|
671
680
|
endsAt
|
|
672
681
|
}, tx);
|
|
673
682
|
}
|
|
683
|
+
/**
|
|
684
|
+
* The code redeemed for a subscription, with the values it was redeemed
|
|
685
|
+
* at, unless the redemption was reversed — or null.
|
|
686
|
+
*
|
|
687
|
+
* An expired redemption still counts. Its term is counted from the
|
|
688
|
+
* subscription's start, which lies before a trial, while a contract counts
|
|
689
|
+
* a discount from the first period that is paid: a code for one month
|
|
690
|
+
* redeemed in a thirty-day trial has expired before the customer has paid
|
|
691
|
+
* for anything. A code deleted since still names what was agreed, so it is
|
|
692
|
+
* read without the refusal `findOne` gives.
|
|
693
|
+
*/
|
|
694
|
+
async redeemedCodeFor(subscriptionId) {
|
|
695
|
+
const redemption = await this.redemptionRepo.findBySubscription(subscriptionId);
|
|
696
|
+
if (!redemption || redemption.status === "REVERSED") return null;
|
|
697
|
+
const promo = await this.promoRepo.findById(redemption.promoCodeId);
|
|
698
|
+
if (!promo) return null;
|
|
699
|
+
return {
|
|
700
|
+
code: promo.code,
|
|
701
|
+
valueType: redemption.appliedValueType,
|
|
702
|
+
value: redemption.appliedValue,
|
|
703
|
+
durationType: redemption.appliedDurationType,
|
|
704
|
+
durationValue: redemption.appliedDurationValue,
|
|
705
|
+
redeemedAt: redemption.redeemedAt
|
|
706
|
+
};
|
|
707
|
+
}
|
|
674
708
|
async reverse(subscriptionId) {
|
|
675
709
|
return this.transactionRunner.run(async (tx) => {
|
|
676
710
|
const redemption = await this.redemptionRepo.findBySubscription(subscriptionId, tx);
|
|
@@ -876,6 +910,7 @@ __name(termsAfter, "termsAfter");
|
|
|
876
910
|
|
|
877
911
|
export {
|
|
878
912
|
computeDiscountGross,
|
|
913
|
+
promoCodeDiscountNet,
|
|
879
914
|
computeDiscountedGross,
|
|
880
915
|
computeRegularStartsAt,
|
|
881
916
|
addCycles,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CheckoutOfferService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WTAS2CLM.js";
|
|
4
4
|
import {
|
|
5
5
|
grossFromNet,
|
|
6
6
|
netFromGross
|
|
@@ -9,8 +9,9 @@ import {
|
|
|
9
9
|
PaymentCallbackService,
|
|
10
10
|
PaymentGatewayRegistry,
|
|
11
11
|
SUBSCRIBER_PAYMENT_METHOD_REPOSITORY_TOKEN,
|
|
12
|
+
openGatewayForm,
|
|
12
13
|
refuseForeignReturnUrls
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-WQNOCOI2.js";
|
|
14
15
|
import {
|
|
15
16
|
INVOICE_ADDRESS_FIELDS,
|
|
16
17
|
settleNewSubscriberDetails
|
|
@@ -242,7 +243,7 @@ var RegistrationPaymentService = class _RegistrationPaymentService {
|
|
|
242
243
|
if (!account) {
|
|
243
244
|
throw new ConflictException(codedError(PAYMENT_ERROR_CODES.PAYMENTS_NOT_CONFIGURED));
|
|
244
245
|
}
|
|
245
|
-
const session = await account
|
|
246
|
+
const session = await openGatewayForm(account, {
|
|
246
247
|
subject: {
|
|
247
248
|
kind: "registration",
|
|
248
249
|
pendingRegistrationId: pending.id
|
|
@@ -262,7 +263,7 @@ var RegistrationPaymentService = class _RegistrationPaymentService {
|
|
|
262
263
|
methods: account.methods,
|
|
263
264
|
successUrl: urls.successUrl,
|
|
264
265
|
cancelUrl: urls.cancelUrl
|
|
265
|
-
});
|
|
266
|
+
}, this.logger);
|
|
266
267
|
const updated = await this.repo.update(pending.id, {
|
|
267
268
|
...billing,
|
|
268
269
|
status: "CHECKOUT_STARTED",
|
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
REQUIRE_FEATURE_KEY,
|
|
8
8
|
loadPlanCatalogFromString,
|
|
9
9
|
periodEndAfter
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3YYLOYUT.js";
|
|
11
11
|
import {
|
|
12
12
|
EnforceMfa
|
|
13
13
|
} from "./chunk-34XVPR6P.js";
|
|
14
14
|
import {
|
|
15
15
|
EntitlementService,
|
|
16
16
|
isLimitExceededError
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-B4YP7REK.js";
|
|
18
18
|
import {
|
|
19
19
|
ENTITLEMENT_SERVICE_TOKEN
|
|
20
20
|
} from "./chunk-OUDSQ3PU.js";
|