@@ -54,90 +54,102 @@ const validateFallbacks = (fallbacks) => {
5454 return true ;
5555} ;
5656
57- // eslint-disable-next-line max-lines-per-function
58- const lint = ( packageJsonData , severity , config = { conditions : [ ] } ) => {
59- const conditions = [ ...( config . conditions || [ ] ) , 'default' ] ;
57+ const validateStringValue = ( parentKey , value ) => {
58+ if ( ! isValidPath ( value ) ) {
59+ return { error : 'invalidPath' , str : value } ;
60+ }
6061
61- if ( ! exists ( packageJsonData , nodeName ) ) return true ;
62+ if ( parentKey . endsWith ( '/' ) && ! value . endsWith ( '/' ) ) {
63+ return { error : 'folderMappedToFile' , str : parentKey } ;
64+ }
6265
63- // eslint-disable-next-line complexity,max-statements,max-lines-per-function
64- const traverse = ( parentKey , parentType , exports ) => {
65- if ( typeof exports === 'string' ) {
66- if ( ! isValidPath ( exports ) ) {
67- return { error : 'invalidPath' , str : exports } ;
68- }
66+ return true ;
67+ } ;
6968
70- if ( parentKey . endsWith ( '/' ) && ! exports . endsWith ( '/' ) ) {
71- return { error : 'folderMappedToFile' , str : parentKey } ;
72- }
69+ const validateObject = ( parentKey , parentType , object , config ) => {
70+ // either a paths object or a conditions object
71+ let objectType ;
7372
74- return true ;
75- }
73+ const entries = Object . entries ( object ) ;
7674
77- if ( Array . isArray ( exports ) ) {
78- // https://nodejs.org/api/esm.html#esm_package_exports_fallbacks
79- // eslint-disable-next-line no-restricted-syntax
80- return validateFallbacks ( exports ) ;
81- }
75+ for ( let i = 0 ; i < entries . length ; i += 1 ) {
76+ const [ key , value ] = entries [ i ] ;
8277
83- if ( ! isPlainObj ( exports ) ) {
84- return { error : 'unexpectedType' , str : typeof exports } ;
85- }
78+ if ( isValidPathKey ( key ) ) {
79+ if ( objectType === 'conditions' ) {
80+ return { error : 'pathInConditions' , str : key } ;
81+ }
8682
87- // either a paths object or a conditions object
88- let objectType ;
83+ if ( parentType === 'paths' ) {
84+ return { error : 'nestedPaths' , str : parentKey } ;
85+ }
8986
90- const entries = Object . entries ( exports ) ;
87+ objectType = 'paths' ;
9188
92- for ( let i = 0 ; i < entries . length ; i += 1 ) {
93- const [ key , value ] = entries [ i ] ;
89+ // eslint-disable-next-line no-use-before-define
90+ const result = traverse ( key , objectType , value , config ) ;
9491
95- if ( isValidPathKey ( key ) ) {
96- if ( objectType === 'conditions' ) {
97- return { error : 'pathInConditions' , str : key } ;
98- }
92+ if ( result !== true ) return result ;
93+ } else {
94+ // `key` interpreted as a condition
95+ if ( ! config . conditions . includes ( key ) ) {
96+ return { error : 'unsupportedCondition' , str : key } ;
97+ }
9998
100- if ( parentType === 'paths' ) {
101- return { error : 'nestedPaths ' , str : parentKey } ;
102- }
99+ if ( objectType === 'paths' ) {
100+ return { error : 'conditionInPaths ' , str : key } ;
101+ }
103102
104- objectType = 'paths' ;
103+ objectType = 'conditions' ;
104+ if ( key === 'default' && i + 1 < entries . length ) {
105+ return { error : 'defaultConditionNotLast' } ;
106+ }
105107
106- const result = traverse ( key , objectType , value ) ;
108+ // eslint-disable-next-line no-use-before-define
109+ const result = traverse ( key , objectType , value , config ) ;
107110
108- if ( result !== true ) return result ;
109- } else {
110- // `key` interpreted as a condition
111- if ( ! conditions . includes ( key ) ) {
112- return { error : 'unsupportedCondition' , str : key } ;
113- }
111+ if ( result !== true ) return result ;
112+ }
113+ }
114114
115- if ( objectType === 'paths' ) {
116- return { error : 'conditionInPaths' , str : key } ;
117- }
115+ return true ;
116+ } ;
118117
119- objectType = 'conditions' ;
120- if ( key === 'default' && i + 1 < entries . length ) {
121- return { error : 'defaultConditionNotLast' } ;
122- }
118+ const traverse = ( parentKey , parentType , node , config ) => {
119+ if ( typeof node === 'string' ) {
120+ return validateStringValue ( parentKey , node ) ;
121+ }
123122
124- const result = traverse ( key , objectType , value ) ;
123+ if ( Array . isArray ( node ) ) {
124+ // https://nodejs.org/api/esm.html#esm_package_exports_fallbacks
125+ return validateFallbacks ( node ) ;
126+ }
125127
126- if ( result !== true ) return result ;
127- }
128- }
128+ if ( ! isPlainObj ( node ) ) {
129+ return { error : 'unexpectedType' , str : typeof node } ;
130+ }
131+
132+ return validateObject ( parentKey , parentType , node , config ) ;
133+ } ;
129134
130- return true ;
135+ const lint = ( packageJsonData , severity , providedConfig ) => {
136+ const config = {
137+ conditions : [ ] ,
138+ ...providedConfig ,
131139 } ;
132140
133- const result = traverse ( nodeName , 'root' , packageJsonData [ nodeName ] ) ;
141+ config . conditions . push ( 'default' ) ;
142+
143+ if ( ! exists ( packageJsonData , nodeName ) ) return true ;
144+
145+ const result = traverse ( nodeName , 'root' , packageJsonData [ nodeName ] , config ) ;
134146
135147 if ( result !== true ) {
136148 const message = {
137149 invalidPath : `invalid path \`${ result . str } \` must start with \`./\`` ,
138150 pathInConditions : `found path key \`${ result . str } \` in a conditions object` ,
139151 nestedPaths : `key \`${ result . str } \` has paths object vaule but only conditions may be nested` ,
140- unsupportedCondition : `condition \`${ result . str } \` not in supported conditions \`${ conditions } \`` ,
152+ unsupportedCondition : `condition \`${ result . str } \` not in supported conditions \`${ config . conditions } \`` ,
141153 conditionInPaths : `found condition key \`${ result . str } \` in a paths object` ,
142154 unexpectedType : `unexpected \`${ result . str } \`` ,
143155 defaultConditionNotLast : 'condition `default` must be the last key' ,
0 commit comments