@nx/angular 23.0.0 → 23.1.0-beta.1

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 (114) hide show
  1. package/README.md +1 -2
  2. package/dist/src/builders/dev-server/schema.json +2 -2
  3. package/dist/src/builders/webpack-browser/webpack-browser.impl.js +1 -1
  4. package/dist/src/executors/application/application.impl.js +3 -14
  5. package/dist/src/executors/application/schema.json +9 -3
  6. package/dist/src/executors/application/utils/normalize-options.js +19 -8
  7. package/dist/src/executors/application/utils/validate-options.js +0 -10
  8. package/dist/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/entry-point.d.ts +1 -1
  9. package/dist/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/entry-point.js +4 -21
  10. package/dist/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/write-bundles.di.d.ts +1 -1
  11. package/dist/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/write-bundles.di.js +6 -9
  12. package/dist/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/write-bundles.transform.js +7 -10
  13. package/dist/src/executors/unit-test/schema.json +8 -0
  14. package/dist/src/executors/unit-test/unit-test.impl.d.ts +1 -2
  15. package/dist/src/executors/unit-test/unit-test.impl.js +8 -0
  16. package/dist/src/executors/utilities/esbuild-extensions.js +17 -3
  17. package/dist/src/executors/utilities/ng-packagr/stylesheet-processor.di.js +2 -5
  18. package/dist/src/executors/utilities/ng-packagr/stylesheet-processor.js +11 -19
  19. package/dist/src/executors/utilities/typescript.js +2 -4
  20. package/dist/src/generators/application/application.js +11 -15
  21. package/dist/src/generators/application/files/base/tsconfig.app.json__tpl__ +0 -5
  22. package/dist/src/generators/application/files/base/tsconfig.json__tpl__ +1 -4
  23. package/dist/src/generators/application/files/ng-module/src/app/app__componentFileSuffix__.spec.ts__tpl__ +1 -7
  24. package/dist/src/generators/application/files/ng-module/src/app/app__componentFileSuffix__.ts__tpl__ +1 -1
  25. package/dist/src/generators/application/files/ng-module/src/app/app__moduleTypeSeparator__module.ts__tpl__ +2 -2
  26. package/dist/src/generators/application/files/ng-module/src/main.ts__tpl__ +0 -8
  27. package/dist/src/generators/application/files/standalone-components/src/app/app.config.ts__tpl__ +3 -3
  28. package/dist/src/generators/application/files/standalone-components/src/app/app__componentFileSuffix__.spec.ts__tpl__ +1 -7
  29. package/dist/src/generators/application/files/standalone-components/src/app/app__componentFileSuffix__.ts__tpl__ +1 -1
  30. package/dist/src/generators/application/lib/create-files.js +0 -8
  31. package/dist/src/generators/application/lib/create-project.js +3 -12
  32. package/dist/src/generators/application/lib/update-tsconfig-files.js +6 -36
  33. package/dist/src/generators/application/schema.d.ts +0 -1
  34. package/dist/src/generators/application/schema.json +0 -4
  35. package/dist/src/generators/component/component.js +1 -0
  36. package/dist/src/generators/component/files/__fileName__.ts__tpl__ +3 -2
  37. package/dist/src/generators/component/lib/index.d.ts +1 -0
  38. package/dist/src/generators/component/lib/index.js +1 -0
  39. package/dist/src/generators/component/lib/normalize-options.js +2 -4
  40. package/dist/src/generators/component/lib/validate-options.d.ts +3 -0
  41. package/dist/src/generators/component/lib/validate-options.js +10 -0
  42. package/dist/src/generators/component/schema.d.ts +1 -1
  43. package/dist/src/generators/component/schema.json +3 -4
  44. package/dist/src/generators/convert-to-application-executor/convert-to-application-executor.js +1 -6
  45. package/dist/src/generators/convert-to-rspack/convert-to-rspack.js +1 -2
  46. package/dist/src/generators/directive/lib/normalize-options.js +0 -5
  47. package/dist/src/generators/directive/schema.json +1 -1
  48. package/dist/src/generators/library/lib/normalized-schema.d.ts +1 -1
  49. package/dist/src/generators/library/lib/update-tsconfig-files.js +6 -14
  50. package/dist/src/generators/library/schema.d.ts +1 -1
  51. package/dist/src/generators/library/schema.json +2 -3
  52. package/dist/src/generators/pipe/lib/normalize-options.js +1 -3
  53. package/dist/src/generators/pipe/schema.json +1 -1
  54. package/dist/src/generators/remote/lib/update-ssr-setup.js +1 -4
  55. package/dist/src/generators/scam/lib/normalize-options.js +0 -5
  56. package/dist/src/generators/scam/schema.d.ts +1 -1
  57. package/dist/src/generators/scam/schema.json +3 -4
  58. package/dist/src/generators/scam-directive/lib/normalize-options.js +0 -5
  59. package/dist/src/generators/scam-directive/schema.json +1 -1
  60. package/dist/src/generators/scam-pipe/lib/normalize-options.js +1 -3
  61. package/dist/src/generators/scam-pipe/schema.json +1 -1
  62. package/dist/src/generators/setup-mf/setup-mf.js +4 -7
  63. package/dist/src/generators/setup-ssr/lib/add-dependencies.js +1 -4
  64. package/dist/src/generators/setup-ssr/lib/add-server-file.js +3 -13
  65. package/dist/src/generators/setup-ssr/lib/generate-files.js +5 -27
  66. package/dist/src/generators/setup-ssr/lib/generate-server-ts-config.js +11 -20
  67. package/dist/src/generators/setup-ssr/lib/normalize-options.js +0 -17
  68. package/dist/src/generators/setup-ssr/lib/update-project-config.js +1 -6
  69. package/dist/src/generators/setup-ssr/lib/validate-options.js +0 -14
  70. package/dist/src/generators/setup-ssr/schema.d.ts +0 -1
  71. package/dist/src/generators/setup-ssr/schema.json +0 -4
  72. package/dist/src/generators/utils/app-components-info.js +1 -5
  73. package/dist/src/generators/utils/artifact-types.js +2 -10
  74. package/dist/src/generators/utils/ensure-angular-dependencies.js +0 -5
  75. package/dist/src/generators/utils/update-project-root-tsconfig.js +4 -4
  76. package/dist/src/generators/utils/version-utils.d.ts +0 -5
  77. package/dist/src/generators/utils/version-utils.js +0 -13
  78. package/dist/src/migrations/update-23-1-0/add-istanbul-instrumenter.d.ts +2 -0
  79. package/dist/src/migrations/update-23-1-0/add-istanbul-instrumenter.js +56 -0
  80. package/dist/src/migrations/update-23-1-0/add-istanbul-instrumenter.md +65 -0
  81. package/dist/src/migrations/update-23-1-0/add-trust-proxy-headers.d.ts +2 -0
  82. package/dist/src/migrations/update-23-1-0/add-trust-proxy-headers.js +61 -0
  83. package/dist/src/migrations/update-23-1-0/add-trust-proxy-headers.md +48 -0
  84. package/dist/src/migrations/update-23-1-0/rename-ssr-experimental-platform.d.ts +2 -0
  85. package/dist/src/migrations/update-23-1-0/rename-ssr-experimental-platform.js +70 -0
  86. package/dist/src/migrations/update-23-1-0/rename-ssr-experimental-platform.md +85 -0
  87. package/dist/src/utils/backward-compatible-versions.d.ts +2 -2
  88. package/dist/src/utils/backward-compatible-versions.js +23 -24
  89. package/dist/src/utils/versions.d.ts +7 -7
  90. package/dist/src/utils/versions.js +7 -7
  91. package/dist/src/utils/zoneless.d.ts +1 -1
  92. package/dist/types/nx-angular-mf.d.ts.map +1 -1
  93. package/dist/types/nx-angular.d.ts.map +1 -1
  94. package/migrations.json +188 -0
  95. package/package.json +18 -17
  96. package/dist/src/executors/extract-i18n/utils/validate-options.d.ts +0 -2
  97. package/dist/src/executors/extract-i18n/utils/validate-options.js +0 -13
  98. package/dist/src/executors/utilities/ng-packagr/package-imports.d.ts +0 -3
  99. package/dist/src/executors/utilities/ng-packagr/package-imports.js +0 -10
  100. package/dist/src/generators/application/files/base/tsconfig.editor.json__tpl__ +0 -5
  101. package/dist/src/generators/setup-ssr/files/v19/application-builder/ngmodule-src/__main__ +0 -1
  102. package/dist/src/generators/setup-ssr/files/v19/application-builder/ngmodule-src/app/__rootModuleFileName__ +0 -13
  103. package/dist/src/generators/setup-ssr/files/v19/application-builder/ngmodule-src/app/app.routes.server.ts__tpl__ +0 -8
  104. package/dist/src/generators/setup-ssr/files/v19/application-builder/server/__serverFileName__ +0 -66
  105. package/dist/src/generators/setup-ssr/files/v19/application-builder/standalone-src/__main__ +0 -12
  106. package/dist/src/generators/setup-ssr/files/v19/application-builder/standalone-src/app/app.config.server.ts__tpl__ +0 -14
  107. package/dist/src/generators/setup-ssr/files/v19/application-builder/standalone-src/app/app.routes.server.ts__tpl__ +0 -8
  108. package/dist/src/generators/setup-ssr/files/v19/application-builder-common-engine/server/__serverFileName__ +0 -67
  109. package/dist/src/generators/setup-ssr/files/v19/server-builder/ngmodule-src/__main__ +0 -1
  110. package/dist/src/generators/setup-ssr/files/v19/server-builder/ngmodule-src/app/__rootModuleFileName__ +0 -14
  111. package/dist/src/generators/setup-ssr/files/v19/server-builder/root/tsconfig.server.json.template +0 -16
  112. package/dist/src/generators/setup-ssr/files/v19/server-builder/server/__serverFileName__ +0 -69
  113. package/dist/src/generators/setup-ssr/files/v19/server-builder/standalone-src/__main__ +0 -12
  114. package/dist/src/generators/setup-ssr/files/v19/server-builder/standalone-src/app/app.config.server.ts.template +0 -11
