Skip to content

Commit a0e3060

Browse files
committedJan 26, 2024
fix(@angular-devkit/build-angular): correctly handle glob negation in proxy config when using vite
This commit fixes an issue were negated globs in proxy config were not process correctly when using vite. Closes #26970 (cherry picked from commit dbd3984)
1 parent 5332e5b commit a0e3060

File tree

2 files changed

+57
-49
lines changed

2 files changed

+57
-49
lines changed
 

‎packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/proxy-config_spec.ts

+54-46
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import * as http from 'http';
9+
import { createServer } from 'node:http';
1010
import { executeDevServer } from '../../index';
1111
import { executeOnceAndFetch } from '../execute-fetch';
1212
import { describeServeBuilder } from '../jasmine-helpers';
@@ -27,21 +27,18 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
2727
proxyConfig: 'proxy.config.json',
2828
});
2929

30-
const proxyServer = createProxyServer();
30+
const proxyServer = await createProxyServer();
3131
try {
32-
await new Promise<void>((resolve) => proxyServer.listen(0, '127.0.0.1', resolve));
33-
const proxyAddress = proxyServer.address() as import('net').AddressInfo;
34-
3532
await harness.writeFiles({
36-
'proxy.config.json': `{ "/api/*": { "target": "http://127.0.0.1:${proxyAddress.port}" } }`,
33+
'proxy.config.json': `{ "/api/*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } }`,
3734
});
3835

3936
const { result, response } = await executeOnceAndFetch(harness, '/api/test');
4037

4138
expect(result?.success).toBeTrue();
4239
expect(await response?.text()).toContain('TEST_API_RETURN');
4340
} finally {
44-
await new Promise<void>((resolve) => proxyServer.close(() => resolve()));
41+
await proxyServer.close();
4542
}
4643
});
4744

@@ -51,15 +48,12 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
5148
proxyConfig: 'proxy.config.json',
5249
});
5350

54-
const proxyServer = createProxyServer();
51+
const proxyServer = await createProxyServer();
5552
try {
56-
await new Promise<void>((resolve) => proxyServer.listen(0, '127.0.0.1', resolve));
57-
const proxyAddress = proxyServer.address() as import('net').AddressInfo;
58-
5953
await harness.writeFiles({
6054
'proxy.config.json': `
6155
// JSON file with comments
62-
{ "/api/*": { "target": "http://127.0.0.1:${proxyAddress.port}" } }
56+
{ "/api/*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } }
6357
`,
6458
});
6559

@@ -68,7 +62,7 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
6862
expect(result?.success).toBeTrue();
6963
expect(await response?.text()).toContain('TEST_API_RETURN');
7064
} finally {
71-
await new Promise<void>((resolve) => proxyServer.close(() => resolve()));
65+
await proxyServer.close();
7266
}
7367
});
7468

@@ -77,22 +71,18 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
7771
...BASE_OPTIONS,
7872
proxyConfig: 'proxy.config.js',
7973
});
80-
81-
const proxyServer = createProxyServer();
74+
const proxyServer = await createProxyServer();
8275
try {
83-
await new Promise<void>((resolve) => proxyServer.listen(0, '127.0.0.1', resolve));
84-
const proxyAddress = proxyServer.address() as import('net').AddressInfo;
85-
8676
await harness.writeFiles({
87-
'proxy.config.js': `module.exports = { "/api/*": { "target": "http://127.0.0.1:${proxyAddress.port}" } }`,
77+
'proxy.config.js': `module.exports = { "/api/*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } }`,
8878
});
8979

9080
const { result, response } = await executeOnceAndFetch(harness, '/api/test');
9181

9282
expect(result?.success).toBeTrue();
9383
expect(await response?.text()).toContain('TEST_API_RETURN');
9484
} finally {
95-
await new Promise<void>((resolve) => proxyServer.close(() => resolve()));
85+
await proxyServer.close();
9686
}
9787
});
9888

@@ -102,13 +92,10 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
10292
proxyConfig: 'proxy.config.js',
10393
});
10494

105-
const proxyServer = createProxyServer();
95+
const proxyServer = await createProxyServer();
10696
try {
107-
await new Promise<void>((resolve) => proxyServer.listen(0, '127.0.0.1', resolve));
108-
const proxyAddress = proxyServer.address() as import('net').AddressInfo;
109-
11097
await harness.writeFiles({
111-
'proxy.config.js': `export default { "/api/*": { "target": "http://127.0.0.1:${proxyAddress.port}" } }`,
98+
'proxy.config.js': `export default { "/api/*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } }`,
11299
'package.json': '{ "type": "module" }',
113100
});
114101

@@ -117,7 +104,7 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
117104
expect(result?.success).toBeTrue();
118105
expect(await response?.text()).toContain('TEST_API_RETURN');
119106
} finally {
120-
await new Promise<void>((resolve) => proxyServer.close(() => resolve()));
107+
await proxyServer.close();
121108
}
122109
});
123110

@@ -127,10 +114,9 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
127114
proxyConfig: 'proxy.config.cjs',
128115
});
129116

130-
const proxyServer = createProxyServer();
117+
const proxyServer = await createProxyServer();
131118
try {
132-
await new Promise<void>((resolve) => proxyServer.listen(0, '127.0.0.1', resolve));
133-
const proxyAddress = proxyServer.address() as import('net').AddressInfo;
119+
const proxyAddress = proxyServer.address;
134120

135121
await harness.writeFiles({
136122
'proxy.config.cjs': `module.exports = { "/api/*": { "target": "http://127.0.0.1:${proxyAddress.port}" } }`,
@@ -141,7 +127,7 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
141127
expect(result?.success).toBeTrue();
142128
expect(await response?.text()).toContain('TEST_API_RETURN');
143129
} finally {
144-
await new Promise<void>((resolve) => proxyServer.close(() => resolve()));
130+
await proxyServer.close();
145131
}
146132
});
147133

