@angular/build 19.0.0-next.9 → 19.0.0-rc.0

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 (77) hide show
  1. package/package.json +21 -19
  2. package/src/builders/application/build-action.js +9 -9
  3. package/src/builders/application/chunk-optimizer.js +1 -4
  4. package/src/builders/application/execute-build.js +34 -6
  5. package/src/builders/application/execute-post-bundle.js +9 -1
  6. package/src/builders/application/index.d.ts +0 -16
  7. package/src/builders/application/index.js +15 -10
  8. package/src/builders/application/options.d.ts +4 -1
  9. package/src/builders/application/options.js +16 -10
  10. package/src/builders/application/results.d.ts +5 -3
  11. package/src/builders/application/schema.d.ts +86 -0
  12. package/src/builders/application/schema.js +19 -1
  13. package/src/builders/application/schema.json +73 -4
  14. package/src/builders/application/setup-bundling.d.ts +3 -1
  15. package/src/builders/application/setup-bundling.js +33 -6
  16. package/src/builders/dev-server/vite-server.d.ts +2 -2
  17. package/src/builders/dev-server/vite-server.js +39 -10
  18. package/src/index.d.ts +1 -0
  19. package/src/tools/angular/angular-host.d.ts +1 -1
  20. package/src/tools/angular/angular-host.js +1 -4
  21. package/src/tools/angular/compilation/angular-compilation.d.ts +1 -0
  22. package/src/tools/angular/compilation/aot-compilation.d.ts +1 -0
  23. package/src/tools/angular/compilation/aot-compilation.js +39 -0
  24. package/src/tools/angular/compilation/parallel-compilation.js +2 -2
  25. package/src/tools/angular/compilation/parallel-worker.d.ts +1 -0
  26. package/src/tools/angular/compilation/parallel-worker.js +5 -2
  27. package/src/tools/esbuild/angular/compiler-plugin.d.ts +2 -4
  28. package/src/tools/esbuild/angular/compiler-plugin.js +53 -33
  29. package/src/tools/esbuild/angular/component-stylesheets.d.ts +17 -18
  30. package/src/tools/esbuild/angular/component-stylesheets.js +63 -38
  31. package/src/tools/esbuild/angular/jit-plugin-callbacks.d.ts +1 -1
  32. package/src/tools/esbuild/angular/jit-plugin-callbacks.js +11 -3
  33. package/src/tools/esbuild/application-code-bundle.d.ts +5 -4
  34. package/src/tools/esbuild/application-code-bundle.js +66 -41
  35. package/src/tools/esbuild/bundler-context.d.ts +2 -1
  36. package/src/tools/esbuild/bundler-context.js +10 -12
  37. package/src/tools/esbuild/bundler-execution-result.d.ts +5 -2
  38. package/src/tools/esbuild/bundler-execution-result.js +5 -1
  39. package/src/tools/esbuild/commonjs-checker.js +2 -2
  40. package/src/tools/esbuild/compiler-plugin-options.d.ts +1 -4
  41. package/src/tools/esbuild/compiler-plugin-options.js +14 -37
  42. package/src/tools/esbuild/global-scripts.js +1 -1
  43. package/src/tools/esbuild/global-styles.js +4 -1
  44. package/src/tools/esbuild/index-html-generator.js +8 -0
  45. package/src/tools/esbuild/javascript-transformer.js +2 -0
  46. package/src/tools/esbuild/server-bundle-metadata-plugin.d.ts +22 -0
  47. package/src/tools/esbuild/server-bundle-metadata-plugin.js +36 -0
  48. package/src/tools/esbuild/stylesheets/bundle-options.d.ts +2 -0
  49. package/src/tools/esbuild/stylesheets/bundle-options.js +2 -1
  50. package/src/tools/esbuild/stylesheets/sass-language.js +4 -0
  51. package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.d.ts +9 -0
  52. package/src/tools/esbuild/utils.js +13 -31
  53. package/src/tools/sass/worker.js +19 -0
  54. package/src/tools/vite/middlewares/assets-middleware.d.ts +1 -1
  55. package/src/tools/vite/middlewares/assets-middleware.js +19 -3
  56. package/src/tools/vite/middlewares/component-middleware.d.ts +9 -0
  57. package/src/tools/vite/middlewares/component-middleware.js +33 -0
  58. package/src/tools/vite/middlewares/index.d.ts +1 -0
  59. package/src/tools/vite/middlewares/index.js +3 -1
  60. package/src/tools/vite/middlewares/ssr-middleware.js +6 -6
  61. package/src/tools/vite/plugins/setup-middlewares-plugin.d.ts +2 -1
  62. package/src/tools/vite/plugins/setup-middlewares-plugin.js +2 -1
  63. package/src/tools/vite/utils.d.ts +1 -0
  64. package/src/typings.d.ts +1 -1
  65. package/src/utils/environment-options.js +1 -1
  66. package/src/utils/index-file/auto-csp.d.ts +23 -0
  67. package/src/utils/index-file/auto-csp.js +283 -0
  68. package/src/utils/index-file/html-rewriting-stream.d.ts +5 -1
  69. package/src/utils/index-file/index-html-generator.d.ts +4 -0
  70. package/src/utils/index-file/index-html-generator.js +11 -0
  71. package/src/utils/index-file/inline-critical-css.js +17 -18
  72. package/src/utils/normalize-cache.js +1 -1
  73. package/src/utils/server-rendering/launch-server.js +5 -5
  74. package/src/utils/server-rendering/load-esm-from-memory.d.ts +1 -1
  75. package/src/utils/server-rendering/manifest.d.ts +1 -1
  76. package/src/utils/server-rendering/prerender.js +5 -3
  77. package/src/utils/supported-browsers.js +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/build",
