@saasicat/nest 1.0.0-rc.2 → 1.0.0-rc.21
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/README.md +44 -8
- package/dist/.build-stamp +1 -1
- package/dist/_entries.cjs +10214 -4796
- package/dist/admin/index.d.cts +5 -4
- package/dist/admin/index.d.ts +5 -4
- package/dist/admin/index.js +13 -9
- package/dist/{admin-resources.module-CpvzcfCc.d.cts → admin-resources.module-B4XNvdH-.d.cts} +1 -2
- package/dist/{admin-resources.module-DF5_Q7RD.d.ts → admin-resources.module-CWqdI9BV.d.ts} +1 -2
- package/dist/{admin-stats.service-TYiSUwIR.d.ts → admin-stats.service-CsLNt19Z.d.ts} +11 -7
- package/dist/{admin-stats.service-DfKupywR.d.cts → admin-stats.service-DrZrU8IJ.d.cts} +11 -7
- package/dist/{aggregation-B3CD0v_d.d.cts → aggregation-ChpZDh0g.d.ts} +39 -6
- package/dist/{aggregation-BFzW07DE.d.ts → aggregation-OpnhwzF5.d.cts} +39 -6
- package/dist/billing/index.d.cts +448 -108
- package/dist/billing/index.d.ts +448 -108
- package/dist/billing/index.js +108 -41
- package/dist/catalog/index.d.cts +74 -45
- package/dist/catalog/index.d.ts +74 -45
- package/dist/catalog/index.js +21 -13
- package/dist/catalog.module-C9O7BxRq.d.ts +180 -0
- package/dist/catalog.module-T-I5Ricz.d.cts +180 -0
- package/dist/checkout-offer/index.d.cts +17 -22
- package/dist/checkout-offer/index.d.ts +17 -22
- package/dist/checkout-offer/index.js +21 -7
- package/dist/checkout-offer.module-DFhGy6JO.d.cts +58 -0
- package/dist/checkout-offer.module-x7SP_dX4.d.ts +58 -0
- package/dist/checkout-offer.service-BeHgYikI.d.ts +242 -0
- package/dist/checkout-offer.service-CCVxG9b2.d.cts +242 -0
- package/dist/chunk-34XVPR6P.js +222 -0
- package/dist/{chunk-AOQJEYOL.js → chunk-3QVGA6JX.js} +3 -1
- package/dist/chunk-3RLWML2S.js +896 -0
- package/dist/{chunk-TXC3LHHB.js → chunk-4SDSYV4A.js} +21 -13
- package/dist/chunk-55QEDAMX.js +946 -0
- package/dist/chunk-5CKC7O52.js +140 -0
- package/dist/chunk-6PJE7EWO.js +185 -0
- package/dist/chunk-7NJKVC5X.js +353 -0
- package/dist/{chunk-RUNZ3X4C.js → chunk-AOS2JPDD.js} +1263 -185
- package/dist/{chunk-WOVQPXV4.js → chunk-CQ2ZZMTD.js} +702 -725
- package/dist/{chunk-NA6O63B7.js → chunk-F5X66HF5.js} +5 -5
- package/dist/chunk-FEQZCWUL.js +174 -0
- package/dist/{chunk-VIJ5NJWC.js → chunk-G6EZWECL.js} +107 -31
- package/dist/chunk-G7RQO2XO.js +0 -0
- package/dist/{chunk-N3L3AICU.js → chunk-GPQWGA6B.js} +5 -6
- package/dist/chunk-GZTL64QK.js +7 -0
- package/dist/{chunk-SABTXESR.js → chunk-J7NJRK3K.js} +17 -1
- package/dist/{chunk-SEPN52AD.js → chunk-JBCC6C3M.js} +566 -307
- package/dist/{chunk-I7GTA3RX.js → chunk-JQRA724W.js} +1 -1
- package/dist/{chunk-WXYJHZCN.js → chunk-JVAEKTJ4.js} +2 -14
- package/dist/chunk-KPEMTBOP.js +26 -0
- package/dist/chunk-LF6J4YYN.js +301 -0
- package/dist/{chunk-LTT736P3.js → chunk-LLYVYRGJ.js} +228 -387
- package/dist/{chunk-6Z7JR4EW.js → chunk-M47BNEY2.js} +1897 -633
- package/dist/{chunk-KFT5AIIH.js → chunk-NDLC5GYK.js} +206 -24
- package/dist/{chunk-O2J2HDXA.js → chunk-OOTEXP47.js} +3 -8
- package/dist/chunk-QPVDCKYS.js +702 -0
- package/dist/{chunk-NHVDCYK5.js → chunk-R5YCJBHY.js} +71 -106
- package/dist/{chunk-XBYAFEOR.js → chunk-S33SO5XX.js} +1 -1
- package/dist/chunk-SZ7RFPXA.js +10 -0
- package/dist/chunk-TBBZWZQT.js +98 -0
- package/dist/chunk-TOEFN7DN.js +295 -0
- package/dist/{chunk-7ZEGFL42.js → chunk-WHJSYKNC.js} +6 -6
- package/dist/chunk-WOEJ6K7M.js +55 -0
- package/dist/{chunk-AU3OOREM.js → chunk-XSSWYPP5.js} +16 -3
- package/dist/contract-line-item-money-B0Z3Ogur.d.cts +43 -0
- package/dist/contract-line-item-money-B0Z3Ogur.d.ts +43 -0
- package/dist/discovery/index.d.cts +2 -2
- package/dist/discovery/index.d.ts +2 -2
- package/dist/discovery/index.js +6 -6
- package/dist/{discovery.scanner-9cMqF95o.d.cts → discovery.scanner-DXKc6JkV.d.cts} +1 -1
- package/dist/{discovery.scanner-9cMqF95o.d.ts → discovery.scanner-DXKc6JkV.d.ts} +1 -1
- package/dist/{enforce-quota.interceptor-Df0e3OWe.d.cts → enforce-quota.interceptor-BFyVdWe8.d.cts} +6 -6
- package/dist/{enforce-quota.interceptor-DW3etVyI.d.ts → enforce-quota.interceptor-GaBXboGx.d.ts} +6 -6
- package/dist/entitlement/index.d.cts +27 -4
- package/dist/entitlement/index.d.ts +27 -4
- package/dist/entitlement/index.js +13 -8
- package/dist/index.d.cts +209 -28
- package/dist/index.d.ts +209 -28
- package/dist/index.js +285 -163
- package/dist/issuer-identity.check-CBO0vcsq.d.cts +197 -0
- package/dist/issuer-identity.check-Cz9CEMkZ.d.ts +197 -0
- package/dist/{module-options-COSEb0VW.d.ts → module-options-DmQ3G4sZ.d.ts} +135 -41
- package/dist/{module-options-BG3MzQva.d.cts → module-options-qAOwinHR.d.cts} +135 -41
- package/dist/payment-callback.service-CR84Xw1Z.d.cts +125 -0
- package/dist/payment-callback.service-CR84Xw1Z.d.ts +125 -0
- package/dist/payments/index.cjs +4 -0
- package/dist/payments/index.d.cts +187 -0
- package/dist/payments/index.d.ts +187 -0
- package/dist/payments/index.js +141 -0
- package/dist/payments.module-BdUq9ot_.d.cts +57 -0
- package/dist/payments.module-CQGv_VG7.d.ts +57 -0
- package/dist/plan-catalog-source-DWe-BGY1.d.cts +21 -0
- package/dist/plan-catalog-source-DWe-BGY1.d.ts +21 -0
- package/dist/{plan-resolution-Cgo_TR1H.d.cts → plan-resolution-CwUy_OqC.d.cts} +14 -0
- package/dist/{plan-resolution-Cgo_TR1H.d.ts → plan-resolution-CwUy_OqC.d.ts} +14 -0
- package/dist/{plan-versions.service-DChhbK6h.d.ts → plan-versions.service-C0N-Em2W.d.ts} +38 -64
- package/dist/{plan-versions.service-TPEtbN0r.d.cts → plan-versions.service-DARLh-qI.d.cts} +38 -64
- package/dist/platform/index.d.cts +52 -23
- package/dist/platform/index.d.ts +52 -23
- package/dist/platform/index.js +57 -36
- package/dist/promo/index.d.cts +23 -8
- package/dist/promo/index.d.ts +23 -8
- package/dist/promo/index.js +15 -7
- package/dist/{promo.module-DtvIycpt.d.cts → promo.module-CKkECmU8.d.cts} +9 -3
- package/dist/{promo.module-Z8h1PNX-.d.ts → promo.module-DuIJdK3U.d.ts} +9 -3
- package/dist/promo.service-BYBu6dy3.d.cts +215 -0
- package/dist/promo.service-CFjfF0Xm.d.ts +215 -0
- package/dist/registration/index.d.cts +104 -47
- package/dist/registration/index.d.ts +104 -47
- package/dist/registration/index.js +15 -9
- package/dist/subscriber/index.cjs +4 -0
- package/dist/subscriber/index.d.cts +28 -0
- package/dist/subscriber/index.d.ts +28 -0
- package/dist/subscriber/index.js +16 -0
- package/dist/subscriber.service-5W6Gi-1B.d.cts +68 -0
- package/dist/subscriber.service-5W6Gi-1B.d.ts +68 -0
- package/dist/subscription-contract/index.d.cts +4 -2
- package/dist/subscription-contract/index.d.ts +4 -2
- package/dist/subscription-contract/index.js +13 -5
- package/dist/{subscription-contract.module-fDFdQ0jm.d.ts → subscription-contract.module-BfIRpc1o.d.ts} +8 -2
- package/dist/{subscription-contract.module-CEK8HS5-.d.cts → subscription-contract.module-DTMuUJYd.d.cts} +8 -2
- package/dist/{subscription-contract.service-hD87MKyg.d.cts → subscription-contract.service-CPZrTM9C.d.ts} +32 -3
- package/dist/{subscription-contract.service-hD87MKyg.d.ts → subscription-contract.service-CfNApLuP.d.cts} +32 -3
- package/dist/tenant-billing.controller-BLqbsONe.d.ts +812 -0
- package/dist/tenant-billing.controller-DKbAqTbM.d.cts +812 -0
- package/dist/tenant-billing.module-ClbjzocC.d.cts +364 -0
- package/dist/tenant-billing.module-DohgJJ2m.d.ts +364 -0
- package/dist/tenant-billing.tokens-G-1xOlMr.d.cts +129 -0
- package/dist/tenant-billing.tokens-G-1xOlMr.d.ts +129 -0
- package/dist/testing/index.d.cts +44 -17
- package/dist/testing/index.d.ts +44 -17
- package/dist/testing/index.js +189 -40
- package/package.json +24 -4
- package/dist/catalog.module-BDDO6iwq.d.cts +0 -103
- package/dist/catalog.module-BTnMsE6u.d.ts +0 -103
- package/dist/checkout-offer.module-CMtiQJTT.d.ts +0 -39
- package/dist/checkout-offer.module-CVpWrzbe.d.cts +0 -39
- package/dist/checkout-offer.service-BLOv2HOo.d.cts +0 -49
- package/dist/checkout-offer.service-BLOv2HOo.d.ts +0 -49
- package/dist/chunk-57V6ZTI6.js +0 -22
- package/dist/chunk-BSK6YBLI.js +0 -87
- package/dist/chunk-DQKCK7DX.js +0 -217
- package/dist/chunk-VXEYLNIB.js +0 -632
- package/dist/chunk-WUDYIPYH.js +0 -715
- package/dist/define-saasicat-DROBe-b1.d.ts +0 -69
- package/dist/define-saasicat-vGBCkFys.d.cts +0 -69
- package/dist/promo.service-BJbKAmw3.d.cts +0 -112
- package/dist/promo.service-BJbKAmw3.d.ts +0 -112
- package/dist/tenant-billing.controller-BQ67mlmI.d.ts +0 -438
- package/dist/tenant-billing.controller-DS8kB8a7.d.cts +0 -438
- package/dist/tenant-billing.module-BznC3XtW.d.cts +0 -299
- package/dist/tenant-billing.module-wUbsQSFG.d.ts +0 -299
- /package/dist/{chunk-2FR6ZL7R.js → chunk-BHZOH2DY.js} +0 -0
- /package/dist/{chunk-2SLTRKXC.js → chunk-DFOW3JVO.js} +0 -0
- /package/dist/{chunk-DBZGV3HC.js → chunk-DU56UKEH.js} +0 -0
- /package/dist/{chunk-OYNHOY45.js → chunk-GAUEVIAE.js} +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import * as _nestjs_common from '@nestjs/common';
|
|
2
|
+
import { ExecutionContext, DynamicModule, OnModuleInit } from '@nestjs/common';
|
|
3
|
+
import { Reflector } from '@nestjs/core';
|
|
4
|
+
import { SuperAdminProvisioningPort, SetupStatusResponse, SetupRequest, SetupResult, SetupConfirmMfaRequest, SetupConfirmMfaResponse, PlanCatalogSettings, AppliedSettingsPort, SubscriptionContractRepository, RlsBypassPort, IssuerIdentityChange, RunningContractIssuers } from '@saasicat/core';
|
|
5
|
+
import { M as MfaService } from './admin-stats.service-DrZrU8IJ.cjs';
|
|
6
|
+
import { c as SaaSiCatModuleOptions } from './module-options-qAOwinHR.cjs';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Shared metadata key for endpoints that intentionally run without application
|
|
10
|
+
* authentication. `Symbol.for` keeps the marker stable across package entries.
|
|
11
|
+
*/
|
|
12
|
+
declare const SAASICAT_PUBLIC_ROUTE_KEY: unique symbol;
|
|
13
|
+
/** Marks a SaaSiCat controller or handler as intentionally public. */
|
|
14
|
+
declare const SaaSiCatPublicRoute: () => _nestjs_common.CustomDecorator<typeof SAASICAT_PUBLIC_ROUTE_KEY>;
|
|
15
|
+
/** Returns whether the current endpoint is marked as a public SaaSiCat route. */
|
|
16
|
+
declare function isSaaSiCatPublicRoute(reflector: Reflector, context: ExecutionContext): boolean;
|
|
17
|
+
|
|
18
|
+
declare const SETUP_PROVISIONING_PORT_TOKEN: unique symbol;
|
|
19
|
+
declare const SETUP_CONFIG_TOKEN: unique symbol;
|
|
20
|
+
interface SetupConfig {
|
|
21
|
+
/** Env-var name of the setup token. Without the var set, setup is disabled. */
|
|
22
|
+
setupTokenEnvVar: string;
|
|
23
|
+
/** Authenticator issuer for the MFA enrollment in the wizard. */
|
|
24
|
+
mfaIssuer: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare class SetupService {
|
|
28
|
+
private readonly users;
|
|
29
|
+
private readonly config;
|
|
30
|
+
private readonly mfa;
|
|
31
|
+
constructor(users: SuperAdminProvisioningPort, config: SetupConfig, mfa: MfaService);
|
|
32
|
+
status(): Promise<SetupStatusResponse>;
|
|
33
|
+
setup(req: SetupRequest): Promise<SetupResult>;
|
|
34
|
+
confirmMfa(req: SetupConfirmMfaRequest): Promise<SetupConfirmMfaResponse>;
|
|
35
|
+
private assertToken;
|
|
36
|
+
private assertNoSuperAdmin;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Bundles the complete standard SaaSiCat backend stack into a single
|
|
41
|
+
* `forRoot({...})` call. Reduces AppModule boilerplate and eliminates the
|
|
42
|
+
* ordering trap.
|
|
43
|
+
*
|
|
44
|
+
* Quickstart path (Prisma + PostgreSQL on the canonical schema):
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* SaaSiCatModule.forRoot({
|
|
48
|
+
* planCatalog: loadPlanCatalogFromFile({ path: 'config/saas.yaml' }),
|
|
49
|
+
* controller: { guards: [JwtAuthGuard] },
|
|
50
|
+
* imports: [AuthModule],
|
|
51
|
+
* persistence: prismaPersistence({ client: PrismaService }), // @saasicat/adapter-prisma
|
|
52
|
+
* })
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Individual `adapters` entries stay supported (custom schema / other ORM)
|
|
56
|
+
* and override bundle slices field by field.
|
|
57
|
+
*/
|
|
58
|
+
declare class SaaSiCatModule {
|
|
59
|
+
static forRoot(options: SaaSiCatModuleOptions): DynamicModule;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Typed identity helper for the high-level SaaSiCat configuration. It keeps
|
|
64
|
+
* literal types and gives editors one place for completion without adding
|
|
65
|
+
* runtime behavior.
|
|
66
|
+
*/
|
|
67
|
+
declare function defineSaaSiCat<const T extends SaaSiCatModuleOptions>(options: T): T;
|
|
68
|
+
|
|
69
|
+
/** An undeclared change is the only one that refuses a start. */
|
|
70
|
+
type UndeclaredChange = Extract<IssuerIdentityChange, {
|
|
71
|
+
kind: 'undeclared';
|
|
72
|
+
}>;
|
|
73
|
+
/** What a start, or `<app> doctor`, finds when it compares the two. */
|
|
74
|
+
type IssuerIdentityVerdict =
|
|
75
|
+
/**
|
|
76
|
+
* There was no previous identity to compare the file with — nothing records
|
|
77
|
+
* the applied settings, or the record could not be read while the file
|
|
78
|
+
* names no issuer at all. `why` says which.
|
|
79
|
+
*/
|
|
80
|
+
{
|
|
81
|
+
kind: 'not-compared';
|
|
82
|
+
why: string;
|
|
83
|
+
}
|
|
84
|
+
/** The file and the record agree, or the difference is declared. */
|
|
85
|
+
| {
|
|
86
|
+
kind: 'settled';
|
|
87
|
+
change: Exclude<IssuerIdentityChange, UndeclaredChange>;
|
|
88
|
+
}
|
|
89
|
+
/** Another legal entity, undeclared. The start does not continue. */
|
|
90
|
+
| {
|
|
91
|
+
kind: 'refused';
|
|
92
|
+
change: UndeclaredChange;
|
|
93
|
+
/** The contracts still running, or `null` where they could not be read. */
|
|
94
|
+
running: RunningContractIssuers | null;
|
|
95
|
+
/** What the start dies with, and what `<app> doctor` prints. */
|
|
96
|
+
refusal: string;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* The comparison, and nothing else.
|
|
100
|
+
*
|
|
101
|
+
* Kept apart from the hook below so that asking the question costs nothing: a
|
|
102
|
+
* class whose construction is also a lifecycle hook cannot be injected by
|
|
103
|
+
* anything that only wants the answer.
|
|
104
|
+
*/
|
|
105
|
+
declare class IssuerIdentityInspector {
|
|
106
|
+
private readonly fileSettings;
|
|
107
|
+
private readonly source;
|
|
108
|
+
private readonly settings;
|
|
109
|
+
private readonly contracts;
|
|
110
|
+
private readonly rlsBypass;
|
|
111
|
+
private readonly logger;
|
|
112
|
+
/** This start's answer, settled the first time anything asks for it. */
|
|
113
|
+
private verdict;
|
|
114
|
+
constructor(fileSettings: PlanCatalogSettings, source: string, settings?: AppliedSettingsPort | null, contracts?: SubscriptionContractRepository | null, rlsBypass?: RlsBypassPort | null);
|
|
115
|
+
/**
|
|
116
|
+
* What the issuer in the file is, against the identity the record holds.
|
|
117
|
+
*
|
|
118
|
+
* Answered once per process, and the cached answer is the point rather than
|
|
119
|
+
* the saved query: `AppliedSettingsRecorder` replaces the record moments
|
|
120
|
+
* later, in a bootstrap hook, so a second comparison would find the file
|
|
121
|
+
* agreeing with what this very start wrote. A reader asking afterwards —
|
|
122
|
+
* `<app> doctor`, a health endpoint — would then be told that nothing had
|
|
123
|
+
* moved, on a start that had just carried a correction through. What this
|
|
124
|
+
* start found is a fact about this start, so it is settled when the start
|
|
125
|
+
* asks and does not change afterwards.
|
|
126
|
+
*/
|
|
127
|
+
inspect(): Promise<IssuerIdentityVerdict>;
|
|
128
|
+
/**
|
|
129
|
+
* How many contracts are running, for a report that says what changing the
|
|
130
|
+
* identity would cost. A query of its own rather than a field on the
|
|
131
|
+
* verdict: a start needs this only to name the contracts in a refusal, and
|
|
132
|
+
* no boot should pay for a number nobody reads. `null` where they are not
|
|
133
|
+
* known.
|
|
134
|
+
*/
|
|
135
|
+
runningContractCount(): Promise<number | null>;
|
|
136
|
+
private compare;
|
|
137
|
+
/**
|
|
138
|
+
* The settings of the last start, or what stopped this from reading them.
|
|
139
|
+
*
|
|
140
|
+
* A read that fails while the file names an issuer takes the boot down: a
|
|
141
|
+
* guard that cannot see is not a guard that saw nothing, and an installation
|
|
142
|
+
* that puts a legal entity on every contract it concludes should not conclude
|
|
143
|
+
* one while nothing can tell whether that entity is still the recorded one.
|
|
144
|
+
*
|
|
145
|
+
* Where the file names no issuer, the same failure is only a warning. There
|
|
146
|
+
* is then no entity to conclude a contract on behalf of, and the promise the
|
|
147
|
+
* record makes — an installation whose record cannot be kept still runs the
|
|
148
|
+
* right configuration — is worth more than a boot refused over a comparison
|
|
149
|
+
* with nothing on one side. What that leaves uncaught is narrow and worth
|
|
150
|
+
* naming: an operator who removes the issuer block while contracts run, in
|
|
151
|
+
* the same start where the record cannot be read.
|
|
152
|
+
*/
|
|
153
|
+
private readRecorded;
|
|
154
|
+
/**
|
|
155
|
+
* The contracts a refusal is about. Best effort on purpose: the refusal is
|
|
156
|
+
* already decided, and losing it because the list behind it could not be
|
|
157
|
+
* read would replace a message an operator can act on with one they cannot.
|
|
158
|
+
* Where they are not known, the message says which of the two it is —
|
|
159
|
+
* "nothing here writes contracts" and "the query failed" send an operator
|
|
160
|
+
* looking in different places.
|
|
161
|
+
*/
|
|
162
|
+
private readRunning;
|
|
163
|
+
/**
|
|
164
|
+
* Inside the bypass frame where one is bound, and plainly where none is.
|
|
165
|
+
*
|
|
166
|
+
* An installation without row-level security binds a port that only calls
|
|
167
|
+
* through; one that has it cannot be read platform-wide without this.
|
|
168
|
+
* `@Optional()` rather than required because a hand-wired application may
|
|
169
|
+
* have no `AdminModule` in scope, and a boot check is not the place to
|
|
170
|
+
* refuse to construct over a message.
|
|
171
|
+
*/
|
|
172
|
+
private withBypass;
|
|
173
|
+
/**
|
|
174
|
+
* The line a start that continues is worth, and nothing where it is worth
|
|
175
|
+
* none. Public because the hook beside this class calls it; not an offer.
|
|
176
|
+
*
|
|
177
|
+
* @internal
|
|
178
|
+
*/
|
|
179
|
+
report(verdict: Exclude<IssuerIdentityVerdict, {
|
|
180
|
+
kind: 'refused';
|
|
181
|
+
}>): void;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Refuses a start whose file names another legal entity than the record does.
|
|
185
|
+
*
|
|
186
|
+
* A module hook, not a bootstrap one: `AppliedSettingsRecorder` replaces the
|
|
187
|
+
* record in `onApplicationBootstrap`, and Nest runs every module hook before a
|
|
188
|
+
* single bootstrap hook. That is what makes the comparison see the previous
|
|
189
|
+
* start's values rather than this start's own.
|
|
190
|
+
*/
|
|
191
|
+
declare class IssuerIdentityCheck implements OnModuleInit {
|
|
192
|
+
private readonly inspector;
|
|
193
|
+
constructor(inspector: IssuerIdentityInspector);
|
|
194
|
+
onModuleInit(): Promise<void>;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export { IssuerIdentityCheck as I, SetupService as S, IssuerIdentityInspector as a, type IssuerIdentityVerdict as b, SAASICAT_PUBLIC_ROUTE_KEY as c, SETUP_CONFIG_TOKEN as d, SETUP_PROVISIONING_PORT_TOKEN as e, SaaSiCatModule as f, SaaSiCatPublicRoute as g, type SetupConfig as h, defineSaaSiCat as i, isSaaSiCatPublicRoute as j };
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import * as _nestjs_common from '@nestjs/common';
|
|
2
|
+
import { ExecutionContext, DynamicModule, OnModuleInit } from '@nestjs/common';
|
|
3
|
+
import { Reflector } from '@nestjs/core';
|
|
4
|
+
import { SuperAdminProvisioningPort, SetupStatusResponse, SetupRequest, SetupResult, SetupConfirmMfaRequest, SetupConfirmMfaResponse, PlanCatalogSettings, AppliedSettingsPort, SubscriptionContractRepository, RlsBypassPort, IssuerIdentityChange, RunningContractIssuers } from '@saasicat/core';
|
|
5
|
+
import { M as MfaService } from './admin-stats.service-CsLNt19Z.js';
|
|
6
|
+
import { c as SaaSiCatModuleOptions } from './module-options-DmQ3G4sZ.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Shared metadata key for endpoints that intentionally run without application
|
|
10
|
+
* authentication. `Symbol.for` keeps the marker stable across package entries.
|
|
11
|
+
*/
|
|
12
|
+
declare const SAASICAT_PUBLIC_ROUTE_KEY: unique symbol;
|
|
13
|
+
/** Marks a SaaSiCat controller or handler as intentionally public. */
|
|
14
|
+
declare const SaaSiCatPublicRoute: () => _nestjs_common.CustomDecorator<typeof SAASICAT_PUBLIC_ROUTE_KEY>;
|
|
15
|
+
/** Returns whether the current endpoint is marked as a public SaaSiCat route. */
|
|
16
|
+
declare function isSaaSiCatPublicRoute(reflector: Reflector, context: ExecutionContext): boolean;
|
|
17
|
+
|
|
18
|
+
declare const SETUP_PROVISIONING_PORT_TOKEN: unique symbol;
|
|
19
|
+
declare const SETUP_CONFIG_TOKEN: unique symbol;
|
|
20
|
+
interface SetupConfig {
|
|
21
|
+
/** Env-var name of the setup token. Without the var set, setup is disabled. */
|
|
22
|
+
setupTokenEnvVar: string;
|
|
23
|
+
/** Authenticator issuer for the MFA enrollment in the wizard. */
|
|
24
|
+
mfaIssuer: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare class SetupService {
|
|
28
|
+
private readonly users;
|
|
29
|
+
private readonly config;
|
|
30
|
+
private readonly mfa;
|
|
31
|
+
constructor(users: SuperAdminProvisioningPort, config: SetupConfig, mfa: MfaService);
|
|
32
|
+
status(): Promise<SetupStatusResponse>;
|
|
33
|
+
setup(req: SetupRequest): Promise<SetupResult>;
|
|
34
|
+
confirmMfa(req: SetupConfirmMfaRequest): Promise<SetupConfirmMfaResponse>;
|
|
35
|
+
private assertToken;
|
|
36
|
+
private assertNoSuperAdmin;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Bundles the complete standard SaaSiCat backend stack into a single
|
|
41
|
+
* `forRoot({...})` call. Reduces AppModule boilerplate and eliminates the
|
|
42
|
+
* ordering trap.
|
|
43
|
+
*
|
|
44
|
+
* Quickstart path (Prisma + PostgreSQL on the canonical schema):
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* SaaSiCatModule.forRoot({
|
|
48
|
+
* planCatalog: loadPlanCatalogFromFile({ path: 'config/saas.yaml' }),
|
|
49
|
+
* controller: { guards: [JwtAuthGuard] },
|
|
50
|
+
* imports: [AuthModule],
|
|
51
|
+
* persistence: prismaPersistence({ client: PrismaService }), // @saasicat/adapter-prisma
|
|
52
|
+
* })
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Individual `adapters` entries stay supported (custom schema / other ORM)
|
|
56
|
+
* and override bundle slices field by field.
|
|
57
|
+
*/
|
|
58
|
+
declare class SaaSiCatModule {
|
|
59
|
+
static forRoot(options: SaaSiCatModuleOptions): DynamicModule;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Typed identity helper for the high-level SaaSiCat configuration. It keeps
|
|
64
|
+
* literal types and gives editors one place for completion without adding
|
|
65
|
+
* runtime behavior.
|
|
66
|
+
*/
|
|
67
|
+
declare function defineSaaSiCat<const T extends SaaSiCatModuleOptions>(options: T): T;
|
|
68
|
+
|
|
69
|
+
/** An undeclared change is the only one that refuses a start. */
|
|
70
|
+
type UndeclaredChange = Extract<IssuerIdentityChange, {
|
|
71
|
+
kind: 'undeclared';
|
|
72
|
+
}>;
|
|
73
|
+
/** What a start, or `<app> doctor`, finds when it compares the two. */
|
|
74
|
+
type IssuerIdentityVerdict =
|
|
75
|
+
/**
|
|
76
|
+
* There was no previous identity to compare the file with — nothing records
|
|
77
|
+
* the applied settings, or the record could not be read while the file
|
|
78
|
+
* names no issuer at all. `why` says which.
|
|
79
|
+
*/
|
|
80
|
+
{
|
|
81
|
+
kind: 'not-compared';
|
|
82
|
+
why: string;
|
|
83
|
+
}
|
|
84
|
+
/** The file and the record agree, or the difference is declared. */
|
|
85
|
+
| {
|
|
86
|
+
kind: 'settled';
|
|
87
|
+
change: Exclude<IssuerIdentityChange, UndeclaredChange>;
|
|
88
|
+
}
|
|
89
|
+
/** Another legal entity, undeclared. The start does not continue. */
|
|
90
|
+
| {
|
|
91
|
+
kind: 'refused';
|
|
92
|
+
change: UndeclaredChange;
|
|
93
|
+
/** The contracts still running, or `null` where they could not be read. */
|
|
94
|
+
running: RunningContractIssuers | null;
|
|
95
|
+
/** What the start dies with, and what `<app> doctor` prints. */
|
|
96
|
+
refusal: string;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* The comparison, and nothing else.
|
|
100
|
+
*
|
|
101
|
+
* Kept apart from the hook below so that asking the question costs nothing: a
|
|
102
|
+
* class whose construction is also a lifecycle hook cannot be injected by
|
|
103
|
+
* anything that only wants the answer.
|
|
104
|
+
*/
|
|
105
|
+
declare class IssuerIdentityInspector {
|
|
106
|
+
private readonly fileSettings;
|
|
107
|
+
private readonly source;
|
|
108
|
+
private readonly settings;
|
|
109
|
+
private readonly contracts;
|
|
110
|
+
private readonly rlsBypass;
|
|
111
|
+
private readonly logger;
|
|
112
|
+
/** This start's answer, settled the first time anything asks for it. */
|
|
113
|
+
private verdict;
|
|
114
|
+
constructor(fileSettings: PlanCatalogSettings, source: string, settings?: AppliedSettingsPort | null, contracts?: SubscriptionContractRepository | null, rlsBypass?: RlsBypassPort | null);
|
|
115
|
+
/**
|
|
116
|
+
* What the issuer in the file is, against the identity the record holds.
|
|
117
|
+
*
|
|
118
|
+
* Answered once per process, and the cached answer is the point rather than
|
|
119
|
+
* the saved query: `AppliedSettingsRecorder` replaces the record moments
|
|
120
|
+
* later, in a bootstrap hook, so a second comparison would find the file
|
|
121
|
+
* agreeing with what this very start wrote. A reader asking afterwards —
|
|
122
|
+
* `<app> doctor`, a health endpoint — would then be told that nothing had
|
|
123
|
+
* moved, on a start that had just carried a correction through. What this
|
|
124
|
+
* start found is a fact about this start, so it is settled when the start
|
|
125
|
+
* asks and does not change afterwards.
|
|
126
|
+
*/
|
|
127
|
+
inspect(): Promise<IssuerIdentityVerdict>;
|
|
128
|
+
/**
|
|
129
|
+
* How many contracts are running, for a report that says what changing the
|
|
130
|
+
* identity would cost. A query of its own rather than a field on the
|
|
131
|
+
* verdict: a start needs this only to name the contracts in a refusal, and
|
|
132
|
+
* no boot should pay for a number nobody reads. `null` where they are not
|
|
133
|
+
* known.
|
|
134
|
+
*/
|
|
135
|
+
runningContractCount(): Promise<number | null>;
|
|
136
|
+
private compare;
|
|
137
|
+
/**
|
|
138
|
+
* The settings of the last start, or what stopped this from reading them.
|
|
139
|
+
*
|
|
140
|
+
* A read that fails while the file names an issuer takes the boot down: a
|
|
141
|
+
* guard that cannot see is not a guard that saw nothing, and an installation
|
|
142
|
+
* that puts a legal entity on every contract it concludes should not conclude
|
|
143
|
+
* one while nothing can tell whether that entity is still the recorded one.
|
|
144
|
+
*
|
|
145
|
+
* Where the file names no issuer, the same failure is only a warning. There
|
|
146
|
+
* is then no entity to conclude a contract on behalf of, and the promise the
|
|
147
|
+
* record makes — an installation whose record cannot be kept still runs the
|
|
148
|
+
* right configuration — is worth more than a boot refused over a comparison
|
|
149
|
+
* with nothing on one side. What that leaves uncaught is narrow and worth
|
|
150
|
+
* naming: an operator who removes the issuer block while contracts run, in
|
|
151
|
+
* the same start where the record cannot be read.
|
|
152
|
+
*/
|
|
153
|
+
private readRecorded;
|
|
154
|
+
/**
|
|
155
|
+
* The contracts a refusal is about. Best effort on purpose: the refusal is
|
|
156
|
+
* already decided, and losing it because the list behind it could not be
|
|
157
|
+
* read would replace a message an operator can act on with one they cannot.
|
|
158
|
+
* Where they are not known, the message says which of the two it is —
|
|
159
|
+
* "nothing here writes contracts" and "the query failed" send an operator
|
|
160
|
+
* looking in different places.
|
|
161
|
+
*/
|
|
162
|
+
private readRunning;
|
|
163
|
+
/**
|
|
164
|
+
* Inside the bypass frame where one is bound, and plainly where none is.
|
|
165
|
+
*
|
|
166
|
+
* An installation without row-level security binds a port that only calls
|
|
167
|
+
* through; one that has it cannot be read platform-wide without this.
|
|
168
|
+
* `@Optional()` rather than required because a hand-wired application may
|
|
169
|
+
* have no `AdminModule` in scope, and a boot check is not the place to
|
|
170
|
+
* refuse to construct over a message.
|
|
171
|
+
*/
|
|
172
|
+
private withBypass;
|
|
173
|
+
/**
|
|
174
|
+
* The line a start that continues is worth, and nothing where it is worth
|
|
175
|
+
* none. Public because the hook beside this class calls it; not an offer.
|
|
176
|
+
*
|
|
177
|
+
* @internal
|
|
178
|
+
*/
|
|
179
|
+
report(verdict: Exclude<IssuerIdentityVerdict, {
|
|
180
|
+
kind: 'refused';
|
|
181
|
+
}>): void;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Refuses a start whose file names another legal entity than the record does.
|
|
185
|
+
*
|
|
186
|
+
* A module hook, not a bootstrap one: `AppliedSettingsRecorder` replaces the
|
|
187
|
+
* record in `onApplicationBootstrap`, and Nest runs every module hook before a
|
|
188
|
+
* single bootstrap hook. That is what makes the comparison see the previous
|
|
189
|
+
* start's values rather than this start's own.
|
|
190
|
+
*/
|
|
191
|
+
declare class IssuerIdentityCheck implements OnModuleInit {
|
|
192
|
+
private readonly inspector;
|
|
193
|
+
constructor(inspector: IssuerIdentityInspector);
|
|
194
|
+
onModuleInit(): Promise<void>;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export { IssuerIdentityCheck as I, SetupService as S, IssuerIdentityInspector as a, type IssuerIdentityVerdict as b, SAASICAT_PUBLIC_ROUTE_KEY as c, SETUP_CONFIG_TOKEN as d, SETUP_PROVISIONING_PORT_TOKEN as e, SaaSiCatModule as f, SaaSiCatPublicRoute as g, type SetupConfig as h, defineSaaSiCat as i, isSaaSiCatPublicRoute as j };
|