@saasicat/nest 0.8.0 → 0.9.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/admin/index.cjs +261 -2
- package/dist/admin/index.d.cts +6 -4
- package/dist/admin/index.d.ts +6 -4
- package/dist/admin/index.js +12 -4
- package/dist/{admin-manifest.service-Cp6uwvmt.d.cts → admin-manifest.service-BMeSLRW4.d.ts} +1 -1
- package/dist/{admin-manifest.service-UGgzR1x-.d.ts → admin-manifest.service-StAQe6QO.d.cts} +1 -1
- package/dist/admin-resources.module-BybEjZs-.d.cts +40 -0
- package/dist/admin-resources.module-CUCLlUAi.d.ts +40 -0
- package/dist/billing/index.cjs +3 -1
- package/dist/billing/index.d.cts +5 -287
- package/dist/billing/index.d.ts +5 -287
- package/dist/billing/index.js +5 -8
- package/dist/catalog/index.d.cts +4 -101
- package/dist/catalog/index.d.ts +4 -101
- package/dist/catalog/index.js +12 -10
- package/dist/catalog.module-BKObceo0.d.ts +103 -0
- package/dist/catalog.module-Dw2Hrbyu.d.cts +103 -0
- package/dist/{chunk-PLDHI6NA.js → chunk-3M6VLT5N.js} +256 -1
- package/dist/chunk-7K5PT2LX.js +211 -0
- package/dist/{chunk-RZU4HIAN.js → chunk-GW2I3JZD.js} +25 -22
- package/dist/{chunk-6LP7CDS2.js → chunk-HXAWPPFW.js} +10 -5
- package/dist/chunk-OFBDEO45.js +755 -0
- package/dist/{chunk-5DDCSGZC.js → chunk-PBQRPDO2.js} +142 -354
- package/dist/{chunk-T5SXXAKG.js → chunk-WGVTXSYW.js} +1 -1
- package/dist/{chunk-YHHE4KDA.js → chunk-ZZMAHX22.js} +343 -16
- package/dist/{enforce-quota.interceptor-Dj1Kusr5.d.ts → enforce-quota.interceptor-B3CL5MSw.d.ts} +94 -12
- package/dist/{enforce-quota.interceptor-cv7r80VM.d.cts → enforce-quota.interceptor-SqrQVF91.d.cts} +94 -12
- package/dist/entitlement/index.cjs +1 -0
- package/dist/entitlement/index.d.cts +3 -1
- package/dist/entitlement/index.d.ts +3 -1
- package/dist/entitlement/index.js +1 -2
- package/dist/index.cjs +3501 -2805
- package/dist/index.d.cts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +75 -61
- package/dist/module-B5m080F0.d.ts +39 -0
- package/dist/module-DeH_Jkcq.d.cts +39 -0
- package/dist/platform/index.cjs +11110 -964
- package/dist/platform/index.d.cts +41 -7
- package/dist/platform/index.d.ts +41 -7
- package/dist/platform/index.js +26 -6
- package/dist/promo/index.cjs +530 -5
- package/dist/promo/index.d.cts +47 -30
- package/dist/promo/index.d.ts +47 -30
- package/dist/promo/index.js +9 -1
- package/dist/{service-DX8KbGXl.d.cts → service-DlhMnYjW.d.cts} +1 -1
- package/dist/{service-DX8KbGXl.d.ts → service-DlhMnYjW.d.ts} +1 -1
- package/dist/subscription-bundles.module-BQmoozm5.d.ts +291 -0
- package/dist/subscription-bundles.module-DCpV-Pb5.d.cts +291 -0
- package/dist/testing/index.cjs +11098 -966
- package/dist/testing/index.d.cts +9 -4
- package/dist/testing/index.d.ts +9 -4
- package/dist/testing/index.js +10 -4
- package/package.json +4 -4
- package/dist/admin-manifest.config-DyrQNT7M.d.cts +0 -10
- package/dist/admin-manifest.config-DyrQNT7M.d.ts +0 -10
- package/dist/chunk-52UTQRD3.js +0 -326
- package/dist/chunk-Q53N43LQ.js +0 -13
- /package/dist/{chunk-2FR6ZL7R.js → chunk-HWGIMNWR.js} +0 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DiscoverySnapshotNotFoundError,
|
|
3
|
+
loadDiscoverySnapshotFromFile
|
|
4
|
+
} from "./chunk-ABB2CRAS.js";
|
|
5
|
+
import {
|
|
6
|
+
ADVISORY_STRICT_MODE_CODES,
|
|
7
|
+
validateBundleDraft,
|
|
8
|
+
validatePlanDraft
|
|
9
|
+
} from "./chunk-PBQRPDO2.js";
|
|
10
|
+
import {
|
|
11
|
+
__name
|
|
12
|
+
} from "./chunk-SHUYVCID.js";
|
|
13
|
+
|
|
14
|
+
// src/catalog/preflight.ts
|
|
15
|
+
function runPreflight(input) {
|
|
16
|
+
const findings = [];
|
|
17
|
+
const approved = input.approved ?? null;
|
|
18
|
+
for (const pv of input.planVersions) {
|
|
19
|
+
const warns = validatePlanDraft({
|
|
20
|
+
features: pv.features,
|
|
21
|
+
quotas: pv.quotas ?? {}
|
|
22
|
+
}, input.snapshot, /* @__PURE__ */ new Set(), approved);
|
|
23
|
+
for (const w of warns) {
|
|
24
|
+
findings.push({
|
|
25
|
+
kind: "plan",
|
|
26
|
+
versionId: pv.id,
|
|
27
|
+
entityKey: pv.planId,
|
|
28
|
+
version: pv.version,
|
|
29
|
+
warning: w
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
for (const bv of input.bundleVersions) {
|
|
34
|
+
const warns = validateBundleDraft({
|
|
35
|
+
features: bv.features,
|
|
36
|
+
quotas: bv.quotas ?? {}
|
|
37
|
+
}, input.snapshot, null, /* @__PURE__ */ new Set(), approved);
|
|
38
|
+
for (const w of warns) {
|
|
39
|
+
findings.push({
|
|
40
|
+
kind: "bundle",
|
|
41
|
+
versionId: bv.id,
|
|
42
|
+
entityKey: bv.bundleKey,
|
|
43
|
+
version: bv.version,
|
|
44
|
+
warning: w
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
findings.sort((a, b) => {
|
|
49
|
+
if (a.kind !== b.kind) return a.kind.localeCompare(b.kind);
|
|
50
|
+
if (a.entityKey !== b.entityKey) return a.entityKey.localeCompare(b.entityKey);
|
|
51
|
+
if (a.version !== b.version) return a.version - b.version;
|
|
52
|
+
return a.warning.code.localeCompare(b.warning.code);
|
|
53
|
+
});
|
|
54
|
+
const counts = {
|
|
55
|
+
planFindings: findings.filter((f) => f.kind === "plan").length,
|
|
56
|
+
bundleFindings: findings.filter((f) => f.kind === "bundle").length,
|
|
57
|
+
total: findings.length
|
|
58
|
+
};
|
|
59
|
+
const hasBlockingFinding = findings.some((f) => !ADVISORY_STRICT_MODE_CODES.has(f.warning.code));
|
|
60
|
+
return {
|
|
61
|
+
overall: hasBlockingFinding ? "error" : "ok",
|
|
62
|
+
counts,
|
|
63
|
+
findings
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
__name(runPreflight, "runPreflight");
|
|
67
|
+
function formatPreflightReport(report) {
|
|
68
|
+
const lines = [];
|
|
69
|
+
lines.push(`Preflight (Status: ${report.overall.toUpperCase()})`, ` Plans: ${report.counts.planFindings} \xB7 Bundles: ${report.counts.bundleFindings} \xB7 Gesamt: ${report.counts.total}`, "");
|
|
70
|
+
if (report.findings.length === 0) {
|
|
71
|
+
lines.push(" \u2713 Keine Strict-Mode-Verst\xF6\xDFe gefunden.");
|
|
72
|
+
return lines.join("\n");
|
|
73
|
+
}
|
|
74
|
+
let lastEntity = "";
|
|
75
|
+
for (const f of report.findings) {
|
|
76
|
+
const entityHeader = `${f.kind} ${f.entityKey} v${f.version}`;
|
|
77
|
+
if (entityHeader !== lastEntity) {
|
|
78
|
+
lines.push(` \u2717 ${entityHeader} (${f.versionId})`);
|
|
79
|
+
lastEntity = entityHeader;
|
|
80
|
+
}
|
|
81
|
+
const fieldHint = f.warning.field ? ` [${f.warning.field}]` : "";
|
|
82
|
+
lines.push(` ${f.warning.code}${fieldHint}: ${f.warning.message}`);
|
|
83
|
+
}
|
|
84
|
+
return lines.join("\n");
|
|
85
|
+
}
|
|
86
|
+
__name(formatPreflightReport, "formatPreflightReport");
|
|
87
|
+
function preflightExitCode(report) {
|
|
88
|
+
return report.overall === "error" ? 4 : 0;
|
|
89
|
+
}
|
|
90
|
+
__name(preflightExitCode, "preflightExitCode");
|
|
91
|
+
|
|
92
|
+
// src/catalog/seed-gate.ts
|
|
93
|
+
function validateSeedAgainstSnapshot(input) {
|
|
94
|
+
const findings = [];
|
|
95
|
+
for (const plan of input.plans ?? []) {
|
|
96
|
+
const warns = validatePlanDraft({
|
|
97
|
+
features: plan.features,
|
|
98
|
+
quotas: plan.quotas ?? {}
|
|
99
|
+
}, input.snapshot, /* @__PURE__ */ new Set(), input.approved ?? null);
|
|
100
|
+
for (const warning of warns) {
|
|
101
|
+
findings.push({
|
|
102
|
+
kind: "plan",
|
|
103
|
+
entityKey: plan.planKey,
|
|
104
|
+
warning
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
for (const bundle of input.bundles ?? []) {
|
|
109
|
+
const warns = validateBundleDraft({
|
|
110
|
+
features: bundle.features,
|
|
111
|
+
quotas: bundle.quotas ?? {}
|
|
112
|
+
}, input.snapshot, null, /* @__PURE__ */ new Set(), input.approved ?? null);
|
|
113
|
+
for (const warning of warns) {
|
|
114
|
+
findings.push({
|
|
115
|
+
kind: "bundle",
|
|
116
|
+
entityKey: bundle.bundleKey,
|
|
117
|
+
warning
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
findings.sort((a, b) => {
|
|
122
|
+
if (a.kind !== b.kind) return a.kind.localeCompare(b.kind);
|
|
123
|
+
if (a.entityKey !== b.entityKey) return a.entityKey.localeCompare(b.entityKey);
|
|
124
|
+
return a.warning.code.localeCompare(b.warning.code);
|
|
125
|
+
});
|
|
126
|
+
const counts = {
|
|
127
|
+
planFindings: findings.filter((f) => f.kind === "plan").length,
|
|
128
|
+
bundleFindings: findings.filter((f) => f.kind === "bundle").length,
|
|
129
|
+
total: findings.length
|
|
130
|
+
};
|
|
131
|
+
const hasBlockingFinding = findings.some((f) => !ADVISORY_STRICT_MODE_CODES.has(f.warning.code));
|
|
132
|
+
return {
|
|
133
|
+
overall: hasBlockingFinding ? "error" : "ok",
|
|
134
|
+
counts,
|
|
135
|
+
findings
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
__name(validateSeedAgainstSnapshot, "validateSeedAgainstSnapshot");
|
|
139
|
+
function formatSeedGateReport(report) {
|
|
140
|
+
const lines = [];
|
|
141
|
+
lines.push(`Seed-Gate (Status: ${report.overall.toUpperCase()})`, ` Plans: ${report.counts.planFindings} \xB7 Bundles: ${report.counts.bundleFindings} \xB7 Gesamt: ${report.counts.total}`, "");
|
|
142
|
+
if (report.findings.length === 0) {
|
|
143
|
+
lines.push(" \u2713 Alle geseedeten Plan-/Bundle-Features sind discovered (und, sofern gepr\xFCft, approved).");
|
|
144
|
+
return lines.join("\n");
|
|
145
|
+
}
|
|
146
|
+
let lastEntity = "";
|
|
147
|
+
for (const f of report.findings) {
|
|
148
|
+
const entityHeader = `${f.kind} ${f.entityKey}`;
|
|
149
|
+
if (entityHeader !== lastEntity) {
|
|
150
|
+
lines.push(` \u2717 ${entityHeader}`);
|
|
151
|
+
lastEntity = entityHeader;
|
|
152
|
+
}
|
|
153
|
+
const fieldHint = f.warning.field ? ` [${f.warning.field}]` : "";
|
|
154
|
+
lines.push(` ${f.warning.code}${fieldHint}: ${f.warning.message}`);
|
|
155
|
+
}
|
|
156
|
+
return lines.join("\n");
|
|
157
|
+
}
|
|
158
|
+
__name(formatSeedGateReport, "formatSeedGateReport");
|
|
159
|
+
function seedGateExitCode(report) {
|
|
160
|
+
return report.overall === "error" ? 4 : 0;
|
|
161
|
+
}
|
|
162
|
+
__name(seedGateExitCode, "seedGateExitCode");
|
|
163
|
+
|
|
164
|
+
// src/catalog/seed-gate-runner.ts
|
|
165
|
+
function runSeedGateFromFile(options) {
|
|
166
|
+
const mode = options.mode ?? "report-only";
|
|
167
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
168
|
+
const warn = options.warn ?? ((line) => console.warn(line));
|
|
169
|
+
const error = options.error ?? ((line) => console.error(line));
|
|
170
|
+
const exit = options.exit ?? ((code) => process.exit(code));
|
|
171
|
+
let snapshot;
|
|
172
|
+
try {
|
|
173
|
+
snapshot = loadDiscoverySnapshotFromFile(options.snapshotPath);
|
|
174
|
+
} catch (err) {
|
|
175
|
+
if (err instanceof DiscoverySnapshotNotFoundError) {
|
|
176
|
+
if (mode === "blocking") {
|
|
177
|
+
error(`[seed-gate] FEHLER: Kein Discovery-Snapshot unter ${options.snapshotPath} \u2014 im blocking-Modus Pflicht (Headless-Scan vor dem Seed ausf\xFChren, #23).`);
|
|
178
|
+
return exit(4);
|
|
179
|
+
}
|
|
180
|
+
warn(`[seed-gate] Kein Discovery-Snapshot unter ${options.snapshotPath} \u2014 \xFCbersprungen (report-only).`);
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
const report = validateSeedAgainstSnapshot({
|
|
186
|
+
snapshot,
|
|
187
|
+
plans: options.plans,
|
|
188
|
+
bundles: options.bundles,
|
|
189
|
+
approved: options.approved ?? null
|
|
190
|
+
});
|
|
191
|
+
log(formatSeedGateReport(report));
|
|
192
|
+
if (report.overall === "error") {
|
|
193
|
+
if (mode === "blocking") {
|
|
194
|
+
error("[seed-gate] blocking: Verst\xF6\xDFe gefunden \u2014 Seed wird abgebrochen (#23).");
|
|
195
|
+
return exit(seedGateExitCode(report));
|
|
196
|
+
}
|
|
197
|
+
warn("[seed-gate] report-only: Verst\xF6\xDFe gefunden, Seed l\xE4uft trotzdem weiter.");
|
|
198
|
+
}
|
|
199
|
+
return report;
|
|
200
|
+
}
|
|
201
|
+
__name(runSeedGateFromFile, "runSeedGateFromFile");
|
|
202
|
+
|
|
203
|
+
export {
|
|
204
|
+
runPreflight,
|
|
205
|
+
formatPreflightReport,
|
|
206
|
+
preflightExitCode,
|
|
207
|
+
validateSeedAgainstSnapshot,
|
|
208
|
+
formatSeedGateReport,
|
|
209
|
+
seedGateExitCode,
|
|
210
|
+
runSeedGateFromFile
|
|
211
|
+
};
|
|
@@ -25,10 +25,6 @@ import {
|
|
|
25
25
|
__name
|
|
26
26
|
} from "./chunk-SHUYVCID.js";
|
|
27
27
|
|
|
28
|
-
// src/billing/subscription-bundles.tokens.ts
|
|
29
|
-
var SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionBundleRepository");
|
|
30
|
-
var SUBSCRIPTION_BUNDLE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionBundleConfig");
|
|
31
|
-
|
|
32
28
|
// src/entitlement/aggregation.ts
|
|
33
29
|
function filterActiveSubscriptionBundles(bundles, now) {
|
|
34
30
|
return bundles.filter((b) => b.canceledEffectiveAt === null || b.canceledEffectiveAt > now);
|
|
@@ -222,6 +218,24 @@ function assertNoReplacesCycle(index) {
|
|
|
222
218
|
}
|
|
223
219
|
__name(assertNoReplacesCycle, "assertNoReplacesCycle");
|
|
224
220
|
|
|
221
|
+
// src/entitlement/plan-resolution.ts
|
|
222
|
+
function resolveEntitlementPlan(input, config, now) {
|
|
223
|
+
if (input.isPilot && config.pilotEntitlementPlan !== void 0) {
|
|
224
|
+
return config.pilotEntitlementPlan;
|
|
225
|
+
}
|
|
226
|
+
if (input.status === "TRIAL") {
|
|
227
|
+
return input.trialEntitlementPlan ?? config.defaultTrialEntitlementPlan ?? input.plan;
|
|
228
|
+
}
|
|
229
|
+
if (input.status === "PENDING_SALES" && config.pendingSalesEntitlementPlan !== void 0) {
|
|
230
|
+
return config.pendingSalesEntitlementPlan;
|
|
231
|
+
}
|
|
232
|
+
if (input.pendingPlan && input.pendingEffectiveAt && input.pendingEffectiveAt <= now) {
|
|
233
|
+
return input.pendingPlan;
|
|
234
|
+
}
|
|
235
|
+
return input.plan;
|
|
236
|
+
}
|
|
237
|
+
__name(resolveEntitlementPlan, "resolveEntitlementPlan");
|
|
238
|
+
|
|
225
239
|
// src/entitlement/limit-exceeded-error.ts
|
|
226
240
|
var LIMIT_EXCEEDED = "LIMIT_EXCEEDED";
|
|
227
241
|
var LimitExceededError = class extends Error {
|
|
@@ -242,26 +256,14 @@ function isLimitExceededError(err) {
|
|
|
242
256
|
}
|
|
243
257
|
__name(isLimitExceededError, "isLimitExceededError");
|
|
244
258
|
|
|
245
|
-
// src/entitlement/plan-resolution.ts
|
|
246
|
-
function resolveEntitlementPlan(input, config, now) {
|
|
247
|
-
if (input.isPilot && config.pilotEntitlementPlan !== void 0) {
|
|
248
|
-
return config.pilotEntitlementPlan;
|
|
249
|
-
}
|
|
250
|
-
if (input.status === "TRIAL") {
|
|
251
|
-
return input.trialEntitlementPlan ?? config.defaultTrialEntitlementPlan ?? input.plan;
|
|
252
|
-
}
|
|
253
|
-
if (input.status === "PENDING_SALES" && config.pendingSalesEntitlementPlan !== void 0) {
|
|
254
|
-
return config.pendingSalesEntitlementPlan;
|
|
255
|
-
}
|
|
256
|
-
if (input.pendingPlan && input.pendingEffectiveAt && input.pendingEffectiveAt <= now) {
|
|
257
|
-
return input.pendingPlan;
|
|
258
|
-
}
|
|
259
|
-
return input.plan;
|
|
260
|
-
}
|
|
261
|
-
__name(resolveEntitlementPlan, "resolveEntitlementPlan");
|
|
262
|
-
|
|
263
259
|
// src/entitlement/service.ts
|
|
264
260
|
import { Inject, Injectable, NotFoundException, Optional } from "@nestjs/common";
|
|
261
|
+
|
|
262
|
+
// src/billing/subscription-bundles.tokens.ts
|
|
263
|
+
var SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionBundleRepository");
|
|
264
|
+
var SUBSCRIPTION_BUNDLE_CONFIG_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/SubscriptionBundleConfig");
|
|
265
|
+
|
|
266
|
+
// src/entitlement/service.ts
|
|
265
267
|
function _ts_decorate(decorators, target, key, desc) {
|
|
266
268
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
267
269
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -552,6 +554,7 @@ var EntitlementModule = class _EntitlementModule {
|
|
|
552
554
|
return {
|
|
553
555
|
module: _EntitlementModule,
|
|
554
556
|
global: options.global ?? false,
|
|
557
|
+
imports: options.imports ?? [],
|
|
555
558
|
providers,
|
|
556
559
|
exports: [
|
|
557
560
|
EntitlementService,
|
|
@@ -16,9 +16,6 @@ import {
|
|
|
16
16
|
USER_EMAIL_RESOLVER_TOKEN,
|
|
17
17
|
USER_ID_RESOLVER_TOKEN
|
|
18
18
|
} from "./chunk-WPUVJRIN.js";
|
|
19
|
-
import {
|
|
20
|
-
REQUIRE_FEATURE_KEY
|
|
21
|
-
} from "./chunk-Q53N43LQ.js";
|
|
22
19
|
import {
|
|
23
20
|
AdminAuditService
|
|
24
21
|
} from "./chunk-E56W4U2P.js";
|
|
@@ -28,7 +25,7 @@ import {
|
|
|
28
25
|
SUBSCRIPTION_BUNDLE_REPOSITORY_TOKEN,
|
|
29
26
|
isLimitExceededError,
|
|
30
27
|
toEffectiveLimitsSnapshot
|
|
31
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-GW2I3JZD.js";
|
|
32
29
|
import {
|
|
33
30
|
PLAN_CATALOG_TOKEN,
|
|
34
31
|
findPlan,
|
|
@@ -171,6 +168,11 @@ function computeNextPeriod(sub, now) {
|
|
|
171
168
|
}
|
|
172
169
|
__name(computeNextPeriod, "computeNextPeriod");
|
|
173
170
|
|
|
171
|
+
// src/billing/require-feature.decorator.ts
|
|
172
|
+
import { SetMetadata } from "@nestjs/common";
|
|
173
|
+
var REQUIRE_FEATURE_KEY = "require-feature";
|
|
174
|
+
var RequireFeature = /* @__PURE__ */ __name((...features) => SetMetadata(REQUIRE_FEATURE_KEY, features), "RequireFeature");
|
|
175
|
+
|
|
174
176
|
// src/billing/feature-guard.tokens.ts
|
|
175
177
|
var FEATURE_GUARD_CONFIG_TOKEN = /* @__PURE__ */ Symbol("FEATURE_GUARD_CONFIG");
|
|
176
178
|
|
|
@@ -2560,7 +2562,8 @@ var TenantBillingModule = class _TenantBillingModule {
|
|
|
2560
2562
|
] : [],
|
|
2561
2563
|
...hasContractFreeze ? [
|
|
2562
2564
|
CONTRACT_FREEZE_PORT_TOKEN
|
|
2563
|
-
] : []
|
|
2565
|
+
] : [],
|
|
2566
|
+
...options.extraExports ?? []
|
|
2564
2567
|
]
|
|
2565
2568
|
};
|
|
2566
2569
|
}
|
|
@@ -3270,6 +3273,8 @@ export {
|
|
|
3270
3273
|
decideRenewal,
|
|
3271
3274
|
clearPendingPlanVersionFields,
|
|
3272
3275
|
computeNextPeriod,
|
|
3276
|
+
REQUIRE_FEATURE_KEY,
|
|
3277
|
+
RequireFeature,
|
|
3273
3278
|
FEATURE_GUARD_CONFIG_TOKEN,
|
|
3274
3279
|
UPSELL_OFFER_RESOLVER_TOKEN,
|
|
3275
3280
|
UPSELL_OFFER_CURRENCY_TOKEN,
|