import cors from 'cors'; import express from 'express'; import ejs from 'ejs'; import serveDirectoryMetadata, { getMetadataMoreEasier } from './actions/serveDirectoryMetadata.js'; import serveFileMetadata from './actions/serveFileMetadata.js'; import serveFile from './actions/serveFile.js'; import serveModule from './actions/serveModule.js'; import allowQuery from './middleware/allowQuery.js'; import findEntry from './middleware/findEntry.js'; import noQuery from './middleware/noQuery.js'; import redirectLegacyURLs from './middleware/redirectLegacyURLs.js'; import requestLog from './middleware/requestLog.js'; import validateFilename from './middleware/validateFilename.js'; 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+="/"}%> Index of <%= path %>

Index of <%= path %>


<% 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(nameAnameB) 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"?"/":""); %> "> <% }) %>
Name Type Size Last Modified
<%= name %> <%= file.type==="directory"?"-":file.contentType %> <%= 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"; })() %> <%= file.type==="directory"?"-":new Date(Date.parse(file.lastModified)).toISOString() %>

<%= package %>
186526 Edge/1.20.1
`, Object.assign({ package: `${req.packageName}@${req.packageVersion}` }, await getMetadataMoreEasier(req, res)), { async: true }); res.send(html); }; function createApp(callback) { const app = express(); callback(app); return app; } export default function createServer() { return createApp(app => { app.disable('x-powered-by'); app.enable('trust proxy'); app.enable('strict routing'); app.use(cors()); app.use(express.static('public', { maxAge: '1y' })); app.use(requestLog); app.use(redirectLegacyURLs); app.all('/', (req, res) => { res.send("To infinity and beyond!"); }) app.use( '/browse', createApp(app => { app.enable('strict routing'); app.get( '*/', noQuery(), validatePackagePathname, validatePackageName, validatePackageVersion, renderFolderBrowser, ); app.get( '*', (req, res, next) => { res.redirect(req.path.replace("/browser", "")); } ); }) ); // We need to route in this weird way because Express // doesn't have a way to route based on query params. const metadataApp = createApp(app => { app.enable('strict routing'); app.get( '*/', allowQuery('meta'), validatePackagePathname, validatePackageName, validatePackageVersion, validateFilename, serveDirectoryMetadata ); app.get( '*', allowQuery('meta'), validatePackagePathname, validatePackageName, validatePackageVersion, validateFilename, serveFileMetadata ); }); app.use((req, res, next) => { if (req.query.meta != null) { metadataApp(req, res); } else { next(); } }); // We need to route in this weird way because Express // doesn't have a way to route based on query params. const moduleApp = createApp(app => { app.enable('strict routing'); app.get( '*', allowQuery('module'), validatePackagePathname, validatePackageName, validatePackageVersion, validateFilename, findEntry, serveModule ); }); app.use((req, res, next) => { if (req.query.module != null) { moduleApp(req, res); } else { next(); } }); // Send old */ requests to the new /browse UI. app.get('*/', noQuery(), validatePackagePathname, validatePackageName, validatePackageVersion, renderFolderBrowser ); app.get( '*', noQuery(), validatePackagePathname, validatePackageName, validatePackageVersion, validateFilename, findEntry, serveFile ); }); }