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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/package.json +18 -18
  2. package/src/builders/application/execute-build.js +2 -4
  3. package/src/builders/application/execute-post-bundle.js +9 -12
  4. package/src/builders/application/options.js +42 -25
  5. package/src/builders/browser/index.js +1 -1
  6. package/src/builders/dev-server/vite-server.js +3 -3
  7. package/src/builders/dev-server/webpack-server.js +2 -2
  8. package/src/builders/ssr-dev-server/index.js +28 -28
  9. package/src/tools/esbuild/angular/compiler-plugin.js +12 -4
  10. package/src/tools/esbuild/index-html-generator.d.ts +2 -2
  11. package/src/tools/esbuild/index-html-generator.js +5 -53
  12. package/src/tools/esbuild/javascript-transformer.js +5 -1
  13. package/src/tools/esbuild/stylesheets/css-resource-plugin.js +15 -8
  14. package/src/tools/esbuild/utils.js +2 -2
  15. package/src/tools/sass/rebasing-importer.js +3 -6
  16. package/src/tools/sass/sass-service.d.ts +24 -1
  17. package/src/tools/sass/worker.js +32 -4
  18. package/src/tools/webpack/plugins/any-component-style-budget-checker.d.ts +2 -2
  19. package/src/tools/webpack/plugins/any-component-style-budget-checker.js +13 -16
  20. package/src/tools/webpack/plugins/index-html-webpack-plugin.js +1 -1
  21. package/src/tools/webpack/utils/stats.d.ts +0 -13
  22. package/src/tools/webpack/utils/stats.js +3 -207
  23. package/src/utils/action-executor.d.ts +1 -1
  24. package/src/utils/bundle-calculator.d.ts +5 -5
  25. package/src/utils/bundle-calculator.js +8 -7
  26. package/src/utils/format-bytes.d.ts +8 -0
  27. package/src/utils/format-bytes.js +22 -0
  28. package/src/utils/i18n-inlining.d.ts +1 -1
  29. package/src/utils/i18n-options.d.ts +2 -9
  30. package/src/utils/i18n-options.js +4 -97
  31. package/src/utils/i18n-webpack.d.ts +16 -0
  32. package/src/utils/i18n-webpack.js +108 -0
  33. package/src/utils/index-file/add-event-dispatch-contract.d.ts +8 -0
  34. package/src/utils/index-file/add-event-dispatch-contract.js +28 -0
  35. package/src/utils/index-file/augment-index-html.js +1 -0
  36. package/src/utils/index-file/index-html-generator.d.ts +12 -2
  37. package/src/utils/index-file/index-html-generator.js +38 -22
  38. package/src/utils/index-file/inline-fonts.js +1 -1
  39. package/src/utils/index-file/{style-nonce.d.ts → nonce.d.ts} +2 -2
  40. package/src/utils/index-file/{style-nonce.js → nonce.js} +7 -5
  41. package/src/utils/load-proxy-config.d.ts +1 -1
  42. package/src/utils/load-proxy-config.js +2 -5
  43. package/src/utils/normalize-cache.js +1 -1
  44. package/src/utils/output-paths.d.ts +1 -1
  45. package/src/utils/resolve-assets.d.ts +18 -0
  46. package/src/utils/resolve-assets.js +35 -0
  47. package/src/utils/stats-table.d.ts +20 -0
  48. package/src/utils/stats-table.js +205 -0
  49. package/src/utils/webpack-browser-config.d.ts +1 -1
  50. package/src/utils/webpack-browser-config.js +2 -2
