This commit is contained in:
186526 2022-05-12 09:28:46 +08:00
parent d9e588dcbc
commit 5a65aefca9
Signed by: 186526
GPG Key ID: C7EB1E6B8CC5E51D
5 changed files with 183 additions and 160 deletions

View File

@ -14,9 +14,9 @@ var querystring = require('querystring');
var url = require('url'); var url = require('url');
var http = require('http'); var http = require('http');
var crypto = require('crypto'); var crypto = require('crypto');
var os = require('os');
var constants$1 = require('constants'); var constants$1 = require('constants');
var https = require('https'); var https = require('https');
var os = require('os');
var assert = require('assert'); var assert = require('assert');
var module$1 = require('module'); var module$1 = require('module');
var v8$1 = require('v8'); var v8$1 = require('v8');
@ -58,9 +58,9 @@ var querystring__default = /*#__PURE__*/_interopDefaultLegacy(querystring);
var url__default = /*#__PURE__*/_interopDefaultLegacy(url); var url__default = /*#__PURE__*/_interopDefaultLegacy(url);
var http__default = /*#__PURE__*/_interopDefaultLegacy(http); var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto); var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto);
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
var constants__default = /*#__PURE__*/_interopDefaultLegacy(constants$1); var constants__default = /*#__PURE__*/_interopDefaultLegacy(constants$1);
var https__default = /*#__PURE__*/_interopDefaultLegacy(https); var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert); var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert);
var module__default = /*#__PURE__*/_interopDefaultLegacy(module$1); var module__default = /*#__PURE__*/_interopDefaultLegacy(module$1);
var v8__default = /*#__PURE__*/_interopDefaultLegacy(v8$1); var v8__default = /*#__PURE__*/_interopDefaultLegacy(v8$1);
@ -222004,12 +222004,125 @@ async function validateVersion(req, res, next) {
var validatePackageVersion = asyncHandler(validateVersion); var validatePackageVersion = asyncHandler(validateVersion);
const renderFolderBrowser = async (req, res, next) => {
res.set({
'Cache-Control': 'public, max-age=14400', // 4 hours
'Cache-Tag': 'browse'
});
const html = await ejs.render(`<%if(path!=="/"){path+="/"}%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Index of <%= path %></title>
<style>
body {
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.5;
padding: 0 10px 5px
}
table {
width: 100%;
border-collapse: collapse;
font: .85em Monaco, monospace
}
tr.even {
background-color: #eee
}
th {
text-align: left
}
td,
th {
padding: .1em .25em
}
.version-wrapper {
line-height: 2.25em;
float: right
}
#version {
font-size: 1em
}
address {
text-align: right
}
</style>
</head>
<body>
<h1>Index of <%= path %></h1>
<hr />
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Size</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<%
files.sort((fileA,fileB) => {
let nameA = fileA.path.toUpperCase();
let nameB = fileB.path.toUpperCase();
if(fileA.type === "directory") return -1;
else if(fileB.type === "directory") return 1;
else if(nameA<nameB) return -1;
else if(nameA>nameB) return 1;
else return 0;
})
if(path!=="/"){
files.splice(0,0,{
path: "..",
type: "directory",
});
}
%>
<% files.forEach((file,index) => { let name = file.path.replace(path,"")+(file.type==="directory"?"/":""); %>
<tr class="<%= index%2===0?"even":"odd" %> ">
<td><a title="<%= name %>" href="<%= name %>"><%= name %></a></td>
<td><%= file.type==="directory"?"-":file.contentType %></td>
<td><%= file.type==="directory"?"-":(()=>{
if(file.size<=1024) return file.size+" B";
else if(file.size<=1024*1024) return (file.size/1024).toFixed(2)+" KiB";
else return (file.size/1024/1024).toFixed(2)+" MB";
})() %></td>
<td><%= file.type==="directory"?"-":new Date(Date.parse(file.lastModified)).toISOString()
%></td>
</tr>
<% }) %>
</tbody>
</table>
<hr />
<address><%= package %> </address>
<address>186526 NPM Edge Network #d9e588d</address>
</body>
</html>`, Object.assign({ package: `${req.packageName}@${req.packageVersion}` }, await getMetadataMoreEasier(req)), { async: true });
res.send(html);
};
function createApp(callback) { function createApp(callback) {
const app = express$1(); const app = express$1();
callback(app); callback(app);
return app; return app;
} }
const hostname = os__default['default'].hostname();
function createServer() { function createServer() {
return createApp(app => { return createApp(app => {
app.disable('x-powered-by'); app.disable('x-powered-by');
@ -222019,6 +222132,12 @@ function createServer() {
app.use(lib()); app.use(lib());
app.use(express$1.static('public', { maxAge: '1y' })); app.use(express$1.static('public', { maxAge: '1y' }));
app.use((req, res, next) => {
res.set({ 'x-delivery-by': hostname ,
'timing-allow-origin': '*' });
next();
});
app.use(requestLog); app.use(requestLog);
app.use(redirectLegacyURLs); app.use(redirectLegacyURLs);
@ -222027,136 +222146,27 @@ function createServer() {
res.send("To infinity and beyond!"); res.send("To infinity and beyond!");
}); });
app.use( // app.use(
'/browse', // '/browse',
createApp(app => { // createApp(app => {
app.enable('strict routing'); // app.enable('strict routing');
app.get( // app.get(
'*/', // '*/',
noQuery(), // noQuery(),
validatePackagePathname, // validatePackagePathname,
validatePackageName, // validatePackageName,
validatePackageVersion, // validatePackageVersion,
async (req, res, next) => { // renderFolderBrowser,
// );
res.set({ // app.get(
'Cache-Control': 'public, max-age=14400', // 4 hours // '*',
'Cache-Tag': 'browse' // (req, res, next) => {
}); // res.redirect(req.path.replace("/browser", ""));
// }
const html = await ejs.render(`<%if(path!=="/"){path+="/"}%> // );
<!DOCTYPE html> // })
<html> // );
<head>
<meta charset="utf-8" />
<title>Index of <%= path %></title>
<style>
body {
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.5;
padding: 0 10px 5px
}
table {
width: 100%;
border-collapse: collapse;
font: .85em Monaco, monospace
}
tr.even {
background-color: #eee
}
th {
text-align: left
}
td,
th {
padding: .1em .25em
}
.version-wrapper {
line-height: 2.25em;
float: right
}
#version {
font-size: 1em
}
address {
text-align: right
}
</style>
</head>
<body>
<h1>Index of <%= path %></h1>
<hr />
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Size</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<%
files.sort((fileA,fileB) => {
let nameA = fileA.path.toUpperCase();
let nameB = fileB.path.toUpperCase();
if(fileA.type === "directory") return -1;
else if(fileB.type === "directory") return 1;
else if(nameA<nameB) return -1;
else if(nameA>nameB) return 1;
else return 0;
})
if(path!=="/"){
files.splice(0,0,{
path: "..",
type: "directory",
});
}
%>
<% files.forEach((file,index) => { let name = file.path.replace(path,"")+(file.type==="directory"?"/":""); %>
<tr class="<%= index%2===0?"even":"odd" %> ">
<td><a title="<%= name %>" href="<%= name %>"><%= name %></a></td>
<td><%= file.type==="directory"?"-":file.contentType %></td>
<td><%= file.type==="directory"?"-":(()=>{
if(file.size<=1024) return file.size+" B";
else if(file.size<=1024*1024) return (file.size/1024).toFixed(2)+" KiB";
else return (file.size/1024/1024).toFixed(2)+" MB";
})() %></td>
<td><%= file.type==="directory"?"-":new Date(Date.parse(file.lastModified)).toISOString()
%></td>
</tr>
<% }) %>
</tbody>
</table>
<hr />
<address><%= package %> </address>
<address>186526 Edge/1.20.1</address>
</body>
</html>`, Object.assign({ package: `${req.packageName}@${req.packageVersion}` }, await getMetadataMoreEasier(req)), { async: true });
res.send(html);
});
app.get(
'*',
(req,res,next) => {
res.redirect(req.path.replace("/browser",""));
}
);
})
);
// We need to route in this weird way because Express // We need to route in this weird way because Express
// doesn't have a way to route based on query params. // doesn't have a way to route based on query params.
@ -222217,10 +222227,12 @@ function createServer() {
} }
}); });
// Send old */ requests to the new /browse UI. app.get('*/', noQuery(),
app.get('*/', (req, res) => { validatePackagePathname,
res.redirect(302, '/browse' + req.url); validatePackageName,
}); validatePackageVersion,
renderFolderBrowser
);
app.get( app.get(
'*', '*',

2
dist/main.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
import cors from 'cors'; import cors from 'cors';
import express from 'express'; import express from 'express';
import ejs from 'ejs'; import ejs from 'ejs';
import os from "os";
import serveDirectoryMetadata, { getMetadataMoreEasier } from './actions/serveDirectoryMetadata.js'; import serveDirectoryMetadata, { getMetadataMoreEasier } from './actions/serveDirectoryMetadata.js';
import serveFileMetadata from './actions/serveFileMetadata.js'; import serveFileMetadata from './actions/serveFileMetadata.js';
@ -121,7 +122,7 @@ const renderFolderBrowser = async (req, res, next) => {
</table> </table>
<hr /> <hr />
<address><%= package %> </address> <address><%= package %> </address>
<address>186526 NPM Edge Network #010fed1</address> <address>186526 NPM Edge Network #d9e588d</address>
</body> </body>
</html>`, Object.assign({ package: `${req.packageName}@${req.packageVersion}` }, await getMetadataMoreEasier(req, res)), { async: true }); </html>`, Object.assign({ package: `${req.packageName}@${req.packageVersion}` }, await getMetadataMoreEasier(req, res)), { async: true });
@ -134,6 +135,8 @@ function createApp(callback) {
return app; return app;
} }
const hostname = os.hostname();
export default function createServer() { export default function createServer() {
return createApp(app => { return createApp(app => {
app.disable('x-powered-by'); app.disable('x-powered-by');
@ -143,6 +146,16 @@ export default function createServer() {
app.use(cors()); app.use(cors());
app.use(express.static('public', { maxAge: '1y' })); app.use(express.static('public', { maxAge: '1y' }));
app.use((req, res, next) => {
res.set({
'x-delivery-by': hostname,
'timing-allow-origin': '*',
'x-powered-by': '186526 NPM Edge Network',
'x-version': 'd9e588d'
});
next();
})
app.use(requestLog); app.use(requestLog);
app.use(redirectLegacyURLs); app.use(redirectLegacyURLs);
@ -151,27 +164,27 @@ export default function createServer() {
res.send("To infinity and beyond!"); res.send("To infinity and beyond!");
}) })
app.use( // app.use(
'/browse', // '/browse',
createApp(app => { // createApp(app => {
app.enable('strict routing'); // app.enable('strict routing');
app.get( // app.get(
'*/', // '*/',
noQuery(), // noQuery(),
validatePackagePathname, // validatePackagePathname,
validatePackageName, // validatePackageName,
validatePackageVersion, // validatePackageVersion,
renderFolderBrowser, // renderFolderBrowser,
); // );
app.get( // app.get(
'*', // '*',
(req, res, next) => { // (req, res, next) => {
res.redirect(req.path.replace("/browser", "")); // res.redirect(req.path.replace("/browser", ""));
} // }
); // );
}) // })
); // );
// We need to route in this weird way because Express // We need to route in this weird way because Express
// doesn't have a way to route based on query params. // doesn't have a way to route based on query params.
@ -232,7 +245,6 @@ export default function createServer() {
} }
}); });
// Send old */ requests to the new /browse UI.
app.get('*/', noQuery(), app.get('*/', noQuery(),
validatePackagePathname, validatePackagePathname,
validatePackageName, validatePackageName,

View File

@ -1,10 +1,9 @@
{ {
"name": "unpkg", "name": "unpkg",
"private": true, "private": true,
"type":"module",
"description": "The CDN for everything on npm", "description": "The CDN for everything on npm",
"scripts": { "scripts": {
"build": "rollup -c", "build": "rollup -c rollup.config.cjs",
"clean": "git clean -e '!/.env' -fdX .", "clean": "git clean -e '!/.env' -fdX .",
"lint": "eslint .", "lint": "eslint .",
"serve": "nodemon -w server.js server.js", "serve": "nodemon -w server.js server.js",