3
- "version": "19.0.0-next.9",
3
+ "version": "19.0.0-rc.0",
4
4
  "description": "Official build system for Angular",
5
5
  "keywords": [
6
6
  "Angular CLI",
@@ -23,39 +23,41 @@
23
23
  "builders": "builders.json",
24
24
  "dependencies": {
25
25
  "@ampproject/remapping": "2.3.0",
26
- "@angular-devkit/architect": "0.1900.0-next.9",
27
- "@babel/core": "7.25.2",
28
- "@babel/helper-annotate-as-pure": "7.24.7",
26
+ "@angular-devkit/architect": "0.1900.0-rc.0",
27
+ "@babel/core": "7.26.0",
28
+ "@babel/helper-annotate-as-pure": "7.25.9",
29
29
  "@babel/helper-split-export-declaration": "7.24.7",
30
- "@babel/plugin-syntax-import-attributes": "7.25.6",
31
- "@inquirer/confirm": "4.0.1",
30
+ "@babel/plugin-syntax-import-attributes": "7.26.0",
31
+ "@inquirer/confirm": "5.0.1",
32
32
  "@vitejs/plugin-basic-ssl": "1.1.0",
33
+ "beasties": "0.1.0",
33
34
  "browserslist": "^4.23.0",
34
- "critters": "0.0.24",
35
35
  "esbuild": "0.24.0",
36
36
  "fast-glob": "3.3.2",
37
37
  "https-proxy-agent": "7.0.5",
38
38
  "istanbul-lib-instrument": "6.0.3",
39
- "listr2": "8.2.4",
40
- "lmdb": "3.1.3",
41
- "magic-string": "0.30.11",
39
+ "listr2": "8.2.5",
40
+ "magic-string": "0.30.12",
42
41
  "mrmime": "2.0.0",
43
42
  "parse5-html-rewriting-stream": "7.0.0",
44
43
  "picomatch": "4.0.2",
45
44
  "piscina": "4.7.0",
46
- "rollup": "4.22.5",
47
- "sass": "1.79.4",
45
+ "rollup": "4.24.3",
46
+ "sass": "1.80.5",
48
47
  "semver": "7.6.3",
49
- "vite": "5.4.8",
48
+ "vite": "5.4.10",
50
49
  "watchpack": "2.4.2"
51
50
  },
51
+ "optionalDependencies": {
52
+ "lmdb": "3.1.3"
53
+ },
52
54
  "peerDependencies": {
53
- "@angular/compiler": "^19.0.0-next.0",
54
- "@angular/compiler-cli": "^19.0.0-next.0",
55
- "@angular/localize": "^19.0.0-next.0",
56
- "@angular/platform-server": "^19.0.0-next.0",
57
- "@angular/service-worker": "^19.0.0-next.0",
58
- "@angular/ssr": "^19.0.0-next.9",
55
+ "@angular/compiler": "^19.0.0-next.9",
56
+ "@angular/compiler-cli": "^19.0.0-next.9",
57
+ "@angular/localize": "^19.0.0-next.9",
58
+ "@angular/platform-server": "^19.0.0-next.9",
59
+ "@angular/service-worker": "^19.0.0-next.9",
60
+ "@angular/ssr": "^19.0.0-rc.0",
59
61
  "less": "^4.2.0",
60
62
  "postcss": "^8.4.0",
61
63
  "tailwindcss": "^2.0.0 || ^3.0.0",
@@ -83,12 +83,6 @@ async function* runEsBuildBuildAction(action, options) {
83
83
  cacheOptions.basePath,
84
84
  `${workspaceRoot.replace(/\\/g, '/')}/**/.*/**`,
85
85
  ];
86
- if (!preserveSymlinks) {
87
- // Ignore all node modules directories to avoid excessive file watchers.
88
- // Package changes are handled below by watching manifest and lock files.
89
- // NOTE: this is not enable when preserveSymlinks is true as this would break `npm link` usages.
90
- ignored.push('**/node_modules/**');
91
- }
92
86
  // Setup a watcher
93
87
  const { createWatcher } = await Promise.resolve().then(() => __importStar(require('../../tools/esbuild/watcher')));
94
88
  watcher = createWatcher({
@@ -101,11 +95,17 @@ async function* runEsBuildBuildAction(action, options) {
101
95
  options.signal?.addEventListener('abort', () => void watcher?.close());
102
96
  // Watch the entire project root if 'NG_BUILD_WATCH_ROOT' environment variable is set
103
97
  if (environment_options_1.shouldWatchRoot) {
98
+ if (!preserveSymlinks) {
99
+ // Ignore all node modules directories to avoid excessive file watchers.
100
+ // Package changes are handled below by watching manifest and lock files.
101
+ // NOTE: this is not enable when preserveSymlinks is true as this would break `npm link` usages.
102
+ ignored.push('**/node_modules/**');
103
+ watcher.add(packageWatchFiles
104
+ .map((file) => node_path_1.default.join(workspaceRoot, file))
105
+ .filter((file) => (0, node_fs_1.existsSync)(file)));
106
+ }
104
107
  watcher.add(projectRoot);
105
108
  }
106
- watcher.add(packageWatchFiles
107
- .map((file) => node_path_1.default.join(workspaceRoot, file))
108
- .filter((file) => (0, node_fs_1.existsSync)(file)));
109
109
  // Watch locations provided by the initial build result
110
110
  watcher.add(result.watchFiles);
111
111
  }
@@ -83,10 +83,7 @@ async function optimizeChunks(original, sourcemap) {
83
83
  const result = await bundle.generate({
84
84
  compact: true,
85
85
  sourcemap,
86
- chunkFileNames(chunkInfo) {
87
- // Do not add hash to file name if already present
88
- return /-[a-zA-Z0-9]{8}$/.test(chunkInfo.name) ? '[name].js' : '[name]-[hash].js';
89
- },
86
+ chunkFileNames: (chunkInfo) => `${chunkInfo.name.replace(/-[a-zA-Z0-9]{8}$/, '')}-[hash].js`,
90
87
  });
91
88
  optimizedOutput = result.output;
92
89
  }
@@ -41,18 +41,42 @@ async function executeBuild(options, context, rebuildState) {
41
41
  await (0, i18n_1.loadActiveTranslations)(context, i18nOptions);
42
42
  }
43
43
  // Reuse rebuild state or create new bundle contexts for code and global stylesheets
44
- let bundlerContexts = rebuildState?.rebuildContexts;
45
- const codeBundleCache = rebuildState?.codeBundleCache ??
46
- new source_file_cache_1.SourceFileCache(cacheOptions.enabled ? cacheOptions.path : undefined);
47
- if (bundlerContexts === undefined) {
48
- bundlerContexts = (0, setup_bundling_1.setupBundlerContexts)(options, browsers, codeBundleCache);
44
+ let bundlerContexts;
45
+ let componentStyleBundler;
46
+ let codeBundleCache;
47
+ if (rebuildState) {
48
+ bundlerContexts = rebuildState.rebuildContexts;
49
+ componentStyleBundler = rebuildState.componentStyleBundler;
50
+ codeBundleCache = rebuildState.codeBundleCache;
51
+ }
52
+ else {
53
+ const target = (0, utils_1.transformSupportedBrowsersToTargets)(browsers);
54
+ codeBundleCache = new source_file_cache_1.SourceFileCache(cacheOptions.enabled ? cacheOptions.path : undefined);
55
+ componentStyleBundler = (0, setup_bundling_1.createComponentStyleBundler)(options, target);
56
+ bundlerContexts = (0, setup_bundling_1.setupBundlerContexts)(options, target, codeBundleCache, componentStyleBundler);
49
57
  }
50
58
  let bundlingResult = await bundler_context_1.BundlerContext.bundleAll(bundlerContexts, rebuildState?.fileChanges.all);
59
+ if (rebuildState && options.externalRuntimeStyles) {
60
+ const invalidatedStylesheetEntries = componentStyleBundler.invalidate(rebuildState.fileChanges.all);
61
+ if (invalidatedStylesheetEntries?.length) {
62
+ const componentResults = [];
63
+ for (const stylesheetFile of invalidatedStylesheetEntries) {
64
+ // externalId is already linked in the bundler context so only enabling is required here
65
+ const result = await componentStyleBundler.bundleFile(stylesheetFile, true, true);
66
+ componentResults.push(result);
67
+ }
68
+ bundlingResult = bundler_context_1.BundlerContext.mergeResults([bundlingResult, ...componentResults]);
69
+ }
70
+ }
51
71
  if (options.optimizationOptions.scripts && environment_options_1.shouldOptimizeChunks) {
52
72
  bundlingResult = await (0, profiling_1.profileAsync)('OPTIMIZE_CHUNKS', () => (0, chunk_optimizer_1.optimizeChunks)(bundlingResult, options.sourcemapOptions.scripts ? !options.sourcemapOptions.hidden || 'hidden' : false));
53
73
  }
54
- const executionResult = new bundler_execution_result_1.ExecutionResult(bundlerContexts, codeBundleCache);
74
+ const executionResult = new bundler_execution_result_1.ExecutionResult(bundlerContexts, componentStyleBundler, codeBundleCache);
55
75
  executionResult.addWarnings(bundlingResult.warnings);
76
+ // Add used external component style referenced files to be watched
77
+ if (options.externalRuntimeStyles) {
78
+ executionResult.extraWatchFiles.push(...componentStyleBundler.collectReferencedFiles());
79
+ }
56
80
  // Return if the bundling has errors
57
81
  if (bundlingResult.errors) {
58
82
  executionResult.addErrors(bundlingResult.errors);
@@ -115,6 +139,10 @@ async function executeBuild(options, context, rebuildState) {
115
139
  if (serverEntryPoint) {
116
140
  executionResult.addOutputFile(manifest_1.SERVER_APP_ENGINE_MANIFEST_FILENAME, (0, manifest_1.generateAngularServerAppEngineManifest)(i18nOptions, baseHref, undefined), bundler_context_1.BuildOutputFileType.ServerRoot);
117
141
  }
142
+ // Override auto-CSP settings if we are serving through Vite middleware.
143
+ if (context.builder.builderName === 'dev-server' && options.security) {
144
+ options.security.autoCsp = false;
145
+ }
118
146
  // Perform i18n translation inlining if enabled
119
147
  if (i18nOptions.shouldInline) {
120
148
  const result = await (0, i18n_1.inlineI18n)(options, executionResult, initialFiles);
@@ -71,7 +71,15 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
71
71
  // Update the index contents with the app shell under these conditions:
72
72
  // - Replace 'index.html' with the app shell only if it hasn't been prerendered yet.
73
73
  // - Always replace 'index.csr.html' with the app shell.
74
- const filePath = appShellRoute && !indexHasBeenPrerendered ? indexHtmlOptions.output : path;
74
+ let filePath = path;
75
+ if (appShellRoute && !indexHasBeenPrerendered) {
76
+ if (outputMode !== schema_1.OutputMode.Server && indexHtmlOptions.output === options_1.INDEX_HTML_CSR) {
77
+ filePath = 'index.html';
78
+ }
79
+ else {
80
+ filePath = indexHtmlOptions.output;
81
+ }
82
+ }
75
83
  additionalHtmlOutputFiles.set(filePath, (0, utils_1.createOutputFile)(filePath, content, bundler_context_1.BuildOutputFileType.Browser));
76
84
  }
77
85
  const serializableRouteTreeNodeForManifest = [];
@@ -6,7 +6,6 @@
6
6
  * found in the LICENSE file at https://angular.dev/license
7
7
  */
8
8
  import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
9
- import type { Plugin } from 'esbuild';
10
9
  import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
11
10
  import { ApplicationBuilderExtensions, ApplicationBuilderInternalOptions } from './options';
12
11
  import { Result } from './results';
@@ -22,21 +21,6 @@ export interface ApplicationBuilderOutput extends BuilderOutput {
22
21
  destination: string;
23
22
  }[];
24
23
  }
25
- /**
26
- * Builds an application using the `application` builder with the provided
27
- * options.
28
- *
29
- * Usage of the `plugins` parameter is NOT supported and may cause unexpected
30
- * build output or build failures.
31
- *
32
- * @experimental Direct usage of this function is considered experimental.
33
- *
34
- * @param options The options defined by the builder's schema to use.
35
- * @param context An Architect builder context instance.
36
- * @param plugins An array of plugins to apply to the main code bundling.
37
- * @returns The build output results of the build.
38
- */
39
- export declare function buildApplication(options: ApplicationBuilderOptions, context: BuilderContext, plugins?: Plugin[]): AsyncIterable<ApplicationBuilderOutput>;
40
24
  /**
41
25
  * Builds an application using the `application` builder with the provided
42
26
  * options.
@@ -100,16 +100,21 @@ context, extensions) {
100
100
  signal,
101
101
  });
102
102
  }
103
- async function* buildApplication(options, context, pluginsOrExtensions) {
104
- let extensions;
105
- if (pluginsOrExtensions && Array.isArray(pluginsOrExtensions)) {
106
- extensions = {
107
- codePlugins: pluginsOrExtensions,
108
- };
109
- }
110
- else {
111
- extensions = pluginsOrExtensions;
112
- }
103
+ /**
104
+ * Builds an application using the `application` builder with the provided
105
+ * options.
106
+ *
107
+ * Usage of the `extensions` parameter is NOT supported and may cause unexpected
108
+ * build output or build failures.
109
+ *
110
+ * @experimental Direct usage of this function is considered experimental.
111
+ *
112
+ * @param options The options defined by the builder's schema to use.
113
+ * @param context An Architect builder context instance.
114
+ * @param extensions An object contain extension points for the build.
115
+ * @returns The build output results of the build.
116
+ */
117
+ async function* buildApplication(options, context, extensions) {
113
118
  let initial = true;
114
119
  for await (const result of buildApplicationInternal(options, context, extensions)) {
115
120
  const outputOptions = result.detail?.['outputOptions'];
@@ -9,7 +9,7 @@ import type { BuilderContext } from '@angular-devkit/architect';
9
9
  import type { Plugin } from 'esbuild';
10
10
  import { I18nOptions } from '../../utils/i18n-options';
11
11
  import { IndexHtmlTransform } from '../../utils/index-file/index-html-generator';
12
- import { Schema as ApplicationBuilderOptions, I18NTranslation, OutputMode, OutputPathClass } from './schema';
12
+ import { Schema as ApplicationBuilderOptions, ExperimentalPlatform, I18NTranslation, OutputMode, OutputPathClass } from './schema';
13
13
  /**
14
14
  * The filename for the client-side rendered HTML template.
15
15
  * This template is used for client-side rendering (CSR) in a web application.
@@ -119,8 +119,10 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
119
119
  outputMode: OutputMode | undefined;
120
120
  ssrOptions: {
121
121
  entry?: undefined;
122
+ platform?: undefined;
122
123
  } | {
123
124
  entry: string | undefined;
125
+ platform: ExperimentalPlatform;
124
126
  } | undefined;
125
127
  verbose: boolean | undefined;
126
128
  watch: boolean | undefined;
@@ -181,6 +183,7 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
181
183
  partialSSRBuild: boolean;
182
184
  externalRuntimeStyles: boolean | undefined;
183
185
  instrumentForCoverage: ((filename: string) => boolean) | undefined;
186
+ security: import("./schema").Security | undefined;
184
187
  }>;
185
188
  export declare function getLocaleBaseHref(baseHref: string | undefined, i18n: NormalizedApplicationBuildOptions['i18nOptions'], locale: string): string | undefined;
186
189
  export {};
@@ -116,14 +116,12 @@ async function normalizeOptions(context, projectName, options, extensions) {
116
116
  if (!options.server) {
117
117
  options.ssr = false;
118
118
  }
119
- if (options.prerender) {
120
- context.logger.warn('The "prerender" option is no longer needed when "outputMode" is specified.');
119
+ if (options.prerender !== undefined) {
120
+ context.logger.warn('The "prerender" option is not considered when "outputMode" is specified.');
121
121
  }
122
- else {
123
- options.prerender = !!options.server;
124
- }
125
- if (options.appShell) {
126
- context.logger.warn('The "appShell" option is no longer needed when "outputMode" is specified.');
122
+ options.prerender = !!options.server;
123
+ if (options.appShell !== undefined) {
124
+ context.logger.warn('The "appShell" option is not considered when "outputMode" is specified.');
127
125
  }
128
126
  }
129
127
  // A configuration file can exist in the project or workspace root
@@ -153,9 +151,10 @@ async function normalizeOptions(context, projectName, options, extensions) {
153
151
  ssrOptions = {};
154
152
  }
155
153
  else if (typeof options.ssr === 'object') {
156
- const { entry } = options.ssr;
154
+ const { entry, experimentalPlatform = schema_1.ExperimentalPlatform.Node } = options.ssr;
157
155
  ssrOptions = {
158
156
  entry: entry && node_path_1.default.join(workspaceRoot, entry),
157
+ platform: experimentalPlatform,
159
158
  };
160
159
  }
161
160
  let appShellOptions;
@@ -199,10 +198,16 @@ async function normalizeOptions(context, projectName, options, extensions) {
199
198
  * If SSR is activated, create a distinct entry file for the `index.html`.
200
199
  * This is necessary because numerous server/cloud providers automatically serve the `index.html` as a static file
201
200
  * if it exists (handling SSG).
201
+ *
202
202
  * For instance, accessing `foo.com/` would lead to `foo.com/index.html` being served instead of hitting the server.
203
+ *
204
+ * This approach can also be applied to service workers, where the `index.csr.html` is served instead of the prerendered `index.html`.
203
205
  */
204
206
  const indexBaseName = node_path_1.default.basename(options.index);
205
- indexOutput = ssrOptions && indexBaseName === 'index.html' ? exports.INDEX_HTML_CSR : indexBaseName;
207
+ indexOutput =
208
+ (ssrOptions || prerenderOptions) && indexBaseName === 'index.html'
209
+ ? exports.INDEX_HTML_CSR
210
+ : indexBaseName;
206
211
  }
207
212
  else {
208
213
  indexOutput = options.index.output || 'index.html';
@@ -231,7 +236,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
231
236
  }
232
237
  }
233
238
  // Initial options to keep
234
- const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, statsJson, outputMode, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, namedChunks, budgets, deployUrl, clearScreen, define, partialSSRBuild = false, externalRuntimeStyles, instrumentForCoverage, } = options;
239
+ const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, statsJson, outputMode, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, namedChunks, budgets, deployUrl, clearScreen, define, partialSSRBuild = false, externalRuntimeStyles, instrumentForCoverage, security, } = options;
235
240
  // Return all the normalized options
236
241
  return {
237
242
  advancedOptimizations: !!aot && optimizationOptions.scripts,
@@ -290,6 +295,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
290
295
  partialSSRBuild: environment_options_1.usePartialSsrBuild || partialSSRBuild,
291
296
  externalRuntimeStyles,
292
297
  instrumentForCoverage,
298
+ security,
293
299
  };
294
300
  }
295
301
  async function getTailwindConfig(searchDirectories, workspaceRoot, context) {
@@ -61,7 +61,9 @@ export interface ResultMessage {
61
61
  }
62
62
  export interface ComponentUpdateResult extends BaseResult {
63
63
  kind: ResultKind.ComponentUpdate;
64
- id: string;
65
- type: 'style' | 'template';
66
- content: string;
64
+ updates: {
65
+ id: string;
66
+ type: 'style' | 'template';
67
+ content: string;
68
+ }[];
67
69
  }
@@ -153,6 +153,10 @@ export interface Schema {
153
153
  * Global scripts to be included in the build.
154
154
  */
155
155
  scripts?: ScriptElement[];
156
+ /**
157
+ * Security features to protect against XSS and other common attacks
158
+ */
159
+ security?: Security;
156
160
  /**
157
161
  * The full path for the server entry point to the application, relative to the current
158
162
  * workspace.
@@ -464,6 +468,31 @@ export interface ScriptClass {
464
468
  */
465
469
  input: string;
466
470
  }
471
+ /**
472
+ * Security features to protect against XSS and other common attacks
473
+ */
474
+ export interface Security {
475
+ /**
476
+ * Enables automatic generation of a hash-based Strict Content Security Policy
477
+ * (https://web.dev/articles/strict-csp#choose-hash) based on scripts in index.html. Will
478
+ * default to true once we are out of experimental/preview phases.
479
+ */
480
+ autoCsp?: AutoCspUnion;
481
+ }
482
+ /**
483
+ * Enables automatic generation of a hash-based Strict Content Security Policy
484
+ * (https://web.dev/articles/strict-csp#choose-hash) based on scripts in index.html. Will
485
+ * default to true once we are out of experimental/preview phases.
486
+ */
487
+ export type AutoCspUnion = boolean | AutoCspClass;
488
+ export interface AutoCspClass {
489
+ /**
490
+ * Include the `unsafe-eval` directive (https://web.dev/articles/strict-csp#remove-eval) in
491
+ * the auto-CSP. Please only enable this if you are absolutely sure that you need to, as
492
+ * allowing calls to eval will weaken the XSS defenses provided by the auto-CSP.
493
+ */
494
+ unsafeEval?: boolean;
495
+ }
467
496
  /**
468
497
  * Generates a service worker configuration.
469
498
  */
@@ -500,6 +529,37 @@ export interface SsrClass {
500
529
  * The server entry-point that when executed will spawn the web server.
501
530
  */
502
531
  entry?: string;
532
+ /**
533
+ * Specifies the platform for which the server bundle is generated. This affects the APIs
534
+ * and modules available in the server-side code.
535
+ *
536
+ * - `node`: (Default) Generates a bundle optimized for Node.js environments.
537
+ * - `neutral`: Generates a platform-neutral bundle suitable for environments like edge
538
+ * workers, and other serverless platforms. This option avoids using Node.js-specific APIs,
539
+ * making the bundle more portable.
540
+ *
541
+ * Please note that this feature does not provide polyfills for Node.js modules.
542
+ * Additionally, it is experimental, and the schematics may undergo changes in future
543
+ * versions.
544
+ */
545
+ experimentalPlatform?: ExperimentalPlatform;
546
+ }
547
+ /**
548
+ * Specifies the platform for which the server bundle is generated. This affects the APIs
549
+ * and modules available in the server-side code.
550
+ *
551
+ * - `node`: (Default) Generates a bundle optimized for Node.js environments.
552
+ * - `neutral`: Generates a platform-neutral bundle suitable for environments like edge
553
+ * workers, and other serverless platforms. This option avoids using Node.js-specific APIs,
554
+ * making the bundle more portable.
555
+ *
556
+ * Please note that this feature does not provide polyfills for Node.js modules.
557
+ * Additionally, it is experimental, and the schematics may undergo changes in future
558
+ * versions.
559
+ */
560
+ export declare enum ExperimentalPlatform {
561
+ Neutral = "neutral",
562
+ Node = "node"
503
563
  }
504
564
  /**
505
565
  * Options to pass to style preprocessors.
@@ -509,6 +569,32 @@ export interface StylePreprocessorOptions {
509
569
  * Paths to include. Paths will be resolved to workspace root.
510
570
  */
511
571
  includePaths?: string[];
572
+ /**
573
+ * Options to pass to the sass preprocessor.
574
+ */
575
+ sass?: Sass;
576
+ }
577
+ /**
578
+ * Options to pass to the sass preprocessor.
579
+ */
580
+ export interface Sass {
581
+ /**
582
+ * A set of deprecations to treat as fatal. If a deprecation warning of any provided type is
583
+ * encountered during compilation, the compiler will error instead. If a Version is
584
+ * provided, then all deprecations that were active in that compiler version will be treated
585
+ * as fatal.
586
+ */
587
+ fatalDeprecations?: string[];
588
+ /**
589
+ * A set of future deprecations to opt into early. Future deprecations passed here will be
590
+ * treated as active by the compiler, emitting warnings as necessary.
591
+ */
592
+ futureDeprecations?: string[];
593
+ /**
594
+ * A set of active deprecations to ignore. If a deprecation warning of any provided type is
595
+ * encountered during compilation, the compiler will ignore it instead.
596
+ */
597
+ silenceDeprecations?: string[];
512
598
  }
513
599
  export type StyleElement = StyleClass | string;
514
600
  export interface StyleClass {
@@ -2,7 +2,7 @@
2
2
  // THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
3
3
  // CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.OutputMode = exports.OutputHashing = exports.InlineStyleLanguage = exports.I18NTranslation = exports.CrossOrigin = exports.Type = void 0;
5
+ exports.ExperimentalPlatform = exports.OutputMode = exports.OutputHashing = exports.InlineStyleLanguage = exports.I18NTranslation = exports.CrossOrigin = exports.Type = void 0;
6
6
  /**
7
7
  * The type of budget.
8
8
  */
@@ -66,3 +66,21 @@ var OutputMode;
66
66
  OutputMode["Server"] = "server";
67
67
  OutputMode["Static"] = "static";
68
68
  })(OutputMode || (exports.OutputMode = OutputMode = {}));
69
+ /**
70
+ * Specifies the platform for which the server bundle is generated. This affects the APIs
71
+ * and modules available in the server-side code.
72
+ *
73
+ * - `node`: (Default) Generates a bundle optimized for Node.js environments.
74
+ * - `neutral`: Generates a platform-neutral bundle suitable for environments like edge
75
+ * workers, and other serverless platforms. This option avoids using Node.js-specific APIs,
76
+ * making the bundle more portable.
77
+ *
78
+ * Please note that this feature does not provide polyfills for Node.js modules.
79
+ * Additionally, it is experimental, and the schematics may undergo changes in future
80
+ * versions.
81
+ */
82
+ var ExperimentalPlatform;
83
+ (function (ExperimentalPlatform) {
84
+ ExperimentalPlatform["Neutral"] = "neutral";
85
+ ExperimentalPlatform["Node"] = "node";
86
+ })(ExperimentalPlatform || (exports.ExperimentalPlatform = ExperimentalPlatform = {}));
@@ -18,7 +18,18 @@
18
18
  },
19
19
  "server": {
20
20
  "type": "string",
21
- "description": "The full path for the server entry point to the application, relative to the current workspace."
21
+ "description": "The full path for the server entry point to the application, relative to the current workspace.",
22
+ "oneOf": [
23
+ {
24
+ "type": "string",
25
+ "description": "The full path for the server entry point to the application, relative to the current workspace."
26
+ },
27
+ {
28
+ "const": false,
29
+ "type": "boolean",
30
+ "description": "Indicates that a server entry point is not provided."
31
+ }
32
+ ]
22
33
  },
23
34
  "polyfills": {
24
35
  "description": "A list of polyfills to include in the build. Can be a full path for a file, relative to the current workspace or module specifier. Example: 'zone.js'.",
@@ -37,6 +48,33 @@
37
48
  "type": "string",
38
49
  "description": "Customize the base path for the URLs of resources in 'index.html' and component stylesheets. This option is only necessary for specific deployment scenarios, such as with Angular Elements or when utilizing different CDN locations."
39
50
  },
51
+ "security": {
52
+ "description": "Security features to protect against XSS and other common attacks",
53
+ "type": "object",
54
+ "additionalProperties": false,
55
+ "properties": {
56
+ "autoCsp": {
57
+ "description": "Enables automatic generation of a hash-based Strict Content Security Policy (https://web.dev/articles/strict-csp#choose-hash) based on scripts in index.html. Will default to true once we are out of experimental/preview phases.",
58
+ "default": false,
59
+ "oneOf": [
60
+ {
61
+ "type": "object",
62
+ "properties": {
63
+ "unsafeEval": {
64
+ "type": "boolean",
65
+ "description": "Include the `unsafe-eval` directive (https://web.dev/articles/strict-csp#remove-eval) in the auto-CSP. Please only enable this if you are absolutely sure that you need to, as allowing calls to eval will weaken the XSS defenses provided by the auto-CSP.",
66
+ "default": false
67
+ }
68
+ },
69
+ "additionalProperties": false
70
+ },
71
+ {
72
+ "type": "boolean"
73
+ }
74
+ ]
75
+ }
76
+ }
77
+ },
40
78
  "scripts": {
41
79
  "description": "Global scripts to be included in the build.",
42
80
  "type": "array",
@@ -125,6 +163,34 @@
125
163
  "type": "string"
126
164
  },
127
165
  "default": []
166
+ },
167
+ "sass": {
168
+ "description": "Options to pass to the sass preprocessor.",
169
+ "type": "object",
170
+ "properties": {
171
+ "fatalDeprecations": {
172
+ "description": "A set of deprecations to treat as fatal. If a deprecation warning of any provided type is encountered during compilation, the compiler will error instead. If a Version is provided, then all deprecations that were active in that compiler version will be treated as fatal.",
173
+ "type": "array",
174
+ "items": {
175
+ "type": "string"
176
+ }
177
+ },
178
+ "silenceDeprecations": {
179
+ "description": " A set of active deprecations to ignore. If a deprecation warning of any provided type is encountered during compilation, the compiler will ignore it instead.",
180
+ "type": "array",
181
+ "items": {
182
+ "type": "string"
183
+ }
184
+ },
185
+ "futureDeprecations": {
186
+ "description": "A set of future deprecations to opt into early. Future deprecations passed here will be treated as active by the compiler, emitting warnings as necessary.",
187
+ "type": "array",
188
+ "items": {
189
+ "type": "string"
190
+ }
191
+ }
192
+ },
193
+ "additionalProperties": false
128
194
  }
