Move utilities into middleware/utils

This commit is contained in:
MICHAEL JACKSON
2017-08-18 12:57:42 -07:00
parent 2d03ed9be6
commit 7408b24adf
15 changed files with 149 additions and 154 deletions

View File

@ -0,0 +1,21 @@
const mime = require('mime')
mime.define({
'text/plain': [
'license',
'readme',
'changes',
'authors',
'makefile',
'ts',
'flow'
]
})
const TextFiles = /\/?(\.[a-z]*rc|\.git[a-z]*|\.[a-z]*ignore)$/i
function getFileContentType(file) {
return TextFiles.test(file) ? 'text/plain' : mime.lookup(file)
}
module.exports = getFileContentType

View File

@ -0,0 +1,34 @@
const getFileContentType = require('./getFileContentType')
it('gets a content type of text/plain for LICENSE|README|CHANGES|AUTHORS|Makefile', () => {
expect(getFileContentType('LICENSE')).toBe('text/plain')
expect(getFileContentType('README')).toBe('text/plain')
expect(getFileContentType('CHANGES')).toBe('text/plain')
expect(getFileContentType('AUTHORS')).toBe('text/plain')
expect(getFileContentType('Makefile')).toBe('text/plain')
})
it('gets a content type of text/plain for .*rc files', () => {
expect(getFileContentType('.eslintrc')).toBe('text/plain')
expect(getFileContentType('.babelrc')).toBe('text/plain')
expect(getFileContentType('.anythingrc')).toBe('text/plain')
})
it('gets a content type of text/plain for .git* files', () => {
expect(getFileContentType('.gitignore')).toBe('text/plain')
expect(getFileContentType('.gitanything')).toBe('text/plain')
})
it('gets a content type of text/plain for .*ignore files', () => {
expect(getFileContentType('.eslintignore')).toBe('text/plain')
expect(getFileContentType('.anythingignore')).toBe('text/plain')
})
it('gets a content type of text/plain for .ts files', () => {
expect(getFileContentType('app.ts')).toBe('text/plain')
expect(getFileContentType('app.d.ts')).toBe('text/plain')
})
it('gets a content type of text/plain for .flow files', () => {
expect(getFileContentType('app.js.flow')).toBe('text/plain')
})

View File

@ -0,0 +1,15 @@
const fs = require('fs')
function getFileStats(file) {
return new Promise((resolve, reject) => {
fs.lstat(file, (error, stats) => {
if (error) {
reject(error)
} else {
resolve(stats)
}
})
})
}
module.exports = getFileStats

View File

@ -0,0 +1,12 @@
function getFileType(stats) {
if (stats.isFile()) return 'file'
if (stats.isDirectory()) return 'directory'
if (stats.isBlockDevice()) return 'blockDevice'
if (stats.isCharacterDevice()) return 'characterDevice'
if (stats.isSymbolicLink()) return 'symlink'
if (stats.isSocket()) return 'socket'
if (stats.isFIFO()) return 'fifo'
return 'unknown'
}
module.exports = getFileType

View File

@ -0,0 +1,42 @@
const fs = require('fs')
const path = require('path')
const React = require('react')
const ReactDOMServer = require('react-dom/server')
const getFileStats = require('./getFileStats')
const IndexPage = require('../components/IndexPage')
const e = React.createElement
function getEntries(dir) {
return new Promise(function (resolve, reject) {
fs.readdir(dir, function (error, files) {
if (error) {
reject(error)
} else {
resolve(
Promise.all(
files.map(file => getFileStats(path.join(dir, file)))
).then(function (statsArray) {
return statsArray.map(function (stats, index) {
return { file: files[index], stats }
})
})
)
}
})
})
}
const DOCTYPE = '<!DOCTYPE html>'
function createHTML(props) {
return DOCTYPE + ReactDOMServer.renderToStaticMarkup(e(IndexPage, props))
}
function getIndexHTML(packageInfo, version, baseDir, dir, callback) {
getEntries(path.join(baseDir, dir))
.then(entries => createHTML({ packageInfo, version, dir, entries }))
.then(html => callback(null, html), callback)
}
module.exports = getIndexHTML

View File

@ -0,0 +1,77 @@
const fs = require('fs')
const path = require('path')
const SRIToolbox = require('sri-toolbox')
const getFileContentType = require('./getFileContentType')
const getFileStats = require('./getFileStats')
const getFileType = require('./getFileType')
function getEntries(dir, file, maximumDepth) {
return new Promise(function (resolve, reject) {
fs.readdir(path.join(dir, file), function (error, files) {
if (error) {
reject(error)
} else {
resolve(
Promise.all(
files.map(function (f) {
return getFileStats(path.join(dir, file, f))
})
).then(function (statsArray) {
return Promise.all(statsArray.map(function (stats, index) {
return getMetadataRecursive(dir, path.join(file, files[index]), stats, maximumDepth - 1)
}))
})
)
}
})
})
}
function formatTime(time) {
return new Date(time).toISOString()
}
function getIntegrity(file) {
return new Promise(function (resolve, reject) {
fs.readFile(file, function (error, data) {
if (error) {
reject(error)
} else {
resolve(SRIToolbox.generate({ algorithms: [ 'sha384' ] }, data))
}
})
})
}
function getMetadataRecursive(dir, file, stats, maximumDepth) {
const metadata = {
lastModified: formatTime(stats.mtime),
contentType: getFileContentType(file),
path: file,
size: stats.size,
type: getFileType(stats)
}
if (stats.isFile()) {
return getIntegrity(path.join(dir, file)).then(function (integrity) {
metadata.integrity = integrity
return metadata
})
}
if (!stats.isDirectory() || maximumDepth === 0)
return Promise.resolve(metadata)
return getEntries(dir, file, maximumDepth).then(function (files) {
metadata.files = files
return metadata
})
}
function getMetadata(baseDir, path, stats, maximumDepth, callback) {
getMetadataRecursive(baseDir, path, stats, maximumDepth).then(function (metadata) {
callback(null, metadata)
}, callback)
}
module.exports = getMetadata

View File

@ -0,0 +1,9 @@
const fs = require('fs')
const path = require('path')
const csso = require('csso')
function readCSS(...args) {
return csso.minify(fs.readFileSync(path.resolve(...args), 'utf8')).css
}
module.exports = readCSS