@@ -8,12 +8,13 @@ const readdir = promisify(fs.readdir)
88// following the principles of the “sweet spot” discussed in
99// https://www.w3.org/DesignIssues/HTTPFilenameMapping.html
1010class ResourceMapper {
11- constructor ( { rootUrl, rootPath, includeHost, defaultContentType } ) {
11+ constructor ( { rootUrl, rootPath, includeHost, defaultContentType, indexName = 'index' } ) {
1212 this . _rootUrl = this . _removeTrailingSlash ( rootUrl )
1313 this . _rootPath = this . _removeTrailingSlash ( rootPath )
1414 this . _includeHost = includeHost
1515 this . _readdir = readdir
1616 this . _defaultContentType = defaultContentType
17+ this . _indexName = indexName
1718
1819 // If the host needs to be replaced on every call, pre-split the root URL
1920 if ( includeHost ) {
@@ -29,16 +30,28 @@ class ResourceMapper {
2930 }
3031
3132 // Maps the request for a given resource and representation format to a server file
33+ // When the URL ends with a '/', then files with the prefix 'index.' will be matched,
34+ // such as 'index.html' and 'index.ttl'.
3235 async mapUrlToFile ( { url, contentType, createIfNotExists } ) {
33- const fullPath = this . _getFullPath ( url )
36+ let fullPath = this . _getFullPath ( url )
37+ let isIndex = fullPath . endsWith ( '/' )
3438 let path
3539
40+ // Append index filename if the URL ends with a '/'
41+ if ( isIndex ) {
42+ fullPath += this . _indexName
43+ }
44+
3645 // Create the path for a new file
3746 if ( createIfNotExists ) {
3847 path = fullPath
3948 // If the extension is not correct for the content type, append the correct extension
4049 if ( this . _getContentTypeByExtension ( path ) !== contentType ) {
41- path += contentType in extensions ? `$.${ extensions [ contentType ] [ 0 ] } ` : '$.unknown'
50+ // Append a '$', unless we map for the index
51+ if ( ! isIndex ) {
52+ path += '$'
53+ }
54+ path += contentType in extensions ? `.${ extensions [ contentType ] [ 0 ] } ` : '.unknown'
4255 }
4356 // Determine the path of an existing file
4457 } else {
@@ -48,7 +61,8 @@ class ResourceMapper {
4861 const files = await this . _readdir ( folder )
4962
5063 // Find a file with the same name (minus the dollar extension)
51- const match = files . find ( f => this . _removeDollarExtension ( f ) === filename )
64+ const match = files . find ( f => this . _removeDollarExtension ( f ) === filename ||
65+ ( isIndex && f . startsWith ( this . _indexName + '.' ) ) )
5266 if ( ! match ) {
5367 throw new Error ( 'File not found' )
5468 }
0 commit comments