@saasicat/nest 0.9.0 → 0.10.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.
Files changed (86) hide show
  1. package/dist/_entries.cjs +17678 -0
  2. package/dist/admin/index.cjs +4 -1533
  3. package/dist/admin/index.d.cts +10 -173
  4. package/dist/admin/index.d.ts +10 -173
  5. package/dist/admin/index.js +3 -2
  6. package/dist/{admin-resources.module-BybEjZs-.d.cts → admin-resources.module-BZN_yBFj.d.cts} +1 -1
  7. package/dist/{admin-resources.module-CUCLlUAi.d.ts → admin-resources.module-Cms8MY6h.d.ts} +1 -1
  8. package/dist/admin-stats.module-15ac5KY3.d.ts +201 -0
  9. package/dist/admin-stats.module-v4SVvWzj.d.cts +201 -0
  10. package/dist/billing/index.cjs +4 -5130
  11. package/dist/billing/index.d.cts +8 -437
  12. package/dist/billing/index.d.ts +8 -437
  13. package/dist/billing/index.js +4 -4
  14. package/dist/catalog/index.cjs +4 -5624
  15. package/dist/catalog/index.d.cts +5 -328
  16. package/dist/catalog/index.d.ts +5 -328
  17. package/dist/catalog/index.js +4 -4
  18. package/dist/checkout-offer/index.cjs +4 -807
  19. package/dist/checkout-offer/index.d.cts +5 -84
  20. package/dist/checkout-offer/index.d.ts +5 -84
  21. package/dist/checkout-offer/index.js +3 -2
  22. package/dist/checkout-offer.module-Y0hDOVrq.d.ts +85 -0
  23. package/dist/checkout-offer.module-ZYF5IsDY.d.cts +85 -0
  24. package/dist/{chunk-PBQRPDO2.js → chunk-33TP26MR.js} +2 -2
  25. package/dist/{chunk-CK54YKVK.js → chunk-75JABGZK.js} +16 -16
  26. package/dist/{chunk-HRU3CP57.js → chunk-BOADBIGB.js} +1 -1
  27. package/dist/chunk-DBZGV3HC.js +0 -0
  28. package/dist/{chunk-ZLUGQE5D.js → chunk-E7AJ42AB.js} +8 -8
  29. package/dist/{chunk-HXAWPPFW.js → chunk-F3VV6EXG.js} +9 -9
  30. package/dist/{chunk-3M6VLT5N.js → chunk-FVT7KTUI.js} +2 -2
  31. package/dist/{chunk-GW2I3JZD.js → chunk-GBDUH6DO.js} +1 -1
  32. package/dist/{chunk-K3OPNVFR.js → chunk-HBFU5AN3.js} +5 -9
  33. package/dist/{chunk-OFBDEO45.js → chunk-IRWZC3GC.js} +1 -1
  34. package/dist/chunk-L4KTQ6CL.js +20 -0
  35. package/dist/{chunk-WGVTXSYW.js → chunk-LZHLGUQI.js} +1 -1
  36. package/dist/{chunk-ZZMAHX22.js → chunk-PUXLPUVH.js} +15 -12
  37. package/dist/{chunk-7K5PT2LX.js → chunk-TXDH4FUA.js} +1 -1
  38. package/dist/chunk-UF53DWWR.js +0 -0
  39. package/dist/{chunk-AJ3EPELS.js → chunk-V34AA7C7.js} +1 -1
  40. package/dist/chunk-WJ6BMDL3.js +313 -0
  41. package/dist/{chunk-M6CZQYPY.js → chunk-Z3FWN3HJ.js} +2 -2
  42. package/dist/discovery/index.cjs +4 -588
  43. package/dist/discovery/index.js +3 -3
  44. package/dist/{enforce-quota.interceptor-SqrQVF91.d.cts → enforce-quota.interceptor-BhkX5nq2.d.cts} +35 -2
  45. package/dist/{enforce-quota.interceptor-B3CL5MSw.d.ts → enforce-quota.interceptor-CcqZc0Yu.d.ts} +35 -2
  46. package/dist/entitlement/index.cjs +4 -781
  47. package/dist/entitlement/index.js +2 -2
  48. package/dist/index.cjs +4 -15671
  49. package/dist/index.d.cts +21 -56
  50. package/dist/index.d.ts +21 -56
  51. package/dist/index.js +39 -334
  52. package/dist/{module-DeH_Jkcq.d.cts → module-CSN8j8Tp.d.cts} +1 -1
  53. package/dist/{module-B5m080F0.d.ts → module-DgYJur6f.d.ts} +1 -1
  54. package/dist/plan-versions.service-BB36Q1bg.d.ts +329 -0
  55. package/dist/plan-versions.service-CUR2Whyr.d.cts +329 -0
  56. package/dist/platform/index.cjs +4 -12925
  57. package/dist/platform/index.d.cts +17 -9
  58. package/dist/platform/index.d.ts +17 -9
  59. package/dist/platform/index.js +98 -14
  60. package/dist/promo/index.cjs +4 -1520
  61. package/dist/promo/index.d.cts +6 -21
  62. package/dist/promo/index.d.ts +6 -21
  63. package/dist/promo/index.js +2 -2
  64. package/dist/rate-limit.guard-dntqAlfZ.d.cts +19 -0
  65. package/dist/rate-limit.guard-dntqAlfZ.d.ts +19 -0
  66. package/dist/registration/index.cjs +4 -1655
  67. package/dist/registration/index.js +1 -1
  68. package/dist/{service-DlhMnYjW.d.ts → service-DX8KbGXl.d.cts} +1 -1
  69. package/dist/{service-DlhMnYjW.d.cts → service-DX8KbGXl.d.ts} +1 -1
  70. package/dist/setup.service-BPwJ7My_.d.cts +45 -0
  71. package/dist/setup.service-D2mrdDDB.d.ts +45 -0
  72. package/dist/subscription-bundle-preview.service-BkJXHAeP.d.cts +438 -0
  73. package/dist/subscription-bundle-preview.service-DBbrE_cw.d.ts +438 -0
  74. package/dist/subscription-contract/index.cjs +4 -471
  75. package/dist/subscription-contract/index.d.cts +5 -13
  76. package/dist/subscription-contract/index.d.ts +5 -13
  77. package/dist/subscription-contract.module-CG9fPKAr.d.cts +14 -0
  78. package/dist/subscription-contract.module-CVebZzHR.d.ts +14 -0
  79. package/dist/testing/index.cjs +4 -13888
  80. package/dist/testing/index.d.cts +5 -5
  81. package/dist/testing/index.d.ts +5 -5
  82. package/dist/testing/index.js +10 -10
  83. package/package.json +4 -4
  84. package/dist/admin-manifest.service-BMeSLRW4.d.ts +0 -33
  85. package/dist/admin-manifest.service-StAQe6QO.d.cts +0 -33
  86. package/dist/chunk-N3WANKSA.js +0 -20
