@saasicat/nest 0.2.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/LICENSE +202 -0
- package/README.md +53 -0
- package/dist/admin/index.cjs +1283 -0
- package/dist/admin/index.d.cts +225 -0
- package/dist/admin/index.d.ts +225 -0
- package/dist/admin/index.js +58 -0
- package/dist/admin-audit.service-9IqXMlZm.d.cts +30 -0
- package/dist/admin-audit.service-9IqXMlZm.d.ts +30 -0
- package/dist/admin-manifest.config-DyrQNT7M.d.cts +10 -0
- package/dist/admin-manifest.config-DyrQNT7M.d.ts +10 -0
- package/dist/aggregation-CJ3qQf92.d.cts +288 -0
- package/dist/aggregation-Dvz9e8X2.d.ts +288 -0
- package/dist/billing/index.cjs +5205 -0
- package/dist/billing/index.d.cts +1326 -0
- package/dist/billing/index.d.ts +1326 -0
- package/dist/billing/index.js +197 -0
- package/dist/catalog/index.cjs +6449 -0
- package/dist/catalog/index.d.cts +1073 -0
- package/dist/catalog/index.d.ts +1073 -0
- package/dist/catalog/index.js +158 -0
- package/dist/checkout-offer/index.cjs +807 -0
- package/dist/checkout-offer/index.d.cts +120 -0
- package/dist/checkout-offer/index.d.ts +120 -0
- package/dist/checkout-offer/index.js +20 -0
- package/dist/chunk-2FR6ZL7R.js +0 -0
- package/dist/chunk-2PNX2QL2.js +347 -0
- package/dist/chunk-2VNZYRDV.js +326 -0
- package/dist/chunk-7MLGHWKO.js +12 -0
- package/dist/chunk-ABB2CRAS.js +31 -0
- package/dist/chunk-AJ3EPELS.js +157 -0
- package/dist/chunk-E56W4U2P.js +90 -0
- package/dist/chunk-HRU3CP57.js +71 -0
- package/dist/chunk-L4SUWH5B.js +14 -0
- package/dist/chunk-M6CZQYPY.js +314 -0
- package/dist/chunk-MDIZUVIK.js +87 -0
- package/dist/chunk-MV6LW5UB.js +217 -0
- package/dist/chunk-NYLON2VC.js +6 -0
- package/dist/chunk-P6MYZMXQ.js +951 -0
- package/dist/chunk-Q53N43LQ.js +13 -0
- package/dist/chunk-QJVPRD3R.js +573 -0
- package/dist/chunk-RIGLQ4BV.js +3367 -0
- package/dist/chunk-SABTXESR.js +24 -0
- package/dist/chunk-SHUYVCID.js +6 -0
- package/dist/chunk-SYEVGPFC.js +686 -0
- package/dist/chunk-V7HUZ6UQ.js +5923 -0
- package/dist/chunk-WPUVJRIN.js +29 -0
- package/dist/chunk-XCZ3TTFK.js +22 -0
- package/dist/chunk-XSGU2Y2O.js +1611 -0
- package/dist/chunk-YNEW3L63.js +190 -0
- package/dist/chunk-YXGHPILG.js +614 -0
- package/dist/chunk-ZL4LLE2Z.js +465 -0
- package/dist/di-CcNeq9v-.d.cts +16 -0
- package/dist/di-CcNeq9v-.d.ts +16 -0
- package/dist/discovery/index.cjs +588 -0
- package/dist/discovery/index.d.cts +299 -0
- package/dist/discovery/index.d.ts +299 -0
- package/dist/discovery/index.js +49 -0
- package/dist/discovery.scanner-CUYLKlYT.d.cts +59 -0
- package/dist/discovery.scanner-CUYLKlYT.d.ts +59 -0
- package/dist/entitlement/index.cjs +805 -0
- package/dist/entitlement/index.d.cts +60 -0
- package/dist/entitlement/index.d.ts +60 -0
- package/dist/entitlement/index.js +57 -0
- package/dist/index.cjs +15918 -0
- package/dist/index.d.cts +85 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +956 -0
- package/dist/plan-resolution-CFCoUkrE.d.cts +41 -0
- package/dist/plan-resolution-CFCoUkrE.d.ts +41 -0
- package/dist/platform/index.cjs +2772 -0
- package/dist/platform/index.d.cts +118 -0
- package/dist/platform/index.d.ts +118 -0
- package/dist/platform/index.js +37 -0
- package/dist/promo/index.cjs +995 -0
- package/dist/promo/index.d.cts +121 -0
- package/dist/promo/index.d.ts +121 -0
- package/dist/promo/index.js +58 -0
- package/dist/registration/index.cjs +1687 -0
- package/dist/registration/index.d.cts +444 -0
- package/dist/registration/index.d.ts +444 -0
- package/dist/registration/index.js +82 -0
- package/dist/saas-platform.module-CgZ2omgg.d.cts +180 -0
- package/dist/saas-platform.module-DT9TnCzk.d.ts +180 -0
- package/dist/service-DX8KbGXl.d.cts +109 -0
- package/dist/service-DX8KbGXl.d.ts +109 -0
- package/dist/subscription-contract/index.cjs +471 -0
- package/dist/subscription-contract/index.d.cts +17 -0
- package/dist/subscription-contract/index.d.ts +17 -0
- package/dist/subscription-contract/index.js +21 -0
- package/dist/subscription-contract.service--cm47ZJJ.d.cts +39 -0
- package/dist/subscription-contract.service--cm47ZJJ.d.ts +39 -0
- package/dist/testing/index.cjs +3942 -0
- package/dist/testing/index.d.cts +279 -0
- package/dist/testing/index.d.ts +279 -0
- package/dist/testing/index.js +1195 -0
- package/package.json +185 -0
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/discovery/index.ts
|
|
22
|
+
var discovery_exports = {};
|
|
23
|
+
__export(discovery_exports, {
|
|
24
|
+
DEFINES_QUOTA_KEY: () => DEFINES_QUOTA_KEY,
|
|
25
|
+
DISCOVERY_APP_INFO_TOKEN: () => DISCOVERY_APP_INFO_TOKEN,
|
|
26
|
+
DISCOVERY_SNAPSHOT_PATH_TOKEN: () => DISCOVERY_SNAPSHOT_PATH_TOKEN,
|
|
27
|
+
DISCOVERY_SNAPSHOT_TOKEN: () => DISCOVERY_SNAPSHOT_TOKEN,
|
|
28
|
+
DefinesQuota: () => DefinesQuota,
|
|
29
|
+
DiscoveryModule: () => DiscoveryModule,
|
|
30
|
+
DiscoveryScanner: () => DiscoveryScanner,
|
|
31
|
+
DiscoverySnapshotNotFoundError: () => DiscoverySnapshotNotFoundError,
|
|
32
|
+
ENFORCE_QUOTA_KEY: () => ENFORCE_QUOTA_KEY,
|
|
33
|
+
EnforceQuota: () => EnforceQuota,
|
|
34
|
+
IMPLEMENTS_CAPABILITY_KEY: () => IMPLEMENTS_CAPABILITY_KEY,
|
|
35
|
+
ImplementsCapability: () => ImplementsCapability,
|
|
36
|
+
REQUIRES_CAPABILITY_KEY: () => REQUIRES_CAPABILITY_KEY,
|
|
37
|
+
RequiresCapability: () => RequiresCapability,
|
|
38
|
+
buildDiscoveryController: () => buildDiscoveryController,
|
|
39
|
+
computeSnapshotHash: () => computeSnapshotHash,
|
|
40
|
+
loadDiscoverySnapshotFromFile: () => loadDiscoverySnapshotFromFile,
|
|
41
|
+
runHeadlessDiscoveryScan: () => runHeadlessDiscoveryScan
|
|
42
|
+
});
|
|
43
|
+
module.exports = __toCommonJS(discovery_exports);
|
|
44
|
+
|
|
45
|
+
// src/discovery/decorators.ts
|
|
46
|
+
var import_common = require("@nestjs/common");
|
|
47
|
+
|
|
48
|
+
// src/discovery/tokens.ts
|
|
49
|
+
var IMPLEMENTS_CAPABILITY_KEY = "discovery:implements-capability";
|
|
50
|
+
var REQUIRES_CAPABILITY_KEY = "discovery:requires-capability";
|
|
51
|
+
var DEFINES_QUOTA_KEY = "discovery:defines-quota";
|
|
52
|
+
var ENFORCE_QUOTA_KEY = "discovery:enforce-quota";
|
|
53
|
+
var DISCOVERY_SNAPSHOT_TOKEN = /* @__PURE__ */ Symbol.for("saas-platform/DiscoverySnapshot");
|
|
54
|
+
|
|
55
|
+
// src/discovery/decorators.ts
|
|
56
|
+
var ImplementsCapability = /* @__PURE__ */ __name((capabilityKey, options = {}) => (0, import_common.SetMetadata)(IMPLEMENTS_CAPABILITY_KEY, {
|
|
57
|
+
capabilityKey,
|
|
58
|
+
...options
|
|
59
|
+
}), "ImplementsCapability");
|
|
60
|
+
var RequiresCapability = /* @__PURE__ */ __name((...capabilityKeys) => (0, import_common.SetMetadata)(REQUIRES_CAPABILITY_KEY, capabilityKeys), "RequiresCapability");
|
|
61
|
+
var DefinesQuota = /* @__PURE__ */ __name((options) => (0, import_common.SetMetadata)(DEFINES_QUOTA_KEY, options), "DefinesQuota");
|
|
62
|
+
var EnforceQuota = /* @__PURE__ */ __name((quotaKey, options = {}) => (0, import_common.SetMetadata)(ENFORCE_QUOTA_KEY, {
|
|
63
|
+
quotaKey,
|
|
64
|
+
incrementBy: options.incrementBy ?? 1,
|
|
65
|
+
timing: options.timing ?? "before"
|
|
66
|
+
}), "EnforceQuota");
|
|
67
|
+
|
|
68
|
+
// src/discovery/discovery.scanner.ts
|
|
69
|
+
var import_node_crypto = require("crypto");
|
|
70
|
+
var import_node_fs = require("fs");
|
|
71
|
+
var import_node_path = require("path");
|
|
72
|
+
var import_common2 = require("@nestjs/common");
|
|
73
|
+
var import_core = require("@nestjs/core");
|
|
74
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
75
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
76
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
77
|
+
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;
|
|
78
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
79
|
+
}
|
|
80
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
81
|
+
function _ts_metadata(k, v) {
|
|
82
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
83
|
+
}
|
|
84
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
85
|
+
function _ts_param(paramIndex, decorator) {
|
|
86
|
+
return function(target, key) {
|
|
87
|
+
decorator(target, key, paramIndex);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
__name(_ts_param, "_ts_param");
|
|
91
|
+
var DEFAULT_APP_INFO = {
|
|
92
|
+
key: "unknown",
|
|
93
|
+
version: "0.0.0"
|
|
94
|
+
};
|
|
95
|
+
var DISCOVERY_APP_INFO_TOKEN = /* @__PURE__ */ Symbol("DISCOVERY_APP_INFO");
|
|
96
|
+
var DISCOVERY_SNAPSHOT_PATH_TOKEN = /* @__PURE__ */ Symbol("DISCOVERY_SNAPSHOT_PATH");
|
|
97
|
+
var DiscoveryScanner = class _DiscoveryScanner {
|
|
98
|
+
static {
|
|
99
|
+
__name(this, "DiscoveryScanner");
|
|
100
|
+
}
|
|
101
|
+
discoveryService;
|
|
102
|
+
metadataScanner;
|
|
103
|
+
reflector;
|
|
104
|
+
appInfo;
|
|
105
|
+
snapshotPath;
|
|
106
|
+
logger = new import_common2.Logger(_DiscoveryScanner.name);
|
|
107
|
+
snapshot = null;
|
|
108
|
+
// Explicit @Inject instead of type reflection: in the platform package
|
|
109
|
+
// build tsup/esbuild do not emit `design:paramtypes` metadata, so Nest
|
|
110
|
+
// cannot otherwise resolve the DI targets at the constructor
|
|
111
|
+
// (UndefinedDependencyException at the consumer's boot). Pattern
|
|
112
|
+
// analogous to admin/admin-manifest.module.ts.
|
|
113
|
+
constructor(discoveryService, metadataScanner, reflector, appInfo = DEFAULT_APP_INFO, snapshotPath = null) {
|
|
114
|
+
this.discoveryService = discoveryService;
|
|
115
|
+
this.metadataScanner = metadataScanner;
|
|
116
|
+
this.reflector = reflector;
|
|
117
|
+
this.appInfo = appInfo;
|
|
118
|
+
this.snapshotPath = snapshotPath;
|
|
119
|
+
}
|
|
120
|
+
onApplicationBootstrap() {
|
|
121
|
+
this.snapshot = this.buildSnapshot();
|
|
122
|
+
this.logger.log(`Discovery snapshot built: ${this.snapshot.capabilities.length} capabilities, ${this.snapshot.features.length} features, ${this.snapshot.quotas.length} quotas (hash=${this.snapshot.hash.slice(0, 12)}\u2026)`);
|
|
123
|
+
if (this.snapshotPath) {
|
|
124
|
+
this.persistSnapshot(this.snapshotPath, this.snapshot);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
persistSnapshot(path, snapshot) {
|
|
128
|
+
try {
|
|
129
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(path), {
|
|
130
|
+
recursive: true
|
|
131
|
+
});
|
|
132
|
+
(0, import_node_fs.writeFileSync)(path, JSON.stringify(snapshot, null, 2) + "\n", "utf-8");
|
|
133
|
+
this.logger.log(`Discovery snapshot persisted to ${path}`);
|
|
134
|
+
} catch (err) {
|
|
135
|
+
this.logger.warn(`Discovery snapshot konnte nicht nach ${path} geschrieben werden: ${err.message}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Returns the boot-time snapshot. Before `onApplicationBootstrap` (e.g. in
|
|
140
|
+
* tests) the snapshot is built lazily.
|
|
141
|
+
*/
|
|
142
|
+
getSnapshot() {
|
|
143
|
+
if (!this.snapshot) {
|
|
144
|
+
this.snapshot = this.buildSnapshot();
|
|
145
|
+
}
|
|
146
|
+
return this.snapshot;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Forces a re-scan (SuperAdmin "re-run discovery" or tests with
|
|
150
|
+
* dynamically registered providers). `scannedAt` is set anew and the
|
|
151
|
+
* snapshot — as at boot — is persisted to disk so that the last scan
|
|
152
|
+
* actually performed is preserved.
|
|
153
|
+
*/
|
|
154
|
+
rebuildSnapshot() {
|
|
155
|
+
this.snapshot = this.buildSnapshot();
|
|
156
|
+
if (this.snapshotPath) {
|
|
157
|
+
this.persistSnapshot(this.snapshotPath, this.snapshot);
|
|
158
|
+
}
|
|
159
|
+
return this.snapshot;
|
|
160
|
+
}
|
|
161
|
+
buildSnapshot() {
|
|
162
|
+
const capabilitiesByKey = /* @__PURE__ */ new Map();
|
|
163
|
+
const quotasByKey = /* @__PURE__ */ new Map();
|
|
164
|
+
const enforceRefs = [];
|
|
165
|
+
const wrappers = [
|
|
166
|
+
...this.discoveryService.getProviders(),
|
|
167
|
+
...this.discoveryService.getControllers()
|
|
168
|
+
];
|
|
169
|
+
for (const wrapper of wrappers) {
|
|
170
|
+
const instance = wrapper.instance;
|
|
171
|
+
if (!instance || typeof instance !== "object") continue;
|
|
172
|
+
const ctor = instance.constructor;
|
|
173
|
+
if (!ctor) continue;
|
|
174
|
+
const quotaOpts = this.reflector.get(DEFINES_QUOTA_KEY, ctor);
|
|
175
|
+
if (quotaOpts) {
|
|
176
|
+
this.registerQuota(quotasByKey, quotaOpts, ctor.name);
|
|
177
|
+
}
|
|
178
|
+
const prototype = Object.getPrototypeOf(instance);
|
|
179
|
+
const methodNames = this.metadataScanner.getAllMethodNames(prototype);
|
|
180
|
+
for (const methodName of methodNames) {
|
|
181
|
+
const methodRef = instance[methodName];
|
|
182
|
+
if (typeof methodRef !== "function") continue;
|
|
183
|
+
const capMeta = this.reflector.get(IMPLEMENTS_CAPABILITY_KEY, methodRef);
|
|
184
|
+
if (capMeta) {
|
|
185
|
+
this.registerCapability(capabilitiesByKey, capMeta, `${ctor.name}.${methodName}`);
|
|
186
|
+
}
|
|
187
|
+
const enforceMeta = this.reflector.get(ENFORCE_QUOTA_KEY, methodRef);
|
|
188
|
+
if (enforceMeta && capMeta) {
|
|
189
|
+
enforceRefs.push({
|
|
190
|
+
capabilityKey: capMeta.capabilityKey,
|
|
191
|
+
quotaKey: enforceMeta.quotaKey
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const capabilities = sortByKey([
|
|
197
|
+
...capabilitiesByKey.values()
|
|
198
|
+
], (c) => c.capabilityKey);
|
|
199
|
+
const features = aggregateFeatures(capabilities);
|
|
200
|
+
const quotas = sortByKey(decorateQuotasWithEnforcers([
|
|
201
|
+
...quotasByKey.values()
|
|
202
|
+
], enforceRefs), (q) => q.quotaKey);
|
|
203
|
+
const snapshot = {
|
|
204
|
+
schemaVersion: 1,
|
|
205
|
+
scannedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
206
|
+
app: {
|
|
207
|
+
...this.appInfo
|
|
208
|
+
},
|
|
209
|
+
capabilities,
|
|
210
|
+
features,
|
|
211
|
+
quotas,
|
|
212
|
+
hash: ""
|
|
213
|
+
};
|
|
214
|
+
snapshot.hash = computeSnapshotHash(snapshot);
|
|
215
|
+
return snapshot;
|
|
216
|
+
}
|
|
217
|
+
registerCapability(target, meta, declaredAt) {
|
|
218
|
+
const existing = target.get(meta.capabilityKey);
|
|
219
|
+
if (existing) {
|
|
220
|
+
this.logger.warn(`Capability '${meta.capabilityKey}' wird an mehreren Stellen deklariert (${existing.declaredAt} und ${declaredAt}); erste Deklaration gewinnt`);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
target.set(meta.capabilityKey, {
|
|
224
|
+
capabilityKey: meta.capabilityKey,
|
|
225
|
+
label: meta.label ?? null,
|
|
226
|
+
feature: meta.feature ?? null,
|
|
227
|
+
status: meta.status ?? "active",
|
|
228
|
+
kind: meta.kind ?? "endpoint",
|
|
229
|
+
owner: meta.owner ?? null,
|
|
230
|
+
replacementKey: meta.replacementKey ?? null,
|
|
231
|
+
removalPlannedAt: meta.removalPlannedAt ?? null,
|
|
232
|
+
reason: meta.reason ?? null,
|
|
233
|
+
requires: normalizeKeyList(meta.requires),
|
|
234
|
+
replaces: normalizeKeyList(meta.replaces),
|
|
235
|
+
declaredAt
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
registerQuota(target, opts, declaredAt) {
|
|
239
|
+
const existing = target.get(opts.key);
|
|
240
|
+
if (existing) {
|
|
241
|
+
this.logger.warn(`Quota '${opts.key}' wird an mehreren Stellen definiert (${existing.declaredAt} und ${declaredAt}); erste Definition gewinnt`);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
target.set(opts.key, {
|
|
245
|
+
quotaKey: opts.key,
|
|
246
|
+
label: opts.label,
|
|
247
|
+
unit: opts.unit,
|
|
248
|
+
policy: opts.policy,
|
|
249
|
+
feature: opts.feature ?? null,
|
|
250
|
+
replaces: normalizeKeyList(opts.replaces),
|
|
251
|
+
declaredAt,
|
|
252
|
+
enforcedBy: []
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
DiscoveryScanner = _ts_decorate([
|
|
257
|
+
(0, import_common2.Injectable)(),
|
|
258
|
+
_ts_param(0, (0, import_common2.Inject)(import_core.DiscoveryService)),
|
|
259
|
+
_ts_param(1, (0, import_common2.Inject)(import_core.MetadataScanner)),
|
|
260
|
+
_ts_param(2, (0, import_common2.Inject)(import_core.Reflector)),
|
|
261
|
+
_ts_param(3, (0, import_common2.Optional)()),
|
|
262
|
+
_ts_param(3, (0, import_common2.Inject)(DISCOVERY_APP_INFO_TOKEN)),
|
|
263
|
+
_ts_param(4, (0, import_common2.Optional)()),
|
|
264
|
+
_ts_param(4, (0, import_common2.Inject)(DISCOVERY_SNAPSHOT_PATH_TOKEN)),
|
|
265
|
+
_ts_metadata("design:type", Function),
|
|
266
|
+
_ts_metadata("design:paramtypes", [
|
|
267
|
+
typeof import_core.DiscoveryService === "undefined" ? Object : import_core.DiscoveryService,
|
|
268
|
+
typeof import_core.MetadataScanner === "undefined" ? Object : import_core.MetadataScanner,
|
|
269
|
+
typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
|
|
270
|
+
typeof DiscoveryAppInfo === "undefined" ? Object : DiscoveryAppInfo,
|
|
271
|
+
Object
|
|
272
|
+
])
|
|
273
|
+
], DiscoveryScanner);
|
|
274
|
+
function aggregateFeatures(capabilities) {
|
|
275
|
+
const byFeature = /* @__PURE__ */ new Map();
|
|
276
|
+
for (const cap of capabilities) {
|
|
277
|
+
if (!cap.feature) continue;
|
|
278
|
+
const acc = byFeature.get(cap.feature) ?? {
|
|
279
|
+
capabilityKeys: [],
|
|
280
|
+
requires: /* @__PURE__ */ new Set(),
|
|
281
|
+
replaces: /* @__PURE__ */ new Set()
|
|
282
|
+
};
|
|
283
|
+
acc.capabilityKeys.push(cap.capabilityKey);
|
|
284
|
+
for (const key of cap.requires ?? []) acc.requires.add(key);
|
|
285
|
+
for (const key of cap.replaces ?? []) acc.replaces.add(key);
|
|
286
|
+
byFeature.set(cap.feature, acc);
|
|
287
|
+
}
|
|
288
|
+
return sortByKey([
|
|
289
|
+
...byFeature.entries()
|
|
290
|
+
].map(([featureKey, acc]) => {
|
|
291
|
+
acc.requires.delete(featureKey);
|
|
292
|
+
acc.replaces.delete(featureKey);
|
|
293
|
+
return {
|
|
294
|
+
featureKey,
|
|
295
|
+
capabilityKeys: [
|
|
296
|
+
...acc.capabilityKeys
|
|
297
|
+
].sort((a, b) => a.localeCompare(b)),
|
|
298
|
+
requires: setToSortedListOrNull(acc.requires),
|
|
299
|
+
replaces: setToSortedListOrNull(acc.replaces)
|
|
300
|
+
};
|
|
301
|
+
}), (f) => f.featureKey);
|
|
302
|
+
}
|
|
303
|
+
__name(aggregateFeatures, "aggregateFeatures");
|
|
304
|
+
function normalizeKeyList(keys) {
|
|
305
|
+
if (!keys || keys.length === 0) return null;
|
|
306
|
+
return [
|
|
307
|
+
...new Set(keys)
|
|
308
|
+
].sort((a, b) => a.localeCompare(b));
|
|
309
|
+
}
|
|
310
|
+
__name(normalizeKeyList, "normalizeKeyList");
|
|
311
|
+
function setToSortedListOrNull(keys) {
|
|
312
|
+
if (keys.size === 0) return null;
|
|
313
|
+
return [
|
|
314
|
+
...keys
|
|
315
|
+
].sort((a, b) => a.localeCompare(b));
|
|
316
|
+
}
|
|
317
|
+
__name(setToSortedListOrNull, "setToSortedListOrNull");
|
|
318
|
+
function decorateQuotasWithEnforcers(quotas, enforceRefs) {
|
|
319
|
+
const enforcedByQuota = /* @__PURE__ */ new Map();
|
|
320
|
+
for (const ref of enforceRefs) {
|
|
321
|
+
const set = enforcedByQuota.get(ref.quotaKey) ?? /* @__PURE__ */ new Set();
|
|
322
|
+
set.add(ref.capabilityKey);
|
|
323
|
+
enforcedByQuota.set(ref.quotaKey, set);
|
|
324
|
+
}
|
|
325
|
+
return quotas.map((q) => ({
|
|
326
|
+
...q,
|
|
327
|
+
enforcedBy: [
|
|
328
|
+
...enforcedByQuota.get(q.quotaKey) ?? /* @__PURE__ */ new Set()
|
|
329
|
+
].sort((a, b) => a.localeCompare(b))
|
|
330
|
+
}));
|
|
331
|
+
}
|
|
332
|
+
__name(decorateQuotasWithEnforcers, "decorateQuotasWithEnforcers");
|
|
333
|
+
function sortByKey(items, keyFn) {
|
|
334
|
+
return [
|
|
335
|
+
...items
|
|
336
|
+
].sort((a, b) => keyFn(a).localeCompare(keyFn(b)));
|
|
337
|
+
}
|
|
338
|
+
__name(sortByKey, "sortByKey");
|
|
339
|
+
function computeSnapshotHash(snapshot) {
|
|
340
|
+
const stableInput = {
|
|
341
|
+
schemaVersion: snapshot.schemaVersion,
|
|
342
|
+
appKey: snapshot.app.key,
|
|
343
|
+
capabilities: snapshot.capabilities.map((c) => ({
|
|
344
|
+
...c
|
|
345
|
+
})),
|
|
346
|
+
features: snapshot.features,
|
|
347
|
+
quotas: snapshot.quotas
|
|
348
|
+
};
|
|
349
|
+
const json = canonicalStringify(stableInput);
|
|
350
|
+
return `sha256-${(0, import_node_crypto.createHash)("sha256").update(json).digest("hex")}`;
|
|
351
|
+
}
|
|
352
|
+
__name(computeSnapshotHash, "computeSnapshotHash");
|
|
353
|
+
function canonicalStringify(value) {
|
|
354
|
+
return JSON.stringify(value, (_key, val) => {
|
|
355
|
+
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
356
|
+
const sorted = {};
|
|
357
|
+
for (const k of Object.keys(val).sort()) {
|
|
358
|
+
sorted[k] = val[k];
|
|
359
|
+
}
|
|
360
|
+
return sorted;
|
|
361
|
+
}
|
|
362
|
+
return val;
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
__name(canonicalStringify, "canonicalStringify");
|
|
366
|
+
|
|
367
|
+
// src/discovery/discovery.module.ts
|
|
368
|
+
var import_common4 = require("@nestjs/common");
|
|
369
|
+
var import_core2 = require("@nestjs/core");
|
|
370
|
+
|
|
371
|
+
// src/discovery/discovery.controller.ts
|
|
372
|
+
var import_common3 = require("@nestjs/common");
|
|
373
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
374
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
375
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
376
|
+
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;
|
|
377
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
378
|
+
}
|
|
379
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
380
|
+
function _ts_metadata2(k, v) {
|
|
381
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
382
|
+
}
|
|
383
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
384
|
+
function _ts_param2(paramIndex, decorator) {
|
|
385
|
+
return function(target, key) {
|
|
386
|
+
decorator(target, key, paramIndex);
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
__name(_ts_param2, "_ts_param");
|
|
390
|
+
function buildDiscoveryController(guards) {
|
|
391
|
+
let GeneratedDiscoveryController = class GeneratedDiscoveryController {
|
|
392
|
+
static {
|
|
393
|
+
__name(this, "GeneratedDiscoveryController");
|
|
394
|
+
}
|
|
395
|
+
scanner;
|
|
396
|
+
// Explicit @Inject instead of type reflection: tsup/esbuild do not emit
|
|
397
|
+
// any `design:paramtypes` metadata, so otherwise Nest cannot resolve the
|
|
398
|
+
// service type on the constructor.
|
|
399
|
+
constructor(scanner) {
|
|
400
|
+
this.scanner = scanner;
|
|
401
|
+
}
|
|
402
|
+
getDiscovery(ifNoneMatch, res) {
|
|
403
|
+
const snapshot = this.scanner.getSnapshot();
|
|
404
|
+
const etag = `"${snapshot.hash}-${snapshot.scannedAt}"`;
|
|
405
|
+
res.header("ETag", etag);
|
|
406
|
+
if (ifNoneMatch && ifNoneMatch === etag) {
|
|
407
|
+
res.status(import_common3.HttpStatus.NOT_MODIFIED);
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
return snapshot;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Forces a fresh code scan and returns the new snapshot.
|
|
414
|
+
* `scannedAt` is updated; the Capability/Feature/Quota data
|
|
415
|
+
* are identical within the running process (code is stable at runtime).
|
|
416
|
+
*/
|
|
417
|
+
rescanDiscovery() {
|
|
418
|
+
return this.scanner.rebuildSnapshot();
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
_ts_decorate2([
|
|
422
|
+
(0, import_common3.Get)("discovery"),
|
|
423
|
+
(0, import_common3.Header)("Cache-Control", "private, no-cache"),
|
|
424
|
+
_ts_param2(0, (0, import_common3.Headers)("if-none-match")),
|
|
425
|
+
_ts_param2(1, (0, import_common3.Res)({
|
|
426
|
+
passthrough: true
|
|
427
|
+
})),
|
|
428
|
+
_ts_metadata2("design:type", Function),
|
|
429
|
+
_ts_metadata2("design:paramtypes", [
|
|
430
|
+
Object,
|
|
431
|
+
typeof HttpResponseLike === "undefined" ? Object : HttpResponseLike
|
|
432
|
+
]),
|
|
433
|
+
_ts_metadata2("design:returntype", Object)
|
|
434
|
+
], GeneratedDiscoveryController.prototype, "getDiscovery", null);
|
|
435
|
+
_ts_decorate2([
|
|
436
|
+
(0, import_common3.Post)("discovery/rescan"),
|
|
437
|
+
_ts_metadata2("design:type", Function),
|
|
438
|
+
_ts_metadata2("design:paramtypes", []),
|
|
439
|
+
_ts_metadata2("design:returntype", typeof DiscoverySnapshot === "undefined" ? Object : DiscoverySnapshot)
|
|
440
|
+
], GeneratedDiscoveryController.prototype, "rescanDiscovery", null);
|
|
441
|
+
GeneratedDiscoveryController = _ts_decorate2([
|
|
442
|
+
(0, import_common3.Controller)("admin"),
|
|
443
|
+
(0, import_common3.UseGuards)(...guards),
|
|
444
|
+
_ts_param2(0, (0, import_common3.Inject)(DiscoveryScanner)),
|
|
445
|
+
_ts_metadata2("design:type", Function),
|
|
446
|
+
_ts_metadata2("design:paramtypes", [
|
|
447
|
+
typeof DiscoveryScanner === "undefined" ? Object : DiscoveryScanner
|
|
448
|
+
])
|
|
449
|
+
], GeneratedDiscoveryController);
|
|
450
|
+
return GeneratedDiscoveryController;
|
|
451
|
+
}
|
|
452
|
+
__name(buildDiscoveryController, "buildDiscoveryController");
|
|
453
|
+
|
|
454
|
+
// src/discovery/discovery.module.ts
|
|
455
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
456
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
457
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
458
|
+
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;
|
|
459
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
460
|
+
}
|
|
461
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
462
|
+
var DiscoveryModule = class _DiscoveryModule {
|
|
463
|
+
static {
|
|
464
|
+
__name(this, "DiscoveryModule");
|
|
465
|
+
}
|
|
466
|
+
static forRoot(options) {
|
|
467
|
+
const isGlobal = options.isGlobal ?? true;
|
|
468
|
+
const controllers = [];
|
|
469
|
+
if (options.controller) {
|
|
470
|
+
controllers.push(buildDiscoveryController(options.controller.guards));
|
|
471
|
+
}
|
|
472
|
+
const providers = [
|
|
473
|
+
{
|
|
474
|
+
provide: DISCOVERY_APP_INFO_TOKEN,
|
|
475
|
+
useValue: options.app
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
provide: DISCOVERY_SNAPSHOT_PATH_TOKEN,
|
|
479
|
+
useValue: options.snapshotPath ?? null
|
|
480
|
+
},
|
|
481
|
+
DiscoveryScanner,
|
|
482
|
+
{
|
|
483
|
+
provide: DISCOVERY_SNAPSHOT_TOKEN,
|
|
484
|
+
useFactory: /* @__PURE__ */ __name((scanner) => scanner.getSnapshot(), "useFactory"),
|
|
485
|
+
inject: [
|
|
486
|
+
DiscoveryScanner
|
|
487
|
+
]
|
|
488
|
+
}
|
|
489
|
+
];
|
|
490
|
+
return {
|
|
491
|
+
module: _DiscoveryModule,
|
|
492
|
+
imports: [
|
|
493
|
+
import_core2.DiscoveryModule,
|
|
494
|
+
...options.imports ?? []
|
|
495
|
+
],
|
|
496
|
+
controllers,
|
|
497
|
+
providers,
|
|
498
|
+
exports: [
|
|
499
|
+
DiscoveryScanner,
|
|
500
|
+
DISCOVERY_SNAPSHOT_TOKEN
|
|
501
|
+
],
|
|
502
|
+
global: isGlobal
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
DiscoveryModule = _ts_decorate3([
|
|
507
|
+
(0, import_common4.Module)({})
|
|
508
|
+
], DiscoveryModule);
|
|
509
|
+
|
|
510
|
+
// src/discovery/snapshot-loader.ts
|
|
511
|
+
var import_node_fs2 = require("fs");
|
|
512
|
+
var import_node_path2 = require("path");
|
|
513
|
+
var DiscoverySnapshotNotFoundError = class extends Error {
|
|
514
|
+
static {
|
|
515
|
+
__name(this, "DiscoverySnapshotNotFoundError");
|
|
516
|
+
}
|
|
517
|
+
path;
|
|
518
|
+
constructor(path) {
|
|
519
|
+
super(`Discovery-Snapshot-Datei nicht gefunden: ${path}. Booten Sie zuerst die App mit DISCOVERY_SNAPSHOT_PATH oder DiscoveryModule.forRoot({ snapshotPath: '\u2026' }), damit der Scanner die Datei beim OnApplicationBootstrap-Hook schreibt.`), this.path = path;
|
|
520
|
+
this.name = "DiscoverySnapshotNotFoundError";
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
function loadDiscoverySnapshotFromFile(path) {
|
|
524
|
+
const absolute = (0, import_node_path2.resolve)(path);
|
|
525
|
+
if (!(0, import_node_fs2.existsSync)(absolute)) {
|
|
526
|
+
throw new DiscoverySnapshotNotFoundError(absolute);
|
|
527
|
+
}
|
|
528
|
+
const raw = (0, import_node_fs2.readFileSync)(absolute, "utf-8");
|
|
529
|
+
return JSON.parse(raw);
|
|
530
|
+
}
|
|
531
|
+
__name(loadDiscoverySnapshotFromFile, "loadDiscoverySnapshotFromFile");
|
|
532
|
+
|
|
533
|
+
// src/discovery/headless-scan.ts
|
|
534
|
+
var import_core3 = require("@nestjs/core");
|
|
535
|
+
async function runHeadlessDiscoveryScan(appModule, options = {}) {
|
|
536
|
+
const exit = options.exit ?? ((code) => process.exit(code));
|
|
537
|
+
try {
|
|
538
|
+
const app = await import_core3.NestFactory.createApplicationContext(appModule, {
|
|
539
|
+
logger: options.logger ?? [
|
|
540
|
+
"error",
|
|
541
|
+
"warn",
|
|
542
|
+
"log"
|
|
543
|
+
]
|
|
544
|
+
});
|
|
545
|
+
try {
|
|
546
|
+
return resolveSnapshotFromContext(app);
|
|
547
|
+
} finally {
|
|
548
|
+
await app.close();
|
|
549
|
+
}
|
|
550
|
+
} catch (err) {
|
|
551
|
+
console.error("[discovery-scan] FEHLER:", err instanceof Error ? err.message : err);
|
|
552
|
+
return exit(4);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
__name(runHeadlessDiscoveryScan, "runHeadlessDiscoveryScan");
|
|
556
|
+
function resolveSnapshotFromContext(app) {
|
|
557
|
+
try {
|
|
558
|
+
return app.get(DISCOVERY_SNAPSHOT_TOKEN, {
|
|
559
|
+
strict: false
|
|
560
|
+
});
|
|
561
|
+
} catch {
|
|
562
|
+
return app.get(DiscoveryScanner, {
|
|
563
|
+
strict: false
|
|
564
|
+
}).getSnapshot();
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
__name(resolveSnapshotFromContext, "resolveSnapshotFromContext");
|
|
568
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
569
|
+
0 && (module.exports = {
|
|
570
|
+
DEFINES_QUOTA_KEY,
|
|
571
|
+
DISCOVERY_APP_INFO_TOKEN,
|
|
572
|
+
DISCOVERY_SNAPSHOT_PATH_TOKEN,
|
|
573
|
+
DISCOVERY_SNAPSHOT_TOKEN,
|
|
574
|
+
DefinesQuota,
|
|
575
|
+
DiscoveryModule,
|
|
576
|
+
DiscoveryScanner,
|
|
577
|
+
DiscoverySnapshotNotFoundError,
|
|
578
|
+
ENFORCE_QUOTA_KEY,
|
|
579
|
+
EnforceQuota,
|
|
580
|
+
IMPLEMENTS_CAPABILITY_KEY,
|
|
581
|
+
ImplementsCapability,
|
|
582
|
+
REQUIRES_CAPABILITY_KEY,
|
|
583
|
+
RequiresCapability,
|
|
584
|
+
buildDiscoveryController,
|
|
585
|
+
computeSnapshotHash,
|
|
586
|
+
loadDiscoverySnapshotFromFile,
|
|
587
|
+
runHeadlessDiscoveryScan
|
|
588
|
+
});
|