@@ -151,21 +137,18 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
151137
proxyConfig: 'proxy.config.mjs',
152138
});
153139

154-
const proxyServer = createProxyServer();
140+
const proxyServer = await createProxyServer();
155141
try {
156-
await new Promise<void>((resolve) => proxyServer.listen(0, '127.0.0.1', resolve));
157-
const proxyAddress = proxyServer.address() as import('net').AddressInfo;
158-
159142
await harness.writeFiles({
160-
'proxy.config.mjs': `export default { "/api/*": { "target": "http://127.0.0.1:${proxyAddress.port}" } }`,
143+
'proxy.config.mjs': `export default { "/api/*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } }`,
161144
});
162145

163146
const { result, response } = await executeOnceAndFetch(harness, '/api/test');
164147

165148
expect(result?.success).toBeTrue();
166149
expect(await response?.text()).toContain('TEST_API_RETURN');
167150
} finally {
168-
await new Promise<void>((resolve) => proxyServer.close(() => resolve()));
151+
await proxyServer.close();
169152
}
170153
});
171154

@@ -175,21 +158,18 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
175158
proxyConfig: 'proxy.config.json',
176159
});
177160

178-
const proxyServer = createProxyServer();
161+
const proxyServer = await createProxyServer();
179162
try {
180-
await new Promise<void>((resolve) => proxyServer.listen(0, '127.0.0.1', resolve));
181-
const proxyAddress = proxyServer.address() as import('net').AddressInfo;
182-
183163
await harness.writeFiles({
184-
'proxy.config.json': `[ { "context": ["/api", "/abc"], "target": "http://127.0.0.1:${proxyAddress.port}" } ]`,
164+
'proxy.config.json': `[ { "context": ["/api", "/abc"], "target": "http://127.0.0.1:${proxyServer.address.port}" } ]`,
185165
});
186166

187167
const { result, response } = await executeOnceAndFetch(harness, '/api/test');
188168

189169
expect(result?.success).toBeTrue();
190170
expect(await response?.text()).toContain('TEST_API_RETURN');
191171
} finally {
192-
await new Promise<void>((resolve) => proxyServer.close(() => resolve()));
172+
await proxyServer.close();
193173
}
194174
});
195175

@@ -232,18 +212,39 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
232212
}),
233213
);
234214
});
215+
216+
it('supports negation of globs', async () => {
217+
harness.useTarget('serve', {
218+
...BASE_OPTIONS,
219+
proxyConfig: 'proxy.config.json',
220+
});
221+
222+
const proxyServer = await createProxyServer();
223+
try {
224+
await harness.writeFiles({
225+
'proxy.config.json': `
226+
{ "!something/**/*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } }
227+
`,
228+
});
229+
230+
const { result, response } = await executeOnceAndFetch(harness, '/api/test');
231+
232+
expect(result?.success).toBeTrue();
233+
expect(await response?.text()).toContain('TEST_API_RETURN');
234+
} finally {
235+
await proxyServer.close();
236+
}
237+
});
235238
});
236239
});
237240

238241
/**
239242
* Creates an HTTP Server used for proxy testing that provides a `/test` endpoint
240243
* that returns a 200 response with a body of `TEST_API_RETURN`. All other requests
241244
* will return a 404 response.
242-
*
243-
* @returns An HTTP Server instance.
244245
*/
245-
function createProxyServer() {
246-
return http.createServer((request, response) => {
246+
async function createProxyServer() {
247+
const proxyServer = createServer((request, response) => {
247248
if (request.url?.endsWith('/test')) {
248249
response.writeHead(200);
249250
response.end('TEST_API_RETURN');
@@ -252,4 +253,11 @@ function createProxyServer() {
252253
response.end();
253254
}
254255
});
256+
257+
await new Promise<void>((resolve) => proxyServer.listen(0, '127.0.0.1', resolve));
258+
259+
return {
260+
address: proxyServer.address() as import('net').AddressInfo,
261+
close: () => new Promise<void>((resolve) => proxyServer.close(() => resolve())),
262+
};
255263
}

‎packages/angular_devkit/build_angular/src/utils/load-proxy-config.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { existsSync } from 'node:fs';
1111
import { readFile } from 'node:fs/promises';
1212
import { extname, resolve } from 'node:path';
1313
import { pathToFileURL } from 'node:url';
14-
import { parse as parseGlob } from 'picomatch';
14+
import { makeRe as makeRegExpFromGlob } from 'picomatch';
1515
import { assertIsError } from './error';
1616
import { loadEsmModule } from './load-esm';
1717

@@ -129,8 +129,8 @@ function normalizeProxyConfiguration(
129129
// TODO: Consider upstreaming glob support
130130
for (const key of Object.keys(normalizedProxy)) {
131131
if (isDynamicPattern(key)) {
132-
const { output } = parseGlob(key);
133-
normalizedProxy[`^${output}$`] = normalizedProxy[key];
132+
const pattern = makeRegExpFromGlob(key).source;
133+
normalizedProxy[pattern] = normalizedProxy[key];
134134
delete normalizedProxy[key];
135135
}
136136
}

0 commit comments

Comments
 (0)
Please sign in to comment.