@@ -1,588 +1,4 @@
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
- });
1
+ 'use strict';
2
+ // Generated by scripts/build-cjs-stubs.mjs — do not edit.
3
+ // Thin re-export so every entry shares one set of class objects.
4
+ module.exports = require('../_entries.cjs').discoveryNs;
@@ -4,7 +4,7 @@ import {
4
4
  ImplementsCapability,
5
5
  RequiresCapability,
6
6
  runHeadlessDiscoveryScan
7
- } from "../chunk-HRU3CP57.js";
7
+ } from "../chunk-BOADBIGB.js";
8
8
  import {
9
9
  DiscoverySnapshotNotFoundError,
10
10
  loadDiscoverySnapshotFromFile
@@ -12,13 +12,13 @@ import {
12
12
  import {
13
13
  DiscoveryModule,
14
14
  buildDiscoveryController
15
- } from "../chunk-AJ3EPELS.js";
15
+ } from "../chunk-V34AA7C7.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-M6CZQYPY.js";
21
+ } from "../chunk-Z3FWN3HJ.js";
22
22
  import {
23
23
  DEFINES_QUOTA_KEY,
24
24
  DISCOVERY_SNAPSHOT_TOKEN,
@@ -1,9 +1,9 @@
1
1
  import { Type, CanActivate, DynamicModule, ForwardReference, FactoryProvider, Provider, ExecutionContext, NestInterceptor, CallHandler } from '@nestjs/common';
2
2
  import { PlanCatalog, SaasicatPersistenceAdapter, MfaPort, AuditPort, RlsBypassPort, PlanCatalogReadSink, SubscriptionRepository, PlanVersionRepository, TransactionRunner, QuotaProvider, FeatureUiRegistry, SubscriptionUsagePort, UsageSnapshotPort, TenantSubscriptionWritePort, AdminResourcesPort, FirstTimeCustomerCheck } from '@saasicat/types';
3
3
  import { P as ProviderSpec } from './di-CcNeq9v-.cjs';
4
- import { A as AdminManifestConfig, d as AdminResourcesModuleOptions } from './admin-resources.module-BybEjZs-.cjs';
4
+ import { b as AdminManifestConfig, d as AdminResourcesModuleOptions } from './admin-resources.module-BZN_yBFj.cjs';
5
5
  import { E as EntitlementResolutionConfig } from './plan-resolution-CFCoUkrE.cjs';
6
- import { a as PromoCodesModuleOptions } from './module-DeH_Jkcq.cjs';
6
+ import { a as PromoCodesModuleOptions } from './module-CSN8j8Tp.cjs';
7
7
  import { b as DiscoveryAppInfo } from './discovery.scanner-DLgEvuoy.cjs';
8
8
  import { b as CatalogModuleOptions } from './catalog.module-Dw2Hrbyu.cjs';
9
9
  import { t as TenantBillingModuleOptions, p as SubscriptionBundleModuleOptions, n as SubscriptionBundleControllerOptions } from './subscription-bundles.module-DCpV-Pb5.cjs';
@@ -125,6 +125,15 @@ interface SaasPlatformPromoCodesOptions extends Omit<PromoCodesModuleOptions, 'p
125
125
  firstTimeCustomerCheck?: ProviderSpec<FirstTimeCustomerCheck>;
126
126
  /** Override the default controller guards + `SuperAdminGuard` chain. */
127
127
  adminGuards?: Array<Type<CanActivate>>;
128
+ /**
129
+ * Mount the SuperAdmin promo-code CRUD controller. Default `true`.
130
+ *
131
+ * Set `false` when the app serves `/admin/promo-codes` itself — two
132
+ * controllers on one path abort the boot with a duplicate-route error.
133
+ * The promo domain service stays available either way, so an app-owned
134
+ * controller can still delegate its validation to the platform.
135
+ */
136
+ adminController?: false;
128
137
  }
