@@ -17,7 +17,9 @@ import {
1717 getNodeDisableSigusr1Flags ,
1818 getNodeHardenFlags ,
1919 getNodeMajorVersion ,
20+ getNodeMinorVersion ,
2021 getNodeNoWarningsFlags ,
22+ getNodePatchVersion ,
2123 getNodePermissionFlags ,
2224 getNodeVersion ,
2325 supportsNodeCompileCacheApi ,
@@ -51,13 +53,39 @@ describe('node constants', () => {
5153
5254 it ( 'should match process.version major' , ( ) => {
5355 const expected = Number . parseInt (
54- process . version . slice ( 1 ) . split ( '.' ) [ 0 ] || '0' ,
56+ process . version . slice ( 1 ) . split ( '.' ) [ 0 ] ?? '0' ,
5557 10 ,
5658 )
5759 expect ( getNodeMajorVersion ( ) ) . toBe ( expected )
5860 } )
5961 } )
6062
63+ describe ( 'getNodeMinorVersion' , ( ) => {
64+ it ( 'should return minor version number' , ( ) => {
65+ const minor = getNodeMinorVersion ( )
66+ expect ( typeof minor ) . toBe ( 'number' )
67+ expect ( minor ) . toBeGreaterThanOrEqual ( 0 )
68+ } )
69+
70+ it ( 'should match process.version minor' , ( ) => {
71+ const expected = Number . parseInt ( process . version . split ( '.' ) [ 1 ] ?? '0' , 10 )
72+ expect ( getNodeMinorVersion ( ) ) . toBe ( expected )
73+ } )
74+ } )
75+
76+ describe ( 'getNodePatchVersion' , ( ) => {
77+ it ( 'should return patch version number' , ( ) => {
78+ const patch = getNodePatchVersion ( )
79+ expect ( typeof patch ) . toBe ( 'number' )
80+ expect ( patch ) . toBeGreaterThanOrEqual ( 0 )
81+ } )
82+
83+ it ( 'should match process.version patch' , ( ) => {
84+ const expected = Number . parseInt ( process . version . split ( '.' ) [ 2 ] ?? '0' , 10 )
85+ expect ( getNodePatchVersion ( ) ) . toBe ( expected )
86+ } )
87+ } )
88+
6189 describe ( 'getMaintainedNodeVersions' , ( ) => {
6290 it ( 'should return maintained versions object' , ( ) => {
6391 const versions = getMaintainedNodeVersions ( )
@@ -165,7 +193,7 @@ describe('node constants', () => {
165193 it ( 'should check minor version for Node.js 22' , ( ) => {
166194 const major = getNodeMajorVersion ( )
167195 if ( major === 22 ) {
168- const minor = Number . parseInt ( process . version . split ( '.' ) [ 1 ] || '0' , 10 )
196+ const minor = getNodeMinorVersion ( )
169197 const result = supportsNodeRequireModule ( )
170198 if ( minor >= 12 ) {
171199 expect ( result ) . toBe ( true )
@@ -193,7 +221,7 @@ describe('node constants', () => {
193221 it ( 'should check minor version for Node.js 22' , ( ) => {
194222 const major = getNodeMajorVersion ( )
195223 if ( major === 22 ) {
196- const minor = Number . parseInt ( process . version . split ( '.' ) [ 1 ] || '0' , 10 )
224+ const minor = getNodeMinorVersion ( )
197225 const result = supportsNodeRun ( )
198226 if ( minor >= 11 ) {
199227 expect ( result ) . toBe ( true )
@@ -212,7 +240,7 @@ describe('node constants', () => {
212240
213241 it ( 'should check version-specific support' , ( ) => {
214242 const major = getNodeMajorVersion ( )
215- const minor = Number . parseInt ( process . version . split ( '.' ) [ 1 ] || '0' , 10 )
243+ const minor = getNodeMinorVersion ( )
216244 const result = supportsNodeDisableSigusr1Flag ( )
217245
218246 if ( major >= 24 ) {
@@ -263,31 +291,54 @@ describe('node constants', () => {
263291 expect ( flags ) . toContain ( '--disable-proto=delete' )
264292 } )
265293
266- it ( 'should include force-node-api flag' , ( ) => {
267- const flags = getNodeHardenFlags ( )
268- expect ( flags ) . toContain ( '--force-node-api-uncaught-exceptions-policy' )
269- } )
270-
271- it ( 'should use --permission for Node.js 24+' , ( ) => {
294+ it ( 'should use --permission for Node.js 24+ with explicit grants' , ( ) => {
272295 const major = getNodeMajorVersion ( )
273296 const flags = getNodeHardenFlags ( )
274297 if ( major >= 24 ) {
275298 expect ( flags ) . toContain ( '--permission' )
276299 expect ( flags ) . not . toContain ( '--experimental-permission' )
277- expect ( flags ) . not . toContain ( '--experimental-policy' )
300+ // Should include permission grants from getNodePermissionFlags()
301+ expect ( flags ) . toContain ( '--allow-fs-read=*' )
302+ expect ( flags ) . toContain ( '--allow-fs-write=*' )
303+ expect ( flags ) . toContain ( '--allow-child-process' )
304+ } else {
305+ expect ( flags ) . not . toContain ( '--permission' )
306+ // Permission grants should not be included for Node < 24
307+ expect ( flags ) . not . toContain ( '--allow-fs-read=*' )
308+ expect ( flags ) . not . toContain ( '--allow-fs-write=*' )
309+ expect ( flags ) . not . toContain ( '--allow-child-process' )
278310 }
279311 } )
280312
281- it ( 'should use --experimental-permission for Node.js < 24 ' , ( ) => {
313+ it ( 'should use --experimental-permission for Node.js 20-23 ' , ( ) => {
282314 const major = getNodeMajorVersion ( )
283315 const flags = getNodeHardenFlags ( )
284- if ( major < 24 ) {
316+ if ( major >= 20 && major < 24 ) {
285317 expect ( flags ) . toContain ( '--experimental-permission' )
286- expect ( flags ) . toContain ( '--experimental-policy' )
318+ expect ( flags ) . not . toContain ( '--permission' )
319+ } else if ( major < 20 ) {
320+ expect ( flags ) . not . toContain ( '--experimental-permission' )
287321 expect ( flags ) . not . toContain ( '--permission' )
288322 }
289323 } )
290324
325+ it ( 'should include --force-node-api-uncaught-exceptions-policy for Node.js 22+' , ( ) => {
326+ const major = getNodeMajorVersion ( )
327+ const flags = getNodeHardenFlags ( )
328+ if ( major >= 22 ) {
329+ expect ( flags ) . toContain ( '--force-node-api-uncaught-exceptions-policy' )
330+ } else {
331+ expect ( flags ) . not . toContain (
332+ '--force-node-api-uncaught-exceptions-policy' ,
333+ )
334+ }
335+ } )
336+
337+ it ( 'should not include --experimental-policy' , ( ) => {
338+ const flags = getNodeHardenFlags ( )
339+ expect ( flags ) . not . toContain ( '--experimental-policy' )
340+ } )
341+
291342 it ( 'should return same instance on multiple calls' , ( ) => {
292343 const first = getNodeHardenFlags ( )
293344 const second = getNodeHardenFlags ( )
0 commit comments