@nx/angular 21.5.0-beta.1 → 21.5.0-beta.2

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 (31) hide show
  1. package/migrations.json +169 -0
  2. package/package.json +9 -9
  3. package/spec/src/migrations/update-21-5-0/remove-default-karma-configuration-files.spec.d.ts +2 -0
  4. package/spec/src/migrations/update-21-5-0/remove-default-karma-configuration-files.spec.d.ts.map +1 -0
  5. package/spec/src/migrations/update-21-5-0/update-angular-cli.spec.d.ts +2 -0
  6. package/spec/src/migrations/update-21-5-0/update-angular-cli.spec.d.ts.map +1 -0
  7. package/src/generators/convert-to-rspack/convert-to-rspack.d.ts.map +1 -1
  8. package/src/generators/convert-to-rspack/convert-to-rspack.js +9 -3
  9. package/src/generators/setup-mf/lib/fix-bootstrap.js +2 -2
  10. package/src/generators/utils/version-utils.d.ts +5 -0
  11. package/src/generators/utils/version-utils.d.ts.map +1 -1
  12. package/src/generators/utils/version-utils.js +18 -0
  13. package/src/migrations/update-21-5-0/remove-default-karma-configuration-files.d.ts +3 -0
  14. package/src/migrations/update-21-5-0/remove-default-karma-configuration-files.d.ts.map +1 -0
  15. package/src/migrations/update-21-5-0/remove-default-karma-configuration-files.js +53 -0
  16. package/src/migrations/update-21-5-0/update-angular-cli.d.ts +4 -0
  17. package/src/migrations/update-21-5-0/update-angular-cli.d.ts.map +1 -0
  18. package/src/migrations/update-21-5-0/update-angular-cli.js +23 -0
  19. package/src/migrations/update-21-5-0/utils/karma-config-analyzer.d.ts +28 -0
  20. package/src/migrations/update-21-5-0/utils/karma-config-analyzer.d.ts.map +1 -0
  21. package/src/migrations/update-21-5-0/utils/karma-config-analyzer.js +139 -0
  22. package/src/migrations/update-21-5-0/utils/karma-config-comparer.d.ts +64 -0
  23. package/src/migrations/update-21-5-0/utils/karma-config-comparer.d.ts.map +1 -0
  24. package/src/migrations/update-21-5-0/utils/karma-config-comparer.js +145 -0
  25. package/src/utils/backward-compatible-versions.d.ts +1 -1
  26. package/src/utils/backward-compatible-versions.d.ts.map +1 -1
  27. package/src/utils/backward-compatible-versions.js +0 -1
  28. package/src/utils/versions.d.ts +4 -5
  29. package/src/utils/versions.d.ts.map +1 -1
  30. package/src/utils/versions.js +5 -6
  31. package/spec/tsconfig.spec.tsbuildinfo +0 -1
package/migrations.json CHANGED
@@ -357,6 +357,23 @@
357
357
  "version": "21.5.0-beta.0",
358
358
  "description": "Set the 'tsConfig' option to build and test targets to help with Angular migration issues.",
359
359
  "factory": "./src/migrations/update-21-5-0/set-tsconfig-option"
360
+ },
361
+ "update-angular-cli-version-20-2-0": {
362
+ "cli": "nx",
363
+ "version": "21.5.0-beta.2",
364
+ "requires": {
365
+ "@angular/core": ">=20.2.0"
366
+ },
367
+ "description": "Update the @angular/cli package version to ~20.2.0.",
368
+ "factory": "./src/migrations/update-21-5-0/update-angular-cli"
369
+ },
370
+ "remove-default-karma-configuration-files": {
371
+ "version": "21.5.0-beta.2",
372
+ "requires": {
373
+ "@angular/core": ">=20.2.0"
374
+ },
375
+ "description": "Remove any Karma configuration files that only contain the default content. The default configuration is automatically available without a specific project configurationfile.",
376
+ "factory": "./src/migrations/update-21-5-0/remove-default-karma-configuration-files"
360
377
  }
361
378
  },
362
379
  "packageJsonUpdates": {
@@ -1915,6 +1932,158 @@
1915
1932
  "alwaysAddToPackageJson": false
1916
1933
  }
1917
1934
  }
