@nx/angular 22.3.0-beta.2 → 22.3.0-beta.3

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/migrations.json CHANGED
@@ -381,6 +381,22 @@
381
381
  },
382
382
  "description": "Update 'vitest' unit test runner option to 'vitest-analog' in generator defaults.",
383
383
  "factory": "./src/migrations/update-22-3-0/update-unit-test-runner-option"
384
+ },
385
+ "set-isolated-modules-22-3-0": {
386
+ "version": "22.3.0-beta.3",
387
+ "requires": {
388
+ "@angular/core": ">=21.0.0"
389
+ },
390
+ "description": "Set 'isolatedModules' to 'true' in TypeScript test configurations for Angular projects.",
391
+ "factory": "./src/migrations/update-22-3-0/set-isolated-modules"
392
+ },
393
+ "update-jest-preset-angular-setup": {
394
+ "version": "22.3.0-beta.3",
395
+ "requires": {
396
+ "@angular/core": ">=21.0.0"
397
+ },
398
+ "description": "Replace 'jest-preset-angular/setup-jest' imports with the new 'setupZoneTestEnv' function.",
399
+ "factory": "./src/migrations/update-22-3-0/update-jest-preset-angular-setup"
384
400
  }
385
401
  },
386
402
  "packageJsonUpdates": {
@@ -2144,22 +2160,6 @@
2144
2160
  "alwaysAddToPackageJson": false
2145
2161
  }
2146
2162
  }
2147
- },
2148
- "22.3.0-jest": {
2149
- "version": "22.3.0-beta.0",
2150
- "requires": {
2151
- "@angular/compiler-cli": ">=19.0.0 <22.0.0",
2152
- "@angular/core": ">=19.0.0 <22.0.0",
2153
- "@angular/platform-browser": ">=19.0.0 <22.0.0",
2154
- "@angular/platform-browser-dynamic": ">=19.0.0 <22.0.0",
2155
- "jest": "^30.0.0"
2156
- },
2157
- "packages": {
2158
- "jest-preset-angular": {
2159
- "version": "~16.0.0",
2160
- "alwaysAddToPackageJson": false
2161
- }
2162
- }
2163
2163
  }
2164
2164
  }
2165
2165
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/angular",
3
- "version": "22.3.0-beta.2",
3
+ "version": "22.3.0-beta.3",
4
4
  "private": false,
5
5
  "description": "The Nx Plugin for Angular contains executors, generators, and utilities for managing Angular applications and libraries within an Nx workspace. It provides: \n\n- Integration with libraries such as Storybook, Jest, ESLint, Tailwind CSS, Playwright and Cypress. \n\n- Generators to help scaffold code quickly (like: Micro Frontends, Libraries, both internal to your codebase and publishable to npm) \n\n- Single Component Application Modules (SCAMs) \n\n- NgRx helpers. \n\n- Utilities for automatic workspace refactoring.",
6
6
  "repository": {
@@ -62,14 +62,14 @@
62
62
  "migrations": "./migrations.json"
63
63
  },
