@@ -15,7 +15,11 @@ import { parse as parseGlob } from 'picomatch';
1515import { assertIsError } from '../../utils/error' ;
1616import { loadEsmModule } from '../../utils/load-esm' ;
1717
18- export async function loadProxyConfiguration ( root : string , proxyConfig : string | undefined ) {
18+ export async function loadProxyConfiguration (
19+ root : string ,
20+ proxyConfig : string | undefined ,
21+ normalize = false ,
22+ ) {
1923 if ( ! proxyConfig ) {
2024 return undefined ;
2125 }
@@ -26,13 +30,14 @@ export async function loadProxyConfiguration(root: string, proxyConfig: string |
2630 throw new Error ( `Proxy configuration file ${ proxyPath } does not exist.` ) ;
2731 }
2832
33+ let proxyConfiguration ;
2934 switch ( extname ( proxyPath ) ) {
3035 case '.json' : {
3136 const content = await readFile ( proxyPath , 'utf-8' ) ;
3237
3338 const { parse, printParseErrorCode } = await import ( 'jsonc-parser' ) ;
3439 const parseErrors : import ( 'jsonc-parser' ) . ParseError [ ] = [ ] ;
35- const proxyConfiguration = parse ( content , parseErrors , { allowTrailingComma : true } ) ;
40+ proxyConfiguration = parse ( content , parseErrors , { allowTrailingComma : true } ) ;
3641
3742 if ( parseErrors . length > 0 ) {
3843 let errorMessage = `Proxy configuration file ${ proxyPath } contains parse errors:` ;
@@ -43,47 +48,94 @@ export async function loadProxyConfiguration(root: string, proxyConfig: string |
4348 throw new Error ( errorMessage ) ;
4449 }
4550
46- return proxyConfiguration ;
51+ break ;
4752 }
4853 case '.mjs' :
4954 // Load the ESM configuration file using the TypeScript dynamic import workaround.
5055 // Once TypeScript provides support for keeping the dynamic import this workaround can be
5156 // changed to a direct dynamic import.
52- return ( await loadEsmModule < { default : unknown } > ( pathToFileURL ( proxyPath ) ) ) . default ;
57+ proxyConfiguration = ( await loadEsmModule < { default : unknown } > ( pathToFileURL ( proxyPath ) ) )
58+ . default ;
59+ break ;
5360 case '.cjs' :
54- return require ( proxyPath ) ;
61+ proxyConfiguration = require ( proxyPath ) ;
62+ break ;
5563 default :
5664 // The file could be either CommonJS or ESM.
5765 // CommonJS is tried first then ESM if loading fails.
5866 try {
59- return require ( proxyPath ) ;
67+ proxyConfiguration = require ( proxyPath ) ;
68+ break ;
6069 } catch ( e ) {
6170 assertIsError ( e ) ;
6271 if ( e . code === 'ERR_REQUIRE_ESM' ) {
6372 // Load the ESM configuration file using the TypeScript dynamic import workaround.
6473 // Once TypeScript provides support for keeping the dynamic import this workaround can be
6574 // changed to a direct dynamic import.
66- return ( await loadEsmModule < { default : unknown } > ( pathToFileURL ( proxyPath ) ) ) . default ;
75+ proxyConfiguration = ( await loadEsmModule < { default : unknown } > ( pathToFileURL ( proxyPath ) ) )
76+ . default ;
77+ break ;
6778 }
6879
6980 throw e ;
7081 }
7182 }
83+
84+ if ( normalize ) {
85+ proxyConfiguration = normalizeProxyConfiguration ( proxyConfiguration ) ;
86+ }
87+
88+ return proxyConfiguration ;
7289}
7390
7491/**
7592 * Converts glob patterns to regular expressions to support Vite's proxy option.
93+ * Also converts the Webpack supported array form to an object form supported by both.
94+ *
7695 * @param proxy A proxy configuration object.
7796 */
78- export function normalizeProxyConfiguration ( proxy : Record < string , unknown > ) {
97+ function normalizeProxyConfiguration (
98+ proxy : Record < string , unknown > | object [ ] ,
99+ ) : Record < string , unknown > {
100+ let normalizedProxy : Record < string , unknown > | undefined ;
101+
102+ if ( Array . isArray ( proxy ) ) {
103+ // Construct an object-form proxy configuration from the array
104+ normalizedProxy = { } ;
105+ for ( const proxyEntry of proxy ) {
106+ if ( ! ( 'context' in proxyEntry ) ) {
107+ continue ;
108+ }
109+ if ( ! Array . isArray ( proxyEntry . context ) ) {
110+ continue ;
111+ }
112+
113+ // Array-form entries contain a context string array with the path(s)
114+ // to use for the configuration entry.
115+ const context = proxyEntry . context ;
116+ delete proxyEntry . context ;
117+ for ( const contextEntry of context ) {
118+ if ( typeof contextEntry !== 'string' ) {
119+ continue ;
120+ }
121+
122+ normalizedProxy [ contextEntry ] = proxyEntry ;
123+ }
124+ }
125+ } else {
126+ normalizedProxy = proxy ;
127+ }
128+
79129 // TODO: Consider upstreaming glob support
80- for ( const key of Object . keys ( proxy ) ) {
130+ for ( const key of Object . keys ( normalizedProxy ) ) {
81131 if ( isDynamicPattern ( key ) ) {
82132 const { output } = parseGlob ( key ) ;
83- proxy [ `^${ output } $` ] = proxy [ key ] ;
84- delete proxy [ key ] ;
133+ normalizedProxy [ `^${ output } $` ] = normalizedProxy [ key ] ;
134+ delete normalizedProxy [ key ] ;
85135 }
86136 }
137+
138+ return normalizedProxy ;
87139}
88140
89141/**
0 commit comments