129
195
  },
130
196
  "additionalProperties": false
@@ -481,7 +547,6 @@
481
547
  },
482
548
  "prerender": {
483
549
  "description": "Prerender (SSG) pages of your application during build time.",
484
- "default": false,
485
550
  "oneOf": [
486
551
  {
487
552
  "type": "boolean",
@@ -518,6 +583,11 @@
518
583
  "entry": {
519
584
  "type": "string",
520
585
  "description": "The server entry-point that when executed will spawn the web server."
586
+ },
587
+ "experimentalPlatform": {
588
+ "description": "Specifies the platform for which the server bundle is generated. This affects the APIs and modules available in the server-side code. \n\n- `node`: (Default) Generates a bundle optimized for Node.js environments. \n- `neutral`: Generates a platform-neutral bundle suitable for environments like edge workers, and other serverless platforms. This option avoids using Node.js-specific APIs, making the bundle more portable. \n\nPlease note that this feature does not provide polyfills for Node.js modules. Additionally, it is experimental, and the schematics may undergo changes in future versions.",
589
+ "default": "node",
590
+ "enum": ["node", "neutral"]
521
591
  }
522
592
  },
523
593
  "additionalProperties": false
@@ -526,8 +596,7 @@
526
596
  },
527
597
  "appShell": {
528
598
  "type": "boolean",
529
- "description": "Generates an application shell during build time.",
530
- "default": false
599
+ "description": "Generates an application shell during build time."
531
600
  },
532
601
  "outputMode": {
533
602
  "type": "string",
@@ -5,6 +5,7 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.dev/license
7
7
  */
8
+ import { ComponentStylesheetBundler } from '../../tools/esbuild/angular/component-stylesheets';
8
9
  import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache';
9
10
  import { BundlerContext } from '../../tools/esbuild/bundler-context';
10
11
  import { NormalizedApplicationBuildOptions } from './options';
@@ -16,4 +17,5 @@ import { NormalizedApplicationBuildOptions } from './options';
16
17
  * @param codeBundleCache An instance of the TypeScript source file cache.
17
18
  * @returns An array of BundlerContext objects.
18
19
  */
19
- export declare function setupBundlerContexts(options: NormalizedApplicationBuildOptions, browsers: string[], codeBundleCache: SourceFileCache): BundlerContext[];
20
+ export declare function setupBundlerContexts(options: NormalizedApplicationBuildOptions, target: string[], codeBundleCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler): BundlerContext[];
21
+ export declare function createComponentStyleBundler(options: NormalizedApplicationBuildOptions, target: string[]): ComponentStylesheetBundler;