@saasicat/nest 0.18.0 → 0.19.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.
- package/dist/_entries.cjs +1309 -519
- package/dist/admin/index.js +1 -1
- package/dist/billing/index.d.cts +7 -4
- package/dist/billing/index.d.ts +7 -4
- package/dist/billing/index.js +6 -6
- package/dist/catalog/index.js +4 -4
- package/dist/checkout-offer/index.js +2 -2
- package/dist/{chunk-Z3FWN3HJ.js → chunk-5ZXBXYXU.js} +3 -3
- package/dist/{chunk-RZVSKKXX.js → chunk-6WA4X5U3.js} +46 -45
- package/dist/{chunk-V34AA7C7.js → chunk-6WL6VQ7Z.js} +1 -1
- package/dist/{chunk-ABB2CRAS.js → chunk-74SCJ4HF.js} +1 -1
- package/dist/{chunk-PLJEAUFU.js → chunk-7JIHG53V.js} +76 -39
- package/dist/{chunk-7RRWI5LH.js → chunk-AFK2IE2L.js} +10 -10
- package/dist/{chunk-32EMXPU2.js → chunk-B7NRY2LV.js} +48 -17
- package/dist/{chunk-MDIZUVIK.js → chunk-BSK6YBLI.js} +1 -1
- package/dist/{chunk-R2QOSVAA.js → chunk-DQKCK7DX.js} +1 -1
- package/dist/{chunk-GLLCB4BP.js → chunk-EUU3B6NB.js} +17 -13
- package/dist/{chunk-EXOLOJFZ.js → chunk-F6DCLVBB.js} +29 -8
- package/dist/{chunk-5KH2O4SF.js → chunk-I77VS3YH.js} +287 -105
- package/dist/{chunk-YITTE646.js → chunk-KUDKD7ZG.js} +34 -14
- package/dist/{chunk-P3DP6GJE.js → chunk-LXUBCLRK.js} +486 -160
- package/dist/{chunk-GJBXOCRZ.js → chunk-ORWIGSNN.js} +45 -17
- package/dist/{chunk-E7AJ42AB.js → chunk-QLJHIIOY.js} +168 -28
- package/dist/{chunk-BOADBIGB.js → chunk-YYUXKLXK.js} +2 -2
- package/dist/{define-saasicat-Rc0rXrYG.d.ts → define-saasicat-CqkhnHn-.d.ts} +1 -1
- package/dist/{define-saasicat-CeDBX9ji.d.cts → define-saasicat-D8c6Bs4T.d.cts} +1 -1
- package/dist/discovery/index.d.cts +2 -2
- package/dist/discovery/index.d.ts +2 -2
- package/dist/discovery/index.js +4 -4
- package/dist/{enforce-quota.interceptor-DMw-bPyk.d.cts → enforce-quota.interceptor-Dk0eEtzV.d.cts} +1 -1
- package/dist/{enforce-quota.interceptor-CmbWX39L.d.ts → enforce-quota.interceptor-Dp8wTYro.d.ts} +1 -1
- package/dist/entitlement/index.js +2 -2
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +17 -17
- package/dist/{module-DgYJur6f.d.ts → module-BwD-wAor.d.ts} +1 -1
- package/dist/{module-CSN8j8Tp.d.cts → module-DsDkbawm.d.cts} +1 -1
- package/dist/platform/index.d.cts +8 -8
- package/dist/platform/index.d.ts +8 -8
- package/dist/platform/index.js +13 -13
- package/dist/promo/index.d.cts +3 -3
- package/dist/promo/index.d.ts +3 -3
- package/dist/promo/index.js +3 -3
- package/dist/registration/index.js +1 -1
- package/dist/{saas-platform.module-DLhoqKNA.d.ts → saas-platform.module-BQmrDGVU.d.ts} +1 -1
- package/dist/{saas-platform.module-D3rUTiho.d.cts → saas-platform.module-DducnQ9s.d.cts} +1 -1
- package/dist/{service-DX8KbGXl.d.cts → service-DPZ2W1E-.d.cts} +2 -2
- package/dist/{service-DX8KbGXl.d.ts → service-DPZ2W1E-.d.ts} +2 -2
- package/dist/subscription-contract/index.js +2 -2
- package/dist/{tenant-billing.controller-BwZRnJ3q.d.ts → tenant-billing.controller-b1G1yB09.d.ts} +2 -2
- package/dist/{tenant-billing.controller-CG4CaFUP.d.cts → tenant-billing.controller-m42YQ_Ei.d.cts} +2 -2
- package/dist/testing/index.d.cts +5 -5
- package/dist/testing/index.d.ts +5 -5
- package/dist/testing/index.js +33 -33
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
appendImplicitDiscountLineItem
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BSK6YBLI.js";
|
|
4
4
|
import {
|
|
5
5
|
SaaSiCatPublicRoute
|
|
6
6
|
} from "./chunk-YSC46BGM.js";
|
|
@@ -21,7 +21,7 @@ var CHECKOUT_OFFER_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/
|
|
|
21
21
|
|
|
22
22
|
// src/checkout-offer/checkout-offer.service.ts
|
|
23
23
|
import { ConflictException, Inject, Injectable, NotFoundException, Optional, UnprocessableEntityException } from "@nestjs/common";
|
|
24
|
-
import { buildFeatureRequiresIndex, collectUnsatisfiedRequires, startOfUtcDay } from "@saasicat/types";
|
|
24
|
+
import { CONTRACT_ERROR_CODES, buildFeatureRequiresIndex, collectUnsatisfiedRequires, startOfUtcDay } from "@saasicat/types";
|
|
25
25
|
function _ts_decorate(decorators, target, key, desc) {
|
|
26
26
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
27
27
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -59,7 +59,13 @@ var CheckoutOfferService = class {
|
|
|
59
59
|
async getById(id) {
|
|
60
60
|
const row = await this.repo.findById(id);
|
|
61
61
|
if (!row) {
|
|
62
|
-
throw new NotFoundException(
|
|
62
|
+
throw new NotFoundException({
|
|
63
|
+
code: CONTRACT_ERROR_CODES.CHECKOUT_OFFER_NOT_FOUND,
|
|
64
|
+
message: `CheckoutOffer '${id}' not found`,
|
|
65
|
+
params: {
|
|
66
|
+
offerId: id
|
|
67
|
+
}
|
|
68
|
+
});
|
|
63
69
|
}
|
|
64
70
|
return row;
|
|
65
71
|
}
|
|
@@ -77,7 +83,7 @@ var CheckoutOfferService = class {
|
|
|
77
83
|
/** Customization in onboarding — only while the offer is `open`. */
|
|
78
84
|
async update(id, data) {
|
|
79
85
|
const existing = await this.getById(id);
|
|
80
|
-
this.assertOpen(existing, "
|
|
86
|
+
this.assertOpen(existing, "changed");
|
|
81
87
|
const next = this.normalizeUpdateData(existing, data);
|
|
82
88
|
await this.assertFeatureRequiresSatisfied({
|
|
83
89
|
projectKey: existing.projectKey,
|
|
@@ -95,7 +101,7 @@ var CheckoutOfferService = class {
|
|
|
95
101
|
*/
|
|
96
102
|
async consume(id) {
|
|
97
103
|
const existing = await this.getById(id);
|
|
98
|
-
this.assertOpen(existing, "
|
|
104
|
+
this.assertOpen(existing, "consumed");
|
|
99
105
|
await this.assertBundleVersionsStillBookable(existing);
|
|
100
106
|
return this.repo.consume(id);
|
|
101
107
|
}
|
|
@@ -124,8 +130,8 @@ var CheckoutOfferService = class {
|
|
|
124
130
|
], requiresIndex);
|
|
125
131
|
if (missingRequires.length > 0) {
|
|
126
132
|
throw new UnprocessableEntityException({
|
|
127
|
-
code:
|
|
128
|
-
message: `
|
|
133
|
+
code: CONTRACT_ERROR_CODES.CHECKOUT_OFFER_FEATURE_DEPENDENCY_UNSATISFIED,
|
|
134
|
+
message: `The selected plan does not cover all feature dependencies: [${missingRequires.join(", ")}] are missing from the plan + selected bundles.`,
|
|
129
135
|
missingRequires
|
|
130
136
|
});
|
|
131
137
|
}
|
|
@@ -205,8 +211,8 @@ var CheckoutOfferService = class {
|
|
|
205
211
|
}
|
|
206
212
|
if (violations.length > 0) {
|
|
207
213
|
throw new UnprocessableEntityException({
|
|
208
|
-
code:
|
|
209
|
-
message: "
|
|
214
|
+
code: CONTRACT_ERROR_CODES.CHECKOUT_OFFER_BUNDLE_VERSION_NOT_BOOKABLE,
|
|
215
|
+
message: "At least one bundle version from the checkout offer is no longer bookable.",
|
|
210
216
|
violations
|
|
211
217
|
});
|
|
212
218
|
}
|
|
@@ -260,15 +266,15 @@ var CheckoutOfferService = class {
|
|
|
260
266
|
const hasPlan = lineItems.some((item) => item.kind === "plan");
|
|
261
267
|
if (!hasPlan) {
|
|
262
268
|
throw new UnprocessableEntityException({
|
|
263
|
-
code:
|
|
264
|
-
message: "
|
|
269
|
+
code: CONTRACT_ERROR_CODES.CHECKOUT_OFFER_PLAN_LINE_ITEM_REQUIRED,
|
|
270
|
+
message: "A checkout offer requires a frozen plan line item."
|
|
265
271
|
});
|
|
266
272
|
}
|
|
267
273
|
const missingBundleVersionIds = input.bundleVersionIds.filter((versionId) => !lineItems.some((item) => item.kind === "bundle" && item.sourceVersionId === versionId));
|
|
268
274
|
if (missingBundleVersionIds.length > 0) {
|
|
269
275
|
throw new UnprocessableEntityException({
|
|
270
|
-
code:
|
|
271
|
-
message: "
|
|
276
|
+
code: CONTRACT_ERROR_CODES.CHECKOUT_OFFER_BUNDLE_LINE_ITEMS_REQUIRED,
|
|
277
|
+
message: "Every selected bundle version requires a frozen bundle line item.",
|
|
272
278
|
bundleVersionIds: missingBundleVersionIds
|
|
273
279
|
});
|
|
274
280
|
}
|
|
@@ -300,13 +306,35 @@ var CheckoutOfferService = class {
|
|
|
300
306
|
}
|
|
301
307
|
assertOpen(existing, action) {
|
|
302
308
|
if (existing.status === "consumed") {
|
|
303
|
-
throw new ConflictException(
|
|
309
|
+
throw new ConflictException({
|
|
310
|
+
code: CONTRACT_ERROR_CODES.CHECKOUT_OFFER_ALREADY_CONSUMED,
|
|
311
|
+
message: `Checkout offer '${existing.id}' has already been consumed and cannot be ${action}`,
|
|
312
|
+
params: {
|
|
313
|
+
offerId: existing.id,
|
|
314
|
+
action
|
|
315
|
+
}
|
|
316
|
+
});
|
|
304
317
|
}
|
|
305
318
|
if (existing.status === "expired") {
|
|
306
|
-
throw new ConflictException(
|
|
319
|
+
throw new ConflictException({
|
|
320
|
+
code: CONTRACT_ERROR_CODES.CHECKOUT_OFFER_EXPIRED,
|
|
321
|
+
message: `Checkout offer '${existing.id}' has expired and cannot be ${action}`,
|
|
322
|
+
params: {
|
|
323
|
+
offerId: existing.id,
|
|
324
|
+
action
|
|
325
|
+
}
|
|
326
|
+
});
|
|
307
327
|
}
|
|
308
328
|
if (this.isExpired(existing)) {
|
|
309
|
-
throw new ConflictException(
|
|
329
|
+
throw new ConflictException({
|
|
330
|
+
code: CONTRACT_ERROR_CODES.CHECKOUT_OFFER_EXPIRED,
|
|
331
|
+
message: `CheckoutOffer '${existing.id}' has expired and cannot be ${action}`,
|
|
332
|
+
params: {
|
|
333
|
+
offerId: existing.id,
|
|
334
|
+
action,
|
|
335
|
+
validUntil: existing.validUntil ?? null
|
|
336
|
+
}
|
|
337
|
+
});
|
|
310
338
|
}
|
|
311
339
|
}
|
|
312
340
|
isExpired(row) {
|
|
@@ -385,7 +413,7 @@ var CreateCheckoutOfferDto = class {
|
|
|
385
413
|
_ts_decorate2([
|
|
386
414
|
IsString(),
|
|
387
415
|
Matches(PROJECT_KEY_PATTERN, {
|
|
388
|
-
message: "projectKey
|
|
416
|
+
message: "projectKey must be kebab-case"
|
|
389
417
|
}),
|
|
390
418
|
MaxLength(64),
|
|
391
419
|
_ts_metadata2("design:type", String)
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
computeIncludedVat,
|
|
4
4
|
getPlanPriceGross,
|
|
5
5
|
round2
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DQKCK7DX.js";
|
|
7
7
|
import {
|
|
8
8
|
__name
|
|
9
9
|
} from "./chunk-SHUYVCID.js";
|
|
@@ -50,15 +50,15 @@ function buildLabel(code, cycle) {
|
|
|
50
50
|
maximumFractionDigits: 2
|
|
51
51
|
})} \u20AC`;
|
|
52
52
|
if (code.durationType === "ONCE") {
|
|
53
|
-
return `${valueStr}
|
|
53
|
+
return `${valueStr} once`;
|
|
54
54
|
}
|
|
55
55
|
if (code.durationType === "MONTHS") {
|
|
56
56
|
const m = code.durationValue ?? 0;
|
|
57
|
-
return m === 1 ? `${valueStr}
|
|
57
|
+
return m === 1 ? `${valueStr} for the first month` : `${valueStr} for ${m} months`;
|
|
58
58
|
}
|
|
59
59
|
const n = code.durationValue ?? 0;
|
|
60
|
-
if (n === 1) return cycle === "YEARLY" ? `${valueStr}
|
|
61
|
-
return cycle === "YEARLY" ? `${valueStr}
|
|
60
|
+
if (n === 1) return cycle === "YEARLY" ? `${valueStr} for the first year` : `${valueStr} for the first month`;
|
|
61
|
+
return cycle === "YEARLY" ? `${valueStr} for the first ${n} years` : `${valueStr} for the first ${n} months`;
|
|
62
62
|
}
|
|
63
63
|
__name(buildLabel, "buildLabel");
|
|
64
64
|
|
|
@@ -74,6 +74,7 @@ var PROMO_SERVICE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/Promo
|
|
|
74
74
|
|
|
75
75
|
// src/promo/service.ts
|
|
76
76
|
import { BadRequestException, Inject, Injectable, NotFoundException } from "@nestjs/common";
|
|
77
|
+
import { BILLING_ERROR_CODES, PROMO_ERROR_CODES } from "@saasicat/types";
|
|
77
78
|
function _ts_decorate(decorators, target, key, desc) {
|
|
78
79
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
79
80
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -91,7 +92,23 @@ function _ts_param(paramIndex, decorator) {
|
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
__name(_ts_param, "_ts_param");
|
|
94
|
-
var
|
|
95
|
+
var CODE_MIN_LENGTH = 4;
|
|
96
|
+
var CODE_MAX_LENGTH = 32;
|
|
97
|
+
var CODE_PATTERN = new RegExp(`^[A-Z0-9_-]{${CODE_MIN_LENGTH},${CODE_MAX_LENGTH}}$`);
|
|
98
|
+
var PERCENT_MIN_EXCLUSIVE = 0;
|
|
99
|
+
var PERCENT_MAX = 100;
|
|
100
|
+
var DURATION_MIN = 1;
|
|
101
|
+
var DURATION_MAX = 24;
|
|
102
|
+
function notRedeemable(reason) {
|
|
103
|
+
return new BadRequestException({
|
|
104
|
+
code: PROMO_ERROR_CODES.PROMO_CODE_NOT_REDEEMABLE,
|
|
105
|
+
message: `Code cannot be redeemed: ${reason}`,
|
|
106
|
+
params: {
|
|
107
|
+
reason
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
__name(notRedeemable, "notRedeemable");
|
|
95
112
|
var PromoCodesService = class {
|
|
96
113
|
static {
|
|
97
114
|
__name(this, "PromoCodesService");
|
|
@@ -120,46 +137,118 @@ var PromoCodesService = class {
|
|
|
120
137
|
async create(input) {
|
|
121
138
|
const code = input.code.trim().toUpperCase();
|
|
122
139
|
if (!CODE_PATTERN.test(code)) {
|
|
123
|
-
throw new BadRequestException(
|
|
140
|
+
throw new BadRequestException({
|
|
141
|
+
code: PROMO_ERROR_CODES.PROMO_CODE_FORMAT_INVALID,
|
|
142
|
+
message: 'The code may only contain upper-case letters, digits, "-" and "_" (4\u201332 characters).',
|
|
143
|
+
params: {
|
|
144
|
+
promoCode: code,
|
|
145
|
+
minLength: CODE_MIN_LENGTH,
|
|
146
|
+
maxLength: CODE_MAX_LENGTH
|
|
147
|
+
}
|
|
148
|
+
});
|
|
124
149
|
}
|
|
125
150
|
if (input.valueType === "PERCENT") {
|
|
126
|
-
if (!(input.value >
|
|
127
|
-
throw new BadRequestException(
|
|
151
|
+
if (!(input.value > PERCENT_MIN_EXCLUSIVE && input.value <= PERCENT_MAX)) {
|
|
152
|
+
throw new BadRequestException({
|
|
153
|
+
code: PROMO_ERROR_CODES.PROMO_PERCENT_OUT_OF_RANGE,
|
|
154
|
+
message: "The percentage must be between 0 and 100.",
|
|
155
|
+
params: {
|
|
156
|
+
value: input.value,
|
|
157
|
+
min: PERCENT_MIN_EXCLUSIVE,
|
|
158
|
+
max: PERCENT_MAX
|
|
159
|
+
}
|
|
160
|
+
});
|
|
128
161
|
}
|
|
129
162
|
} else if (!(input.value > 0)) {
|
|
130
|
-
throw new BadRequestException(
|
|
163
|
+
throw new BadRequestException({
|
|
164
|
+
code: PROMO_ERROR_CODES.PROMO_AMOUNT_NOT_POSITIVE,
|
|
165
|
+
message: "The amount must be positive.",
|
|
166
|
+
params: {
|
|
167
|
+
value: input.value,
|
|
168
|
+
min: 0
|
|
169
|
+
}
|
|
170
|
+
});
|
|
131
171
|
}
|
|
132
172
|
if (input.durationType === "ONCE") {
|
|
133
173
|
if (input.durationValue != null) {
|
|
134
|
-
throw new BadRequestException(
|
|
174
|
+
throw new BadRequestException({
|
|
175
|
+
code: PROMO_ERROR_CODES.PROMO_ONE_OFF_WITH_DURATION,
|
|
176
|
+
message: "A one-off discount must not set a duration.",
|
|
177
|
+
params: {
|
|
178
|
+
durationValue: input.durationValue
|
|
179
|
+
}
|
|
180
|
+
});
|
|
135
181
|
}
|
|
136
182
|
} else {
|
|
137
183
|
const v = input.durationValue;
|
|
138
|
-
if (v == null || v <
|
|
139
|
-
throw new BadRequestException(
|
|
184
|
+
if (v == null || v < DURATION_MIN || v > DURATION_MAX) {
|
|
185
|
+
throw new BadRequestException({
|
|
186
|
+
code: PROMO_ERROR_CODES.PROMO_DURATION_INVALID,
|
|
187
|
+
message: "Invalid duration (at most 24 months or billing periods).",
|
|
188
|
+
params: {
|
|
189
|
+
durationValue: v ?? null,
|
|
190
|
+
min: DURATION_MIN,
|
|
191
|
+
max: DURATION_MAX
|
|
192
|
+
}
|
|
193
|
+
});
|
|
140
194
|
}
|
|
141
195
|
}
|
|
142
196
|
if (input.validFrom && input.validUntil && input.validFrom >= input.validUntil) {
|
|
143
|
-
throw new BadRequestException(
|
|
197
|
+
throw new BadRequestException({
|
|
198
|
+
code: PROMO_ERROR_CODES.PROMO_VALIDITY_WINDOW_INVALID,
|
|
199
|
+
message: "Invalid validity window.",
|
|
200
|
+
params: {
|
|
201
|
+
validFrom: input.validFrom.toISOString(),
|
|
202
|
+
validUntil: input.validUntil.toISOString()
|
|
203
|
+
}
|
|
204
|
+
});
|
|
144
205
|
}
|
|
145
206
|
const plans = input.appliesToPlans ?? [];
|
|
146
207
|
const blocked = this.config.nonRedeemablePlans ?? [];
|
|
147
208
|
for (const p of plans) {
|
|
148
209
|
if (blocked.includes(p)) {
|
|
149
|
-
throw new BadRequestException(
|
|
210
|
+
throw new BadRequestException({
|
|
211
|
+
code: PROMO_ERROR_CODES.PROMO_PLAN_NOT_DISCOUNTABLE,
|
|
212
|
+
message: `${p}-Plan cannot be discounted.`,
|
|
213
|
+
params: {
|
|
214
|
+
plan: p
|
|
215
|
+
}
|
|
216
|
+
});
|
|
150
217
|
}
|
|
151
218
|
}
|
|
152
219
|
if (input.minimumPlanAmountGross != null && input.minimumPlanAmountGross <= 0) {
|
|
153
|
-
throw new BadRequestException(
|
|
220
|
+
throw new BadRequestException({
|
|
221
|
+
code: PROMO_ERROR_CODES.PROMO_MIN_AMOUNT_NOT_POSITIVE,
|
|
222
|
+
message: "The minimum plan gross amount must be positive.",
|
|
223
|
+
params: {
|
|
224
|
+
value: input.minimumPlanAmountGross,
|
|
225
|
+
min: 0
|
|
226
|
+
}
|
|
227
|
+
});
|
|
154
228
|
}
|
|
155
229
|
if (input.valueType === "ABSOLUTE" && !input.allowZeroInvoice) {
|
|
156
230
|
const lowestApplicableGross = this.lowestApplicablePlanGross(plans);
|
|
157
231
|
if (lowestApplicableGross != null && input.value >= lowestApplicableGross) {
|
|
158
|
-
throw new BadRequestException(
|
|
232
|
+
throw new BadRequestException({
|
|
233
|
+
code: PROMO_ERROR_CODES.PROMO_WOULD_PRODUCE_ZERO_INVOICE,
|
|
234
|
+
message: "For absolute amounts the discount must stay below the lowest applicable plan price, or allowZeroInvoice must be enabled.",
|
|
235
|
+
params: {
|
|
236
|
+
value: input.value,
|
|
237
|
+
lowestApplicablePlanGross: lowestApplicableGross
|
|
238
|
+
}
|
|
239
|
+
});
|
|
159
240
|
}
|
|
160
241
|
}
|
|
161
242
|
const exists = await this.promoRepo.findByCode(code);
|
|
162
|
-
if (exists)
|
|
243
|
+
if (exists) {
|
|
244
|
+
throw new BadRequestException({
|
|
245
|
+
code: PROMO_ERROR_CODES.PROMO_CODE_ALREADY_EXISTS,
|
|
246
|
+
message: "The code already exists.",
|
|
247
|
+
params: {
|
|
248
|
+
promoCode: code
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
163
252
|
return this.promoRepo.create({
|
|
164
253
|
...input,
|
|
165
254
|
code
|
|
@@ -167,10 +256,25 @@ var PromoCodesService = class {
|
|
|
167
256
|
}
|
|
168
257
|
async update(id, input) {
|
|
169
258
|
const existing = await this.promoRepo.findById(id);
|
|
170
|
-
if (!existing)
|
|
259
|
+
if (!existing) {
|
|
260
|
+
throw new NotFoundException({
|
|
261
|
+
code: PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
|
|
262
|
+
message: "Code not found",
|
|
263
|
+
params: {
|
|
264
|
+
promoCodeId: id
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
171
268
|
if (input.maxRedemptions != null && existing.maxRedemptions != null) {
|
|
172
269
|
if (input.maxRedemptions < existing.maxRedemptions) {
|
|
173
|
-
throw new BadRequestException(
|
|
270
|
+
throw new BadRequestException({
|
|
271
|
+
code: PROMO_ERROR_CODES.PROMO_MAX_REDEMPTIONS_LOWERED,
|
|
272
|
+
message: "maxRedemptions cannot be lowered.",
|
|
273
|
+
params: {
|
|
274
|
+
current: existing.maxRedemptions,
|
|
275
|
+
requested: input.maxRedemptions
|
|
276
|
+
}
|
|
277
|
+
});
|
|
174
278
|
}
|
|
175
279
|
}
|
|
176
280
|
return this.promoRepo.update(id, input);
|
|
@@ -178,7 +282,14 @@ var PromoCodesService = class {
|
|
|
178
282
|
async softDelete(id) {
|
|
179
283
|
const redemptions = await this.redemptionRepo.countByPromoCode(id);
|
|
180
284
|
if (redemptions > 0) {
|
|
181
|
-
throw new BadRequestException(
|
|
285
|
+
throw new BadRequestException({
|
|
286
|
+
code: PROMO_ERROR_CODES.PROMO_CODE_HAS_REDEMPTIONS,
|
|
287
|
+
message: "The code already has redemptions \u2014 it cannot be soft-deleted. Pause it instead.",
|
|
288
|
+
params: {
|
|
289
|
+
promoCodeId: id,
|
|
290
|
+
redemptions
|
|
291
|
+
}
|
|
292
|
+
});
|
|
182
293
|
}
|
|
183
294
|
await this.promoRepo.softDelete(id);
|
|
184
295
|
}
|
|
@@ -189,7 +300,15 @@ var PromoCodesService = class {
|
|
|
189
300
|
async findOne(id) {
|
|
190
301
|
await this.lazyExpire();
|
|
191
302
|
const code = await this.promoRepo.findById(id);
|
|
192
|
-
if (!code || code.deletedAt)
|
|
303
|
+
if (!code || code.deletedAt) {
|
|
304
|
+
throw new NotFoundException({
|
|
305
|
+
code: PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
|
|
306
|
+
message: "Code not found",
|
|
307
|
+
params: {
|
|
308
|
+
promoCodeId: id
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
193
312
|
return code;
|
|
194
313
|
}
|
|
195
314
|
async stats(id) {
|
|
@@ -317,28 +436,49 @@ var PromoCodesService = class {
|
|
|
317
436
|
const code = input.code.trim().toUpperCase();
|
|
318
437
|
const promo = await this.promoRepo.findByCode(code, tx);
|
|
319
438
|
if (!promo || promo.deletedAt) {
|
|
320
|
-
throw new BadRequestException(
|
|
439
|
+
throw new BadRequestException({
|
|
440
|
+
code: PROMO_ERROR_CODES.PROMO_CODE_NOT_FOUND,
|
|
441
|
+
message: "Code not found",
|
|
442
|
+
params: {
|
|
443
|
+
promoCode: code
|
|
444
|
+
}
|
|
445
|
+
});
|
|
321
446
|
}
|
|
322
447
|
const sub = await this.subscriptionLookup.findById(input.subscriptionId, tx);
|
|
323
|
-
if (!sub)
|
|
448
|
+
if (!sub) {
|
|
449
|
+
throw new NotFoundException({
|
|
450
|
+
code: BILLING_ERROR_CODES.SUBSCRIPTION_NOT_FOUND,
|
|
451
|
+
message: "Subscription not found",
|
|
452
|
+
params: {
|
|
453
|
+
subscriptionId: input.subscriptionId
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
}
|
|
324
457
|
if (sub.tenantId !== input.tenantId) {
|
|
325
|
-
throw new BadRequestException(
|
|
458
|
+
throw new BadRequestException({
|
|
459
|
+
code: BILLING_ERROR_CODES.SUBSCRIPTION_TENANT_MISMATCH,
|
|
460
|
+
message: "Subscription does not belong to the tenant",
|
|
461
|
+
params: {
|
|
462
|
+
subscriptionId: sub.id,
|
|
463
|
+
tenantId: input.tenantId
|
|
464
|
+
}
|
|
465
|
+
});
|
|
326
466
|
}
|
|
327
467
|
const reason = this.checkEligibility(promo, {
|
|
328
468
|
code,
|
|
329
469
|
planId: sub.plan,
|
|
330
470
|
billingCycle: sub.billingCycle
|
|
331
471
|
});
|
|
332
|
-
if (reason) throw
|
|
472
|
+
if (reason) throw notRedeemable(reason);
|
|
333
473
|
const firstTimeReason = await this.checkFirstTimeCustomer(promo, input.email, {
|
|
334
474
|
requireEmail: true
|
|
335
475
|
});
|
|
336
476
|
if (firstTimeReason) {
|
|
337
|
-
throw
|
|
477
|
+
throw notRedeemable(firstTimeReason);
|
|
338
478
|
}
|
|
339
479
|
const claimed = await this.promoRepo.claimSlot(promo.id, tx);
|
|
340
480
|
if (!claimed) {
|
|
341
|
-
throw
|
|
481
|
+
throw notRedeemable("EXHAUSTED");
|
|
342
482
|
}
|
|
343
483
|
await this.promoRepo.markExhaustedIfFull(promo.id, tx);
|
|
344
484
|
const startsAt = sub.startedAt ?? /* @__PURE__ */ new Date();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DiscoveryScanner
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5ZXBXYXU.js";
|
|
4
4
|
import {
|
|
5
5
|
DEFINES_QUOTA_KEY,
|
|
6
6
|
DISCOVERY_SNAPSHOT_TOKEN,
|
|
@@ -44,7 +44,7 @@ async function runHeadlessDiscoveryScan(appModule, options = {}) {
|
|
|
44
44
|
await app.close();
|
|
45
45
|
}
|
|
46
46
|
} catch (err) {
|
|
47
|
-
console.error("[discovery-scan]
|
|
47
|
+
console.error("[discovery-scan] ERROR:", err instanceof Error ? err.message : err);
|
|
48
48
|
return exit(4);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -3,7 +3,7 @@ import { ExecutionContext } from '@nestjs/common';
|
|
|
3
3
|
import { Reflector } from '@nestjs/core';
|
|
4
4
|
import { SuperAdminProvisioningPort, SetupStatusResponse, SetupRequest, SetupResult, SetupConfirmMfaRequest, SetupConfirmMfaResponse } from '@saasicat/types';
|
|
5
5
|
import { h as MfaService } from './admin-stats.service-Db2exT_d.js';
|
|
6
|
-
import { f as SaasPlatformModuleOptions } from './saas-platform.module-
|
|
6
|
+
import { f as SaasPlatformModuleOptions } from './saas-platform.module-BQmrDGVU.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Shared metadata key for endpoints that intentionally run without application
|
|
@@ -3,7 +3,7 @@ import { ExecutionContext } from '@nestjs/common';
|
|
|
3
3
|
import { Reflector } from '@nestjs/core';
|
|
4
4
|
import { SuperAdminProvisioningPort, SetupStatusResponse, SetupRequest, SetupResult, SetupConfirmMfaRequest, SetupConfirmMfaResponse } from '@saasicat/types';
|
|
5
5
|
import { h as MfaService } from './admin-stats.service-HUZIU448.cjs';
|
|
6
|
-
import { f as SaasPlatformModuleOptions } from './saas-platform.module-
|
|
6
|
+
import { f as SaasPlatformModuleOptions } from './saas-platform.module-DducnQ9s.cjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Shared metadata key for endpoints that intentionally run without application
|
|
@@ -117,7 +117,7 @@ interface ImplementsCapabilityMetadata extends ImplementsCapabilityOptions {
|
|
|
117
117
|
* ```ts
|
|
118
118
|
* @Post()
|
|
119
119
|
* @ImplementsCapability('invoice.create', {
|
|
120
|
-
* label: '
|
|
120
|
+
* label: 'Create invoice',
|
|
121
121
|
* feature: 'INVOICE_MANAGEMENT',
|
|
122
122
|
* kind: 'endpoint',
|
|
123
123
|
* owner: 'accounting',
|
|
@@ -157,7 +157,7 @@ declare const RequiresCapability: (...capabilityKeys: string[]) => _nestjs_commo
|
|
|
157
157
|
* @Injectable()
|
|
158
158
|
* @DefinesQuota({
|
|
159
159
|
* key: 'invoicesPerMonth',
|
|
160
|
-
* label: '
|
|
160
|
+
* label: 'Invoices per month',
|
|
161
161
|
* unit: 'invoices',
|
|
162
162
|
* policy: 'monthlyReset',
|
|
163
163
|
* feature: 'INVOICE_MANAGEMENT',
|
|
@@ -117,7 +117,7 @@ interface ImplementsCapabilityMetadata extends ImplementsCapabilityOptions {
|
|
|
117
117
|
* ```ts
|
|
118
118
|
* @Post()
|
|
119
119
|
* @ImplementsCapability('invoice.create', {
|
|
120
|
-
* label: '
|
|
120
|
+
* label: 'Create invoice',
|
|
121
121
|
* feature: 'INVOICE_MANAGEMENT',
|
|
122
122
|
* kind: 'endpoint',
|
|
123
123
|
* owner: 'accounting',
|
|
@@ -157,7 +157,7 @@ declare const RequiresCapability: (...capabilityKeys: string[]) => _nestjs_commo
|
|
|
157
157
|
* @Injectable()
|
|
158
158
|
* @DefinesQuota({
|
|
159
159
|
* key: 'invoicesPerMonth',
|
|
160
|
-
* label: '
|
|
160
|
+
* label: 'Invoices per month',
|
|
161
161
|
* unit: 'invoices',
|
|
162
162
|
* policy: 'monthlyReset',
|
|
163
163
|
* feature: 'INVOICE_MANAGEMENT',
|
package/dist/discovery/index.js
CHANGED
|
@@ -4,21 +4,21 @@ import {
|
|
|
4
4
|
ImplementsCapability,
|
|
5
5
|
RequiresCapability,
|
|
6
6
|
runHeadlessDiscoveryScan
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-YYUXKLXK.js";
|
|
8
8
|
import {
|
|
9
9
|
DiscoverySnapshotNotFoundError,
|
|
10
10
|
loadDiscoverySnapshotFromFile
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-74SCJ4HF.js";
|
|
12
12
|
import {
|
|
13
13
|
DiscoveryModule,
|
|
14
14
|
buildDiscoveryController
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-6WL6VQ7Z.js";
|
|
16
16
|
import {
|
|
17
17
|
DISCOVERY_APP_INFO_TOKEN,
|
|
18
18
|
DISCOVERY_SNAPSHOT_PATH_TOKEN,
|
|
19
19
|
DiscoveryScanner,
|
|
20
20
|
computeSnapshotHash
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-5ZXBXYXU.js";
|
|
22
22
|
import {
|
|
23
23
|
DEFINES_QUOTA_KEY,
|
|
24
24
|
DISCOVERY_SNAPSHOT_TOKEN,
|
package/dist/{enforce-quota.interceptor-DMw-bPyk.d.cts → enforce-quota.interceptor-Dk0eEtzV.d.cts}
RENAMED
|
@@ -2,7 +2,7 @@ import { CanActivate, ExecutionContext, NestInterceptor, CallHandler } from '@ne
|
|
|
2
2
|
import { Reflector } from '@nestjs/core';
|
|
3
3
|
import { Observable } from 'rxjs';
|
|
4
4
|
import { PlanCatalog, QuotaProvider } from '@saasicat/types';
|
|
5
|
-
import { p as PlanResolverPort } from './saas-platform.module-
|
|
5
|
+
import { p as PlanResolverPort } from './saas-platform.module-DducnQ9s.cjs';
|
|
6
6
|
|
|
7
7
|
interface StaticEntitlementSnapshot {
|
|
8
8
|
planId: string | null;
|
package/dist/{enforce-quota.interceptor-CmbWX39L.d.ts → enforce-quota.interceptor-Dp8wTYro.d.ts}
RENAMED
|
@@ -2,7 +2,7 @@ import { CanActivate, ExecutionContext, NestInterceptor, CallHandler } from '@ne
|
|
|
2
2
|
import { Reflector } from '@nestjs/core';
|
|
3
3
|
import { Observable } from 'rxjs';
|
|
4
4
|
import { PlanCatalog, QuotaProvider } from '@saasicat/types';
|
|
5
|
-
import { p as PlanResolverPort } from './saas-platform.module-
|
|
5
|
+
import { p as PlanResolverPort } from './saas-platform.module-BQmrDGVU.js';
|
|
6
6
|
|
|
7
7
|
interface StaticEntitlementSnapshot {
|
|
8
8
|
planId: string | null;
|
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
mergeSubscriptionBundlesIntoLimits,
|
|
20
20
|
resolveEntitlementPlan,
|
|
21
21
|
toEffectiveLimitsSnapshot
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import "../chunk-
|
|
22
|
+
} from "../chunk-F6DCLVBB.js";
|
|
23
|
+
import "../chunk-DQKCK7DX.js";
|
|
24
24
|
import "../chunk-NYLON2VC.js";
|
|
25
25
|
import {
|
|
26
26
|
ENTITLEMENT_RESOLUTION_CONFIG_TOKEN,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
export { P as ProviderSpec, a as asProvider } from './di-CcNeq9v-.cjs';
|
|
2
|
-
import { S as SetupService } from './define-saasicat-
|
|
3
|
-
export { a as SAASICAT_PUBLIC_ROUTE_KEY, b as SETUP_CONFIG_TOKEN, c as SETUP_PROVISIONING_PORT_TOKEN, d as SaaSiCatPublicRoute, e as SetupConfig, f as defineSaaSiCat, i as isSaaSiCatPublicRoute } from './define-saasicat-
|
|
2
|
+
import { S as SetupService } from './define-saasicat-D8c6Bs4T.cjs';
|
|
3
|
+
export { a as SAASICAT_PUBLIC_ROUTE_KEY, b as SETUP_CONFIG_TOKEN, c as SETUP_PROVISIONING_PORT_TOKEN, d as SaaSiCatPublicRoute, e as SetupConfig, f as defineSaaSiCat, i as isSaaSiCatPublicRoute } from './define-saasicat-D8c6Bs4T.cjs';
|
|
4
4
|
export { CreatePromoCodeDto, PROMO_CODE_REDEMPTION_REPOSITORY_TOKEN, PROMO_CODE_REPOSITORY_TOKEN, PROMO_CODE_VALIDATION_LOG_REPOSITORY_TOKEN, PROMO_FIRST_TIME_CUSTOMER_CHECK_TOKEN, PROMO_REVENUE_DEDUCTION_AGGREGATOR_TOKEN, PROMO_SERVICE_CONFIG_TOKEN, PROMO_SUBSCRIPTION_LOOKUP_TOKEN, PROMO_TRANSACTION_RUNNER_TOKEN, PreviewPromoCodeDto, PromoCodeExpirer, PromoCodeForCalc, PromoCodePublicController, UpdatePromoCodeDto, addCycles, buildLabel, buildPromoCodeAdminController, computeDiscountGross, computeDiscountedGross, computeIncludedVat, computeRegularStartsAt, grossFromNet, round2 } from './promo/index.cjs';
|
|
5
|
-
export { P as PreviewInput, a as PreviewInvalid, b as PreviewReason, c as PreviewResult, d as PreviewValid, e as PromoCodeStats, f as PromoCodesService, g as PromoServiceConfig, R as RedeemInput } from './service-
|
|
5
|
+
export { P as PreviewInput, a as PreviewInvalid, b as PreviewReason, c as PreviewResult, d as PreviewValid, e as PromoCodeStats, f as PromoCodesService, g as PromoServiceConfig, R as RedeemInput } from './service-DPZ2W1E-.cjs';
|
|
6
6
|
export { P as PromoCodeRateLimitGuard, h as hashIp, i as ipFingerprint } from './rate-limit.guard-dntqAlfZ.cjs';
|
|
7
|
-
export { P as PromoCodesModule, a as PromoCodesModuleOptions } from './module-
|
|
7
|
+
export { P as PromoCodesModule, a as PromoCodesModuleOptions } from './module-DsDkbawm.cjs';
|
|
8
8
|
export { AjvErrorLike, CatalogBundleUpsellResolver, ConfiguratorCatalogBuilder, FEATURE_GUARD_CONFIG_TOKEN, FEATURE_UI_REGISTRY_TOKEN, FeatureGuard, FeatureGuardConfig, LimitExceededFilter, LoadPlanCatalogOptions, MarketingFields, NextPeriodWindow, PLAN_CATALOG_IMPORT_SINK_TOKEN, PLAN_CATALOG_READ_SINK_TOKEN, PLAN_CATALOG_TOKEN, PUBLIC_CATALOG_BUNDLE_REPOSITORY_TOKEN, PUBLIC_CATALOG_MARKETING_REPOSITORY_TOKEN, PUBLIC_CATALOG_PROJECT_KEY_TOKEN, PeriodRollInput, PlanCatalogBuildSettings, PlanCatalogImportDto, PlanCatalogImporterControllerConfig, PlanCatalogImporterModule, PlanCatalogImporterModuleOptions, PlanCatalogImporterService, PlanCatalogModule, PlanCatalogModuleOptions, PlanCatalogValidationError, PlanResponseEntry, PublicBundleEntry, PublicCatalogController, PublicCatalogModule, PublicCatalogModuleOptions, PublishValidationError, PublishablePlanVersion, REQUIRE_FEATURE_KEY, RenewalDecision, RenewalSubInput, RequireFeature, SUBSCRIPTION_BUNDLE_CONFIG_TOKEN, SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN, SubscriptionContractFreezeService, UPSELL_OFFER_CURRENCY_TOKEN, UPSELL_OFFER_RESOLVER_TOKEN, assertBaseVersionFresh, assertChangeNote, assertDraftPublishable, assertOptimisticLockHeld, buildPlanCatalogFromSnapshot, buildPlanCatalogImporterController, buildTenantSubscriptionBundlesController, clearPendingPlanVersionFields, computeCarriedTrialEndsAt, computeNextPeriod, decideRenewal, findPlan, getActiveFeatureKeys, getMarketedPlans, getPlanOrThrow, getPlanPriceGross, getPlanPriceNet, getPlanQuota, initialPeriodWindow, isFeatureInPlan, isFeaturePlannedOnly, loadPlanCatalogFromFile, loadPlanCatalogFromString, periodEndAfter, periodEndWithMinLead } from './billing/index.cjs';
|
|
9
9
|
import { SetupStatusResponse, SetupResult, SetupConfirmMfaResponse } from '@saasicat/types';
|
|
10
10
|
export { BundleVersionFields, ChangeDirection, DiffResult, DiscoveredCapability, DiscoveredFeature, DiscoveredQuota, DiscoverySnapshot, PasswordHasher, PlanVersionFields, VersionChange, VersionChangeDirection, classifyBundleVersionDiff, classifyPlanDiff } from '@saasicat/types';
|
|
11
11
|
export { A as AUDIT_CONTEXT_RESOLVER_TOKEN, a as AuditContextResolver, b as AuthGuardList, C as CONTRACT_FREEZE_PORT_TOKEN, c as CONTRACT_FREEZE_PROJECT_KEY_TOKEN, d as CONTRACT_FREEZE_SOURCE_PORT_TOKEN, e as ContractFreezeBundleSnapshot, f as ContractFreezePort, g as ContractFreezeSourcePort, D as DuePendingPlanChange, P as PENDING_PLAN_QUERY_PORT_TOKEN, h as PendingPlanQueryPort, S as SELF_SERVICE_BLOCKED_BUNDLES_TOKEN, i as SELF_SERVICE_BLOCKED_PLANS_TOKEN, j as SUBSCRIPTION_USAGE_PORT_TOKEN, k as SUBSCRIPTION_WRITE_PORT_TOKEN, l as SelfServiceBlockedBundles, m as SelfServiceBlockedPlans, n as SubscriptionBundleControllerOptions, o as SubscriptionBundleModule, p as SubscriptionBundleModuleOptions, T as TENANT_AUTH_GUARDS_TOKEN, q as TENANT_ID_RESOLVER_TOKEN, r as TRIAL_PROJECTION_PORT_TOKEN, s as TenantBillingModule, t as TenantBillingModuleOptions, u as TenantIdResolver, v as TrialProjectionInput, w as TrialProjectionPort, U as USAGE_SNAPSHOT_PORT_TOKEN, x as USER_EMAIL_RESOLVER_TOKEN, y as USER_ID_RESOLVER_TOKEN, z as UserEmailResolver, B as UserIdResolver } from './subscription-bundles.module-DCpV-Pb5.cjs';
|
|
12
|
-
export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from './tenant-billing.controller-
|
|
12
|
+
export { A as AddBundleToSubscriptionInput, B as BundlePreviewSnapshot, C as CancelBundleFromSubscriptionInput, a as CancelSubscriptionDto, b as ChangePlanDto, c as CompleteOnboardingSubscriptionDto, d as ComposedTenantAuthGuard, L as LimitsCheckRow, P as PendingPlanMaterializationService, e as PlanChangeContext, f as PlanChangePreviewDto, g as PlanChangePreviewIssue, h as PlanChangePreviewService, i as PlanChangeType, j as PlanSnapshotDto, k as PreviewPlanChangeDto, l as ProrationDto, m as ProrationInput, R as RedundantFeatureHint, S as SubscriptionBundleAddPreviewDto, n as SubscriptionBundleCancelPreviewDto, o as SubscriptionBundleConfig, p as SubscriptionBundlePreviewContext, q as SubscriptionBundlePreviewIssue, r as SubscriptionBundlePreviewService, s as SubscriptionBundlesService, T as TenantAdminGuard, t as TenantBillingController, U as UsageResponse, u as addMonths, v as computeProration, w as resolveBundleCancelEffectiveAt, x as resolveBundlePriceNet } from './tenant-billing.controller-m42YQ_Ei.cjs';
|
|
13
13
|
export { C as CustomLimitsShape, E as EffectiveLimits, a as EffectiveLimitsSnapshot, b as EnforceLimitInput, c as EntitlementService, P as PlanVersionSnapshot, S as SubscriptionBundleSnapshot, d as SubscriptionLimitsInput, e as aggregateContractLineItemEntitlements, f as aggregateLimits, g as aggregateSubscriptionBundleQuotas, h as applyCustomLimits, i as collectSubscriptionBundleFeatures, j as contractBundleVersionIds, k as contractLimits, l as filterActiveSubscriptionBundles, m as filterPlannedOnlyFeatures, n as hasAnyFeature, o as hasFeature, p as mergeSubscriptionBundlesIntoLimits, t as toEffectiveLimitsSnapshot } from './aggregation-SKfXu09x.cjs';
|
|
14
14
|
export { ENTITLEMENT_RESOLUTION_CONFIG_TOKEN, ENTITLEMENT_SERVICE_TOKEN, EntitlementModule, EntitlementModuleOptions, LimitExceededError, PLAN_VERSION_REPOSITORY_TOKEN, ReplacedByIndex, SUBSCRIPTION_REPOSITORY_TOKEN, TRANSACTION_RUNNER_TOKEN, buildReplacedByIndex, expandReplacedFeatures, isLimitExceededError } from './entitlement/index.cjs';
|
|
15
15
|
export { E as EntitlementResolutionConfig, a as EntitlementResolutionInput, r as resolveEntitlementPlan } from './plan-resolution-CFCoUkrE.cjs';
|
|
@@ -17,7 +17,7 @@ export { ADMIN_STATS_AUDIT_WINDOW_DAYS_TOKEN, AUDIT_PORT_TOKEN, AUDIT_STATS_PORT
|
|
|
17
17
|
export { A as AdminBypassRlsInterceptor, a as AdminManifestModule, b as AdminManifestModuleOptions, c as AdminManifestService, d as AdminModule, e as AdminModuleOptions, f as AdminStatsService, g as AdminStatsSnapshot, M as MfaGuard, h as MfaService, P as PLATFORM_CORE_CONTRIBUTION_TOKEN, R as REQUIRE_MFA_KEY, i as RequireMfa, S as SuperAdminGuard, T as TotpSetupResult, V as VerifyTotpInput } from './admin-stats.service-HUZIU448.cjs';
|
|
18
18
|
export { A as AdminAuditService } from './admin-audit.service-9IqXMlZm.cjs';
|
|
19
19
|
export { A as ADMIN_MANIFEST_CONFIG, a as ADMIN_RESOURCES_PORT_TOKEN, b as AdminManifestConfig, c as AdminResourcesModule, d as AdminResourcesModuleOptions, e as AdminResourcesService, f as AdminStatsModule, g as AdminStatsModuleOptions, S as SuspendTenantDto } from './admin-resources.module-DGgGSdzN.cjs';
|
|
20
|
-
export { S as SaaSiCatModule, a as SaasPlatformAdapters, b as SaasPlatformAdminResourcesOptions, c as SaasPlatformAdminStatsOptions, d as SaasPlatformCatalogOptions, e as SaasPlatformCheckoutOfferOptions, S as SaasPlatformModule, f as SaasPlatformModuleOptions, g as SaasPlatformPromoCodesOptions, h as SaasPlatformSetupOptions, i as SaasPlatformSubscriptionBundlesOptions, j as SaasPlatformSubscriptionContractOptions, k as SaasPlatformTenantAuthGuards, l as SaasPlatformTenantBillingOptions, m as SetupModule, n as SetupModuleOptions } from './saas-platform.module-
|
|
20
|
+
export { S as SaaSiCatModule, a as SaasPlatformAdapters, b as SaasPlatformAdminResourcesOptions, c as SaasPlatformAdminStatsOptions, d as SaasPlatformCatalogOptions, e as SaasPlatformCheckoutOfferOptions, S as SaasPlatformModule, f as SaasPlatformModuleOptions, g as SaasPlatformPromoCodesOptions, h as SaasPlatformSetupOptions, i as SaasPlatformSubscriptionBundlesOptions, j as SaasPlatformSubscriptionContractOptions, k as SaasPlatformTenantAuthGuards, l as SaasPlatformTenantBillingOptions, m as SetupModule, n as SetupModuleOptions } from './saas-platform.module-DducnQ9s.cjs';
|
|
21
21
|
export { ACTIVATION_ORCHESTRATOR_TOKEN, BaseIpRateLimitGuard, ContinueRegistrationDto, PASSWORD_HASHER_TOKEN, PAYMENT_EVENT_LOG_TOKEN, PAYMENT_PROVIDER_TOKEN, PENDING_REGISTRATION_REPOSITORY_TOKEN, PLAN_CATALOG_LOOKUP_TOKEN, PaymentWebhookDto, PendingRegistrationService, PreviewRegistrationPromoDto, PromoEvaluation, REGISTRATION_AUDIT_LOGGER_TOKEN, REGISTRATION_CONFIGURATOR_LOOKUP_TOKEN, REGISTRATION_CONFIG_TOKEN, REGISTRATION_OTP_DELIVERY_TOKEN, REGISTRATION_PROMO_PREVIEW_TOKEN, REGISTRATION_RESUME_BASE_URL_TOKEN, REGISTRATION_RESUME_DELIVERY_TOKEN, REGISTRATION_RESUME_TOKEN_SIGNER_TOKEN, RegisterStartDto, RegistrationCleanupCron, RegistrationModule, RegistrationModuleOptions, ResendRegistrationOtpDto, SLUG_AVAILABILITY_CHECK_TOKEN, SaveRegistrationConfigDto, SaveRegistrationConfigSelectionDto, SelectRegistrationPlanDto, StartRegistrationCheckoutDto, USER_ACCOUNT_LOOKUP_TOKEN, VerifyRegistrationOtpDto, computeBreakdown, generateOtpCode, hashOtpCode, resolveModel, slugify, verifyOtpCode } from './registration/index.cjs';
|
|
22
22
|
export { DEFINES_QUOTA_KEY, DISCOVERY_SNAPSHOT_TOKEN, DefinesQuota, DefinesQuotaOptions, DiscoveryControllerConfig, DiscoveryModule, DiscoveryModuleOptions, DiscoverySnapshotNotFoundError, ENFORCE_QUOTA_KEY, EnforceQuota, EnforceQuotaMetadata, EnforceQuotaOptions, HeadlessScanOptions, IMPLEMENTS_CAPABILITY_KEY, ImplementsCapability, ImplementsCapabilityMetadata, ImplementsCapabilityOptions, REQUIRES_CAPABILITY_KEY, RequiresCapability, RequiresCapabilityKeys, buildDiscoveryController, loadDiscoverySnapshotFromFile, runHeadlessDiscoveryScan } from './discovery/index.cjs';
|
|
23
23
|
export { D as DISCOVERY_APP_INFO_TOKEN, a as DISCOVERY_SNAPSHOT_PATH_TOKEN, b as DiscoveryAppInfo, c as DiscoveryScanner, d as computeSnapshotHash } from './discovery.scanner-DLgEvuoy.cjs';
|