1935
+ },
1936
+ "21.5.0": {
1937
+ "version": "21.5.0-beta.2",
1938
+ "x-prompt": "Do you want to update the Angular version to v20.2?",
1939
+ "requires": {
1940
+ "@angular/core": ">=20.1.0 <20.2.0"
1941
+ },
1942
+ "packages": {
1943
+ "@angular-devkit/build-angular": {
1944
+ "version": "~20.2.0",
1945
+ "alwaysAddToPackageJson": false
1946
+ },
1947
+ "@angular-devkit/core": {
1948
+ "version": "~20.2.0",
1949
+ "alwaysAddToPackageJson": false
1950
+ },
1951
+ "@angular-devkit/schematics": {
1952
+ "version": "~20.2.0",
1953
+ "alwaysAddToPackageJson": false
1954
+ },
1955
+ "@angular/build": {
1956
+ "version": "~20.2.0",
1957
+ "alwaysAddToPackageJson": false
1958
+ },
1959
+ "@angular/pwa": {
1960
+ "version": "~20.2.0",
1961
+ "alwaysAddToPackageJson": false
1962
+ },
1963
+ "@angular/ssr": {
1964
+ "version": "~20.2.0",
1965
+ "alwaysAddToPackageJson": false
1966
+ },
1967
+ "@schematics/angular": {
1968
+ "version": "~20.2.0",
1969
+ "alwaysAddToPackageJson": false
1970
+ },
1971
+ "@angular-devkit/architect": {
1972
+ "version": "~0.2002.0",
1973
+ "alwaysAddToPackageJson": false
1974
+ },
1975
+ "@angular-devkit/build-webpack": {
1976
+ "version": "~0.2002.0",
1977
+ "alwaysAddToPackageJson": false
1978
+ },
1979
+ "@angular/core": {
1980
+ "version": "~20.2.0",
1981
+ "alwaysAddToPackageJson": true
1982
+ },
1983
+ "@angular/material": {
1984
+ "version": "~20.2.0",
1985
+ "alwaysAddToPackageJson": false
1986
+ },
1987
+ "@angular/cdk": {
1988
+ "version": "~20.2.0",
1989
+ "alwaysAddToPackageJson": false
1990
+ },
1991
+ "@angular/google-maps": {
1992
+ "version": "~20.2.0",
1993
+ "alwaysAddToPackageJson": false
1994
+ },
1995
+ "ng-packagr": {
1996
+ "version": "~20.2.0",
1997
+ "alwaysAddToPackageJson": false
1998
+ }
1999
+ }
2000
+ },
2001
+ "21.5.0-angular-eslint": {
2002
+ "version": "21.5.0-beta.2",
2003
+ "requires": {
2004
+ "@angular/core": ">= 20.0.0 < 21.0.0",
2005
+ "typescript-eslint": "^8.0.0",
2006
+ "eslint": "^8.57.0 || ^9.0.0"
2007
+ },
2008
+ "packages": {
2009
+ "angular-eslint": {
2010
+ "version": "^20.2.0",
2011
+ "alwaysAddToPackageJson": false
2012
+ },
2013
+ "@angular-eslint/eslint-plugin": {
2014
+ "version": "^20.2.0",
2015
+ "alwaysAddToPackageJson": false
2016
+ },
2017
+ "@angular-eslint/eslint-plugin-template": {
2018
+ "version": "^20.2.0",
2019
+ "alwaysAddToPackageJson": false
2020
+ },
2021
+ "@angular-eslint/template-parser": {
2022
+ "version": "^20.2.0",
2023
+ "alwaysAddToPackageJson": false
2024
+ },
2025
+ "@angular-eslint/utils": {
2026
+ "version": "^20.2.0",
2027
+ "alwaysAddToPackageJson": false
2028
+ },
2029
+ "@angular-eslint/schematics": {
2030
+ "version": "^20.2.0",
2031
+ "alwaysAddToPackageJson": false
2032
+ },
2033
+ "@angular-eslint/test-utils": {
2034
+ "version": "^20.2.0",
2035
+ "alwaysAddToPackageJson": false
2036
+ },
2037
+ "@angular-eslint/builder": {
2038
+ "version": "^20.2.0",
2039
+ "alwaysAddToPackageJson": false
2040
+ },
2041
+ "@angular-eslint/bundled-angular-compiler": {
2042
+ "version": "^20.2.0",
2043
+ "alwaysAddToPackageJson": false
2044
+ }
2045
+ }
2046
+ },
2047
+ "21.5.0-@angular-eslint": {
2048
+ "version": "21.5.0-beta.2",
2049
+ "requires": {
2050
+ "@angular/core": ">= 20.0.0 < 21.0.0",
2051
+ "eslint": "^8.57.0 || ^9.0.0"
2052
+ },
2053
+ "packages": {
2054
+ "@angular-eslint/eslint-plugin": {
2055
+ "version": "^20.2.0",
2056
+ "alwaysAddToPackageJson": false
2057
+ },
2058
+ "@angular-eslint/eslint-plugin-template": {
2059
+ "version": "^20.2.0",
2060
+ "alwaysAddToPackageJson": false
2061
+ },
2062
+ "@angular-eslint/template-parser": {
2063
+ "version": "^20.2.0",
2064
+ "alwaysAddToPackageJson": false
2065
+ },
2066
+ "@angular-eslint/utils": {
2067
+ "version": "^20.2.0",
2068
+ "alwaysAddToPackageJson": false
2069
+ },
2070
+ "@angular-eslint/schematics": {
2071
+ "version": "^20.2.0",
2072
+ "alwaysAddToPackageJson": false
2073
+ },
2074
+ "@angular-eslint/test-utils": {
2075
+ "version": "^20.2.0",
2076
+ "alwaysAddToPackageJson": false
2077
+ },
2078
+ "@angular-eslint/builder": {
2079
+ "version": "^20.2.0",
2080
+ "alwaysAddToPackageJson": false
2081
+ },
2082
+ "@angular-eslint/bundled-angular-compiler": {
2083
+ "version": "^20.2.0",
2084
+ "alwaysAddToPackageJson": false
2085
+ }
2086
+ }
1918
2087
  }
