@@ -13,16 +13,20 @@ const folderSeparator = '.';
1313 * @return {String|boolean } Full path or boolean false
1414 */
1515module . exports = ( tag , options ) => {
16- const fileNameFromTag = tag
17- . replace ( options . tagPrefix , '' )
18- . split ( folderSeparator )
19- . join ( path . sep )
20- . concat ( folderSeparator , options . fileExtension ) ;
16+ const extensions = Array . isArray ( options . fileExtension ) ? options . fileExtension : [ options . fileExtension ] ;
17+
18+ const fileNamesFromTag = extensions . map ( ext =>
19+ tag
20+ . replace ( options . tagPrefix , '' )
21+ . split ( folderSeparator )
22+ . join ( path . sep )
23+ . concat ( folderSeparator , ext )
24+ )
2125
2226 try {
23- return tag . includes ( options . namespaceSeparator ) ?
24- searchInNamespaces ( tag , fileNameFromTag . split ( options . namespaceSeparator ) , options ) :
25- searchInFolders ( tag , fileNameFromTag , options ) ;
27+ return tag . includes ( options . namespaceSeparator )
28+ ? searchInNamespaces ( tag , fileNamesFromTag , options )
29+ : searchInFolders ( tag , fileNamesFromTag , options ) ;
2630 } catch ( error ) {
2731 if ( options . strict ) {
2832 throw new Error ( error . message ) ;
@@ -36,15 +40,17 @@ module.exports = (tag, options) => {
3640 * Search component file in root
3741 *
3842 * @param {String } tag [tag name]
39- * @param {String } fileNameFromTag [filename converted from tag name]
43+ * @param {Array } fileNamesFromTag [filename converted from tag name]
4044 * @param {Object } options [posthtml options]
4145 * @return {String|boolean } [custom tag root where the module is found]
4246 */
43- function searchInFolders ( tag , fileNameFromTag , options ) {
44- const componentPath = search ( options . root , options . folders , fileNameFromTag , options . fileExtension ) ;
47+ function searchInFolders ( tag , fileNamesFromTag , options ) {
48+ const componentPath = search ( options . root , options . folders , fileNamesFromTag , options . fileExtension ) ;
4549
4650 if ( ! componentPath ) {
47- throw new Error ( `[components] <${ tag } > could not find ${ fileNameFromTag } in the defined root paths (${ options . folders . join ( ', ' ) } )` ) ;
51+ throw new Error (
52+ `[components] <${ tag } > could not find ${ fileNamesFromTag } in the defined root paths (${ options . folders . join ( ', ' ) } )`
53+ ) ;
4854 }
4955
5056 return componentPath ;
@@ -54,65 +60,89 @@ function searchInFolders(tag, fileNameFromTag, options) {
5460 * Search component file within all defined namespaces
5561 *
5662 * @param {String } tag [tag name with namespace]
57- * @param {String } namespace [tag's namespace]
58- * @param {String } fileNameFromTag [filename converted from tag name]
63+ * @param {Array } namespaceAndFileNames Array of [namespace]::[filename]
5964 * @param {Object } options [posthtml options]
6065 * @return {String|boolean } [custom tag root where the module is found]
6166 */
62- function searchInNamespaces ( tag , [ namespace , fileNameFromTag ] , options ) {
63- const namespaceOption = options . namespaces . find ( n => n . name === namespace . replace ( options . tagPrefix , '' ) ) ;
67+ function searchInNamespaces ( tag , namespaceAndFileNames , options ) {
68+ let result = '' ;
6469
65- if ( ! namespaceOption ) {
66- throw new Error ( `[components] Unknown component namespace: ${ namespace } .` ) ;
67- }
70+ for ( const namespaceAndFileName of namespaceAndFileNames ) {
71+ const [ namespace , fileNameFromTag ] = namespaceAndFileName . split ( '::' ) ;
6872
69- let componentPath ;
73+ const namespaceOption = options . namespaces . find ( n => n . name === namespace . replace ( options . tagPrefix , '' ) ) ;
7074
71- // 1) Check in custom root
72- if ( namespaceOption . custom ) {
73- componentPath = search ( namespaceOption . custom , options . folders , fileNameFromTag , options . fileExtension ) ;
74- }
75+ if ( ! namespaceOption ) {
76+ throw new Error ( `[components] Unknown component namespace: ${ namespace } .` ) ;
77+ }
7578
76- // 2) Check in base root
77- if ( ! componentPath ) {
78- componentPath = search ( namespaceOption . root , options . folders , fileNameFromTag , options . fileExtension ) ;
79- }
79+ let componentPath ;
8080
81- // 3) Check in fallback root
82- if ( ! componentPath && namespaceOption . fallback ) {
83- componentPath = search ( namespaceOption . fallback , options . folders , fileNameFromTag , options . fileExtension ) ;
84- }
81+ // 1) Check in custom root
82+ if ( namespaceOption . custom ) {
83+ componentPath = search ( namespaceOption . custom , options . folders , fileNameFromTag , options . fileExtension ) ;
84+ }
85+
86+ // 2) Check in base root
87+ if ( ! componentPath ) {
88+ componentPath = search ( namespaceOption . root , options . folders , fileNameFromTag , options . fileExtension ) ;
89+ }
90+
91+ // 3) Check in fallback root
92+ if ( ! componentPath && namespaceOption . fallback ) {
93+ componentPath = search ( namespaceOption . fallback , options . folders , fileNameFromTag , options . fileExtension ) ;
94+ }
8595
86- if ( ! componentPath && options . strict ) {
87- throw new Error ( `[components] <${ tag } > could not find ${ fileNameFromTag } in the defined namespace base path ${ namespaceOption . root } ` ) ;
96+ if ( ! componentPath ) {
97+ throw new Error ( `[components] <${ tag } > could not find ${ fileNameFromTag } in the defined namespace paths.` ) ;
98+ }
99+
100+ result = componentPath ;
88101 }
89102
90- return componentPath ;
103+ return result ;
91104}
92105
93106/**
94- * Main search component file function
107+ * Main component file search function
95108 *
96- * @param {String } root Base root or namespace root from options
97- * @param {Array } folders Folders from options
98- * @param {String } fileName Filename converted from tag name
99- * @param {String } extension File extension from options
109+ * @param {String } root Base root or namespace root from ` options`
110+ * @param {Array } folders Folders to search in from ` options`
111+ * @param {Array } fileNames Filenames converted from tag name
112+ * @param {Array } extensions File extension(s) from ` options`
100113 * @return {String|boolean } [custom tag root where the module is found]
101114 */
102- function search ( root , folders , fileName , extension ) {
115+ function search ( root , folders , fileNames , extensions ) {
103116 let componentPath ;
117+ let componentFound = false ;
104118
105- let componentFound = folders . some ( folder => {
106- componentPath = path . join ( path . resolve ( root , folder ) , fileName ) ;
107- return existsSync ( componentPath ) ;
108- } ) ;
119+ fileNames = Array . isArray ( fileNames ) ? fileNames : [ fileNames ] ;
109120
110- if ( ! componentFound ) {
111- fileName = fileName . replace ( `.${ extension } ` , `${ path . sep } index.${ extension } ` ) ;
121+ for ( const fileName of fileNames ) {
112122 componentFound = folders . some ( folder => {
113123 componentPath = path . join ( path . resolve ( root , folder ) , fileName ) ;
124+
114125 return existsSync ( componentPath ) ;
115126 } ) ;
127+
128+ if ( componentFound ) break ;
129+ }
130+
131+ if ( ! componentFound ) {
132+ for ( const extension of extensions ) {
133+ for ( const fileName of fileNames ) {
134+ const newFileName = fileName . replace ( `.${ extension } ` , `${ path . sep } index.${ extension } ` ) ;
135+
136+ componentFound = folders . some ( folder => {
137+ componentPath = path . join ( path . resolve ( root , folder ) , newFileName ) ;
138+ return existsSync ( componentPath ) ;
139+ } ) ;
140+
141+ if ( componentFound ) break ;
142+ }
143+
144+ if ( componentFound ) break ;
145+ }
116146 }
117147
118148 return componentFound ? componentPath : false ;
0 commit comments