@angular-devkit/build-angular 18.0.0-next.2 → 18.0.0-next.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/builders.json +1 -5
  2. package/package.json +21 -20
  3. package/src/builders/app-shell/index.js +3 -5
  4. package/src/builders/browser/index.d.ts +1 -1
  5. package/src/builders/browser/index.js +9 -13
  6. package/src/builders/browser-esbuild/index.d.ts +2 -2
  7. package/src/builders/browser-esbuild/index.js +6 -9
  8. package/src/builders/dev-server/builder.d.ts +2 -2
  9. package/src/builders/dev-server/builder.js +11 -6
  10. package/src/builders/dev-server/index.d.ts +1 -1
  11. package/src/builders/dev-server/webpack-server.d.ts +1 -1
  12. package/src/builders/dev-server/webpack-server.js +5 -6
  13. package/src/builders/extract-i18n/application-extraction.js +2 -2
  14. package/src/builders/extract-i18n/builder.js +3 -4
  15. package/src/builders/extract-i18n/options.d.ts +1 -1
  16. package/src/builders/extract-i18n/options.js +2 -2
  17. package/src/builders/jest/index.js +2 -2
  18. package/src/builders/karma/index.js +3 -4
  19. package/src/builders/ng-packagr/index.js +8 -7
  20. package/src/builders/ng-packagr/schema.d.ts +4 -0
  21. package/src/builders/ng-packagr/schema.json +4 -0
  22. package/src/builders/prerender/index.js +2 -2
  23. package/src/builders/prerender/render-worker.js +1 -1
  24. package/src/builders/server/index.js +3 -4
  25. package/src/builders/server/platform-server-exports-loader.js +2 -1
  26. package/src/builders/ssr-dev-server/index.js +34 -34
  27. package/src/builders/web-test-runner/index.js +2 -2
  28. package/src/index.d.ts +1 -1
  29. package/src/index.js +2 -2
  30. package/src/tools/babel/presets/application.js +1 -1
  31. package/src/tools/webpack/configs/styles.js +2 -2
  32. package/src/tools/webpack/plugins/any-component-style-budget-checker.d.ts +2 -2
  33. package/src/tools/webpack/plugins/any-component-style-budget-checker.js +14 -17
  34. package/src/tools/webpack/plugins/css-optimizer-plugin.js +2 -2
  35. package/src/tools/webpack/plugins/index-html-webpack-plugin.d.ts +1 -1
  36. package/src/tools/webpack/plugins/index-html-webpack-plugin.js +3 -3
  37. package/src/tools/webpack/plugins/javascript-optimizer-plugin.js +2 -2
  38. package/src/tools/webpack/plugins/service-worker-plugin.js +2 -2
  39. package/src/tools/webpack/utils/stats.d.ts +1 -14
  40. package/src/tools/webpack/utils/stats.js +3 -207
  41. package/src/utils/action-executor.d.ts +1 -1
  42. package/src/utils/i18n-inlining.d.ts +1 -1
  43. package/src/utils/i18n-webpack.d.ts +16 -0
  44. package/src/utils/i18n-webpack.js +107 -0
  45. package/src/utils/index.d.ts +1 -2
  46. package/src/utils/index.js +4 -2
  47. package/src/utils/normalize-builder-schema.js +2 -2
  48. package/src/utils/normalize-cache.js +1 -1
  49. package/src/utils/normalize-optimization.d.ts +1 -1
  50. package/src/utils/normalize-optimization.js +0 -2
  51. package/src/utils/output-paths.d.ts +1 -1
  52. package/src/utils/webpack-browser-config.d.ts +1 -1
  53. package/src/utils/webpack-browser-config.js +2 -2
  54. package/src/builders/application/build-action.d.ts +0 -33
  55. package/src/builders/application/build-action.js +0 -183
  56. package/src/builders/application/execute-build.d.ts +0 -11
  57. package/src/builders/application/execute-build.js +0 -127
  58. package/src/builders/application/execute-post-bundle.d.ts +0 -25
  59. package/src/builders/application/execute-post-bundle.js +0 -96
  60. package/src/builders/application/i18n.d.ts +0 -29
  61. package/src/builders/application/i18n.js +0 -128
  62. package/src/builders/application/index.d.ts +0 -57
  63. package/src/builders/application/index.js +0 -121
  64. package/src/builders/application/options.d.ts +0 -149
  65. package/src/builders/application/options.js +0 -352
  66. package/src/builders/application/schema.d.ts +0 -512
  67. package/src/builders/application/schema.js +0 -58
  68. package/src/builders/application/schema.json +0 -635
  69. package/src/builders/application/setup-bundling.d.ts +0 -19
  70. package/src/builders/application/setup-bundling.js +0 -71
  71. package/src/builders/dev-server/vite-server.d.ts +0 -30
  72. package/src/builders/dev-server/vite-server.js +0 -502
  73. package/src/tools/babel/plugins/adjust-static-class-members.d.ts +0 -27
  74. package/src/tools/babel/plugins/adjust-static-class-members.js +0 -351
  75. package/src/tools/babel/plugins/adjust-typescript-enums.d.ts +0 -23
  76. package/src/tools/babel/plugins/adjust-typescript-enums.js +0 -113
  77. package/src/tools/babel/plugins/elide-angular-metadata.d.ts +0 -23
  78. package/src/tools/babel/plugins/elide-angular-metadata.js +0 -110
  79. package/src/tools/babel/plugins/index.d.ts +0 -11
  80. package/src/tools/babel/plugins/index.js +0 -21
  81. package/src/tools/babel/plugins/pure-toplevel-functions.d.ts +0 -16
  82. package/src/tools/babel/plugins/pure-toplevel-functions.js +0 -90
  83. package/src/tools/esbuild/angular/angular-host.d.ts +0 -26
  84. package/src/tools/esbuild/angular/angular-host.js +0 -72
  85. package/src/tools/esbuild/angular/compilation/angular-compilation.d.ts +0 -42
  86. package/src/tools/esbuild/angular/compilation/angular-compilation.js +0 -94
  87. package/src/tools/esbuild/angular/compilation/aot-compilation.d.ts +0 -21
  88. package/src/tools/esbuild/angular/compilation/aot-compilation.js +0 -228
  89. package/src/tools/esbuild/angular/compilation/factory.d.ts +0 -16
  90. package/src/tools/esbuild/angular/compilation/factory.js +0 -56
  91. package/src/tools/esbuild/angular/compilation/index.d.ts +0 -10
  92. package/src/tools/esbuild/angular/compilation/index.js +0 -17
  93. package/src/tools/esbuild/angular/compilation/jit-compilation.d.ts +0 -21
  94. package/src/tools/esbuild/angular/compilation/jit-compilation.js +0 -106
  95. package/src/tools/esbuild/angular/compilation/noop-compilation.d.ts +0 -20
  96. package/src/tools/esbuild/angular/compilation/noop-compilation.js +0 -26
  97. package/src/tools/esbuild/angular/compilation/parallel-compilation.d.ts +0 -42
  98. package/src/tools/esbuild/angular/compilation/parallel-compilation.js +0 -123
  99. package/src/tools/esbuild/angular/compilation/parallel-worker.d.ts +0 -33
  100. package/src/tools/esbuild/angular/compilation/parallel-worker.js +0 -90
  101. package/src/tools/esbuild/angular/compilation-state.d.ts +0 -15
  102. package/src/tools/esbuild/angular/compilation-state.js +0 -44
  103. package/src/tools/esbuild/angular/compiler-plugin.d.ts +0 -27
  104. package/src/tools/esbuild/angular/compiler-plugin.js +0 -433
  105. package/src/tools/esbuild/angular/component-stylesheets.d.ts +0 -44
  106. package/src/tools/esbuild/angular/component-stylesheets.js +0 -150
  107. package/src/tools/esbuild/angular/diagnostics.d.ts +0 -15
  108. package/src/tools/esbuild/angular/diagnostics.js +0 -69
  109. package/src/tools/esbuild/angular/file-reference-tracker.d.ts +0 -17
  110. package/src/tools/esbuild/angular/file-reference-tracker.js +0 -57
  111. package/src/tools/esbuild/angular/jit-plugin-callbacks.d.ts +0 -23
  112. package/src/tools/esbuild/angular/jit-plugin-callbacks.js +0 -117
  113. package/src/tools/esbuild/angular/jit-resource-transformer.d.ts +0 -17
  114. package/src/tools/esbuild/angular/jit-resource-transformer.js +0 -186
  115. package/src/tools/esbuild/angular/source-file-cache.d.ts +0 -18
  116. package/src/tools/esbuild/angular/source-file-cache.js +0 -65
  117. package/src/tools/esbuild/angular/uri.d.ts +0 -54
  118. package/src/tools/esbuild/angular/uri.js +0 -74
  119. package/src/tools/esbuild/angular/web-worker-transformer.d.ts +0 -17
  120. package/src/tools/esbuild/angular/web-worker-transformer.js +0 -94
  121. package/src/tools/esbuild/application-code-bundle.d.ts +0 -20
  122. package/src/tools/esbuild/application-code-bundle.js +0 -368
  123. package/src/tools/esbuild/budget-stats.d.ts +0 -19
  124. package/src/tools/esbuild/budget-stats.js +0 -59
  125. package/src/tools/esbuild/bundler-context.d.ts +0 -75
  126. package/src/tools/esbuild/bundler-context.js +0 -366
  127. package/src/tools/esbuild/bundler-execution-result.d.ts +0 -71
  128. package/src/tools/esbuild/bundler-execution-result.js +0 -131
  129. package/src/tools/esbuild/cache.d.ts +0 -88
  130. package/src/tools/esbuild/cache.js +0 -92
  131. package/src/tools/esbuild/commonjs-checker.d.ts +0 -28
  132. package/src/tools/esbuild/commonjs-checker.js +0 -151
  133. package/src/tools/esbuild/compiler-plugin-options.d.ts +0 -16
  134. package/src/tools/esbuild/compiler-plugin-options.js +0 -49
  135. package/src/tools/esbuild/external-packages-plugin.d.ts +0 -18
  136. package/src/tools/esbuild/external-packages-plugin.js +0 -70
  137. package/src/tools/esbuild/global-scripts.d.ts +0 -16
  138. package/src/tools/esbuild/global-scripts.js +0 -142
  139. package/src/tools/esbuild/global-styles.d.ts +0 -10
  140. package/src/tools/esbuild/global-styles.js +0 -74
  141. package/src/tools/esbuild/i18n-inliner-worker.d.ts +0 -42
  142. package/src/tools/esbuild/i18n-inliner-worker.js +0 -136
  143. package/src/tools/esbuild/i18n-inliner.d.ts +0 -44
  144. package/src/tools/esbuild/i18n-inliner.js +0 -150
  145. package/src/tools/esbuild/i18n-locale-plugin.d.ts +0 -22
  146. package/src/tools/esbuild/i18n-locale-plugin.js +0 -120
  147. package/src/tools/esbuild/index-html-generator.d.ts +0 -15
  148. package/src/tools/esbuild/index-html-generator.js +0 -129
  149. package/src/tools/esbuild/javascript-transformer-worker.d.ts +0 -19
  150. package/src/tools/esbuild/javascript-transformer-worker.js +0 -154
  151. package/src/tools/esbuild/javascript-transformer.d.ts +0 -54
  152. package/src/tools/esbuild/javascript-transformer.js +0 -143
  153. package/src/tools/esbuild/license-extractor.d.ts +0 -25
  154. package/src/tools/esbuild/license-extractor.js +0 -158
  155. package/src/tools/esbuild/load-result-cache.d.ts +0 -21
  156. package/src/tools/esbuild/load-result-cache.js +0 -75
  157. package/src/tools/esbuild/profiling.d.ts +0 -11
  158. package/src/tools/esbuild/profiling.js +0 -78
  159. package/src/tools/esbuild/rxjs-esm-resolution-plugin.d.ts +0 -18
  160. package/src/tools/esbuild/rxjs-esm-resolution-plugin.js +0 -44
  161. package/src/tools/esbuild/sourcemap-ignorelist-plugin.d.ts +0 -17
  162. package/src/tools/esbuild/sourcemap-ignorelist-plugin.js +0 -73
  163. package/src/tools/esbuild/stylesheets/bundle-options.d.ts +0 -35
  164. package/src/tools/esbuild/stylesheets/bundle-options.js +0 -64
  165. package/src/tools/esbuild/stylesheets/css-inline-fonts-plugin.d.ts +0 -25
  166. package/src/tools/esbuild/stylesheets/css-inline-fonts-plugin.js +0 -57
  167. package/src/tools/esbuild/stylesheets/css-language.d.ts +0 -9
  168. package/src/tools/esbuild/stylesheets/css-language.js +0 -15
  169. package/src/tools/esbuild/stylesheets/css-resource-plugin.d.ts +0 -18
  170. package/src/tools/esbuild/stylesheets/css-resource-plugin.js +0 -107
  171. package/src/tools/esbuild/stylesheets/less-language.d.ts +0 -9
  172. package/src/tools/esbuild/stylesheets/less-language.js +0 -155
  173. package/src/tools/esbuild/stylesheets/sass-language.d.ts +0 -10
  174. package/src/tools/esbuild/stylesheets/sass-language.js +0 -185
  175. package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.d.ts +0 -58
  176. package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js +0 -282
  177. package/src/tools/esbuild/utils.d.ts +0 -41
  178. package/src/tools/esbuild/utils.js +0 -378
  179. package/src/tools/esbuild/virtual-module-plugin.d.ts +0 -33
  180. package/src/tools/esbuild/virtual-module-plugin.js +0 -43
  181. package/src/tools/esbuild/watcher.d.ts +0 -25
  182. package/src/tools/esbuild/watcher.js +0 -118
  183. package/src/tools/sass/lexer.d.ts +0 -18
  184. package/src/tools/sass/lexer.js +0 -161
  185. package/src/tools/sass/rebasing-importer.d.ts +0 -101
  186. package/src/tools/sass/rebasing-importer.js +0 -337
  187. package/src/tools/sass/sass-service.d.ts +0 -49
  188. package/src/tools/sass/sass-service.js +0 -213
  189. package/src/tools/sass/worker.d.ts +0 -8
  190. package/src/tools/sass/worker.js +0 -164
  191. package/src/tools/vite/angular-memory-plugin.d.ts +0 -24
  192. package/src/tools/vite/angular-memory-plugin.js +0 -268
  193. package/src/tools/vite/i18n-locale-plugin.d.ts +0 -18
  194. package/src/tools/vite/i18n-locale-plugin.js +0 -55
  195. package/src/typings.d.ts +0 -21
  196. package/src/utils/bundle-calculator.d.ts +0 -44
  197. package/src/utils/bundle-calculator.js +0 -302
  198. package/src/utils/check-port.d.ts +0 -8
  199. package/src/utils/check-port.js +0 -58
  200. package/src/utils/delete-output-dir.d.ts +0 -11
  201. package/src/utils/delete-output-dir.js +0 -46
  202. package/src/utils/i18n-options.d.ts +0 -40
  203. package/src/utils/i18n-options.js +0 -254
  204. package/src/utils/index-file/augment-index-html.d.ts +0 -40
  205. package/src/utils/index-file/augment-index-html.js +0 -238
  206. package/src/utils/index-file/html-rewriting-stream.d.ts +0 -11
  207. package/src/utils/index-file/html-rewriting-stream.js +0 -28
  208. package/src/utils/index-file/index-html-generator.d.ts +0 -47
  209. package/src/utils/index-file/index-html-generator.js +0 -119
  210. package/src/utils/index-file/inline-critical-css.d.ts +0 -24
  211. package/src/utils/index-file/inline-critical-css.js +0 -179
  212. package/src/utils/index-file/inline-fonts.d.ts +0 -23
  213. package/src/utils/index-file/inline-fonts.js +0 -267
  214. package/src/utils/index-file/style-nonce.d.ts +0 -12
  215. package/src/utils/index-file/style-nonce.js +0 -53
  216. package/src/utils/load-proxy-config.d.ts +0 -8
  217. package/src/utils/load-proxy-config.js +0 -192
  218. package/src/utils/load-translations.d.ts +0 -16
  219. package/src/utils/load-translations.js +0 -84
  220. package/src/utils/postcss-configuration.d.ts +0 -17
  221. package/src/utils/postcss-configuration.js +0 -86
  222. package/src/utils/purge-cache.d.ts +0 -10
  223. package/src/utils/purge-cache.js +0 -40
  224. package/src/utils/routes-extractor/extractor.d.ts +0 -15
  225. package/src/utils/routes-extractor/extractor.js +0 -97
  226. package/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.d.ts +0 -18
  227. package/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.js +0 -129
  228. package/src/utils/server-rendering/esm-in-memory-loader/register-hooks.d.ts +0 -8
  229. package/src/utils/server-rendering/esm-in-memory-loader/register-hooks.js +0 -13
  230. package/src/utils/server-rendering/fetch-patch.d.ts +0 -8
  231. package/src/utils/server-rendering/fetch-patch.js +0 -66
  232. package/src/utils/server-rendering/load-esm-from-memory.d.ts +0 -10
  233. package/src/utils/server-rendering/load-esm-from-memory.js +0 -26
  234. package/src/utils/server-rendering/main-bundle-exports.d.ts +0 -27
  235. package/src/utils/server-rendering/main-bundle-exports.js +0 -9
  236. package/src/utils/server-rendering/prerender.d.ts +0 -23
  237. package/src/utils/server-rendering/prerender.js +0 -192
  238. package/src/utils/server-rendering/render-page.d.ts +0 -26
  239. package/src/utils/server-rendering/render-page.js +0 -110
  240. package/src/utils/server-rendering/render-worker.d.ts +0 -22
  241. package/src/utils/server-rendering/render-worker.js +0 -30
  242. package/src/utils/server-rendering/routes-extractor-worker.d.ts +0 -21
  243. package/src/utils/server-rendering/routes-extractor-worker.js +0 -53
  244. package/src/utils/service-worker.d.ts +0 -25
  245. package/src/utils/service-worker.js +0 -211
  246. package/src/utils/supported-browsers.d.ts +0 -10
  247. package/src/utils/supported-browsers.js +0 -42
  248. package/src/utils/version.d.ts +0 -8
  249. package/src/utils/version.js +0 -59
