Browse Source

Update.

master
186526 9 months ago
parent
commit
010fed101f
Signed by: 186526
GPG Key ID: C7EB1E6B8CC5E51D
  1. 7
      Dockerfile.unpkg
  2. 222243
      build/main.js
  3. 1911
      dist/main.js
  4. 295
      dist/main.js.LICENSE.txt
  5. 101
      modules/actions/dir.ejs
  6. 10
      modules/actions/serveDirectoryMetadata.js
  7. 1
      modules/actions/serveMainPage.js
  8. 150
      modules/createServer.js
  9. 4
      modules/utils/asyncHandler.js
  10. 6
      package.json
  11. 6
      rollup.config.js
  12. 18
      rollup.config.mjs
  13. 3
      webpack.config.js
  14. 6281
      yarn.lock

7
Dockerfile.unpkg

@ -0,0 +1,7 @@
FROM docker.io/library/node:lts-alpine
COPY ./dist/main.js /app/main.js
WORKDIR /app
CMD NODE_ENV=production node main.js

222243
build/main.js

File diff suppressed because one or more lines are too long

1911
dist/main.js vendored

File diff suppressed because one or more lines are too long

295
dist/main.js.LICENSE.txt vendored

@ -0,0 +1,295 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/*!
* accepts
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* bytes
* Copyright(c) 2012-2014 TJ Holowaychuk
* Copyright(c) 2015 Jed Watson
* MIT Licensed
*/
/*!
* content-disposition
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* content-type
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* cookie
* Copyright(c) 2012-2014 Roman Shtylman
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* depd
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* depd
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* depd
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* depd
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* destroy
* Copyright(c) 2014 Jonathan Ong
* MIT Licensed
*/
/*!
* ee-first
* Copyright(c) 2014 Jonathan Ong
* MIT Licensed
*/
/*!
* encodeurl
* Copyright(c) 2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* escape-html
* Copyright(c) 2012-2013 TJ Holowaychuk
* Copyright(c) 2015 Andreas Lubbe
* Copyright(c) 2015 Tiancheng "Timothy" Gu
* MIT Licensed
*/
/*!
* etag
* Copyright(c) 2014-2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2013 Roman Shtylman
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* finalhandler
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* forwarded
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* fresh
* Copyright(c) 2012 TJ Holowaychuk
* Copyright(c) 2016-2017 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* http-errors
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* media-typer
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* merge-descriptors
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* methods
* Copyright(c) 2013-2014 TJ Holowaychuk
* Copyright(c) 2015-2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* mime-db
* Copyright(c) 2014 Jonathan Ong
* MIT Licensed
*/
/*!
* mime-types
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* negotiator
* Copyright(c) 2012 Federico Romero
* Copyright(c) 2012-2014 Isaac Z. Schlueter
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* on-finished
* Copyright(c) 2013 Jonathan Ong
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* parseurl
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* proxy-addr
* Copyright(c) 2014-2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* range-parser
* Copyright(c) 2012-2014 TJ Holowaychuk
* Copyright(c) 2015-2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* raw-body
* Copyright(c) 2013-2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* send
* Copyright(c) 2012 TJ Holowaychuk
* Copyright(c) 2014-2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* serve-static
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2014-2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* statuses
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* toidentifier
* Copyright(c) 2016 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* type-is
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* unpipe
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*!
* vary
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
/**
* @file Embedded JavaScript templating engine. {@link http://ejs.co}
* @author Matthew Eernisse <[email protected]>
* @author Tiancheng "Timothy" Gu <[email protected]>
* @project EJS
* @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0}
*/

101
modules/actions/dir.ejs

@ -0,0 +1,101 @@
<%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>

10
modules/actions/serveDirectoryMetadata.js

@ -99,4 +99,14 @@ async function serveDirectoryMetadata(req, res) {
res.send(metadata);
}
export async function getMetadataMoreEasier(req,res) {
const stream = await getPackage(req.packageName, req.packageVersion, req.log);
const filename = req.filename.slice(0, -1) || '/';
const entries = await findMatchingEntries(stream, filename);
const metadata = getMetadata(entries[filename], entries);
return metadata;
}
export default asyncHandler(serveDirectoryMetadata);

1
modules/actions/serveMainPage.js

