1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.ModuleTokenFactory = void 0;
|
4 | const common_1 = require("@nestjs/common");
|
5 | const random_string_generator_util_1 = require("@nestjs/common/utils/random-string-generator.util");
|
6 | const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
|
7 | const crypto_1 = require("crypto");
|
8 | const fast_safe_stringify_1 = require("fast-safe-stringify");
|
9 | const perf_hooks_1 = require("perf_hooks");
|
10 | const CLASS_STR = 'class ';
|
11 | const CLASS_STR_LEN = CLASS_STR.length;
|
12 | class ModuleTokenFactory {
|
13 | constructor() {
|
14 | this.moduleTokenCache = new Map();
|
15 | this.moduleIdsCache = new WeakMap();
|
16 | this.logger = new common_1.Logger(ModuleTokenFactory.name, {
|
17 | timestamp: true,
|
18 | });
|
19 | }
|
20 | create(metatype, dynamicModuleMetadata) {
|
21 | const moduleId = this.getModuleId(metatype);
|
22 | if (!dynamicModuleMetadata) {
|
23 | return this.getStaticModuleToken(moduleId, this.getModuleName(metatype));
|
24 | }
|
25 | const opaqueToken = {
|
26 | id: moduleId,
|
27 | module: this.getModuleName(metatype),
|
28 | dynamic: dynamicModuleMetadata,
|
29 | };
|
30 | const start = perf_hooks_1.performance.now();
|
31 | const opaqueTokenString = this.getStringifiedOpaqueToken(opaqueToken);
|
32 | const timeSpentInMs = perf_hooks_1.performance.now() - start;
|
33 | if (timeSpentInMs > 10) {
|
34 | const formattedTimeSpent = timeSpentInMs.toFixed(2);
|
35 | this.logger.warn(`The module "${opaqueToken.module}" is taking ${formattedTimeSpent}ms to serialize, this may be caused by larger objects statically assigned to the module. More details: https://github.com/nestjs/nest/issues/12738`);
|
36 | }
|
37 | return this.hashString(opaqueTokenString);
|
38 | }
|
39 | getStaticModuleToken(moduleId, moduleName) {
|
40 | const key = `${moduleId}_${moduleName}`;
|
41 | if (this.moduleTokenCache.has(key)) {
|
42 | return this.moduleTokenCache.get(key);
|
43 | }
|
44 | const hash = this.hashString(key);
|
45 | this.moduleTokenCache.set(key, hash);
|
46 | return hash;
|
47 | }
|
48 | getStringifiedOpaqueToken(opaqueToken) {
|
49 |
|
50 |
|
51 |
|
52 | return opaqueToken ? (0, fast_safe_stringify_1.default)(opaqueToken, this.replacer) : '';
|
53 | }
|
54 | getModuleId(metatype) {
|
55 | let moduleId = this.moduleIdsCache.get(metatype);
|
56 | if (moduleId) {
|
57 | return moduleId;
|
58 | }
|
59 | moduleId = (0, random_string_generator_util_1.randomStringGenerator)();
|
60 | this.moduleIdsCache.set(metatype, moduleId);
|
61 | return moduleId;
|
62 | }
|
63 | getModuleName(metatype) {
|
64 | return metatype.name;
|
65 | }
|
66 | hashString(value) {
|
67 | return (0, crypto_1.createHash)('sha256').update(value).digest('hex');
|
68 | }
|
69 | replacer(key, value) {
|
70 | if ((0, shared_utils_1.isFunction)(value)) {
|
71 | const funcAsString = value.toString();
|
72 | const isClass = funcAsString.slice(0, CLASS_STR_LEN) === CLASS_STR;
|
73 | if (isClass) {
|
74 | return value.name;
|
75 | }
|
76 | return funcAsString;
|
77 | }
|
78 | if ((0, shared_utils_1.isSymbol)(value)) {
|
79 | return value.toString();
|
80 | }
|
81 | return value;
|
82 | }
|
83 | }
|
84 | exports.ModuleTokenFactory = ModuleTokenFactory;
|