Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sort): Add sort option - micah/35/sort #75

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,24 @@ Display icons. Defaults to `false`.

Optional path to a CSS stylesheet. Defaults to a built-in stylesheet.

##### sort

Apply this sort function to files. Optional. The `sort` function is
called for each file tuple with the signature `sort(file1, file2)`.
An example for sorting files by date of modification (descending) is:
```js
function sortbyModifiedDate(file1, file2) {
// sort ".." to the top
if (file1.name === '..' || file2.name === '..') {
return file1.name === file2.name ? 0
: file1.name === '..' ? -1 : 1;
}
// sort directories first then sort files by date of modification
return Number(file2.stat && file2.stat.isDirectory()) - Number(file1.stat && file1.stat.isDirectory()) ||
new Date(file2.stat.mtime) - new Date(file1.stat.mtime);
}
```

##### template

Optional path to an HTML template or a function that will render a HTML
Expand Down
16 changes: 8 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function serveIndex(root, options) {
var stylesheet = opts.stylesheet || defaultStylesheet;
var template = opts.template || defaultTemplate;
var view = opts.view || 'tiles';

var sort = opts.sort || fileSort;
return function (req, res, next) {
if (req.method !== 'GET' && req.method !== 'HEAD') {
res.statusCode = 'OPTIONS' === req.method ? 200 : 405;
Expand Down Expand Up @@ -164,7 +164,7 @@ function serveIndex(root, options) {

// not acceptable
if (!type) return next(createError(406));
serveIndex[mediaType[type]](req, res, files, next, originalDir, showUp, icons, path, view, template, stylesheet);
serveIndex[mediaType[type]](req, res, files, next, originalDir, showUp, icons, path, sort, view, template, stylesheet);
});
});
};
Expand All @@ -174,7 +174,7 @@ function serveIndex(root, options) {
* Respond with text/html.
*/

serveIndex.html = function _html(req, res, files, next, dir, showUp, icons, path, view, template, stylesheet) {
serveIndex.html = function _html(req, res, files, next, dir, showUp, icons, path, sort, view, template, stylesheet) {
var render = typeof template !== 'function'
? createHtmlRender(template)
: template
Expand All @@ -188,7 +188,7 @@ serveIndex.html = function _html(req, res, files, next, dir, showUp, icons, path
if (err) return next(err);

// sort file list
fileList.sort(fileSort);
fileList.sort(sort);

// read stylesheet
fs.readFile(stylesheet, 'utf8', function (err, style) {
Expand Down Expand Up @@ -217,13 +217,13 @@ serveIndex.html = function _html(req, res, files, next, dir, showUp, icons, path
* Respond with application/json.
*/

serveIndex.json = function _json (req, res, files, next, dir, showUp, icons, path) {
serveIndex.json = function _json (req, res, files, next, dir, showUp, icons, path, sort) {
// stat all files
stat(path, files, function (err, fileList) {
if (err) return next(err)

// sort file list
fileList.sort(fileSort)
fileList.sort(sort)

// serialize
var body = JSON.stringify(fileList.map(function (file) {
Expand All @@ -238,13 +238,13 @@ serveIndex.json = function _json (req, res, files, next, dir, showUp, icons, pat
* Respond with text/plain.
*/

serveIndex.plain = function _plain (req, res, files, next, dir, showUp, icons, path) {
serveIndex.plain = function _plain (req, res, files, next, dir, showUp, icons, path, sort) {
// stat all files
stat(path, files, function (err, fileList) {
if (err) return next(err)

// sort file list
fileList.sort(fileSort)
fileList.sort(sort)

// serialize
var body = fileList.map(function (file) {
Expand Down
35 changes: 32 additions & 3 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,35 @@ describe('serveIndex(root)', function () {
});
});

describe('with "sort" option', function () {
it('should include icons for html', function (done) {
var server = createServer(fixtures, {'sort': function (a, b) {
return String(b.name).toLocaleLowerCase().localeCompare(String(a.name).toLocaleLowerCase());
}});

request(server)
.get('/')
.expect(200)
.end(function (err, res) {
if (err) done(err);
var body = res.text.split('</h1>')[1];
var urls = body.split(/<a href="([^"]*)"/).filter(function(s, i){ return i%2; });
assert.deepEqual(urls, [
'/%E3%81%95%E3%81%8F%E3%82%89.txt',
'/users',
'/todo.txt',
'/nums',
'/g%23%20%253%20o%20%26%20%252525%20%2537%20dir',
'/foo%20%26%20bar',
'/file%20%231.txt',
'/collect',
'/%23directory'
]);
done();
});
});
});

describe('with "template" option', function () {
describe('when setting a custom template file', function () {
var server;
Expand Down Expand Up @@ -584,7 +613,7 @@ describe('serveIndex(root)', function () {
it('should get template path', function (done) {
var server = createServer()

serveIndex.html = function (req, res, files, next, dir, showUp, icons, path, view, template) {
serveIndex.html = function (req, res, files, next, dir, showUp, icons, path, sort, view, template) {
res.setHeader('Content-Type', 'text/html')
res.end(String(fs.existsSync(template)))
}
Expand All @@ -598,7 +627,7 @@ describe('serveIndex(root)', function () {
it('should get template with tokens', function (done) {
var server = createServer()

serveIndex.html = function (req, res, files, next, dir, showUp, icons, path, view, template) {
serveIndex.html = function (req, res, files, next, dir, showUp, icons, path, sort, view, template) {
res.setHeader('Content-Type', 'text/html')
res.end(fs.readFileSync(template, 'utf8'))
}
Expand All @@ -616,7 +645,7 @@ describe('serveIndex(root)', function () {
it('should get stylesheet path', function (done) {
var server = createServer()

serveIndex.html = function (req, res, files, next, dir, showUp, icons, path, view, template, stylesheet) {
serveIndex.html = function (req, res, files, next, dir, showUp, icons, path, sort, view, template, stylesheet) {
res.setHeader('Content-Type', 'text/html')
res.end(String(fs.existsSync(stylesheet)))
}
Expand Down