Use single quotes :P

This commit is contained in:
Michael Jackson 2018-12-17 09:38:05 -08:00
parent ada37035cd
commit 19b2e5574b
93 changed files with 792 additions and 791 deletions

View File

@ -1,3 +0,0 @@
{
"singleQuote": false
}

View File

@ -1,22 +1,22 @@
const crypto = require("crypto");
const jwt = require("jsonwebtoken");
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const db = require("./utils/data");
const secretKey = require("./secretKey");
const db = require('./utils/data');
const secretKey = require('./secretKey');
function getCurrentSeconds() {
return Math.floor(Date.now() / 1000);
}
function createTokenId() {
return crypto.randomBytes(16).toString("hex");
return crypto.randomBytes(16).toString('hex');
}
function createToken(scopes = {}) {
return new Promise((resolve, reject) => {
const payload = {
jti: createTokenId(),
iss: "https://unpkg.com",
iss: 'https://unpkg.com',
iat: getCurrentSeconds(),
scopes
};
@ -24,7 +24,7 @@ function createToken(scopes = {}) {
jwt.sign(
payload,
secretKey.private,
{ algorithm: "RS256" },
{ algorithm: 'RS256' },
(error, token) => {
if (error) {
reject(error);
@ -36,11 +36,11 @@ function createToken(scopes = {}) {
});
}
const revokedTokensSet = "revoked-tokens";
const revokedTokensSet = 'revoked-tokens';
function verifyToken(token) {
return new Promise((resolve, reject) => {
const options = { algorithms: ["RS256"] };
const options = { algorithms: ['RS256'] };
jwt.verify(token, secretKey.public, options, (error, payload) => {
if (error) {

View File

@ -1,6 +1,6 @@
const db = require("./utils/data");
const db = require('./utils/data');
const blacklistSet = "blacklisted-packages";
const blacklistSet = 'blacklisted-packages';
function addPackage(packageName) {
return new Promise((resolve, reject) => {

View File

@ -1,24 +1,24 @@
require("isomorphic-fetch");
const invariant = require("invariant");
const gunzip = require("gunzip-maybe");
const ndjson = require("ndjson");
require('isomorphic-fetch');
const invariant = require('invariant');
const gunzip = require('gunzip-maybe');
const ndjson = require('ndjson');
const cloudflareURL = "https://api.cloudflare.com/client/v4";
const cloudflareURL = 'https://api.cloudflare.com/client/v4';
const cloudflareEmail = process.env.CLOUDFLARE_EMAIL;
const cloudflareKey = process.env.CLOUDFLARE_KEY;
invariant(
cloudflareEmail,
"Missing the $CLOUDFLARE_EMAIL environment variable"
'Missing the $CLOUDFLARE_EMAIL environment variable'
);
invariant(cloudflareKey, "Missing the $CLOUDFLARE_KEY environment variable");
invariant(cloudflareKey, 'Missing the $CLOUDFLARE_KEY environment variable');
function get(path, headers) {
return fetch(`${cloudflareURL}${path}`, {
headers: Object.assign({}, headers, {
"X-Auth-Email": cloudflareEmail,
"X-Auth-Key": cloudflareKey
'X-Auth-Email': cloudflareEmail,
'X-Auth-Key': cloudflareKey
})
});
}
@ -32,7 +32,7 @@ function getJSON(path, headers) {
if (!data.success) {
console.error(`CloudflareAPI.getJSON failed at ${path}`);
console.error(data);
throw new Error("Failed to getJSON from Cloudflare");
throw new Error('Failed to getJSON from Cloudflare');
}
return data.result;
@ -51,9 +51,9 @@ function reduceResults(target, values) {
Object.keys(values).forEach(key => {
const value = values[key];
if (typeof value === "object" && value) {
if (typeof value === 'object' && value) {
target[key] = reduceResults(target[key] || {}, value);
} else if (typeof value === "number") {
} else if (typeof value === 'number') {
target[key] = (target[key] || 0) + values[key];
}
});
@ -75,7 +75,7 @@ function getZoneAnalyticsDashboard(zones, since, until) {
function getJSONStream(path, headers) {
const gzipHeaders = Object.assign({}, headers, {
"Accept-Encoding": "gzip"
'Accept-Encoding': 'gzip'
});
return get(path, gzipHeaders)
@ -84,7 +84,7 @@ function getJSONStream(path, headers) {
}
function getLogs(zoneId, startTime, endTime, fieldsArray) {
const fields = fieldsArray.join(",");
const fields = fieldsArray.join(',');
// console.log(
// `https://api.cloudflare.com/client/v4/zones/${zoneId}/logs/received?start=${startTime}&end=${endTime}&fields=${fields}`

View File

@ -1,7 +1,7 @@
const db = require("./utils/data");
const db = require('./utils/data');
const CloudflareAPI = require("./CloudflareAPI");
const BlacklistAPI = require("./BlacklistAPI");
const CloudflareAPI = require('./CloudflareAPI');
const BlacklistAPI = require('./BlacklistAPI');
function prunePackages(packagesMap) {
return Promise.all(
@ -39,7 +39,7 @@ function createScoresMap(array) {
function getScoresMap(key, n = 100) {
return new Promise((resolve, reject) => {
db.zrevrange(key, 0, n, "withscores", (error, value) => {
db.zrevrange(key, 0, n, 'withscores', (error, value) => {
if (error) {
reject(error);
} else {
@ -141,7 +141,7 @@ function extractPublicInfo(data) {
};
}
const DomainNames = ["unpkg.com", "npmcdn.com"];
const DomainNames = ['unpkg.com', 'npmcdn.com'];
function fetchStats(since, until) {
return CloudflareAPI.getZones(DomainNames).then(zones => {

View File

@ -1,11 +1,11 @@
const AuthAPI = require("../AuthAPI");
const AuthAPI = require('../AuthAPI');
describe("Auth API", () => {
describe('Auth API', () => {
beforeEach(done => {
AuthAPI.removeAllRevokedTokens().then(() => done(), done);
});
it("creates tokens with the right scopes", done => {
it('creates tokens with the right scopes', done => {
const scopes = {
blacklist: {
add: true,
@ -24,7 +24,7 @@ describe("Auth API", () => {
});
});
it("refuses to verify revoked tokens", done => {
it('refuses to verify revoked tokens', done => {
const scopes = {};
AuthAPI.createToken(scopes).then(token => {

View File

@ -1,12 +1,12 @@
const BlacklistAPI = require("../BlacklistAPI");
const BlacklistAPI = require('../BlacklistAPI');
describe("Blacklist API", () => {
describe('Blacklist API', () => {
beforeEach(done => {
BlacklistAPI.removeAllPackages().then(() => done(), done);
});
it("adds and removes packages to/from the blacklist", done => {
const packageName = "bad-package";
it('adds and removes packages to/from the blacklist', done => {
const packageName = 'bad-package';
BlacklistAPI.addPackage(packageName).then(() => {
BlacklistAPI.getPackages().then(packageNames => {

View File

@ -1,46 +1,46 @@
const request = require("supertest");
const request = require('supertest');
const createServer = require("../createServer");
const withRevokedToken = require("./utils/withRevokedToken");
const withToken = require("./utils/withToken");
const createServer = require('../createServer');
const withRevokedToken = require('./utils/withRevokedToken');
const withToken = require('./utils/withToken');
describe("The /_auth endpoint", () => {
describe('The /_auth endpoint', () => {
let server;
beforeEach(() => {
server = createServer();
});
describe("POST /_auth", () => {
it("creates a new auth token", done => {
describe('POST /_auth', () => {
it('creates a new auth token', done => {
request(server)
.post("/_auth")
.post('/_auth')
.end((err, res) => {
expect(res.body).toHaveProperty("token");
expect(res.body).toHaveProperty('token');
done();
});
});
});
describe("GET /_auth", () => {
describe("with no auth", () => {
it("echoes back null", done => {
describe('GET /_auth', () => {
describe('with no auth', () => {
it('echoes back null', done => {
request(server)
.get("/_auth")
.get('/_auth')
.end((err, res) => {
expect(res.body).toHaveProperty("auth");
expect(res.body).toHaveProperty('auth');
expect(res.body.auth).toBe(null);
done();
});
});
});
describe("with a revoked auth token", () => {
it("echoes back null", done => {
describe('with a revoked auth token', () => {
it('echoes back null', done => {
withRevokedToken({ some: { scope: true } }, token => {
request(server)
.get("/_auth?token=" + token)
.get('/_auth?token=' + token)
.end((err, res) => {
expect(res.body).toHaveProperty("auth");
expect(res.body).toHaveProperty('auth');
expect(res.body.auth).toBe(null);
done();
});
@ -48,14 +48,14 @@ describe("The /_auth endpoint", () => {
});
});
describe("with a valid auth token", () => {
it("echoes back the auth payload", done => {
describe('with a valid auth token', () => {
it('echoes back the auth payload', done => {
withToken({ some: { scope: true } }, token => {
request(server)
.get("/_auth?token=" + token)
.get('/_auth?token=' + token)
.end((err, res) => {
expect(res.body).toHaveProperty("auth");
expect(typeof res.body.auth).toBe("object");
expect(res.body).toHaveProperty('auth');
expect(typeof res.body.auth).toBe('object');
done();
});
});

View File

@ -1,22 +1,22 @@
const request = require("supertest");
const request = require('supertest');
const createServer = require("../createServer");
const clearBlacklist = require("./utils/clearBlacklist");
const withToken = require("./utils/withToken");
const createServer = require('../createServer');
const clearBlacklist = require('./utils/clearBlacklist');
const withToken = require('./utils/withToken');
describe("The /_blacklist endpoint", () => {
describe('The /_blacklist endpoint', () => {
let server;
beforeEach(() => {
server = createServer();
});
describe("POST /_blacklist", () => {
describe('POST /_blacklist', () => {
afterEach(clearBlacklist);
describe("with no auth", () => {
it("is forbidden", done => {
describe('with no auth', () => {
it('is forbidden', done => {
request(server)
.post("/_blacklist")
.post('/_blacklist')
.end((err, res) => {
expect(res.statusCode).toBe(403);
done();
@ -25,11 +25,11 @@ describe("The /_blacklist endpoint", () => {
});
describe('with the "blacklist.add" scope', () => {
it("can add to the blacklist", done => {
it('can add to the blacklist', done => {
withToken({ blacklist: { add: true } }, token => {
request(server)
.post("/_blacklist")
.send({ token, packageName: "bad-package" })
.post('/_blacklist')
.send({ token, packageName: 'bad-package' })
.end((err, res) => {
expect(res.statusCode).toBe(200);
expect(res.body.ok).toBe(true);
@ -40,11 +40,11 @@ describe("The /_blacklist endpoint", () => {
});
});
describe("GET /_blacklist", () => {
describe("with no auth", () => {
it("is forbidden", done => {
describe('GET /_blacklist', () => {
describe('with no auth', () => {
it('is forbidden', done => {
request(server)
.get("/_blacklist")
.get('/_blacklist')
.end((err, res) => {
expect(res.statusCode).toBe(403);
done();
@ -53,10 +53,10 @@ describe("The /_blacklist endpoint", () => {
});
describe('with the "blacklist.read" scope', () => {
it("can read the blacklist", done => {
it('can read the blacklist', done => {
withToken({ blacklist: { read: true } }, token => {
request(server)
.get("/_blacklist?token=" + token)
.get('/_blacklist?token=' + token)
.end((err, res) => {
expect(res.statusCode).toBe(200);
done();
@ -66,11 +66,11 @@ describe("The /_blacklist endpoint", () => {
});
});
describe("DELETE /_blacklist/:packageName", () => {
describe("with no auth", () => {
it("is forbidden", done => {
describe('DELETE /_blacklist/:packageName', () => {
describe('with no auth', () => {
it('is forbidden', done => {
request(server)
.delete("/_blacklist/bad-package")
.delete('/_blacklist/bad-package')
.end((err, res) => {
expect(res.statusCode).toBe(403);
done();
@ -79,10 +79,10 @@ describe("The /_blacklist endpoint", () => {
});
describe('with the "blacklist.remove" scope', () => {
it("can remove a package from the blacklist", done => {
it('can remove a package from the blacklist', done => {
withToken({ blacklist: { remove: true } }, token => {
request(server)
.delete("/_blacklist/bad-package")
.delete('/_blacklist/bad-package')
.send({ token })
.end((err, res) => {
expect(res.statusCode).toBe(200);
@ -92,10 +92,10 @@ describe("The /_blacklist endpoint", () => {
});
});
it("can remove a scoped package from the blacklist", done => {
it('can remove a scoped package from the blacklist', done => {
withToken({ blacklist: { remove: true } }, token => {
request(server)
.delete("/_blacklist/@scope/bad-package")
.delete('/_blacklist/@scope/bad-package')
.send({ token })
.end((err, res) => {
expect(res.statusCode).toBe(200);

View File

@ -1,17 +1,17 @@
const request = require("supertest");
const request = require('supertest');
const createServer = require("../createServer");
const createServer = require('../createServer');
describe("The /_publicKey endpoint", () => {
describe('The /_publicKey endpoint', () => {
let server;
beforeEach(() => {
server = createServer();
});
describe("GET /_publicKey", () => {
it("echoes the public key", done => {
describe('GET /_publicKey', () => {
it('echoes the public key', done => {
request(server)
.get("/_publicKey")
.get('/_publicKey')
.end((err, res) => {
expect(res.text).toMatch(/PUBLIC KEY/);
done();

View File

@ -1,47 +1,47 @@
const request = require("supertest");
const request = require('supertest');
const createServer = require("../createServer");
const withAuthHeader = require("./utils/withAuthHeader");
const withRevokedToken = require("./utils/withRevokedToken");
const withToken = require("./utils/withToken");
const createServer = require('../createServer');
const withAuthHeader = require('./utils/withAuthHeader');
const withRevokedToken = require('./utils/withRevokedToken');
const withToken = require('./utils/withToken');
describe("The /api/auth endpoint", () => {
describe('The /api/auth endpoint', () => {
let server;
beforeEach(() => {
server = createServer();
});
describe("POST /api/auth", () => {
it("creates a new auth token", done => {
describe('POST /api/auth', () => {
it('creates a new auth token', done => {
request(server)
.post("/api/auth")
.post('/api/auth')
.end((err, res) => {
expect(res.body).toHaveProperty("token");
expect(res.body).toHaveProperty('token');
done();
});
});
});
describe("GET /api/auth", () => {
describe("with no auth", () => {
it("echoes back null", done => {
describe('GET /api/auth', () => {
describe('with no auth', () => {
it('echoes back null', done => {
request(server)
.get("/api/auth")
.get('/api/auth')
.end((err, res) => {
expect(res.body).toHaveProperty("auth");
expect(res.body).toHaveProperty('auth');
expect(res.body.auth).toBe(null);
done();
});
});
});
describe("with a revoked auth token", () => {
it("echoes back null", done => {
describe('with a revoked auth token', () => {
it('echoes back null', done => {
withRevokedToken({ some: { scope: true } }, token => {
request(server)
.get("/api/auth?token=" + token)
.get('/api/auth?token=' + token)
.end((err, res) => {
expect(res.body).toHaveProperty("auth");
expect(res.body).toHaveProperty('auth');
expect(res.body.auth).toBe(null);
done();
});
@ -49,16 +49,16 @@ describe("The /api/auth endpoint", () => {
});
});
describe("with a valid auth token", () => {
describe("in the query string", () => {
it("echoes back the auth payload", done => {
describe('with a valid auth token', () => {
describe('in the query string', () => {
it('echoes back the auth payload', done => {
const scopes = { some: { scope: true } };
withToken(scopes, token => {
request(server)
.get("/api/auth?token=" + token)
.get('/api/auth?token=' + token)
.end((err, res) => {
expect(res.body).toHaveProperty("auth");
expect(res.body).toHaveProperty('auth');
expect(res.body.auth).toBeDefined();
expect(res.body.auth.scopes).toMatchObject(scopes);
done();
@ -67,16 +67,16 @@ describe("The /api/auth endpoint", () => {
});
});
describe("in the Authorization header", () => {
it("echoes back the auth payload", done => {
describe('in the Authorization header', () => {
it('echoes back the auth payload', done => {
const scopes = { some: { scope: true } };
withAuthHeader(scopes, header => {
request(server)
.get("/api/auth")
.get('/api/auth')
.set({ Authorization: header })
.end((err, res) => {
expect(res.body).toHaveProperty("auth");
expect(res.body).toHaveProperty('auth');
expect(res.body.auth).toBeDefined();
expect(res.body.auth.scopes).toMatchObject(scopes);
done();

View File

@ -1,22 +1,22 @@
const request = require("supertest");
const request = require('supertest');
const createServer = require("../createServer");
const clearBlacklist = require("./utils/clearBlacklist");
const withToken = require("./utils/withToken");
const createServer = require('../createServer');
const clearBlacklist = require('./utils/clearBlacklist');
const withToken = require('./utils/withToken');
describe("The /api/blacklist endpoint", () => {
describe('The /api/blacklist endpoint', () => {
let server;
beforeEach(() => {
server = createServer();
});
describe("POST /api/blacklist", () => {
describe('POST /api/blacklist', () => {
afterEach(clearBlacklist);
describe("with no auth", () => {
it("is forbidden", done => {
describe('with no auth', () => {
it('is forbidden', done => {
request(server)
.post("/api/blacklist")
.post('/api/blacklist')
.end((err, res) => {
expect(res.statusCode).toBe(403);
done();
@ -25,11 +25,11 @@ describe("The /api/blacklist endpoint", () => {
});
describe('with the "blacklist.add" scope', () => {
it("can add to the blacklist", done => {
it('can add to the blacklist', done => {
withToken({ blacklist: { add: true } }, token => {
request(server)
.post("/api/blacklist")
.send({ token, packageName: "bad-package" })
.post('/api/blacklist')
.send({ token, packageName: 'bad-package' })
.end((err, res) => {
expect(res.statusCode).toBe(200);
expect(res.body.ok).toBe(true);
@ -40,11 +40,11 @@ describe("The /api/blacklist endpoint", () => {
});
});
describe("GET /api/blacklist", () => {
describe("with no auth", () => {
it("is forbidden", done => {
describe('GET /api/blacklist', () => {
describe('with no auth', () => {
it('is forbidden', done => {
request(server)
.get("/api/blacklist")
.get('/api/blacklist')
.end((err, res) => {
expect(res.statusCode).toBe(403);
done();
@ -53,10 +53,10 @@ describe("The /api/blacklist endpoint", () => {
});
describe('with the "blacklist.read" scope', () => {
it("can read the blacklist", done => {
it('can read the blacklist', done => {
withToken({ blacklist: { read: true } }, token => {
request(server)
.get("/api/blacklist?token=" + token)
.get('/api/blacklist?token=' + token)
.end((err, res) => {
expect(res.statusCode).toBe(200);
done();
@ -66,11 +66,11 @@ describe("The /api/blacklist endpoint", () => {
});
});
describe("DELETE /api/blacklist", () => {
describe("with no auth", () => {
it("is forbidden", done => {
describe('DELETE /api/blacklist', () => {
describe('with no auth', () => {
it('is forbidden', done => {
request(server)
.delete("/api/blacklist")
.delete('/api/blacklist')
.end((err, res) => {
expect(res.statusCode).toBe(403);
done();
@ -79,11 +79,11 @@ describe("The /api/blacklist endpoint", () => {
});
describe('with the "blacklist.remove" scope', () => {
it("can remove a package from the blacklist", done => {
it('can remove a package from the blacklist', done => {
withToken({ blacklist: { remove: true } }, token => {
request(server)
.delete("/api/blacklist")
.send({ token, packageName: "bad-package" })
.delete('/api/blacklist')
.send({ token, packageName: 'bad-package' })
.end((err, res) => {
expect(res.statusCode).toBe(200);
expect(res.body.ok).toBe(true);
@ -92,11 +92,11 @@ describe("The /api/blacklist endpoint", () => {
});
});
it("can remove a scoped package from the blacklist", done => {
it('can remove a scoped package from the blacklist', done => {
withToken({ blacklist: { remove: true } }, token => {
request(server)
.delete("/api/blacklist")
.send({ token, packageName: "@scope/bad-package" })
.delete('/api/blacklist')
.send({ token, packageName: '@scope/bad-package' })
.end((err, res) => {
expect(res.statusCode).toBe(200);
expect(res.body.ok).toBe(true);

View File

@ -1,17 +1,17 @@
const request = require("supertest");
const request = require('supertest');
const createServer = require("../createServer");
const createServer = require('../createServer');
describe("The /api/publicKey endpoint", () => {
describe('The /api/publicKey endpoint', () => {
let server;
beforeEach(() => {
server = createServer();
});
describe("GET /api/publicKey", () => {
it("echoes the public key", done => {
describe('GET /api/publicKey', () => {
it('echoes the public key', done => {
request(server)
.get("/api/publicKey")
.get('/api/publicKey')
.end((err, res) => {
expect(res.text).toMatch(/PUBLIC KEY/);
done();

View File

@ -1,62 +1,62 @@
const request = require("supertest");
const request = require('supertest');
const createServer = require("../createServer");
const createServer = require('../createServer');
const clearBlacklist = require("./utils/clearBlacklist");
const withBlacklist = require("./utils/withBlacklist");
const clearBlacklist = require('./utils/clearBlacklist');
const withBlacklist = require('./utils/withBlacklist');
describe("The server", () => {
describe('The server', () => {
let server;
beforeEach(() => {
server = createServer();
});
it("redirects /_meta to ?meta", done => {
it('redirects /_meta to ?meta', done => {
request(server)
.get("/_meta/react")
.get('/_meta/react')
.end((err, res) => {
expect(res.statusCode).toBe(301);
expect(res.headers.location).toBe("/react?meta");
expect(res.headers.location).toBe('/react?meta');
done();
});
});
it("redirects ?json to ?meta", done => {
it('redirects ?json to ?meta', done => {
request(server)
.get("/react?json")
.get('/react?json')
.end((err, res) => {
expect(res.statusCode).toBe(301);
expect(res.headers.location).toBe("/react?meta");
expect(res.headers.location).toBe('/react?meta');
done();
});
});
it("redirects invalid query params", done => {
it('redirects invalid query params', done => {
request(server)
.get("/react?main=index&invalid")
.get('/react?main=index&invalid')
.end((err, res) => {
expect(res.statusCode).toBe(302);
expect(res.headers.location).toBe("/react?main=index");
expect(res.headers.location).toBe('/react?main=index');
done();
});
});
it("rejects invalid package names", done => {
it('rejects invalid package names', done => {
request(server)
.get("/_invalid/index.js")
.get('/_invalid/index.js')
.end((err, res) => {
expect(res.statusCode).toBe(403);
done();
});
});
describe("blacklisted packages", () => {
describe('blacklisted packages', () => {
afterEach(clearBlacklist);
it("does not serve blacklisted packages", done => {
withBlacklist(["bad-package"], () => {
it('does not serve blacklisted packages', done => {
withBlacklist(['bad-package'], () => {
request(server)
.get("/bad-package/index.js")
.get('/bad-package/index.js')
.end((err, res) => {
expect(res.statusCode).toBe(403);
done();

View File

@ -1,3 +1,3 @@
const closeDatabase = require("./utils/closeDatabase");
const closeDatabase = require('./utils/closeDatabase');
afterAll(closeDatabase);

View File

@ -1,4 +1,4 @@
const BlacklistAPI = require("../../BlacklistAPI");
const BlacklistAPI = require('../../BlacklistAPI');
function clearBlacklist(done) {
BlacklistAPI.removeAllPackages().then(done, done);

View File

@ -1,7 +1,7 @@
const withToken = require("./withToken");
const withToken = require('./withToken');
function encodeBase64(token) {
return Buffer.from(token).toString("base64");
return Buffer.from(token).toString('base64');
}
function withAuthHeader(scopes, done) {

View File

@ -1,4 +1,4 @@
const BlacklistAPI = require("../../BlacklistAPI");
const BlacklistAPI = require('../../BlacklistAPI');
function withBlacklist(blacklist, done) {
Promise.all(blacklist.map(BlacklistAPI.addPackage)).then(done);

View File

@ -1,5 +1,5 @@
const withToken = require("./withToken");
const AuthAPI = require("../../AuthAPI");
const withToken = require('./withToken');
const AuthAPI = require('../../AuthAPI');
function withRevokedToken(scopes, done) {
withToken(scopes, token => {

View File

@ -1,4 +1,4 @@
const AuthAPI = require("../../AuthAPI");
const AuthAPI = require('../../AuthAPI');
function withToken(scopes, done) {
AuthAPI.createToken(scopes).then(done);

View File

@ -1,6 +1,6 @@
const validateNpmPackageName = require("validate-npm-package-name");
const validateNpmPackageName = require('validate-npm-package-name');
const BlacklistAPI = require("../BlacklistAPI");
const BlacklistAPI = require('../BlacklistAPI');
function addToBlacklist(req, res) {
const packageName = req.body.packageName;
@ -15,7 +15,7 @@ function addToBlacklist(req, res) {
// Disallow invalid package names.
if (nameErrors) {
const reason = nameErrors.join(", ");
const reason = nameErrors.join(', ');
return res.status(403).send({
error: `Invalid package name "${packageName}" (${reason})`
});
@ -33,7 +33,7 @@ function addToBlacklist(req, res) {
res.send({
ok: true,
message: `Package "${packageName}" was ${
added ? "added to" : "already in"
added ? 'added to' : 'already in'
} the blacklist`
});
},

View File

@ -1,4 +1,4 @@
const AuthAPI = require("../AuthAPI");
const AuthAPI = require('../AuthAPI');
const defaultScopes = {
blacklist: {
@ -15,7 +15,7 @@ function createAuth(req, res) {
console.error(error);
res.status(500).send({
error: "Unable to generate auth token"
error: 'Unable to generate auth token'
});
}
);

View File

@ -1,6 +1,6 @@
const validateNpmPackageName = require("validate-npm-package-name");
const validateNpmPackageName = require('validate-npm-package-name');
const BlacklistAPI = require("../BlacklistAPI");
const BlacklistAPI = require('../BlacklistAPI');
function removeFromBlacklist(req, res) {
// TODO: Remove req.packageName when DELETE
@ -17,7 +17,7 @@ function removeFromBlacklist(req, res) {
// Disallow invalid package names.
if (nameErrors) {
const reason = nameErrors.join(", ");
const reason = nameErrors.join(', ');
return res.status(403).send({
error: `Invalid package name "${packageName}" (${reason})`
});
@ -35,7 +35,7 @@ function removeFromBlacklist(req, res) {
res.send({
ok: true,
message: `Package "${packageName}" was ${
removed ? "removed from" : "not in"
removed ? 'removed from' : 'not in'
} the blacklist`
});
},

View File

@ -1,21 +1,21 @@
const React = require("react");
const ReactDOMServer = require("react-dom/server");
const semver = require("semver");
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const semver = require('semver');
const MainPage = require("../client/MainPage");
const AutoIndexApp = require("../client/autoIndex/App");
const createHTML = require("../client/utils/createHTML");
const renderPage = require("../utils/renderPage");
const MainPage = require('../client/MainPage');
const AutoIndexApp = require('../client/autoIndex/App');
const createHTML = require('../client/utils/createHTML');
const renderPage = require('../utils/renderPage');
const globalScripts =
process.env.NODE_ENV === "production"
process.env.NODE_ENV === 'production'
? [
"/react@16.4.1/umd/react.production.min.js",
"/react-dom@16.4.1/umd/react-dom.production.min.js"
'/react@16.4.1/umd/react.production.min.js',
'/react-dom@16.4.1/umd/react-dom.production.min.js'
]
: [
"/react@16.4.1/umd/react.development.js",
"/react-dom@16.4.1/umd/react-dom.development.js"
'/react@16.4.1/umd/react.development.js',
'/react-dom@16.4.1/umd/react-dom.development.js'
];
function byVersion(a, b) {
@ -23,8 +23,8 @@ function byVersion(a, b) {
}
function serveAutoIndexPage(req, res) {
const scripts = globalScripts.concat(req.assets.getScripts("autoIndex"));
const styles = req.assets.getStyles("autoIndex");
const scripts = globalScripts.concat(req.assets.getScripts('autoIndex'));
const styles = req.assets.getStyles('autoIndex');
const props = {
packageName: req.packageName,
@ -49,8 +49,8 @@ function serveAutoIndexPage(req, res) {
res
.set({
"Cache-Control": "public,max-age=60", // 1 minute
"Cache-Tag": "auto-index"
'Cache-Control': 'public,max-age=60', // 1 minute
'Cache-Tag': 'auto-index'
})
.send(html);
}

View File

@ -1,8 +1,8 @@
const serveAutoIndexPage = require("./serveAutoIndexPage");
const serveHTMLModule = require("./serveHTMLModule");
const serveJavaScriptModule = require("./serveJavaScriptModule");
const serveStaticFile = require("./serveStaticFile");
const serveMetadata = require("./serveMetadata");
const serveAutoIndexPage = require('./serveAutoIndexPage');
const serveHTMLModule = require('./serveHTMLModule');
const serveJavaScriptModule = require('./serveJavaScriptModule');
const serveStaticFile = require('./serveStaticFile');
const serveMetadata = require('./serveMetadata');
/**
* Send the file, JSON metadata, or HTML directory listing.
@ -12,23 +12,23 @@ function serveFile(req, res) {
return serveMetadata(req, res);
}
if (req.entry.type === "directory") {
if (req.entry.type === 'directory') {
return serveAutoIndexPage(req, res);
}
if (req.query.module != null) {
if (req.entry.contentType === "application/javascript") {
if (req.entry.contentType === 'application/javascript') {
return serveJavaScriptModule(req, res);
}
if (req.entry.contentType === "text/html") {
if (req.entry.contentType === 'text/html') {
return serveHTMLModule(req, res);
}
return res
.status(403)
.type("text")
.send("?module mode is available only for JavaScript and HTML files");
.type('text')
.send('?module mode is available only for JavaScript and HTML files');
}
serveStaticFile(req, res);

View File

@ -1,14 +1,14 @@
const etag = require("etag");
const cheerio = require("cheerio");
const etag = require('etag');
const cheerio = require('cheerio');
const getContentTypeHeader = require("../utils/getContentTypeHeader");
const rewriteBareModuleIdentifiers = require("../utils/rewriteBareModuleIdentifiers");
const getContentTypeHeader = require('../utils/getContentTypeHeader');
const rewriteBareModuleIdentifiers = require('../utils/rewriteBareModuleIdentifiers');
function serveHTMLModule(req, res) {
try {
const $ = cheerio.load(req.entry.content.toString("utf8"));
const $ = cheerio.load(req.entry.content.toString('utf8'));
$("script[type=module]").each((index, element) => {
$('script[type=module]').each((index, element) => {
$(element).html(
rewriteBareModuleIdentifiers($(element).html(), req.packageConfig)
);
@ -18,11 +18,11 @@ function serveHTMLModule(req, res) {
res
.set({
"Content-Length": Buffer.byteLength(code),
"Content-Type": getContentTypeHeader(req.entry.contentType),
"Cache-Control": "public, max-age=31536000, immutable", // 1 year
'Content-Length': Buffer.byteLength(code),
'Content-Type': getContentTypeHeader(req.entry.contentType),
'Cache-Control': 'public, max-age=31536000, immutable', // 1 year
ETag: etag(code),
"Cache-Tag": "file, html-file, html-module"
'Cache-Tag': 'file, html-file, html-module'
})
.send(code);
} catch (error) {
@ -38,7 +38,7 @@ function serveHTMLModule(req, res) {
res
.status(500)
.type("text")
.type('text')
.send(
`Cannot generate module for ${req.packageSpec}${
req.filename

View File

@ -1,22 +1,22 @@
const etag = require("etag");
const etag = require('etag');
const getContentTypeHeader = require("../utils/getContentTypeHeader");
const rewriteBareModuleIdentifiers = require("../utils/rewriteBareModuleIdentifiers");
const getContentTypeHeader = require('../utils/getContentTypeHeader');
const rewriteBareModuleIdentifiers = require('../utils/rewriteBareModuleIdentifiers');
function serveJavaScriptModule(req, res) {
try {
const code = rewriteBareModuleIdentifiers(
req.entry.content.toString("utf8"),
req.entry.content.toString('utf8'),
req.packageConfig
);
res
.set({
"Content-Length": Buffer.byteLength(code),
"Content-Type": getContentTypeHeader(req.entry.contentType),
"Cache-Control": "public, max-age=31536000, immutable", // 1 year
'Content-Length': Buffer.byteLength(code),
'Content-Type': getContentTypeHeader(req.entry.contentType),
'Cache-Control': 'public, max-age=31536000, immutable', // 1 year
ETag: etag(code),
"Cache-Tag": "file,js-file,js-module"
'Cache-Tag': 'file,js-file,js-module'
})
.send(code);
} catch (error) {
@ -32,7 +32,7 @@ function serveJavaScriptModule(req, res) {
res
.status(500)
.type("text")
.type('text')
.send(
`Cannot generate module for ${req.packageSpec}${
req.filename

View File

@ -1,9 +1,9 @@
const path = require("path");
const path = require('path');
const addLeadingSlash = require("../utils/addLeadingSlash");
const addLeadingSlash = require('../utils/addLeadingSlash');
function getMatchingEntries(entry, entries) {
const dirname = entry.name || ".";
const dirname = entry.name || '.';
return Object.keys(entries)
.filter(name => entry.name !== name && path.dirname(name) === dirname)
@ -16,12 +16,12 @@ function getMetadata(entry, entries) {
type: entry.type
};
if (entry.type === "file") {
if (entry.type === 'file') {
metadata.contentType = entry.contentType;
metadata.integrity = entry.integrity;
metadata.lastModified = entry.lastModified;
metadata.size = entry.size;
} else if (entry.type === "directory") {
} else if (entry.type === 'directory') {
metadata.files = getMatchingEntries(entry, entries).map(e =>
getMetadata(e, entries)
);
@ -35,8 +35,8 @@ function serveMetadata(req, res) {
res
.set({
"Cache-Control": "public, max-age=31536000, immutable", // 1 year
"Cache-Tag": "meta"
'Cache-Control': 'public, max-age=31536000, immutable', // 1 year
'Cache-Tag': 'meta'
})
.send(metadata);
}

View File

@ -1,22 +1,22 @@
const MainPage = require("../client/MainPage");
const renderPage = require("../utils/renderPage");
const MainPage = require('../client/MainPage');
const renderPage = require('../utils/renderPage');
const globalScripts =
process.env.NODE_ENV === "production"
process.env.NODE_ENV === 'production'
? [
"/react@16.4.1/umd/react.production.min.js",
"/react-dom@16.4.1/umd/react-dom.production.min.js",
"/react-router-dom@4.3.1/umd/react-router-dom.min.js"
'/react@16.4.1/umd/react.production.min.js',
'/react-dom@16.4.1/umd/react-dom.production.min.js',
'/react-router-dom@4.3.1/umd/react-router-dom.min.js'
]
: [
"/react@16.4.1/umd/react.development.js",
"/react-dom@16.4.1/umd/react-dom.development.js",
"/react-router-dom@4.3.1/umd/react-router-dom.js"
'/react@16.4.1/umd/react.development.js',
'/react-dom@16.4.1/umd/react-dom.development.js',
'/react-router-dom@4.3.1/umd/react-router-dom.js'
];
function serveRootPage(req, res) {
const scripts = globalScripts.concat(req.assets.getScripts("main"));
const styles = req.assets.getStyles("main");
const scripts = globalScripts.concat(req.assets.getScripts('main'));
const styles = req.assets.getStyles('main');
const html = renderPage(MainPage, {
scripts: scripts,

View File

@ -1,10 +1,10 @@
const path = require("path");
const etag = require("etag");
const path = require('path');
const etag = require('etag');
const getContentTypeHeader = require("../utils/getContentTypeHeader");
const getContentTypeHeader = require('../utils/getContentTypeHeader');
function serveStaticFile(req, res) {
const tags = ["file"];
const tags = ['file'];
const ext = path.extname(req.entry.name).substr(1);
if (ext) {
@ -13,12 +13,12 @@ function serveStaticFile(req, res) {
res
.set({
"Content-Length": req.entry.size,
"Content-Type": getContentTypeHeader(req.entry.contentType),
"Cache-Control": "public, max-age=31536000, immutable", // 1 year
"Last-Modified": req.entry.lastModified,
'Content-Length': req.entry.size,
'Content-Type': getContentTypeHeader(req.entry.contentType),
'Cache-Control': 'public, max-age=31536000, immutable', // 1 year
'Last-Modified': req.entry.lastModified,
ETag: etag(req.entry.content),
"Cache-Tag": tags.join(",")
'Cache-Tag': tags.join(',')
})
.send(req.entry.content);
}

View File

@ -1,4 +1,4 @@
const BlacklistAPI = require("../BlacklistAPI");
const BlacklistAPI = require('../BlacklistAPI');
function showBlacklist(req, res) {
BlacklistAPI.getPackages().then(
@ -8,7 +8,7 @@ function showBlacklist(req, res) {
error => {
console.error(error);
res.status(500).send({
error: "Unable to fetch blacklist"
error: 'Unable to fetch blacklist'
});
}
);

View File

@ -1,4 +1,4 @@
const secretKey = require("../secretKey");
const secretKey = require('../secretKey');
function showPublicKey(req, res) {
res.send({ publicKey: secretKey.public });

View File

@ -1,21 +1,21 @@
const subDays = require("date-fns/sub_days");
const startOfDay = require("date-fns/start_of_day");
const startOfSecond = require("date-fns/start_of_second");
const subDays = require('date-fns/sub_days');
const startOfDay = require('date-fns/start_of_day');
const startOfSecond = require('date-fns/start_of_second');
const StatsAPI = require("../StatsAPI");
const StatsAPI = require('../StatsAPI');
function showStats(req, res) {
let since, until;
switch (req.query.period) {
case "last-day":
case 'last-day':
until = startOfDay(new Date());
since = subDays(until, 1);
break;
case "last-week":
case 'last-week':
until = startOfDay(new Date());
since = subDays(until, 7);
break;
case "last-month":
case 'last-month':
until = startOfDay(new Date());
since = subDays(until, 30);
break;
@ -27,35 +27,35 @@ function showStats(req, res) {
}
if (isNaN(since.getTime())) {
return res.status(403).send({ error: "?since is not a valid date" });
return res.status(403).send({ error: '?since is not a valid date' });
}
if (isNaN(until.getTime())) {
return res.status(403).send({ error: "?until is not a valid date" });
return res.status(403).send({ error: '?until is not a valid date' });
}
if (until <= since) {
return res
.status(403)
.send({ error: "?until date must come after ?since date" });
.send({ error: '?until date must come after ?since date' });
}
if (until >= new Date()) {
return res.status(403).send({ error: "?until must be a date in the past" });
return res.status(403).send({ error: '?until must be a date in the past' });
}
StatsAPI.getStats(since, until).then(
stats => {
res
.set({
"Cache-Control": "public, max-age=60",
"Cache-Tag": "stats"
'Cache-Control': 'public, max-age=60',
'Cache-Tag': 'stats'
})
.send(stats);
},
error => {
console.error(error);
res.status(500).send({ error: "Unable to fetch stats" });
res.status(500).send({ error: 'Unable to fetch stats' });
}
);
}

View File

@ -1,8 +1,8 @@
const React = require("react");
const PropTypes = require("prop-types");
const React = require('react');
const PropTypes = require('prop-types');
const createHTML = require("./utils/createHTML");
const x = require("./utils/execScript");
const createHTML = require('./utils/createHTML');
const x = require('./utils/execScript');
function MainPage({ title, description, scripts, styles, data, content }) {
return (
@ -17,19 +17,23 @@ function MainPage({ title, description, scripts, styles, data, content }) {
/>
<meta name="timestamp" content={new Date().toISOString()} />
<link rel="shortcut icon" href="/favicon.ico" />
{styles.map(s => <link key={s} rel="stylesheet" href={s} />)}
{styles.map(s => (
<link key={s} rel="stylesheet" href={s} />
))}
{x(
"window.Promise || document.write('\\x3Cscript src=\"/_polyfills/es6-promise.min.js\">\\x3C/script>\\x3Cscript>ES6Promise.polyfill()\\x3C/script>')"
'window.Promise || document.write(\'\\x3Cscript src="/_polyfills/es6-promise.min.js">\\x3C/script>\\x3Cscript>ES6Promise.polyfill()\\x3C/script>\')'
)}
{x(
"window.fetch || document.write('\\x3Cscript src=\"/_polyfills/fetch.min.js\">\\x3C/script>')"
'window.fetch || document.write(\'\\x3Cscript src="/_polyfills/fetch.min.js">\\x3C/script>\')'
)}
{x(`window.__DATA__ = ${JSON.stringify(data)}`)}
<title>{title}</title>
</head>
<body>
<div id="root" dangerouslySetInnerHTML={content} />
{scripts.map(s => <script key={s} src={s} />)}
{scripts.map(s => (
<script key={s} src={s} />
))}
</body>
</html>
);
@ -49,12 +53,12 @@ MainPage.propTypes = {
};
MainPage.defaultProps = {
title: "UNPKG",
description: "The CDN for everything on npm",
title: 'UNPKG',
description: 'The CDN for everything on npm',
scripts: [],
styles: [],
data: {},
content: createHTML("")
content: createHTML('')
};
module.exports = MainPage;

View File

@ -1,10 +1,10 @@
require("./autoIndex.css");
require('./autoIndex.css');
const React = require("react");
const ReactDOM = require("react-dom");
const React = require('react');
const ReactDOM = require('react-dom');
const App = require("./autoIndex/App");
const App = require('./autoIndex/App');
const props = window.__DATA__ || {};
ReactDOM.hydrate(<App {...props} />, document.getElementById("root"));
ReactDOM.hydrate(<App {...props} />, document.getElementById('root'));

View File

@ -1,8 +1,8 @@
require("./App.css");
require('./App.css');
const React = require("react");
const React = require('react');
const DirectoryListing = require("./DirectoryListing");
const DirectoryListing = require('./DirectoryListing');
class App extends React.Component {
static defaultProps = {
@ -11,8 +11,8 @@ class App extends React.Component {
handleChange = event => {
window.location.href = window.location.href.replace(
"@" + this.props.packageVersion,
"@" + event.target.value
'@' + this.props.packageVersion,
'@' + event.target.value
);
};
@ -26,7 +26,7 @@ class App extends React.Component {
</h1>
<div className="app-version-selector">
Version:{" "}
Version:{' '}
<select
id="version"
defaultValue={this.props.packageVersion}
@ -59,8 +59,8 @@ class App extends React.Component {
}
}
if (process.env.NODE_ENV === "development") {
const PropTypes = require("prop-types");
if (process.env.NODE_ENV === 'development') {
const PropTypes = require('prop-types');
const entryType = PropTypes.object;

View File

@ -1,20 +1,20 @@
require("./DirectoryListing.css");
require('./DirectoryListing.css');
const React = require("react");
const formatBytes = require("pretty-bytes");
const sortBy = require("sort-by");
const React = require('react');
const formatBytes = require('pretty-bytes');
const sortBy = require('sort-by');
function getDirname(name) {
return (
name
.split("/")
.split('/')
.slice(0, -1)
.join("/") || "."
.join('/') || '.'
);
}
function getMatchingEntries(entry, entries) {
const dirname = entry.name || ".";
const dirname = entry.name || '.';
return Object.keys(entries)
.filter(name => entry.name !== name && getDirname(name) === dirname)
@ -28,7 +28,7 @@ function getRelativeName(base, name) {
function DirectoryListing({ filename, entry, entries }) {
const rows = [];
if (filename !== "/") {
if (filename !== '/') {
rows.push(
<tr key="..">
<td>
@ -46,11 +46,11 @@ function DirectoryListing({ filename, entry, entries }) {
const matchingEntries = getMatchingEntries(entry, entries);
matchingEntries
.filter(({ type }) => type === "directory")
.sort(sortBy("name"))
.filter(({ type }) => type === 'directory')
.sort(sortBy('name'))
.forEach(({ name }) => {
const relName = getRelativeName(entry.name, name);
const href = relName + "/";
const href = relName + '/';
rows.push(
<tr key={name}>
@ -67,8 +67,8 @@ function DirectoryListing({ filename, entry, entries }) {
});
matchingEntries
.filter(({ type }) => type === "file")
.sort(sortBy("name"))
.filter(({ type }) => type === 'file')
.sort(sortBy('name'))
.forEach(({ name, size, contentType, lastModified }) => {
const relName = getRelativeName(entry.name, name);
@ -100,7 +100,7 @@ function DirectoryListing({ filename, entry, entries }) {
<tbody>
{rows.map((row, index) =>
React.cloneElement(row, {
className: index % 2 ? "odd" : "even"
className: index % 2 ? 'odd' : 'even'
})
)}
</tbody>
@ -109,8 +109,8 @@ function DirectoryListing({ filename, entry, entries }) {
);
}
if (process.env.NODE_ENV === "development") {
const PropTypes = require("prop-types");
if (process.env.NODE_ENV === 'development') {
const PropTypes = require('prop-types');
const entryType = PropTypes.shape({
name: PropTypes.string.isRequired

View File

@ -1,8 +1,8 @@
require("./main.css");
require('./main.css');
const React = require("react");
const ReactDOM = require("react-dom");
const React = require('react');
const ReactDOM = require('react-dom');
const App = require("./main/App");
const App = require('./main/App');
ReactDOM.render(<App />, document.getElementById("root"));
ReactDOM.render(<App />, document.getElementById('root'));

View File

@ -1,9 +1,9 @@
require("./About.css");
require('./About.css');
const React = require("react");
const React = require('react');
const h = require("../utils/createHTML");
const markup = require("./About.md");
const h = require('../utils/createHTML');
const markup = require('./About.md');
function About() {
return <div className="wrapper" dangerouslySetInnerHTML={h(markup)} />;

View File

@ -1,7 +1,7 @@
const React = require("react");
const { HashRouter } = require("react-router-dom");
const React = require('react');
const { HashRouter } = require('react-router-dom');
const Layout = require("./Layout");
const Layout = require('./Layout');
function App() {
return (

View File

@ -1,9 +1,9 @@
require("./Home.css");
require('./Home.css');
const React = require("react");
const React = require('react');
const h = require("../utils/createHTML");
const markup = require("./Home.md");
const h = require('../utils/createHTML');
const markup = require('./Home.md');
function Home() {
return <div className="wrapper" dangerouslySetInnerHTML={h(markup)} />;

View File

@ -1,14 +1,14 @@
require("./Layout.css");
require('./Layout.css');
const React = require("react");
const PropTypes = require("prop-types");
const { Switch, Route, Link, withRouter } = require("react-router-dom");
const { Motion, spring } = require("react-motion");
const React = require('react');
const PropTypes = require('prop-types');
const { Switch, Route, Link, withRouter } = require('react-router-dom');
const { Motion, spring } = require('react-motion');
const WindowSize = require("./WindowSize");
const About = require("./About");
const Stats = require("./Stats");
const Home = require("./Home");
const WindowSize = require('./WindowSize');
const About = require('./About');
const Stats = require('./Stats');
const Home = require('./Home');
class Layout extends React.Component {
static propTypes = {
@ -26,18 +26,18 @@ class Layout extends React.Component {
adjustUnderline = (useSpring = false) => {
let itemIndex;
switch (this.props.location.pathname) {
case "/stats":
case '/stats':
itemIndex = 1;
break;
case "/about":
case '/about':
itemIndex = 2;
break;
case "/":
case '/':
default:
itemIndex = 0;
}
const itemNodes = this.listNode.querySelectorAll("li");
const itemNodes = this.listNode.querySelectorAll('li');
const currentNode = itemNodes[itemIndex];
this.setState({
@ -50,7 +50,7 @@ class Layout extends React.Component {
componentDidMount() {
this.adjustUnderline();
fetch("/api/stats?period=last-month")
fetch('/api/stats?period=last-month')
.then(res => res.json())
.then(stats => this.setState({ stats }));

View File

@ -1,14 +1,14 @@
require("./Stats.css");
require('./Stats.css');
const React = require("react");
const PropTypes = require("prop-types");
const formatBytes = require("pretty-bytes");
const formatDate = require("date-fns/format");
const parseDate = require("date-fns/parse");
const { continents, countries } = require("countries-list");
const React = require('react');
const PropTypes = require('prop-types');
const formatBytes = require('pretty-bytes');
const formatDate = require('date-fns/format');
const parseDate = require('date-fns/parse');
const { continents, countries } = require('countries-list');
const formatNumber = require("../utils/formatNumber");
const formatPercent = require("../utils/formatPercent");
const formatNumber = require('../utils/formatNumber');
const formatPercent = require('../utils/formatPercent');
function getCountriesByContinent(continent) {
return Object.keys(countries).filter(
@ -68,15 +68,15 @@ class Stats extends React.Component {
</a>
</td>
<td>
{formatNumber(requests)} ({formatPercent(
requests / totals.requests.all
)}%)
{formatNumber(requests)} (
{formatPercent(requests / totals.requests.all)}
%)
</td>
{bandwidth ? (
<td>
{formatBytes(bandwidth)} ({formatPercent(
bandwidth / totals.bandwidth.all
)}%)
{formatBytes(bandwidth)} (
{formatPercent(bandwidth / totals.bandwidth.all)}
%)
</td>
) : (
<td>-</td>
@ -120,16 +120,16 @@ class Stats extends React.Component {
</td>
<td>
<strong>
{formatNumber(continentData.requests)} ({formatPercent(
continentData.requests / totals.requests.all
)}%)
{formatNumber(continentData.requests)} (
{formatPercent(continentData.requests / totals.requests.all)}
%)
</strong>
</td>
<td>
<strong>
{formatBytes(continentData.bandwidth)} ({formatPercent(
continentData.bandwidth / totals.bandwidth.all
)}%)
{formatBytes(continentData.bandwidth)} (
{formatPercent(continentData.bandwidth / totals.bandwidth.all)}
%)
</strong>
</td>
</tr>
@ -148,14 +148,14 @@ class Stats extends React.Component {
<tr key={continent + country} className="country-row">
<td className="country-name">{countries[country].name}</td>
<td>
{formatNumber(countryRequests)} ({formatPercent(
countryRequests / totals.requests.all
)}%)
{formatNumber(countryRequests)} (
{formatPercent(countryRequests / totals.requests.all)}
%)
</td>
<td>
{formatBytes(countryBandwidth)} ({formatPercent(
countryBandwidth / totals.bandwidth.all
)}%)
{formatBytes(countryBandwidth)} (
{formatPercent(countryBandwidth / totals.bandwidth.all)}
%)
</td>
</tr>
);
@ -176,9 +176,9 @@ class Stats extends React.Component {
<tr key={protocol}>
<td>{protocol}</td>
<td>
{formatNumber(requests)} ({formatPercent(
requests / sumValues(totals.requests.protocol)
)}%)
{formatNumber(requests)} (
{formatPercent(requests / sumValues(totals.requests.protocol))}
%)
</td>
</tr>
);
@ -187,29 +187,29 @@ class Stats extends React.Component {
return (
<div className="wrapper">
<p>
From <strong>{formatDate(since, "MMM D")}</strong> to{" "}
<strong>{formatDate(until, "MMM D")}</strong> unpkg served{" "}
From <strong>{formatDate(since, 'MMM D')}</strong> to{' '}
<strong>{formatDate(until, 'MMM D')}</strong> unpkg served{' '}
<strong>{formatNumber(totals.requests.all)}</strong> requests and a
total of <strong>{formatBytes(totals.bandwidth.all)}</strong> of data
to <strong>{formatNumber(totals.uniques.all)}</strong> unique
visitors,{" "}
visitors,{' '}
<strong>
{formatPercent(totals.requests.cached / totals.requests.all, 0)}%
</strong>{" "}
</strong>{' '}
of which were served from the cache.
</p>
<h3>Packages</h3>
<p>
The table below shows the most popular packages served by unpkg from{" "}
<strong>{formatDate(since, "MMM D")}</strong> to{" "}
<strong>{formatDate(until, "MMM D")}</strong>. Only the top{" "}
The table below shows the most popular packages served by unpkg from{' '}
<strong>{formatDate(since, 'MMM D')}</strong> to{' '}
<strong>{formatDate(until, 'MMM D')}</strong>. Only the top{' '}
{Object.keys(totals.requests.package).length} packages are shown.
</p>
<p className="table-filter">
Include only packages that received at least{" "}
Include only packages that received at least{' '}
<select
value={this.state.minPackageRequests}
onChange={event =>
@ -224,11 +224,11 @@ class Stats extends React.Component {
<option value="100000">100,000</option>
<option value="1000000">1,000,000</option>
<option value="10000000">10,000,000</option>
</select>{" "}
</select>{' '}
requests.
</p>
<table cellSpacing="0" cellPadding="0" style={{ width: "100%" }}>
<table cellSpacing="0" cellPadding="0" style={{ width: '100%' }}>
<thead>
<tr>
<th>
@ -248,13 +248,13 @@ class Stats extends React.Component {
<h3>Regions</h3>
<p>
The table below breaks down requests to unpkg from{" "}
<strong>{formatDate(since, "MMM D")}</strong> to{" "}
<strong>{formatDate(until, "MMM D")}</strong> by geographic region.
The table below breaks down requests to unpkg from{' '}
<strong>{formatDate(since, 'MMM D')}</strong> to{' '}
<strong>{formatDate(until, 'MMM D')}</strong> by geographic region.
</p>
<p className="table-filter">
Include only countries that made at least{" "}
Include only countries that made at least{' '}
<select
value={this.state.minCountryRequests}
onChange={event =>
@ -268,14 +268,14 @@ class Stats extends React.Component {
<option value="1000000">1,000,000</option>
<option value="10000000">10,000,000</option>
<option value="100000000">100,000,000</option>
</select>{" "}
</select>{' '}
requests.
</p>
<table
cellSpacing="0"
cellPadding="0"
style={{ width: "100%" }}
style={{ width: '100%' }}
className="regions-table"
>
<thead>
@ -297,12 +297,12 @@ class Stats extends React.Component {
<h3>Protocols</h3>
<p>
The table below breaks down requests to unpkg from{" "}
<strong>{formatDate(since, "MMM D")}</strong> to{" "}
<strong>{formatDate(until, "MMM D")}</strong> by HTTP protocol.
The table below breaks down requests to unpkg from{' '}
<strong>{formatDate(since, 'MMM D')}</strong> to{' '}
<strong>{formatDate(until, 'MMM D')}</strong> by HTTP protocol.
</p>
<table cellSpacing="0" cellPadding="0" style={{ width: "100%" }}>
<table cellSpacing="0" cellPadding="0" style={{ width: '100%' }}>
<thead>
<tr>
<th>

View File

@ -1,10 +1,10 @@
const React = require("react");
const PropTypes = require("prop-types");
const React = require('react');
const PropTypes = require('prop-types');
const addEvent = require("../utils/addEvent");
const removeEvent = require("../utils/removeEvent");
const addEvent = require('../utils/addEvent');
const removeEvent = require('../utils/removeEvent');
const resizeEvent = "resize";
const resizeEvent = 'resize';
class WindowSize extends React.Component {
static propTypes = {

View File

@ -2,7 +2,7 @@ function addEvent(node, type, handler) {
if (node.addEventListener) {
node.addEventListener(type, handler, false);
} else if (node.attachEvent) {
node.attachEvent("on" + type, handler);
node.attachEvent('on' + type, handler);
}
}

View File

@ -1,6 +1,6 @@
const React = require("react");
const React = require('react');
const h = require("./createHTML");
const h = require('./createHTML');
function execScript(code) {
return <script dangerouslySetInnerHTML={h(code)} />;

View File

@ -1,12 +1,12 @@
function formatNumber(n) {
const digits = String(n).split("");
const digits = String(n).split('');
const groups = [];
while (digits.length) {
groups.unshift(digits.splice(-3).join(""));
groups.unshift(digits.splice(-3).join(''));
}
return groups.join(",");
return groups.join(',');
}
module.exports = formatNumber;

View File

@ -1,5 +1,5 @@
function parseNumber(s) {
return parseInt(s.replace(/,/g, ""), 10) || 0;
return parseInt(s.replace(/,/g, ''), 10) || 0;
}
module.exports = parseNumber;

View File

@ -2,7 +2,7 @@ function removeEvent(node, type, handler) {
if (node.removeEventListener) {
node.removeEventListener(type, handler, false);
} else if (node.detachEvent) {
node.detachEvent("on" + type, handler);
node.detachEvent('on' + type, handler);
}
}

View File

@ -1,9 +1,9 @@
// Use babel to compile JSX on the fly.
require("@babel/register")({
require('@babel/register')({
only: [/modules\/client/]
});
// Ignore require("*.css") calls.
require.extensions[".css"] = function() {
require.extensions['.css'] = function() {
return {};
};

View File

@ -1,11 +1,11 @@
const webpack = require("webpack");
const webpack = require('webpack');
/**
* Returns a modified copy of the given webpackEntry object with
* the moduleId in front of all other assets.
*/
function prependModuleId(webpackEntry, moduleId) {
if (typeof webpackEntry === "string") {
if (typeof webpackEntry === 'string') {
return [moduleId, webpackEntry];
}
@ -13,7 +13,7 @@ function prependModuleId(webpackEntry, moduleId) {
return [moduleId, ...webpackEntry];
}
if (webpackEntry && typeof webpackEntry === "object") {
if (webpackEntry && typeof webpackEntry === 'object') {
const entry = { ...webpackEntry };
for (const chunkName in entry) {
@ -25,7 +25,7 @@ function prependModuleId(webpackEntry, moduleId) {
return entry;
}
throw new Error("Invalid webpack entry object");
throw new Error('Invalid webpack entry object');
}
/**

View File

@ -1,11 +1,11 @@
const express = require("express");
const morgan = require("morgan");
const WebpackDevServer = require("webpack-dev-server");
const devErrorHandler = require("errorhandler");
const express = require('express');
const morgan = require('morgan');
const WebpackDevServer = require('webpack-dev-server');
const devErrorHandler = require('errorhandler');
const devAssets = require("./middleware/devAssets");
const createDevCompiler = require("./createDevCompiler");
const createRouter = require("./createRouter");
const devAssets = require('./middleware/devAssets');
const createDevCompiler = require('./createDevCompiler');
const createRouter = require('./createRouter');
function createDevServer(publicDir, webpackConfig, devOrigin) {
const compiler = createDevCompiler(
@ -33,8 +33,8 @@ function createDevServer(publicDir, webpackConfig, devOrigin) {
disableHostCheck: true,
before(app) {
// This runs before webpack-dev-middleware
app.disable("x-powered-by");
app.use(morgan("dev"));
app.disable('x-powered-by');
app.use(morgan('dev'));
}
});

View File

@ -1,6 +1,6 @@
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
function route(setup) {
const app = express.Router();
@ -11,92 +11,92 @@ function route(setup) {
function createRouter() {
const app = express.Router();
app.get("/", require("./actions/serveRootPage"));
app.get('/', require('./actions/serveRootPage'));
app.use(cors());
app.use(bodyParser.json());
app.use(require("./middleware/userToken"));
app.use(require('./middleware/userToken'));
app.use(
"/api",
'/api',
route(app => {
app.get("/publicKey", require("./actions/showPublicKey"));
app.get('/publicKey', require('./actions/showPublicKey'));
app.post("/auth", require("./actions/createAuth"));
app.get("/auth", require("./actions/showAuth"));
app.post('/auth', require('./actions/createAuth'));
app.get('/auth', require('./actions/showAuth'));
app.post(
"/blacklist",
require("./middleware/requireAuth")("blacklist.add"),
require("./actions/addToBlacklist")
'/blacklist',
require('./middleware/requireAuth')('blacklist.add'),
require('./actions/addToBlacklist')
);
app.get(
"/blacklist",
require("./middleware/requireAuth")("blacklist.read"),
require("./actions/showBlacklist")
'/blacklist',
require('./middleware/requireAuth')('blacklist.read'),
require('./actions/showBlacklist')
);
app.delete(
"/blacklist",
require("./middleware/requireAuth")("blacklist.remove"),
require("./actions/removeFromBlacklist")
'/blacklist',
require('./middleware/requireAuth')('blacklist.remove'),
require('./actions/removeFromBlacklist')
);
if (process.env.NODE_ENV !== "test") {
app.get("/stats", require("./actions/showStats"));
if (process.env.NODE_ENV !== 'test') {
app.get('/stats', require('./actions/showStats'));
}
})
);
// TODO: Remove
app.get("/_publicKey", require("./actions/showPublicKey"));
app.get('/_publicKey', require('./actions/showPublicKey'));
// TODO: Remove
app.use(
"/_auth",
'/_auth',
route(app => {
app.post("/", require("./actions/createAuth"));
app.get("/", require("./actions/showAuth"));
app.post('/', require('./actions/createAuth'));
app.get('/', require('./actions/showAuth'));
})
);
// TODO: Remove
app.use(
"/_blacklist",
'/_blacklist',
route(app => {
app.post(
"/",
require("./middleware/requireAuth")("blacklist.add"),
require("./actions/addToBlacklist")
'/',
require('./middleware/requireAuth')('blacklist.add'),
require('./actions/addToBlacklist')
);
app.get(
"/",
require("./middleware/requireAuth")("blacklist.read"),
require("./actions/showBlacklist")
'/',
require('./middleware/requireAuth')('blacklist.read'),
require('./actions/showBlacklist')
);
app.delete(
"*",
require("./middleware/requireAuth")("blacklist.remove"),
require("./middleware/validatePackageURL"),
require("./actions/removeFromBlacklist")
'*',
require('./middleware/requireAuth')('blacklist.remove'),
require('./middleware/validatePackageURL'),
require('./actions/removeFromBlacklist')
);
})
);
// TODO: Remove
if (process.env.NODE_ENV !== "test") {
app.get("/_stats", require("./actions/showStats"));
if (process.env.NODE_ENV !== 'test') {
app.get('/_stats', require('./actions/showStats'));
}
app.get(
"*",
require("./middleware/redirectLegacyURLs"),
require("./middleware/validatePackageURL"),
require("./middleware/validatePackageName"),
require("./middleware/validateQuery"),
require("./middleware/checkBlacklist"),
require("./middleware/fetchPackage"),
require("./middleware/findFile"),
require("./actions/serveFile")
'*',
require('./middleware/redirectLegacyURLs'),
require('./middleware/validatePackageURL'),
require('./middleware/validatePackageName'),
require('./middleware/validateQuery'),
require('./middleware/checkBlacklist'),
require('./middleware/fetchPackage'),
require('./middleware/findFile'),
require('./actions/serveFile')
);
return app;

View File

@ -1,14 +1,14 @@
const http = require("http");
const express = require("express");
const morgan = require("morgan");
const raven = require("raven");
const http = require('http');
const express = require('express');
const morgan = require('morgan');
const raven = require('raven');
const staticAssets = require("./middleware/staticAssets");
const createRouter = require("./createRouter");
const staticAssets = require('./middleware/staticAssets');
const createRouter = require('./createRouter');
morgan.token("fwd", req => {
const fwd = req.get("x-forwarded-for");
return fwd ? fwd.replace(/\s/g, "") : "-";
morgan.token('fwd', req => {
const fwd = req.get('x-forwarded-for');
return fwd ? fwd.replace(/\s/g, '') : '-';
});
if (process.env.SENTRY_DSN) {
@ -34,13 +34,13 @@ if (process.env.SENTRY_DSN) {
function createServer(publicDir, statsFile) {
const app = express();
app.disable("x-powered-by");
app.disable('x-powered-by');
if (process.env.SENTRY_DSN) {
app.use(raven.requestHandler());
}
if (process.env.NODE_ENV !== "test") {
if (process.env.NODE_ENV !== 'test') {
app.use(
morgan(
// Modified version of Heroku's log format
@ -53,7 +53,7 @@ function createServer(publicDir, statsFile) {
// app.use(errorHandler);
if (publicDir) {
app.use(express.static(publicDir, { maxAge: "365d" }));
app.use(express.static(publicDir, { maxAge: '365d' }));
}
if (statsFile) {
@ -76,14 +76,14 @@ function createServer(publicDir, statsFile) {
socket.end(
[
"HTTP/1.1 503 Service Unavailable",
"Date: " + new Date().toGMTString(),
"Content-Length: " + Buffer.byteLength(message),
"Content-Type: text/plain",
"Connection: close",
"",
'HTTP/1.1 503 Service Unavailable',
'Date: ' + new Date().toGMTString(),
'Content-Length: ' + Buffer.byteLength(message),
'Content-Type: text/plain',
'Connection: close',
'',
message
].join("\r\n")
].join('\r\n')
);
});

View File

@ -1,20 +1,20 @@
const parseURL = require("url").parse;
const startOfDay = require("date-fns/start_of_day");
const addDays = require("date-fns/add_days");
const parseURL = require('url').parse;
const startOfDay = require('date-fns/start_of_day');
const addDays = require('date-fns/add_days');
const db = require("./utils/data");
const isValidPackageName = require("./utils/isValidPackageName");
const parsePackageURL = require("./utils/parsePackageURL");
const logging = require("./utils/logging");
const db = require('./utils/data');
const isValidPackageName = require('./utils/isValidPackageName');
const parsePackageURL = require('./utils/parsePackageURL');
const logging = require('./utils/logging');
const CloudflareAPI = require("./CloudflareAPI");
const StatsAPI = require("./StatsAPI");
const CloudflareAPI = require('./CloudflareAPI');
const StatsAPI = require('./StatsAPI');
/**
* Domains we want to analyze.
*/
const domainNames = [
"unpkg.com"
'unpkg.com'
//"npmcdn.com" // We don't have log data on npmcdn.com yet :/
];
@ -25,7 +25,7 @@ function getSeconds(date) {
}
function stringifySeconds(seconds) {
return new Date(seconds * 1000).toISOString().replace(/\.0+Z$/, "Z");
return new Date(seconds * 1000).toISOString().replace(/\.0+Z$/, 'Z');
}
function toSeconds(ms) {
@ -45,8 +45,8 @@ function computeCounters(stream) {
}
stream
.on("error", reject)
.on("data", entry => {
.on('error', reject)
.on('data', entry => {
totalEntries += 1;
const date = new Date(Math.round(entry.EdgeStartTimestamp / 1000000));
@ -105,7 +105,7 @@ function computeCounters(stream) {
);
}
})
.on("end", () => {
.on('end', () => {
resolve({ counters, expireat, totalEntries });
});
});
@ -137,12 +137,12 @@ function ingestLogsForZone(zone, startDate, endDate) {
const startFetchTime = Date.now();
const fields = [
"EdgeStartTimestamp",
"EdgeResponseStatus",
"EdgeResponseBytes",
"ClientRequestProtocol",
"ClientRequestURI",
"ClientRequestReferer"
'EdgeStartTimestamp',
'EdgeResponseStatus',
'EdgeResponseBytes',
'ClientRequestProtocol',
'ClientRequestURI',
'ClientRequestReferer'
];
return CloudflareAPI.getLogs(
@ -154,7 +154,7 @@ function ingestLogsForZone(zone, startDate, endDate) {
const endFetchTime = Date.now();
logging.info(
"Fetched logs for %s from %s to %s (%dms)",
'Fetched logs for %s from %s to %s (%dms)',
zone.name,
stringifySeconds(startSeconds),
stringifySeconds(endSeconds),
@ -167,7 +167,7 @@ function ingestLogsForZone(zone, startDate, endDate) {
const endProcessTime = Date.now();
logging.info(
"Processed %d log entries for %s (%dms)",
'Processed %d log entries for %s (%dms)',
totalEntries,
zone.name,
endProcessTime - startProcessTime

View File

@ -1,7 +1,7 @@
const addMinutes = require("date-fns/add_minutes");
const startOfMinute = require("date-fns/start_of_minute");
const addMinutes = require('date-fns/add_minutes');
const startOfMinute = require('date-fns/start_of_minute');
const ingestLogs = require("./ingestLogs");
const ingestLogs = require('./ingestLogs');
const oneSecond = 1000;
const oneMinute = oneSecond * 60;
@ -26,18 +26,18 @@ function work() {
}
function shutdown() {
console.log("Shutting down...");
console.log('Shutting down...');
clearInterval(timer);
currentWorkload.then(() => {
console.log("Goodbye!");
console.log('Goodbye!');
process.exit();
});
}
work();
process.on("SIGINT", shutdown).on("SIGTERM", shutdown);
process.on('SIGINT', shutdown).on('SIGTERM', shutdown);
timer = setInterval(work, oneMinute);

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,14 +7,14 @@ function checkBlacklist(req, res, next) {
if (blacklisted) {
res
.status(403)
.type("text")
.type('text')
.send(`Package "${req.packageName}" is blacklisted`);
} else {
next();
}
},
error => {
console.error("Unable to fetch the blacklist: %s", error);
console.error('Unable to fetch the blacklist: %s', error);
// Continue anyway.
next();

View File

@ -1,6 +1,6 @@
const invariant = require("invariant");
const invariant = require('invariant');
const createAssets = require("./utils/createAssets");
const createAssets = require('./utils/createAssets');
/**
* An express middleware that sets req.assets from the
@ -9,15 +9,15 @@ const createAssets = require("./utils/createAssets");
*/
function devAssets(webpackCompiler) {
let assets;
webpackCompiler.plugin("done", stats => {
webpackCompiler.plugin('done', stats => {
assets = createAssets(stats.toJson());
});
return (req, res, next) => {
invariant(
assets != null,
"devAssets middleware needs a running compiler; " +
"use webpack-dev-middleware in front of devAssets"
'devAssets middleware needs a running compiler; ' +
'use webpack-dev-middleware in front of devAssets'
);
req.assets = assets;

View File

@ -1,19 +1,19 @@
const semver = require("semver");
const semver = require('semver');
const addLeadingSlash = require("../utils/addLeadingSlash");
const createPackageURL = require("../utils/createPackageURL");
const createSearch = require("../utils/createSearch");
const getNpmPackageInfo = require("../utils/getNpmPackageInfo");
const incrementCounter = require("../utils/incrementCounter");
const addLeadingSlash = require('../utils/addLeadingSlash');
const createPackageURL = require('../utils/createPackageURL');
const createSearch = require('../utils/createSearch');
const getNpmPackageInfo = require('../utils/getNpmPackageInfo');
const incrementCounter = require('../utils/incrementCounter');
function tagRedirect(req, res) {
const version = req.packageInfo["dist-tags"][req.packageVersion];
const version = req.packageInfo['dist-tags'][req.packageVersion];
// 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,
@ -31,8 +31,8 @@ function semverRedirect(req, res) {
// 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,
@ -41,7 +41,7 @@ function semverRedirect(req, res) {
} else {
res
.status(404)
.type("text")
.type('text')
.send(`Cannot find package ${req.packageSpec}`);
}
}
@ -52,12 +52,12 @@ function filenameRedirect(req, res) {
// See https://github.com/rollup/rollup/wiki/pkg.module
filename =
req.packageConfig.module ||
req.packageConfig["jsnext:main"] ||
"/index.js";
req.packageConfig['jsnext:main'] ||
'/index.js';
} else if (
req.query.main &&
req.packageConfig[req.query.main] &&
typeof req.packageConfig[req.query.main] === "string"
typeof req.packageConfig[req.query.main] === 'string'
) {
// Deprecated, see #63
filename = req.packageConfig[req.query.main];
@ -65,35 +65,35 @@ function filenameRedirect(req, res) {
// Count which packages are using this so we can warn them when we
// remove this functionality.
incrementCounter(
"package-json-custom-main",
req.packageSpec + "?main=" + req.query.main,
'package-json-custom-main',
req.packageSpec + '?main=' + req.query.main,
1
);
} else if (
req.packageConfig.unpkg &&
typeof req.packageConfig.unpkg === "string"
typeof req.packageConfig.unpkg === 'string'
) {
filename = req.packageConfig.unpkg;
} else if (
req.packageConfig.browser &&
typeof req.packageConfig.browser === "string"
typeof req.packageConfig.browser === 'string'
) {
// Deprecated, see #63
filename = req.packageConfig.browser;
// Count which packages are using this so we can warn them when we
// remove this functionality.
incrementCounter("package-json-browser-fallback", req.packageSpec, 1);
incrementCounter('package-json-browser-fallback', req.packageSpec, 1);
} else {
filename = req.packageConfig.main || "/index.js";
filename = req.packageConfig.main || '/index.js';
}
// Redirect to the exact filename so relative imports
// and URLs resolve correctly.
res
.set({
"Cache-Control": "public, max-age=31536000, immutable", // 1 year
"Cache-Tag": "redirect, filename-redirect"
'Cache-Control': 'public, max-age=31536000, immutable', // 1 year
'Cache-Tag': 'redirect, filename-redirect'
})
.redirect(
302,
@ -117,7 +117,7 @@ function fetchPackage(req, res, next) {
if (packageInfo == null || packageInfo.versions == null) {
return res
.status(404)
.type("text")
.type('text')
.send(`Cannot find package "${req.packageName}"`);
}
@ -126,7 +126,7 @@ function fetchPackage(req, res, next) {
if (!req.packageConfig) {
// Redirect to a fully-resolved version.
if (req.packageVersion in req.packageInfo["dist-tags"]) {
if (req.packageVersion in req.packageInfo['dist-tags']) {
return tagRedirect(req, res);
} else {
return semverRedirect(req, res);
@ -144,7 +144,7 @@ function fetchPackage(req, res, next) {
return res
.status(500)
.type("text")
.type('text')
.send(`Cannot get info for package "${req.packageName}"`);
}
);

View File

@ -1,19 +1,19 @@
const path = require("path");
const path = require('path');
const addLeadingSlash = require("../utils/addLeadingSlash");
const createPackageURL = require("../utils/createPackageURL");
const createSearch = require("../utils/createSearch");
const fetchNpmPackage = require("../utils/fetchNpmPackage");
const getIntegrity = require("../utils/getIntegrity");
const getContentType = require("../utils/getContentType");
const addLeadingSlash = require('../utils/addLeadingSlash');
const createPackageURL = require('../utils/createPackageURL');
const createSearch = require('../utils/createSearch');
const fetchNpmPackage = require('../utils/fetchNpmPackage');
const getIntegrity = require('../utils/getIntegrity');
const getContentType = require('../utils/getContentType');
function indexRedirect(req, res, entry) {
// Redirect to the index file so relative imports
// resolve correctly.
res
.set({
"Cache-Control": "public, max-age=31536000, immutable", // 1 year
"Cache-Tag": "redirect, index-redirect"
'Cache-Control': 'public, max-age=31536000, immutable', // 1 year
'Cache-Tag': 'redirect, index-redirect'
})
.redirect(
302,
@ -27,7 +27,7 @@ function indexRedirect(req, res, entry) {
}
function stripLeadingSegment(name) {
return name.replace(/^[^/]+\/?/, "");
return name.replace(/^[^/]+\/?/, '');
}
function searchEntries(tarballStream, entryName, wantsIndex) {
@ -35,14 +35,14 @@ function searchEntries(tarballStream, entryName, wantsIndex) {
const entries = {};
let foundEntry = null;
if (entryName === "") {
foundEntry = entries[""] = { name: "", type: "directory" };
if (entryName === '') {
foundEntry = entries[''] = { name: '', type: 'directory' };
}
tarballStream
.on("error", reject)
.on("finish", () => resolve({ entries, foundEntry }))
.on("entry", (header, stream, next) => {
.on('error', reject)
.on('finish', () => resolve({ entries, foundEntry }))
.on('entry', (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
@ -53,9 +53,9 @@ function searchEntries(tarballStream, entryName, wantsIndex) {
};
// We are only interested in files that match the entryName.
if (entry.type !== "file" || entry.name.indexOf(entryName) !== 0) {
if (entry.type !== 'file' || entry.name.indexOf(entryName) !== 0) {
stream.resume();
stream.on("end", next);
stream.on('end', next);
return;
}
@ -65,8 +65,8 @@ function searchEntries(tarballStream, entryName, wantsIndex) {
// that are in this file's path. Some tarballs omit these entries
// for some reason, so this is the brute force method.
let dirname = path.dirname(entry.name);
while (dirname !== ".") {
const directoryEntry = { name: dirname, type: "directory" };
while (dirname !== '.') {
const directoryEntry = { name: dirname, type: 'directory' };
if (!entries[dirname]) {
entries[dirname] = directoryEntry;
@ -94,7 +94,7 @@ function searchEntries(tarballStream, entryName, wantsIndex) {
const chunks = [];
stream.on("data", chunk => chunks.push(chunk)).on("end", () => {
stream.on('data', chunk => chunks.push(chunk)).on('end', () => {
const content = Buffer.concat(chunks);
// Set some extra properties for files that we will
@ -126,8 +126,8 @@ const trailingSlash = /\/$/;
function findFile(req, res, next) {
fetchNpmPackage(req.packageConfig).then(tarballStream => {
const entryName = req.filename
.replace(trailingSlash, "")
.replace(leadingSlash, "");
.replace(trailingSlash, '')
.replace(leadingSlash, '');
const wantsIndex = trailingSlash.test(req.filename);
searchEntries(tarballStream, entryName, wantsIndex).then(
@ -135,7 +135,7 @@ function findFile(req, res, next) {
if (!foundEntry) {
return res
.status(404)
.type("text")
.type('text')
.send(`Cannot find "${req.filename}" in ${req.packageSpec}`);
}
@ -144,17 +144,17 @@ function findFile(req, res, next) {
// inside that directory. This is so our URLs work in a similar way
// to require("lib") in node where it searches for `lib/index.js`
// and `lib/index.json` when `lib` is a directory.
if (foundEntry.type === "directory" && !wantsIndex) {
if (foundEntry.type === 'directory' && !wantsIndex) {
const indexEntry =
entries[path.join(entryName, "index.js")] ||
entries[path.join(entryName, "index.json")];
entries[path.join(entryName, 'index.js')] ||
entries[path.join(entryName, 'index.json')];
if (indexEntry && indexEntry.type === "file") {
if (indexEntry && indexEntry.type === 'file') {
return indexRedirect(req, res, indexEntry);
} else {
return res
.status(404)
.type("text")
.type('text')
.send(
`Cannot find an index in "${req.filename}" in ${
req.packageSpec

View File

@ -1,4 +1,4 @@
const createSearch = require("../utils/createSearch");
const createSearch = require('../utils/createSearch');
/**
* Redirect old URLs that we no longer support.
@ -6,14 +6,14 @@ const createSearch = require("../utils/createSearch");
function redirectLegacyURLs(req, res, next) {
// Permanently redirect /_meta/path to /path?meta.
if (req.path.match(/^\/_meta\//)) {
req.query.meta = "";
req.query.meta = '';
return res.redirect(301, req.path.substr(6) + createSearch(req.query));
}
// Permanently redirect /path?json => /path?meta
if (req.query.json != null) {
delete req.query.json;
req.query.meta = "";
req.query.meta = '';
return res.redirect(301, req.path + createSearch(req.query));
}

View File

@ -4,8 +4,8 @@
*/
function requireAuth(scope) {
let checkScopes;
if (scope.includes(".")) {
const parts = scope.split(".");
if (scope.includes('.')) {
const parts = scope.split('.');
checkScopes = scopes =>
parts.reduce((memo, part) => memo && memo[part], scopes) != null;
} else {
@ -20,11 +20,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,7 +1,7 @@
const fs = require("fs");
const invariant = require("invariant");
const fs = require('fs');
const invariant = require('invariant');
const createAssets = require("./utils/createAssets");
const createAssets = require('./utils/createAssets');
/**
* An express middleware that sets req.assets from the build
@ -10,12 +10,12 @@ const createAssets = require("./utils/createAssets");
function staticAssets(webpackStatsFile) {
let stats;
try {
stats = JSON.parse(fs.readFileSync(webpackStatsFile, "utf8"));
stats = JSON.parse(fs.readFileSync(webpackStatsFile, 'utf8'));
} catch (error) {
invariant(
false,
"staticAssets middleware cannot read the build stats in %s; " +
"run the `build` script before starting the server",
'staticAssets middleware cannot read the build stats in %s; ' +
'run the `build` script before starting the server',
webpackStatsFile
);
}

View File

@ -1,9 +1,9 @@
const AuthAPI = require("../AuthAPI");
const AuthAPI = require('../AuthAPI');
const ReadMethods = { GET: true, HEAD: true };
function decodeBase64(string) {
return Buffer.from(string, "base64").toString();
return Buffer.from(string, 'base64').toString();
}
/**
@ -14,7 +14,7 @@ function userToken(req, res, next) {
return next();
}
const auth = req.get("Authorization");
const auth = req.get('Authorization');
const token = auth
? decodeBase64(auth)
: (ReadMethods[req.method] ? req.query : req.body).token;
@ -30,7 +30,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}`
});
@ -38,7 +38,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

@ -12,7 +12,7 @@ function createAssets(webpackStats) {
/**
* Returns an array of URLs to all assets in the given chunks.
*/
const getAll = (chunks = ["main"]) =>
const getAll = (chunks = ['main']) =>
(Array.isArray(chunks) ? chunks : [chunks])
.reduce((memo, chunk) => memo.concat(assetsByChunkName[chunk] || []), [])
.map(createURL);

View File

@ -1,4 +1,4 @@
const validateNpmPackageName = require("validate-npm-package-name");
const validateNpmPackageName = require('validate-npm-package-name');
const hexValue = /^[a-f0-9]+$/i;
@ -13,18 +13,18 @@ function validatePackageName(req, res, next) {
if (isHash(req.packageName)) {
return res
.status(403)
.type("text")
.type('text')
.send(`Invalid package name "${req.packageName}" (cannot be a hash)`);
}
const errors = validateNpmPackageName(req.packageName).errors;
if (errors) {
const reason = errors.join(", ");
const reason = errors.join(', ');
return res
.status(403)
.type("text")
.type('text')
.send(`Invalid package name "${req.packageName}" (${reason})`);
}

View File

@ -1,4 +1,4 @@
const parsePackageURL = require("../utils/parsePackageURL");
const parsePackageURL = require('../utils/parsePackageURL');
/**
* Parse the URL and add various properties to the request object to

View File

@ -1,4 +1,4 @@
const createSearch = require("../utils/createSearch");
const createSearch = require('../utils/createSearch');
const knownQueryParams = {
main: true, // Deprecated, see #63

View File

@ -1,5 +1,5 @@
const babel = require("babel-core");
const unpkgRewrite = require("../unpkgRewrite");
const babel = require('babel-core');
const unpkgRewrite = require('../unpkgRewrite');
const testCases = [
{
@ -66,13 +66,13 @@ const testCases = [
];
const dependencies = {
react: "15.6.1",
"@angular/router": "4.3.5",
"lodash.map": "4.6.0",
pn: "1.0.0"
react: '15.6.1',
'@angular/router': '4.3.5',
'lodash.map': '4.6.0',
pn: '1.0.0'
};
describe("Rewriting imports/exports", () => {
describe('Rewriting imports/exports', () => {
testCases.forEach(testCase => {
it(`successfully rewrites '${testCase.before}'`, () => {
const result = babel.transform(testCase.before, {

View File

@ -1,7 +1,7 @@
const URL = require("whatwg-url");
const warning = require("warning");
const URL = require('whatwg-url');
const warning = require('warning');
const origin = require("../serverConfig").origin;
const origin = require('../serverConfig').origin;
const bareIdentifierFormat = /^((?:@[^/]+\/)?[^/]+)(\/.*)?$/;
@ -10,7 +10,7 @@ function isValidURL(value) {
}
function isProbablyURLWithoutProtocol(value) {
return value.substr(0, 2) === "//";
return value.substr(0, 2) === '//';
}
function isAbsoluteURL(value) {
@ -18,7 +18,7 @@ function isAbsoluteURL(value) {
}
function isBareIdentifier(value) {
return value.charAt(0) !== "." && value.charAt(0) !== "/";
return value.charAt(0) !== '.' && value.charAt(0) !== '/';
}
function rewriteValue(/* StringLiteral */ node, dependencies) {
@ -30,7 +30,7 @@ function rewriteValue(/* StringLiteral */ node, dependencies) {
// "bare" identifier
const match = bareIdentifierFormat.exec(node.value);
const packageName = match[1];
const file = match[2] || "";
const file = match[2] || '';
warning(
dependencies[packageName],
@ -38,7 +38,7 @@ function rewriteValue(/* StringLiteral */ node, dependencies) {
packageName
);
const version = dependencies[packageName] || "latest";
const version = dependencies[packageName] || 'latest';
node.value = `${origin}/${packageName}@${version}${file}?module`;
} else {
@ -51,16 +51,16 @@ function unpkgRewrite(dependencies = {}) {
return {
manipulateOptions(opts, parserOpts) {
parserOpts.plugins.push(
"dynamicImport",
"exportDefaultFrom",
"exportNamespaceFrom",
"importMeta"
'dynamicImport',
'exportDefaultFrom',
'exportNamespaceFrom',
'importMeta'
);
},
visitor: {
CallExpression(path) {
if (path.node.callee.type !== "Import") {
if (path.node.callee.type !== 'Import') {
// Some other function call, not import();
return;
}

View File

@ -1,19 +1,19 @@
const fs = require("fs");
const path = require("path");
const forge = require("node-forge");
const invariant = require("invariant");
const fs = require('fs');
const path = require('path');
const forge = require('node-forge');
const invariant = require('invariant');
let secretKey;
if (process.env.NODE_ENV === "production") {
if (process.env.NODE_ENV === 'production') {
invariant(
process.env.PRIVATE_KEY,
"Missing $PRIVATE_KEY environment variable"
'Missing $PRIVATE_KEY environment variable'
);
secretKey = {
public: fs.readFileSync(
path.resolve(__dirname, "../secret_key.pub"),
"utf8"
path.resolve(__dirname, '../secret_key.pub'),
'utf8'
),
private: process.env.PRIVATE_KEY
};

View File

@ -1,9 +1,9 @@
exports.port = parseInt(process.env.PORT, 10) || 5000;
exports.origin =
process.env.NODE_ENV === "production" || process.env.NODE_ENV === "test"
? "https://unpkg.com"
process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test'
? 'https://unpkg.com'
: `http://localhost:${exports.port}`;
exports.registryURL =
process.env.NPM_REGISTRY_URL || "https://registry.npmjs.org";
process.env.NPM_REGISTRY_URL || 'https://registry.npmjs.org';

View File

@ -1,15 +1,15 @@
const createSearch = require("../createSearch");
const createSearch = require('../createSearch');
describe("createSearch", () => {
it("omits the trailing = for empty string values", () => {
expect(createSearch({ a: "a", b: "" })).toEqual("?a=a&b");
describe('createSearch', () => {
it('omits the trailing = for empty string values', () => {
expect(createSearch({ a: 'a', b: '' })).toEqual('?a=a&b');
});
it("sorts keys", () => {
expect(createSearch({ b: "b", a: "a", c: "c" })).toEqual("?a=a&b=b&c=c");
it('sorts keys', () => {
expect(createSearch({ b: 'b', a: 'a', c: 'c' })).toEqual('?a=a&b=b&c=c');
});
it("returns an empty string when there are no params", () => {
expect(createSearch({})).toEqual("");
it('returns an empty string when there are no params', () => {
expect(createSearch({})).toEqual('');
});
});

View File

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

View File

@ -1,80 +1,80 @@
const parsePackageURL = require("../parsePackageURL");
const parsePackageURL = require('../parsePackageURL');
describe("parsePackageURL", () => {
it("parses plain packages", () => {
expect(parsePackageURL("/history@1.0.0/umd/history.min.js")).toEqual({
pathname: "/history@1.0.0/umd/history.min.js",
search: "",
describe('parsePackageURL', () => {
it('parses plain packages', () => {
expect(parsePackageURL('/history@1.0.0/umd/history.min.js')).toEqual({
pathname: '/history@1.0.0/umd/history.min.js',
search: '',
query: {},
packageName: "history",
packageVersion: "1.0.0",
filename: "/umd/history.min.js"
packageName: 'history',
packageVersion: '1.0.0',
filename: '/umd/history.min.js'
});
});
it("parses plain packages with a hyphen in the name", () => {
expect(parsePackageURL("/query-string@5.0.0/index.js")).toEqual({
pathname: "/query-string@5.0.0/index.js",
search: "",
it('parses plain packages with a hyphen in the name', () => {
expect(parsePackageURL('/query-string@5.0.0/index.js')).toEqual({
pathname: '/query-string@5.0.0/index.js',
search: '',
query: {},
packageName: "query-string",
packageVersion: "5.0.0",
filename: "/index.js"
packageName: 'query-string',
packageVersion: '5.0.0',
filename: '/index.js'
});
});
it("parses plain packages with no version specified", () => {
expect(parsePackageURL("/query-string/index.js")).toEqual({
pathname: "/query-string/index.js",
search: "",
it('parses plain packages with no version specified', () => {
expect(parsePackageURL('/query-string/index.js')).toEqual({
pathname: '/query-string/index.js',
search: '',
query: {},
packageName: "query-string",
packageVersion: "latest",
filename: "/index.js"
packageName: 'query-string',
packageVersion: 'latest',
filename: '/index.js'
});
});
it("parses plain packages with version spec", () => {
expect(parsePackageURL("/query-string@>=4.0.0/index.js")).toEqual({
pathname: "/query-string@>=4.0.0/index.js",
search: "",
it('parses plain packages with version spec', () => {
expect(parsePackageURL('/query-string@>=4.0.0/index.js')).toEqual({
pathname: '/query-string@>=4.0.0/index.js',
search: '',
query: {},
packageName: "query-string",
packageVersion: ">=4.0.0",
filename: "/index.js"
packageName: 'query-string',
packageVersion: '>=4.0.0',
filename: '/index.js'
});
});
it("parses scoped packages", () => {
expect(parsePackageURL("/@angular/router@4.3.3/src/index.d.ts")).toEqual({
pathname: "/@angular/router@4.3.3/src/index.d.ts",
search: "",
it('parses scoped packages', () => {
expect(parsePackageURL('/@angular/router@4.3.3/src/index.d.ts')).toEqual({
pathname: '/@angular/router@4.3.3/src/index.d.ts',
search: '',
query: {},
packageName: "@angular/router",
packageVersion: "4.3.3",
filename: "/src/index.d.ts"
packageName: '@angular/router',
packageVersion: '4.3.3',
filename: '/src/index.d.ts'
});
});
it("parses package names with a period in them", () => {
expect(parsePackageURL("/index.js")).toEqual({
pathname: "/index.js",
search: "",
it('parses package names with a period in them', () => {
expect(parsePackageURL('/index.js')).toEqual({
pathname: '/index.js',
search: '',
query: {},
packageName: "index.js",
packageVersion: "latest",
filename: ""
packageName: 'index.js',
packageVersion: 'latest',
filename: ''
});
});
it("parses valid query parameters", () => {
expect(parsePackageURL("/history?main=browser")).toEqual({
pathname: "/history",
search: "?main=browser",
query: { main: "browser" },
packageName: "history",
packageVersion: "latest",
filename: ""
it('parses valid query parameters', () => {
expect(parsePackageURL('/history?main=browser')).toEqual({
pathname: '/history',
search: '?main=browser',
query: { main: 'browser' },
packageName: 'history',
packageVersion: 'latest',
filename: ''
});
});
});

View File

@ -1,5 +1,5 @@
function addLeadingSlash(name) {
return name.charAt(0) === "/" ? name : "/" + name;
return name.charAt(0) === '/' ? name : '/' + name;
}
module.exports = addLeadingSlash;

View File

@ -3,9 +3,9 @@ function bufferStream(stream) {
const chunks = [];
stream
.on("error", reject)
.on("data", chunk => chunks.push(chunk))
.on("end", () => resolve(Buffer.concat(chunks)));
.on('error', reject)
.on('data', chunk => chunks.push(chunk))
.on('end', () => resolve(Buffer.concat(chunks)));
});
}

View File

@ -1,9 +1,9 @@
const redis = require("redis");
const redis = require('redis');
redis.debug_mode = process.env.DEBUG_REDIS != null;
const client = redis.createClient(
process.env.CACHE_URL || process.env.OPENREDIS_URL || "redis://localhost:6379"
process.env.CACHE_URL || process.env.OPENREDIS_URL || 'redis://localhost:6379'
);
module.exports = client;

View File

@ -3,14 +3,14 @@ function createSearch(query) {
const params = keys.reduce(
(memo, key) =>
memo.concat(
query[key] === ""
query[key] === ''
? key // Omit the trailing "=" from key=
: `${key}=${encodeURIComponent(query[key])}`
),
[]
);
return params.length ? `?${params.join("&")}` : "";
return params.length ? `?${params.join('&')}` : '';
}
module.exports = createSearch;

View File

@ -1,9 +1,9 @@
const redis = require("redis");
const redis = require('redis');
redis.debug_mode = process.env.DEBUG_REDIS != null;
const client = redis.createClient(
process.env.DATA_URL || process.env.OPENREDIS_URL || "redis://localhost:6379"
process.env.DATA_URL || process.env.OPENREDIS_URL || 'redis://localhost:6379'
);
module.exports = client;

View File

@ -1,18 +1,18 @@
const url = require("url");
const https = require("https");
const gunzip = require("gunzip-maybe");
const tar = require("tar-stream");
const url = require('url');
const https = require('https');
const gunzip = require('gunzip-maybe');
const tar = require('tar-stream');
const bufferStream = require("./bufferStream");
const agent = require("./registryAgent");
const logging = require("./logging");
const bufferStream = require('./bufferStream');
const agent = require('./registryAgent');
const logging = require('./logging');
function fetchNpmPackage(packageConfig) {
return new Promise((resolve, reject) => {
const tarballURL = packageConfig.dist.tarball;
logging.debug(
"Fetching package for %s from %s",
'Fetching package for %s from %s',
packageConfig.name,
tarballURL
);
@ -31,7 +31,7 @@ function fetchNpmPackage(packageConfig) {
} else {
bufferStream(res).then(data => {
const spec = `${packageConfig.name}@${packageConfig.version}`;
const content = data.toString("utf-8");
const content = data.toString('utf-8');
const error = new Error(
`Failed to fetch tarball for ${spec}\nstatus: ${
res.statusCode
@ -42,7 +42,7 @@ function fetchNpmPackage(packageConfig) {
});
}
})
.on("error", reject);
.on('error', reject);
});
}

View File

@ -1,10 +1,10 @@
const url = require("url");
const https = require("https");
const url = require('url');
const https = require('https');
const serverConfig = require("../serverConfig");
const bufferStream = require("./bufferStream");
const agent = require("./registryAgent");
const logging = require("./logging");
const serverConfig = require('../serverConfig');
const bufferStream = require('./bufferStream');
const agent = require('./registryAgent');
const logging = require('./logging');
function parseJSON(res) {
return bufferStream(res).then(JSON.parse);
@ -13,13 +13,13 @@ function parseJSON(res) {
function fetchNpmPackageInfo(packageName) {
return new Promise((resolve, reject) => {
const encodedPackageName =
packageName.charAt(0) === "@"
packageName.charAt(0) === '@'
? `@${encodeURIComponent(packageName.substring(1))}`
: encodeURIComponent(packageName);
const infoURL = `${serverConfig.registryURL}/${encodedPackageName}`;
logging.debug("Fetching package info for %s from %s", packageName, infoURL);
logging.debug('Fetching package info for %s from %s', packageName, infoURL);
const { hostname, pathname } = url.parse(infoURL);
const options = {
@ -27,7 +27,7 @@ function fetchNpmPackageInfo(packageName) {
hostname: hostname,
path: pathname,
headers: {
Accept: "application/json"
Accept: 'application/json'
}
};
@ -39,7 +39,7 @@ function fetchNpmPackageInfo(packageName) {
resolve(null);
} else {
bufferStream(res).then(data => {
const content = data.toString("utf-8");
const content = data.toString('utf-8');
const error = new Error(
`Failed to fetch info for ${packageName}\nstatus: ${
res.statusCode
@ -50,7 +50,7 @@ function fetchNpmPackageInfo(packageName) {
});
}
})
.on("error", reject);
.on('error', reject);
});
}

View File

@ -1,22 +1,22 @@
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|\.lock)$/i;
function getContentType(file) {
return textFiles.test(file) ? "text/plain" : mime.lookup(file);
return textFiles.test(file) ? 'text/plain' : mime.lookup(file);
}
module.exports = getContentType;

View File

@ -1,5 +1,5 @@
function getContentTypeHeader(type) {
return type === "application/javascript" ? type + "; charset=utf-8" : type;
return type === 'application/javascript' ? type + '; charset=utf-8' : type;
}
module.exports = getContentTypeHeader;

View File

@ -1,7 +1,7 @@
const SRIToolbox = require("sri-toolbox");
const SRIToolbox = require('sri-toolbox');
function getIntegrity(data) {
return SRIToolbox.generate({ algorithms: ["sha384"] }, data);
return SRIToolbox.generate({ algorithms: ['sha384'] }, data);
}
module.exports = getIntegrity;

View File

@ -1,5 +1,5 @@
const cache = require("./cache");
const fetchNpmPackageInfo = require("./fetchNpmPackageInfo");
const cache = require('./cache');
const fetchNpmPackageInfo = require('./fetchNpmPackageInfo');
const notFound = 0;

View File

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

View File

@ -1,4 +1,4 @@
const validateNpmPackageName = require("validate-npm-package-name");
const validateNpmPackageName = require('validate-npm-package-name');
function isValidPackageName(packageName) {
return validateNpmPackageName(packageName).errors == null;

View File

@ -4,11 +4,11 @@ function noop() {}
let debug, info, warn;
if (process.env.LOG_LEVEL === "none") {
if (process.env.LOG_LEVEL === 'none') {
debug = info = warn = noop;
} else if (process.env.LOG_LEVEL === "debug") {
} else if (process.env.LOG_LEVEL === 'debug') {
debug = info = warn = log;
} else if (process.env.LOG_LEVEL === "warn") {
} else if (process.env.LOG_LEVEL === 'warn') {
debug = info = noop;
warn = log;
} else {

View File

@ -1,4 +1,4 @@
const url = require("url");
const url = require('url');
const packageURLFormat = /^\/((?:@[^/@]+\/)?[^/@]+)(?:@([^/]+))?(\/.*)?$/;
@ -11,7 +11,7 @@ function decodeParam(param) {
}
}
return "";
return '';
}
function parsePackageURL(originalURL) {
@ -24,13 +24,13 @@ function parsePackageURL(originalURL) {
}
const packageName = match[1];
const packageVersion = decodeParam(match[2]) || "latest";
const packageVersion = decodeParam(match[2]) || 'latest';
const filename = decodeParam(match[3]);
return {
// If the URL is /@scope/name@version/file.js?main=browser:
pathname, // /@scope/name@version/path.js
search: search || "", // ?main=browser
search: search || '', // ?main=browser
query, // { main: 'browser' }
packageName, // @scope/name
packageVersion, // version

View File

@ -1,4 +1,4 @@
const https = require("https");
const https = require('https');
const agent = new https.Agent({
keepAlive: true

View File

@ -1,7 +1,7 @@
const React = require("react");
const ReactDOMServer = require("react-dom/server");
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const doctype = "<!DOCTYPE html>";
const doctype = '<!DOCTYPE html>';
function renderPage(page, props) {
const element = React.createElement(page, props);

View File

@ -1,6 +1,6 @@
const babel = require("babel-core");
const babel = require('babel-core');
const unpkgRewrite = require("../plugins/unpkgRewrite");
const unpkgRewrite = require('../plugins/unpkgRewrite');
function rewriteBareModuleIdentifiers(code, packageConfig) {
const dependencies = Object.assign(