Remove addLeadingSlash util

This commit is contained in:
Michael Jackson 2019-07-10 21:59:23 -07:00
parent b2d8e28344
commit ab83549744
4 changed files with 35 additions and 48 deletions

View File

@ -1,7 +1,5 @@
import path from 'path';
import addLeadingSlash from '../utils/addLeadingSlash.js';
function getMatchingEntries(entry, entries) {
const dirname = entry.name || '.';
@ -10,9 +8,11 @@ function getMatchingEntries(entry, entries) {
.map(name => entries[name]);
}
const leadingSlashes = /^\/*/;
function getMetadata(entry, entries) {
const metadata = {
path: addLeadingSlash(entry.name),
path: entry.name.replace(leadingSlashes, '/'),
type: entry.type
};

View File

@ -1,4 +1,3 @@
import addLeadingSlash from '../utils/addLeadingSlash.js';
import createPackageURL from '../utils/createPackageURL.js';
import createSearch from '../utils/createSearch.js';
import { getPackageConfig, resolveVersion } from '../utils/npm.js';
@ -15,6 +14,8 @@ function semverRedirect(req, res, newVersion) {
);
}
const leadingSlashes = /^\/*/;
function filenameRedirect(req, res) {
let filename;
if (req.query.module != null) {
@ -75,7 +76,7 @@ function filenameRedirect(req, res) {
createPackageURL(
req.packageName,
req.packageVersion,
addLeadingSlash(filename),
filename.replace(leadingSlashes, '/'),
createSearch(req.query)
)
);

View File

@ -2,12 +2,17 @@ import path from 'path';
import gunzip from 'gunzip-maybe';
import tar from 'tar-stream';
import addLeadingSlash from '../utils/addLeadingSlash.js';
import createPackageURL from '../utils/createPackageURL.js';
import createSearch from '../utils/createSearch.js';
import { getPackage } from '../utils/npm.js';
import getIntegrity from '../utils/getIntegrity.js';
import getContentType from '../utils/getContentType.js';
import bufferStream from '../utils/bufferStream.js';
const leadingSlashes = /^\/*/;
const multipleSlashes = /\/*/;
const trailingSlashes = /\/*$/;
const leadingSegment = /^[^/]+\/?/;
function fileRedirect(req, res, entry) {
// Redirect to the file with the extension so it's more
@ -22,7 +27,7 @@ function fileRedirect(req, res, entry) {
createPackageURL(
req.packageName,
req.packageVersion,
addLeadingSlash(entry.name),
entry.name.replace(leadingSlashes, '/'),
createSearch(req.query)
)
);
@ -41,23 +46,19 @@ function indexRedirect(req, res, entry) {
createPackageURL(
req.packageName,
req.packageVersion,
addLeadingSlash(entry.name),
entry.name.replace(leadingSlashes, '/'),
createSearch(req.query)
)
);
}
function stripLeadingSegment(name) {
return name.replace(/^[^/]+\/?/, '');
}
/**
* Search the given tarball for entries that match the given name.
* Follows node's resolution algorithm.
* https://nodejs.org/api/modules.html#modules_all_together
*/
function searchEntries(stream, entryName, wantsIndex) {
return new Promise((resolve, reject) => {
return new Promise((accept, reject) => {
const jsEntryName = `${entryName}.js`;
const jsonEntryName = `${entryName}.json`;
const entries = {};
@ -72,13 +73,13 @@ function searchEntries(stream, entryName, wantsIndex) {
.pipe(gunzip())
.pipe(tar.extract())
.on('error', reject)
.on('entry', (header, stream, next) => {
.on('entry', async (header, stream, next) => {
const entry = {
// Most packages have header names that look like `package/index.js`
// 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.
name: stripLeadingSegment(header.name),
name: header.name.replace(leadingSegment, ''),
type: header.type
};
@ -124,33 +125,25 @@ function searchEntries(stream, entryName, wantsIndex) {
}
}
const chunks = [];
const content = await bufferStream(stream);
stream
.on('data', chunk => {
chunks.push(chunk);
})
.on('end', () => {
const content = Buffer.concat(chunks);
// Set some extra properties for files that we will
// need to serve them and for ?meta listings.
entry.contentType = getContentType(entry.name);
entry.integrity = getIntegrity(content);
entry.lastModified = header.mtime.toUTCString();
entry.size = content.length;
// Set some extra properties for files that we will
// need to serve them and for ?meta listings.
entry.contentType = getContentType(entry.name);
entry.integrity = getIntegrity(content);
entry.lastModified = header.mtime.toUTCString();
entry.size = content.length;
// Set the content only for the foundEntry and
// discard the buffer for all others.
if (entry === foundEntry) {
entry.content = content;
}
// Set the content only for the foundEntry and
// discard the buffer for all others.
if (entry === foundEntry) {
entry.content = content;
}
next();
});
next();
})
.on('finish', () => {
resolve({
accept({
entries,
// If we didn't find a matching file entry,
// try a directory entry with the same name.
@ -160,22 +153,18 @@ function searchEntries(stream, entryName, wantsIndex) {
});
}
const leadingSlash = /^\//;
const multipleSlash = /\/\/+/;
const trailingSlash = /\/$/;
/**
* Fetch and search the archive to try and find the requested file.
* Redirect to the "index" file if a directory was requested.
*/
export default async function findFile(req, res, next) {
const wantsIndex = trailingSlash.test(req.filename);
const wantsIndex = req.filename.endsWith('/');
// The name of the file/directory we're looking for.
const entryName = req.filename
.replace(multipleSlash, '/')
.replace(trailingSlash, '')
.replace(leadingSlash, '');
.replace(multipleSlashes, '/')
.replace(trailingSlashes, '')
.replace(leadingSlashes, '');
const stream = await getPackage(req.packageName, req.packageVersion);
const { entries, foundEntry } = await searchEntries(

View File

@ -1,3 +0,0 @@
export default function addLeadingSlash(name) {
return name.charAt(0) === '/' ? name : '/' + name;
}