1919
2088
  }
1920
2089
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/angular",
3
- "version": "21.5.0-beta.1",
3
+ "version": "21.5.0-beta.2",
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": {
@@ -58,14 +58,14 @@
58
58
  "migrations": "./migrations.json"
59
59
  },
60
60
  "dependencies": {
61
- "@nx/devkit": "21.5.0-beta.1",
62
- "@nx/eslint": "21.5.0-beta.1",
63
- "@nx/js": "21.5.0-beta.1",
64
- "@nx/module-federation": "21.5.0-beta.1",
65
- "@nx/rspack": "21.5.0-beta.1",
66
- "@nx/web": "21.5.0-beta.1",
67
- "@nx/webpack": "21.5.0-beta.1",
68
- "@nx/workspace": "21.5.0-beta.1",
61
+ "@nx/devkit": "21.5.0-beta.2",
62
+ "@nx/eslint": "21.5.0-beta.2",
63
+ "@nx/js": "21.5.0-beta.2",
64
+ "@nx/module-federation": "21.5.0-beta.2",
65
+ "@nx/rspack": "21.5.0-beta.2",
66
+ "@nx/web": "21.5.0-beta.2",
67
+ "@nx/webpack": "21.5.0-beta.2",
68
+ "@nx/workspace": "21.5.0-beta.2",
69
69
  "@phenomnomnominal/tsquery": "~5.0.1",
70
70
  "@typescript-eslint/type-utils": "^8.0.0",
71
71
  "enquirer": "~2.3.6",
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=remove-default-karma-configuration-files.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-default-karma-configuration-files.spec.d.ts","sourceRoot":"","sources":["../../../../../../../packages/angular/src/migrations/update-21-5-0/remove-default-karma-configuration-files.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=update-angular-cli.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-angular-cli.spec.d.ts","sourceRoot":"","sources":["../../../../../../../packages/angular/src/migrations/update-21-5-0/update-angular-cli.spec.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"convert-to-rspack.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/generators/convert-to-rspack/convert-to-rspack.ts"],"names":[],"mappings":"AAAA,OAAO,EAcL,KAAK,iBAAiB,EAEtB,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAiBpB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AA6StD,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,qBAAqB,8BA+X9B;AAED,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"convert-to-rspack.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/generators/convert-to-rspack/convert-to-rspack.ts"],"names":[],"mappings":"AAAA,OAAO,EAcL,KAAK,iBAAiB,EAEtB,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAapB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AA6StD,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,qBAAqB,8BAuY9B;AAED,eAAe,eAAe,CAAC"}
@@ -8,6 +8,7 @@ const enquirer_1 = require("enquirer");
8
8
  const path_1 = require("path");
