This commit is contained in:
MICHAEL JACKSON
2017-11-25 13:25:01 -08:00
parent f3974b5e2d
commit 3a309241da
64 changed files with 635 additions and 801 deletions

View File

@ -1,4 +1,4 @@
const BlacklistAPI = require('../BlacklistAPI')
const BlacklistAPI = require("../BlacklistAPI")
function checkBlacklist(req, res, next) {
BlacklistAPI.includesPackage(req.packageName).then(
@ -7,7 +7,7 @@ function checkBlacklist(req, res, next) {
if (blacklisted) {
res
.status(403)
.type('text')
.type("text")
.send(`Package "${req.packageName}" is blacklisted`)
} else {
next()
@ -17,7 +17,7 @@ function checkBlacklist(req, res, next) {
console.error(error)
res.status(500).send({
error: 'Unable to fetch the blacklist'
error: "Unable to fetch the blacklist"
})
}
)

View File

@ -1,6 +1,6 @@
const React = require('react')
const prettyBytes = require('pretty-bytes')
const getFileContentType = require('../utils/getFileContentType')
const React = require("react")
const prettyBytes = require("pretty-bytes")
const getFileContentType = require("../utils/getFileContentType")
const e = React.createElement
@ -9,46 +9,46 @@ const formatTime = time => new Date(time).toISOString()
const DirectoryListing = ({ dir, entries }) => {
const rows = entries.map(({ file, stats }, index) => {
const isDir = stats.isDirectory()
const href = file + (isDir ? '/' : '')
const href = file + (isDir ? "/" : "")
return e(
'tr',
{ key: file, className: index % 2 ? 'odd' : 'even' },
e('td', null, e('a', { title: file, href }, file)),
e('td', null, isDir ? '-' : getFileContentType(file)),
e('td', null, isDir ? '-' : prettyBytes(stats.size)),
e('td', null, isDir ? '-' : formatTime(stats.mtime))
"tr",
{ key: file, className: index % 2 ? "odd" : "even" },
e("td", null, e("a", { title: file, href }, file)),
e("td", null, isDir ? "-" : getFileContentType(file)),
e("td", null, isDir ? "-" : prettyBytes(stats.size)),
e("td", null, isDir ? "-" : formatTime(stats.mtime))
)
})
if (dir !== '/')
if (dir !== "/")
rows.unshift(
e(
'tr',
{ key: '..', className: 'odd' },
e('td', null, e('a', { title: 'Parent directory', href: '../' }, '..')),
e('td', null, '-'),
e('td', null, '-'),
e('td', null, '-')
"tr",
{ key: "..", className: "odd" },
e("td", null, e("a", { title: "Parent directory", href: "../" }, "..")),
e("td", null, "-"),
e("td", null, "-"),
e("td", null, "-")
)
)
return e(
'table',
"table",
null,
e(
'thead',
"thead",
null,
e(
'tr',
"tr",
null,
e('th', null, 'Name'),
e('th', null, 'Type'),
e('th', null, 'Size'),
e('th', null, 'Last Modified')
e("th", null, "Name"),
e("th", null, "Type"),
e("th", null, "Size"),
e("th", null, "Last Modified")
)
),
e('tbody', null, rows)
e("tbody", null, rows)
)
}

View File

@ -1,11 +1,11 @@
const React = require('react')
const semver = require('semver')
const DirectoryListing = require('./DirectoryListing')
const readCSS = require('../utils/readCSS')
const React = require("react")
const semver = require("semver")
const DirectoryListing = require("./DirectoryListing")
const readCSS = require("../utils/readCSS")
const e = React.createElement
const IndexPageStyle = readCSS(__dirname, 'IndexPage.css')
const IndexPageStyle = readCSS(__dirname, "IndexPage.css")
const IndexPageScript = `
var s = document.getElementById('version'), v = s.value
s.onchange = function () {
@ -17,37 +17,35 @@ const byVersion = (a, b) => (semver.lt(a, b) ? -1 : semver.gt(a, b) ? 1 : 0)
const IndexPage = ({ packageInfo, version, dir, entries }) => {
const versions = Object.keys(packageInfo.versions).sort(byVersion)
const options = versions.map(v =>
e('option', { key: v, value: v }, `${packageInfo.name}@${v}`)
)
const options = versions.map(v => e("option", { key: v, value: v }, `${packageInfo.name}@${v}`))
return e(
'html',
"html",
null,
e(
'head',
"head",
null,
e('meta', { charSet: 'utf-8' }),
e('title', null, `Index of ${dir}`),
e('style', { dangerouslySetInnerHTML: { __html: IndexPageStyle } })
e("meta", { charSet: "utf-8" }),
e("title", null, `Index of ${dir}`),
e("style", { dangerouslySetInnerHTML: { __html: IndexPageStyle } })
),
e(
'body',
"body",
null,
e(
'div',
{ className: 'content-wrapper' },
"div",
{ className: "content-wrapper" },
e(
'div',
{ className: 'version-wrapper' },
e('select', { id: 'version', defaultValue: version }, options)
"div",
{ className: "version-wrapper" },
e("select", { id: "version", defaultValue: version }, options)
),
e('h1', null, `Index of ${dir}`),
e('script', { dangerouslySetInnerHTML: { __html: IndexPageScript } }),
e('hr'),
e("h1", null, `Index of ${dir}`),
e("script", { dangerouslySetInnerHTML: { __html: IndexPageScript } }),
e("hr"),
e(DirectoryListing, { dir, entries }),
e('hr'),
e('address', null, `${packageInfo.name}@${version}`)
e("hr"),
e("address", null, `${packageInfo.name}@${version}`)
)
)
)

View File

@ -1,11 +1,11 @@
const fs = require('fs')
const path = require('path')
const semver = require('semver')
const createPackageURL = require('../utils/createPackageURL')
const createSearch = require('./utils/createSearch')
const getPackageInfo = require('./utils/getPackageInfo')
const getPackage = require('./utils/getPackage')
const incrementCounter = require('./utils/incrementCounter')
const fs = require("fs")
const path = require("path")
const semver = require("semver")
const createPackageURL = require("../utils/createPackageURL")
const createSearch = require("./utils/createSearch")
const getPackageInfo = require("./utils/getPackageInfo")
const getPackage = require("./utils/getPackage")
const incrementCounter = require("./utils/incrementCounter")
function getBasename(file) {
return path.basename(file, path.extname(file))
@ -14,7 +14,7 @@ function getBasename(file) {
/**
* File extensions to look for when automatically resolving.
*/
const FindExtensions = ['', '.js', '.json']
const FindExtensions = ["", ".js", ".json"]
/**
* Resolves a path like "lib/file" into "lib/file.js" or "lib/file.json"
@ -27,17 +27,13 @@ function findFile(base, useIndex, callback) {
return function() {
fs.stat(file, function(error, stats) {
if (error) {
if (error.code === 'ENOENT' || error.code === 'ENOTDIR') {
if (error.code === "ENOENT" || error.code === "ENOTDIR") {
next()
} else {
callback(error)
}
} else if (useIndex && stats.isDirectory()) {
findFile(path.join(file, 'index'), false, function(
error,
indexFile,
indexStats
) {
findFile(path.join(file, "index"), false, function(error, indexFile, indexStats) {
if (error) {
callback(error)
} else if (indexFile) {
@ -65,14 +61,14 @@ function fetchFile(req, res, next) {
console.error(error)
return res
.status(500)
.type('text')
.type("text")
.send(`Cannot get info for package "${req.packageName}"`)
}
if (packageInfo == null || packageInfo.versions == null)
return res
.status(404)
.type('text')
.type("text")
.send(`Cannot find package "${req.packageName}"`)
req.packageInfo = packageInfo
@ -86,7 +82,7 @@ function fetchFile(req, res, next) {
console.error(error)
res
.status(500)
.type('text')
.type("text")
.send(`Cannot fetch package ${req.packageSpec}`)
} else {
req.packageDir = outputDir
@ -98,77 +94,56 @@ function fetchFile(req, res, next) {
// They want an ES module. Try "module", "jsnext:main", and "/"
// https://github.com/rollup/rollup/wiki/pkg.module
if (!filename)
filename =
req.packageConfig.module ||
req.packageConfig['jsnext:main'] ||
'/'
filename = req.packageConfig.module || req.packageConfig["jsnext:main"] || "/"
} else if (filename) {
// They are requesting an explicit filename. Only try to find an
// index file if they are NOT requesting an HTML directory listing.
useIndex = filename[filename.length - 1] !== '/'
} else if (
req.query.main &&
typeof req.packageConfig[req.query.main] === 'string'
) {
useIndex = filename[filename.length - 1] !== "/"
} else if (req.query.main && typeof req.packageConfig[req.query.main] === "string") {
// They specified a custom ?main field.
filename = req.packageConfig[req.query.main]
incrementCounter(
'package-json-custom-main',
req.packageSpec + '?main=' + req.query.main,
"package-json-custom-main",
req.packageSpec + "?main=" + req.query.main,
1
)
} else if (typeof req.packageConfig.unpkg === 'string') {
} else if (typeof req.packageConfig.unpkg === "string") {
// The "unpkg" field allows packages to explicitly declare the
// file to serve at the bare URL (see #59).
filename = req.packageConfig.unpkg
} else if (typeof req.packageConfig.browser === 'string') {
} else if (typeof req.packageConfig.browser === "string") {
// Fall back to the "browser" field if declared (only support strings).
filename = req.packageConfig.browser
// Count which packages + versions are actually using this fallback
// so we can warn them when we deprecate this functionality.
// See https://github.com/unpkg/unpkg/issues/63
incrementCounter(
'package-json-browser-fallback',
req.packageSpec,
1
)
incrementCounter("package-json-browser-fallback", req.packageSpec, 1)
} else {
// Fall back to "main" or / (same as npm).
filename = req.packageConfig.main || '/'
filename = req.packageConfig.main || "/"
}
findFile(path.join(req.packageDir, filename), useIndex, function(
error,
file,
stats
) {
findFile(path.join(req.packageDir, filename), useIndex, function(error, file, stats) {
if (error) console.error(error)
if (file == null)
return res
.status(404)
.type('text')
.send(
`Cannot find module "${filename}" in package ${
req.packageSpec
}`
)
.type("text")
.send(`Cannot find module "${filename}" in package ${req.packageSpec}`)
filename = file.replace(req.packageDir, '')
filename = file.replace(req.packageDir, "")
if (
req.query.main != null ||
getBasename(req.filename) !== getBasename(filename)
) {
if (req.query.main != null || getBasename(req.filename) !== getBasename(filename)) {
// Need to redirect to the module file so relative imports resolve
// correctly. Cache module redirects for 1 minute.
delete req.query.main
res
.set({
'Cache-Control': 'public, max-age=60',
'Cache-Tag': 'redirect,module-redirect'
"Cache-Control": "public, max-age=60",
"Cache-Tag": "redirect,module-redirect"
})
.redirect(
302,
@ -187,18 +162,18 @@ function fetchFile(req, res, next) {
})
}
})
} else if (req.packageVersion in req.packageInfo['dist-tags']) {
} else if (req.packageVersion in req.packageInfo["dist-tags"]) {
// Cache tag redirects for 1 minute.
res
.set({
'Cache-Control': 'public, max-age=60',
'Cache-Tag': 'redirect,tag-redirect'
"Cache-Control": "public, max-age=60",
"Cache-Tag": "redirect,tag-redirect"
})
.redirect(
302,
createPackageURL(
req.packageName,
req.packageInfo['dist-tags'][req.packageVersion],
req.packageInfo["dist-tags"][req.packageVersion],
req.filename,
req.search
)
@ -213,22 +188,14 @@ function fetchFile(req, res, next) {
// Cache semver redirects for 1 minute.
res
.set({
'Cache-Control': 'public, max-age=60',
'Cache-Tag': 'redirect,semver-redirect'
"Cache-Control": "public, max-age=60",
"Cache-Tag": "redirect,semver-redirect"
})
.redirect(
302,
createPackageURL(
req.packageName,
maxVersion,
req.filename,
req.search
)
)
.redirect(302, createPackageURL(req.packageName, maxVersion, req.filename, req.search))
} else {
res
.status(404)
.type('text')
.type("text")
.send(`Cannot find package ${req.packageSpec}`)
}
}

View File

@ -1,6 +1,6 @@
const validateNpmPackageName = require('validate-npm-package-name')
const parsePackageURL = require('../utils/parsePackageURL')
const createSearch = require('./utils/createSearch')
const validateNpmPackageName = require("validate-npm-package-name")
const parsePackageURL = require("../utils/parsePackageURL")
const createSearch = require("./utils/createSearch")
const KnownQueryParams = {
main: true,
@ -32,14 +32,14 @@ function sanitizeQuery(query) {
function parseURL(req, res, next) {
// Redirect /_meta/path to /path?meta.
if (req.path.match(/^\/_meta\//)) {
req.query.meta = ''
req.query.meta = ""
return res.redirect(302, req.path.substr(6) + createSearch(req.query))
}
// Redirect /path?json => /path?meta
if (req.query.json != null) {
delete req.query.json
req.query.meta = ''
req.query.meta = ""
return res.redirect(302, req.path + createSearch(req.query))
}
@ -56,7 +56,7 @@ function parseURL(req, res, next) {
if (url == null) {
return res
.status(403)
.type('text')
.type("text")
.send(`Invalid URL: ${req.url}`)
}
@ -64,10 +64,10 @@ function parseURL(req, res, next) {
// Disallow invalid package names.
if (nameErrors) {
const reason = nameErrors.join(', ')
const reason = nameErrors.join(", ")
return res
.status(403)
.type('text')
.type("text")
.send(`Invalid package name "${url.packageName}" (${reason})`)
}

View File

@ -4,10 +4,9 @@
*/
function requireAuth(scope) {
let checkScopes
if (scope.includes('.')) {
const parts = scope.split('.')
checkScopes = scopes =>
parts.reduce((memo, part) => memo && memo[part], scopes) != null
if (scope.includes(".")) {
const parts = scope.split(".")
checkScopes = scopes => parts.reduce((memo, part) => memo && memo[part], scopes) != null
} else {
checkScopes = scopes => scopes[scope] != null
}
@ -20,11 +19,11 @@ function requireAuth(scope) {
const user = req.user
if (!user) {
return res.status(403).send({ error: 'Missing auth token' })
return res.status(403).send({ error: "Missing auth token" })
}
if (!user.scopes || !checkScopes(user.scopes)) {
return res.status(403).send({ error: 'Insufficient scopes' })
return res.status(403).send({ error: "Insufficient scopes" })
}
if (req.auth) {

View File

@ -1,11 +1,11 @@
const fs = require('fs')
const path = require('path')
const etag = require('etag')
const babel = require('babel-core')
const unpkgRewrite = require('babel-plugin-unpkg-rewrite')
const getMetadata = require('./utils/getMetadata')
const getFileContentType = require('./utils/getFileContentType')
const getIndexHTML = require('./utils/getIndexHTML')
const fs = require("fs")
const path = require("path")
const etag = require("etag")
const babel = require("babel-core")
const unpkgRewrite = require("babel-plugin-unpkg-rewrite")
const getMetadata = require("./utils/getMetadata")
const getFileContentType = require("./utils/getFileContentType")
const getIndexHTML = require("./utils/getIndexHTML")
/**
* Automatically generate HTML pages that show package contents.
@ -35,24 +35,19 @@ const FileTransforms = {
function serveFile(req, res, next) {
if (req.query.meta != null) {
// Serve JSON metadata.
getMetadata(req.packageDir, req.filename, req.stats, MaximumDepth, function(
error,
metadata
) {
getMetadata(req.packageDir, req.filename, req.stats, MaximumDepth, function(error, metadata) {
if (error) {
console.error(error)
res
.status(500)
.type('text')
.send(
`Cannot generate metadata for ${req.packageSpec}${req.filename}`
)
.type("text")
.send(`Cannot generate metadata for ${req.packageSpec}${req.filename}`)
} else {
// Cache metadata for 1 year.
res
.set({
'Cache-Control': 'public, max-age=31536000',
'Cache-Tag': 'meta'
"Cache-Control": "public, max-age=31536000",
"Cache-Tag": "meta"
})
.send(metadata)
}
@ -63,9 +58,9 @@ function serveFile(req, res, next) {
let contentType = getFileContentType(file)
if (contentType === 'text/html') contentType = 'text/plain' // We can't serve HTML because bad people :(
if (contentType === "text/html") contentType = "text/plain" // We can't serve HTML because bad people :(
if (contentType === 'application/javascript' && req.query.module != null) {
if (contentType === "application/javascript" && req.query.module != null) {
// Serve a JavaScript module.
const dependencies = Object.assign(
{},
@ -78,33 +73,29 @@ function serveFile(req, res, next) {
console.error(error)
const debugInfo =
error.constructor.name +
': ' +
": " +
error.message.replace(/^.*?\/unpkg-.+?\//, `/${req.packageSpec}/`) +
'\n\n' +
"\n\n" +
error.codeFrame
res
.status(500)
.type('text')
.send(
`Cannot generate module for ${req.packageSpec}${
req.filename
}\n\n${debugInfo}`
)
.type("text")
.send(`Cannot generate module for ${req.packageSpec}${req.filename}\n\n${debugInfo}`)
} else {
// Cache modules for 1 year.
res
.set({
'Content-Type': contentType,
'Content-Length': Buffer.byteLength(code),
'Cache-Control': 'public, max-age=31536000',
'Cache-Tag': 'file,js-file,js-module'
"Content-Type": contentType,
"Content-Length": Buffer.byteLength(code),
"Cache-Control": "public, max-age=31536000",
"Cache-Tag": "file,js-file,js-module"
})
.send(code)
}
})
} else {
// Serve some other static file.
const tags = ['file']
const tags = ["file"]
const ext = path.extname(req.filename).substr(1)
@ -112,17 +103,17 @@ function serveFile(req, res, next) {
// Cache files for 1 year.
res.set({
'Content-Type': contentType,
'Content-Length': req.stats.size,
'Cache-Control': 'public, max-age=31536000',
'Last-Modified': req.stats.mtime.toUTCString(),
"Content-Type": contentType,
"Content-Length": req.stats.size,
"Cache-Control": "public, max-age=31536000",
"Last-Modified": req.stats.mtime.toUTCString(),
ETag: etag(req.stats),
'Cache-Tag': tags.join(',')
"Cache-Tag": tags.join(",")
})
const stream = fs.createReadStream(file)
stream.on('error', function(error) {
stream.on("error", function(error) {
console.error(`Cannot send file ${req.packageSpec}${req.filename}`)
console.error(error)
res.sendStatus(500)
@ -132,35 +123,30 @@ function serveFile(req, res, next) {
}
} else if (AutoIndex && req.stats.isDirectory()) {
// Serve an HTML directory listing.
getIndexHTML(
req.packageInfo,
req.packageVersion,
req.packageDir,
req.filename,
function(error, html) {
if (error) {
console.error(error)
res
.status(500)
.type('text')
.send(
`Cannot generate index page for ${req.packageSpec}${req.filename}`
)
} else {
// Cache HTML directory listings for 1 minute.
res
.set({
'Cache-Control': 'public, max-age=60',
'Cache-Tag': 'index'
})
.send(html)
}
getIndexHTML(req.packageInfo, req.packageVersion, req.packageDir, req.filename, function(
error,
html
) {
if (error) {
console.error(error)
res
.status(500)
.type("text")
.send(`Cannot generate index page for ${req.packageSpec}${req.filename}`)
} else {
// Cache HTML directory listings for 1 minute.
res
.set({
"Cache-Control": "public, max-age=60",
"Cache-Tag": "index"
})
.send(html)
}
)
})
} else {
res
.status(403)
.type('text')
.type("text")
.send(`Cannot serve ${req.packageSpec}${req.filename}; it's not a file`)
}
}

View File

@ -1,4 +1,4 @@
const AuthAPI = require('../AuthAPI')
const AuthAPI = require("../AuthAPI")
const ReadMethods = { GET: true, HEAD: true }
@ -23,7 +23,7 @@ function userToken(req, res, next) {
next()
},
error => {
if (error.name === 'JsonWebTokenError') {
if (error.name === "JsonWebTokenError") {
res.status(403).send({
error: `Bad auth token: ${error.message}`
})
@ -31,7 +31,7 @@ function userToken(req, res, next) {
console.error(error)
res.status(500).send({
error: 'Unable to verify auth'
error: "Unable to verify auth"
})
}
}

View File

@ -1,35 +1,35 @@
const getFileContentType = require('../getFileContentType')
const getFileContentType = require("../getFileContentType")
it('gets a content type of text/plain for LICENSE|README|CHANGES|AUTHORS|Makefile', () => {
expect(getFileContentType('AUTHORS')).toBe('text/plain')
expect(getFileContentType('CHANGES')).toBe('text/plain')
expect(getFileContentType('LICENSE')).toBe('text/plain')
expect(getFileContentType('Makefile')).toBe('text/plain')
expect(getFileContentType('PATENTS')).toBe('text/plain')
expect(getFileContentType('README')).toBe('text/plain')
it("gets a content type of text/plain for LICENSE|README|CHANGES|AUTHORS|Makefile", () => {
expect(getFileContentType("AUTHORS")).toBe("text/plain")
expect(getFileContentType("CHANGES")).toBe("text/plain")
expect(getFileContentType("LICENSE")).toBe("text/plain")
expect(getFileContentType("Makefile")).toBe("text/plain")
expect(getFileContentType("PATENTS")).toBe("text/plain")
expect(getFileContentType("README")).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 .*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 .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 .*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 .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')
it("gets a content type of text/plain for .flow files", () => {
expect(getFileContentType("app.js.flow")).toBe("text/plain")
})

View File

@ -1,8 +1,8 @@
const db = require('../../RedisClient')
const db = require("../../RedisClient")
function createCache(keyPrefix) {
function createKey(key) {
return keyPrefix + '-' + key
return keyPrefix + "-" + key
}
function set(key, value, expiry, callback) {

View File

@ -2,16 +2,16 @@ function createSearch(query) {
const params = []
Object.keys(query).forEach(param => {
if (query[param] === '') {
if (query[param] === "") {
params.push(param) // Omit the trailing "=" from param=
} else {
params.push(`${param}=${encodeURIComponent(query[param])}`)
}
})
const search = params.join('&')
const search = params.join("&")
return search ? `?${search}` : ''
return search ? `?${search}` : ""
}
module.exports = createSearch

View File

@ -1,22 +1,13 @@
const mime = require('mime')
const mime = require("mime")
mime.define({
'text/plain': [
'authors',
'changes',
'license',
'makefile',
'patents',
'readme',
'ts',
'flow'
]
"text/plain": ["authors", "changes", "license", "makefile", "patents", "readme", "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)
return TextFiles.test(file) ? "text/plain" : mime.lookup(file)
}
module.exports = getFileContentType

View File

@ -1,4 +1,4 @@
const fs = require('fs')
const fs = require("fs")
function getFileStats(file) {
return new Promise((resolve, reject) => {

View File

@ -1,12 +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'
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

@ -1,9 +1,9 @@
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 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
@ -14,9 +14,7 @@ function getEntries(dir) {
reject(error)
} else {
resolve(
Promise.all(
files.map(file => getFileStats(path.join(dir, file)))
).then(statsArray => {
Promise.all(files.map(file => getFileStats(path.join(dir, file)))).then(statsArray => {
return statsArray.map((stats, index) => {
return { file: files[index], stats }
})
@ -27,7 +25,7 @@ function getEntries(dir) {
})
}
const DOCTYPE = '<!DOCTYPE html>'
const DOCTYPE = "<!DOCTYPE html>"
function createHTML(props) {
return DOCTYPE + ReactDOMServer.renderToStaticMarkup(e(IndexPage, props))

View File

@ -1,9 +1,9 @@
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')
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((resolve, reject) => {
@ -12,17 +12,10 @@ function getEntries(dir, file, maximumDepth) {
reject(error)
} else {
resolve(
Promise.all(
files.map(f => getFileStats(path.join(dir, file, f)))
).then(statsArray => {
Promise.all(files.map(f => getFileStats(path.join(dir, file, f)))).then(statsArray => {
return Promise.all(
statsArray.map((stats, index) =>
getMetadataRecursive(
dir,
path.join(file, files[index]),
stats,
maximumDepth - 1
)
getMetadataRecursive(dir, path.join(file, files[index]), stats, maximumDepth - 1)
)
)
})
@ -42,7 +35,7 @@ function getIntegrity(file) {
if (error) {
reject(error)
} else {
resolve(SRIToolbox.generate({ algorithms: ['sha384'] }, data))
resolve(SRIToolbox.generate({ algorithms: ["sha384"] }, data))
}
})
})
@ -64,8 +57,7 @@ function getMetadataRecursive(dir, file, stats, maximumDepth) {
})
}
if (!stats.isDirectory() || maximumDepth === 0)
return Promise.resolve(metadata)
if (!stats.isDirectory() || maximumDepth === 0) return Promise.resolve(metadata)
return getEntries(dir, file, maximumDepth).then(files => {
metadata.files = files
@ -74,12 +66,9 @@ function getMetadataRecursive(dir, file, stats, maximumDepth) {
}
function getMetadata(baseDir, path, stats, maximumDepth, callback) {
getMetadataRecursive(baseDir, path, stats, maximumDepth).then(function(
metadata
) {
getMetadataRecursive(baseDir, path, stats, maximumDepth).then(function(metadata) {
callback(null, metadata)
},
callback)
}, callback)
}
module.exports = getMetadata

View File

@ -1,14 +1,14 @@
require('isomorphic-fetch')
const fs = require('fs')
const path = require('path')
const tmpdir = require('os-tmpdir')
const gunzip = require('gunzip-maybe')
const mkdirp = require('mkdirp')
const tar = require('tar-fs')
const createMutex = require('./createMutex')
require("isomorphic-fetch")
const fs = require("fs")
const path = require("path")
const tmpdir = require("os-tmpdir")
const gunzip = require("gunzip-maybe")
const mkdirp = require("mkdirp")
const tar = require("tar-fs")
const createMutex = require("./createMutex")
function createTempPath(name, version) {
const normalName = name.replace(/\//g, '-')
const normalName = name.replace(/\//g, "-")
return path.join(tmpdir(), `unpkg-${normalName}-${version}`)
}
@ -17,12 +17,12 @@ function stripNamePrefix(headers) {
// so we shorten that to just "index.js" here. A few packages use a
// prefix other than "package/". e.g. the firebase package uses the
// "firebase_npm/" prefix. So we just strip the first dir name.
headers.name = headers.name.replace(/^[^\/]+\//, '')
headers.name = headers.name.replace(/^[^\/]+\//, "")
return headers
}
function ignoreSymlinks(file, headers) {
return headers.type === 'link'
return headers.type === "link"
}
function extractResponse(response, outputDir) {
@ -36,8 +36,8 @@ function extractResponse(response, outputDir) {
response.body
.pipe(gunzip())
.pipe(extract)
.on('finish', resolve)
.on('error', reject)
.on("finish", resolve)
.on("error", reject)
})
}
@ -54,7 +54,7 @@ const fetchMutex = createMutex((payload, callback) => {
fs.access(outputDir, function(error) {
if (error) {
if (error.code === 'ENOENT' || error.code === 'ENOTDIR') {
if (error.code === "ENOENT" || error.code === "ENOTDIR") {
// ENOENT or ENOTDIR are to be expected when we haven't yet
// fetched a package for the first time. Carry on!
mkdirp(outputDir, function(error) {

View File

@ -1,16 +1,16 @@
require('isomorphic-fetch')
const createCache = require('./createCache')
const createMutex = require('./createMutex')
require("isomorphic-fetch")
const createCache = require("./createCache")
const createMutex = require("./createMutex")
const RegistryURL = process.env.NPM_REGISTRY_URL || 'https://registry.npmjs.org'
const RegistryURL = process.env.NPM_REGISTRY_URL || "https://registry.npmjs.org"
const PackageInfoCache = createCache('packageInfo')
const PackageInfoCache = createCache("packageInfo")
function fetchPackageInfo(packageName) {
console.log(`info: Fetching package info for ${packageName}`)
let encodedPackageName
if (packageName.charAt(0) === '@') {
if (packageName.charAt(0) === "@") {
encodedPackageName = `@${encodeURIComponent(packageName.substring(1))}`
} else {
encodedPackageName = encodeURIComponent(packageName)
@ -20,14 +20,14 @@ function fetchPackageInfo(packageName) {
return fetch(url, {
headers: {
Accept: 'application/json'
Accept: "application/json"
}
}).then(res => {
return res.status === 404 ? null : res.json()
})
}
const PackageNotFound = 'PackageNotFound'
const PackageNotFound = "PackageNotFound"
// This mutex prevents multiple concurrent requests to
// the registry for the same package info.

View File

@ -1,4 +1,4 @@
const db = require('../../RedisClient')
const db = require("../../RedisClient")
function incrementCounter(counter, key, by) {
return new Promise((resolve, reject) => {

View File

@ -1,9 +1,9 @@
const fs = require('fs')
const path = require('path')
const csso = require('csso')
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
return csso.minify(fs.readFileSync(path.resolve(...args), "utf8")).css
}
module.exports = readCSS

View File

@ -1,4 +1,4 @@
const parsePackageURL = require('../utils/parsePackageURL')
const parsePackageURL = require("../utils/parsePackageURL")
/**
* Adds various properties to the request object to do with the