@nestjs/core 11.0.0-next.2 → 11.0.0-next.4

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.
@@ -100,6 +100,9 @@ class NestContainer {
100
100
  await this.addDynamicMetadata(token, dynamicMetadata, updatedScope);
101
101
  if (this.isGlobalModule(type, dynamicMetadata)) {
102
102
  moduleRef.isGlobal = true;
103
+ // Set global module distance to MAX_VALUE to ensure their lifecycle hooks
104
+ // are always executed first (when initializing the application)
105
+ moduleRef.distance = Number.MAX_VALUE;
103
106
  this.addGlobalModule(moduleRef);
104
107
  }
105
108
  return moduleRef;
@@ -269,7 +269,9 @@ class NestApplicationContext extends abstract_instance_resolver_1.AbstractInstan
269
269
  * modules and children.
270
270
  */
271
271
  async callShutdownHook(signal) {
272
- const modulesSortedByDistance = this.getModulesToTriggerHooksOn();
272
+ const modulesSortedByDistance = [
273
+ ...this.getModulesToTriggerHooksOn(),
274
+ ].reverse();
273
275
  for (const module of modulesSortedByDistance) {
274
276
  await (0, hooks_1.callAppShutdownHook)(module, signal);
275
277
  }
@@ -279,7 +281,9 @@ class NestApplicationContext extends abstract_instance_resolver_1.AbstractInstan
279
281
  * modules and children.
280
282
  */
281
283
  async callBeforeShutdownHook(signal) {
282
- const modulesSortedByDistance = this.getModulesToTriggerHooksOn();
284
+ const modulesSortedByDistance = [
285
+ ...this.getModulesToTriggerHooksOn(),
286
+ ].reverse();
283
287
  for (const module of modulesSortedByDistance) {
284
288
  await (0, hooks_1.callBeforeAppShutdownHook)(module, signal);
285
289
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/core",
3
- "version": "11.0.0-next.2",
3
+ "version": "11.0.0-next.4",
4
4
  "description": "Nest - modern, fast, powerful node.js web framework (@core)",
5
5
  "author": "Kamil Mysliwiec",
6
6
  "license": "MIT",
@@ -36,7 +36,7 @@
36
36
  "uid": "2.0.2"
37
37
  },
38
38
  "devDependencies": {
39
- "@nestjs/common": "^11.0.0-next.2"
39
+ "@nestjs/common": "^11.0.0-next.4"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@nestjs/common": "^10.0.0",
@@ -22,14 +22,14 @@ class LegacyRouteConverter {
22
22
  if (normalizedRoute !== '/(.*)/') {
23
23
  this.printWarning(route);
24
24
  }
25
- return route.replace('(.*)', '*path');
25
+ return route.replace('(.*)', '{*path}');
26
26
  }
27
27
  if (normalizedRoute.endsWith('/*/')) {
28
28
  // Skip printing warning for the "all" wildcard.
29
29
  if (normalizedRoute !== '/*/') {
30
30
  this.printWarning(route);
31
31
  }
32
- return route.replace('*', '*path');
32
+ return route.replace('*', '{*path}');
33
33
  }
34
34
  if (normalizedRoute.endsWith('/+/')) {
35
35
  this.printWarning(route);
package/scanner.js CHANGED
@@ -30,8 +30,11 @@ class DependenciesScanner {
30
30
  });
31
31
  await this.scanModulesForDependencies();
32
32
  this.addScopedEnhancersMetadata();
33
- this.container.bindGlobalScope();
33
+ // Modules distance calculation should be done after all modules are scanned
34
+ // but before global modules are registered (linked to all modules).
35
+ // Global modules have their distance set to MAX anyway.
34
36
  this.calculateModulesDistance();
37
+ this.container.bindGlobalScope();
35
38
  }
36
39
  async scanForModules({ moduleDefinition, lazy, scope = [], ctxRegistry = [], overrides = [], }) {
37
40
  const { moduleRef: moduleInstance, inserted: moduleInserted } = (await this.insertOrOverrideModule(moduleDefinition, overrides, scope)) ??
@@ -207,7 +210,8 @@ class DependenciesScanner {
207
210
  const moduleImports = moduleRef.imports;
208
211
  moduleImports.forEach(importedModuleRef => {
209
212
  if (importedModuleRef) {
210
- if (distance > importedModuleRef.distance) {
213
+ if (distance > importedModuleRef.distance &&
214
+ !importedModuleRef.isGlobal) {
211
215
  importedModuleRef.distance = distance;
212
216
  }
213
217
  calculateDistance(importedModuleRef, distance + 1, localModulesStack);
@@ -1,14 +0,0 @@
1
- import { DynamicModule } from '@nestjs/common';
2
- import { Type } from '@nestjs/common/interfaces/type.interface';
3
- export declare class ModuleTokenFactory {
4
- private readonly moduleTokenCache;
5
- private readonly moduleIdsCache;
6
- private readonly logger;
7
- create(metatype: Type<unknown>, dynamicModuleMetadata?: Partial<DynamicModule> | undefined): string;
8
- getStaticModuleToken(moduleId: string, moduleName: string): string;
9
- getStringifiedOpaqueToken(opaqueToken: object | undefined): string;
10
- getModuleId(metatype: Type<unknown>): string;
11
- getModuleName(metatype: Type<any>): string;
12
- private hashString;
13
- private replacer;
14
- }
@@ -1,84 +0,0 @@
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
- // Uses safeStringify instead of JSON.stringify to support circular dynamic modules
50
- // The replacer function is also required in order to obtain real class names
51
- // instead of the unified "Function" key
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;