9
9
  const posix_1 = require("path/posix");
10
10
  const versions_1 = require("../../utils/versions");
11
+ const version_utils_1 = require("../utils/version-utils");
11
12
  const create_config_1 = require("./lib/create-config");
12
13
  const get_custom_webpack_config_1 = require("./lib/get-custom-webpack-config");
13
14
  const update_tsconfig_1 = require("./lib/update-tsconfig");
@@ -249,6 +250,10 @@ async function convertToRspack(tree, schema) {
249
250
  const targetsToRemove = [];
250
251
  let customWebpackConfigPath;
251
252
  (0, validate_supported_executor_1.validateSupportedBuildExecutor)(Object.values(project.targets));
253
+ const angularRspackVersion = (0, version_utils_1.getAngularRspackVersion)(tree);
254
+ if (!angularRspackVersion) {
255
+ throw new Error('Angular Rspack requires Angular 19 or higher. Please upgrade your Angular version before converting to Rspack.');
256
+ }
252
257
  let projectServePort = DEFAULT_PORT;
253
258
  for (const [targetName, target] of Object.entries(project.targets)) {
254
259
  if (target.executor === '@angular-devkit/build-angular:browser' ||
@@ -491,10 +496,11 @@ async function convertToRspack(tree, schema) {
491
496
  (0, devkit_1.writeJson)(tree, 'package.json', rootPkgJson);
492
497
  }
493
498
  if (!schema.skipInstall) {
499
+ const { webpackMergeVersion, tsNodeVersion } = (0, version_utils_1.versions)(tree);
494
500
  const installTask = (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
495
- '@nx/angular-rspack': versions_1.angularRspackVersion,
496
- 'webpack-merge': versions_1.webpackMergeVersion,
497
- 'ts-node': versions_1.tsNodeVersion,
501
+ '@nx/angular-rspack': angularRspackVersion,
502
+ 'webpack-merge': webpackMergeVersion,
503
+ 'ts-node': tsNodeVersion,
498
504
  });
499
505
  tasks.push(installTask);
500
506
  }
@@ -20,12 +20,12 @@ function fixBootstrap(tree, appRoot, options) {
20
20
  if (tree.exists((0, devkit_1.joinPathFragments)(appRoot, 'public/module-federation.manifest.json'))) {
21
21
  manifestPath = '/module-federation.manifest.json';
22
22
  }
23
- const fetchMFManifestCode = `import { init } from '@module-federation/enhanced/runtime';
23
+ const fetchMFManifestCode = `import { registerRemotes } from '@module-federation/enhanced/runtime';
24
24
 
25
25
  fetch('${manifestPath}')
26
26
  .then((res) => res.json())
27
27
  .then((remotes: Record<string, string>) => Object.entries(remotes).map(([name, entry]) => ({ name,entry})))
28
- .then(remotes => init({name: '${options.appName}', remotes}))
28
+ .then(remotes => registerRemotes(remotes))
29
29
  .then(() => ${bootstrapImportCode});`;
30
30
  tree.write(mainFilePath, fetchMFManifestCode);
31
31
  }
@@ -13,4 +13,9 @@ export declare function getInstalledPackageVersionInfo(tree: Tree, pkgName: stri
13
13
  version: string;
14
14
  };
15
15
  export declare function versions(tree: Tree): PackageLatestVersions | PackageCompatVersions;
16
+ /**
17
+ * Temporary helper to abstract away the version of angular-rspack to be installed
18
+ * until we stop supporting Angular 19.
19
+ */
20
+ export declare function getAngularRspackVersion(tree: Tree): string | null;
16
21
  //# sourceMappingURL=version-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version-utils.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/generators/utils/version-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,0CAA0C,CAAC;AAIlD,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAK1E;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAgB7D;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAElE;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,IAAI;;;EAOxD;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM;;;EAIzE;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,IAAI,GACT,qBAAqB,GAAG,qBAAqB,CAU/C"}
1
+ {"version":3,"file":"version-utils.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/generators/utils/version-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,0CAA0C,CAAC;AAIlD,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAK1E;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAgB7D;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAElE;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,IAAI;;;EAOxD;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM;;;EAIzE;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,IAAI,GACT,qBAAqB,GAAG,qBAAqB,CAU/C;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAcjE"}
@@ -7,6 +7,7 @@ exports.getInstalledAngularVersionInfo = getInstalledAngularVersionInfo;
7
7
  exports.getInstalledPackageVersion = getInstalledPackageVersion;
8
8
  exports.getInstalledPackageVersionInfo = getInstalledPackageVersionInfo;
9
9
  exports.versions = versions;
10
+ exports.getAngularRspackVersion = getAngularRspackVersion;
10
11
  const tslib_1 = require("tslib");
11
12
  const devkit_1 = require("@nx/devkit");
12
13
  const semver_1 = require("semver");
@@ -57,3 +58,20 @@ function versions(tree) {
57
58
  return latestVersions;
58
59
  }
59
60
  }
61
+ /**
62
+ * Temporary helper to abstract away the version of angular-rspack to be installed
63
+ * until we stop supporting Angular 19.
64
+ */
65
+ function getAngularRspackVersion(tree) {
66
+ const majorAngularVersion = getInstalledAngularMajorVersion(tree);
67
+ if (majorAngularVersion === 19) {
68
+ return backward_compatible_versions_1.backwardCompatibleVersions.angularV19.angularRspackVersion;
69
+ }
70
+ if (majorAngularVersion >= 20) {
71
+ // Starting with Angular 20, we can use an Angular Rspack version that is
72
+ // aligned with the Nx version
73
+ return latestVersions.nxVersion;
74
+ }
75
+ // Lower versions of Angular are not supported
76
+ return null;
77
+ }
@@ -0,0 +1,3 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<void>;
3
+ //# sourceMappingURL=remove-default-karma-configuration-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-default-karma-configuration-files.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/migrations/update-21-5-0/remove-default-karma-configuration-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAQpB,yBAA+B,IAAI,EAAE,IAAI,iBA4DxC"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const targets_1 = require("../../utils/targets");
6
+ const karma_config_analyzer_1 = require("./utils/karma-config-analyzer");
7
+ const karma_config_comparer_1 = require("./utils/karma-config-comparer");
8
+ async function default_1(tree) {
9
+ const removableKarmaConfigs = new Map();
10
+ const projects = (0, devkit_1.getProjects)(tree);
11
+ for (const [projectName, project] of projects) {
12
+ for (const [, target] of (0, targets_1.allProjectTargets)(project)) {
13
+ let needDevkitPlugin = false;
14
+ switch (target.executor) {
15
+ case '@angular-devkit/build-angular:karma':
16
+ needDevkitPlugin = true;
17
+ break;
18
+ case '@angular/build:karma':
19
+ break;
20
+ default:
21
+ continue;
22
+ }
23
+ for (const [, options] of (0, targets_1.allTargetOptions)(target)) {
24
+ const karmaConfig = options['karmaConfig'];
25
+ if (typeof karmaConfig !== 'string') {
26
+ continue;
27
+ }
28
+ let isRemovable = removableKarmaConfigs.get(karmaConfig);
29
+ if (isRemovable === undefined && tree.exists(karmaConfig)) {
30
+ const content = tree.read(karmaConfig, 'utf-8');
31
+ const analysis = (0, karma_config_analyzer_1.analyzeKarmaConfig)(content);
32
+ if (analysis.hasUnsupportedValues) {
33
+ // Cannot safely determine if the file is removable.
34
+ isRemovable = false;
35
+ }
36
+ else {
37
+ const diff = await (0, karma_config_comparer_1.compareKarmaConfigToDefault)(analysis, projectName, karmaConfig, needDevkitPlugin);
38
+ isRemovable = !(0, karma_config_comparer_1.hasDifferences)(diff) && diff.isReliable;
39
+ }
40
+ removableKarmaConfigs.set(karmaConfig, isRemovable);
41
+ if (isRemovable) {
42
+ tree.delete(karmaConfig);
43
+ }
44
+ }
45
+ if (isRemovable) {
46
+ delete options['karmaConfig'];
47
+ (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ await (0, devkit_1.formatFiles)(tree);
53
+ }
@@ -0,0 +1,4 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export declare const angularCliVersion = "~20.2.0";
3
+ export default function (tree: Tree): Promise<void>;
4
+ //# sourceMappingURL=update-angular-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-angular-cli.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/migrations/update-21-5-0/update-angular-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAc,MAAM,YAAY,CAAC;AAE3D,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C,yBAA+B,IAAI,EAAE,IAAI,iBAkBxC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.angularCliVersion = void 0;
4
+ exports.default = default_1;
5
+ const devkit_1 = require("@nx/devkit");
6
+ exports.angularCliVersion = '~20.2.0';
7
+ async function default_1(tree) {
8
+ let shouldFormat = false;
9
+ (0, devkit_1.updateJson)(tree, 'package.json', (json) => {
10
+ if (json.devDependencies?.['@angular/cli']) {
11
+ json.devDependencies['@angular/cli'] = exports.angularCliVersion;
12
+ shouldFormat = true;
13
+ }
14
+ else if (json.dependencies?.['@angular/cli']) {
15
+ json.dependencies['@angular/cli'] = exports.angularCliVersion;
16
+ shouldFormat = true;
17
+ }
18
+ return json;
19
+ });
20
+ if (shouldFormat) {
21
+ await (0, devkit_1.formatFiles)(tree);
22
+ }
23
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.dev/license
7
+ */
8
+ export interface RequireInfo {
9
+ module: string;
10
+ export?: string;
11
+ isCall?: boolean;
12
+ arguments?: KarmaConfigValue[];
13
+ }
14
+ export type KarmaConfigValue = string | boolean | number | KarmaConfigValue[] | {
15
+ [key: string]: KarmaConfigValue;
16
+ } | RequireInfo | undefined;
17
+ export interface KarmaConfigAnalysis {
18
+ settings: Map<string, KarmaConfigValue>;
19
+ hasUnsupportedValues: boolean;
20
+ }
21
+ /**
22
+ * Analyzes the content of a Karma configuration file to extract its settings.
23
+ *
24
+ * @param content The string content of the `karma.conf.js` file.
25
+ * @returns An object containing the configuration settings and a flag indicating if unsupported values were found.
26
+ */
27
+ export declare function analyzeKarmaConfig(content: string): KarmaConfigAnalysis;
28
+ //# sourceMappingURL=karma-config-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"karma-config-analyzer.d.ts","sourceRoot":"","sources":["../../../../../../../packages/angular/src/migrations/update-21-5-0/utils/karma-config-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqBH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,OAAO,GACP,MAAM,GACN,gBAAgB,EAAE,GAClB;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAAA;CAAE,GACnC,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACxC,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAID;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CA+HvE"}
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.dev/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.analyzeKarmaConfig = analyzeKarmaConfig;
11
+ /**
12
+ * Adapts the private utility from Angular CLI to be used in the migration.
13
+ */
14
+ const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
15
+ let ts;
16
+ /**
17
+ * Analyzes the content of a Karma configuration file to extract its settings.
18
+ *
19
+ * @param content The string content of the `karma.conf.js` file.
20
+ * @returns An object containing the configuration settings and a flag indicating if unsupported values were found.
21
+ */
22
+ function analyzeKarmaConfig(content) {
23
+ if (!ts) {
24
+ ts = (0, ensure_typescript_1.ensureTypescript)();
25
+ }
26
+ const sourceFile = ts.createSourceFile('karma.conf.js', content, ts.ScriptTarget.Latest, true);
27
+ const settings = new Map();
28
+ let hasUnsupportedValues = false;
29
+ function visit(node) {
30
+ // The Karma configuration is defined within a `config.set({ ... })` call.
31
+ if (ts.isCallExpression(node) &&
32
+ ts.isPropertyAccessExpression(node.expression) &&
33
+ node.expression.expression.getText(sourceFile) === 'config' &&
34
+ node.expression.name.text === 'set' &&
35
+ node.arguments.length === 1 &&
36
+ ts.isObjectLiteralExpression(node.arguments[0])) {
37
+ // We found `config.set`, now we extract the properties from the object literal.
38
+ for (const prop of node.arguments[0].properties) {
39
+ if (isSupportedPropertyAssignment(prop)) {
40
+ const key = prop.name.text;
41
+ const value = extractValue(prop.initializer);
42
+ settings.set(key, value);
43
+ }
44
+ else {
45
+ hasUnsupportedValues = true;
46
+ }
47
+ }
48
+ }
49
+ else {
50
+ ts.forEachChild(node, visit);
51
+ }
52
+ }
53
+ function extractValue(node) {
54
+ switch (node.kind) {
55
+ case ts.SyntaxKind.StringLiteral:
56
+ return node.text;
57
+ case ts.SyntaxKind.NumericLiteral:
58
+ return Number(node.text);
59
+ case ts.SyntaxKind.TrueKeyword:
60
+ return true;
61
+ case ts.SyntaxKind.FalseKeyword:
62
+ return false;
63
+ case ts.SyntaxKind.Identifier: {
64
+ const identifier = node.text;
65
+ if (identifier === '__dirname' || identifier === '__filename') {
66
+ return identifier;
67
+ }
68
+ break;
69
+ }
70
+ case ts.SyntaxKind.CallExpression: {
71
+ const callExpr = node;
72
+ // Handle require('...')
73
+ if (ts.isIdentifier(callExpr.expression) &&
74
+ callExpr.expression.text === 'require' &&
75
+ callExpr.arguments.length === 1 &&
76
+ ts.isStringLiteral(callExpr.arguments[0])) {
77
+ return { module: callExpr.arguments[0].text };
78
+ }
79
+ // Handle calls on a require, e.g. require('path').join()
80
+ const calleeValue = extractValue(callExpr.expression);
81
+ if (isRequireInfo(calleeValue)) {
82
+ return {
83
+ ...calleeValue,
84
+ isCall: true,
85
+ arguments: callExpr.arguments.map(extractValue),
86
+ };
87
+ }
88
+ break;
89
+ }
90
+ case ts.SyntaxKind.PropertyAccessExpression: {
91
+ const propAccessExpr = node;
92
+ // Handle config constants like `config.LOG_INFO`
93
+ if (ts.isIdentifier(propAccessExpr.expression) &&
94
+ propAccessExpr.expression.text === 'config') {
95
+ return `config.${propAccessExpr.name.text}`;
96
+ }
97
+ const value = extractValue(propAccessExpr.expression);
98
+ if (isRequireInfo(value)) {
99
+ const currentExport = value.export
100
+ ? `${value.export}.${propAccessExpr.name.text}`
101
+ : propAccessExpr.name.text;
102
+ return { ...value, export: currentExport };
103
+ }
104
+ break;
105
+ }
106
+ case ts.SyntaxKind.ArrayLiteralExpression:
107
+ return node.elements.map(extractValue);
108
+ case ts.SyntaxKind.ObjectLiteralExpression: {
109
+ const obj = {};
110
+ for (const prop of node.properties) {
111
+ if (isSupportedPropertyAssignment(prop)) {
112
+ // Recursively extract values for nested objects.
113
+ obj[prop.name.text] = extractValue(prop.initializer);
114
+ }
115
+ else {
116
+ hasUnsupportedValues = true;
117
+ }
118
+ }
119
+ return obj;
120
+ }
121
+ }
122
+ // For complex expressions (like variables) that we don't need to resolve,
123
+ // we mark the analysis as potentially incomplete.
124
+ hasUnsupportedValues = true;
125
+ return undefined;
126
+ }
127
+ visit(sourceFile);
128
+ return { settings, hasUnsupportedValues };
129
+ }
130
+ function isRequireInfo(value) {
131
+ return (typeof value === 'object' &&
132
+ value !== null &&
133
+ !Array.isArray(value) &&
134
+ 'module' in value);
135
+ }
136
+ function isSupportedPropertyAssignment(prop) {
137
+ return (ts.isPropertyAssignment(prop) &&
138
+ (ts.isIdentifier(prop.name) || ts.isStringLiteral(prop.name)));
139
+ }