@ -29,7 +29,6 @@ export default function serveMainPage(req, res) {
res
.set({
'Cache-Control': 'public, max-age=14400', // 4 hours
'Cache-Tag': 'main'
})
.send(html);

150
modules/createServer.js

@ -1,15 +1,11 @@
import cors from 'cors';
import express from 'express';
import morgan from 'morgan';
import ejs from 'ejs';
import serveDirectoryBrowser from './actions/serveDirectoryBrowser.js';
import serveDirectoryMetadata from './actions/serveDirectoryMetadata.js';
import serveFileBrowser from './actions/serveFileBrowser.js';
import serveDirectoryMetadata, { getMetadataMoreEasier } from './actions/serveDirectoryMetadata.js';
import serveFileMetadata from './actions/serveFileMetadata.js';
import serveFile from './actions/serveFile.js';
import serveMainPage from './actions/serveMainPage.js';
import serveModule from './actions/serveModule.js';
import serveStats from './actions/serveStats.js';
import allowQuery from './middleware/allowQuery.js';
import findEntry from './middleware/findEntry.js';
@ -21,6 +17,117 @@ import validatePackagePathname from './middleware/validatePackagePathname.js';
import validatePackageName from './middleware/validatePackageName.js';
import validatePackageVersion from './middleware/validatePackageVersion.js';
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 Edge/1.20.1</address>
</body>
</html>`, Object.assign({ package: `${req.packageName}@${req.packageVersion}` }, await getMetadataMoreEasier(req, res)), { async: true });
res.send(html);
};
function createApp(callback) {
const app = express();
callback(app);
@ -33,20 +140,17 @@ export default function createServer() {
app.enable('trust proxy');
app.enable('strict routing');
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
}
app.use(cors());
app.use(express.static('public', { maxAge: '1y' }));
app.use(requestLog);
app.get('/', serveMainPage);
app.get('/api/stats', serveStats);
app.use(redirectLegacyURLs);
app.all('/', (req, res) => {
res.send("To infinity and beyond!");
})
app.use(
'/browse',
createApp(app => {
@ -58,16 +162,13 @@ export default function createServer() {
validatePackagePathname,
validatePackageName,
validatePackageVersion,
serveDirectoryBrowser
renderFolderBrowser,
);
app.get(
'*',
noQuery(),
validatePackagePathname,
validatePackageName,
validatePackageVersion,
serveFileBrowser
(req, res, next) => {
res.redirect(req.path.replace("/browser", ""));
}
);
})
);
@ -132,9 +233,12 @@ export default function createServer() {
});
// Send old */ requests to the new /browse UI.
app.get('*/', (req, res) => {
res.redirect(302, '/browse' + req.url);
});
app.get('*/', noQuery(),
validatePackagePathname,
validatePackageName,
validatePackageVersion,
renderFolderBrowser
);
app.get(
'*',

4
modules/utils/asyncHandler.js

@ -5,8 +5,8 @@
export default function asyncHandler(handler) {
return (req, res, next) => {
Promise.resolve(handler(req, res, next)).catch(error => {
req.log.error(`Unexpected error in ${handler.name}!`);
req.log.error(error.stack);
console.error(`Unexpected error in ${handler.name}!`);
console.error(error.stack);
next(error);
});

6
package.json

@ -1,6 +1,7 @@
{
"name": "unpkg",
"private": true,
"type":"module",
"description": "The CDN for everything on npm",
"scripts": {
"build": "rollup -c",
@ -22,9 +23,11 @@
"@babel/plugin-syntax-import-meta": "^7.2.0",
"@emotion/core": "^10.0.6",
"@reach/visually-hidden": "^0.1.4",
"@rollup/plugin-json": "^4.1.0",
"cheerio": "^1.0.0-rc.2",
"cors": "^2.8.5",
"date-fns": "^1.30.1",
"ejs": "^3.1.6",
"etag": "^1.8.1",
"express": "^4.16.4",
"gunzip-maybe": "^1.4.1",
@ -77,8 +80,5 @@
"rollup-plugin-replace": "^2.1.0",
"rollup-plugin-url": "^2.1.0",
"supertest": "^3.0.0"
},
"engines": {
"node": "12"
}
}

6
rollup.config.js

@ -3,7 +3,7 @@ const execSync = require('child_process').execSync;
const babel = require('rollup-plugin-babel');
const commonjs = require('rollup-plugin-commonjs');
const compiler = require('@ampproject/rollup-plugin-closure-compiler');
//const compiler = require('@ampproject/rollup-plugin-closure-compiler');
const json = require('rollup-plugin-json');
const replace = require('rollup-plugin-replace');
const resolve = require('rollup-plugin-node-resolve');
@ -11,6 +11,7 @@ const url = require('rollup-plugin-url');
const entryManifest = require('./plugins/entryManifest');
const pkg = require('./package.json');
const progress = require('rollup-plugin-progress');
const buildId =
process.env.BUILD_ID ||
@ -40,6 +41,7 @@ const client = ['browse', 'main'].map(entryName => {
babel({ exclude: /node_modules/ }),
json(),
resolve(),
progress(),
commonjs({
namedExports: {
'node_modules/react/index.js': [
@ -61,7 +63,7 @@ const client = ['browse', 'main'].map(entryName => {
limit: 5 * 1024,
publicPath: '/_client/'
}),
compiler()
//compiler()
]
};
});

18
rollup.config.mjs

@ -0,0 +1,18 @@
import progress from 'rollup-plugin-progress';
import cjs from "rollup-plugin-commonjs";
import node from "rollup-plugin-node-resolve";
import json from '@rollup/plugin-json';
export default {
input: './modules/server.js',
output: { file: "build/main.js", format: "cjs", },
plugins: [
cjs(),
progress({
clearLine: false // default: true
}),
node(),
json(),
]
}

3
webpack.config.js

@ -0,0 +1,3 @@
module.exports = {
target: "node",
}

6281
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save