serve-handler
Advanced tools
Comparing version 2.1.2 to 2.2.0
{ | ||
"name": "serve-handler", | ||
"version": "2.1.2", | ||
"version": "2.2.0", | ||
"description": "The routing foundation of `serve` and static deployments on Now", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -53,3 +53,4 @@ # serve-handler | ||
- [headers](#headers-array) (set custom headers) | ||
- [directoryListing](#trailingslash-boolean) (disable directory listing or restrict it to certain paths) | ||
- [directoryListing](#directorylisting-booleanarray) (disable directory listing or restrict it to certain paths) | ||
- [unlisted](#unlisted-array) (exclude paths from the directory listing) | ||
- [trailingSlash](#trailingslash-boolean) (remove or add trailing slashes to all paths) | ||
@@ -186,2 +187,19 @@ | ||
### unlisted (Array) | ||
In certain cases, you might not want a file or directory to appear in the directory listing. In these situations, there are two ways of solving this problem. | ||
Either you disable the directory listing entirely (like shown [here](#directorylisting-booleanarray)), or you exclude certain paths from those listings by adding them all to this config property. | ||
```json | ||
{ | ||
"unlisted": [ | ||
".DS_Store", | ||
".git" | ||
] | ||
} | ||
``` | ||
The items shown above are excluded from the directory listing by default. | ||
### trailingSlash (Boolean) | ||
@@ -188,0 +206,0 @@ |
@@ -108,4 +108,5 @@ // Native | ||
if (typeof trailingSlash === 'boolean') { | ||
const {ext} = path.parse(decodedPath); | ||
const {ext, name} = path.parse(decodedPath); | ||
const isTrailed = decodedPath.endsWith('/'); | ||
const isDotfile = name.startsWith('.'); | ||
@@ -116,3 +117,3 @@ let target = null; | ||
target = decodedPath.slice(0, -1); | ||
} else if (trailingSlash && !isTrailed && !ext) { | ||
} else if (trailingSlash && !isTrailed && !ext && !isDotfile) { | ||
target = `${decodedPath}/`; | ||
@@ -255,4 +256,29 @@ } | ||
const canBeListed = (excluded, file) => { | ||
const slashed = slasher(file); | ||
let whether = true; | ||
for (let mark = 0; mark < excluded.length; mark++) { | ||
const source = excluded[mark]; | ||
if (sourceMatches(source, slashed)) { | ||
whether = false; | ||
break; | ||
} | ||
} | ||
return whether; | ||
}; | ||
const renderDirectory = async (current, relativePath, absolutePath, handlers, config) => { | ||
if (!applicable(relativePath, config.directoryListing, false)) { | ||
const {directoryListing, trailingSlash, unlisted = []} = config; | ||
const slashSuffix = typeof trailingSlash === 'boolean' ? (trailingSlash ? '/' : '') : '/'; | ||
const excluded = [ | ||
'.DS_Store', | ||
'.git', | ||
...unlisted | ||
]; | ||
if (!applicable(relativePath, directoryListing, false)) { | ||
return null; | ||
@@ -263,3 +289,5 @@ } | ||
for (const file of files) { | ||
for (let index = 0; index < files.length; index++) { | ||
const file = files[index]; | ||
const filePath = path.resolve(absolutePath, file); | ||
@@ -272,3 +300,6 @@ const details = path.parse(filePath); | ||
if (stats.isDirectory()) { | ||
details.base += '/'; | ||
details.base += slashSuffix; | ||
details.relative += slashSuffix; | ||
details.isDirectory = true; | ||
} else { | ||
@@ -280,12 +311,18 @@ details.ext = details.ext.split('.')[1] || 'txt'; | ||
details.title = details.base; | ||
files[files.indexOf(file)] = details; | ||
if (canBeListed(excluded, file)) { | ||
files[index] = details; | ||
} else { | ||
delete files[index]; | ||
} | ||
} | ||
const directory = path.join(path.basename(current), relativePath, '/'); | ||
const pathParts = directory.split(path.sep); | ||
const toRoot = path.relative(current, absolutePath); | ||
const directory = path.join(path.basename(current), toRoot, slashSuffix); | ||
const pathParts = directory.split(path.sep).filter(Boolean); | ||
// Sort to list directories first, then sort alphabetically | ||
files = files.sort((a, b) => { | ||
const aIsDir = a.base.endsWith('/'); | ||
const bIsDir = b.base.endsWith('/'); | ||
const aIsDir = a.isDirectory; | ||
const bIsDir = b.isDirectory; | ||
@@ -309,13 +346,13 @@ if (aIsDir && !bIsDir) { | ||
return 0; | ||
}); | ||
}).filter(Boolean); | ||
// Add parent directory to the head of the sorted files array | ||
if (absolutePath.indexOf(`${current}/`) > -1) { | ||
const directoryPath = [...pathParts]; | ||
directoryPath.shift(); | ||
if (toRoot.length > 0) { | ||
const directoryPath = [...pathParts].slice(1); | ||
const relative = path.join('/', ...directoryPath, '..', slashSuffix); | ||
files.unshift({ | ||
base: '..', | ||
relative: path.join(...directoryPath, '..'), | ||
title: path.join(...pathParts.slice(0, -2), '/') | ||
relative, | ||
title: relative | ||
}); | ||
@@ -325,13 +362,10 @@ } | ||
const paths = []; | ||
pathParts.pop(); | ||
for (const part in pathParts) { | ||
if (!{}.hasOwnProperty.call(pathParts, part)) { | ||
continue; | ||
} | ||
for (let index = 0; index < pathParts.length; index++) { | ||
const parents = []; | ||
const isLast = index === (pathParts.length - 1); | ||
let before = 0; | ||
const parents = []; | ||
while (before <= part) { | ||
while (before <= index) { | ||
parents.push(pathParts[before]); | ||
@@ -344,4 +378,4 @@ before++; | ||
paths.push({ | ||
name: pathParts[part], | ||
url: parents.join('/') | ||
name: pathParts[index] + (isLast ? slashSuffix : '/'), | ||
url: index === 0 ? '' : parents.join('/') + slashSuffix | ||
}); | ||
@@ -348,0 +382,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20332
358
248