64
64
  "dependencies": {
65
- "@nx/devkit": "22.3.0-beta.2",
66
- "@nx/eslint": "22.3.0-beta.2",
67
- "@nx/js": "22.3.0-beta.2",
68
- "@nx/module-federation": "22.3.0-beta.2",
69
- "@nx/rspack": "22.3.0-beta.2",
70
- "@nx/web": "22.3.0-beta.2",
71
- "@nx/webpack": "22.3.0-beta.2",
72
- "@nx/workspace": "22.3.0-beta.2",
65
+ "@nx/devkit": "22.3.0-beta.3",
66
+ "@nx/eslint": "22.3.0-beta.3",
67
+ "@nx/js": "22.3.0-beta.3",
68
+ "@nx/module-federation": "22.3.0-beta.3",
69
+ "@nx/rspack": "22.3.0-beta.3",
70
+ "@nx/web": "22.3.0-beta.3",
71
+ "@nx/webpack": "22.3.0-beta.3",
72
+ "@nx/workspace": "22.3.0-beta.3",
73
73
  "@phenomnomnominal/tsquery": "~5.0.1",
74
74
  "@typescript-eslint/type-utils": "^8.0.0",
75
75
  "enquirer": "~2.3.6",
@@ -17,7 +17,7 @@ async function normalizeOptions(host, schema) {
17
17
  // Publishable libs cannot use `full` yet, so if its false then use the passed value or default to `full`
18
18
  compilationMode: schema.publishable
19
19
  ? 'partial'
20
- : schema.compilationMode ?? 'full',
20
+ : (schema.compilationMode ?? 'full'),
21
21
  skipModule: schema.skipModule || schema.standalone,
22
22
  ...schema,
23
23
  };
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../../../../../../packages/angular/src/generators/ng-add/utilities/dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,IAAI,EAAE,MAAM,YAAY,CAAC;AAI1E,wBAAgB,+CAA+C,CAC7D,IAAI,EAAE,IAAI,GACT,IAAI,CA4BN"}
1
+ {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../../../../../../packages/angular/src/generators/ng-add/utilities/dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,IAAI,EAAE,MAAM,YAAY,CAAC;AAI1E,wBAAgB,+CAA+C,CAC7D,IAAI,EAAE,IAAI,GACT,IAAI,CA+BN"}
@@ -22,7 +22,7 @@ function normalizeOptions(tree, options) {
22
22
  : options.parent
23
23
  ? (0, path_1.dirname)(options.parent)
24
24
  : undefined,
25
- route: options.route === '' ? `''` : options.route ?? `''`,
25
+ route: options.route === '' ? `''` : (options.route ?? `''`),
26
26
  directory: (0, devkit_1.names)(options.directory).fileName,
27
27
  rxjsVersion,
28
28
  rxjsMajorVersion,
@@ -21,7 +21,7 @@ function normalizeOptions(tree, options) {
21
21
  name,
22
22
  subdirectory,
23
23
  parentDirectory: options.parent ? (0, path_1.dirname)(options.parent) : undefined,
24
- route: options.route === '' ? `''` : options.route ?? `''`,
24
+ route: options.route === '' ? `''` : (options.route ?? `''`),
25
25
  directory: (0, devkit_1.names)(options.directory).fileName,
26
26
  rxjsVersion,
27
27
  rxjsMajorVersion,
@@ -1 +1 @@
1
- {"version":3,"file":"convert-scam-to-standalone.d.ts","sourceRoot":"","sources":["../../../../../../../packages/angular/src/generators/scam-to-standalone/lib/convert-scam-to-standalone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGnD,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,UAAU,EACxB,qBAAqB,EAAE,MAAM,EAC7B,YAAY,EAAE,MAAM,EAAE,EACtB,cAAc,EAAE,MAAM,EAAE,EACxB,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,EACxB,IAAI,EAAE,IAAI,EACV,uBAAuB,EAAE,MAAM,EAC/B,aAAa,EAAE,MAAM,QAyDtB"}
1
+ {"version":3,"file":"convert-scam-to-standalone.d.ts","sourceRoot":"","sources":["../../../../../../../packages/angular/src/generators/scam-to-standalone/lib/convert-scam-to-standalone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGnD,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,UAAU,EACxB,qBAAqB,EAAE,MAAM,EAC7B,YAAY,EAAE,MAAM,EAAE,EACtB,cAAc,EAAE,MAAM,EAAE,EACxB,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,EACxB,IAAI,EAAE,IAAI,EACV,uBAAuB,EAAE,MAAM,EAC/B,aAAa,EAAE,MAAM,QA2DtB"}
@@ -11,7 +11,9 @@ function convertScamToStandalone(componentAST, componentFileContents, importsArr
11
11
  const componentDecoratorMetadataNode = tsquery(componentAST, COMPONENT_PROPERTY_SELECTOR, { visitAllChildren: true })[0];
12
12
  const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
13
13
  newComponentContents = `${componentFileContents.slice(0, componentDecoratorMetadataNode.getStart() - 1)}({
14
- imports: [${importsArray.join(',')}],${providersArray.length > 0 ? `providers: [${providersArray.join(',')}],` : ''}${componentFileContents.slice(componentDecoratorMetadataNode.getStart() + 1, moduleNodes[0].getStart() - 1)}`;
14
+ imports: [${importsArray.join(',')}],${providersArray.length > 0
15
+ ? `providers: [${providersArray.join(',')}],`
16
+ : ''}${componentFileContents.slice(componentDecoratorMetadataNode.getStart() + 1, moduleNodes[0].getStart() - 1)}`;
15
17
  tree.write(normalizedComponentPath, newComponentContents);
16
18
  const componentPathParts = (0, path_1.parse)(normalizedComponentPath);
17
19
  const pathToComponentSpec = (0, devkit_1.joinPathFragments)(componentPathParts.dir, '/', `${componentPathParts.name}.spec.ts`);
@@ -32,7 +32,7 @@ function generateSSRFiles(tree, options) {
32
32
  const sourceRoot = (0, ts_solution_setup_1.getProjectSourceRoot)(project, tree);
33
33
  const ssrVersion = (0, devkit_1.getDependencyVersionFromPackageJson)(tree, '@angular/ssr');
34
34
  const cleanedSsrVersion = ssrVersion
35
- ? (0, semver_1.clean)(ssrVersion) ?? (0, semver_1.coerce)(ssrVersion).version
35
+ ? ((0, semver_1.clean)(ssrVersion) ?? (0, semver_1.coerce)(ssrVersion).version)
36
36
  : null;
37
37
  const componentType = (0, artifact_types_1.getComponentType)(tree);
38
38
  const appComponentInfo = (0, app_components_info_1.getAppComponentInfo)(tree, componentType ? `.${componentType}` : '', project);
@@ -6,7 +6,7 @@ const path_1 = require("path");
6
6
  function locateLibraryEntryPointFromDirectory(tree, directory, projectRoot, projectSourceRoot) {
7
7
  const ngPackageJsonPath = (0, devkit_1.joinPathFragments)(directory, 'ng-package.json');
8
8
  let entryPointFile = tree.exists(ngPackageJsonPath)
9
- ? (0, devkit_1.readJson)(tree, ngPackageJsonPath).lib?.entryFile ?? 'src/public_api.ts'
9
+ ? ((0, devkit_1.readJson)(tree, ngPackageJsonPath).lib?.entryFile ?? 'src/public_api.ts')
10
10
  : null;
11
11
  if (entryPointFile) {
12
12
  return (0, devkit_1.joinPathFragments)(directory, entryPointFile);
@@ -10,7 +10,7 @@ function normalizeOptions(tree, options) {
10
10
  if (projectType !== 'application') {
11
11
  throw new Error(`Web Worker can only be added to an application. Project '${options.project}' is a library.`);
12
12
  }
13
- const path = options.path ?? sourceRoot
13
+ const path = (options.path ?? sourceRoot)
14
14
  ? (0, devkit_1.joinPathFragments)(sourceRoot, 'app')
15
15
  : (0, devkit_1.joinPathFragments)(root, 'src', 'app');
16
16
  if (!tree.exists(path)) {
@@ -0,0 +1,3 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<void>;
3
+ //# sourceMappingURL=set-isolated-modules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-isolated-modules.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/migrations/update-22-3-0/set-isolated-modules.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,IAAI,EAEV,MAAM,YAAY,CAAC;AAWpB,yBAA+B,IAAI,EAAE,IAAI,iBA6CxC"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const tsconfig_utils_1 = require("../../generators/utils/tsconfig-utils");
6
+ const targets_1 = require("../../utils/targets");
7
+ const projects_1 = require("../utils/projects");
8
+ async function default_1(tree) {
9
+ const uniqueSpecTsConfigs = new Set();
10
+ const projects = await (0, projects_1.getProjectsFilteredByDependencies)([
11
+ 'npm:@angular/core',
12
+ 'npm:jest-preset-angular',
13
+ ]);
14
+ for (const graphNode of projects) {
15
+ const projectRoot = graphNode.data.root;
16
+ // add tsconfig.spec.json if it exists
17
+ const specTsConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, 'tsconfig.spec.json');
18
+ if (tree.exists(specTsConfigPath)) {
19
+ uniqueSpecTsConfigs.add(specTsConfigPath);
20
+ }
21
+ // look for tsConfig in @nx/jest:jest tasks in case there are any
22
+ // custom test tsconfig files
23
+ for (const [, target] of (0, targets_1.allProjectTargets)(graphNode.data)) {
24
+ if (target.executor !== '@nx/jest:jest') {
25
+ continue;
26
+ }
27
+ for (const [, options] of (0, targets_1.allTargetOptions)(target)) {
28
+ if (typeof options?.tsConfig === 'string' &&
29
+ tree.exists(options.tsConfig)) {
30
+ uniqueSpecTsConfigs.add(options.tsConfig);
31
+ }
32
+ }
33
+ }
34
+ }
35
+ for (const tsConfig of uniqueSpecTsConfigs) {
36
+ setIsolatedModules(tree, tsConfig);
37
+ }
38
+ await (0, devkit_1.formatFiles)(tree);
39
+ }
40
+ function setIsolatedModules(tree, tsConfigPath) {
41
+ const compilerOptions = (0, tsconfig_utils_1.readCompilerOptionsFromTsConfig)(tree, tsConfigPath);
42
+ if (compilerOptions.isolatedModules === true) {
43
+ // already set to true
44
+ return;
45
+ }
46
+ // set isolatedModules to true
47
+ (0, devkit_1.updateJson)(tree, tsConfigPath, (json) => {
48
+ json.compilerOptions ??= {};
49
+ json.compilerOptions.isolatedModules = true;
50
+ return json;
51
+ });
52
+ }
@@ -0,0 +1,3 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<void>;
3
+ //# sourceMappingURL=update-jest-preset-angular-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-jest-preset-angular-setup.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/migrations/update-22-3-0/update-jest-preset-angular-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAG1E,yBAA+B,IAAI,EAAE,IAAI,iBA2ExC"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const projects_1 = require("../utils/projects");
6
+ async function default_1(tree) {
7
+ const projects = await (0, projects_1.getProjectsFilteredByDependencies)([
8
+ 'npm:jest-preset-angular',
9
+ ]);
10
+ if (!projects.length) {
11
+ return;
12
+ }
13
+ // The old 'jest-preset-angular/setup-jest' import only supported zone-based testing.
14
+ // Zoneless support was added in jest-preset-angular v14.3.0 with the new
15
+ // setupZonelessTestEnv function. Therefore, all projects using the old import
16
+ // were zone-based and should be migrated to setupZoneTestEnv.
17
+ // Regex patterns to match removed imports
18
+ // Matches: import 'jest-preset-angular/setup-jest'; (with optional .js/.mjs extension)
19
+ // Captures .mjs extension in group 3 to preserve it in the replacement
20
+ const setupJestImportRegex = /^(\s*)import\s+(['"`])jest-preset-angular\/setup-jest(?:\.js)?(\.mjs)?\2;?\s*$/gm;
21
+ // Matches: require('jest-preset-angular/setup-jest'); (with optional .js extension)
22
+ // Note: .mjs is not supported with require() so we don't capture it
23
+ const setupJestRequireRegex = /^(\s*)require\s*\(\s*(['"`])jest-preset-angular\/setup-jest(?:\.js)?\2\s*\)\s*;?\s*$/gm;
24
+ for (const project of projects) {
25
+ (0, devkit_1.visitNotIgnoredFiles)(tree, project.data.root, (file) => {
26
+ if (!file.endsWith('.ts')) {
27
+ return;
28
+ }
29
+ let content = tree.read(file, 'utf-8');
30
+ if (!content.includes('jest-preset-angular/setup-jest')) {
31
+ return;
32
+ }
33
+ let wasUpdated = false;
34
+ // Replace import statements, preserving .mjs extension if present
35
+ setupJestImportRegex.lastIndex = 0;
36
+ if (setupJestImportRegex.test(content)) {
37
+ setupJestImportRegex.lastIndex = 0;
38
+ content = content.replace(setupJestImportRegex, (_match, _leadingWhitespace, _quote, mjsExt) => {
39
+ const modulePath = mjsExt
40
+ ? 'jest-preset-angular/setup-env/zone/index.mjs'
41
+ : 'jest-preset-angular/setup-env/zone';
42
+ return `import { setupZoneTestEnv } from '${modulePath}';
43
+
44
+ setupZoneTestEnv();`;
45
+ });
46
+ wasUpdated = true;
47
+ }
48
+ // Replace require statements, keeping require syntax
49
+ setupJestRequireRegex.lastIndex = 0;
50
+ if (setupJestRequireRegex.test(content)) {
51
+ setupJestRequireRegex.lastIndex = 0;
52
+ content = content.replace(setupJestRequireRegex, `const { setupZoneTestEnv } = require('jest-preset-angular/setup-env/zone');
53
+
54
+ setupZoneTestEnv();`);
55
+ wasUpdated = true;
56
+ }
57
+ if (wasUpdated) {
58
+ tree.write(file, content);
59
+ }
60
+ });
61
+ }
62
+ await (0, devkit_1.formatFiles)(tree);
63
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"file-change-recorder.d.ts","sourceRoot":"","sources":["../../../../../packages/angular/src/utils/file-change-recorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,qBAAa,kBAAkB;IAWjB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAQ,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAVlE,OAAO,CAAC,cAAc,CAAc;IAEpC,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;gBAE4B,IAAI,EAAE,IAAI,EAAmB,QAAQ,EAAE,MAAM;IAI1E,YAAY,IAAI,IAAI;IAIpB,UAAU,IAAI,OAAO;IAIrB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIhD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAI1C,uBAAuB,IAAI,IAAI;CAKhC"}
1
+ {"version":3,"file":"file-change-recorder.d.ts","sourceRoot":"","sources":["../../../../../packages/angular/src/utils/file-change-recorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,qBAAa,kBAAkB;IAY3B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAZ3B,OAAO,CAAC,cAAc,CAAc;IAEpC,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;gBAGkB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM;IAKnC,YAAY,IAAI,IAAI;IAIpB,UAAU,IAAI,OAAO;IAIrB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIhD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAI1C,uBAAuB,IAAI,IAAI;CAKhC"}
@@ -9,12 +9,12 @@ const versions = tslib_1.__importStar(require("./versions"));
9
9
  const versions_1 = require("./versions");
10
10
  function getPkgVersionForAngularMajorVersion(pkgVersionName, angularMajorVersion) {
11
11
  return angularMajorVersion < (0, semver_1.major)((0, semver_1.coerce)(versions_1.angularVersion))
12
- ? backward_compatible_versions_1.backwardCompatibleVersions[angularMajorVersion]?.[pkgVersionName] ??
13
- versions[pkgVersionName]
12
+ ? (backward_compatible_versions_1.backwardCompatibleVersions[angularMajorVersion]?.[pkgVersionName] ??
13
+ versions[pkgVersionName])
14
14
  : versions[pkgVersionName];
15
15
  }
16
16
  function getPkgVersionsForAngularMajorVersion(angularMajorVersion) {
17
17
  return angularMajorVersion < (0, semver_1.major)((0, semver_1.coerce)(versions_1.angularVersion))
18
- ? backward_compatible_versions_1.backwardCompatibleVersions[angularMajorVersion] ?? versions
18
+ ? (backward_compatible_versions_1.backwardCompatibleVersions[angularMajorVersion] ?? versions)
19
19
  : versions;
20
20
  }