@@ -3,6 +3,7 @@ import { fileURLToPath } from 'node:url'
33
44import { it } from 'vitest'
55
6+ import { createEnvProxy } from '@socketsecurity/lib/env'
67import { type SpawnOptions , spawn } from '@socketsecurity/lib/spawn'
78import { stripAnsi } from '@socketsecurity/lib/strings'
89
@@ -24,145 +25,6 @@ if (!process.env['VITEST']) {
2425 process . env [ 'VITEST' ] = '1'
2526}
2627
27- /**
28- * Create a case-insensitive environment variable Proxy for Windows compatibility.
29- * On Windows, environment variables are case-insensitive (PATH vs Path vs path).
30- * This Proxy provides consistent access regardless of case, with priority given
31- * to exact matches, then case-insensitive matches for known vars.
32- *
33- * @param base - Base environment object (usually process.env)
34- * @param overrides - Optional overrides to merge
35- * @returns Proxy that handles case-insensitive env var access
36- */
37- function createEnvProxy (
38- base : NodeJS . ProcessEnv ,
39- overrides ?: Record < string , string | undefined > ,
40- ) : NodeJS . ProcessEnv {
41- // Common environment variables that have case sensitivity issues on Windows.
42- const caseInsensitiveKeys = new Set ( [
43- 'PATH' ,
44- 'TEMP' ,
45- 'TMP' ,
46- 'HOME' ,
47- 'USERPROFILE' ,
48- 'APPDATA' ,
49- 'LOCALAPPDATA' ,
50- 'PROGRAMFILES' ,
51- 'SYSTEMROOT' ,
52- 'WINDIR' ,
53- ] )
54-
55- return new Proxy (
56- { } ,
57- {
58- get ( _target , prop ) {
59- if ( typeof prop !== 'string' ) {
60- return undefined
61- }
62-
63- // Priority 1: Check overrides for exact match.
64- if ( overrides && prop in overrides ) {
65- return overrides [ prop ]
66- }
67-
68- // Priority 2: Check base for exact match.
69- if ( prop in base ) {
70- return base [ prop ]
71- }
72-
73- // Priority 3: Case-insensitive lookup for known keys.
74- const upperProp = prop . toUpperCase ( )
75- if ( caseInsensitiveKeys . has ( upperProp ) ) {
76- // Check overrides with case variations.
77- if ( overrides ) {
78- for ( const key of Object . keys ( overrides ) ) {
79- if ( key . toUpperCase ( ) === upperProp ) {
80- return overrides [ key ]
81- }
82- }
83- }
84- // Check base with case variations.
85- for ( const key of Object . keys ( base ) ) {
86- if ( key . toUpperCase ( ) === upperProp ) {
87- return base [ key ]
88- }
89- }
90- }
91-
92- return undefined
93- } ,
94-
95- ownKeys ( _target ) {
96- const keys = new Set < string > ( [
97- ...Object . keys ( base ) ,
98- ...( overrides ? Object . keys ( overrides ) : [ ] ) ,
99- ] )
100- return [ ...keys ]
101- } ,
102-
103- getOwnPropertyDescriptor ( _target , prop ) {
104- if ( typeof prop !== 'string' ) {
105- return undefined
106- }
107-
108- // Use the same lookup logic as get().
109- const value = this . get ?.( _target , prop , _target )
110- return value !== undefined
111- ? {
112- enumerable : true ,
113- configurable : true ,
114- writable : true ,
115- value,
116- }
117- : undefined
118- } ,
119-
120- has ( _target , prop ) {
121- if ( typeof prop !== 'string' ) {
122- return false
123- }
124-
125- // Check overrides.
126- if ( overrides && prop in overrides ) {
127- return true
128- }
129-
130- // Check base.
131- if ( prop in base ) {
132- return true
133- }
134-
135- // Case-insensitive check.
136- const upperProp = prop . toUpperCase ( )
137- if ( caseInsensitiveKeys . has ( upperProp ) ) {
138- if ( overrides ) {
139- for ( const key of Object . keys ( overrides ) ) {
140- if ( key . toUpperCase ( ) === upperProp ) {
141- return true
142- }
143- }
144- }
145- for ( const key of Object . keys ( base ) ) {
146- if ( key . toUpperCase ( ) === upperProp ) {
147- return true
148- }
149- }
150- }
151-
152- return false
153- } ,
154-
155- set ( _target , prop , value ) {
156- if ( typeof prop === 'string' && overrides ) {
157- overrides [ prop ] = value
158- return true
159- }
160- return false
161- } ,
162- } ,
163- ) as NodeJS . ProcessEnv
164- }
165-
16628// Backward compatibility object for tests.
16729// In VITEST mode, use a Proxy to keep env vars live and handle case-sensitivity.
16830const constants = {
0 commit comments