@@ -16,44 +16,22 @@ function generateSSRFiles(tree, options) {
16
16
  // server has already been added
17
17
  return;
18
18
  }
19
- const { major: angularMajorVersion, version: angularVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
20
- const baseFilesPath = (0, path_1.join)(__dirname, '..', 'files');
21
- let pathToFiles;
22
- if (angularMajorVersion >= 20) {
23
- pathToFiles = (0, path_1.join)(baseFilesPath, 'v20+', options.isUsingApplicationBuilder
24
- ? 'application-builder'
25
- : 'server-builder', options.standalone ? 'standalone-src' : 'ngmodule-src');
26
- }
27
- else {
28
- pathToFiles = (0, path_1.join)(baseFilesPath, 'v19', options.isUsingApplicationBuilder
29
- ? 'application-builder'
30
- : 'server-builder', options.standalone ? 'standalone-src' : 'ngmodule-src');
31
- }
19
+ const { version: angularVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
20
+ const pathToFiles = (0, path_1.join)(__dirname, '..', 'files', 'v20+', options.isUsingApplicationBuilder
21
+ ? 'application-builder'
22
+ : 'server-builder', options.standalone ? 'standalone-src' : 'ngmodule-src');
32
23
  const sourceRoot = (0, internal_1.getProjectSourceRoot)(project, tree);
33
- const ssrVersion = (0, devkit_1.getDependencyVersionFromPackageJson)(tree, '@angular/ssr');
34
- const cleanedSsrVersion = ssrVersion
35
- ? ((0, semver_1.clean)(ssrVersion) ?? (0, semver_1.coerce)(ssrVersion).version)
36
- : null;
37
24
  const componentType = (0, artifact_types_1.getComponentType)(tree);
38
25
  const appComponentInfo = (0, app_components_info_1.getAppComponentInfo)(tree, componentType ? `.${componentType}` : '', project);
39
26
  const moduleTypeSeparator = (0, artifact_types_1.getModuleTypeSeparator)(tree);
40
- const useBootstrapContext =
41
27
  // https://github.com/angular/angular-cli/releases/tag/20.3.0
42
- (0, semver_1.gte)(angularVersion, '20.3.0') ||
43
- // https://github.com/angular/angular-cli/releases/tag/19.2.16
44
- (angularMajorVersion === 19 && (0, semver_1.gte)(angularVersion, '19.2.16'));
28
+ const useBootstrapContext = (0, semver_1.gte)(angularVersion, '20.3.0');
45
29
  (0, devkit_1.generateFiles)(tree, pathToFiles, sourceRoot, {
46
30
  ...options,
47
- provideServerRoutingFn: !cleanedSsrVersion || (0, semver_1.gte)(cleanedSsrVersion, '19.2.0')
48
- ? 'provideServerRouting'
49
- : 'provideServerRoutesConfig',
50
31
  appFileName: appComponentInfo.extensionlessFileName,
51
32
  appSymbolName: appComponentInfo.symbolName,
52
33
  moduleTypeSeparator,
53
34
  useBootstrapContext,
54
35
  tpl: '',
55
36
  });
56
- if (angularMajorVersion === 19 && !options.serverRouting) {
57
- tree.delete((0, devkit_1.joinPathFragments)(sourceRoot, 'app/app.routes.server.ts'));
58
- }
59
37
  }
@@ -32,14 +32,7 @@ function generateTsConfigServerJsonForBrowserBuilder(tree, options) {
32
32
  const packageJson = (0, devkit_1.readJson)(tree, 'package.json');
33
33
  const hasLocalizePackage = !!packageJson.dependencies?.['@angular/localize'] ||
34
34
  !!packageJson.devDependencies?.['@angular/localize'];
35
- const baseFilesPath = (0, path_1.join)(__dirname, '..', 'files');
36
- let pathToFiles;
37
- if (angularMajorVersion >= 20) {
38
- pathToFiles = (0, path_1.join)(baseFilesPath, 'v20+', 'server-builder', 'root');
39
- }
40
- else {
41
- pathToFiles = (0, path_1.join)(baseFilesPath, 'v19', 'server-builder', 'root');
42
- }
35
+ const pathToFiles = (0, path_1.join)(__dirname, '..', 'files', 'v20+', 'server-builder', 'root');
43
36
  (0, devkit_1.generateFiles)(tree, pathToFiles, project.root, {
44
37
  ...options,
45
38
  rootOffset: (0, devkit_1.offsetFromRoot)(project.root),
@@ -54,18 +47,16 @@ function generateTsConfigServerJsonForBrowserBuilder(tree, options) {
54
47
  });
55
48
  return json;
56
49
  });
57
- if (angularMajorVersion >= 20) {
58
- (0, devkit_1.updateJson)(tree, options.buildTargetTsConfigPath, (json) => {
59
- const exclude = new Set(json.exclude ?? []);
60
- exclude.add(`src/${options.main}`);
61
- exclude.add(`src/${options.serverFileName}`);
62
- if (options.standalone) {
63
- exclude.add('src/app/app.config.server.ts');
64
- }
65
- json.exclude = Array.from(exclude);
66
- return json;
67
- });
68
- }
50
+ (0, devkit_1.updateJson)(tree, options.buildTargetTsConfigPath, (json) => {
51
+ const exclude = new Set(json.exclude ?? []);
52
+ exclude.add(`src/${options.main}`);
53
+ exclude.add(`src/${options.serverFileName}`);
54
+ if (options.standalone) {
55
+ exclude.add('src/app/app.config.server.ts');
56
+ }
57
+ json.exclude = Array.from(exclude);
58
+ return json;
59
+ });
69
60
  if (angularMajorVersion >= 21) {
70
61
  // remove module and moduleResolution from tsconfig.server.json
71
62
  (0, devkit_1.updateJson)(tree, tsconfigServerPath, (json) => {
@@ -1,29 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeOptions = normalizeOptions;
4
- const internal_1 = require("@nx/devkit/internal");
5
4
  const devkit_1 = require("@nx/devkit");
6
5
  const ast_utils_1 = require("../../../utils/nx-devkit/ast-utils");
7
- const version_utils_1 = require("../../utils/version-utils");
8
6
  async function normalizeOptions(tree, options) {
9
7
  const { targets, root } = (0, devkit_1.readProjectConfiguration)(tree, options.project);
10
8
  const isUsingApplicationBuilder = targets.build.executor === '@angular-devkit/build-angular:application' ||
11
9
  targets.build.executor === '@angular/build:application' ||
12
10
  targets.build.executor === '@nx/angular:application';
13
- if (options.serverRouting === undefined && isUsingApplicationBuilder) {
14
- const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
15
- if (angularMajorVersion === 19) {
16
- options.serverRouting = await (0, internal_1.promptWhenInteractive)({
17
- type: 'confirm',
18
- name: 'serverRouting',
19
- message: 'Would you like to use the Server Routing and App Engine APIs (Developer Preview) for this server application?',
20
- initial: false,
21
- }, { serverRouting: false }).then(({ serverRouting }) => serverRouting);
22
- }
23
- else {
24
- options.serverRouting = true;
25
- }
26
- }
27
11
  const isStandaloneApp = (0, ast_utils_1.isNgStandaloneApp)(tree, options.project);
28
12
  return {
29
13
  project: options.project,
@@ -36,7 +20,6 @@ async function normalizeOptions(tree, options) {
36
20
  skipFormat: options.skipFormat ?? false,
37
21
  standalone: options.standalone ?? isStandaloneApp,
38
22
  hydration: options.hydration ?? true,
39
- serverRouting: options.serverRouting,
40
23
  isUsingApplicationBuilder,
41
24
  buildTargetTsConfigPath: targets.build.options?.tsConfig ??
42
25
  (0, devkit_1.joinPathFragments)(root, 'tsconfig.app.json'),
@@ -35,12 +35,7 @@ function updateProjectConfigForApplicationBuilder(tree, options) {
35
35
  buildTarget.options.ssr = {
36
36
  entry: (0, devkit_1.joinPathFragments)(sourceRoot, options.serverFileName),
37
37
  };
38
- if (options.serverRouting) {
39
- buildTarget.options.outputMode = 'server';
40
- }
41
- else {
42
- buildTarget.options.prerender = true;
43
- }
38
+ buildTarget.options.outputMode = 'server';
44
39
  (0, devkit_1.updateProjectConfiguration)(tree, options.project, project);
45
40
  }
46
41
  function updateProjectConfigForBrowserBuilder(tree, options) {
@@ -3,23 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateOptions = validateOptions;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const validations_1 = require("../../utils/validations");
6
- const version_utils_1 = require("../../utils/version-utils");
7
6
  function validateOptions(tree, options) {
8
7
  validateProject(tree, options.project);
9
8
  validateBuildTarget(tree, options.project);
10
- const { major: angularMajorVersion, version: angularVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
11
- if (angularMajorVersion !== 19 && options.serverRouting !== undefined) {
12
- throw new Error(`The "serverRouting" option is only supported in Angular versions 19.x.x. You are using Angular ${angularVersion}.`);
13
- }
14
- if (options.serverRouting) {
15
- const { targets } = (0, devkit_1.readProjectConfiguration)(tree, options.project);
16
- const isUsingApplicationBuilder = targets.build.executor === '@angular-devkit/build-angular:application' ||
17
- targets.build.executor === '@angular/build:application' ||
18
- targets.build.executor === '@nx/angular:application';
19
- if (!isUsingApplicationBuilder) {
20
- throw new Error('Server routing APIs can only be added to a project using the "application" builder.');
21
- }
22
- }
23
9
  }
24
10
  function validateProject(tree, project) {
25
11
  (0, validations_1.validateProject)(tree, project);
@@ -8,7 +8,6 @@ export interface Schema {
8
8
  rootModuleClassName?: string;
9
9
  standalone?: boolean;
10
10
  hydration?: boolean;
11
- serverRouting?: boolean;
12
11
  skipFormat?: boolean;
13
12
  skipPackageJson?: boolean;
14
13
  }
@@ -52,10 +52,6 @@
52
52
  "description": "Set up Hydration for the SSR application.",
53
53
  "default": true
54
54
  },
55
- "serverRouting": {
56
- "description": "Creates a server application using the Server Routing and App Engine APIs for application using the `application` builder (Developer Preview). _Note: this is only supported in Angular versions 19.x.x_. From Angular 20 onwards, SSR will always enable server routing when using the `application` builder.",
57
- "type": "boolean"
58
- },
59
55
  "skipFormat": {
60
56
  "type": "boolean",
61
57
  "description": "Skip formatting the workspace after the generator completes.",
@@ -5,7 +5,6 @@ exports.getNxWelcomeComponentInfo = getNxWelcomeComponentInfo;
5
5
  const devkit_1 = require("@nx/devkit");
6
6
  const internal_1 = require("@nx/js/internal");
7
7
  const node_path_1 = require("node:path");
8
- const version_utils_1 = require("./version-utils");
9
8
  function getAppComponentInfo(tree, componentFileSuffix, project) {
10
9
  return getComponentInfo(tree, 'app', componentFileSuffix, project);
11
10
  }
@@ -25,10 +24,7 @@ function getComponentInfo(tree, component, componentFileSuffix, project) {
25
24
  }
26
25
  }
27
26
  if (!tree.exists(componentPath)) {
28
- const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
29
- componentPath = (0, devkit_1.joinPathFragments)(sourceRoot, angularMajorVersion >= 20
30
- ? `app/${component}.ts`
31
- : `app/${component}.component.ts`);
27
+ componentPath = (0, devkit_1.joinPathFragments)(sourceRoot, `app/${component}.ts`);
32
28
  }
33
29
  const fileName = (0, node_path_1.basename)(componentPath);
34
30
  const extensionlessFileName = fileName.slice(0, -3);
@@ -3,17 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getComponentType = getComponentType;
4
4
  exports.getModuleTypeSeparator = getModuleTypeSeparator;
5
5
  const devkit_1 = require("@nx/devkit");
6
- const version_utils_1 = require("./version-utils");
7
6
  function getComponentType(tree) {
8
7
  const nxJson = (0, devkit_1.readNxJson)(tree);
9
- let componentType = nxJson.generators?.['@nx/angular:component']?.type ??
8
+ const componentType = nxJson.generators?.['@nx/angular:component']?.type ??
10
9
  nxJson.generators?.['@nx/angular']?.component?.type;
11
- if (!componentType) {
12
- const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
13
- if (angularMajorVersion < 20) {
14
- componentType = 'component';
15
- }
16
- }
17
10
  return componentType;
18
11
  }
19
12
  function getModuleTypeSeparator(tree) {
@@ -26,8 +19,7 @@ function getModuleTypeSeparator(tree) {
26
19
  nxJson.generators?.['@schematics/angular:module']?.typeSeparator ??
27
20
  nxJson.generators?.['@schematics/angular']?.module?.typeSeparator;
28
21
  if (!typeSeparator) {
29
- const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
30
- typeSeparator = angularMajorVersion >= 20 ? '-' : '.';
22
+ typeSeparator = '-';
31
23
  }
32
24
  return typeSeparator;
33
25
  }
@@ -50,10 +50,5 @@ function ensureAngularDependencies(tree, zoneless) {
50
50
  const angularDevkitVersion = installedAngularDevkitVersion ?? pkgVersions.angularDevkitVersion;
51
51
  devDependencies['@angular-devkit/schematics'] = angularDevkitVersion;
52
52
  devDependencies['@schematics/angular'] = angularDevkitVersion;
53
- const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
54
- if (angularMajorVersion < 20) {
55
- devDependencies['@angular/build'] = angularDevkitVersion;
56
- devDependencies['@angular-devkit/build-angular'] = angularDevkitVersion;
57
- }
58
53
  return (0, devkit_1.addDependenciesToPackageJson)(tree, dependencies, devDependencies, undefined, true);
59
54
  }
@@ -3,16 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.extractTsConfigBase = void 0;
4
4
  exports.updateProjectRootTsConfig = updateProjectRootTsConfig;
5
5
  const devkit_1 = require("@nx/devkit");
6
- const js_1 = require("@nx/js");
7
- var js_2 = require("@nx/js");
8
- Object.defineProperty(exports, "extractTsConfigBase", { enumerable: true, get: function () { return js_2.extractTsConfigBase; } });
6
+ const internal_1 = require("@nx/js/internal");
7
+ var js_1 = require("@nx/js");
8
+ Object.defineProperty(exports, "extractTsConfigBase", { enumerable: true, get: function () { return js_1.extractTsConfigBase; } });
9
9
  function updateProjectRootTsConfig(host, projectRoot, relativePathToRootTsConfig, isRootProject) {
10
10
  (0, devkit_1.updateJson)(host, `${projectRoot}/tsconfig.json`, (json) => {
11
11
  if (isRootProject) {
12
12
  // inline tsconfig.base.json into the project
13
13
  json.compileOnSave = false;
14
14
  json.compilerOptions = {
15
- ...js_1.tsConfigBaseOptions,
15
+ ...(0, internal_1.getTsConfigBaseOptions)(host),
16
16
  ...json.compilerOptions,
17
17
  };
18
18
  json.exclude = ['node_modules', 'tmp'];
@@ -15,11 +15,6 @@ export declare function versions(tree: Tree): PackageCompatVersions;
15
15
  export declare function versions<V extends SupportedVersion>(tree: Tree, options: {
16
16
  minAngularMajorVersion: V;
17
17
  }): MinVersionReturnType<V>;
18
- /**
19
- * Temporary helper to abstract away the version of angular-rspack to be installed
20
- * until we stop supporting Angular 19.
21
- */
22
- export declare function getAngularRspackVersion(tree: Tree): string;
23
18
  type TakeUntil<Arr extends readonly any[], Target> = Arr extends readonly [
24
19
  infer Head,
25
20
  ...infer Rest
@@ -6,7 +6,6 @@ exports.getInstalledAngularMajorVersion = getInstalledAngularMajorVersion;
6
6
  exports.getInstalledAngularVersionInfo = getInstalledAngularVersionInfo;
7
7
  exports.getInstalledPackageVersionInfo = getInstalledPackageVersionInfo;
8
8
  exports.versions = versions;
9
- exports.getAngularRspackVersion = getAngularRspackVersion;
10
9
  const tslib_1 = require("tslib");
11
10
  const devkit_1 = require("@nx/devkit");
12
11
  const internal_1 = require("@nx/devkit/internal");
@@ -43,15 +42,3 @@ function versions(tree, options) {
43
42
  }
44
43
  return backward_compatible_versions_1.backwardCompatibleVersions[majorAngularVersion] ?? latestVersions;
45
44
  }
46
- /**
47
- * Temporary helper to abstract away the version of angular-rspack to be installed
48
- * until we stop supporting Angular 19.
49
- */
50
- function getAngularRspackVersion(tree) {
51
- const majorAngularVersion = getInstalledAngularMajorVersion(tree);
52
- // Starting with Angular 20, we can use an Angular Rspack version that is
53
- // aligned with the Nx version
54
- return majorAngularVersion === 19
55
- ? backward_compatible_versions_1.backwardCompatibleVersions[19].angularRspackVersion
56
- : latestVersions.nxVersion;
57
- }
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<import("@nx/devkit").GeneratorCallback>;
@@ -0,0 +1,56 @@
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
+ // In v22 `istanbul-lib-instrument` is an optional peer dependency of
7
+ // `@angular/build` used to instrument code for Karma coverage. Optional peers
8
+ // are not installed automatically, so it must be added when Karma is in use.
9
+ // Inlined here (not in `versions.ts`) because no generator installs it; only
10
+ // this migration does. Mirrors Angular's `add-istanbul-instrumenter`.
11
+ const istanbulLibInstrumentVersion = '^6.0.3';
12
+ const karmaBuilders = [
13
+ '@angular-devkit/build-angular:karma',
14
+ '@angular/build:karma',
15
+ ];
16
+ const unitTestBuilders = ['@angular/build:unit-test', '@nx/angular:unit-test'];
17
+ // A target uses Karma when its builder is a Karma builder, or it's a unit-test
18
+ // builder with `runner: karma` (in options or any configuration). `executors`
19
+ // holds the candidate executor ids: a target's own executor, or those a project
20
+ // `test` target inherits from an nx.json targetDefault (keyed by target name or
21
+ // by executor).
22
+ function usesKarma(executors, target) {
23
+ if (executors.some((e) => karmaBuilders.includes(e))) {
24
+ return true;
25
+ }
26
+ if (executors.some((e) => unitTestBuilders.includes(e))) {
27
+ for (const [, options] of (0, targets_1.allTargetOptions)(target)) {
28
+ if (options?.runner === 'karma') {
29
+ return true;
30
+ }
31
+ }
32
+ }
33
+ return false;
34
+ }
35
+ async function default_1(tree) {
36
+ let needsInstrumenter = false;
37
+ // project.json targets
38
+ for (const [, project] of (0, devkit_1.getProjects)(tree)) {
39
+ needsInstrumenter = Object.values(project.targets ?? {}).some((target) => usesKarma([target.executor], target));
40
+ if (needsInstrumenter) {
41
+ break;
42
+ }
43
+ }
44
+ // nx.json targetDefaults: a project's empty `test` target can inherit a Karma
45
+ // executor/runner from a default.
46
+ if (!needsInstrumenter) {
47
+ const targetDefaults = (0, devkit_1.readNxJson)(tree)?.targetDefaults;
48
+ if (targetDefaults) {
49
+ needsInstrumenter = Object.entries(targetDefaults).some(([targetOrExecutor, config]) => usesKarma([targetOrExecutor, config.executor], config));
50
+ }
51
+ }
52
+ if (!needsInstrumenter) {
53
+ return;
54
+ }
55
+ return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { 'istanbul-lib-instrument': istanbulLibInstrumentVersion }, undefined, true);
56
+ }
@@ -0,0 +1,65 @@
1
+ #### Add `istanbul-lib-instrument` for Karma Coverage
2
+
3
+ Angular v22 makes `istanbul-lib-instrument` an optional peer dependency of `@angular/build`, used to instrument code for Karma coverage. Since optional peers are not installed automatically, this migration adds `istanbul-lib-instrument` to `devDependencies` when the workspace has a project that runs unit tests with Karma, so Karma coverage keeps working. An existing version is preserved.
4
+
5
+ Karma usage is detected on any target using the `@angular-devkit/build-angular:karma` or `@angular/build:karma` builders, or the `@angular/build:unit-test` / `@nx/angular:unit-test` executors with the `runner` option set to `karma`. Targets that inherit their executor or `runner` from an `nx.json` `targetDefaults` entry are detected too.
6
+
7
+ #### Examples
8
+
9
+ ##### `project.json`
10
+
11
+ Before:
12
+
13
+ ```jsonc {5}
14
+ // project.json
15
+ {
16
+ "targets": {
17
+ "test": {
18
+ "executor": "@nx/angular:unit-test",
19
+ "options": {
20
+ "runner": "karma",
21
+ },
22
+ },
23
+ },
24
+ }
25
+ ```
26
+
27
+ After (`package.json`):
28
+
29
+ ```jsonc {4}
30
+ // package.json
31
+ {
32
+ "devDependencies": {
33
+ "istanbul-lib-instrument": "^6.0.3",
34
+ },
35
+ }
36
+ ```
37
+
38
+ ##### `nx.json` (`targetDefaults`)
39
+
40
+ A project whose `test` target inherits its executor and `runner` from an `nx.json` `targetDefaults` entry is also detected:
41
+
42
+ ```jsonc {7}
43
+ // nx.json
44
+ {
45
+ "targetDefaults": {
46
+ "test": {
47
+ "executor": "@nx/angular:unit-test",
48
+ "options": {
49
+ "runner": "karma",
50
+ },
51
+ },
52
+ },
53
+ }
54
+ ```
55
+
56
+ ```jsonc
57
+ // apps/app1/project.json
58
+ {
59
+ "targets": {
60
+ "test": {},
61
+ },
62
+ }
63
+ ```
64
+
65
+ `istanbul-lib-instrument` is added to `package.json` as shown above.
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<void>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const ts = tslib_1.__importStar(require("typescript"));
7
+ const file_change_recorder_1 = require("../../utils/file-change-recorder");
8
+ const projects_1 = require("../utils/projects");
9
+ const TODO_COMMENT = '// TODO: This is a security-sensitive option. Remove if not needed. ' +
10
+ 'For more information, see https://angular.dev/best-practices/security#configuring-trusted-proxy-headers';
11
+ const TRUST_PROXY_HEADERS = `trustProxyHeaders: ['x-forwarded-host', 'x-forwarded-proto'],`;
12
+ async function default_1(tree) {
13
+ const projects = await (0, projects_1.getProjectsFilteredByDependencies)([
14
+ 'npm:@angular/ssr',
15
+ ]);
16
+ for (const graphNode of projects) {
17
+ (0, devkit_1.visitNotIgnoredFiles)(tree, graphNode.data.root, (path) => {
18
+ if (!path.endsWith('.ts') || path.endsWith('.d.ts')) {
19
+ return;
20
+ }
21
+ const content = tree.read(path, 'utf-8');
22
+ // Skip already-migrated files and files not instantiating an SSR engine.
23
+ if (content.includes(TODO_COMMENT) ||
24
+ (!content.includes('AngularNodeAppEngine') &&
25
+ !content.includes('AngularAppEngine'))) {
26
+ return;
27
+ }
28
+ const sourceFile = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
29
+ let recorder;
30
+ const visit = (node) => {
31
+ if (ts.isNewExpression(node) &&
32
+ ts.isIdentifier(node.expression) &&
33
+ (node.expression.text === 'AngularNodeAppEngine' ||
34
+ node.expression.text === 'AngularAppEngine')) {
35
+ if (!node.arguments || node.arguments.length === 0) {
36
+ // No options object: insert one before the closing parenthesis.
37
+ recorder ??= new file_change_recorder_1.FileChangeRecorder(tree, path);
38
+ recorder.insertRight(node.end - 1, `{\n ${TODO_COMMENT}\n ${TRUST_PROXY_HEADERS}\n}`);
39
+ }
40
+ else if (ts.isObjectLiteralExpression(node.arguments[0])) {
41
+ const optionsArg = node.arguments[0];
42
+ const hasTrustProxyHeaders = optionsArg.properties.some((prop) => ts.isPropertyAssignment(prop) &&
43
+ (ts.isIdentifier(prop.name) || ts.isStringLiteral(prop.name)) &&
44
+ prop.name.text === 'trustProxyHeaders');
45
+ if (!hasTrustProxyHeaders) {
46
+ // Insert right after the opening brace of the options object.
47
+ recorder ??= new file_change_recorder_1.FileChangeRecorder(tree, path);
48
+ recorder.insertRight(optionsArg.getStart() + 1, `\n ${TODO_COMMENT}\n ${TRUST_PROXY_HEADERS}`);
49
+ }
50
+ }
51
+ }
52
+ ts.forEachChild(node, visit);
53
+ };
54
+ visit(sourceFile);
55
+ if (recorder) {
56
+ recorder.applyChanges();
57
+ }
58
+ });
59
+ }
60
+ await (0, devkit_1.formatFiles)(tree);
61
+ }
@@ -0,0 +1,48 @@
1
+ #### Add `trustProxyHeaders` to SSR Engines
2
+
3
+ Angular v22 adds a `trustProxyHeaders` option to `AngularNodeAppEngine` and `AngularAppEngine` that controls whether the `X-Forwarded-*` headers are trusted when resolving the incoming request URL. This migration adds the option to existing engine instantiations in SSR server files so the behavior is explicit, along with a TODO comment flagging it as security-sensitive. Instantiations that already set `trustProxyHeaders` are left unchanged.
4
+
5
+ The migration scans the source files of projects that depend on `@angular/ssr` for `new AngularNodeAppEngine(...)` and `new AngularAppEngine(...)` expressions.
6
+
7
+ #### Examples
8
+
9
+ ##### `server.ts`
10
+
11
+ Before:
12
+
13
+ ```ts
14
+ import { AngularNodeAppEngine } from '@angular/ssr/node';
15
+
16
+ const angularApp = new AngularNodeAppEngine();
17
+ ```
18
+
19
+ After:
20
+
21
+ ```ts
22
+ import { AngularNodeAppEngine } from '@angular/ssr/node';
23
+
24
+ const angularApp = new AngularNodeAppEngine({
25
+ // TODO: This is a security-sensitive option. Remove if not needed. For more information, see https://angular.dev/best-practices/security#configuring-trusted-proxy-headers
26
+ trustProxyHeaders: ['x-forwarded-host', 'x-forwarded-proto'],
27
+ });
28
+ ```
29
+
30
+ An existing options object is preserved, with `trustProxyHeaders` added alongside the current options:
31
+
32
+ Before:
33
+
34
+ ```ts
35
+ const angularApp = new AngularAppEngine({
36
+ allowedHosts: ['example.com'],
37
+ });
38
+ ```
39
+
40
+ After:
41
+
42
+ ```ts
43
+ const angularApp = new AngularAppEngine({
44
+ // TODO: This is a security-sensitive option. Remove if not needed. For more information, see https://angular.dev/best-practices/security#configuring-trusted-proxy-headers
45
+ trustProxyHeaders: ['x-forwarded-host', 'x-forwarded-proto'],
46
+ allowedHosts: ['example.com'],
47
+ });
48
+ ```
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<void>;
@@ -0,0 +1,70 @@
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
+ // Application builders whose SSR `experimentalPlatform` option Angular v22
7
+ // renamed to `platform`. This mirrors Angular's `update-workspace-config`
8
+ // migration (which targets the upstream `@angular/build:application` and
9
+ // `@angular-devkit/build-angular:application` builders) and additionally covers
10
+ // the `@nx/angular:application` executor that wraps them, since Nx does not run
11
+ // Angular's own ng-update migrations.
12
+ const ssrApplicationExecutors = [
13
+ '@angular/build:application',
14
+ '@angular-devkit/build-angular:application',
15
+ '@nx/angular:application',
16
+ ];
17
+ function renameSsrPlatform(target) {
18
+ let isUpdated = false;
19
+ for (const [, options] of (0, targets_1.allTargetOptions)(target)) {
20
+ const ssr = options.ssr;
21
+ if (!ssr || typeof ssr !== 'object') {
22
+ continue;
23
+ }
24
+ const platform = ssr.experimentalPlatform;
25
+ if (platform) {
26
+ ssr.platform = platform;
27
+ delete ssr.experimentalPlatform;
28
+ isUpdated = true;
29
+ }
30
+ }
31
+ return isUpdated;
32
+ }
33
+ async function default_1(tree) {
34
+ // project.json target options and configurations
35
+ for (const [projectName, project] of (0, devkit_1.getProjects)(tree)) {
36
+ if (project.projectType !== 'application') {
37
+ continue;
38
+ }
39
+ let isUpdated = false;
40
+ for (const target of Object.values(project.targets ?? {})) {
41
+ if (!ssrApplicationExecutors.includes(target.executor)) {
42
+ continue;
43
+ }
44
+ if (renameSsrPlatform(target)) {
45
+ isUpdated = true;
46
+ }
47
+ }
48
+ if (isUpdated) {
49
+ (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
50
+ }
51
+ }
52
+ // nx.json targetDefaults
53
+ const nxJson = (0, devkit_1.readNxJson)(tree);
54
+ if (nxJson?.targetDefaults) {
55
+ let isUpdated = false;
56
+ for (const [targetOrExecutor, targetConfig] of Object.entries(nxJson.targetDefaults)) {
57
+ if (!ssrApplicationExecutors.includes(targetOrExecutor) &&
58
+ !ssrApplicationExecutors.includes(targetConfig.executor)) {
59
+ continue;
60
+ }
61
+ if (renameSsrPlatform(targetConfig)) {
62
+ isUpdated = true;
63
+ }
64
+ }
65
+ if (isUpdated) {
66
+ (0, devkit_1.updateNxJson)(tree, nxJson);
67
+ }
68
+ }
69
+ await (0, devkit_1.formatFiles)(tree);
70
+ }