@angular/build 20.1.2 → 20.2.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +22 -22
- package/src/builders/unit-test/builder.js +9 -1
- package/src/builders/unit-test/schema.d.ts +2 -1
- package/src/builders/unit-test/schema.json +1 -1
- package/src/tools/vite/middlewares/assets-middleware.js +34 -16
- package/src/utils/index-file/inline-fonts.js +4 -43
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/version.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/build",
|
|
3
|
-
"version": "20.1
|
|
3
|
+
"version": "20.2.0-next.1",
|
|
4
4
|
"description": "Official build system for Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Angular CLI",
|
|
@@ -23,51 +23,51 @@
|
|
|
23
23
|
"builders": "builders.json",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ampproject/remapping": "2.3.0",
|
|
26
|
-
"@angular-devkit/architect": "0.
|
|
27
|
-
"@babel/core": "7.
|
|
26
|
+
"@angular-devkit/architect": "0.2002.0-next.1",
|
|
27
|
+
"@babel/core": "7.28.0",
|
|
28
28
|
"@babel/helper-annotate-as-pure": "7.27.3",
|
|
29
29
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
30
|
-
"@inquirer/confirm": "5.1.
|
|
30
|
+
"@inquirer/confirm": "5.1.14",
|
|
31
31
|
"@vitejs/plugin-basic-ssl": "2.1.0",
|
|
32
|
-
"beasties": "0.3.
|
|
32
|
+
"beasties": "0.3.5",
|
|
33
33
|
"browserslist": "^4.23.0",
|
|
34
|
-
"esbuild": "0.25.
|
|
34
|
+
"esbuild": "0.25.8",
|
|
35
35
|
"https-proxy-agent": "7.0.6",
|
|
36
36
|
"istanbul-lib-instrument": "6.0.3",
|
|
37
37
|
"jsonc-parser": "3.3.1",
|
|
38
|
-
"listr2": "
|
|
38
|
+
"listr2": "9.0.1",
|
|
39
39
|
"magic-string": "0.30.17",
|
|
40
40
|
"mrmime": "2.0.1",
|
|
41
|
-
"parse5-html-rewriting-stream": "
|
|
42
|
-
"picomatch": "4.0.
|
|
43
|
-
"piscina": "5.1.
|
|
44
|
-
"rollup": "4.
|
|
41
|
+
"parse5-html-rewriting-stream": "8.0.0",
|
|
42
|
+
"picomatch": "4.0.3",
|
|
43
|
+
"piscina": "5.1.3",
|
|
44
|
+
"rollup": "4.45.1",
|
|
45
45
|
"sass": "1.89.2",
|
|
46
46
|
"semver": "7.7.2",
|
|
47
47
|
"source-map-support": "0.5.21",
|
|
48
48
|
"tinyglobby": "0.2.14",
|
|
49
|
-
"vite": "7.0.
|
|
49
|
+
"vite": "7.0.5",
|
|
50
50
|
"watchpack": "2.4.4"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
53
|
"lmdb": "3.4.1"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@angular/core": "^20.0.0",
|
|
57
|
-
"@angular/compiler": "^20.0.0",
|
|
58
|
-
"@angular/compiler-cli": "^20.0.0",
|
|
59
|
-
"@angular/localize": "^20.0.0",
|
|
60
|
-
"@angular/platform-browser": "^20.0.0",
|
|
61
|
-
"@angular/platform-server": "^20.0.0",
|
|
62
|
-
"@angular/service-worker": "^20.0.0",
|
|
63
|
-
"@angular/ssr": "^20.1
|
|
56
|
+
"@angular/core": "^20.0.0 || ^20.2.0-next.0",
|
|
57
|
+
"@angular/compiler": "^20.0.0 || ^20.2.0-next.0",
|
|
58
|
+
"@angular/compiler-cli": "^20.0.0 || ^20.2.0-next.0",
|
|
59
|
+
"@angular/localize": "^20.0.0 || ^20.2.0-next.0",
|
|
60
|
+
"@angular/platform-browser": "^20.0.0 || ^20.2.0-next.0",
|
|
61
|
+
"@angular/platform-server": "^20.0.0 || ^20.2.0-next.0",
|
|
62
|
+
"@angular/service-worker": "^20.0.0 || ^20.2.0-next.0",
|
|
63
|
+
"@angular/ssr": "^20.2.0-next.1",
|
|
64
64
|
"karma": "^6.4.0",
|
|
65
65
|
"less": "^4.2.0",
|
|
66
|
-
"ng-packagr": "^20.0.0",
|
|
66
|
+
"ng-packagr": "^20.0.0 || ^20.2.0-next.0",
|
|
67
67
|
"postcss": "^8.4.0",
|
|
68
68
|
"tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0",
|
|
69
69
|
"tslib": "^2.3.0",
|
|
70
|
-
"typescript": ">=5.8 <
|
|
70
|
+
"typescript": ">=5.8 <6.0",
|
|
71
71
|
"vitest": "^3.1.1"
|
|
72
72
|
},
|
|
73
73
|
"peerDependenciesMeta": {
|
|
@@ -256,6 +256,13 @@ function findBrowserProvider(projectResolver) {
|
|
|
256
256
|
catch { }
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
|
+
function normalizeBrowserName(browserName) {
|
|
260
|
+
// Normalize browser names to match Vitest's expectations for headless but also supports karma's names
|
|
261
|
+
// e.g., 'ChromeHeadless' -> 'chrome', 'FirefoxHeadless'
|
|
262
|
+
// and 'Chrome' -> 'chrome', 'Firefox' -> 'firefox'.
|
|
263
|
+
const normalized = browserName.toLowerCase();
|
|
264
|
+
return normalized.replace(/headless$/, '');
|
|
265
|
+
}
|
|
259
266
|
function setupBrowserConfiguration(browsers, debug, projectSourceRoot) {
|
|
260
267
|
if (browsers === undefined) {
|
|
261
268
|
return {};
|
|
@@ -288,8 +295,9 @@ function setupBrowserConfiguration(browsers, debug, projectSourceRoot) {
|
|
|
288
295
|
const browser = {
|
|
289
296
|
enabled: true,
|
|
290
297
|
provider,
|
|
298
|
+
headless: browsers.some((name) => name.toLowerCase().includes('headless')),
|
|
291
299
|
instances: browsers.map((browserName) => ({
|
|
292
|
-
browser: browserName,
|
|
300
|
+
browser: normalizeBrowserName(browserName),
|
|
293
301
|
})),
|
|
294
302
|
};
|
|
295
303
|
return { browser };
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
export type Schema = {
|
|
5
5
|
/**
|
|
6
6
|
* A list of browsers to use for test execution. If undefined, jsdom on Node.js will be used
|
|
7
|
-
* instead of a browser.
|
|
7
|
+
* instead of a browser. For Vitest and Karma, browser names ending with 'Headless' (e.g.,
|
|
8
|
+
* 'ChromeHeadless') will enable headless mode for that browser.
|
|
8
9
|
*/
|
|
9
10
|
browsers?: string[];
|
|
10
11
|
/**
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"enum": ["karma", "vitest"]
|
|
20
20
|
},
|
|
21
21
|
"browsers": {
|
|
22
|
-
"description": "A list of browsers to use for test execution. If undefined, jsdom on Node.js will be used instead of a browser.",
|
|
22
|
+
"description": "A list of browsers to use for test execution. If undefined, jsdom on Node.js will be used instead of a browser. For Vitest and Karma, browser names ending with 'Headless' (e.g., 'ChromeHeadless') will enable headless mode for that browser.",
|
|
23
23
|
"type": "array",
|
|
24
24
|
"items": {
|
|
25
25
|
"type": "string"
|
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.createAngularAssetsMiddleware = createAngularAssetsMiddleware;
|
|
11
11
|
const mrmime_1 = require("mrmime");
|
|
12
|
+
const node_crypto_1 = require("node:crypto");
|
|
13
|
+
const node_fs_1 = require("node:fs");
|
|
12
14
|
const node_path_1 = require("node:path");
|
|
13
15
|
const utils_1 = require("../utils");
|
|
16
|
+
const JS_TS_REGEXP = /\.[cm]?[tj]sx?$/;
|
|
14
17
|
function createAngularAssetsMiddleware(server, assets, outputFiles, componentStyles, encapsulateStyle) {
|
|
15
18
|
return function angularAssetsMiddleware(req, res, next) {
|
|
16
19
|
if (req.url === undefined || res.writableEnded) {
|
|
@@ -24,14 +27,27 @@ function createAngularAssetsMiddleware(server, assets, outputFiles, componentSty
|
|
|
24
27
|
// Rewrite all build assets to a vite raw fs URL
|
|
25
28
|
const asset = assets.get(pathname);
|
|
26
29
|
if (asset) {
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
// This is a workaround to serve JS and TS files without Vite transformations.
|
|
31
|
+
if (JS_TS_REGEXP.test(extension)) {
|
|
32
|
+
const contents = (0, node_fs_1.readFileSync)(asset.source);
|
|
33
|
+
const etag = `W/${(0, node_crypto_1.createHash)('sha256').update(contents).digest('hex')}`;
|
|
34
|
+
if (checkAndHandleEtag(req, res, etag)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const mimeType = (0, mrmime_1.lookup)(extension);
|
|
38
|
+
if (mimeType) {
|
|
39
|
+
res.setHeader('Content-Type', mimeType);
|
|
40
|
+
}
|
|
41
|
+
res.setHeader('ETag', etag);
|
|
42
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
43
|
+
res.end(contents);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// The encoding needs to match what happens in the vite static middleware.
|
|
47
|
+
// ref: https://github.com/vitejs/vite/blob/d4f13bd81468961c8c926438e815ab6b1c82735e/packages/vite/src/node/server/middlewares/static.ts#L163
|
|
48
|
+
req.url = `${server.config.base}@fs/${encodeURI(asset.source)}`;
|
|
49
|
+
next();
|
|
50
|
+
}
|
|
35
51
|
return;
|
|
36
52
|
}
|
|
37
53
|
// HTML fallbacking
|
|
@@ -78,11 +94,8 @@ function createAngularAssetsMiddleware(server, assets, outputFiles, componentSty
|
|
|
78
94
|
else {
|
|
79
95
|
componentStyle.used.add(componentId);
|
|
80
96
|
}
|
|
81
|
-
// Report if there are no changes to avoid reprocessing
|
|
82
97
|
const etag = `W/"${outputFile.contents.byteLength}-${outputFile.hash}-${componentId}"`;
|
|
83
|
-
if (req
|
|
84
|
-
res.statusCode = 304;
|
|
85
|
-
res.end();
|
|
98
|
+
if (checkAndHandleEtag(req, res, etag)) {
|
|
86
99
|
return;
|
|
87
100
|
}
|
|
88
101
|
// Shim the stylesheet if a component ID is provided
|
|
@@ -105,11 +118,8 @@ function createAngularAssetsMiddleware(server, assets, outputFiles, componentSty
|
|
|
105
118
|
return;
|
|
106
119
|
}
|
|
107
120
|
}
|
|
108
|
-
// Avoid resending the content if it has not changed since last request
|
|
109
121
|
const etag = `W/"${outputFile.contents.byteLength}-${outputFile.hash}"`;
|
|
110
|
-
if (req
|
|
111
|
-
res.statusCode = 304;
|
|
112
|
-
res.end();
|
|
122
|
+
if (checkAndHandleEtag(req, res, etag)) {
|
|
113
123
|
return;
|
|
114
124
|
}
|
|
115
125
|
const mimeType = (0, mrmime_1.lookup)(extension);
|
|
@@ -152,3 +162,11 @@ function createAngularAssetsMiddleware(server, assets, outputFiles, componentSty
|
|
|
152
162
|
next();
|
|
153
163
|
};
|
|
154
164
|
}
|
|
165
|
+
function checkAndHandleEtag(req, res, etag) {
|
|
166
|
+
if (req.headers['if-none-match'] === etag) {
|
|
167
|
+
res.statusCode = 304;
|
|
168
|
+
res.end();
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
@@ -6,45 +6,12 @@
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://angular.dev/license
|
|
8
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 () {
|
|
26
|
-
var ownKeys = function(o) {
|
|
27
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
-
var ar = [];
|
|
29
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
-
return ar;
|
|
31
|
-
};
|
|
32
|
-
return ownKeys(o);
|
|
33
|
-
};
|
|
34
|
-
return function (mod) {
|
|
35
|
-
if (mod && mod.__esModule) return mod;
|
|
36
|
-
var result = {};
|
|
37
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
-
__setModuleDefault(result, mod);
|
|
39
|
-
return result;
|
|
40
|
-
};
|
|
41
|
-
})();
|
|
42
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
10
|
exports.InlineFontsProcessor = void 0;
|
|
44
11
|
const https_proxy_agent_1 = require("https-proxy-agent");
|
|
45
12
|
const node_crypto_1 = require("node:crypto");
|
|
46
13
|
const promises_1 = require("node:fs/promises");
|
|
47
|
-
const
|
|
14
|
+
const node_https_1 = require("node:https");
|
|
48
15
|
const node_path_1 = require("node:path");
|
|
49
16
|
const html_rewriting_stream_1 = require("./html-rewriting-stream");
|
|
50
17
|
const SUPPORTED_PROVIDERS = {
|
|
@@ -193,16 +160,11 @@ class InlineFontsProcessor {
|
|
|
193
160
|
}
|
|
194
161
|
catch { }
|
|
195
162
|
}
|
|
196
|
-
let agent;
|
|
197
163
|
const httpsProxy = process.env.HTTPS_PROXY ?? process.env.https_proxy;
|
|
198
|
-
if (httpsProxy) {
|
|
199
|
-
agent = new https_proxy_agent_1.HttpsProxyAgent(httpsProxy);
|
|
200
|
-
}
|
|
201
164
|
const data = await new Promise((resolve, reject) => {
|
|
202
165
|
let rawResponse = '';
|
|
203
|
-
|
|
204
|
-
.
|
|
205
|
-
agent,
|
|
166
|
+
(0, node_https_1.get)(url, {
|
|
167
|
+
agent: httpsProxy ? new https_proxy_agent_1.HttpsProxyAgent(httpsProxy) : undefined,
|
|
206
168
|
headers: {
|
|
207
169
|
/**
|
|
208
170
|
* Always use a Windows UA. This is because Google fonts will including hinting in fonts for Windows.
|
|
@@ -221,8 +183,7 @@ class InlineFontsProcessor {
|
|
|
221
183
|
return;
|
|
222
184
|
}
|
|
223
185
|
res.on('data', (chunk) => (rawResponse += chunk)).on('end', () => resolve(rawResponse));
|
|
224
|
-
})
|
|
225
|
-
.on('error', (e) => reject(new Error(`Inlining of fonts failed. An error has occurred while retrieving ${url} over the internet.\n` +
|
|
186
|
+
}).on('error', (e) => reject(new Error(`Inlining of fonts failed. An error has occurred while retrieving ${url} over the internet.\n` +
|
|
226
187
|
e.message)));
|
|
227
188
|
});
|
|
228
189
|
if (cacheFile) {
|
|
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.normalizeCacheOptions = normalizeCacheOptions;
|
|
11
11
|
const node_path_1 = require("node:path");
|
|
12
12
|
/** Version placeholder is replaced during the build process with actual package version */
|
|
13
|
-
const VERSION = '20.1
|
|
13
|
+
const VERSION = '20.2.0-next.1';
|
|
14
14
|
function hasCacheMetadata(value) {
|
|
15
15
|
return (!!value &&
|
|
16
16
|
typeof value === 'object' &&
|
package/src/utils/version.js
CHANGED
|
@@ -28,7 +28,7 @@ function assertCompatibleAngularVersion(projectRoot) {
|
|
|
28
28
|
'This likely indicates a corrupted local installation. Please try reinstalling your packages.');
|
|
29
29
|
process.exit(2);
|
|
30
30
|
}
|
|
31
|
-
const supportedAngularSemver = '^20.0.0';
|
|
31
|
+
const supportedAngularSemver = '^20.0.0 || ^20.2.0-next.0';
|
|
32
32
|
if (angularPkgJson['version'] === '0.0.0' || supportedAngularSemver.startsWith('0.0.0')) {
|
|
33
33
|
// Internal CLI and FW testing version.
|
|
34
34
|
return;
|