@@ -77,13 +77,15 @@ node_worker_threads_1.parentPort.on('message', (message) => {
77
77
  importer: relativeImporter,
78
78
  logger: hasLogger
79
79
  ? {
80
- warn(message, { deprecation, span, stack }) {
80
+ warn(message, warnOptions) {
81
81
  warnings ??= [];
82
82
  warnings.push({
83
+ ...warnOptions,
83
84
  message,
84
- deprecation,
85
- stack,
86
- span: span && convertSourceSpan(span),
85
+ span: warnOptions.span && convertSourceSpan(warnOptions.span),
86
+ ...convertDeprecation(warnOptions.deprecation,
87
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
88
+ warnOptions.deprecationType),
87
89
  });
88
90
  },
89
91
  }
@@ -162,3 +164,29 @@ function convertSourceSpan(span) {
162
164
  url: span.url ? (0, node_url_1.fileURLToPath)(span.url) : undefined,
163
165
  };
164
166
  }
167
+ function convertDeprecation(deprecation, deprecationType) {
168
+ if (!deprecation || !deprecationType) {
169
+ return { deprecation: false };
170
+ }
171
+ const { obsoleteIn, deprecatedIn, ...rest } = deprecationType;
172
+ return {
173
+ deprecation: true,
174
+ deprecationType: {
175
+ ...rest,
176
+ obsoleteIn: obsoleteIn
177
+ ? {
178
+ major: obsoleteIn.major,
179
+ minor: obsoleteIn.minor,
180
+ patch: obsoleteIn.patch,
181
+ }
182
+ : null,
183
+ deprecatedIn: deprecatedIn
184
+ ? {
185
+ major: deprecatedIn.major,
186
+ minor: deprecatedIn.minor,
187
+ patch: deprecatedIn.patch,
188
+ }
189
+ : null,
190
+ },
191
+ };
192
+ }
@@ -6,13 +6,13 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import { Compiler } from 'webpack';
9
- import { Budget } from '../../../builders/browser/schema';
9
+ import { BudgetEntry } from '../../../utils/bundle-calculator';
10
10
  /**
11
11
  * Check budget sizes for component styles by emitting a warning or error if a
12
12
  * budget is exceeded by a particular component's styles.
13
13
  */
14
14
  export declare class AnyComponentStyleBudgetChecker {
15
15
  private readonly budgets;
16
- constructor(budgets: Budget[]);
16
+ constructor(budgets: BudgetEntry[]);
17
17
  apply(compiler: Compiler): void;
18
18
  }
@@ -33,7 +33,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
33
33
  exports.AnyComponentStyleBudgetChecker = void 0;
34
34
  const path = __importStar(require("path"));
35
35
  const webpack_1 = require("webpack");
36
- const schema_1 = require("../../../builders/browser/schema");
37
36
  const bundle_calculator_1 = require("../../../utils/bundle-calculator");
38
37
  const webpack_diagnostics_1 = require("../../../utils/webpack-diagnostics");
39
38
  const PLUGIN_NAME = 'AnyComponentStyleBudgetChecker';
@@ -44,7 +43,7 @@ const PLUGIN_NAME = 'AnyComponentStyleBudgetChecker';
44
43
  class AnyComponentStyleBudgetChecker {
45
44
  budgets;
46
45
  constructor(budgets) {
47
- this.budgets = budgets.filter((budget) => budget.type === schema_1.Type.AnyComponentStyle);
46
+ this.budgets = budgets.filter((budget) => budget.type === bundle_calculator_1.BudgetType.AnyComponentStyle);
48
47
  }
49
48
  apply(compiler) {
50
49
  compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
@@ -64,22 +63,20 @@ class AnyComponentStyleBudgetChecker {
64
63
  const componentStyles = Object.keys(compilation.assets)
65
64
  .filter((name) => cssExtensions.includes(path.extname(name)))
66
65
  .map((name) => ({
66
+ name,
67
67
  size: compilation.assets[name].size(),
68
- label: name,
68
+ componentStyle: true,
69
69
  }));
70
- const thresholds = this.budgets.flatMap((budget) => [...(0, bundle_calculator_1.calculateThresholds)(budget)]);
71
- for (const { size, label } of componentStyles) {
72
- for (const { severity, message } of (0, bundle_calculator_1.checkThresholds)(thresholds[Symbol.iterator](), size, label)) {
73
- switch (severity) {
74
- case bundle_calculator_1.ThresholdSeverity.Warning:
75
- (0, webpack_diagnostics_1.addWarning)(compilation, message);
76
- break;
77
- case bundle_calculator_1.ThresholdSeverity.Error:
78
- (0, webpack_diagnostics_1.addError)(compilation, message);
79
- break;
80
- default:
81
- assertNever(severity);
82
- }
70
+ for (const { severity, message } of (0, bundle_calculator_1.checkBudgets)(this.budgets, { chunks: [], assets: componentStyles }, true)) {
71
+ switch (severity) {
72
+ case bundle_calculator_1.ThresholdSeverity.Warning:
73
+ (0, webpack_diagnostics_1.addWarning)(compilation, message);
74
+ break;
75
+ case bundle_calculator_1.ThresholdSeverity.Error:
76
+ (0, webpack_diagnostics_1.addError)(compilation, message);
77
+ break;
78
+ default:
79
+ assertNever(severity);
83
80
  }
84
81
  }
85
82
  });
@@ -51,7 +51,7 @@ class IndexHtmlWebpackPlugin extends index_html_generator_1.IndexHtmlGenerator {
51
51
  });
52
52
  }
53
53
  }
54
- const { content, warnings, errors } = await this.process({
54
+ const { csrContent: content, warnings, errors, } = await this.process({
55
55
  files,
56
56
  outputPath: (0, path_1.dirname)(this.options.outputPath),
57
57
  baseHref: this.options.baseHref,
@@ -11,19 +11,6 @@ import { Configuration, StatsCompilation } from 'webpack';
11
11
  import { Schema as BrowserBuilderOptions } from '../../../builders/browser/schema';
12
12
  import { BudgetCalculatorResult } from '../../../utils/bundle-calculator';
13
13
  import { WebpackStatsOptions } from './helpers';
14
- export declare function formatSize(size: number): string;
15
- export type BundleStatsData = [
16
- files: string,
17
- names: string,
18
- rawSize: number | string,
19
- estimatedTransferSize: number | string
20
- ];
21
- export interface BundleStats {
22
- initial: boolean;
23
- stats: BundleStatsData;
24
- }
25
- export declare function generateEsbuildBuildStatsTable([browserStats, serverStats]: [browserStats: BundleStats[], serverStats: BundleStats[]], colors: boolean, showTotalSize: boolean, showEstimatedTransferSize: boolean, budgetFailures?: BudgetCalculatorResult[], verbose?: boolean): string;
26
- export declare function generateBuildStatsTable(data: BundleStats[], colors: boolean, showTotalSize: boolean, showEstimatedTransferSize: boolean, budgetFailures?: BudgetCalculatorResult[]): string;
27
14
  export declare function statsWarningsToString(json: StatsCompilation, statsConfig: WebpackStatsOptions): string;
28
15
  export declare function statsErrorsToString(json: StatsCompilation, statsConfig: WebpackStatsOptions): string;
29
16
  export declare function statsHasErrors(json: StatsCompilation): boolean;
@@ -33,26 +33,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
33
33
  return (mod && mod.__esModule) ? mod : { "default": mod };
34
34
  };
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.webpackStatsLogger = exports.generateBuildEventStats = exports.createWebpackLoggingCallback = exports.statsHasWarnings = exports.statsHasErrors = exports.statsErrorsToString = exports.statsWarningsToString = exports.generateBuildStatsTable = exports.generateEsbuildBuildStatsTable = exports.formatSize = void 0;
36
+ exports.webpackStatsLogger = exports.generateBuildEventStats = exports.createWebpackLoggingCallback = exports.statsHasWarnings = exports.statsHasErrors = exports.statsErrorsToString = exports.statsWarningsToString = void 0;
37
37
  const node_assert_1 = __importDefault(require("node:assert"));
38
38
  const path = __importStar(require("node:path"));
39
- const node_util_1 = require("node:util");
40
39
  const utils_1 = require("../../../utils");
41
40
  const color_1 = require("../../../utils/color");
41
+ const stats_table_1 = require("../../../utils/stats-table");
42
42
  const async_chunks_1 = require("./async-chunks");
43
43
  const helpers_1 = require("./helpers");
44
- function formatSize(size) {
45
- if (size <= 0) {
46
- return '0 bytes';
47
- }
48
- const abbreviations = ['bytes', 'kB', 'MB', 'GB'];
49
- const index = Math.floor(Math.log(size) / Math.log(1024));
50
- const roundedSize = size / Math.pow(1024, index);
51
- // bytes don't have a fraction
52
- const fractionDigits = index === 0 ? 0 : 2;
53
- return `${roundedSize.toFixed(fractionDigits)} ${abbreviations[index]}`;
54
- }
55
- exports.formatSize = formatSize;
56
44
  function getBuildDuration(webpackStats) {
57
45
  (0, node_assert_1.default)(webpackStats.builtAt, 'buildAt cannot be undefined');
58
46
  (0, node_assert_1.default)(webpackStats.time, 'time cannot be undefined');
@@ -72,198 +60,6 @@ function generateBundleStats(info) {
72
60
  stats: [files, names, rawSize, estimatedTransferSize],
73
61
  };
74
62
  }
75
- function generateEsbuildBuildStatsTable([browserStats, serverStats], colors, showTotalSize, showEstimatedTransferSize, budgetFailures, verbose) {
76
- const bundleInfo = generateBuildStatsData(browserStats, colors, showTotalSize, showEstimatedTransferSize, budgetFailures, verbose);
77
- if (serverStats.length) {
78
- const m = (x) => (colors ? color_1.colors.magenta(x) : x);
79
- if (browserStats.length) {
80
- bundleInfo.unshift([m('Browser bundles')]);
81
- // Add seperators between browser and server logs
82
- bundleInfo.push([], []);
83
- }
84
- bundleInfo.push([m('Server bundles')], ...generateBuildStatsData(serverStats, colors, false, false, undefined, verbose));
85
- }
86
- return generateTableText(bundleInfo, colors);
87
- }
88
- exports.generateEsbuildBuildStatsTable = generateEsbuildBuildStatsTable;
89
- function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTransferSize, budgetFailures) {
90
- const bundleInfo = generateBuildStatsData(data, colors, showTotalSize, showEstimatedTransferSize, budgetFailures, true);
91
- return generateTableText(bundleInfo, colors);
92
- }
93
- exports.generateBuildStatsTable = generateBuildStatsTable;
94
- function generateBuildStatsData(data, colors, showTotalSize, showEstimatedTransferSize, budgetFailures, verbose) {
95
- if (data.length === 0) {
96
- return [];
97
- }
98
- const g = (x) => (colors ? color_1.colors.green(x) : x);
99
- const c = (x) => (colors ? color_1.colors.cyan(x) : x);
100
- const r = (x) => (colors ? color_1.colors.redBright(x) : x);
101
- const y = (x) => (colors ? color_1.colors.yellowBright(x) : x);
102
- const bold = (x) => (colors ? color_1.colors.bold(x) : x);
103
- const dim = (x) => (colors ? color_1.colors.dim(x) : x);
104
- const getSizeColor = (name, file, defaultColor = c) => {
105
- const severity = budgets.get(name) || (file && budgets.get(file));
106
- switch (severity) {
107
- case 'warning':
108
- return y;
109
- case 'error':
110
- return r;
111
- default:
112
- return defaultColor;
113
- }
114
- };
115
- const changedEntryChunksStats = [];
116
- const changedLazyChunksStats = [];
117
- let initialTotalRawSize = 0;
118
- let changedLazyChunksCount = 0;
119
- let initialTotalEstimatedTransferSize;
120
- const maxLazyChunksWithoutBudgetFailures = 15;
121
- const budgets = new Map();
122
- if (budgetFailures) {
123
- for (const { label, severity } of budgetFailures) {
124
- // In some cases a file can have multiple budget failures.
125
- // Favor error.
126
- if (label && (!budgets.has(label) || budgets.get(label) === 'warning')) {
127
- budgets.set(label, severity);
128
- }
129
- }
130
- }
131
- // Sort descending by raw size
132
- data.sort((a, b) => {
133
- if (a.stats[2] > b.stats[2]) {
134
- return -1;
135
- }
136
- if (a.stats[2] < b.stats[2]) {
137
- return 1;
138
- }
139
- return 0;
140
- });
141
- for (const { initial, stats } of data) {
142
- const [files, names, rawSize, estimatedTransferSize] = stats;
143
- if (!initial &&
144
- !verbose &&
145
- changedLazyChunksStats.length >= maxLazyChunksWithoutBudgetFailures &&
146
- !budgets.has(names) &&
147
- !budgets.has(files)) {
148
- // Limit the number of lazy chunks displayed in the stats table when there is no budget failure and not in verbose mode.
149
- changedLazyChunksCount++;
150
- continue;
151
- }
152
- const getRawSizeColor = getSizeColor(names, files);
153
- let data;
154
- if (showEstimatedTransferSize) {
155
- data = [
156
- g(files),
157
- dim(names),
158
- getRawSizeColor(typeof rawSize === 'number' ? formatSize(rawSize) : rawSize),
159
- c(typeof estimatedTransferSize === 'number'
160
- ? formatSize(estimatedTransferSize)
161
- : estimatedTransferSize),
162
- ];
163
- }
164
- else {
165
- data = [
166
- g(files),
167
- dim(names),
168
- getRawSizeColor(typeof rawSize === 'number' ? formatSize(rawSize) : rawSize),
169
- '',
170
- ];
171
- }
172
- if (initial) {
173
- changedEntryChunksStats.push(data);
174
- if (typeof rawSize === 'number') {
175
- initialTotalRawSize += rawSize;
176
- }
177
- if (showEstimatedTransferSize && typeof estimatedTransferSize === 'number') {
178
- if (initialTotalEstimatedTransferSize === undefined) {
179
- initialTotalEstimatedTransferSize = 0;
180
- }
181
- initialTotalEstimatedTransferSize += estimatedTransferSize;
182
- }
183
- }
184
- else {
185
- changedLazyChunksStats.push(data);
186
- changedLazyChunksCount++;
187
- }
188
- }
189
- const bundleInfo = [];
190
- const baseTitles = ['Names', 'Raw size'];
191
- if (showEstimatedTransferSize) {
192
- baseTitles.push('Estimated transfer size');
193
- }
194
- // Entry chunks
195
- if (changedEntryChunksStats.length) {
196
- bundleInfo.push(['Initial chunk files', ...baseTitles].map(bold), ...changedEntryChunksStats);
197
- if (showTotalSize) {
198
- const initialSizeTotalColor = getSizeColor('bundle initial', undefined, (x) => x);
199
- const totalSizeElements = [
200
- ' ',
201
- 'Initial total',
202
- initialSizeTotalColor(formatSize(initialTotalRawSize)),
203
- ];
204
- if (showEstimatedTransferSize) {
205
- totalSizeElements.push(typeof initialTotalEstimatedTransferSize === 'number'
206
- ? formatSize(initialTotalEstimatedTransferSize)
207
- : '-');
208
- }
209
- bundleInfo.push([], totalSizeElements.map(bold));
210
- }
211
- }
212
- // Seperator
213
- if (changedEntryChunksStats.length && changedLazyChunksStats.length) {
214
- bundleInfo.push([]);
215
- }
216
- // Lazy chunks
217
- if (changedLazyChunksStats.length) {
218
- bundleInfo.push(['Lazy chunk files', ...baseTitles].map(bold), ...changedLazyChunksStats);
219
- if (changedLazyChunksCount > changedLazyChunksStats.length) {
220
- bundleInfo.push([
221
- dim(`...and ${changedLazyChunksCount - changedLazyChunksStats.length} more lazy chunks files. ` +
222
- 'Use "--verbose" to show all the files.'),
223
- ]);
224
- }
225
- }
226
- return bundleInfo;
227
- }
228
- function generateTableText(bundleInfo, colors) {
229
- const skipText = (value) => value.includes('...and ');
230
- const longest = [];
231
- for (const item of bundleInfo) {
232
- for (let i = 0; i < item.length; i++) {
233
- if (item[i] === undefined) {
234
- continue;
235
- }
236
- const currentItem = item[i].toString();
237
- if (skipText(currentItem)) {
238
- continue;
239
- }
240
- const currentLongest = (longest[i] ??= 0);
241
- const currentItemLength = (0, node_util_1.stripVTControlCharacters)(currentItem).length;
242
- if (currentLongest < currentItemLength) {
243
- longest[i] = currentItemLength;
244
- }
245
- }
246
- }
247
- const seperator = colors ? color_1.colors.dim(' | ') : ' | ';
248
- const outputTable = [];
249
- for (const item of bundleInfo) {
250
- for (let i = 0; i < longest.length; i++) {
251
- if (item[i] === undefined) {
252
- continue;
253
- }
254
- const currentItem = item[i].toString();
255
- if (skipText(currentItem)) {
256
- continue;
257
- }
258
- const currentItemLength = (0, node_util_1.stripVTControlCharacters)(currentItem).length;
259
- const stringPad = ' '.repeat(longest[i] - currentItemLength);
260
- // Values in columns at index 2 and 3 (Raw and Estimated sizes) are always right aligned.
261
- item[i] = i >= 2 ? stringPad + currentItem : currentItem + stringPad;
262
- }
263
- outputTable.push(item.join(seperator));
264
- }
265
- return outputTable.join('\n');
266
- }
267
63
  // We use this cache because we can have multiple builders running in the same process,
268
64
  // where each builder has different output path.
269
65
  // Ideally, we should create the logging callback as a factory, but that would need a refactoring.
@@ -309,7 +105,7 @@ statsConfig, budgetFailures) {
309
105
  }
310
106
  unchangedChunkNumber = json.chunks.length - changedChunksStats.length;
311
107
  runsCache.add(json.outputPath || '');
312
- const statsTable = generateBuildStatsTable(changedChunksStats, colors, unchangedChunkNumber === 0, hasEstimatedTransferSizes, budgetFailures);
108
+ const statsTable = (0, stats_table_1.generateBuildStatsTable)(changedChunksStats, colors, unchangedChunkNumber === 0, hasEstimatedTransferSizes, budgetFailures);
313
109
  // In some cases we do things outside of webpack context
314
110
  // Such us index generation, service worker augmentation etc...
315
111
  // This will correct the time and include these.
@@ -6,7 +6,7 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import { InlineOptions } from './bundle-inline-options';
9
- import { I18nOptions } from './i18n-options';
9
+ import { I18nOptions } from './i18n-webpack';
10
10
  export declare class BundleActionExecutor {
11
11
  private workerOptions;
12
12
  private workerPool?;
@@ -5,7 +5,8 @@
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.io/license
7
7
  */
8
- import { Budget } from '../builders/browser/schema';
8
+ import { Budget as BudgetEntry, Type as BudgetType } from '../builders/application/schema';
9
+ export { BudgetEntry, BudgetType };
9
10
  export interface Threshold {
10
11
  limit: number;
11
12
  type: ThresholdType;
@@ -38,7 +39,6 @@ export interface BudgetStats {
38
39
  chunks?: BudgetChunk[];
39
40
  assets?: BudgetAsset[];
40
41
  }
41
- export declare function calculateThresholds(budget: Budget): IterableIterator<Threshold>;
42
- export declare function checkBudgets(budgets: Budget[], stats: BudgetStats, checkComponentStyles?: boolean): IterableIterator<BudgetCalculatorResult>;
43
- export declare function checkThresholds(thresholds: IterableIterator<Threshold>, size: number, label?: string): IterableIterator<BudgetCalculatorResult>;
44
- export {};
42
+ export declare function calculateThresholds(budget: BudgetEntry): IterableIterator<Threshold>;
43
+ export declare function checkBudgets(budgets: BudgetEntry[], stats: BudgetStats, checkComponentStyles?: boolean): IterableIterator<BudgetCalculatorResult>;
44
+ export declare function checkThresholds(thresholds: Iterable<Threshold>, size: number, label?: string): IterableIterator<BudgetCalculatorResult>;
@@ -7,9 +7,10 @@
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.checkThresholds = exports.checkBudgets = exports.calculateThresholds = exports.ThresholdSeverity = void 0;
11
- const schema_1 = require("../builders/browser/schema");
12
- const stats_1 = require("../tools/webpack/utils/stats");
10
+ exports.checkThresholds = exports.checkBudgets = exports.calculateThresholds = exports.ThresholdSeverity = exports.BudgetType = void 0;
11
+ const schema_1 = require("../builders/application/schema");
12
+ Object.defineProperty(exports, "BudgetType", { enumerable: true, get: function () { return schema_1.Type; } });
13
+ const format_bytes_1 = require("./format-bytes");
13
14
  var ThresholdType;
14
15
  (function (ThresholdType) {
15
16
  ThresholdType["Max"] = "maximum";
@@ -273,11 +274,11 @@ function* checkThresholds(thresholds, size, label) {
273
274
  if (size <= threshold.limit) {
274
275
  continue;
275
276
  }
276
- const sizeDifference = (0, stats_1.formatSize)(size - threshold.limit);
277
+ const sizeDifference = (0, format_bytes_1.formatSize)(size - threshold.limit);
277
278
  yield {
278
279
  severity: threshold.severity,
279
280
  label,
280
- message: `${label} exceeded maximum budget. Budget ${(0, stats_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, stats_1.formatSize)(size)}.`,
281
+ message: `${label} exceeded maximum budget. Budget ${(0, format_bytes_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, format_bytes_1.formatSize)(size)}.`,
281
282
  };
282
283
  break;
283
284
  }
@@ -285,11 +286,11 @@ function* checkThresholds(thresholds, size, label) {
285
286
  if (size >= threshold.limit) {
286
287
  continue;
287
288
  }
288
- const sizeDifference = (0, stats_1.formatSize)(threshold.limit - size);
289
+ const sizeDifference = (0, format_bytes_1.formatSize)(threshold.limit - size);
289
290
  yield {
290
291
  severity: threshold.severity,
291
292
  label,
292
- message: `${label} failed to meet minimum budget. Budget ${(0, stats_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, stats_1.formatSize)(size)}.`,
293
+ message: `${label} failed to meet minimum budget. Budget ${(0, format_bytes_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, format_bytes_1.formatSize)(size)}.`,
293
294
  };
294
295
  break;
295
296
  }
@@ -0,0 +1,8 @@
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 declare function formatSize(size: number): string;
@@ -0,0 +1,22 @@
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.formatSize = void 0;
11
+ function formatSize(size) {
12
+ if (size <= 0) {
13
+ return '0 bytes';
14
+ }
15
+ const abbreviations = ['bytes', 'kB', 'MB', 'GB'];
16
+ const index = Math.floor(Math.log(size) / Math.log(1024));
17
+ const roundedSize = size / Math.pow(1024, index);
18
+ // bytes don't have a fraction
19
+ const fractionDigits = index === 0 ? 0 : 2;
20
+ return `${roundedSize.toFixed(fractionDigits)} ${abbreviations[index]}`;
21
+ }
22
+ exports.formatSize = formatSize;
@@ -7,5 +7,5 @@
7
7
  */
8
8
  import { BuilderContext } from '@angular-devkit/architect';
9
9
  import { EmittedFiles } from '@angular-devkit/build-webpack';
10
- import { I18nOptions } from './i18n-options';
10
+ import { I18nOptions } from './i18n-webpack';
11
11
  export declare function i18nInlineEmittedFiles(context: BuilderContext, emittedFiles: EmittedFiles[], i18n: I18nOptions, baseOutputPath: string, outputPaths: string[], scriptsEntryPointName: string[], emittedPath: string, missingTranslation: 'error' | 'warning' | 'ignore' | undefined): Promise<boolean>;
@@ -5,10 +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.io/license
7
7
  */
8
- import { BuilderContext } from '@angular-devkit/architect';
9
- import { Schema as BrowserBuilderSchema, I18NTranslation } from '../builders/browser/schema';
10
- import { Schema as ServerBuilderSchema } from '../builders/server/schema';
11
- import { TranslationLoader } from './load-translations';
8
+ import type { TranslationLoader } from './load-translations';
12
9
  export interface LocaleDescription {
13
10
  files: {
14
11
  path: string;
@@ -30,11 +27,7 @@ export interface I18nOptions {
30
27
  export declare function createI18nOptions(projectMetadata: {
31
28
  i18n?: unknown;
32
29
  }, inline?: boolean | string[]): I18nOptions;
33
- export declare function configureI18nBuild<T extends BrowserBuilderSchema | ServerBuilderSchema>(context: BuilderContext, options: T): Promise<{
34
- buildOptions: T;
35
- i18n: I18nOptions;
36
- }>;
37
30
  export declare function loadTranslations(locale: string, desc: LocaleDescription, workspaceRoot: string, loader: TranslationLoader, logger: {
38
31
  warn: (message: string) => void;
39
32
  error: (message: string) => void;
40
- }, usedFormats?: Set<string>, duplicateTranslation?: I18NTranslation): void;
33
+ }, usedFormats?: Set<string>, duplicateTranslation?: 'ignore' | 'error' | 'warning'): void;
@@ -10,18 +10,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  return (mod && mod.__esModule) ? mod : { "default": mod };
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.loadTranslations = exports.configureI18nBuild = exports.createI18nOptions = void 0;
14
- const node_fs_1 = __importDefault(require("node:fs"));
15
- const node_module_1 = require("node:module");
16
- const node_os_1 = __importDefault(require("node:os"));
13
+ exports.loadTranslations = exports.createI18nOptions = void 0;
17
14
  const node_path_1 = __importDefault(require("node:path"));
18
- const schema_1 = require("../builders/browser/schema");
19
- const read_tsconfig_1 = require("../utils/read-tsconfig");
20
- const load_translations_1 = require("./load-translations");
21
- /**
22
- * The base module location used to search for locale specific data.
23
- */
24
- const LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global';
25
15
  function normalizeTranslationFileOption(option, locale, expectObjectInError) {
26
16
  if (typeof option === 'string') {
27
17
  return [option];
@@ -123,89 +113,6 @@ function createI18nOptions(projectMetadata, inline) {
123
113
  return i18n;
124
114
  }
125
115
  exports.createI18nOptions = createI18nOptions;
126
- async function configureI18nBuild(context, options) {
127
- if (!context.target) {
128
- throw new Error('The builder requires a target.');
129
- }
130
- const buildOptions = { ...options };
131
- const tsConfig = await (0, read_tsconfig_1.readTsconfig)(buildOptions.tsConfig, context.workspaceRoot);
132
- const metadata = await context.getProjectMetadata(context.target);
133
- const i18n = createI18nOptions(metadata, buildOptions.localize);
134
- // No additional processing needed if no inlining requested and no source locale defined.
135
- if (!i18n.shouldInline && !i18n.hasDefinedSourceLocale) {
136
- return { buildOptions, i18n };
137
- }
138
- const projectRoot = node_path_1.default.join(context.workspaceRoot, metadata.root || '');
139
- // The trailing slash is required to signal that the path is a directory and not a file.
140
- const projectRequire = (0, node_module_1.createRequire)(projectRoot + '/');
141
- const localeResolver = (locale) => projectRequire.resolve(node_path_1.default.join(LOCALE_DATA_BASE_MODULE, locale));
142
- // Load locale data and translations (if present)
143
- let loader;
144
- const usedFormats = new Set();
145
- for (const [locale, desc] of Object.entries(i18n.locales)) {
146
- if (!i18n.inlineLocales.has(locale) && locale !== i18n.sourceLocale) {
147
- continue;
148
- }
149
- let localeDataPath = findLocaleDataPath(locale, localeResolver);
150
- if (!localeDataPath) {
151
- const [first] = locale.split('-');
152
- if (first) {
153
- localeDataPath = findLocaleDataPath(first.toLowerCase(), localeResolver);
154
- if (localeDataPath) {
155
- context.logger.warn(`Locale data for '${locale}' cannot be found. Using locale data for '${first}'.`);
156
- }
157
- }
158
- }
159
- if (!localeDataPath) {
160
- context.logger.warn(`Locale data for '${locale}' cannot be found. No locale data will be included for this locale.`);
161
- }
162
- else {
163
- desc.dataPath = localeDataPath;
164
- }
165
- if (!desc.files.length) {
166
- continue;
167
- }
168
- loader ??= await (0, load_translations_1.createTranslationLoader)();
169
- loadTranslations(locale, desc, context.workspaceRoot, loader, {
170
- warn(message) {
171
- context.logger.warn(message);
172
- },
173
- error(message) {
174
- throw new Error(message);
175
- },
176
- }, usedFormats, buildOptions.i18nDuplicateTranslation);
177
- if (usedFormats.size > 1 && tsConfig.options.enableI18nLegacyMessageIdFormat !== false) {
178
- // This limitation is only for legacy message id support (defaults to true as of 9.0)
179
- throw new Error('Localization currently only supports using one type of translation file format for the entire application.');
180
- }
181
- }
182
- // If inlining store the output in a temporary location to facilitate post-processing
183
- if (i18n.shouldInline) {
184
- // TODO: we should likely save these in the .angular directory in the next major version.
185
- // We'd need to do a migration to add the temp directory to gitignore.
186
- const tempPath = node_fs_1.default.mkdtempSync(node_path_1.default.join(node_fs_1.default.realpathSync(node_os_1.default.tmpdir()), 'angular-cli-i18n-'));
187
- buildOptions.outputPath = tempPath;
188
- process.on('exit', () => {
189
- try {
190
- node_fs_1.default.rmSync(tempPath, { force: true, recursive: true, maxRetries: 3 });
191
- }
192
- catch { }
193
- });
194
- }
195
- return { buildOptions, i18n };
196
- }
197
- exports.configureI18nBuild = configureI18nBuild;
198
- function findLocaleDataPath(locale, resolver) {
199
- // Remove private use subtags
200
- const scrubbedLocale = locale.replace(/-x(-[a-zA-Z0-9]{1,8})+$/, '');
201
- try {
202
- return resolver(scrubbedLocale);
203
- }
204
- catch {
205
- // fallback to known existing en-US locale data as of 14.0
206
- return scrubbedLocale === 'en-US' ? findLocaleDataPath('en', resolver) : null;
207
- }
208
- }
209
116
  function loadTranslations(locale, desc, workspaceRoot, loader, logger, usedFormats, duplicateTranslation) {
210
117
  let translations = undefined;
211
118
  for (const file of desc.files) {
@@ -230,12 +137,12 @@ function loadTranslations(locale, desc, workspaceRoot, loader, logger, usedForma
230
137
  if (translations[id] !== undefined) {
231
138
  const duplicateTranslationMessage = `[${file.path}]: Duplicate translations for message '${id}' when merging.`;
232
139
  switch (duplicateTranslation) {
233
- case schema_1.I18NTranslation.Ignore:
140
+ case 'ignore':
234
141
  break;
235
- case schema_1.I18NTranslation.Error:
142
+ case 'error':
236
143
  logger.error(`ERROR ${duplicateTranslationMessage}`);
237
144
  break;
238
- case schema_1.I18NTranslation.Warning:
145
+ case 'warning':
239
146
  default:
240
147
  logger.warn(`WARNING ${duplicateTranslationMessage}`);
241
148
  break;