@@ -1,119 +0,0 @@
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.io/license
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.IndexHtmlGenerator = void 0;
11
- const promises_1 = require("node:fs/promises");
12
- const node_path_1 = require("node:path");
13
- const augment_index_html_1 = require("./augment-index-html");
14
- const inline_critical_css_1 = require("./inline-critical-css");
15
- const inline_fonts_1 = require("./inline-fonts");
16
- const style_nonce_1 = require("./style-nonce");
17
- class IndexHtmlGenerator {
18
- options;
19
- plugins;
20
- constructor(options) {
21
- this.options = options;
22
- const extraPlugins = [];
23
- if (this.options.optimization?.fonts.inline) {
24
- extraPlugins.push(inlineFontsPlugin(this));
25
- }
26
- if (this.options.optimization?.styles.inlineCritical) {
27
- extraPlugins.push(inlineCriticalCssPlugin(this));
28
- }
29
- this.plugins = [
30
- augmentIndexHtmlPlugin(this),
31
- ...extraPlugins,
32
- // Runs after the `extraPlugins` to capture any nonce or
33
- // `style` tags that might've been added by them.
34
- addStyleNoncePlugin(),
35
- postTransformPlugin(this),
36
- ];
37
- }
38
- async process(options) {
39
- let content = await this.readIndex(this.options.indexPath);
40
- const warnings = [];
41
- const errors = [];
42
- for (const plugin of this.plugins) {
43
- const result = await plugin(content, options);
44
- if (typeof result === 'string') {
45
- content = result;
46
- }
47
- else {
48
- content = result.content;
49
- if (result.warnings.length) {
50
- warnings.push(...result.warnings);
51
- }
52
- if (result.errors.length) {
53
- errors.push(...result.errors);
54
- }
55
- }
56
- }
57
- return {
58
- content,
59
- warnings,
60
- errors,
61
- };
62
- }
63
- async readAsset(path) {
64
- try {
65
- return await (0, promises_1.readFile)(path, 'utf-8');
66
- }
67
- catch {
68
- throw new Error(`Failed to read asset "${path}".`);
69
- }
70
- }
71
- async readIndex(path) {
72
- try {
73
- return new TextDecoder('utf-8').decode(await (0, promises_1.readFile)(path));
74
- }
75
- catch (cause) {
76
- throw new Error(`Failed to read index HTML file "${path}".`, { cause });
77
- }
78
- }
79
- }
80
- exports.IndexHtmlGenerator = IndexHtmlGenerator;
81
- function augmentIndexHtmlPlugin(generator) {
82
- const { deployUrl, crossOrigin, sri = false, entrypoints, imageDomains } = generator.options;
83
- return async (html, options) => {
84
- const { lang, baseHref, outputPath = '', files, hints } = options;
85
- return (0, augment_index_html_1.augmentIndexHtml)({
86
- html,
87
- baseHref,
88
- deployUrl,
89
- crossOrigin,
90
- sri,
91
- lang,
92
- entrypoints,
93
- loadOutputFile: (filePath) => generator.readAsset((0, node_path_1.join)(outputPath, filePath)),
94
- imageDomains,
95
- files,
96
- hints,
97
- });
98
- };
99
- }
100
- function inlineFontsPlugin({ options }) {
101
- const inlineFontsProcessor = new inline_fonts_1.InlineFontsProcessor({
102
- minify: options.optimization?.styles.minify,
103
- });
104
- return async (html) => inlineFontsProcessor.process(html);
105
- }
106
- function inlineCriticalCssPlugin(generator) {
107
- const inlineCriticalCssProcessor = new inline_critical_css_1.InlineCriticalCssProcessor({
108
- minify: generator.options.optimization?.styles.minify,
109
- deployUrl: generator.options.deployUrl,
110
- readAsset: (filePath) => generator.readAsset(filePath),
111
- });
112
- return async (html, options) => inlineCriticalCssProcessor.process(html, { outputPath: options.outputPath });
113
- }
114
- function addStyleNoncePlugin() {
115
- return (html) => (0, style_nonce_1.addStyleNonce)(html);
116
- }
117
- function postTransformPlugin({ options }) {
118
- return async (html) => (options.postTransform ? options.postTransform(html) : html);
119
- }
@@ -1,24 +0,0 @@
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.io/license
7
- */
8
- export interface InlineCriticalCssProcessOptions {
9
- outputPath: string;
10
- }
11
- export interface InlineCriticalCssProcessorOptions {
12
- minify?: boolean;
13
- deployUrl?: string;
14
- readAsset?: (path: string) => Promise<string>;
15
- }
16
- export declare class InlineCriticalCssProcessor {
17
- protected readonly options: InlineCriticalCssProcessorOptions;
18
- constructor(options: InlineCriticalCssProcessorOptions);
19
- process(html: string, options: InlineCriticalCssProcessOptions): Promise<{
20
- content: string;
21
- warnings: string[];
22
- errors: string[];
23
- }>;
24
- }
@@ -1,179 +0,0 @@
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.io/license
8
- */
9
- var __importDefault = (this && this.__importDefault) || function (mod) {
10
- return (mod && mod.__esModule) ? mod : { "default": mod };
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.InlineCriticalCssProcessor = void 0;
14
- const critters_1 = __importDefault(require("critters"));
15
- const promises_1 = require("node:fs/promises");
16
- /**
17
- * Pattern used to extract the media query set by Critters in an `onload` handler.
18
- */
19
- const MEDIA_SET_HANDLER_PATTERN = /^this\.media=["'](.*)["'];?$/;
20
- /**
21
- * Name of the attribute used to save the Critters media query so it can be re-assigned on load.
22
- */
23
- const CSP_MEDIA_ATTR = 'ngCspMedia';
24
- /**
25
- * Script text used to change the media value of the link tags.
26
- *
27
- * NOTE:
28
- * We do not use `document.querySelectorAll('link').forEach((s) => s.addEventListener('load', ...)`
29
- * because this does not always fire on Chome.
30
- * See: https://github.com/angular/angular-cli/issues/26932 and https://crbug.com/1521256
31
- */
32
- const LINK_LOAD_SCRIPT_CONTENT = [
33
- '(() => {',
34
- ` const CSP_MEDIA_ATTR = '${CSP_MEDIA_ATTR}';`,
35
- ' const documentElement = document.documentElement;',
36
- ' const listener = (e) => {',
37
- ' const target = e.target;',
38
- ` if (!target || target.tagName !== 'LINK' || !target.hasAttribute(CSP_MEDIA_ATTR)) {`,
39
- ' return;',
40
- ' }',
41
- ' target.media = target.getAttribute(CSP_MEDIA_ATTR);',
42
- ' target.removeAttribute(CSP_MEDIA_ATTR);',
43
- // Remove onload listener when there are no longer styles that need to be loaded.
44
- ' if (!document.head.querySelector(`link[${CSP_MEDIA_ATTR}]`)) {',
45
- ` documentElement.removeEventListener('load', listener);`,
46
- ' }',
47
- ' };',
48
- // We use an event with capturing (the true parameter) because load events don't bubble.
49
- ` documentElement.addEventListener('load', listener, true);`,
50
- '})();',
51
- ].join('\n');
52
- class CrittersExtended extends critters_1.default {
53
- optionsExtended;
54
- warnings = [];
55
- errors = [];
56
- initialEmbedLinkedStylesheet;
57
- addedCspScriptsDocuments = new WeakSet();
58
- documentNonces = new WeakMap();
59
- constructor(optionsExtended) {
60
- super({
61
- logger: {
62
- warn: (s) => this.warnings.push(s),
63
- error: (s) => this.errors.push(s),
64
- info: () => { },
65
- },
66
- logLevel: 'warn',
67
- path: optionsExtended.outputPath,
68
- publicPath: optionsExtended.deployUrl,
69
- compress: !!optionsExtended.minify,
70
- pruneSource: false,
71
- reduceInlineStyles: false,
72
- mergeStylesheets: false,
73
- // Note: if `preload` changes to anything other than `media`, the logic in
74
- // `embedLinkedStylesheetOverride` will have to be updated.
75
- preload: 'media',
76
- noscriptFallback: true,
77
- inlineFonts: true,
78
- });
79
- this.optionsExtended = optionsExtended;
80
- // We can't use inheritance to override `embedLinkedStylesheet`, because it's not declared in
81
- // the `Critters` .d.ts which means that we can't call the `super` implementation. TS doesn't
82
- // allow for `super` to be cast to a different type.
83
- this.initialEmbedLinkedStylesheet = this.embedLinkedStylesheet;
84
- this.embedLinkedStylesheet = this.embedLinkedStylesheetOverride;
85
- }
86
- readFile(path) {
87
- const readAsset = this.optionsExtended.readAsset;
88
- return readAsset ? readAsset(path) : (0, promises_1.readFile)(path, 'utf-8');
89
- }
90
- /**
91
- * Override of the Critters `embedLinkedStylesheet` method
92
- * that makes it work with Angular's CSP APIs.
93
- */
94
- embedLinkedStylesheetOverride = async (link, document) => {
95
- if (link.getAttribute('media') === 'print' && link.next?.name === 'noscript') {
96
- // Workaround for https://github.com/GoogleChromeLabs/critters/issues/64
97
- // NB: this is only needed for the webpack based builders.
98
- const media = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN);
99
- if (media) {
100
- link.removeAttribute('onload');
101
- link.setAttribute('media', media[1]);
102
- link?.next?.remove();
103
- }
104
- }
105
- const returnValue = await this.initialEmbedLinkedStylesheet(link, document);
106
- const cspNonce = this.findCspNonce(document);
107
- if (cspNonce) {
108
- const crittersMedia = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN);
109
- if (crittersMedia) {
110
- // If there's a Critters-generated `onload` handler and the file has an Angular CSP nonce,
111
- // we have to remove the handler, because it's incompatible with CSP. We save the value
112
- // in a different attribute and we generate a script tag with the nonce that uses
113
- // `addEventListener` to apply the media query instead.
114
- link.removeAttribute('onload');
115
- link.setAttribute(CSP_MEDIA_ATTR, crittersMedia[1]);
116
- this.conditionallyInsertCspLoadingScript(document, cspNonce, link);
117
- }
118
- // Ideally we would hook in at the time Critters inserts the `style` tags, but there isn't
119
- // a way of doing that at the moment so we fall back to doing it any time a `link` tag is
120
- // inserted. We mitigate it by only iterating the direct children of the `<head>` which
121
- // should be pretty shallow.
122
- document.head.children.forEach((child) => {
123
- if (child.tagName === 'style' && !child.hasAttribute('nonce')) {
124
- child.setAttribute('nonce', cspNonce);
125
- }
126
- });
127
- }
128
- return returnValue;
129
- };
130
- /**
131
- * Finds the CSP nonce for a specific document.
132
- */
133
- findCspNonce(document) {
134
- if (this.documentNonces.has(document)) {
135
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
136
- return this.documentNonces.get(document);
137
- }
138
- // HTML attribute are case-insensitive, but the parser used by Critters is case-sensitive.
139
- const nonceElement = document.querySelector('[ngCspNonce], [ngcspnonce]');
140
- const cspNonce = nonceElement?.getAttribute('ngCspNonce') || nonceElement?.getAttribute('ngcspnonce') || null;
141
- this.documentNonces.set(document, cspNonce);
142
- return cspNonce;
143
- }
144
- /**
145
- * Inserts the `script` tag that swaps the critical CSS at runtime,
146
- * if one hasn't been inserted into the document already.
147
- */
148
- conditionallyInsertCspLoadingScript(document, nonce, link) {
149
- if (this.addedCspScriptsDocuments.has(document)) {
150
- return;
151
- }
152
- const script = document.createElement('script');
153
- script.setAttribute('nonce', nonce);
154
- script.textContent = LINK_LOAD_SCRIPT_CONTENT;
155
- // Prepend the script to the head since it needs to
156
- // run as early as possible, before the `link` tags.
157
- document.head.insertBefore(script, link);
158
- this.addedCspScriptsDocuments.add(document);
159
- }
160
- }
161
- class InlineCriticalCssProcessor {
162
- options;
163
- constructor(options) {
164
- this.options = options;
165
- }
166
- async process(html, options) {
167
- const critters = new CrittersExtended({ ...this.options, ...options });
168
- const content = await critters.process(html);
169
- return {
170
- // Clean up value from value less attributes.
171
- // This is caused because parse5 always requires attributes to have a string value.
172
- // nomodule="" defer="" -> nomodule defer.
173
- content: content.replace(/(\s(?:defer|nomodule))=""/g, '$1'),
174
- errors: critters.errors,
175
- warnings: critters.warnings,
176
- };
177
- }
178
- }
179
- exports.InlineCriticalCssProcessor = InlineCriticalCssProcessor;
@@ -1,23 +0,0 @@
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.io/license
7
- */
8
- import { NormalizedCachedOptions } from '../normalize-cache';
9
- export interface InlineFontsOptions {
10
- minify?: boolean;
11
- cache?: NormalizedCachedOptions;
12
- }
13
- export declare class InlineFontsProcessor {
14
- private options;
15
- private readonly cachePath;
16
- constructor(options: InlineFontsOptions);
17
- process(content: string): Promise<string>;
18
- private getResponse;
19
- processURL(url: string | URL): Promise<string | undefined>;
20
- canInlineRequest(url: string): boolean;
21
- private getFontProviderDetails;
22
- private createNormalizedUrl;
23
- }
@@ -1,267 +0,0 @@
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.io/license
8
- */
9
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- var desc = Object.getOwnPropertyDescriptor(m, k);
12
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
- desc = { enumerable: true, get: function() { return m[k]; } };
14
- }
15
- Object.defineProperty(o, k2, desc);
16
- }) : (function(o, m, k, k2) {
17
- if (k2 === undefined) k2 = k;
18
- o[k2] = m[k];
19
- }));
20
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
- Object.defineProperty(o, "default", { enumerable: true, value: v });
22
- }) : function(o, v) {
23
- o["default"] = v;
24
- });
25
- var __importStar = (this && this.__importStar) || function (mod) {
26
- if (mod && mod.__esModule) return mod;
27
- var result = {};
28
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
- __setModuleDefault(result, mod);
30
- return result;
31
- };
32
- Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.InlineFontsProcessor = void 0;
34
- const https_proxy_agent_1 = require("https-proxy-agent");
35
- const node_crypto_1 = require("node:crypto");
36
- const promises_1 = require("node:fs/promises");
37
- const https = __importStar(require("node:https"));
38
- const node_path_1 = require("node:path");
39
- const html_rewriting_stream_1 = require("./html-rewriting-stream");
40
- const SUPPORTED_PROVIDERS = {
41
- 'fonts.googleapis.com': {
42
- preconnectUrl: 'https://fonts.gstatic.com',
43
- },
44
- 'use.typekit.net': {
45
- preconnectUrl: 'https://use.typekit.net',
46
- },
47
- };
48
- /**
49
- * Hash algorithm used for cached files.
50
- */
51
- const CONTENT_HASH_ALGORITHM = 'sha256';
52
- /**
53
- * String length of the SHA-256 content hash stored in cached files.
54
- */
55
- const CONTENT_HASH_LENGTH = 64;
56
- class InlineFontsProcessor {
57
- options;
58
- cachePath;
59
- constructor(options) {
60
- this.options = options;
61
- const { path: cacheDirectory, enabled } = this.options.cache || {};
62
- if (cacheDirectory && enabled) {
63
- this.cachePath = (0, node_path_1.join)(cacheDirectory, 'angular-build-fonts');
64
- }
65
- }
66
- async process(content) {
67
- const hrefList = [];
68
- const existingPreconnect = new Set();
69
- // Collector link tags with href
70
- const { rewriter: collectorStream, transformedContent: initCollectorStream } = await (0, html_rewriting_stream_1.htmlRewritingStream)(content);
71
- collectorStream.on('startTag', (tag) => {
72
- const { tagName, attrs } = tag;
73
- if (tagName !== 'link') {
74
- return;
75
- }
76
- let hrefValue;
77
- let relValue;
78
- for (const { name, value } of attrs) {
79
- switch (name) {
80
- case 'rel':
81
- relValue = value;
82
- break;
83
- case 'href':
84
- hrefValue = value;
85
- break;
86
- }
87
- if (hrefValue && relValue) {
88
- switch (relValue) {
89
- case 'stylesheet':
90
- // <link rel="stylesheet" href="https://example.com/main.css">
91
- hrefList.push(hrefValue);
92
- break;
93
- case 'preconnect':
94
- // <link rel="preconnect" href="https://example.com">
95
- existingPreconnect.add(hrefValue.replace(/\/$/, ''));
96
- break;
97
- }
98
- return;
99
- }
100
- }
101
- });
102
- initCollectorStream().catch(() => {
103
- // We don't really care about any errors here because it just initializes
104
- // the rewriting stream, as we are waiting for `finish` below.
105
- });
106
- await new Promise((resolve) => collectorStream.on('finish', resolve));
107
- // Download stylesheets
108
- const hrefsContent = new Map();
109
- const newPreconnectUrls = new Set();
110
- for (const hrefItem of hrefList) {
111
- const url = this.createNormalizedUrl(hrefItem);
112
- if (!url) {
113
- continue;
114
- }
115
- const content = await this.processURL(url);
116
- if (content === undefined) {
117
- continue;
118
- }
119
- hrefsContent.set(hrefItem, content);
120
- // Add preconnect
121
- const preconnectUrl = this.getFontProviderDetails(url)?.preconnectUrl;
122
- if (preconnectUrl && !existingPreconnect.has(preconnectUrl)) {
123
- newPreconnectUrls.add(preconnectUrl);
124
- }
125
- }
126
- if (hrefsContent.size === 0) {
127
- return content;
128
- }
129
- // Replace link with style tag.
130
- const { rewriter, transformedContent } = await (0, html_rewriting_stream_1.htmlRewritingStream)(content);
131
- rewriter.on('startTag', (tag) => {
132
- const { tagName, attrs } = tag;
133
- switch (tagName) {
134
- case 'head':
135
- rewriter.emitStartTag(tag);
136
- for (const url of newPreconnectUrls) {
137
- rewriter.emitRaw(`<link rel="preconnect" href="${url}" crossorigin>`);
138
- }
139
- break;
140
- case 'link':
141
- const hrefAttr = attrs.some(({ name, value }) => name === 'rel' && value === 'stylesheet') &&
142
- attrs.find(({ name, value }) => name === 'href' && hrefsContent.has(value));
143
- if (hrefAttr) {
144
- const href = hrefAttr.value;
145
- const cssContent = hrefsContent.get(href);
146
- rewriter.emitRaw(`<style type="text/css">${cssContent}</style>`);
147
- }
148
- else {
149
- rewriter.emitStartTag(tag);
150
- }
151
- break;
152
- default:
153
- rewriter.emitStartTag(tag);
154
- break;
155
- }
156
- });
157
- return transformedContent();
158
- }
159
- async getResponse(url) {
160
- let cacheFile;
161
- if (this.cachePath) {
162
- const key = (0, node_crypto_1.createHash)(CONTENT_HASH_ALGORITHM).update(`${url}`).digest('hex');
163
- cacheFile = (0, node_path_1.join)(this.cachePath, key);
164
- }
165
- if (cacheFile) {
166
- try {
167
- const data = await (0, promises_1.readFile)(cacheFile, 'utf8');
168
- // Check for valid content via stored hash
169
- if (data.length > CONTENT_HASH_LENGTH) {
170
- const storedHash = data.slice(0, CONTENT_HASH_LENGTH);
171
- const content = data.slice(CONTENT_HASH_LENGTH);
172
- const contentHash = (0, node_crypto_1.createHash)(CONTENT_HASH_ALGORITHM).update(content).digest('base64');
173
- if (storedHash === contentHash) {
174
- // Return valid content
175
- return content;
176
- }
177
- else {
178
- // Delete corrupted cache content
179
- await (0, promises_1.rm)(cacheFile);
180
- }
181
- }
182
- }
183
- catch { }
184
- }
185
- let agent;
186
- const httpsProxy = process.env.HTTPS_PROXY ?? process.env.https_proxy;
187
- if (httpsProxy) {
188
- agent = new https_proxy_agent_1.HttpsProxyAgent(httpsProxy);
189
- }
190
- const data = await new Promise((resolve, reject) => {
191
- let rawResponse = '';
192
- https
193
- .get(url, {
194
- agent,
195
- headers: {
196
- /**
197
- * Always use a Windows UA. This is because Google fonts will including hinting in fonts for Windows.
198
- * Hinting is a technique used with Windows files to improve appearance however
199
- * results in 20-50% larger file sizes.
200
- *
201
- * @see http://google3/java/com/google/fonts/css/OpenSansWebFontsCssBuilder.java?l=22
202
- * @see https://fonts.google.com/knowledge/glossary/hinting (short)
203
- * @see https://glyphsapp.com/learn/hinting-manual-truetype-hinting (deep dive)
204
- */
205
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
206
- },
207
- }, (res) => {
208
- if (res.statusCode !== 200) {
209
- reject(new Error(`Inlining of fonts failed. ${url} returned status code: ${res.statusCode}.`));
210
- return;
211
- }
212
- res.on('data', (chunk) => (rawResponse += chunk)).on('end', () => resolve(rawResponse));
213
- })
214
- .on('error', (e) => reject(new Error(`Inlining of fonts failed. An error has occurred while retrieving ${url} over the internet.\n` +
215
- e.message)));
216
- });
217
- if (cacheFile) {
218
- try {
219
- const dataHash = (0, node_crypto_1.createHash)(CONTENT_HASH_ALGORITHM).update(data).digest('hex');
220
- await (0, promises_1.writeFile)(cacheFile, dataHash + data);
221
- }
222
- catch { }
223
- }
224
- return data;
225
- }
226
- async processURL(url) {
227
- const normalizedURL = url instanceof URL ? url : this.createNormalizedUrl(url);
228
- if (!normalizedURL) {
229
- return;
230
- }
231
- const provider = this.getFontProviderDetails(normalizedURL);
232
- if (!provider) {
233
- return undefined;
234
- }
235
- let cssContent = await this.getResponse(normalizedURL);
236
- if (this.options.minify) {
237
- cssContent = cssContent
238
- // Comments.
239
- .replace(/\/\*([\s\S]*?)\*\//g, '')
240
- // New lines.
241
- .replace(/\n/g, '')
242
- // Safe spaces.
243
- .replace(/\s?[{:;]\s+/g, (s) => s.trim());
244
- }
245
- return cssContent;
246
- }
247
- canInlineRequest(url) {
248
- const normalizedUrl = this.createNormalizedUrl(url);
249
- return normalizedUrl ? !!this.getFontProviderDetails(normalizedUrl) : false;
250
- }
251
- getFontProviderDetails(url) {
252
- return SUPPORTED_PROVIDERS[url.hostname];
253
- }
254
- createNormalizedUrl(value) {
255
- // Need to convert '//' to 'https://' because the URL parser will fail with '//'.
256
- const url = new URL(value.startsWith('//') ? `https:${value}` : value, 'resolve://');
257
- switch (url.protocol) {
258
- case 'http:':
259
- case 'https:':
260
- url.protocol = 'https:';
261
- return url;
262
- default:
263
- return undefined;
264
- }
265
- }
266
- }
267
- exports.InlineFontsProcessor = InlineFontsProcessor;
@@ -1,12 +0,0 @@
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.io/license
7
- */
8
- /**
9
- * Finds the `ngCspNonce` value and copies it to all inline `<style>` tags.
10
- * @param html Markup that should be processed.
11
- */
12
- export declare function addStyleNonce(html: string): Promise<string>;
@@ -1,53 +0,0 @@
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.io/license
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.addStyleNonce = void 0;
11
- const html_rewriting_stream_1 = require("./html-rewriting-stream");
12
- /**
13
- * Pattern matching the name of the Angular nonce attribute. Note that this is
14
- * case-insensitive, because HTML attribute names are case-insensitive as well.
15
- */
16
- const NONCE_ATTR_PATTERN = /ngCspNonce/i;
17
- /**
18
- * Finds the `ngCspNonce` value and copies it to all inline `<style>` tags.
19
- * @param html Markup that should be processed.
20
- */
21
- async function addStyleNonce(html) {
22
- const nonce = await findNonce(html);
23
- if (!nonce) {
24
- return html;
25
- }
26
- const { rewriter, transformedContent } = await (0, html_rewriting_stream_1.htmlRewritingStream)(html);
27
- rewriter.on('startTag', (tag) => {
28
- if (tag.tagName === 'style' && !tag.attrs.some((attr) => attr.name === 'nonce')) {
29
- tag.attrs.push({ name: 'nonce', value: nonce });
30
- }
31
- rewriter.emitStartTag(tag);
32
- });
33
- return transformedContent();
34
- }
35
- exports.addStyleNonce = addStyleNonce;
36
- /** Finds the Angular nonce in an HTML string. */
37
- async function findNonce(html) {
38
- // Inexpensive check to avoid parsing the HTML when we're sure there's no nonce.
39
- if (!NONCE_ATTR_PATTERN.test(html)) {
40
- return null;
41
- }
42
- const { rewriter, transformedContent } = await (0, html_rewriting_stream_1.htmlRewritingStream)(html);
43
- let nonce = null;
44
- rewriter.on('startTag', (tag) => {
45
- const nonceAttr = tag.attrs.find((attr) => NONCE_ATTR_PATTERN.test(attr.name));
46
- if (nonceAttr?.value) {
47
- nonce = nonceAttr.value;
48
- rewriter.stop(); // Stop parsing since we've found the nonce.
49
- }
50
- });
51
- await transformedContent();
52
- return nonce;
53
- }