129
138
  interface SaasPlatformModuleOptions {
130
139
  /**
@@ -178,6 +187,16 @@ interface SaasPlatformModuleOptions {
178
187
  * `MfaGuard`). Optional.
179
188
  */
180
189
  reloadGuards?: Array<Type<CanActivate>>;
190
+ /**
191
+ * Mount the platform's `GET /admin/manifest` + `POST /admin/manifest/reload`
192
+ * controller. Default `true`.
193
+ *
194
+ * Set `false` when the app serves those routes from its own controller —
195
+ * two controllers on one path abort the boot with a duplicate-route error
196
+ * (`FST_ERR_DUPLICATED_ROUTE` under Fastify), so this is not something the
197
+ * app can simply override.
198
+ */
199
+ includeManifestController?: boolean;
181
200
  /**
182
201
  * Modules whose providers must be visible in the DI scope (typically:
183
202
  * `AuthModule` with the `JwtAuthGuard`).
@@ -265,6 +284,20 @@ interface SaasPlatformModuleOptions {
265
284
  * `controller.guards`.
266
285
  */
267
286
  tenantManifest?: true | TenantManifestControllerOptions;
287
+ /**
288
+ * Bind `StaticFeatureGuard` as a global `APP_GUARD`. Default `true`.
289
+ *
290
+ * Set `false` when the app authenticates in a controller-local guard.
291
+ * Nest runs every global guard before every controller-local one, so a
292
+ * global feature guard sees no `request.user` and rejects with 403 before
293
+ * authentication has run. Apps in that shape bind the guard themselves,
294
+ * behind their auth guard: `@UseGuards(JwtAuthGuard, FeatureGuard)`.
295
+ *
296
+ * Only the guard is affected. `EnforceQuotaInterceptor` stays global
297
+ * either way — interceptors run after all guards, so it does see the
298
+ * authenticated request.
299
+ */
300
+ globalFeatureGuard?: boolean;
268
301
  }
269
302
  /**
270
303
  * Bundles PlanCatalog + Discovery + Admin + AdminManifest (+ optionally